Commit ae6549431624
Changed files (5)
dots
.config
copilot-hooks
git
template
hooks
home
common
shell
dots/.config/copilot-hooks/claude-hooks.json
@@ -0,0 +1,38 @@
+{
+ "version": 1,
+ "hooks": {
+ "sessionStart": [
+ {
+ "type": "command",
+ "bash": "claude-hooks-initialize-session",
+ "timeoutSec": 5
+ }
+ ],
+ "sessionEnd": [
+ {
+ "type": "command",
+ "bash": "claude-hooks-save-session",
+ "timeoutSec": 10
+ }
+ ],
+ "preToolUse": [
+ {
+ "type": "command",
+ "bash": ".github/hooks/copilot-to-claude.sh claude-hooks-validate-git-push",
+ "timeoutSec": 5
+ }
+ ],
+ "postToolUse": [
+ {
+ "type": "command",
+ "bash": ".github/hooks/copilot-to-claude.sh claude-hooks-capture-tool-output",
+ "timeoutSec": 5
+ },
+ {
+ "type": "command",
+ "bash": ".github/hooks/copilot-to-claude.sh claude-hooks-update-terminal-title",
+ "timeoutSec": 2
+ }
+ ]
+ }
+}
dots/.config/copilot-hooks/copilot-to-claude.sh
@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+# Wrapper script to translate Copilot hook JSON format to Claude Code format
+# Usage: copilot-to-claude.sh <claude-hooks-binary>
+#
+# Copilot format:
+# { "toolName": "bash", "toolArgs": "{\"command\":\"...\"}", "toolResult": {...} }
+#
+# Claude Code format:
+# { "tool_name": "Bash", "tool_input": {"command": "..."}, "tool_response": {...} }
+
+set -euo pipefail
+
+BINARY="${1:-}"
+if [[ -z "$BINARY" ]]; then
+ echo "Usage: $0 <claude-hooks-binary>" >&2
+ exit 1
+fi
+
+# Read stdin
+INPUT=$(cat)
+
+# Check if we have input
+if [[ -z "$INPUT" ]]; then
+ exit 0
+fi
+
+# Transform Copilot format to Claude Code format using jq
+# - toolName -> tool_name (capitalize first letter for Claude Code convention)
+# - toolArgs (string) -> tool_input (parsed object)
+# - toolResult -> tool_response
+TRANSFORMED=$(echo "$INPUT" | jq -c '
+{
+ tool_name: (.toolName | split("") | .[0:1] | map(ascii_upcase) | join("") + (.toolName | .[1:])),
+ tool_input: (if .toolArgs then (.toolArgs | fromjson) else {} end),
+ tool_response: (.toolResult // {}),
+ conversation_id: (.sessionId // "copilot")
+}
+' 2>/dev/null) || {
+ # If jq fails, just pass through empty and let binary handle it
+ exit 0
+}
+
+# Call the Claude hooks binary with transformed input
+echo "$TRANSFORMED" | "$BINARY"
+exit $?
dots/.config/git/template/hooks/post-checkout
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+# Git post-checkout hook (installed via git template)
+# Automatically installs GitHub Copilot hooks to .github/hooks/
+#
+# This runs after:
+# - git clone (prev_head is null-ref)
+# - git checkout/switch (branch checkout when flag=1)
+
+set -euo pipefail
+
+COPILOT_HOOKS_SOURCE="${XDG_CONFIG_HOME:-$HOME/.config}/copilot-hooks"
+
+# Only proceed if we have hooks to install
+if [[ ! -d "$COPILOT_HOOKS_SOURCE" ]]; then
+ exit 0
+fi
+
+# Only install if .github/hooks doesn't exist yet
+if [[ -d ".github/hooks" ]]; then
+ exit 0
+fi
+
+# Check if this looks like a repo that might use Copilot
+# (has .github/ directory or is a code project)
+if [[ ! -d ".github" ]] && [[ ! -f "package.json" ]] && [[ ! -f "go.mod" ]] && [[ ! -f "Cargo.toml" ]] && [[ ! -f "flake.nix" ]] && [[ ! -f "pyproject.toml" ]]; then
+ exit 0
+fi
+
+# Install hooks
+mkdir -p .github/hooks
+cp -r "$COPILOT_HOOKS_SOURCE"/* .github/hooks/ 2>/dev/null || true
+
+# Make scripts executable
+chmod +x .github/hooks/*.sh 2>/dev/null || true
+
+echo "Installed Copilot hooks to .github/hooks/"
dots/Makefile
@@ -53,6 +53,10 @@ lazypr : ~/.config/lazypr/config.toml
all += gh-news
gh-news : ~/.config/gh-news/config.toml
+all += git-template copilot-hooks
+git-template : ~/.config/git/template
+copilot-hooks : ~/.config/copilot-hooks
+
# Backward compatibility: symlink ~/.claude to ~/.config/claude
~/.claude : force
@echo "๐ Creating backward compatibility symlink: ~/.claude -> ~/.config/claude"
home/common/shell/git.nix
@@ -103,6 +103,8 @@ in
core = {
pager = "${pkgs.delta}/bin/delta";
abbrev = 12;
+ # Override system excludesFile to use XDG user ignores
+ excludesFile = "${config.xdg.configHome}/git/ignore";
# pager = "${pkgs.delta}/bin/delta --syntax-theme GitHub";
# editor = "${pkgs.emacs}/bin/emacsclient -t";
};
@@ -121,6 +123,7 @@ in
};
init = {
defaultBranch = "main";
+ templateDir = "${config.xdg.configHome}/git/template";
};
color = {
status = "auto";
@@ -253,6 +256,8 @@ in
"#*#"
".makefile"
".clean"
+ # Copilot hooks are auto-installed via git template, never commit
+ ".github/hooks"
];
};
}