@synapse-research/synapse 0.2.12 → 0.2.13
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/dist/.next/BUILD_ID +1 -1
- package/dist/.next/app-build-manifest.json +113 -113
- package/dist/.next/app-path-routes-manifest.json +27 -27
- package/dist/.next/build-manifest.json +2 -2
- package/dist/.next/prerender-manifest.json +6 -6
- package/dist/.next/server/app/(dashboard)/agents/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/compute/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/project-groups/[uuid]/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/[uuid]/activity/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/[uuid]/dashboard/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/[uuid]/documents/[documentUuid]/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/[uuid]/documents/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/[uuid]/experiment-designs/[designUuid]/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/[uuid]/experiment-designs/new/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/[uuid]/experiment-designs/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/[uuid]/experiment-runs/[runUuid]/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/[uuid]/experiment-runs/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/[uuid]/experiments/new/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/[uuid]/experiments/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/[uuid]/insights/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/[uuid]/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/[uuid]/related-works/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/[uuid]/research-questions/[questionUuid]/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/[uuid]/research-questions/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/[uuid]/settings/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/new/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/research-projects/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/_not-found.html +1 -1
- package/dist/.next/server/app/_not-found.rsc +1 -1
- package/dist/.next/server/app/admin/companies/[uuid]/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/admin/companies/new/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/admin/companies/new.html +1 -1
- package/dist/.next/server/app/admin/companies/new.rsc +1 -1
- package/dist/.next/server/app/admin/companies/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/admin/companies.html +1 -1
- package/dist/.next/server/app/admin/companies.rsc +1 -1
- package/dist/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/admin.html +1 -1
- package/dist/.next/server/app/admin.rsc +1 -1
- package/dist/.next/server/app/api/admin/companies/[uuid]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/admin/companies/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/admin/login/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/admin/session/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/admin/stats/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/agents/[uuid]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/agents/[uuid]/sessions/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/agents/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/api-keys/[uuid]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/api-keys/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/auth/callback/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/auth/check-default/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/auth/default-login/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/auth/identify/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/auth/me/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/auth/refresh/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/auth/session/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/auth/sync-token/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/comments/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/compute-gpus/[uuid]/release/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/compute-nodes/[uuid]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/compute-nodes/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/compute-pools/[uuid]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/compute-pools/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/documents/[uuid]/images/[filename]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/documents/[uuid]/images/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/documents/[uuid]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/events/notifications/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiment-designs/[uuid]/approve/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiment-designs/[uuid]/close/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiment-designs/[uuid]/reject/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiment-designs/[uuid]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiment-runs/[uuid]/claim/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiment-runs/[uuid]/dependencies/[dependsOnRunUuid]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiment-runs/[uuid]/dependencies/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiment-runs/[uuid]/evaluate-criteria/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiment-runs/[uuid]/registry/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiment-runs/[uuid]/release/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiment-runs/[uuid]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiment-runs/[uuid]/sessions/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiments/[uuid]/complete/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiments/[uuid]/progress/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiments/[uuid]/request-plan/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiments/[uuid]/reset/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiments/[uuid]/review/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiments/[uuid]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/experiments/[uuid]/start/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/mcp/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/me/assignments/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/mentionables/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/notifications/[uuid]/archive/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/notifications/[uuid]/read/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/notifications/preferences/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/notifications/read-all/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/notifications/unread-count/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/onboarding/status/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/project-groups/[uuid]/dashboard/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/project-groups/[uuid]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/project-groups/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/activity/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/agent-activity/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/available/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/baselines/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/documents/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/experiment-designs/[designUuid]/validate/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/experiment-designs/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/experiment-designs/summary/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/experiment-runs/dependencies/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/experiment-runs/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/experiments/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/github/branches/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/group/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/related-works/[workUuid]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/related-works/auto-search/complete/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/related-works/auto-search/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/related-works/deep-research/complete/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/related-works/deep-research/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/related-works/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/research-questions/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/synthesis/complete/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/synthesis/refresh/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/[uuid]/synthesis/trigger/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-projects/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-questions/[uuid]/claim/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-questions/[uuid]/move/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-questions/[uuid]/release/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-questions/[uuid]/review/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/research-questions/[uuid]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/sessions/[uuid]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/settings/integrations/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/ssh-config/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/index.html +1 -1
- package/dist/.next/server/app/index.rsc +1 -1
- package/dist/.next/server/app/login/admin/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/login/admin.html +1 -1
- package/dist/.next/server/app/login/admin.rsc +1 -1
- package/dist/.next/server/app/login/callback/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/login/callback.html +1 -1
- package/dist/.next/server/app/login/callback.rsc +1 -1
- package/dist/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/login/silent-refresh/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/login/silent-refresh.html +1 -1
- package/dist/.next/server/app/login/silent-refresh.rsc +1 -1
- package/dist/.next/server/app/login.html +1 -1
- package/dist/.next/server/app/login.rsc +1 -1
- package/dist/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/research-projects/new.html +1 -1
- package/dist/.next/server/app/research-projects/new.rsc +1 -1
- package/dist/.next/server/app/research-projects.html +1 -1
- package/dist/.next/server/app/research-projects.rsc +1 -1
- package/dist/.next/server/app/settings.html +1 -1
- package/dist/.next/server/app/settings.rsc +1 -1
- package/dist/.next/server/app-paths-manifest.json +27 -27
- package/dist/.next/server/middleware-manifest.json +1 -1
- package/dist/.next/server/pages/404.html +1 -1
- package/dist/.next/server/pages/500.html +1 -1
- package/dist/.next/server/pages-manifest.json +1 -1
- package/package.json +4 -2
- package/dist/public/skill/SKILL.md +0 -200
- package/dist/public/skill/aris-synapse-sync/SKILL.md +0 -368
- package/dist/public/skill/package.json +0 -79
- package/dist/public/skill/references/00-common-tools.md +0 -253
- package/dist/public/skill/references/01-setup.md +0 -251
- package/dist/public/skill/references/02-pm-workflow.md +0 -584
- package/dist/public/skill/references/03-developer-workflow.md +0 -325
- package/dist/public/skill/references/04-admin-workflow.md +0 -328
- package/dist/public/skill/references/06-claude-code-agent-teams.md +0 -233
- package/dist/public/synapse-plugin/.claude-plugin/plugin.json +0 -20
- package/dist/public/synapse-plugin/.mcp.json +0 -11
- package/dist/public/synapse-plugin/bin/on-post-create-experiment.sh +0 -61
- package/dist/public/synapse-plugin/bin/on-post-submit-results.sh +0 -56
- package/dist/public/synapse-plugin/bin/on-pre-enter-plan.sh +0 -26
- package/dist/public/synapse-plugin/bin/on-pre-exit-plan.sh +0 -22
- package/dist/public/synapse-plugin/bin/on-pre-spawn-agent.sh +0 -64
- package/dist/public/synapse-plugin/bin/on-session-end.sh +0 -39
- package/dist/public/synapse-plugin/bin/on-session-start.sh +0 -284
- package/dist/public/synapse-plugin/bin/on-subagent-start.sh +0 -233
- package/dist/public/synapse-plugin/bin/on-subagent-stop.sh +0 -80
- package/dist/public/synapse-plugin/bin/on-task-completed.sh +0 -66
- package/dist/public/synapse-plugin/bin/on-teammate-idle.sh +0 -47
- package/dist/public/synapse-plugin/bin/on-user-prompt.sh +0 -57
- package/dist/public/synapse-plugin/bin/synapse-api.sh +0 -387
- package/dist/public/synapse-plugin/bin/test-syntax.sh +0 -85
- package/dist/public/synapse-plugin/hooks/hooks.json +0 -125
- package/dist/public/synapse-plugin/skills/autonomy/SKILL.md +0 -177
- package/dist/public/synapse-plugin/skills/experiments/SKILL.md +0 -135
- package/dist/public/synapse-plugin/skills/research/SKILL.md +0 -58
- package/dist/public/synapse-plugin/skills/sessions/SKILL.md +0 -176
- package/dist/public/synapse-plugin/skills/setup/SKILL.md +0 -108
- package/dist/public/synapse-plugin/skills/synapse/SKILL.md +0 -145
- package/dist/public/synapse-plugin/skills/synapse/package.json +0 -49
- package/dist/public/synapse-plugin/skills/synapse/references/00-common-tools.md +0 -144
- package/dist/public/synapse-plugin/skills/synapse/references/01-setup.md +0 -130
- package/dist/public/synapse-plugin/skills/synapse/references/02-research-workflow.md +0 -145
- package/dist/public/synapse-plugin/skills/synapse/references/03-experiment-workflow.md +0 -319
- package/dist/public/synapse-plugin/skills/synapse/references/04-autonomous-loop.md +0 -223
- package/dist/public/synapse-plugin/skills/synapse/references/05-session-sub-agent.md +0 -253
- /package/dist/.next/static/{CTg26EE4IkxbdY0E6xEiL → VlyiqgSt6DSLuCX7rlcKa}/_buildManifest.js +0 -0
- /package/dist/.next/static/{CTg26EE4IkxbdY0E6xEiL → VlyiqgSt6DSLuCX7rlcKa}/_ssgManifest.js +0 -0
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# on-teammate-idle.sh — TeammateIdle hook
|
|
3
|
-
# Triggered when a teammate goes idle (between turns).
|
|
4
|
-
# Sends a heartbeat via MCP to keep the Synapse session active.
|
|
5
|
-
#
|
|
6
|
-
# Output: suppressed (heartbeats are frequent and noisy)
|
|
7
|
-
|
|
8
|
-
set -euo pipefail
|
|
9
|
-
|
|
10
|
-
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
11
|
-
API="${SCRIPT_DIR}/synapse-api.sh"
|
|
12
|
-
|
|
13
|
-
# Check environment
|
|
14
|
-
if [ -z "${SYNAPSE_URL:-}" ] || [ -z "${SYNAPSE_API_KEY:-}" ]; then
|
|
15
|
-
exit 0
|
|
16
|
-
fi
|
|
17
|
-
|
|
18
|
-
# Read event JSON from stdin
|
|
19
|
-
EVENT=""
|
|
20
|
-
if [ ! -t 0 ]; then
|
|
21
|
-
EVENT=$(cat)
|
|
22
|
-
fi
|
|
23
|
-
|
|
24
|
-
if [ -z "$EVENT" ]; then
|
|
25
|
-
exit 0
|
|
26
|
-
fi
|
|
27
|
-
|
|
28
|
-
# Extract teammate info from event
|
|
29
|
-
# TeammateIdle provides teammate_name (unlike SubagentStart/Stop which don't)
|
|
30
|
-
TEAMMATE_NAME=$(echo "$EVENT" | jq -r '.teammate_name // .teammateName // empty' 2>/dev/null) || true
|
|
31
|
-
|
|
32
|
-
# Try to find session UUID by teammate name first, then look up from state
|
|
33
|
-
SESSION_UUID=""
|
|
34
|
-
|
|
35
|
-
if [ -n "$TEAMMATE_NAME" ]; then
|
|
36
|
-
SESSION_UUID=$("$API" state-get "session_${TEAMMATE_NAME}" 2>/dev/null) || true
|
|
37
|
-
fi
|
|
38
|
-
|
|
39
|
-
if [ -z "$SESSION_UUID" ]; then
|
|
40
|
-
exit 0
|
|
41
|
-
fi
|
|
42
|
-
|
|
43
|
-
# Send heartbeat via MCP (suppress all output — heartbeats are too frequent to notify)
|
|
44
|
-
"$API" mcp-tool "synapse_session_heartbeat" "$(printf '{"sessionUuid":"%s"}' "$SESSION_UUID")" >/dev/null 2>&1 || true
|
|
45
|
-
|
|
46
|
-
# Suppress output entirely — no systemMessage for heartbeats
|
|
47
|
-
echo '{"suppressOutput": true}'
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# on-user-prompt.sh — UserPromptSubmit hook
|
|
3
|
-
# Fires on EVERY user message. Must be ultra-fast (<100ms).
|
|
4
|
-
# NO MCP calls, NO network calls — only local file checks.
|
|
5
|
-
# Injects a brief Synapse workflow reminder into Claude's context.
|
|
6
|
-
#
|
|
7
|
-
# Output: JSON with additionalContext (for Claude)
|
|
8
|
-
|
|
9
|
-
set -euo pipefail
|
|
10
|
-
|
|
11
|
-
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
12
|
-
STATE_DIR="${CLAUDE_PROJECT_DIR:-.}/.synapse"
|
|
13
|
-
SESSIONS_DIR="${STATE_DIR}/sessions"
|
|
14
|
-
|
|
15
|
-
# Skip entirely if Synapse is not configured
|
|
16
|
-
if [ -z "${SYNAPSE_URL:-}" ] || [ -z "${SYNAPSE_API_KEY:-}" ]; then
|
|
17
|
-
exit 0
|
|
18
|
-
fi
|
|
19
|
-
|
|
20
|
-
# Count active session files (fast local check)
|
|
21
|
-
SESSION_COUNT=0
|
|
22
|
-
SESSION_NAMES=""
|
|
23
|
-
if [ -d "$SESSIONS_DIR" ]; then
|
|
24
|
-
for f in "$SESSIONS_DIR"/*.json; do
|
|
25
|
-
[ -f "$f" ] || continue
|
|
26
|
-
SESSION_COUNT=$((SESSION_COUNT + 1))
|
|
27
|
-
NAME=$(basename "$f" .json)
|
|
28
|
-
if [ -n "$SESSION_NAMES" ]; then
|
|
29
|
-
SESSION_NAMES="${SESSION_NAMES}, ${NAME}"
|
|
30
|
-
else
|
|
31
|
-
SESSION_NAMES="$NAME"
|
|
32
|
-
fi
|
|
33
|
-
done
|
|
34
|
-
fi
|
|
35
|
-
|
|
36
|
-
# Build context — keep it concise to minimize token usage
|
|
37
|
-
CONTEXT="[Synapse Plugin Active]
|
|
38
|
-
- Sub-agent sessions are auto-managed by hooks (create/reuse/heartbeat/close).
|
|
39
|
-
- Do NOT call synapse_create_session or synapse_close_session for sub-agents — the plugin handles this.
|
|
40
|
-
- When spawning sub-agents: pass Synapse experiment UUIDs. Session UUID + Experiment workflow are auto-injected by SubagentStart hook.
|
|
41
|
-
- Link Claude Code work items to Synapse experiments with \`synapse:experiment:<uuid>\` in the description."
|
|
42
|
-
|
|
43
|
-
if [ "$SESSION_COUNT" -gt 0 ]; then
|
|
44
|
-
CONTEXT="${CONTEXT}
|
|
45
|
-
- Active sub-agent sessions (${SESSION_COUNT}): ${SESSION_NAMES}"
|
|
46
|
-
fi
|
|
47
|
-
|
|
48
|
-
# Output JSON — no systemMessage (too noisy for every turn)
|
|
49
|
-
if command -v jq &>/dev/null; then
|
|
50
|
-
jq -n --arg ac "$CONTEXT" '{additionalContext: $ac}'
|
|
51
|
-
else
|
|
52
|
-
# Fallback
|
|
53
|
-
AC_ESCAPED="${CONTEXT//\\/\\\\}"
|
|
54
|
-
AC_ESCAPED="${AC_ESCAPED//\"/\\\"}"
|
|
55
|
-
AC_ESCAPED="${AC_ESCAPED//$'\n'/\\n}"
|
|
56
|
-
printf '{"additionalContext":"%s"}\n' "$AC_ESCAPED"
|
|
57
|
-
fi
|
|
@@ -1,387 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# synapse-api.sh — Lightweight REST API wrapper for Synapse session management
|
|
3
|
-
# Used by hook scripts to communicate with Synapse backend.
|
|
4
|
-
#
|
|
5
|
-
# Environment variables:
|
|
6
|
-
# SYNAPSE_URL — Synapse base URL (e.g., http://localhost:3000)
|
|
7
|
-
# SYNAPSE_API_KEY — Agent API key (syn_xxx)
|
|
8
|
-
#
|
|
9
|
-
# State file: $CLAUDE_PROJECT_DIR/.synapse/state.json (gitignored)
|
|
10
|
-
|
|
11
|
-
set -euo pipefail
|
|
12
|
-
|
|
13
|
-
# ===== Configuration =====
|
|
14
|
-
|
|
15
|
-
SYNAPSE_URL="${SYNAPSE_URL:-}"
|
|
16
|
-
SYNAPSE_API_KEY="${SYNAPSE_API_KEY:-}"
|
|
17
|
-
STATE_DIR="${CLAUDE_PROJECT_DIR:-.}/.synapse"
|
|
18
|
-
STATE_FILE="${STATE_DIR}/state.json"
|
|
19
|
-
|
|
20
|
-
# ===== Helpers =====
|
|
21
|
-
|
|
22
|
-
die() {
|
|
23
|
-
echo "ERROR: $*" >&2
|
|
24
|
-
exit 1
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
require_env() {
|
|
28
|
-
[ -n "$SYNAPSE_URL" ] || die "SYNAPSE_URL is not set"
|
|
29
|
-
[ -n "$SYNAPSE_API_KEY" ] || die "SYNAPSE_API_KEY is not set"
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
# Make an authenticated API request to Synapse
|
|
33
|
-
# Usage: api_call METHOD PATH [DATA]
|
|
34
|
-
api_call() {
|
|
35
|
-
local method="$1"
|
|
36
|
-
local path="$2"
|
|
37
|
-
local data="${3:-}"
|
|
38
|
-
|
|
39
|
-
local args=(
|
|
40
|
-
-s -S
|
|
41
|
-
-X "$method"
|
|
42
|
-
-H "Authorization: Bearer ${SYNAPSE_API_KEY}"
|
|
43
|
-
-H "Content-Type: application/json"
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
if [ -n "$data" ]; then
|
|
47
|
-
args+=(-d "$data")
|
|
48
|
-
fi
|
|
49
|
-
|
|
50
|
-
local response
|
|
51
|
-
response=$(curl "${args[@]}" "${SYNAPSE_URL}${path}" 2>&1) || {
|
|
52
|
-
echo "CURL_ERROR: Failed to reach ${SYNAPSE_URL}${path}" >&2
|
|
53
|
-
return 1
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
echo "$response"
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
# Ensure state directory and file exist
|
|
60
|
-
ensure_state() {
|
|
61
|
-
mkdir -p "$STATE_DIR"
|
|
62
|
-
if [ ! -f "$STATE_FILE" ]; then
|
|
63
|
-
echo '{}' > "$STATE_FILE"
|
|
64
|
-
fi
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
# ===== State Management =====
|
|
68
|
-
|
|
69
|
-
state_get() {
|
|
70
|
-
local key="$1"
|
|
71
|
-
ensure_state
|
|
72
|
-
if command -v jq &>/dev/null; then
|
|
73
|
-
jq -r --arg k "$key" '.[$k] // empty' "$STATE_FILE"
|
|
74
|
-
else
|
|
75
|
-
# Fallback: simple grep-based extraction
|
|
76
|
-
grep -o "\"${key}\":\"[^\"]*\"" "$STATE_FILE" 2>/dev/null | cut -d'"' -f4
|
|
77
|
-
fi
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
state_set() {
|
|
81
|
-
local key="$1"
|
|
82
|
-
local value="$2"
|
|
83
|
-
ensure_state
|
|
84
|
-
# Use flock to serialize concurrent state writes (multiple SubagentStart hooks
|
|
85
|
-
# may run in parallel, each calling state-set multiple times).
|
|
86
|
-
(
|
|
87
|
-
flock -w 5 200 || { echo "WARN: state_set flock timeout for key=$key" >&2; return 0; }
|
|
88
|
-
if command -v jq &>/dev/null; then
|
|
89
|
-
local tmp
|
|
90
|
-
tmp=$(mktemp)
|
|
91
|
-
jq --arg k "$key" --arg v "$value" '.[$k] = $v' "$STATE_FILE" > "$tmp" && mv "$tmp" "$STATE_FILE"
|
|
92
|
-
else
|
|
93
|
-
if grep -q "\"${key}\":" "$STATE_FILE" 2>/dev/null; then
|
|
94
|
-
sed -i "s|\"${key}\":\"[^\"]*\"|\"${key}\":\"${value}\"|" "$STATE_FILE"
|
|
95
|
-
else
|
|
96
|
-
local tmp
|
|
97
|
-
tmp=$(mktemp)
|
|
98
|
-
sed "s|}$|,\"${key}\":\"${value}\"}|" "$STATE_FILE" > "$tmp" && mv "$tmp" "$STATE_FILE"
|
|
99
|
-
fi
|
|
100
|
-
fi
|
|
101
|
-
) 200>"${STATE_FILE}.lock"
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
state_delete() {
|
|
105
|
-
local key="$1"
|
|
106
|
-
ensure_state
|
|
107
|
-
(
|
|
108
|
-
flock -w 5 200 || { echo "WARN: state_delete flock timeout for key=$key" >&2; return 0; }
|
|
109
|
-
if command -v jq &>/dev/null; then
|
|
110
|
-
local tmp
|
|
111
|
-
tmp=$(mktemp)
|
|
112
|
-
jq --arg k "$key" 'del(.[$k])' "$STATE_FILE" > "$tmp" && mv "$tmp" "$STATE_FILE"
|
|
113
|
-
fi
|
|
114
|
-
) 200>"${STATE_FILE}.lock"
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
# ===== Hook Output =====
|
|
118
|
-
# Produces JSON that Claude Code parses:
|
|
119
|
-
# systemMessage → shown to user as notification
|
|
120
|
-
# hookSpecificOutput.additionalContext → injected into Claude's context (LLM sees this)
|
|
121
|
-
# hookSpecificOutput.hookEventName → identifies which hook event produced this context
|
|
122
|
-
#
|
|
123
|
-
# Usage: hook_output "User-visible message" "Context for Claude LLM" ["HookEventName"]
|
|
124
|
-
hook_output() {
|
|
125
|
-
local system_message="$1"
|
|
126
|
-
local additional_context="${2:-}"
|
|
127
|
-
local hook_event_name="${3:-}"
|
|
128
|
-
local updated_input_json="${4:-}" # Optional: raw JSON object for updatedInput
|
|
129
|
-
if command -v jq &>/dev/null; then
|
|
130
|
-
if [ -n "$updated_input_json" ]; then
|
|
131
|
-
# Build output with updatedInput (for PreToolUse parameter modification)
|
|
132
|
-
jq -n \
|
|
133
|
-
--arg sm "$system_message" \
|
|
134
|
-
--arg ac "$additional_context" \
|
|
135
|
-
--arg hen "$hook_event_name" \
|
|
136
|
-
--argjson ui "$updated_input_json" \
|
|
137
|
-
'{systemMessage: $sm, hookSpecificOutput: {hookEventName: $hen, additionalContext: $ac, updatedInput: $ui}}'
|
|
138
|
-
elif [ -n "$additional_context" ]; then
|
|
139
|
-
jq -n \
|
|
140
|
-
--arg sm "$system_message" \
|
|
141
|
-
--arg ac "$additional_context" \
|
|
142
|
-
--arg hen "$hook_event_name" \
|
|
143
|
-
'{systemMessage: $sm, hookSpecificOutput: {hookEventName: $hen, additionalContext: $ac}}'
|
|
144
|
-
else
|
|
145
|
-
jq -n \
|
|
146
|
-
--arg sm "$system_message" \
|
|
147
|
-
'{systemMessage: $sm}'
|
|
148
|
-
fi
|
|
149
|
-
else
|
|
150
|
-
# Fallback: manual JSON — escape newlines and quotes
|
|
151
|
-
local sm_escaped="${system_message//\\/\\\\}"
|
|
152
|
-
sm_escaped="${sm_escaped//\"/\\\"}"
|
|
153
|
-
sm_escaped="${sm_escaped//$'\n'/\\n}"
|
|
154
|
-
if [ -n "$additional_context" ]; then
|
|
155
|
-
local ac_escaped="${additional_context//\\/\\\\}"
|
|
156
|
-
ac_escaped="${ac_escaped//\"/\\\"}"
|
|
157
|
-
ac_escaped="${ac_escaped//$'\n'/\\n}"
|
|
158
|
-
printf '{"systemMessage":"%s","hookSpecificOutput":{"hookEventName":"%s","additionalContext":"%s"}}\n' "$sm_escaped" "$hook_event_name" "$ac_escaped"
|
|
159
|
-
else
|
|
160
|
-
printf '{"systemMessage":"%s"}\n' "$sm_escaped"
|
|
161
|
-
fi
|
|
162
|
-
fi
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
# ===== Session File Management (Plan A) =====
|
|
166
|
-
|
|
167
|
-
SESSIONS_DIR="${STATE_DIR}/sessions"
|
|
168
|
-
|
|
169
|
-
# Read a session file by agent name
|
|
170
|
-
# Usage: session_file_read <agent_name>
|
|
171
|
-
session_file_read() {
|
|
172
|
-
local name="$1"
|
|
173
|
-
local file="${SESSIONS_DIR}/${name}.json"
|
|
174
|
-
if [ -f "$file" ]; then
|
|
175
|
-
cat "$file"
|
|
176
|
-
else
|
|
177
|
-
echo "" >&2
|
|
178
|
-
return 1
|
|
179
|
-
fi
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
# List all session files
|
|
183
|
-
session_file_list() {
|
|
184
|
-
if [ ! -d "$SESSIONS_DIR" ]; then
|
|
185
|
-
echo "[]"
|
|
186
|
-
return
|
|
187
|
-
fi
|
|
188
|
-
if command -v jq &>/dev/null; then
|
|
189
|
-
local result="["
|
|
190
|
-
local first=true
|
|
191
|
-
for f in "$SESSIONS_DIR"/*.json; do
|
|
192
|
-
[ -f "$f" ] || continue
|
|
193
|
-
if [ "$first" = true ]; then
|
|
194
|
-
first=false
|
|
195
|
-
else
|
|
196
|
-
result="${result},"
|
|
197
|
-
fi
|
|
198
|
-
result="${result}$(cat "$f")"
|
|
199
|
-
done
|
|
200
|
-
result="${result}]"
|
|
201
|
-
echo "$result" | jq '.'
|
|
202
|
-
else
|
|
203
|
-
ls "$SESSIONS_DIR"/*.json 2>/dev/null | while read -r f; do
|
|
204
|
-
basename "$f" .json
|
|
205
|
-
done
|
|
206
|
-
fi
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
# ===== Subcommands =====
|
|
210
|
-
|
|
211
|
-
cmd_checkin() {
|
|
212
|
-
require_env
|
|
213
|
-
api_call GET "/api/health"
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
# Call an MCP tool via JSON-RPC over HTTP Streamable Transport
|
|
217
|
-
# Usage: cmd_mcp_tool <tool_name> [arguments_json]
|
|
218
|
-
# Returns the text content from the tool result
|
|
219
|
-
cmd_mcp_tool() {
|
|
220
|
-
local tool_name="${1:-}"
|
|
221
|
-
local arguments="${2:-{\}}"
|
|
222
|
-
[ -n "$tool_name" ] || die "Usage: synapse-api.sh mcp-tool <tool_name> [arguments_json]"
|
|
223
|
-
require_env
|
|
224
|
-
ensure_state
|
|
225
|
-
|
|
226
|
-
local mcp_url="${SYNAPSE_URL}/api/mcp"
|
|
227
|
-
local auth_header="Authorization: Bearer ${SYNAPSE_API_KEY}"
|
|
228
|
-
local max_retries=3
|
|
229
|
-
local retry_count=0
|
|
230
|
-
local session_id=""
|
|
231
|
-
local tool_response=""
|
|
232
|
-
|
|
233
|
-
# Retry loop for auto-reconnection on 404 (session expired)
|
|
234
|
-
while [ $retry_count -le $max_retries ]; do
|
|
235
|
-
# Step 1: Initialize MCP session
|
|
236
|
-
local init_payload
|
|
237
|
-
init_payload=$(cat <<JSONEOF
|
|
238
|
-
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"synapse-hook","version":"0.1.1"}}}
|
|
239
|
-
JSONEOF
|
|
240
|
-
)
|
|
241
|
-
|
|
242
|
-
# Use a unique temp file for headers to avoid concurrent hooks overwriting each other
|
|
243
|
-
local headers_file
|
|
244
|
-
headers_file=$(mktemp "${STATE_DIR}/.mcp_headers.XXXXXX")
|
|
245
|
-
|
|
246
|
-
local init_response
|
|
247
|
-
init_response=$(curl -s -S -X POST \
|
|
248
|
-
-H "$auth_header" \
|
|
249
|
-
-H "Content-Type: application/json" \
|
|
250
|
-
-H "Accept: application/json, text/event-stream" \
|
|
251
|
-
-D "$headers_file" \
|
|
252
|
-
-d "$init_payload" \
|
|
253
|
-
"$mcp_url" 2>/dev/null) || { rm -f "$headers_file"; die "MCP initialize failed"; }
|
|
254
|
-
|
|
255
|
-
# Extract session ID from response headers (optional — stateless servers don't return one)
|
|
256
|
-
session_id=$(grep -i "^mcp-session-id:" "$headers_file" 2>/dev/null | tr -d '\r' | awk '{print $2}') || true
|
|
257
|
-
rm -f "$headers_file"
|
|
258
|
-
|
|
259
|
-
# Build session header (empty string if stateless server returned no session ID)
|
|
260
|
-
local session_header=""
|
|
261
|
-
if [ -n "$session_id" ]; then
|
|
262
|
-
session_header="mcp-session-id: $session_id"
|
|
263
|
-
fi
|
|
264
|
-
|
|
265
|
-
# Step 2: Send initialized notification
|
|
266
|
-
local notif_payload='{"jsonrpc":"2.0","method":"notifications/initialized"}'
|
|
267
|
-
if [ -n "$session_header" ]; then
|
|
268
|
-
curl -s -S -X POST \
|
|
269
|
-
-H "$auth_header" \
|
|
270
|
-
-H "Content-Type: application/json" \
|
|
271
|
-
-H "Accept: application/json, text/event-stream" \
|
|
272
|
-
-H "$session_header" \
|
|
273
|
-
-d "$notif_payload" \
|
|
274
|
-
"$mcp_url" >/dev/null 2>&1 || true
|
|
275
|
-
else
|
|
276
|
-
curl -s -S -X POST \
|
|
277
|
-
-H "$auth_header" \
|
|
278
|
-
-H "Content-Type: application/json" \
|
|
279
|
-
-H "Accept: application/json, text/event-stream" \
|
|
280
|
-
-d "$notif_payload" \
|
|
281
|
-
"$mcp_url" >/dev/null 2>&1 || true
|
|
282
|
-
fi
|
|
283
|
-
|
|
284
|
-
# Step 3: Call the tool
|
|
285
|
-
local call_payload
|
|
286
|
-
call_payload=$(printf '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"%s","arguments":%s}}' "$tool_name" "$arguments")
|
|
287
|
-
|
|
288
|
-
# Capture HTTP status code and response separately
|
|
289
|
-
local http_code
|
|
290
|
-
local response_file
|
|
291
|
-
response_file=$(mktemp "${STATE_DIR}/.mcp_response.XXXXXX")
|
|
292
|
-
|
|
293
|
-
if [ -n "$session_header" ]; then
|
|
294
|
-
http_code=$(curl -s -S -X POST \
|
|
295
|
-
-H "$auth_header" \
|
|
296
|
-
-H "Content-Type: application/json" \
|
|
297
|
-
-H "Accept: application/json, text/event-stream" \
|
|
298
|
-
-H "$session_header" \
|
|
299
|
-
-d "$call_payload" \
|
|
300
|
-
-w "%{http_code}" \
|
|
301
|
-
-o "$response_file" \
|
|
302
|
-
"$mcp_url" 2>/dev/null) || http_code="000"
|
|
303
|
-
else
|
|
304
|
-
http_code=$(curl -s -S -X POST \
|
|
305
|
-
-H "$auth_header" \
|
|
306
|
-
-H "Content-Type: application/json" \
|
|
307
|
-
-H "Accept: application/json, text/event-stream" \
|
|
308
|
-
-d "$call_payload" \
|
|
309
|
-
-w "%{http_code}" \
|
|
310
|
-
-o "$response_file" \
|
|
311
|
-
"$mcp_url" 2>/dev/null) || http_code="000"
|
|
312
|
-
fi
|
|
313
|
-
|
|
314
|
-
# Check if session expired (404)
|
|
315
|
-
if [ "$http_code" = "404" ]; then
|
|
316
|
-
retry_count=$((retry_count + 1))
|
|
317
|
-
rm -f "$response_file"
|
|
318
|
-
|
|
319
|
-
if [ $retry_count -le $max_retries ]; then
|
|
320
|
-
# Session expired - retry with new session
|
|
321
|
-
continue
|
|
322
|
-
else
|
|
323
|
-
die "MCP session expired after retry. Please reinitialize."
|
|
324
|
-
fi
|
|
325
|
-
fi
|
|
326
|
-
|
|
327
|
-
# Read the response
|
|
328
|
-
tool_response=$(cat "$response_file")
|
|
329
|
-
rm -f "$response_file"
|
|
330
|
-
|
|
331
|
-
# Break the retry loop - request succeeded
|
|
332
|
-
break
|
|
333
|
-
done
|
|
334
|
-
|
|
335
|
-
# Step 4: Close session (best effort, only for stateful servers)
|
|
336
|
-
if [ -n "$session_id" ]; then
|
|
337
|
-
curl -s -S -X DELETE \
|
|
338
|
-
-H "$auth_header" \
|
|
339
|
-
-H "mcp-session-id: $session_id" \
|
|
340
|
-
"$mcp_url" >/dev/null 2>&1 || true
|
|
341
|
-
fi
|
|
342
|
-
|
|
343
|
-
# Response may be SSE format (event: message\ndata: {...}) or plain JSON
|
|
344
|
-
# Strip SSE framing to get the JSON payload
|
|
345
|
-
local json_response
|
|
346
|
-
if echo "$tool_response" | grep -q "^data: "; then
|
|
347
|
-
json_response=$(echo "$tool_response" | grep "^data: " | head -1 | sed 's/^data: //')
|
|
348
|
-
else
|
|
349
|
-
json_response="$tool_response"
|
|
350
|
-
fi
|
|
351
|
-
|
|
352
|
-
# Extract text content from result
|
|
353
|
-
if command -v jq &>/dev/null; then
|
|
354
|
-
echo "$json_response" | jq -r '.result.content[]? | select(.type=="text") | .text // empty' 2>/dev/null || echo "$json_response"
|
|
355
|
-
else
|
|
356
|
-
echo "$json_response"
|
|
357
|
-
fi
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
# ===== Main Dispatch =====
|
|
361
|
-
|
|
362
|
-
cmd="${1:-}"
|
|
363
|
-
shift || true
|
|
364
|
-
|
|
365
|
-
case "$cmd" in
|
|
366
|
-
checkin) cmd_checkin "$@" ;;
|
|
367
|
-
mcp-tool) cmd_mcp_tool "$@" ;;
|
|
368
|
-
state-get) state_get "${1:-}" ;;
|
|
369
|
-
state-set) state_set "${1:-}" "${2:-}" ;;
|
|
370
|
-
state-delete) state_delete "${1:-}" ;;
|
|
371
|
-
session-read) session_file_read "${1:-}" ;;
|
|
372
|
-
session-list) session_file_list ;;
|
|
373
|
-
hook-output) hook_output "${1:-}" "${2:-}" "${3:-}" "${4:-}" ;;
|
|
374
|
-
*)
|
|
375
|
-
echo "Usage: synapse-api.sh <command> [args...]"
|
|
376
|
-
echo ""
|
|
377
|
-
echo "Commands:"
|
|
378
|
-
echo " checkin Check connectivity with Synapse"
|
|
379
|
-
echo " mcp-tool <name> [args_json] Call an MCP tool via JSON-RPC"
|
|
380
|
-
echo " state-get <key> Read from state.json"
|
|
381
|
-
echo " state-set <key> <value> Write to state.json"
|
|
382
|
-
echo " state-delete <key> Delete key from state.json"
|
|
383
|
-
echo " session-read <name> Read session file for an agent"
|
|
384
|
-
echo " session-list List all pre-created session files"
|
|
385
|
-
exit 1
|
|
386
|
-
;;
|
|
387
|
-
esac
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Test all plugin shell scripts for compatibility with the current bash version.
|
|
3
|
-
# Runs each script with mock input and mock env to catch runtime errors
|
|
4
|
-
# (e.g., ${VAR,,} on Bash 3.2).
|
|
5
|
-
#
|
|
6
|
-
# Usage:
|
|
7
|
-
# /bin/bash public/synapse-plugin/bin/test-syntax.sh # test with macOS system bash 3.2
|
|
8
|
-
# bash public/synapse-plugin/bin/test-syntax.sh # test with default bash
|
|
9
|
-
|
|
10
|
-
set -euo pipefail
|
|
11
|
-
|
|
12
|
-
DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
13
|
-
PASS=0
|
|
14
|
-
FAIL=0
|
|
15
|
-
FAILED=""
|
|
16
|
-
|
|
17
|
-
echo "Using: $BASH ($("$BASH" --version | head -1))"
|
|
18
|
-
echo ""
|
|
19
|
-
|
|
20
|
-
# Mock env so scripts don't exit early on env guards.
|
|
21
|
-
# Use a bogus URL — scripts will fail on actual API calls but that's fine,
|
|
22
|
-
# we only care about bash syntax/substitution errors before the API call.
|
|
23
|
-
export SYNAPSE_URL="http://localhost:0"
|
|
24
|
-
export SYNAPSE_API_KEY="syn_test"
|
|
25
|
-
export CLAUDE_PROJECT_DIR="/tmp/synapse-test-$$"
|
|
26
|
-
mkdir -p "$CLAUDE_PROJECT_DIR"
|
|
27
|
-
|
|
28
|
-
cleanup() { rm -rf "$CLAUDE_PROJECT_DIR"; }
|
|
29
|
-
trap cleanup EXIT
|
|
30
|
-
|
|
31
|
-
# Mock event payloads for each hook type
|
|
32
|
-
run_test() {
|
|
33
|
-
local name="$1"
|
|
34
|
-
local input="$2"
|
|
35
|
-
local script="$DIR/$name"
|
|
36
|
-
local err_file="/tmp/synapse-test-err-$$"
|
|
37
|
-
|
|
38
|
-
# Capture both stdout and stderr; expect exit 0 or exit due to API call failure.
|
|
39
|
-
# We grep stderr for "bad substitution" to detect Bash version issues.
|
|
40
|
-
if printf '%s' "$input" | "$BASH" "$script" >"$err_file" 2>&1; then
|
|
41
|
-
printf " PASS %s\n" "$name"
|
|
42
|
-
PASS=$((PASS + 1))
|
|
43
|
-
else
|
|
44
|
-
# Check if it's a bash substitution error vs expected API failure
|
|
45
|
-
if grep -qi "bad substitution\|syntax error\|unexpected token" "$err_file"; then
|
|
46
|
-
printf " FAIL %s (bash compatibility error)\n" "$name"
|
|
47
|
-
sed 's/^/ /' "$err_file"
|
|
48
|
-
FAIL=$((FAIL + 1))
|
|
49
|
-
FAILED="$FAILED $name"
|
|
50
|
-
else
|
|
51
|
-
# Non-zero exit from API call / curl failure is expected — not a bash issue
|
|
52
|
-
printf " PASS %s (exited non-zero but no bash error)\n" "$name"
|
|
53
|
-
PASS=$((PASS + 1))
|
|
54
|
-
fi
|
|
55
|
-
fi
|
|
56
|
-
rm -f "$err_file"
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
# --- PreToolUse hooks ---
|
|
60
|
-
run_test "on-pre-spawn-agent.sh" '{"tool_input":{"subagent_type":"Explore","name":"test"}}'
|
|
61
|
-
run_test "on-pre-spawn-agent.sh" '{"tool_input":{"subagent_type":"general-purpose","name":"worker"}}'
|
|
62
|
-
run_test "on-pre-enter-plan.sh" '{}'
|
|
63
|
-
run_test "on-pre-exit-plan.sh" '{}'
|
|
64
|
-
|
|
65
|
-
# --- Lifecycle hooks (need agent_id/agent_type) ---
|
|
66
|
-
run_test "on-subagent-start.sh" '{"agent_id":"agent-001","agent_type":"Explore"}'
|
|
67
|
-
run_test "on-subagent-start.sh" '{"agent_id":"agent-002","agent_type":"general-purpose"}'
|
|
68
|
-
run_test "on-subagent-stop.sh" '{"agent_id":"agent-001","agent_type":"general-purpose"}'
|
|
69
|
-
run_test "on-teammate-idle.sh" '{"agent_id":"agent-001","agent_type":"general-purpose"}'
|
|
70
|
-
run_test "on-task-completed.sh" '{"task_id":"work-item-001","task_description":"Complete the analysis and sync notes to synapse:experiment:00000000-0000-0000-0000-000000000000"}'
|
|
71
|
-
|
|
72
|
-
# --- Session hooks ---
|
|
73
|
-
run_test "on-session-start.sh" '{}'
|
|
74
|
-
run_test "on-session-end.sh" '{}'
|
|
75
|
-
|
|
76
|
-
# --- User prompt hook ---
|
|
77
|
-
run_test "on-user-prompt.sh" '{}'
|
|
78
|
-
|
|
79
|
-
echo ""
|
|
80
|
-
echo "Results: $PASS passed, $FAIL failed"
|
|
81
|
-
|
|
82
|
-
if [ "$FAIL" -gt 0 ]; then
|
|
83
|
-
echo "Failed:$FAILED"
|
|
84
|
-
exit 1
|
|
85
|
-
fi
|