@a5c-ai/babysitter-github 5.0.1-staging.b5c14f2a → 5.0.1-staging.c66885f8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/hooks/babysitter-proxied-session-end.ps1 +116 -0
- package/hooks/babysitter-proxied-session-end.sh +112 -0
- package/hooks/babysitter-proxied-session-start.ps1 +189 -0
- package/hooks/babysitter-proxied-session-start.sh +173 -0
- package/hooks/babysitter-proxied-user-prompt-submitted.ps1 +92 -0
- package/hooks/babysitter-proxied-user-prompt-submitted.sh +87 -0
- package/hooks/proxied-hooks.json +29 -0
- package/hooks.json +7 -7
- package/package.json +2 -2
- package/plugin.json +1 -1
- package/versions.json +1 -1
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Unified Session End Hook for GitHub Copilot CLI (PowerShell)
|
|
2
|
+
# Routes through hooks-proxy for all hook execution.
|
|
3
|
+
#
|
|
4
|
+
# Cleanup and logging on session exit.
|
|
5
|
+
#
|
|
6
|
+
# NOTE: Unlike Claude Code's Stop hook, sessionEnd output is IGNORED by
|
|
7
|
+
# Copilot CLI. This hook cannot block session exit or drive an orchestration
|
|
8
|
+
# loop. It is purely for cleanup and logging.
|
|
9
|
+
|
|
10
|
+
$ErrorActionPreference = "Continue"
|
|
11
|
+
|
|
12
|
+
$PluginRoot = if ($env:COPILOT_PLUGIN_DIR) { $env:COPILOT_PLUGIN_DIR } else { Split-Path -Parent $PSScriptRoot }
|
|
13
|
+
$ProxyMarkerFile = Join-Path $PluginRoot ".hooks-proxy-install-attempted"
|
|
14
|
+
|
|
15
|
+
$GlobalRoot = if ($env:BABYSITTER_GLOBAL_STATE_DIR) { $env:BABYSITTER_GLOBAL_STATE_DIR } else { Join-Path $HOME ".a5c" }
|
|
16
|
+
$LogDir = if ($env:BABYSITTER_LOG_DIR) { $env:BABYSITTER_LOG_DIR } else { Join-Path $GlobalRoot "logs" }
|
|
17
|
+
$LogFile = Join-Path $LogDir "babysitter-session-end-hook.log"
|
|
18
|
+
New-Item -ItemType Directory -Path $LogDir -Force -ErrorAction SilentlyContinue | Out-Null
|
|
19
|
+
|
|
20
|
+
function Write-Blog {
|
|
21
|
+
param([string]$Message)
|
|
22
|
+
$ts = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
|
|
23
|
+
Add-Content -Path $LogFile -Value "[INFO] $ts $Message" -ErrorAction SilentlyContinue
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
Write-Blog "Unified hook script invoked"
|
|
27
|
+
Write-Blog "PLUGIN_ROOT=$PluginRoot"
|
|
28
|
+
|
|
29
|
+
# Get required version from versions.json (used for hooks-proxy)
|
|
30
|
+
$versionsFile = Join-Path $PluginRoot "versions.json"
|
|
31
|
+
try {
|
|
32
|
+
$SdkVersion = (Get-Content $versionsFile -Raw | ConvertFrom-Json).sdkVersion
|
|
33
|
+
if (-not $SdkVersion) { $SdkVersion = "latest" }
|
|
34
|
+
} catch {
|
|
35
|
+
$SdkVersion = "latest"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# ---------------------------------------------------------------------------
|
|
39
|
+
# Hooks-proxy install (same pattern as SDK install in session-start)
|
|
40
|
+
# ---------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
function Install-HooksProxy {
|
|
43
|
+
param([string]$TargetVersion)
|
|
44
|
+
try {
|
|
45
|
+
& npm i -g "@a5c-ai/hooks-proxy-cli@$TargetVersion" --loglevel=error 2>$null
|
|
46
|
+
if ($LASTEXITCODE -eq 0) {
|
|
47
|
+
Write-Blog "Installed hooks-proxy globally ($TargetVersion)"
|
|
48
|
+
return $true
|
|
49
|
+
}
|
|
50
|
+
} catch {}
|
|
51
|
+
try {
|
|
52
|
+
$prefix = Join-Path $env:USERPROFILE ".local"
|
|
53
|
+
& npm i -g "@a5c-ai/hooks-proxy-cli@$TargetVersion" --prefix $prefix --loglevel=error 2>$null
|
|
54
|
+
if ($LASTEXITCODE -eq 0) {
|
|
55
|
+
$env:PATH = "$prefix\bin;$env:PATH"
|
|
56
|
+
Write-Blog "Installed hooks-proxy to user prefix ($TargetVersion)"
|
|
57
|
+
return $true
|
|
58
|
+
}
|
|
59
|
+
} catch {}
|
|
60
|
+
return $false
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# Resolve hooks-proxy binary
|
|
64
|
+
$Proxy = $null
|
|
65
|
+
if (Get-Command a5c-hooks-proxy -ErrorAction SilentlyContinue) {
|
|
66
|
+
$Proxy = "a5c-hooks-proxy"
|
|
67
|
+
} else {
|
|
68
|
+
$localProxy = Join-Path $env:USERPROFILE ".local\bin\a5c-hooks-proxy.exe"
|
|
69
|
+
if (Test-Path $localProxy) {
|
|
70
|
+
$Proxy = $localProxy
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# Install if not found (only attempt once per plugin version)
|
|
75
|
+
if (-not $Proxy -and -not (Test-Path $ProxyMarkerFile)) {
|
|
76
|
+
Write-Blog "hooks-proxy not found, attempting install"
|
|
77
|
+
Install-HooksProxy $SdkVersion | Out-Null
|
|
78
|
+
Set-Content -Path $ProxyMarkerFile -Value $SdkVersion -ErrorAction SilentlyContinue
|
|
79
|
+
if (Get-Command a5c-hooks-proxy -ErrorAction SilentlyContinue) {
|
|
80
|
+
$Proxy = "a5c-hooks-proxy"
|
|
81
|
+
} else {
|
|
82
|
+
$localProxy = Join-Path $env:USERPROFILE ".local\bin\a5c-hooks-proxy.exe"
|
|
83
|
+
if (Test-Path $localProxy) {
|
|
84
|
+
$Proxy = $localProxy
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# ---------------------------------------------------------------------------
|
|
90
|
+
# Capture stdin and delegate to hooks-proxy
|
|
91
|
+
# ---------------------------------------------------------------------------
|
|
92
|
+
|
|
93
|
+
$InputFile = [System.IO.Path]::GetTempFileName()
|
|
94
|
+
$input | Out-File -FilePath $InputFile -Encoding utf8
|
|
95
|
+
|
|
96
|
+
Write-Blog "Hook input received"
|
|
97
|
+
|
|
98
|
+
$stderrLog = Join-Path $LogDir "babysitter-session-end-hook-stderr.log"
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
if ($Proxy) {
|
|
102
|
+
Write-Blog "Using hooks-proxy: $Proxy"
|
|
103
|
+
Get-Content $InputFile | & $Proxy invoke --adapter copilot --handler "babysitter hook:run --harness unified --hook-type session-end --plugin-root $PluginRoot --json" --json 2>$stderrLog | Out-Null
|
|
104
|
+
} else {
|
|
105
|
+
Write-Blog "hooks-proxy not found after install, using npx fallback"
|
|
106
|
+
Get-Content $InputFile | & npx -y "@a5c-ai/hooks-proxy-cli@$SdkVersion" invoke --adapter copilot --handler "babysitter hook:run --harness unified --hook-type session-end --plugin-root $PluginRoot --json" --json 2>$stderrLog | Out-Null
|
|
107
|
+
}
|
|
108
|
+
} catch {
|
|
109
|
+
Write-Blog "Hook error: $_"
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
Write-Blog "Session end hook complete"
|
|
113
|
+
|
|
114
|
+
Remove-Item $InputFile -Force -ErrorAction SilentlyContinue
|
|
115
|
+
|
|
116
|
+
exit 0
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Unified Session End Hook for GitHub Copilot CLI
|
|
3
|
+
# Routes through hooks-proxy for all hook execution.
|
|
4
|
+
#
|
|
5
|
+
# Cleanup and logging on session exit.
|
|
6
|
+
#
|
|
7
|
+
# NOTE: Unlike Claude Code's Stop hook, sessionEnd output is IGNORED by
|
|
8
|
+
# Copilot CLI. This hook cannot block session exit or drive an orchestration
|
|
9
|
+
# loop. It is purely for cleanup and logging.
|
|
10
|
+
#
|
|
11
|
+
# Protocol:
|
|
12
|
+
# Input: JSON via stdin (session context)
|
|
13
|
+
# Output: IGNORED by Copilot CLI
|
|
14
|
+
# Exit 0: success (exit code also ignored)
|
|
15
|
+
|
|
16
|
+
set -uo pipefail
|
|
17
|
+
|
|
18
|
+
PLUGIN_ROOT="${COPILOT_PLUGIN_DIR:-$(cd "$(dirname "$0")/.." && pwd)}"
|
|
19
|
+
PROXY_MARKER_FILE="${PLUGIN_ROOT}/.hooks-proxy-install-attempted"
|
|
20
|
+
|
|
21
|
+
GLOBAL_ROOT="${BABYSITTER_GLOBAL_STATE_DIR:-$HOME/.a5c}"
|
|
22
|
+
LOG_DIR="${BABYSITTER_LOG_DIR:-${GLOBAL_ROOT}/logs}"
|
|
23
|
+
LOG_FILE="$LOG_DIR/babysitter-session-end-hook.log"
|
|
24
|
+
|
|
25
|
+
mkdir -p "$LOG_DIR" 2>/dev/null
|
|
26
|
+
|
|
27
|
+
# Get required version from versions.json (used for hooks-proxy)
|
|
28
|
+
SDK_VERSION=$(node -e "try{console.log(JSON.parse(require('fs').readFileSync('${PLUGIN_ROOT}/versions.json','utf8')).sdkVersion||'latest')}catch{console.log('latest')}" 2>/dev/null || echo "latest")
|
|
29
|
+
|
|
30
|
+
# Structured logging helper
|
|
31
|
+
blog() {
|
|
32
|
+
local msg="$1"
|
|
33
|
+
local ts
|
|
34
|
+
ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
35
|
+
echo "[INFO] $ts $msg" >> "$LOG_FILE" 2>/dev/null
|
|
36
|
+
if command -v babysitter &>/dev/null; then
|
|
37
|
+
babysitter log --type hook --label "hook:session-end" --message "$msg" --source shell-hook 2>/dev/null || true
|
|
38
|
+
fi
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
blog "Unified hook script invoked"
|
|
42
|
+
blog "PLUGIN_ROOT=$PLUGIN_ROOT"
|
|
43
|
+
|
|
44
|
+
# ---------------------------------------------------------------------------
|
|
45
|
+
# Hooks-proxy install (same pattern as SDK install in session-start)
|
|
46
|
+
# ---------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
install_hooks_proxy() {
|
|
49
|
+
local target_version="$1"
|
|
50
|
+
if npm i -g "@a5c-ai/hooks-proxy-cli@${target_version}" --loglevel=error 2>/dev/null; then
|
|
51
|
+
blog "Installed hooks-proxy globally (${target_version})"
|
|
52
|
+
return 0
|
|
53
|
+
else
|
|
54
|
+
if npm i -g "@a5c-ai/hooks-proxy-cli@${target_version}" --prefix "$HOME/.local" --loglevel=error 2>/dev/null; then
|
|
55
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
56
|
+
blog "Installed hooks-proxy to user prefix (${target_version})"
|
|
57
|
+
return 0
|
|
58
|
+
fi
|
|
59
|
+
fi
|
|
60
|
+
return 1
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# Resolve hooks-proxy binary
|
|
64
|
+
PROXY=""
|
|
65
|
+
if command -v a5c-hooks-proxy &>/dev/null; then
|
|
66
|
+
PROXY="a5c-hooks-proxy"
|
|
67
|
+
elif [ -f "$HOME/.local/bin/a5c-hooks-proxy" ]; then
|
|
68
|
+
PROXY="$HOME/.local/bin/a5c-hooks-proxy"
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# Install if not found (only attempt once per plugin version)
|
|
72
|
+
if [ -z "$PROXY" ] && [ ! -f "$PROXY_MARKER_FILE" ]; then
|
|
73
|
+
blog "hooks-proxy not found, attempting install"
|
|
74
|
+
install_hooks_proxy "$SDK_VERSION"
|
|
75
|
+
echo "$SDK_VERSION" > "$PROXY_MARKER_FILE" 2>/dev/null
|
|
76
|
+
if command -v a5c-hooks-proxy &>/dev/null; then
|
|
77
|
+
PROXY="a5c-hooks-proxy"
|
|
78
|
+
elif [ -f "$HOME/.local/bin/a5c-hooks-proxy" ]; then
|
|
79
|
+
PROXY="$HOME/.local/bin/a5c-hooks-proxy"
|
|
80
|
+
fi
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
# npx fallback if still not found
|
|
84
|
+
if [ -z "$PROXY" ]; then
|
|
85
|
+
blog "hooks-proxy not found after install, using npx fallback"
|
|
86
|
+
PROXY="npx -y @a5c-ai/hooks-proxy-cli@${SDK_VERSION} "
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
# ---------------------------------------------------------------------------
|
|
90
|
+
# Capture stdin and delegate to hooks-proxy
|
|
91
|
+
# ---------------------------------------------------------------------------
|
|
92
|
+
|
|
93
|
+
INPUT_FILE=$(mktemp 2>/dev/null || echo "/tmp/hook-session-end-$$.json")
|
|
94
|
+
cat > "$INPUT_FILE"
|
|
95
|
+
|
|
96
|
+
blog "Hook input received ($(wc -c < "$INPUT_FILE") bytes)"
|
|
97
|
+
|
|
98
|
+
STDERR_LOG="$LOG_DIR/babysitter-session-end-hook-stderr.log"
|
|
99
|
+
|
|
100
|
+
# Run cleanup/logging via hooks-proxy; output is ignored by Copilot CLI
|
|
101
|
+
blog "Using hooks-proxy: $PROXY"
|
|
102
|
+
$PROXY invoke \
|
|
103
|
+
--adapter copilot \
|
|
104
|
+
--handler "babysitter hook:run --harness unified --hook-type session-end --plugin-root ${PLUGIN_ROOT} --json" \
|
|
105
|
+
--json \
|
|
106
|
+
< "$INPUT_FILE" 2>"$STDERR_LOG" || true
|
|
107
|
+
|
|
108
|
+
blog "Session end hook complete"
|
|
109
|
+
|
|
110
|
+
rm -f "$INPUT_FILE" 2>/dev/null
|
|
111
|
+
|
|
112
|
+
exit 0
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# Unified Session Start Hook for GitHub Copilot CLI (PowerShell)
|
|
2
|
+
# Routes through hooks-proxy for all hook execution.
|
|
3
|
+
#
|
|
4
|
+
# Ensures the babysitter SDK CLI and hooks-proxy are installed (from versions.json
|
|
5
|
+
# sdkVersion), then delegates to the TypeScript handler via hooks-proxy.
|
|
6
|
+
#
|
|
7
|
+
# Protocol:
|
|
8
|
+
# Input: JSON via stdin (contains session_id, cwd, etc.)
|
|
9
|
+
# Output: JSON via stdout ({} on success)
|
|
10
|
+
# Stderr: debug/log output only
|
|
11
|
+
# Exit 0: success
|
|
12
|
+
# Exit 2: block (fatal error)
|
|
13
|
+
|
|
14
|
+
$ErrorActionPreference = "Stop"
|
|
15
|
+
|
|
16
|
+
$PluginRoot = if ($env:COPILOT_PLUGIN_DIR) { $env:COPILOT_PLUGIN_DIR } else { Split-Path -Parent $PSScriptRoot }
|
|
17
|
+
$SdkMarkerFile = Join-Path $PluginRoot ".babysitter-install-attempted"
|
|
18
|
+
$ProxyMarkerFile = Join-Path $PluginRoot ".hooks-proxy-install-attempted"
|
|
19
|
+
|
|
20
|
+
$GlobalRoot = if ($env:BABYSITTER_GLOBAL_STATE_DIR) { $env:BABYSITTER_GLOBAL_STATE_DIR } else { Join-Path $HOME ".a5c" }
|
|
21
|
+
$LogDir = if ($env:BABYSITTER_LOG_DIR) { $env:BABYSITTER_LOG_DIR } else { Join-Path $GlobalRoot "logs" }
|
|
22
|
+
$LogFile = Join-Path $LogDir "babysitter-session-start-hook.log"
|
|
23
|
+
New-Item -ItemType Directory -Path $LogDir -Force -ErrorAction SilentlyContinue | Out-Null
|
|
24
|
+
|
|
25
|
+
function Write-Blog {
|
|
26
|
+
param([string]$Message)
|
|
27
|
+
$ts = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
|
|
28
|
+
Add-Content -Path $LogFile -Value "[INFO] $ts $Message" -ErrorAction SilentlyContinue
|
|
29
|
+
if (Get-Command babysitter -ErrorAction SilentlyContinue) {
|
|
30
|
+
& babysitter log --type hook --label "hook:session-start" --message $Message --source shell-hook 2>$null
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Write-Blog "Unified hook script invoked"
|
|
35
|
+
Write-Blog "PLUGIN_ROOT=$PluginRoot"
|
|
36
|
+
|
|
37
|
+
# Get required SDK version from versions.json (used for both SDK and hooks-proxy)
|
|
38
|
+
$versionsFile = Join-Path $PluginRoot "versions.json"
|
|
39
|
+
try {
|
|
40
|
+
$SdkVersion = (Get-Content $versionsFile -Raw | ConvertFrom-Json).sdkVersion
|
|
41
|
+
if (-not $SdkVersion) { $SdkVersion = "latest" }
|
|
42
|
+
} catch {
|
|
43
|
+
$SdkVersion = "latest"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
# ---------------------------------------------------------------------------
|
|
47
|
+
# SDK install/upgrade
|
|
48
|
+
# ---------------------------------------------------------------------------
|
|
49
|
+
|
|
50
|
+
function Install-Sdk {
|
|
51
|
+
param([string]$TargetVersion)
|
|
52
|
+
try {
|
|
53
|
+
& npm i -g "@a5c-ai/babysitter-sdk@$TargetVersion" --loglevel=error 2>$null
|
|
54
|
+
if ($LASTEXITCODE -eq 0) {
|
|
55
|
+
Write-Blog "Installed SDK globally ($TargetVersion)"
|
|
56
|
+
return $true
|
|
57
|
+
}
|
|
58
|
+
} catch {}
|
|
59
|
+
try {
|
|
60
|
+
$prefix = Join-Path $env:USERPROFILE ".local"
|
|
61
|
+
& npm i -g "@a5c-ai/babysitter-sdk@$TargetVersion" --prefix $prefix --loglevel=error 2>$null
|
|
62
|
+
if ($LASTEXITCODE -eq 0) {
|
|
63
|
+
$env:PATH = "$prefix\bin;$env:PATH"
|
|
64
|
+
Write-Blog "Installed SDK to user prefix ($TargetVersion)"
|
|
65
|
+
return $true
|
|
66
|
+
}
|
|
67
|
+
} catch {}
|
|
68
|
+
return $false
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
$NeedsSdkInstall = $false
|
|
72
|
+
if (Get-Command babysitter -ErrorAction SilentlyContinue) {
|
|
73
|
+
$CurrentVersion = & babysitter --version 2>$null
|
|
74
|
+
if ($CurrentVersion -ne $SdkVersion) {
|
|
75
|
+
Write-Blog "SDK version mismatch: installed=$CurrentVersion, required=$SdkVersion"
|
|
76
|
+
$NeedsSdkInstall = $true
|
|
77
|
+
} else {
|
|
78
|
+
Write-Blog "SDK version OK: $CurrentVersion"
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
Write-Blog "SDK CLI not found, will install"
|
|
82
|
+
$NeedsSdkInstall = $true
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if ($NeedsSdkInstall -and -not (Test-Path $SdkMarkerFile)) {
|
|
86
|
+
Install-Sdk $SdkVersion | Out-Null
|
|
87
|
+
Set-Content -Path $SdkMarkerFile -Value $SdkVersion -ErrorAction SilentlyContinue
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (-not (Get-Command babysitter -ErrorAction SilentlyContinue)) {
|
|
91
|
+
Write-Blog "CLI not found after install, using npx fallback"
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# ---------------------------------------------------------------------------
|
|
95
|
+
# Hooks-proxy install/upgrade (same pattern as SDK)
|
|
96
|
+
# ---------------------------------------------------------------------------
|
|
97
|
+
|
|
98
|
+
function Install-HooksProxy {
|
|
99
|
+
param([string]$TargetVersion)
|
|
100
|
+
try {
|
|
101
|
+
& npm i -g "@a5c-ai/hooks-proxy-cli@$TargetVersion" --loglevel=error 2>$null
|
|
102
|
+
if ($LASTEXITCODE -eq 0) {
|
|
103
|
+
Write-Blog "Installed hooks-proxy globally ($TargetVersion)"
|
|
104
|
+
return $true
|
|
105
|
+
}
|
|
106
|
+
} catch {}
|
|
107
|
+
try {
|
|
108
|
+
$prefix = Join-Path $env:USERPROFILE ".local"
|
|
109
|
+
& npm i -g "@a5c-ai/hooks-proxy-cli@$TargetVersion" --prefix $prefix --loglevel=error 2>$null
|
|
110
|
+
if ($LASTEXITCODE -eq 0) {
|
|
111
|
+
$env:PATH = "$prefix\bin;$env:PATH"
|
|
112
|
+
Write-Blog "Installed hooks-proxy to user prefix ($TargetVersion)"
|
|
113
|
+
return $true
|
|
114
|
+
}
|
|
115
|
+
} catch {}
|
|
116
|
+
return $false
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
$NeedsProxyInstall = $false
|
|
120
|
+
$Proxy = $null
|
|
121
|
+
if (Get-Command a5c-hooks-proxy -ErrorAction SilentlyContinue) {
|
|
122
|
+
$ProxyVersion = & a5c-hooks-proxy --version 2>$null
|
|
123
|
+
if ($ProxyVersion -ne $SdkVersion) {
|
|
124
|
+
Write-Blog "hooks-proxy version mismatch: installed=$ProxyVersion, required=$SdkVersion"
|
|
125
|
+
$NeedsProxyInstall = $true
|
|
126
|
+
} else {
|
|
127
|
+
Write-Blog "hooks-proxy version OK: $ProxyVersion"
|
|
128
|
+
$Proxy = "a5c-hooks-proxy"
|
|
129
|
+
}
|
|
130
|
+
} else {
|
|
131
|
+
$localProxy = Join-Path $env:USERPROFILE ".local\bin\a5c-hooks-proxy.exe"
|
|
132
|
+
if (Test-Path $localProxy) {
|
|
133
|
+
$ProxyVersion = & $localProxy --version 2>$null
|
|
134
|
+
if ($ProxyVersion -ne $SdkVersion) {
|
|
135
|
+
Write-Blog "hooks-proxy version mismatch: installed=$ProxyVersion, required=$SdkVersion"
|
|
136
|
+
$NeedsProxyInstall = $true
|
|
137
|
+
} else {
|
|
138
|
+
Write-Blog "hooks-proxy version OK: $ProxyVersion"
|
|
139
|
+
$Proxy = $localProxy
|
|
140
|
+
}
|
|
141
|
+
} else {
|
|
142
|
+
Write-Blog "hooks-proxy not found, will install"
|
|
143
|
+
$NeedsProxyInstall = $true
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if ($NeedsProxyInstall -and -not (Test-Path $ProxyMarkerFile)) {
|
|
148
|
+
Install-HooksProxy $SdkVersion | Out-Null
|
|
149
|
+
Set-Content -Path $ProxyMarkerFile -Value $SdkVersion -ErrorAction SilentlyContinue
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
# Re-resolve after potential install
|
|
153
|
+
if (-not $Proxy) {
|
|
154
|
+
if (Get-Command a5c-hooks-proxy -ErrorAction SilentlyContinue) {
|
|
155
|
+
$Proxy = "a5c-hooks-proxy"
|
|
156
|
+
} else {
|
|
157
|
+
$localProxy = Join-Path $env:USERPROFILE ".local\bin\a5c-hooks-proxy.exe"
|
|
158
|
+
if (Test-Path $localProxy) {
|
|
159
|
+
$Proxy = $localProxy
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
# ---------------------------------------------------------------------------
|
|
165
|
+
# Capture stdin and delegate to hooks-proxy
|
|
166
|
+
# ---------------------------------------------------------------------------
|
|
167
|
+
|
|
168
|
+
$InputFile = [System.IO.Path]::GetTempFileName()
|
|
169
|
+
$input | Out-File -FilePath $InputFile -Encoding utf8
|
|
170
|
+
|
|
171
|
+
Write-Blog "Hook input received"
|
|
172
|
+
|
|
173
|
+
$stderrLog = Join-Path $LogDir "babysitter-session-start-hook-stderr.log"
|
|
174
|
+
|
|
175
|
+
if ($Proxy) {
|
|
176
|
+
Write-Blog "Using hooks-proxy: $Proxy"
|
|
177
|
+
$Result = Get-Content $InputFile | & $Proxy invoke --adapter copilot --handler "babysitter hook:run --harness unified --hook-type session-start --plugin-root $PluginRoot --json" --json 2>$stderrLog
|
|
178
|
+
$ExitCode = $LASTEXITCODE
|
|
179
|
+
} else {
|
|
180
|
+
Write-Blog "hooks-proxy not found after install, using npx fallback"
|
|
181
|
+
$Result = Get-Content $InputFile | & npx -y "@a5c-ai/hooks-proxy-cli@$SdkVersion" invoke --adapter copilot --handler "babysitter hook:run --harness unified --hook-type session-start --plugin-root $PluginRoot --json" --json 2>$stderrLog
|
|
182
|
+
$ExitCode = $LASTEXITCODE
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
Write-Blog "CLI exit code=$ExitCode"
|
|
186
|
+
|
|
187
|
+
Remove-Item $InputFile -Force -ErrorAction SilentlyContinue
|
|
188
|
+
Write-Output $Result
|
|
189
|
+
exit $ExitCode
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Unified Session Start Hook for GitHub Copilot CLI
|
|
3
|
+
# Routes through hooks-proxy for all hook execution.
|
|
4
|
+
#
|
|
5
|
+
# Ensures the babysitter SDK CLI and hooks-proxy are installed (from versions.json
|
|
6
|
+
# sdkVersion), then delegates to the TypeScript handler via hooks-proxy.
|
|
7
|
+
#
|
|
8
|
+
# Protocol:
|
|
9
|
+
# Input: JSON via stdin (contains session_id, cwd, etc.)
|
|
10
|
+
# Output: JSON via stdout ({} on success)
|
|
11
|
+
# Stderr: debug/log output only
|
|
12
|
+
# Exit 0: success
|
|
13
|
+
# Exit 2: block (fatal error)
|
|
14
|
+
|
|
15
|
+
set -euo pipefail
|
|
16
|
+
|
|
17
|
+
PLUGIN_ROOT="${COPILOT_PLUGIN_DIR:-$(cd "$(dirname "$0")/.." && pwd)}"
|
|
18
|
+
SDK_MARKER_FILE="${PLUGIN_ROOT}/.babysitter-install-attempted"
|
|
19
|
+
PROXY_MARKER_FILE="${PLUGIN_ROOT}/.hooks-proxy-install-attempted"
|
|
20
|
+
|
|
21
|
+
GLOBAL_ROOT="${BABYSITTER_GLOBAL_STATE_DIR:-$HOME/.a5c}"
|
|
22
|
+
LOG_DIR="${BABYSITTER_LOG_DIR:-${GLOBAL_ROOT}/logs}"
|
|
23
|
+
LOG_FILE="$LOG_DIR/babysitter-session-start-hook.log"
|
|
24
|
+
mkdir -p "$LOG_DIR" 2>/dev/null
|
|
25
|
+
|
|
26
|
+
# Structured logging helper -- writes to both local and global log
|
|
27
|
+
blog() {
|
|
28
|
+
local msg="$1"
|
|
29
|
+
local ts
|
|
30
|
+
ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
31
|
+
echo "[INFO] $ts $msg" >> "$LOG_FILE" 2>/dev/null
|
|
32
|
+
# Use CLI structured logging when available; fall back to direct append
|
|
33
|
+
if command -v babysitter &>/dev/null; then
|
|
34
|
+
babysitter log --type hook --label "hook:session-start" --message "$msg" --source shell-hook 2>/dev/null || true
|
|
35
|
+
fi
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
blog "Unified hook script invoked"
|
|
39
|
+
blog "PLUGIN_ROOT=$PLUGIN_ROOT"
|
|
40
|
+
|
|
41
|
+
# Get required SDK version from versions.json (used for both SDK and hooks-proxy)
|
|
42
|
+
SDK_VERSION=$(node -e "try{console.log(JSON.parse(require('fs').readFileSync('${PLUGIN_ROOT}/versions.json','utf8')).sdkVersion||'latest')}catch{console.log('latest')}" 2>/dev/null || echo "latest")
|
|
43
|
+
|
|
44
|
+
# ---------------------------------------------------------------------------
|
|
45
|
+
# SDK install/upgrade
|
|
46
|
+
# ---------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
install_sdk() {
|
|
49
|
+
local target_version="$1"
|
|
50
|
+
# Try global install first, fall back to user-local if permissions fail
|
|
51
|
+
if npm i -g "@a5c-ai/babysitter-sdk@${target_version}" --loglevel=error 2>/dev/null; then
|
|
52
|
+
blog "Installed SDK globally (${target_version})"
|
|
53
|
+
return 0
|
|
54
|
+
else
|
|
55
|
+
# Global install failed (permissions) -- try user-local prefix
|
|
56
|
+
if npm i -g "@a5c-ai/babysitter-sdk@${target_version}" --prefix "$HOME/.local" --loglevel=error 2>/dev/null; then
|
|
57
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
58
|
+
blog "Installed SDK to user prefix (${target_version})"
|
|
59
|
+
return 0
|
|
60
|
+
fi
|
|
61
|
+
fi
|
|
62
|
+
return 1
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
NEEDS_SDK_INSTALL=false
|
|
66
|
+
if command -v babysitter &>/dev/null; then
|
|
67
|
+
CURRENT_VERSION=$(babysitter --version 2>/dev/null || echo "unknown")
|
|
68
|
+
if [ "$CURRENT_VERSION" != "$SDK_VERSION" ]; then
|
|
69
|
+
blog "SDK version mismatch: installed=${CURRENT_VERSION}, required=${SDK_VERSION}"
|
|
70
|
+
NEEDS_SDK_INSTALL=true
|
|
71
|
+
else
|
|
72
|
+
blog "SDK version OK: ${CURRENT_VERSION}"
|
|
73
|
+
fi
|
|
74
|
+
else
|
|
75
|
+
blog "SDK CLI not found, will install"
|
|
76
|
+
NEEDS_SDK_INSTALL=true
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
if [ "$NEEDS_SDK_INSTALL" = true ] && [ ! -f "$SDK_MARKER_FILE" ]; then
|
|
80
|
+
install_sdk "$SDK_VERSION"
|
|
81
|
+
echo "$SDK_VERSION" > "$SDK_MARKER_FILE" 2>/dev/null
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
if ! command -v babysitter &>/dev/null; then
|
|
85
|
+
blog "CLI not found after install, using npx fallback"
|
|
86
|
+
babysitter() { npx -y "@a5c-ai/babysitter-sdk@${SDK_VERSION}" "$@"; }
|
|
87
|
+
export -f babysitter
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
# ---------------------------------------------------------------------------
|
|
91
|
+
# Hooks-proxy install/upgrade (same pattern as SDK)
|
|
92
|
+
# ---------------------------------------------------------------------------
|
|
93
|
+
|
|
94
|
+
install_hooks_proxy() {
|
|
95
|
+
local target_version="$1"
|
|
96
|
+
if npm i -g "@a5c-ai/hooks-proxy-cli@${target_version}" --loglevel=error 2>/dev/null; then
|
|
97
|
+
blog "Installed hooks-proxy globally (${target_version})"
|
|
98
|
+
return 0
|
|
99
|
+
else
|
|
100
|
+
if npm i -g "@a5c-ai/hooks-proxy-cli@${target_version}" --prefix "$HOME/.local" --loglevel=error 2>/dev/null; then
|
|
101
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
102
|
+
blog "Installed hooks-proxy to user prefix (${target_version})"
|
|
103
|
+
return 0
|
|
104
|
+
fi
|
|
105
|
+
fi
|
|
106
|
+
return 1
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
NEEDS_PROXY_INSTALL=false
|
|
110
|
+
if command -v a5c-hooks-proxy &>/dev/null; then
|
|
111
|
+
PROXY_VERSION=$(a5c-hooks-proxy --version 2>/dev/null || echo "unknown")
|
|
112
|
+
if [ "$PROXY_VERSION" != "$SDK_VERSION" ]; then
|
|
113
|
+
blog "hooks-proxy version mismatch: installed=${PROXY_VERSION}, required=${SDK_VERSION}"
|
|
114
|
+
NEEDS_PROXY_INSTALL=true
|
|
115
|
+
else
|
|
116
|
+
blog "hooks-proxy version OK: ${PROXY_VERSION}"
|
|
117
|
+
fi
|
|
118
|
+
elif [ -f "$HOME/.local/bin/a5c-hooks-proxy" ]; then
|
|
119
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
120
|
+
PROXY_VERSION=$(a5c-hooks-proxy --version 2>/dev/null || echo "unknown")
|
|
121
|
+
if [ "$PROXY_VERSION" != "$SDK_VERSION" ]; then
|
|
122
|
+
blog "hooks-proxy version mismatch: installed=${PROXY_VERSION}, required=${SDK_VERSION}"
|
|
123
|
+
NEEDS_PROXY_INSTALL=true
|
|
124
|
+
else
|
|
125
|
+
blog "hooks-proxy version OK: ${PROXY_VERSION}"
|
|
126
|
+
fi
|
|
127
|
+
else
|
|
128
|
+
blog "hooks-proxy not found, will install"
|
|
129
|
+
NEEDS_PROXY_INSTALL=true
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
if [ "$NEEDS_PROXY_INSTALL" = true ] && [ ! -f "$PROXY_MARKER_FILE" ]; then
|
|
133
|
+
install_hooks_proxy "$SDK_VERSION"
|
|
134
|
+
echo "$SDK_VERSION" > "$PROXY_MARKER_FILE" 2>/dev/null
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
# Resolve hooks-proxy binary (npx fallback if still not found)
|
|
138
|
+
PROXY=""
|
|
139
|
+
if command -v a5c-hooks-proxy &>/dev/null; then
|
|
140
|
+
PROXY="a5c-hooks-proxy"
|
|
141
|
+
elif [ -f "$HOME/.local/bin/a5c-hooks-proxy" ]; then
|
|
142
|
+
PROXY="$HOME/.local/bin/a5c-hooks-proxy"
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
if [ -z "$PROXY" ]; then
|
|
146
|
+
blog "hooks-proxy not found after install, using npx fallback"
|
|
147
|
+
PROXY="npx -y @a5c-ai/hooks-proxy-cli@${SDK_VERSION} "
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
# ---------------------------------------------------------------------------
|
|
151
|
+
# Capture stdin and delegate to hooks-proxy
|
|
152
|
+
# ---------------------------------------------------------------------------
|
|
153
|
+
|
|
154
|
+
INPUT_FILE=$(mktemp 2>/dev/null || echo "/tmp/hook-session-start-$$.json")
|
|
155
|
+
cat > "$INPUT_FILE"
|
|
156
|
+
|
|
157
|
+
blog "Hook input received ($(wc -c < "$INPUT_FILE") bytes)"
|
|
158
|
+
|
|
159
|
+
STDERR_LOG="$LOG_DIR/babysitter-session-start-hook-stderr.log"
|
|
160
|
+
|
|
161
|
+
blog "Using hooks-proxy: $PROXY"
|
|
162
|
+
RESULT=$($PROXY invoke \
|
|
163
|
+
--adapter copilot \
|
|
164
|
+
--handler "babysitter hook:run --harness unified --hook-type session-start --plugin-root ${PLUGIN_ROOT} --json" \
|
|
165
|
+
--json \
|
|
166
|
+
< "$INPUT_FILE" 2>"$STDERR_LOG")
|
|
167
|
+
EXIT_CODE=$?
|
|
168
|
+
|
|
169
|
+
blog "CLI exit code=$EXIT_CODE"
|
|
170
|
+
|
|
171
|
+
rm -f "$INPUT_FILE" 2>/dev/null
|
|
172
|
+
printf '%s\n' "$RESULT"
|
|
173
|
+
exit $EXIT_CODE
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Unified userPromptSubmitted Hook for GitHub Copilot CLI (PowerShell)
|
|
2
|
+
# Routes through hooks-proxy for all hook execution.
|
|
3
|
+
#
|
|
4
|
+
# Applies density-filter compression to long user prompts.
|
|
5
|
+
#
|
|
6
|
+
# NOTE: Output from this hook is IGNORED by Copilot CLI.
|
|
7
|
+
# This hook is for logging and side-effects only.
|
|
8
|
+
|
|
9
|
+
$ErrorActionPreference = "Continue"
|
|
10
|
+
|
|
11
|
+
$PluginRoot = if ($env:COPILOT_PLUGIN_DIR) { $env:COPILOT_PLUGIN_DIR } else { Split-Path -Parent $PSScriptRoot }
|
|
12
|
+
$ProxyMarkerFile = Join-Path $PluginRoot ".hooks-proxy-install-attempted"
|
|
13
|
+
|
|
14
|
+
$GlobalRoot = if ($env:BABYSITTER_GLOBAL_STATE_DIR) { $env:BABYSITTER_GLOBAL_STATE_DIR } else { Join-Path $HOME ".a5c" }
|
|
15
|
+
$LogDir = if ($env:BABYSITTER_LOG_DIR) { $env:BABYSITTER_LOG_DIR } else { Join-Path $GlobalRoot "logs" }
|
|
16
|
+
New-Item -ItemType Directory -Path $LogDir -Force -ErrorAction SilentlyContinue | Out-Null
|
|
17
|
+
|
|
18
|
+
# Get required version from versions.json (used for hooks-proxy)
|
|
19
|
+
$versionsFile = Join-Path $PluginRoot "versions.json"
|
|
20
|
+
try {
|
|
21
|
+
$SdkVersion = (Get-Content $versionsFile -Raw | ConvertFrom-Json).sdkVersion
|
|
22
|
+
if (-not $SdkVersion) { $SdkVersion = "latest" }
|
|
23
|
+
} catch {
|
|
24
|
+
$SdkVersion = "latest"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
# ---------------------------------------------------------------------------
|
|
28
|
+
# Hooks-proxy install (same pattern as SDK install in session-start)
|
|
29
|
+
# ---------------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
function Install-HooksProxy {
|
|
32
|
+
param([string]$TargetVersion)
|
|
33
|
+
try {
|
|
34
|
+
& npm i -g "@a5c-ai/hooks-proxy-cli@$TargetVersion" --loglevel=error 2>$null
|
|
35
|
+
if ($LASTEXITCODE -eq 0) { return $true }
|
|
36
|
+
} catch {}
|
|
37
|
+
try {
|
|
38
|
+
$prefix = Join-Path $env:USERPROFILE ".local"
|
|
39
|
+
& npm i -g "@a5c-ai/hooks-proxy-cli@$TargetVersion" --prefix $prefix --loglevel=error 2>$null
|
|
40
|
+
if ($LASTEXITCODE -eq 0) {
|
|
41
|
+
$env:PATH = "$prefix\bin;$env:PATH"
|
|
42
|
+
return $true
|
|
43
|
+
}
|
|
44
|
+
} catch {}
|
|
45
|
+
return $false
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# Resolve hooks-proxy binary
|
|
49
|
+
$Proxy = $null
|
|
50
|
+
if (Get-Command a5c-hooks-proxy -ErrorAction SilentlyContinue) {
|
|
51
|
+
$Proxy = "a5c-hooks-proxy"
|
|
52
|
+
} else {
|
|
53
|
+
$localProxy = Join-Path $env:USERPROFILE ".local\bin\a5c-hooks-proxy.exe"
|
|
54
|
+
if (Test-Path $localProxy) {
|
|
55
|
+
$Proxy = $localProxy
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
# Install if not found (only attempt once per plugin version)
|
|
60
|
+
if (-not $Proxy -and -not (Test-Path $ProxyMarkerFile)) {
|
|
61
|
+
Install-HooksProxy $SdkVersion | Out-Null
|
|
62
|
+
Set-Content -Path $ProxyMarkerFile -Value $SdkVersion -ErrorAction SilentlyContinue
|
|
63
|
+
if (Get-Command a5c-hooks-proxy -ErrorAction SilentlyContinue) {
|
|
64
|
+
$Proxy = "a5c-hooks-proxy"
|
|
65
|
+
} else {
|
|
66
|
+
$localProxy = Join-Path $env:USERPROFILE ".local\bin\a5c-hooks-proxy.exe"
|
|
67
|
+
if (Test-Path $localProxy) {
|
|
68
|
+
$Proxy = $localProxy
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
# ---------------------------------------------------------------------------
|
|
74
|
+
# Capture stdin and delegate to hooks-proxy
|
|
75
|
+
# ---------------------------------------------------------------------------
|
|
76
|
+
|
|
77
|
+
$InputFile = [System.IO.Path]::GetTempFileName()
|
|
78
|
+
$input | Out-File -FilePath $InputFile -Encoding utf8
|
|
79
|
+
|
|
80
|
+
$stderrLog = Join-Path $LogDir "babysitter-user-prompt-submitted-hook-stderr.log"
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
if ($Proxy) {
|
|
84
|
+
Get-Content $InputFile | & $Proxy invoke --adapter copilot --handler "babysitter hook:run --harness unified --hook-type user-prompt-submitted --json" --json 2>$stderrLog | Out-Null
|
|
85
|
+
} else {
|
|
86
|
+
Get-Content $InputFile | & npx -y "@a5c-ai/hooks-proxy-cli@$SdkVersion" invoke --adapter copilot --handler "babysitter hook:run --harness unified --hook-type user-prompt-submitted --json" --json 2>$stderrLog | Out-Null
|
|
87
|
+
}
|
|
88
|
+
} catch {}
|
|
89
|
+
|
|
90
|
+
Remove-Item $InputFile -Force -ErrorAction SilentlyContinue
|
|
91
|
+
|
|
92
|
+
exit 0
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Unified userPromptSubmitted Hook for GitHub Copilot CLI
|
|
3
|
+
# Routes through hooks-proxy for all hook execution.
|
|
4
|
+
#
|
|
5
|
+
# Applies density-filter compression to long user prompts.
|
|
6
|
+
# Delegates to SDK CLI: babysitter hook:run --hook-type user-prompt-submitted
|
|
7
|
+
#
|
|
8
|
+
# NOTE: Output from this hook is IGNORED by Copilot CLI.
|
|
9
|
+
# This hook is for logging and side-effects only.
|
|
10
|
+
|
|
11
|
+
PLUGIN_ROOT="${COPILOT_PLUGIN_DIR:-$(cd "$(dirname "$0")/.." && pwd)}"
|
|
12
|
+
PROXY_MARKER_FILE="${PLUGIN_ROOT}/.hooks-proxy-install-attempted"
|
|
13
|
+
|
|
14
|
+
GLOBAL_ROOT="${BABYSITTER_GLOBAL_STATE_DIR:-$HOME/.a5c}"
|
|
15
|
+
LOG_DIR="${BABYSITTER_LOG_DIR:-${GLOBAL_ROOT}/logs}"
|
|
16
|
+
mkdir -p "$LOG_DIR" 2>/dev/null
|
|
17
|
+
|
|
18
|
+
# Get required version from versions.json (used for hooks-proxy)
|
|
19
|
+
SDK_VERSION=$(node -e "try{console.log(JSON.parse(require('fs').readFileSync('${PLUGIN_ROOT}/versions.json','utf8')).sdkVersion||'latest')}catch{console.log('latest')}" 2>/dev/null || echo "latest")
|
|
20
|
+
|
|
21
|
+
# ---------------------------------------------------------------------------
|
|
22
|
+
# Hooks-proxy install (same pattern as SDK install in session-start)
|
|
23
|
+
# ---------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
install_hooks_proxy() {
|
|
26
|
+
local target_version="$1"
|
|
27
|
+
if npm i -g "@a5c-ai/hooks-proxy-cli@${target_version}" --loglevel=error 2>/dev/null; then
|
|
28
|
+
return 0
|
|
29
|
+
else
|
|
30
|
+
if npm i -g "@a5c-ai/hooks-proxy-cli@${target_version}" --prefix "$HOME/.local" --loglevel=error 2>/dev/null; then
|
|
31
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
32
|
+
return 0
|
|
33
|
+
fi
|
|
34
|
+
fi
|
|
35
|
+
return 1
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Resolve hooks-proxy binary
|
|
39
|
+
PROXY=""
|
|
40
|
+
if command -v a5c-hooks-proxy &>/dev/null; then
|
|
41
|
+
PROXY="a5c-hooks-proxy"
|
|
42
|
+
elif [ -f "$HOME/.local/bin/a5c-hooks-proxy" ]; then
|
|
43
|
+
PROXY="$HOME/.local/bin/a5c-hooks-proxy"
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
# Install if not found (only attempt once per plugin version)
|
|
47
|
+
if [ -z "$PROXY" ] && [ ! -f "$PROXY_MARKER_FILE" ]; then
|
|
48
|
+
install_hooks_proxy "$SDK_VERSION"
|
|
49
|
+
echo "$SDK_VERSION" > "$PROXY_MARKER_FILE" 2>/dev/null
|
|
50
|
+
if command -v a5c-hooks-proxy &>/dev/null; then
|
|
51
|
+
PROXY="a5c-hooks-proxy"
|
|
52
|
+
elif [ -f "$HOME/.local/bin/a5c-hooks-proxy" ]; then
|
|
53
|
+
PROXY="$HOME/.local/bin/a5c-hooks-proxy"
|
|
54
|
+
fi
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# npx fallback if still not found
|
|
58
|
+
if [ -z "$PROXY" ]; then
|
|
59
|
+
PROXY="npx -y @a5c-ai/hooks-proxy-cli@${SDK_VERSION} "
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# ---------------------------------------------------------------------------
|
|
63
|
+
# Capture stdin and delegate to hooks-proxy
|
|
64
|
+
# ---------------------------------------------------------------------------
|
|
65
|
+
|
|
66
|
+
INPUT_FILE=$(mktemp 2>/dev/null || echo "/tmp/hook-user-prompt-submitted-$$.json")
|
|
67
|
+
cat > "$INPUT_FILE"
|
|
68
|
+
|
|
69
|
+
if command -v babysitter &>/dev/null; then
|
|
70
|
+
babysitter log --type hook --label "hook:user-prompt-submitted" --message "Unified hook invoked" --source shell-hook 2>/dev/null || true
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
STDERR_LOG="$LOG_DIR/babysitter-user-prompt-submitted-hook-stderr.log"
|
|
74
|
+
|
|
75
|
+
$PROXY invoke \
|
|
76
|
+
--adapter copilot \
|
|
77
|
+
--handler "babysitter hook:run --harness unified --hook-type user-prompt-submitted --json" \
|
|
78
|
+
--json \
|
|
79
|
+
< "$INPUT_FILE" 2>"$STDERR_LOG" || true
|
|
80
|
+
|
|
81
|
+
if command -v babysitter &>/dev/null; then
|
|
82
|
+
babysitter log --type hook --label "hook:user-prompt-submitted" --message "Hook complete" --source shell-hook 2>/dev/null || true
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
rm -f "$INPUT_FILE" 2>/dev/null
|
|
86
|
+
|
|
87
|
+
exit 0
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "NOT ACTIVE — Alternative hook registration using per-hook unified scripts with hooks-proxy support. To activate, update the harness plugin configuration to reference these scripts.",
|
|
3
|
+
"hooks": {
|
|
4
|
+
"sessionStart": [
|
|
5
|
+
{
|
|
6
|
+
"type": "command",
|
|
7
|
+
"bash": "bash \"./hooks/babysitter-proxied-session-start.sh\"",
|
|
8
|
+
"powershell": "powershell -NoProfile -ExecutionPolicy Bypass -File \"./hooks/babysitter-proxied-session-start.ps1\"",
|
|
9
|
+
"timeoutSec": 30
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"sessionEnd": [
|
|
13
|
+
{
|
|
14
|
+
"type": "command",
|
|
15
|
+
"bash": "bash \"./hooks/babysitter-proxied-session-end.sh\"",
|
|
16
|
+
"powershell": "powershell -NoProfile -ExecutionPolicy Bypass -File \"./hooks/babysitter-proxied-session-end.ps1\"",
|
|
17
|
+
"timeoutSec": 30
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"userPromptSubmitted": [
|
|
21
|
+
{
|
|
22
|
+
"type": "command",
|
|
23
|
+
"bash": "bash \"./hooks/babysitter-proxied-user-prompt-submitted.sh\"",
|
|
24
|
+
"powershell": "powershell -NoProfile -ExecutionPolicy Bypass -File \"./hooks/babysitter-proxied-user-prompt-submitted.ps1\"",
|
|
25
|
+
"timeoutSec": 15
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
}
|
package/hooks.json
CHANGED
|
@@ -4,25 +4,25 @@
|
|
|
4
4
|
"sessionStart": [
|
|
5
5
|
{
|
|
6
6
|
"type": "command",
|
|
7
|
-
"bash": "./hooks/session-start.sh",
|
|
8
|
-
"powershell": "./hooks/session-start.ps1",
|
|
7
|
+
"bash": "bash \"./hooks/babysitter-proxied-session-start.sh\"",
|
|
8
|
+
"powershell": "powershell -NoProfile -ExecutionPolicy Bypass -File \"./hooks/babysitter-proxied-session-start.ps1\"",
|
|
9
9
|
"timeoutSec": 30
|
|
10
10
|
}
|
|
11
11
|
],
|
|
12
12
|
"sessionEnd": [
|
|
13
13
|
{
|
|
14
14
|
"type": "command",
|
|
15
|
-
"bash": "./hooks/session-end.sh",
|
|
16
|
-
"powershell": "./hooks/session-end.ps1",
|
|
15
|
+
"bash": "bash \"./hooks/babysitter-proxied-session-end.sh\"",
|
|
16
|
+
"powershell": "powershell -NoProfile -ExecutionPolicy Bypass -File \"./hooks/babysitter-proxied-session-end.ps1\"",
|
|
17
17
|
"timeoutSec": 30
|
|
18
18
|
}
|
|
19
19
|
],
|
|
20
20
|
"userPromptSubmitted": [
|
|
21
21
|
{
|
|
22
22
|
"type": "command",
|
|
23
|
-
"bash": "./hooks/user-prompt-submitted.sh",
|
|
24
|
-
"powershell": "./hooks/user-prompt-submitted.ps1",
|
|
25
|
-
"timeoutSec":
|
|
23
|
+
"bash": "bash \"./hooks/babysitter-proxied-user-prompt-submitted.sh\"",
|
|
24
|
+
"powershell": "powershell -NoProfile -ExecutionPolicy Bypass -File \"./hooks/babysitter-proxied-user-prompt-submitted.ps1\"",
|
|
25
|
+
"timeoutSec": 15
|
|
26
26
|
}
|
|
27
27
|
]
|
|
28
28
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@a5c-ai/babysitter-github",
|
|
3
|
-
"version": "5.0.1-staging.
|
|
3
|
+
"version": "5.0.1-staging.c66885f8",
|
|
4
4
|
"description": "Babysitter orchestration plugin for GitHub Copilot CLI with lifecycle hooks and SDK-managed process-library bootstrapping",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node scripts/sync-command-surfaces.js --check && node test/cloud-agent-install.test.js",
|
|
@@ -45,6 +45,6 @@
|
|
|
45
45
|
},
|
|
46
46
|
"homepage": "https://github.com/a5c-ai/babysitter/tree/main/plugins/babysitter-github#readme",
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@a5c-ai/babysitter-sdk": "5.0.1-staging.
|
|
48
|
+
"@a5c-ai/babysitter-sdk": "5.0.1-staging.c66885f8"
|
|
49
49
|
}
|
|
50
50
|
}
|
package/plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "babysitter",
|
|
3
|
-
"version": "5.0.1-staging.
|
|
3
|
+
"version": "5.0.1-staging.c66885f8",
|
|
4
4
|
"description": "Orchestrate complex, multi-step workflows with event-sourced state management, hook-based extensibility, and human-in-the-loop approval -- powered by the Babysitter SDK",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "a5c.ai",
|
package/versions.json
CHANGED