@a5c-ai/babysitter-github 5.0.1-staging.e4f17eff → 5.0.1-staging.fcac7259
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/bin/cli.js +14 -26
- package/bin/install-shared.js +382 -210
- package/bin/install.js +41 -90
- package/bin/uninstall.js +12 -63
- package/commands/doctor.md +5 -5
- package/commands/help.md +245 -244
- package/commands/observe.md +12 -12
- package/hooks/babysitter-proxied-session-end.ps1 +10 -114
- package/hooks/babysitter-proxied-session-end.sh +2 -111
- package/hooks/babysitter-proxied-session-start.ps1 +10 -187
- package/hooks/babysitter-proxied-session-start.sh +6 -168
- package/hooks/babysitter-proxied-user-prompt-submitted.ps1 +10 -90
- package/hooks/babysitter-proxied-user-prompt-submitted.sh +2 -86
- package/hooks.json +10 -10
- package/package.json +18 -20
- package/plugin.json +7 -6
- package/scripts/team-install.js +14 -84
- package/skills/cleanup/SKILL.md +21 -0
- package/skills/contrib/SKILL.md +34 -0
- package/skills/doctor/SKILL.md +5 -5
- package/skills/forever/SKILL.md +8 -0
- package/skills/help/SKILL.md +3 -2
- package/skills/observe/SKILL.md +1 -1
- package/skills/plugins/SKILL.md +257 -0
- package/skills/project-install/SKILL.md +18 -0
- package/skills/resume/SKILL.md +1 -1
- package/skills/retrospect/SKILL.md +48 -48
- package/skills/user-install/SKILL.md +3 -3
- package/skills/yolo/SKILL.md +8 -0
- package/versions.json +1 -1
- package/.github/plugin.json +0 -25
- package/hooks/proxied-hooks.json +0 -29
- package/hooks/session-end.ps1 +0 -69
- package/hooks/session-end.sh +0 -54
- package/hooks/session-start.ps1 +0 -111
- package/hooks/session-start.sh +0 -101
- package/hooks/user-prompt-submitted.ps1 +0 -52
- package/hooks/user-prompt-submitted.sh +0 -31
|
@@ -1,112 +1,3 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
|
|
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
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
babysitter hook:run --harness unified --hook-type session-end --json
|
|
@@ -1,189 +1,12 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
}
|
|
1
|
+
# PowerShell hook wrapper — sets env vars and delegates to bash
|
|
2
|
+
$env:HOOK_TYPE = 'session-start'
|
|
3
|
+
$env:ADAPTER_NAME = 'copilot'
|
|
4
|
+
$env:PLUGIN_ROOT = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
|
|
5
|
+
|
|
6
|
+
$input_data = [Console]::In.ReadToEnd()
|
|
7
|
+
$result = $input_data | & bash "$PSScriptRoot/../$($MyInvocation.MyCommand.Name -replace '\.ps1$','.sh')" 2>$null
|
|
8
|
+
if ($LASTEXITCODE -eq 0 -and $result) {
|
|
9
|
+
Write-Output $result
|
|
80
10
|
} else {
|
|
81
|
-
|
|
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
|
|
11
|
+
Write-Output '{}'
|
|
88
12
|
}
|
|
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
|
|
@@ -1,173 +1,11 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
#
|
|
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
|
-
|
|
2
|
+
# Session Start — installs SDK if needed, then runs hook handler.
|
|
15
3
|
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)
|
|
4
|
+
PLUGIN_ROOT="${PLUGIN_ROOT:-$(cd "$(dirname "$0")/.." && pwd)}"
|
|
42
5
|
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
6
|
if ! command -v babysitter &>/dev/null; then
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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} "
|
|
7
|
+
npm i -g "@a5c-ai/babysitter-sdk@${SDK_VERSION}" --loglevel=error 2>/dev/null || \
|
|
8
|
+
npm i -g "@a5c-ai/babysitter-sdk@${SDK_VERSION}" --prefix "$HOME/.local" --loglevel=error 2>/dev/null || true
|
|
9
|
+
[ -d "$HOME/.local/bin" ] && export PATH="$HOME/.local/bin:$PATH"
|
|
148
10
|
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
|
|
11
|
+
babysitter hook:run --harness unified --hook-type session-start --json
|
|
@@ -1,92 +1,12 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
$
|
|
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"
|
|
1
|
+
# PowerShell hook wrapper — sets env vars and delegates to bash
|
|
2
|
+
$env:HOOK_TYPE = 'user-prompt-submit'
|
|
3
|
+
$env:ADAPTER_NAME = 'copilot'
|
|
4
|
+
$env:PLUGIN_ROOT = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
|
|
5
|
+
|
|
6
|
+
$input_data = [Console]::In.ReadToEnd()
|
|
7
|
+
$result = $input_data | & bash "$PSScriptRoot/../$($MyInvocation.MyCommand.Name -replace '\.ps1$','.sh')" 2>$null
|
|
8
|
+
if ($LASTEXITCODE -eq 0 -and $result) {
|
|
9
|
+
Write-Output $result
|
|
52
10
|
} else {
|
|
53
|
-
|
|
54
|
-
if (Test-Path $localProxy) {
|
|
55
|
-
$Proxy = $localProxy
|
|
56
|
-
}
|
|
11
|
+
Write-Output '{}'
|
|
57
12
|
}
|
|
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
|