@a5c-ai/babysitter-github 0.1.1-staging.0825aadb
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/.github/plugin.json +25 -0
- package/AGENTS.md +41 -0
- package/README.md +545 -0
- package/bin/cli.js +104 -0
- package/bin/install-shared.js +450 -0
- package/bin/install.js +81 -0
- package/bin/uninstall.js +76 -0
- package/commands/assimilate.md +37 -0
- package/commands/call.md +7 -0
- package/commands/cleanup.md +20 -0
- package/commands/contrib.md +33 -0
- package/commands/doctor.md +426 -0
- package/commands/forever.md +7 -0
- package/commands/help.md +244 -0
- package/commands/observe.md +12 -0
- package/commands/plan.md +7 -0
- package/commands/plugins.md +255 -0
- package/commands/project-install.md +17 -0
- package/commands/resume.md +8 -0
- package/commands/retrospect.md +55 -0
- package/commands/user-install.md +17 -0
- package/commands/yolo.md +7 -0
- package/hooks/session-end.ps1 +68 -0
- package/hooks/session-end.sh +65 -0
- package/hooks/session-start.ps1 +110 -0
- package/hooks/session-start.sh +100 -0
- package/hooks/user-prompt-submitted.ps1 +51 -0
- package/hooks/user-prompt-submitted.sh +41 -0
- package/hooks.json +29 -0
- package/package.json +50 -0
- package/plugin.json +25 -0
- package/scripts/sync-command-surfaces.js +62 -0
- package/scripts/team-install.js +86 -0
- package/skills/assimilate/SKILL.md +38 -0
- package/skills/babysit/SKILL.md +77 -0
- package/skills/call/SKILL.md +8 -0
- package/skills/doctor/SKILL.md +427 -0
- package/skills/help/SKILL.md +245 -0
- package/skills/observe/SKILL.md +13 -0
- package/skills/plan/SKILL.md +8 -0
- package/skills/resume/SKILL.md +9 -0
- package/skills/retrospect/SKILL.md +56 -0
- package/skills/user-install/SKILL.md +18 -0
- package/versions.json +3 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Babysitter Session End Hook for GitHub Copilot CLI (PowerShell)
|
|
2
|
+
# Cleanup and logging on session exit.
|
|
3
|
+
#
|
|
4
|
+
# NOTE: Unlike Claude Code's Stop hook, sessionEnd output is IGNORED by
|
|
5
|
+
# Copilot CLI. This hook cannot block session exit or drive an orchestration
|
|
6
|
+
# loop. It is purely for cleanup and logging.
|
|
7
|
+
|
|
8
|
+
$ErrorActionPreference = "Continue"
|
|
9
|
+
|
|
10
|
+
$PluginRoot = if ($env:COPILOT_PLUGIN_DIR) { $env:COPILOT_PLUGIN_DIR } else { Split-Path -Parent $PSScriptRoot }
|
|
11
|
+
|
|
12
|
+
# Resolve babysitter CLI
|
|
13
|
+
$hasBabysitter = [bool](Get-Command babysitter -ErrorAction SilentlyContinue)
|
|
14
|
+
$useFallback = $false
|
|
15
|
+
|
|
16
|
+
if (-not $hasBabysitter) {
|
|
17
|
+
$localBin = Join-Path $env:USERPROFILE ".local\bin\babysitter.cmd"
|
|
18
|
+
if (Test-Path $localBin) {
|
|
19
|
+
$env:PATH = "$(Split-Path $localBin);$env:PATH"
|
|
20
|
+
$hasBabysitter = $true
|
|
21
|
+
} else {
|
|
22
|
+
$versionsFile = Join-Path $PluginRoot "versions.json"
|
|
23
|
+
try {
|
|
24
|
+
$SdkVersion = (Get-Content $versionsFile -Raw | ConvertFrom-Json).sdkVersion
|
|
25
|
+
if (-not $SdkVersion) { $SdkVersion = "latest" }
|
|
26
|
+
} catch {
|
|
27
|
+
$SdkVersion = "latest"
|
|
28
|
+
}
|
|
29
|
+
$useFallback = $true
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
$LogDir = if ($env:BABYSITTER_LOG_DIR) { $env:BABYSITTER_LOG_DIR } else { Join-Path $PluginRoot ".a5c\logs" }
|
|
34
|
+
$LogFile = Join-Path $LogDir "babysitter-session-end-hook.log"
|
|
35
|
+
New-Item -ItemType Directory -Path $LogDir -Force -ErrorAction SilentlyContinue | Out-Null
|
|
36
|
+
|
|
37
|
+
function Write-Blog {
|
|
38
|
+
param([string]$Message)
|
|
39
|
+
$ts = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
|
|
40
|
+
Add-Content -Path $LogFile -Value "[INFO] $ts $Message" -ErrorAction SilentlyContinue
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
Write-Blog "Hook script invoked"
|
|
44
|
+
Write-Blog "PLUGIN_ROOT=$PluginRoot"
|
|
45
|
+
|
|
46
|
+
# Capture stdin
|
|
47
|
+
$InputFile = [System.IO.Path]::GetTempFileName()
|
|
48
|
+
$input | Out-File -FilePath $InputFile -Encoding utf8
|
|
49
|
+
|
|
50
|
+
Write-Blog "Hook input received"
|
|
51
|
+
|
|
52
|
+
$stderrLog = Join-Path $LogDir "babysitter-session-end-hook-stderr.log"
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
if ($useFallback) {
|
|
56
|
+
Get-Content $InputFile | & npx -y "@a5c-ai/babysitter-sdk@$SdkVersion" hook:run --hook-type session-end --harness github-copilot --plugin-root $PluginRoot --json 2>$stderrLog | Out-Null
|
|
57
|
+
} elseif ($hasBabysitter) {
|
|
58
|
+
Get-Content $InputFile | & babysitter hook:run --hook-type session-end --harness github-copilot --plugin-root $PluginRoot --json 2>$stderrLog | Out-Null
|
|
59
|
+
}
|
|
60
|
+
} catch {
|
|
61
|
+
Write-Blog "Hook error: $_"
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
Write-Blog "Session end hook complete"
|
|
65
|
+
|
|
66
|
+
Remove-Item $InputFile -Force -ErrorAction SilentlyContinue
|
|
67
|
+
|
|
68
|
+
exit 0
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Babysitter Session End Hook for GitHub Copilot CLI
|
|
3
|
+
# Cleanup and logging on session exit.
|
|
4
|
+
#
|
|
5
|
+
# NOTE: Unlike Claude Code's Stop hook, sessionEnd output is IGNORED by
|
|
6
|
+
# Copilot CLI. This hook cannot block session exit or drive an orchestration
|
|
7
|
+
# loop. It is purely for cleanup and logging.
|
|
8
|
+
#
|
|
9
|
+
# Protocol:
|
|
10
|
+
# Input: JSON via stdin (session context)
|
|
11
|
+
# Output: IGNORED by Copilot CLI
|
|
12
|
+
# Exit 0: success (exit code also ignored)
|
|
13
|
+
|
|
14
|
+
set -uo pipefail
|
|
15
|
+
|
|
16
|
+
PLUGIN_ROOT="${COPILOT_PLUGIN_DIR:-$(cd "$(dirname "$0")/.." && pwd)}"
|
|
17
|
+
|
|
18
|
+
# Resolve babysitter CLI: installed binary, user-local prefix, or npx fallback
|
|
19
|
+
if ! command -v babysitter &>/dev/null; then
|
|
20
|
+
# Try user-local prefix (set by session-start hook)
|
|
21
|
+
if [ -x "$HOME/.local/bin/babysitter" ]; then
|
|
22
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
23
|
+
else
|
|
24
|
+
# Last resort: npx fallback
|
|
25
|
+
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")
|
|
26
|
+
if [ -n "$SDK_VERSION" ]; then
|
|
27
|
+
babysitter() { npx -y "@a5c-ai/babysitter-sdk@${SDK_VERSION}" "$@"; }
|
|
28
|
+
else
|
|
29
|
+
# No CLI available at all -- exit silently
|
|
30
|
+
exit 0
|
|
31
|
+
fi
|
|
32
|
+
fi
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
LOG_DIR="${BABYSITTER_LOG_DIR:-$PLUGIN_ROOT/.a5c/logs}"
|
|
36
|
+
LOG_FILE="$LOG_DIR/babysitter-session-end-hook.log"
|
|
37
|
+
|
|
38
|
+
mkdir -p "$LOG_DIR" 2>/dev/null
|
|
39
|
+
|
|
40
|
+
# Structured logging helper
|
|
41
|
+
blog() {
|
|
42
|
+
local msg="$1"
|
|
43
|
+
local ts
|
|
44
|
+
ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
45
|
+
echo "[INFO] $ts $msg" >> "$LOG_FILE" 2>/dev/null
|
|
46
|
+
babysitter log --type hook --label "hook:session-end" --message "$msg" --source shell-hook 2>/dev/null || true
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
blog "Hook script invoked"
|
|
50
|
+
blog "PLUGIN_ROOT=$PLUGIN_ROOT"
|
|
51
|
+
|
|
52
|
+
# Capture stdin so we can log size and pass to CLI
|
|
53
|
+
INPUT_FILE=$(mktemp 2>/dev/null || echo "/tmp/hook-session-end-$$.json")
|
|
54
|
+
cat > "$INPUT_FILE"
|
|
55
|
+
|
|
56
|
+
blog "Hook input received ($(wc -c < "$INPUT_FILE") bytes)"
|
|
57
|
+
|
|
58
|
+
# Run cleanup/logging via CLI; output is ignored by Copilot CLI
|
|
59
|
+
babysitter hook:run --hook-type session-end --harness github-copilot --plugin-root "$PLUGIN_ROOT" --json < "$INPUT_FILE" 2>"$LOG_DIR/babysitter-session-end-hook-stderr.log" || true
|
|
60
|
+
|
|
61
|
+
blog "Session end hook complete"
|
|
62
|
+
|
|
63
|
+
rm -f "$INPUT_FILE" 2>/dev/null
|
|
64
|
+
|
|
65
|
+
exit 0
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Babysitter Session Start Hook for GitHub Copilot CLI (PowerShell)
|
|
2
|
+
# Ensures the babysitter SDK CLI is installed (from versions.json sdkVersion),
|
|
3
|
+
# then delegates to the TypeScript handler.
|
|
4
|
+
#
|
|
5
|
+
# Protocol:
|
|
6
|
+
# Input: JSON via stdin (contains session_id, cwd, etc.)
|
|
7
|
+
# Output: JSON via stdout ({} on success)
|
|
8
|
+
# Stderr: debug/log output only
|
|
9
|
+
# Exit 0: success
|
|
10
|
+
# Exit 2: block (fatal error)
|
|
11
|
+
|
|
12
|
+
$ErrorActionPreference = "Stop"
|
|
13
|
+
|
|
14
|
+
$PluginRoot = if ($env:COPILOT_PLUGIN_DIR) { $env:COPILOT_PLUGIN_DIR } else { Split-Path -Parent $PSScriptRoot }
|
|
15
|
+
$MarkerFile = Join-Path $PluginRoot ".babysitter-install-attempted"
|
|
16
|
+
|
|
17
|
+
$LogDir = if ($env:BABYSITTER_LOG_DIR) { $env:BABYSITTER_LOG_DIR } else { Join-Path $PluginRoot ".a5c\logs" }
|
|
18
|
+
$LogFile = Join-Path $LogDir "babysitter-session-start-hook.log"
|
|
19
|
+
New-Item -ItemType Directory -Path $LogDir -Force -ErrorAction SilentlyContinue | Out-Null
|
|
20
|
+
|
|
21
|
+
function Write-Blog {
|
|
22
|
+
param([string]$Message)
|
|
23
|
+
$ts = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
|
|
24
|
+
Add-Content -Path $LogFile -Value "[INFO] $ts $Message" -ErrorAction SilentlyContinue
|
|
25
|
+
if (Get-Command babysitter -ErrorAction SilentlyContinue) {
|
|
26
|
+
& babysitter log --type hook --label "hook:session-start" --message $Message --source shell-hook 2>$null
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
Write-Blog "Hook script invoked"
|
|
31
|
+
Write-Blog "PLUGIN_ROOT=$PluginRoot"
|
|
32
|
+
|
|
33
|
+
# Get required SDK version from versions.json
|
|
34
|
+
$versionsFile = Join-Path $PluginRoot "versions.json"
|
|
35
|
+
try {
|
|
36
|
+
$SdkVersion = (Get-Content $versionsFile -Raw | ConvertFrom-Json).sdkVersion
|
|
37
|
+
if (-not $SdkVersion) { $SdkVersion = "latest" }
|
|
38
|
+
} catch {
|
|
39
|
+
$SdkVersion = "latest"
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function Install-Sdk {
|
|
43
|
+
param([string]$TargetVersion)
|
|
44
|
+
try {
|
|
45
|
+
& npm i -g "@a5c-ai/babysitter-sdk@$TargetVersion" --loglevel=error 2>$null
|
|
46
|
+
if ($LASTEXITCODE -eq 0) {
|
|
47
|
+
Write-Blog "Installed SDK globally ($TargetVersion)"
|
|
48
|
+
return $true
|
|
49
|
+
}
|
|
50
|
+
} catch {}
|
|
51
|
+
try {
|
|
52
|
+
$prefix = Join-Path $env:USERPROFILE ".local"
|
|
53
|
+
& npm i -g "@a5c-ai/babysitter-sdk@$TargetVersion" --prefix $prefix --loglevel=error 2>$null
|
|
54
|
+
if ($LASTEXITCODE -eq 0) {
|
|
55
|
+
$env:PATH = "$prefix\bin;$env:PATH"
|
|
56
|
+
Write-Blog "Installed SDK to user prefix ($TargetVersion)"
|
|
57
|
+
return $true
|
|
58
|
+
}
|
|
59
|
+
} catch {}
|
|
60
|
+
return $false
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# Check if babysitter CLI exists and if version matches
|
|
64
|
+
$NeedsInstall = $false
|
|
65
|
+
if (Get-Command babysitter -ErrorAction SilentlyContinue) {
|
|
66
|
+
$CurrentVersion = & babysitter --version 2>$null
|
|
67
|
+
if ($CurrentVersion -ne $SdkVersion) {
|
|
68
|
+
Write-Blog "SDK version mismatch: installed=$CurrentVersion, required=$SdkVersion"
|
|
69
|
+
$NeedsInstall = $true
|
|
70
|
+
} else {
|
|
71
|
+
Write-Blog "SDK version OK: $CurrentVersion"
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
Write-Blog "SDK CLI not found, will install"
|
|
75
|
+
$NeedsInstall = $true
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
# Install/upgrade if needed (only attempt once per plugin version)
|
|
79
|
+
if ($NeedsInstall -and -not (Test-Path $MarkerFile)) {
|
|
80
|
+
Install-Sdk $SdkVersion | Out-Null
|
|
81
|
+
Set-Content -Path $MarkerFile -Value $SdkVersion -ErrorAction SilentlyContinue
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
# If still not available after install attempt, try npx as last resort
|
|
85
|
+
$useFallback = $false
|
|
86
|
+
if (-not (Get-Command babysitter -ErrorAction SilentlyContinue)) {
|
|
87
|
+
Write-Blog "CLI not found after install, using npx fallback"
|
|
88
|
+
$useFallback = $true
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
# Capture stdin
|
|
92
|
+
$InputFile = [System.IO.Path]::GetTempFileName()
|
|
93
|
+
$input | Out-File -FilePath $InputFile -Encoding utf8
|
|
94
|
+
|
|
95
|
+
Write-Blog "Hook input received"
|
|
96
|
+
|
|
97
|
+
$stderrLog = Join-Path $LogDir "babysitter-session-start-hook-stderr.log"
|
|
98
|
+
|
|
99
|
+
if ($useFallback) {
|
|
100
|
+
$Result = Get-Content $InputFile | & npx -y "@a5c-ai/babysitter-sdk@$SdkVersion" hook:run --hook-type session-start --harness github-copilot --plugin-root $PluginRoot --json 2>$stderrLog
|
|
101
|
+
} else {
|
|
102
|
+
$Result = Get-Content $InputFile | & babysitter hook:run --hook-type session-start --harness github-copilot --plugin-root $PluginRoot --json 2>$stderrLog
|
|
103
|
+
}
|
|
104
|
+
$ExitCode = $LASTEXITCODE
|
|
105
|
+
|
|
106
|
+
Write-Blog "CLI exit code=$ExitCode"
|
|
107
|
+
|
|
108
|
+
Remove-Item $InputFile -Force -ErrorAction SilentlyContinue
|
|
109
|
+
Write-Output $Result
|
|
110
|
+
exit $ExitCode
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Babysitter Session Start Hook for GitHub Copilot CLI
|
|
3
|
+
# Ensures the babysitter SDK CLI is installed (from versions.json sdkVersion),
|
|
4
|
+
# then delegates to the TypeScript handler.
|
|
5
|
+
#
|
|
6
|
+
# Protocol:
|
|
7
|
+
# Input: JSON via stdin (contains session_id, cwd, etc.)
|
|
8
|
+
# Output: JSON via stdout ({} on success)
|
|
9
|
+
# Stderr: debug/log output only
|
|
10
|
+
# Exit 0: success
|
|
11
|
+
# Exit 2: block (fatal error)
|
|
12
|
+
|
|
13
|
+
set -euo pipefail
|
|
14
|
+
|
|
15
|
+
PLUGIN_ROOT="${COPILOT_PLUGIN_DIR:-$(cd "$(dirname "$0")/.." && pwd)}"
|
|
16
|
+
MARKER_FILE="${PLUGIN_ROOT}/.babysitter-install-attempted"
|
|
17
|
+
|
|
18
|
+
LOG_DIR="${BABYSITTER_LOG_DIR:-$PLUGIN_ROOT/.a5c/logs}"
|
|
19
|
+
LOG_FILE="$LOG_DIR/babysitter-session-start-hook.log"
|
|
20
|
+
mkdir -p "$LOG_DIR" 2>/dev/null
|
|
21
|
+
|
|
22
|
+
# Structured logging helper -- writes to both local and global log
|
|
23
|
+
blog() {
|
|
24
|
+
local msg="$1"
|
|
25
|
+
local ts
|
|
26
|
+
ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
27
|
+
echo "[INFO] $ts $msg" >> "$LOG_FILE" 2>/dev/null
|
|
28
|
+
# Use CLI structured logging when available; fall back to direct append
|
|
29
|
+
if command -v babysitter &>/dev/null; then
|
|
30
|
+
babysitter log --type hook --label "hook:session-start" --message "$msg" --source shell-hook 2>/dev/null || true
|
|
31
|
+
fi
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
blog "Hook script invoked"
|
|
35
|
+
blog "PLUGIN_ROOT=$PLUGIN_ROOT"
|
|
36
|
+
|
|
37
|
+
# Get required SDK version from versions.json
|
|
38
|
+
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")
|
|
39
|
+
|
|
40
|
+
# Function to install/upgrade SDK
|
|
41
|
+
install_sdk() {
|
|
42
|
+
local target_version="$1"
|
|
43
|
+
# Try global install first, fall back to user-local if permissions fail
|
|
44
|
+
if npm i -g "@a5c-ai/babysitter-sdk@${target_version}" --loglevel=error 2>/dev/null; then
|
|
45
|
+
blog "Installed SDK globally (${target_version})"
|
|
46
|
+
return 0
|
|
47
|
+
else
|
|
48
|
+
# Global install failed (permissions) -- try user-local prefix
|
|
49
|
+
if npm i -g "@a5c-ai/babysitter-sdk@${target_version}" --prefix "$HOME/.local" --loglevel=error 2>/dev/null; then
|
|
50
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
51
|
+
blog "Installed SDK to user prefix (${target_version})"
|
|
52
|
+
return 0
|
|
53
|
+
fi
|
|
54
|
+
fi
|
|
55
|
+
return 1
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
# Check if babysitter CLI exists and if version matches
|
|
59
|
+
NEEDS_INSTALL=false
|
|
60
|
+
if command -v babysitter &>/dev/null; then
|
|
61
|
+
CURRENT_VERSION=$(babysitter --version 2>/dev/null || echo "unknown")
|
|
62
|
+
if [ "$CURRENT_VERSION" != "$SDK_VERSION" ]; then
|
|
63
|
+
blog "SDK version mismatch: installed=${CURRENT_VERSION}, required=${SDK_VERSION}"
|
|
64
|
+
NEEDS_INSTALL=true
|
|
65
|
+
else
|
|
66
|
+
blog "SDK version OK: ${CURRENT_VERSION}"
|
|
67
|
+
fi
|
|
68
|
+
else
|
|
69
|
+
blog "SDK CLI not found, will install"
|
|
70
|
+
NEEDS_INSTALL=true
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# Install/upgrade if needed (only attempt once per plugin version)
|
|
74
|
+
if [ "$NEEDS_INSTALL" = true ] && [ ! -f "$MARKER_FILE" ]; then
|
|
75
|
+
install_sdk "$SDK_VERSION"
|
|
76
|
+
echo "$SDK_VERSION" > "$MARKER_FILE" 2>/dev/null
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# If still not available after install attempt, try npx as last resort
|
|
80
|
+
if ! command -v babysitter &>/dev/null; then
|
|
81
|
+
blog "CLI not found after install, using npx fallback"
|
|
82
|
+
babysitter() { npx -y "@a5c-ai/babysitter-sdk@${SDK_VERSION}" "$@"; }
|
|
83
|
+
export -f babysitter
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
# Capture stdin to a temp file so the CLI receives a clean EOF
|
|
87
|
+
# (piping /dev/stdin directly can keep the Node.js event loop alive)
|
|
88
|
+
INPUT_FILE=$(mktemp 2>/dev/null || echo "/tmp/hook-session-start-$$.json")
|
|
89
|
+
cat > "$INPUT_FILE"
|
|
90
|
+
|
|
91
|
+
blog "Hook input received ($(wc -c < "$INPUT_FILE") bytes)"
|
|
92
|
+
|
|
93
|
+
RESULT=$(babysitter hook:run --hook-type session-start --harness github-copilot --plugin-root "$PLUGIN_ROOT" --json < "$INPUT_FILE" 2>"$LOG_DIR/babysitter-session-start-hook-stderr.log")
|
|
94
|
+
EXIT_CODE=$?
|
|
95
|
+
|
|
96
|
+
blog "CLI exit code=$EXIT_CODE"
|
|
97
|
+
|
|
98
|
+
rm -f "$INPUT_FILE" 2>/dev/null
|
|
99
|
+
printf '%s\n' "$RESULT"
|
|
100
|
+
exit $EXIT_CODE
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Babysitter userPromptSubmitted Hook for GitHub Copilot CLI (PowerShell)
|
|
2
|
+
# Applies density-filter compression to long user prompts.
|
|
3
|
+
#
|
|
4
|
+
# NOTE: Output from this hook is IGNORED by Copilot CLI.
|
|
5
|
+
# This hook is for logging and side-effects only.
|
|
6
|
+
|
|
7
|
+
$ErrorActionPreference = "Continue"
|
|
8
|
+
|
|
9
|
+
$PluginRoot = if ($env:COPILOT_PLUGIN_DIR) { $env:COPILOT_PLUGIN_DIR } else { Split-Path -Parent $PSScriptRoot }
|
|
10
|
+
|
|
11
|
+
# Resolve babysitter CLI
|
|
12
|
+
$hasBabysitter = [bool](Get-Command babysitter -ErrorAction SilentlyContinue)
|
|
13
|
+
$useFallback = $false
|
|
14
|
+
|
|
15
|
+
if (-not $hasBabysitter) {
|
|
16
|
+
$localBin = Join-Path $env:USERPROFILE ".local\bin\babysitter.cmd"
|
|
17
|
+
if (Test-Path $localBin) {
|
|
18
|
+
$env:PATH = "$(Split-Path $localBin);$env:PATH"
|
|
19
|
+
$hasBabysitter = $true
|
|
20
|
+
} else {
|
|
21
|
+
$versionsFile = Join-Path $PluginRoot "versions.json"
|
|
22
|
+
try {
|
|
23
|
+
$SdkVersion = (Get-Content $versionsFile -Raw | ConvertFrom-Json).sdkVersion
|
|
24
|
+
if (-not $SdkVersion) { $SdkVersion = "latest" }
|
|
25
|
+
} catch {
|
|
26
|
+
$SdkVersion = "latest"
|
|
27
|
+
}
|
|
28
|
+
$useFallback = $true
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
$LogDir = if ($env:BABYSITTER_LOG_DIR) { $env:BABYSITTER_LOG_DIR } else { Join-Path $PluginRoot ".a5c\logs" }
|
|
33
|
+
New-Item -ItemType Directory -Path $LogDir -Force -ErrorAction SilentlyContinue | Out-Null
|
|
34
|
+
|
|
35
|
+
# Capture stdin
|
|
36
|
+
$InputFile = [System.IO.Path]::GetTempFileName()
|
|
37
|
+
$input | Out-File -FilePath $InputFile -Encoding utf8
|
|
38
|
+
|
|
39
|
+
$stderrLog = Join-Path $LogDir "babysitter-user-prompt-submitted-hook-stderr.log"
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
if ($useFallback) {
|
|
43
|
+
Get-Content $InputFile | & npx -y "@a5c-ai/babysitter-sdk@$SdkVersion" hook:run --hook-type user-prompt-submitted --harness github-copilot --json 2>$stderrLog | Out-Null
|
|
44
|
+
} elseif ($hasBabysitter) {
|
|
45
|
+
Get-Content $InputFile | & babysitter hook:run --hook-type user-prompt-submitted --harness github-copilot --json 2>$stderrLog | Out-Null
|
|
46
|
+
}
|
|
47
|
+
} catch {}
|
|
48
|
+
|
|
49
|
+
Remove-Item $InputFile -Force -ErrorAction SilentlyContinue
|
|
50
|
+
|
|
51
|
+
exit 0
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Babysitter userPromptSubmitted Hook for GitHub Copilot CLI
|
|
3
|
+
# Applies density-filter compression to long user prompts.
|
|
4
|
+
# Delegates to SDK CLI: babysitter hook:run --hook-type user-prompt-submitted
|
|
5
|
+
#
|
|
6
|
+
# NOTE: Output from this hook is IGNORED by Copilot CLI.
|
|
7
|
+
# This hook is for logging and side-effects only.
|
|
8
|
+
|
|
9
|
+
PLUGIN_ROOT="${COPILOT_PLUGIN_DIR:-$(cd "$(dirname "$0")/.." && pwd)}"
|
|
10
|
+
|
|
11
|
+
# Resolve babysitter CLI: installed binary, user-local prefix, or npx fallback
|
|
12
|
+
if ! command -v babysitter &>/dev/null; then
|
|
13
|
+
if [ -x "$HOME/.local/bin/babysitter" ]; then
|
|
14
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
15
|
+
else
|
|
16
|
+
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")
|
|
17
|
+
if [ -n "$SDK_VERSION" ]; then
|
|
18
|
+
babysitter() { npx -y "@a5c-ai/babysitter-sdk@${SDK_VERSION}" "$@"; }
|
|
19
|
+
export -f babysitter
|
|
20
|
+
else
|
|
21
|
+
# No CLI available -- exit silently
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
fi
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
LOG_DIR="${BABYSITTER_LOG_DIR:-$PLUGIN_ROOT/.a5c/logs}"
|
|
28
|
+
mkdir -p "$LOG_DIR" 2>/dev/null
|
|
29
|
+
|
|
30
|
+
INPUT_FILE=$(mktemp 2>/dev/null || echo "/tmp/hook-user-prompt-submitted-$$.json")
|
|
31
|
+
cat > "$INPUT_FILE"
|
|
32
|
+
|
|
33
|
+
babysitter log --type hook --label "hook:user-prompt-submitted" --message "Hook invoked" --source shell-hook 2>/dev/null || true
|
|
34
|
+
|
|
35
|
+
babysitter hook:run --hook-type user-prompt-submitted --harness github-copilot --json < "$INPUT_FILE" 2>"$LOG_DIR/babysitter-user-prompt-submitted-hook-stderr.log" || true
|
|
36
|
+
|
|
37
|
+
babysitter log --type hook --label "hook:user-prompt-submitted" --message "Hook complete" --source shell-hook 2>/dev/null || true
|
|
38
|
+
|
|
39
|
+
rm -f "$INPUT_FILE" 2>/dev/null
|
|
40
|
+
|
|
41
|
+
exit 0
|
package/hooks.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"hooks": {
|
|
4
|
+
"sessionStart": [
|
|
5
|
+
{
|
|
6
|
+
"type": "command",
|
|
7
|
+
"bash": "./hooks/session-start.sh",
|
|
8
|
+
"powershell": "./hooks/session-start.ps1",
|
|
9
|
+
"timeoutSec": 30
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"sessionEnd": [
|
|
13
|
+
{
|
|
14
|
+
"type": "command",
|
|
15
|
+
"bash": "./hooks/session-end.sh",
|
|
16
|
+
"powershell": "./hooks/session-end.ps1",
|
|
17
|
+
"timeoutSec": 30
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"userPromptSubmitted": [
|
|
21
|
+
{
|
|
22
|
+
"type": "command",
|
|
23
|
+
"bash": "./hooks/user-prompt-submitted.sh",
|
|
24
|
+
"powershell": "./hooks/user-prompt-submitted.ps1",
|
|
25
|
+
"timeoutSec": 30
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@a5c-ai/babysitter-github",
|
|
3
|
+
"version": "0.1.1-staging.0825aadb",
|
|
4
|
+
"description": "Babysitter orchestration plugin for GitHub Copilot CLI with lifecycle hooks and SDK-managed process-library bootstrapping",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "node scripts/sync-command-surfaces.js --check",
|
|
7
|
+
"sync:commands": "node scripts/sync-command-surfaces.js",
|
|
8
|
+
"postinstall": "node bin/install.js",
|
|
9
|
+
"preuninstall": "node bin/uninstall.js",
|
|
10
|
+
"team:install": "node scripts/team-install.js",
|
|
11
|
+
"deploy": "npm publish --access public",
|
|
12
|
+
"deploy:staging": "npm publish --access public --tag staging"
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"babysitter-github": "bin/cli.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"plugin.json",
|
|
19
|
+
"hooks.json",
|
|
20
|
+
"hooks/",
|
|
21
|
+
"skills/",
|
|
22
|
+
"bin/",
|
|
23
|
+
"scripts/",
|
|
24
|
+
"versions.json",
|
|
25
|
+
"AGENTS.md",
|
|
26
|
+
"commands/",
|
|
27
|
+
".github/",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
"keywords": [
|
|
31
|
+
"babysitter",
|
|
32
|
+
"github-copilot",
|
|
33
|
+
"orchestration",
|
|
34
|
+
"ai-agent",
|
|
35
|
+
"sdk-integration"
|
|
36
|
+
],
|
|
37
|
+
"author": "a5c.ai",
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "https://github.com/a5c-ai/babysitter"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://github.com/a5c-ai/babysitter/tree/main/plugins/babysitter-github#readme",
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@a5c-ai/babysitter-sdk": "0.0.184-staging.0825aadb"
|
|
49
|
+
}
|
|
50
|
+
}
|
package/plugin.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "babysitter",
|
|
3
|
+
"version": "0.1.0",
|
|
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
|
+
"author": { "name": "a5c.ai", "email": "support@a5c.ai" },
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"skills": "skills/",
|
|
8
|
+
"hooks": "hooks.json",
|
|
9
|
+
"commands": "commands/",
|
|
10
|
+
"agents": "AGENTS.md",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/a5c-ai/babysitter"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"orchestration",
|
|
17
|
+
"workflow",
|
|
18
|
+
"automation",
|
|
19
|
+
"event-sourced",
|
|
20
|
+
"hooks",
|
|
21
|
+
"github-copilot",
|
|
22
|
+
"agent",
|
|
23
|
+
"LLM"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const {
|
|
5
|
+
listDirectories,
|
|
6
|
+
listMarkdownBasenames,
|
|
7
|
+
reportCheckResult,
|
|
8
|
+
syncCommandMirrors,
|
|
9
|
+
syncSkillsFromCommands,
|
|
10
|
+
} = require('../../../scripts/plugin-command-sync-lib.cjs');
|
|
11
|
+
|
|
12
|
+
const PACKAGE_ROOT = path.resolve(__dirname, '..');
|
|
13
|
+
const REPO_ROOT = path.resolve(PACKAGE_ROOT, '..', '..');
|
|
14
|
+
const ROOT_COMMANDS = path.join(REPO_ROOT, 'plugins', 'babysitter', 'commands');
|
|
15
|
+
const PLUGIN_COMMANDS = path.join(PACKAGE_ROOT, 'commands');
|
|
16
|
+
const PLUGIN_SKILLS = path.join(PACKAGE_ROOT, 'skills');
|
|
17
|
+
const LABEL = 'babysitter-github sync';
|
|
18
|
+
|
|
19
|
+
function getMirroredCommandNames() {
|
|
20
|
+
const local = new Set(listMarkdownBasenames(PLUGIN_COMMANDS));
|
|
21
|
+
return listMarkdownBasenames(ROOT_COMMANDS).filter((name) => local.has(name));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getDerivedSkillNames() {
|
|
25
|
+
const local = new Set(listDirectories(PLUGIN_SKILLS));
|
|
26
|
+
return listMarkdownBasenames(PLUGIN_COMMANDS).filter((name) => local.has(name));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function main() {
|
|
30
|
+
const check = process.argv.includes('--check');
|
|
31
|
+
const mirrorResult = syncCommandMirrors({
|
|
32
|
+
label: LABEL,
|
|
33
|
+
sourceRoot: ROOT_COMMANDS,
|
|
34
|
+
targetRoot: PLUGIN_COMMANDS,
|
|
35
|
+
names: getMirroredCommandNames(),
|
|
36
|
+
check,
|
|
37
|
+
cwd: PACKAGE_ROOT,
|
|
38
|
+
});
|
|
39
|
+
const skillsResult = syncSkillsFromCommands({
|
|
40
|
+
label: LABEL,
|
|
41
|
+
sourceRoot: PLUGIN_COMMANDS,
|
|
42
|
+
skillsRoot: PLUGIN_SKILLS,
|
|
43
|
+
names: getDerivedSkillNames(),
|
|
44
|
+
check,
|
|
45
|
+
cwd: PACKAGE_ROOT,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
if (check) {
|
|
49
|
+
reportCheckResult(LABEL, [...mirrorResult.stale, ...skillsResult.stale]);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const updated = mirrorResult.updated + skillsResult.updated;
|
|
54
|
+
if (updated === 0) {
|
|
55
|
+
console.log(`[${LABEL}] no GitHub plugin command changes were needed.`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
console.log(`[${LABEL}] updated ${updated} GitHub plugin file(s).`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
main();
|