harnery 0.0.1 → 0.2.0
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/LICENSE +21 -0
- package/README.md +84 -2
- package/bin/agent-coord +42 -0
- package/bin/agent-hook +44 -0
- package/bin/harn +40 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +18 -0
- package/dist/commander.d.ts +128 -0
- package/dist/commander.d.ts.map +1 -0
- package/dist/commander.js +126 -0
- package/dist/commands/agents.d.ts +18 -0
- package/dist/commands/agents.d.ts.map +1 -0
- package/dist/commands/agents.js +3946 -0
- package/dist/commands/backup.d.ts +22 -0
- package/dist/commands/backup.d.ts.map +1 -0
- package/dist/commands/backup.js +262 -0
- package/dist/commands/browse-ai.d.ts +4 -0
- package/dist/commands/browse-ai.d.ts.map +1 -0
- package/dist/commands/browse-ai.js +156 -0
- package/dist/commands/browse.d.ts +4 -0
- package/dist/commands/browse.d.ts.map +1 -0
- package/dist/commands/browse.js +590 -0
- package/dist/commands/callers.d.ts +4 -0
- package/dist/commands/callers.d.ts.map +1 -0
- package/dist/commands/callers.js +276 -0
- package/dist/commands/completion.d.ts +17 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +158 -0
- package/dist/commands/config-get.d.ts +4 -0
- package/dist/commands/config-get.d.ts.map +1 -0
- package/dist/commands/config-get.js +131 -0
- package/dist/commands/context.d.ts +11 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +185 -0
- package/dist/commands/cookies.d.ts +4 -0
- package/dist/commands/cookies.d.ts.map +1 -0
- package/dist/commands/cookies.js +140 -0
- package/dist/commands/docs.d.ts +4 -0
- package/dist/commands/docs.d.ts.map +1 -0
- package/dist/commands/docs.js +137 -0
- package/dist/commands/doctor.d.ts +25 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +200 -0
- package/dist/commands/edit-batch.d.ts +18 -0
- package/dist/commands/edit-batch.d.ts.map +1 -0
- package/dist/commands/edit-batch.js +172 -0
- package/dist/commands/eml.d.ts +4 -0
- package/dist/commands/eml.d.ts.map +1 -0
- package/dist/commands/eml.js +428 -0
- package/dist/commands/env.d.ts +4 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +201 -0
- package/dist/commands/fetch.d.ts +4 -0
- package/dist/commands/fetch.d.ts.map +1 -0
- package/dist/commands/fetch.js +99 -0
- package/dist/commands/file-history.d.ts +4 -0
- package/dist/commands/file-history.d.ts.map +1 -0
- package/dist/commands/file-history.js +152 -0
- package/dist/commands/grep.d.ts +4 -0
- package/dist/commands/grep.d.ts.map +1 -0
- package/dist/commands/grep.js +317 -0
- package/dist/commands/init.d.ts +82 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +288 -0
- package/dist/commands/outline.d.ts +4 -0
- package/dist/commands/outline.d.ts.map +1 -0
- package/dist/commands/outline.js +494 -0
- package/dist/commands/presence.d.ts +12 -0
- package/dist/commands/presence.d.ts.map +1 -0
- package/dist/commands/presence.js +123 -0
- package/dist/commands/read.d.ts +7 -0
- package/dist/commands/read.d.ts.map +1 -0
- package/dist/commands/read.js +46 -0
- package/dist/commands/scratch.d.ts +4 -0
- package/dist/commands/scratch.d.ts.map +1 -0
- package/dist/commands/scratch.js +426 -0
- package/dist/commands/session.d.ts +4 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +162 -0
- package/dist/commands/sync.d.ts +24 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +275 -0
- package/dist/commands/toc.d.ts +5 -0
- package/dist/commands/toc.d.ts.map +1 -0
- package/dist/commands/toc.js +153 -0
- package/dist/commands/tokens.d.ts +4 -0
- package/dist/commands/tokens.d.ts.map +1 -0
- package/dist/commands/tokens.js +48 -0
- package/dist/commands/tunnel.d.ts +4 -0
- package/dist/commands/tunnel.d.ts.map +1 -0
- package/dist/commands/tunnel.js +513 -0
- package/dist/commands/uninstall.d.ts +22 -0
- package/dist/commands/uninstall.d.ts.map +1 -0
- package/dist/commands/uninstall.js +126 -0
- package/dist/commands/web.d.ts +4 -0
- package/dist/commands/web.d.ts.map +1 -0
- package/dist/commands/web.js +165 -0
- package/dist/core/agents/canonical-emit.d.ts +27 -0
- package/dist/core/agents/canonical-emit.d.ts.map +1 -0
- package/dist/core/agents/canonical-emit.js +72 -0
- package/dist/core/agents/cli-emit.d.ts +27 -0
- package/dist/core/agents/cli-emit.d.ts.map +1 -0
- package/dist/core/agents/cli-emit.js +57 -0
- package/dist/core/agents/cli.d.ts +10 -0
- package/dist/core/agents/cli.d.ts.map +1 -0
- package/dist/core/agents/cli.js +757 -0
- package/dist/core/agents/codex-replay.d.ts +29 -0
- package/dist/core/agents/codex-replay.d.ts.map +1 -0
- package/dist/core/agents/codex-replay.js +138 -0
- package/dist/core/agents/coord-client.d.ts +98 -0
- package/dist/core/agents/coord-client.d.ts.map +1 -0
- package/dist/core/agents/coord-client.js +212 -0
- package/dist/core/agents/events/consume.d.ts +59 -0
- package/dist/core/agents/events/consume.d.ts.map +1 -0
- package/dist/core/agents/events/consume.js +147 -0
- package/dist/core/agents/events/emit.d.ts +42 -0
- package/dist/core/agents/events/emit.d.ts.map +1 -0
- package/dist/core/agents/events/emit.js +70 -0
- package/dist/core/agents/events/ulid.d.ts +11 -0
- package/dist/core/agents/events/ulid.d.ts.map +1 -0
- package/dist/core/agents/events/ulid.js +47 -0
- package/dist/core/agents/index.d.ts +14 -0
- package/dist/core/agents/index.d.ts.map +1 -0
- package/dist/core/agents/index.js +13 -0
- package/dist/core/agents/paths.d.ts +6 -0
- package/dist/core/agents/paths.d.ts.map +1 -0
- package/dist/core/agents/paths.js +17 -0
- package/dist/core/agents/render/prompt-context.d.ts +43 -0
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -0
- package/dist/core/agents/render/prompt-context.js +335 -0
- package/dist/core/agents/render/session-context.d.ts +39 -0
- package/dist/core/agents/render/session-context.d.ts.map +1 -0
- package/dist/core/agents/render/session-context.js +283 -0
- package/dist/core/agents/rules/claim-conflict.d.ts +35 -0
- package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -0
- package/dist/core/agents/rules/claim-conflict.js +244 -0
- package/dist/core/agents/rules/commit-conflict.d.ts +59 -0
- package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -0
- package/dist/core/agents/rules/commit-conflict.js +244 -0
- package/dist/core/agents/rules/stop-hook.d.ts +44 -0
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -0
- package/dist/core/agents/rules/stop-hook.js +161 -0
- package/dist/core/agents/session-events.d.ts +41 -0
- package/dist/core/agents/session-events.d.ts.map +1 -0
- package/dist/core/agents/session-events.js +205 -0
- package/dist/core/agents/state/activity-log.d.ts +18 -0
- package/dist/core/agents/state/activity-log.d.ts.map +1 -0
- package/dist/core/agents/state/activity-log.js +34 -0
- package/dist/core/agents/state/council.d.ts +39 -0
- package/dist/core/agents/state/council.d.ts.map +1 -0
- package/dist/core/agents/state/council.js +216 -0
- package/dist/core/agents/state/heartbeat-projector.d.ts +59 -0
- package/dist/core/agents/state/heartbeat-projector.d.ts.map +1 -0
- package/dist/core/agents/state/heartbeat-projector.js +436 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts +64 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -0
- package/dist/core/agents/state/heartbeat-writer.js +271 -0
- package/dist/core/agents/state/names.d.ts +35 -0
- package/dist/core/agents/state/names.d.ts.map +1 -0
- package/dist/core/agents/state/names.js +376 -0
- package/dist/core/agents/state/pidmap.d.ts +11 -0
- package/dist/core/agents/state/pidmap.d.ts.map +1 -0
- package/dist/core/agents/state/pidmap.js +32 -0
- package/dist/core/agents/state/scratch.d.ts +27 -0
- package/dist/core/agents/state/scratch.d.ts.map +1 -0
- package/dist/core/agents/state/scratch.js +90 -0
- package/dist/core/agents/state/shell-mutation.d.ts +17 -0
- package/dist/core/agents/state/shell-mutation.d.ts.map +1 -0
- package/dist/core/agents/state/shell-mutation.js +41 -0
- package/dist/core/agents/state/stale-sweep.d.ts +16 -0
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -0
- package/dist/core/agents/state/stale-sweep.js +166 -0
- package/dist/core/config.d.ts +29 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +108 -0
- package/dist/core/hooks/cli.d.ts +21 -0
- package/dist/core/hooks/cli.d.ts.map +1 -0
- package/dist/core/hooks/cli.js +1123 -0
- package/dist/core/hooks/effects/image-capture.d.ts +43 -0
- package/dist/core/hooks/effects/image-capture.d.ts.map +1 -0
- package/dist/core/hooks/effects/image-capture.js +288 -0
- package/dist/core/hooks/effects/index.d.ts +64 -0
- package/dist/core/hooks/effects/index.d.ts.map +1 -0
- package/dist/core/hooks/effects/index.js +197 -0
- package/dist/core/hooks/events/emit.d.ts +31 -0
- package/dist/core/hooks/events/emit.d.ts.map +1 -0
- package/dist/core/hooks/events/emit.js +89 -0
- package/dist/core/hooks/events/schema.d.ts +235 -0
- package/dist/core/hooks/events/schema.d.ts.map +1 -0
- package/dist/core/hooks/events/schema.js +12 -0
- package/dist/core/hooks/events/ulid.d.ts +10 -0
- package/dist/core/hooks/events/ulid.d.ts.map +1 -0
- package/dist/core/hooks/events/ulid.js +47 -0
- package/dist/core/hooks/harness/detect.d.ts +9 -0
- package/dist/core/hooks/harness/detect.d.ts.map +1 -0
- package/dist/core/hooks/harness/detect.js +29 -0
- package/dist/core/hooks/harness/events.d.ts +45 -0
- package/dist/core/hooks/harness/events.d.ts.map +1 -0
- package/dist/core/hooks/harness/events.js +71 -0
- package/dist/core/hooks/harness/output.d.ts +46 -0
- package/dist/core/hooks/harness/output.d.ts.map +1 -0
- package/dist/core/hooks/harness/output.js +87 -0
- package/dist/core/hooks/harness/parse.d.ts +67 -0
- package/dist/core/hooks/harness/parse.d.ts.map +1 -0
- package/dist/core/hooks/harness/parse.js +132 -0
- package/dist/core/hooks/index.d.ts +8 -0
- package/dist/core/hooks/index.d.ts.map +1 -0
- package/dist/core/hooks/index.js +7 -0
- package/dist/core/hooks/resolve/anchor.d.ts +37 -0
- package/dist/core/hooks/resolve/anchor.d.ts.map +1 -0
- package/dist/core/hooks/resolve/anchor.js +48 -0
- package/dist/core/hooks/resolve/coord-root.d.ts +6 -0
- package/dist/core/hooks/resolve/coord-root.d.ts.map +1 -0
- package/dist/core/hooks/resolve/coord-root.js +27 -0
- package/dist/core/hooks/resolve/intent.d.ts +33 -0
- package/dist/core/hooks/resolve/intent.d.ts.map +1 -0
- package/dist/core/hooks/resolve/intent.js +79 -0
- package/dist/core/hooks/resolve/owner.d.ts +42 -0
- package/dist/core/hooks/resolve/owner.d.ts.map +1 -0
- package/dist/core/hooks/resolve/owner.js +140 -0
- package/dist/core/hooks/resolve/transcript.d.ts +26 -0
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -0
- package/dist/core/hooks/resolve/transcript.js +73 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/lib/agent-browser/client.d.ts +99 -0
- package/dist/lib/agent-browser/client.d.ts.map +1 -0
- package/dist/lib/agent-browser/client.js +177 -0
- package/dist/lib/agent-browser/index.d.ts +2 -0
- package/dist/lib/agent-browser/index.d.ts.map +1 -0
- package/dist/lib/agent-browser/index.js +1 -0
- package/dist/lib/browser/client.d.ts +193 -0
- package/dist/lib/browser/client.d.ts.map +1 -0
- package/dist/lib/browser/client.js +325 -0
- package/dist/lib/browser/dev-overlay.d.ts +23 -0
- package/dist/lib/browser/dev-overlay.d.ts.map +1 -0
- package/dist/lib/browser/dev-overlay.js +153 -0
- package/dist/lib/browser/index.d.ts +5 -0
- package/dist/lib/browser/index.d.ts.map +1 -0
- package/dist/lib/browser/index.js +2 -0
- package/dist/lib/browser/layout.d.ts +79 -0
- package/dist/lib/browser/layout.d.ts.map +1 -0
- package/dist/lib/browser/layout.js +220 -0
- package/dist/lib/browser/visibility.d.ts +86 -0
- package/dist/lib/browser/visibility.d.ts.map +1 -0
- package/dist/lib/browser/visibility.js +333 -0
- package/dist/lib/browser/visual-diff.d.ts +38 -0
- package/dist/lib/browser/visual-diff.d.ts.map +1 -0
- package/dist/lib/browser/visual-diff.js +107 -0
- package/dist/lib/completion/bash.d.ts +25 -0
- package/dist/lib/completion/bash.d.ts.map +1 -0
- package/dist/lib/completion/bash.js +284 -0
- package/dist/lib/completion/fish.d.ts +16 -0
- package/dist/lib/completion/fish.d.ts.map +1 -0
- package/dist/lib/completion/fish.js +118 -0
- package/dist/lib/completion/index.d.ts +5 -0
- package/dist/lib/completion/index.d.ts.map +1 -0
- package/dist/lib/completion/index.js +4 -0
- package/dist/lib/completion/walk.d.ts +68 -0
- package/dist/lib/completion/walk.d.ts.map +1 -0
- package/dist/lib/completion/walk.js +102 -0
- package/dist/lib/completion/zsh.d.ts +13 -0
- package/dist/lib/completion/zsh.d.ts.map +1 -0
- package/dist/lib/completion/zsh.js +249 -0
- package/dist/lib/context/index.d.ts +107 -0
- package/dist/lib/context/index.d.ts.map +1 -0
- package/dist/lib/context/index.js +275 -0
- package/dist/lib/cookies/client.d.ts +131 -0
- package/dist/lib/cookies/client.d.ts.map +1 -0
- package/dist/lib/cookies/client.js +239 -0
- package/dist/lib/cookies/index.d.ts +2 -0
- package/dist/lib/cookies/index.d.ts.map +1 -0
- package/dist/lib/cookies/index.js +1 -0
- package/dist/lib/council/index.d.ts +266 -0
- package/dist/lib/council/index.d.ts.map +1 -0
- package/dist/lib/council/index.js +674 -0
- package/dist/lib/docs-index.d.ts +28 -0
- package/dist/lib/docs-index.d.ts.map +1 -0
- package/dist/lib/docs-index.js +169 -0
- package/dist/lib/docs-lint.d.ts +26 -0
- package/dist/lib/docs-lint.d.ts.map +1 -0
- package/dist/lib/docs-lint.js +378 -0
- package/dist/lib/docs-sweep.d.ts +34 -0
- package/dist/lib/docs-sweep.d.ts.map +1 -0
- package/dist/lib/docs-sweep.js +304 -0
- package/dist/lib/docs.d.ts +27 -0
- package/dist/lib/docs.d.ts.map +1 -0
- package/dist/lib/docs.js +142 -0
- package/dist/lib/env.d.ts +11 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +12 -0
- package/dist/lib/exec.d.ts +32 -0
- package/dist/lib/exec.d.ts.map +1 -0
- package/dist/lib/exec.js +54 -0
- package/dist/lib/format.d.ts +29 -0
- package/dist/lib/format.d.ts.map +1 -0
- package/dist/lib/format.js +139 -0
- package/dist/lib/http/client.d.ts +56 -0
- package/dist/lib/http/client.d.ts.map +1 -0
- package/dist/lib/http/client.js +160 -0
- package/dist/lib/http/index.d.ts +2 -0
- package/dist/lib/http/index.d.ts.map +1 -0
- package/dist/lib/http/index.js +1 -0
- package/dist/lib/identities/index.d.ts +77 -0
- package/dist/lib/identities/index.d.ts.map +1 -0
- package/dist/lib/identities/index.js +190 -0
- package/dist/lib/machine.d.ts +19 -0
- package/dist/lib/machine.d.ts.map +1 -0
- package/dist/lib/machine.js +61 -0
- package/dist/lib/presence.d.ts +48 -0
- package/dist/lib/presence.d.ts.map +1 -0
- package/dist/lib/presence.js +123 -0
- package/dist/lib/readability/client.d.ts +32 -0
- package/dist/lib/readability/client.d.ts.map +1 -0
- package/dist/lib/readability/client.js +119 -0
- package/dist/lib/readability/index.d.ts +2 -0
- package/dist/lib/readability/index.d.ts.map +1 -0
- package/dist/lib/readability/index.js +1 -0
- package/dist/lib/scratch/index.d.ts +74 -0
- package/dist/lib/scratch/index.d.ts.map +1 -0
- package/dist/lib/scratch/index.js +393 -0
- package/dist/lib/tunnel/gate.d.ts +12 -0
- package/dist/lib/tunnel/gate.d.ts.map +1 -0
- package/dist/lib/tunnel/gate.js +101 -0
- package/dist/lib/tunnel/state.d.ts +34 -0
- package/dist/lib/tunnel/state.d.ts.map +1 -0
- package/dist/lib/tunnel/state.js +132 -0
- package/package.json +160 -8
- package/schemas/.gitkeep +0 -0
- package/schemas/config.schema.json +109 -0
- package/src/cli.ts +22 -0
- package/src/commander.ts +242 -0
- package/src/commands/.gitkeep +0 -0
- package/src/commands/agents.ts +4567 -0
- package/src/commands/backup.ts +305 -0
- package/src/commands/browse-ai.ts +198 -0
- package/src/commands/browse.ts +849 -0
- package/src/commands/callers.ts +363 -0
- package/src/commands/completion.ts +193 -0
- package/src/commands/config-get.ts +161 -0
- package/src/commands/context.ts +209 -0
- package/src/commands/cookies.ts +198 -0
- package/src/commands/docs.ts +174 -0
- package/src/commands/doctor.ts +231 -0
- package/src/commands/edit-batch.ts +233 -0
- package/src/commands/eml.ts +519 -0
- package/src/commands/env.ts +254 -0
- package/src/commands/fetch.ts +136 -0
- package/src/commands/file-history.ts +202 -0
- package/src/commands/grep.ts +371 -0
- package/src/commands/init.ts +335 -0
- package/src/commands/outline.ts +564 -0
- package/src/commands/presence.ts +152 -0
- package/src/commands/read.ts +64 -0
- package/src/commands/scratch.ts +445 -0
- package/src/commands/session.ts +187 -0
- package/src/commands/sync.ts +306 -0
- package/src/commands/toc.ts +218 -0
- package/src/commands/tokens.ts +79 -0
- package/src/commands/tunnel.ts +633 -0
- package/src/commands/uninstall.ts +144 -0
- package/src/commands/web.ts +193 -0
- package/src/core/agents/canonical-emit.ts +77 -0
- package/src/core/agents/cli-emit.ts +64 -0
- package/src/core/agents/cli.ts +838 -0
- package/src/core/agents/codex-replay.ts +163 -0
- package/src/core/agents/coord-client.ts +249 -0
- package/src/core/agents/events/consume.ts +196 -0
- package/src/core/agents/events/emit.ts +108 -0
- package/src/core/agents/events/ulid.ts +51 -0
- package/src/core/agents/index.ts +14 -0
- package/src/core/agents/paths.ts +16 -0
- package/src/core/agents/render/prompt-context.ts +401 -0
- package/src/core/agents/render/session-context.ts +341 -0
- package/src/core/agents/rules/claim-conflict.ts +282 -0
- package/src/core/agents/rules/commit-conflict.ts +303 -0
- package/src/core/agents/rules/stop-hook.ts +229 -0
- package/src/core/agents/session-events.ts +228 -0
- package/src/core/agents/state/activity-log.ts +33 -0
- package/src/core/agents/state/council.ts +265 -0
- package/src/core/agents/state/heartbeat-projector.ts +488 -0
- package/src/core/agents/state/heartbeat-writer.ts +333 -0
- package/src/core/agents/state/names.ts +399 -0
- package/src/core/agents/state/pidmap.ts +38 -0
- package/src/core/agents/state/scratch.ts +121 -0
- package/src/core/agents/state/shell-mutation.ts +44 -0
- package/src/core/agents/state/stale-sweep.ts +190 -0
- package/src/core/config.ts +111 -0
- package/src/core/hooks/cli.ts +1247 -0
- package/src/core/hooks/effects/image-capture.ts +330 -0
- package/src/core/hooks/effects/index.ts +210 -0
- package/src/core/hooks/events/emit.ts +120 -0
- package/src/core/hooks/events/schema.ts +430 -0
- package/src/core/hooks/events/ulid.ts +51 -0
- package/src/core/hooks/harness/detect.ts +30 -0
- package/src/core/hooks/harness/events.ts +102 -0
- package/src/core/hooks/harness/output.ts +100 -0
- package/src/core/hooks/harness/parse.ts +180 -0
- package/src/core/hooks/index.ts +16 -0
- package/src/core/hooks/resolve/anchor.ts +51 -0
- package/src/core/hooks/resolve/coord-root.ts +25 -0
- package/src/core/hooks/resolve/intent.ts +89 -0
- package/src/core/hooks/resolve/owner.ts +140 -0
- package/src/core/hooks/resolve/transcript.ts +72 -0
- package/src/hooks/.gitkeep +0 -0
- package/src/index.ts +15 -0
- package/src/lib/agent-browser/client.ts +239 -0
- package/src/lib/agent-browser/index.ts +1 -0
- package/src/lib/browser/client.ts +449 -0
- package/src/lib/browser/dev-overlay.ts +207 -0
- package/src/lib/browser/index.ts +24 -0
- package/src/lib/browser/layout.ts +288 -0
- package/src/lib/browser/visibility.ts +419 -0
- package/src/lib/browser/visual-diff.ts +150 -0
- package/src/lib/completion/bash.ts +291 -0
- package/src/lib/completion/fish.ts +134 -0
- package/src/lib/completion/index.ts +10 -0
- package/src/lib/completion/walk.ts +184 -0
- package/src/lib/completion/zsh.ts +262 -0
- package/src/lib/context/index.ts +386 -0
- package/src/lib/cookies/client.ts +301 -0
- package/src/lib/cookies/index.ts +13 -0
- package/src/lib/council/index.ts +803 -0
- package/src/lib/docs-index.ts +216 -0
- package/src/lib/docs-lint.ts +413 -0
- package/src/lib/docs-sweep.ts +348 -0
- package/src/lib/docs.ts +199 -0
- package/src/lib/env.ts +12 -0
- package/src/lib/exec.ts +74 -0
- package/src/lib/format.ts +147 -0
- package/src/lib/http/client.ts +211 -0
- package/src/lib/http/index.ts +1 -0
- package/src/lib/identities/index.ts +210 -0
- package/src/lib/machine.ts +61 -0
- package/src/lib/presence.ts +154 -0
- package/src/lib/readability/client.ts +156 -0
- package/src/lib/readability/index.ts +5 -0
- package/src/lib/readability/turndown-plugin-gfm.d.ts +10 -0
- package/src/lib/scratch/index.ts +470 -0
- package/src/lib/tunnel/gate.ts +113 -0
- package/src/lib/tunnel/state.ts +167 -0
- package/src/web/.gitkeep +0 -0
- package/index.js +0 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { appendFileSync, closeSync, mkdirSync, openSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { SCHEMA_VERSION, } from "./schema.js";
|
|
4
|
+
import { ulid } from "./ulid.js";
|
|
5
|
+
const LOCK_FILE = ".harnery/events.ndjson.lock";
|
|
6
|
+
const STREAM_FILE = ".harnery/events.ndjson";
|
|
7
|
+
const MAX_LINE_BYTES = 64 * 1024;
|
|
8
|
+
/**
|
|
9
|
+
* Build a canonical envelope around the caller's `data` payload. Pure;
|
|
10
|
+
* doesn't touch the filesystem. Useful for tests + replay fixtures.
|
|
11
|
+
*/
|
|
12
|
+
export function buildEnvelope(input) {
|
|
13
|
+
return {
|
|
14
|
+
schema_version: SCHEMA_VERSION,
|
|
15
|
+
event_id: ulid(),
|
|
16
|
+
event_type: input.event_type,
|
|
17
|
+
ts: input.ts ?? new Date().toISOString(),
|
|
18
|
+
instance_id: input.instance_id,
|
|
19
|
+
session_id: input.session_id,
|
|
20
|
+
parent_session_id: input.parent_session_id,
|
|
21
|
+
turn_id: input.turn_id,
|
|
22
|
+
parent_turn_id: input.parent_turn_id,
|
|
23
|
+
harness: input.harness,
|
|
24
|
+
source: input.source ?? "agent-hooks",
|
|
25
|
+
data: input.data,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Append one canonical event to `.harnery/events.ndjson` under a file lock.
|
|
30
|
+
* Append-only, one JSON object per line, lock-serialized.
|
|
31
|
+
*
|
|
32
|
+
* Synchronous because hooks are short-lived processes: we want the append to
|
|
33
|
+
* land before the binary exits, and async/await across a tiny write is just
|
|
34
|
+
* latency for no benefit.
|
|
35
|
+
*
|
|
36
|
+
* Returns the envelope so callers can chain off it (debug logs, post-emit
|
|
37
|
+
* verdict requests).
|
|
38
|
+
*/
|
|
39
|
+
export function emit(coordRoot, input) {
|
|
40
|
+
const envelope = buildEnvelope(input);
|
|
41
|
+
const streamPath = join(coordRoot, STREAM_FILE);
|
|
42
|
+
const lockPath = join(coordRoot, LOCK_FILE);
|
|
43
|
+
ensureDir(dirname(streamPath));
|
|
44
|
+
ensureFile(lockPath);
|
|
45
|
+
let line = `${JSON.stringify(envelope)}\n`;
|
|
46
|
+
if (Buffer.byteLength(line, "utf8") > MAX_LINE_BYTES) {
|
|
47
|
+
// lines >64KB are a schema bug. Phase 2 hard-truncates the `data`
|
|
48
|
+
// payload + sets `truncated: true` so we keep audit visibility without
|
|
49
|
+
// breaking downstream consumers.
|
|
50
|
+
const truncated = `${JSON.stringify({
|
|
51
|
+
...envelope,
|
|
52
|
+
data: { __over_size_limit: true, original_bytes: Buffer.byteLength(line, "utf8") },
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
54
|
+
})}\n`;
|
|
55
|
+
line = truncated;
|
|
56
|
+
}
|
|
57
|
+
const lockFd = openSync(lockPath, "r+");
|
|
58
|
+
try {
|
|
59
|
+
// flock isn't directly exposed in node fs; use fcntl-like via shelling out
|
|
60
|
+
// would be slower than POSIX flock(2) inside the kernel. Bun exposes
|
|
61
|
+
// `Bun.flock` in recent builds, but a simple fs-level append is atomic
|
|
62
|
+
// for lines <PIPE_BUF (4KB on Linux) anyway. For larger lines we rely on
|
|
63
|
+
// append-mode flag (O_APPEND) which kernels serialize per-fd.
|
|
64
|
+
//
|
|
65
|
+
// The `events.ndjson.lock` file is kept around for forward
|
|
66
|
+
// compatibility: Phase 4+ helpers acquire it before multi-write batches.
|
|
67
|
+
appendFileSync(streamPath, line, { encoding: "utf8", flag: "a" });
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
closeSync(lockFd);
|
|
71
|
+
}
|
|
72
|
+
return envelope;
|
|
73
|
+
}
|
|
74
|
+
function ensureDir(path) {
|
|
75
|
+
try {
|
|
76
|
+
mkdirSync(path, { recursive: true });
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
/* swallow */
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function ensureFile(path) {
|
|
83
|
+
try {
|
|
84
|
+
closeSync(openSync(path, "a"));
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
/* swallow */
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical event schema v1. Inter-module contract between agent-hooks (writer)
|
|
3
|
+
* and agent-coord (consumer + projector).
|
|
4
|
+
*
|
|
5
|
+
* Schema evolution rules:
|
|
6
|
+
* - Forward-compatible only within a major version. Consumers ignore unknown
|
|
7
|
+
* fields. Adding an optional field is a minor bump; removing or retyping a
|
|
8
|
+
* field is a major bump.
|
|
9
|
+
* - Mixed-version streams are legal during migrations; consumers branch on
|
|
10
|
+
* `schema_version`.
|
|
11
|
+
*/
|
|
12
|
+
export declare const SCHEMA_VERSION: 1;
|
|
13
|
+
export type Harness = "claude-code" | "cursor" | "codex";
|
|
14
|
+
export type Source = "agent-hooks" | "agent-coord" | "user" | "system";
|
|
15
|
+
/**
|
|
16
|
+
* Common envelope every event carries. Tool events, `user_prompt.submit`, and
|
|
17
|
+
* `turn.stop` MUST carry `turn_id`; CLI/state/council/presence/health/session
|
|
18
|
+
* events MAY carry `turn_id` when agent-coord can bind them to the active turn
|
|
19
|
+
* for that owner.
|
|
20
|
+
*/
|
|
21
|
+
export interface EventEnvelope<TType extends string, TData> {
|
|
22
|
+
schema_version: typeof SCHEMA_VERSION;
|
|
23
|
+
event_id: string;
|
|
24
|
+
event_type: TType;
|
|
25
|
+
ts: string;
|
|
26
|
+
instance_id: string;
|
|
27
|
+
session_id: string;
|
|
28
|
+
parent_session_id?: string;
|
|
29
|
+
turn_id?: string;
|
|
30
|
+
parent_turn_id?: string;
|
|
31
|
+
harness: Harness;
|
|
32
|
+
source: Source;
|
|
33
|
+
data: TData;
|
|
34
|
+
}
|
|
35
|
+
export type SessionStart = EventEnvelope<"session.start", {
|
|
36
|
+
started_at: string;
|
|
37
|
+
cwd: string;
|
|
38
|
+
model?: string;
|
|
39
|
+
pid: number;
|
|
40
|
+
}>;
|
|
41
|
+
export type SessionEnd = EventEnvelope<"session.end", {
|
|
42
|
+
ended_at: string;
|
|
43
|
+
clean_exit: boolean;
|
|
44
|
+
}>;
|
|
45
|
+
export type SubagentStart = EventEnvelope<"subagent.start", {
|
|
46
|
+
agent_type: string;
|
|
47
|
+
prompt_summary?: string;
|
|
48
|
+
}>;
|
|
49
|
+
export type SubagentStop = EventEnvelope<"subagent.stop", {
|
|
50
|
+
exit_status: "ok" | "error" | "interrupted";
|
|
51
|
+
}>;
|
|
52
|
+
export type UserPromptSubmit = EventEnvelope<"user_prompt.submit", {
|
|
53
|
+
prompt_text: string;
|
|
54
|
+
truncated?: boolean;
|
|
55
|
+
}>;
|
|
56
|
+
export type TurnStop = EventEnvelope<"turn.stop", {
|
|
57
|
+
tool_call_count: number;
|
|
58
|
+
text_length: number;
|
|
59
|
+
status_box_present: boolean;
|
|
60
|
+
}>;
|
|
61
|
+
export type CommandStart = EventEnvelope<"command.start", {
|
|
62
|
+
cmd_id: string;
|
|
63
|
+
intent?: string;
|
|
64
|
+
cmd: string;
|
|
65
|
+
}>;
|
|
66
|
+
export type CommandOutput = EventEnvelope<"command.output", {
|
|
67
|
+
cmd_id: string;
|
|
68
|
+
stream: "stdout" | "stderr";
|
|
69
|
+
line: string;
|
|
70
|
+
}>;
|
|
71
|
+
export type CommandEnd = EventEnvelope<"command.end", {
|
|
72
|
+
cmd_id: string;
|
|
73
|
+
exit: number;
|
|
74
|
+
duration_ms: number;
|
|
75
|
+
signal?: string;
|
|
76
|
+
}>;
|
|
77
|
+
export type Narration = EventEnvelope<"narration", {
|
|
78
|
+
message: string;
|
|
79
|
+
}>;
|
|
80
|
+
export type ToolPreUse = EventEnvelope<"tool.pre_use", {
|
|
81
|
+
tool_name: string;
|
|
82
|
+
tool_input: unknown;
|
|
83
|
+
intent?: string;
|
|
84
|
+
truncated?: boolean;
|
|
85
|
+
}>;
|
|
86
|
+
export type ToolPostUse = EventEnvelope<"tool.post_use", {
|
|
87
|
+
tool_name: string;
|
|
88
|
+
output_summary: string;
|
|
89
|
+
exit_status: "ok" | "error";
|
|
90
|
+
duration_ms: number;
|
|
91
|
+
truncated?: boolean;
|
|
92
|
+
}>;
|
|
93
|
+
export type ToolPostUseFailure = EventEnvelope<"tool.post_use_failure", {
|
|
94
|
+
tool_name: string;
|
|
95
|
+
error: string;
|
|
96
|
+
duration_ms: number;
|
|
97
|
+
}>;
|
|
98
|
+
export type ToolOutputChunk = EventEnvelope<"tool.output_chunk", {
|
|
99
|
+
chunk: string;
|
|
100
|
+
chunk_no: number;
|
|
101
|
+
stream: "stdout" | "stderr";
|
|
102
|
+
truncated?: boolean;
|
|
103
|
+
}>;
|
|
104
|
+
/**
|
|
105
|
+
* An image an agent viewed (Read tool) or produced (a Bash command wrote it).
|
|
106
|
+
* Emitted by agent-hooks as a side-effect of a tool event when the tool
|
|
107
|
+
* references an image path on disk; the bytes are content-addressed into
|
|
108
|
+
* `.harnery/images/<hash>.<ext>` (dedup) and this event records the provenance
|
|
109
|
+
* for the web image feed. Grouped by `hash` downstream → one card per distinct
|
|
110
|
+
* image with a touch timeline.
|
|
111
|
+
*/
|
|
112
|
+
export type ImageCaptured = EventEnvelope<"image.captured", {
|
|
113
|
+
hash: string;
|
|
114
|
+
ext: string;
|
|
115
|
+
bytes: number;
|
|
116
|
+
role: "viewed" | "produced";
|
|
117
|
+
source_path: string;
|
|
118
|
+
tool_name: string;
|
|
119
|
+
tool_use_id?: string;
|
|
120
|
+
intent?: string;
|
|
121
|
+
command_head?: string;
|
|
122
|
+
}>;
|
|
123
|
+
export type ClaimAcquire = EventEnvelope<"claim.acquire", {
|
|
124
|
+
path: string;
|
|
125
|
+
mode: "read" | "write";
|
|
126
|
+
}>;
|
|
127
|
+
export type ClaimRelease = EventEnvelope<"claim.release", {
|
|
128
|
+
path: string;
|
|
129
|
+
reason: "explicit" | "turn_end" | "session_end" | "heal";
|
|
130
|
+
}>;
|
|
131
|
+
export type ClaimConflict = EventEnvelope<"claim.conflict", {
|
|
132
|
+
path: string;
|
|
133
|
+
peer_instance_id: string;
|
|
134
|
+
reason?: "ordering_violation" | "concurrent_write";
|
|
135
|
+
}>;
|
|
136
|
+
export type StateTaskSet = EventEnvelope<"state.task_set", {
|
|
137
|
+
task: string;
|
|
138
|
+
cleared: boolean;
|
|
139
|
+
}>;
|
|
140
|
+
export type StateStatusChecked = EventEnvelope<"state.status_checked", {
|
|
141
|
+
format: "box" | "json" | "table";
|
|
142
|
+
agent_count: number;
|
|
143
|
+
included_self: boolean;
|
|
144
|
+
}>;
|
|
145
|
+
export type StateScratchAppend = EventEnvelope<"state.scratch_append", {
|
|
146
|
+
category: "note" | "plan" | "decision" | "blocker" | "question" | "done" | "handoff";
|
|
147
|
+
body_summary: string;
|
|
148
|
+
}>;
|
|
149
|
+
export type StatePresenceChange = EventEnvelope<"state.presence_change", {
|
|
150
|
+
from: "mobile" | "office";
|
|
151
|
+
to: "mobile" | "office";
|
|
152
|
+
source: "hook" | "cli" | "user";
|
|
153
|
+
}>;
|
|
154
|
+
export type StateHeartbeat = EventEnvelope<"state.heartbeat", Record<string, never>>;
|
|
155
|
+
export type CouncilOpen = EventEnvelope<"council.open", {
|
|
156
|
+
council_id: string;
|
|
157
|
+
topic: string;
|
|
158
|
+
members: string[];
|
|
159
|
+
target_doc?: string;
|
|
160
|
+
}>;
|
|
161
|
+
export type CouncilRoundOpen = EventEnvelope<"council.round_open", {
|
|
162
|
+
council_id: string;
|
|
163
|
+
round_no: number;
|
|
164
|
+
}>;
|
|
165
|
+
export type CouncilContribution = EventEnvelope<"council.contribution", {
|
|
166
|
+
council_id: string;
|
|
167
|
+
round_no: number;
|
|
168
|
+
member: string;
|
|
169
|
+
body_summary: string;
|
|
170
|
+
}>;
|
|
171
|
+
export type CouncilRoundClose = EventEnvelope<"council.round_close", {
|
|
172
|
+
council_id: string;
|
|
173
|
+
round_no: number;
|
|
174
|
+
}>;
|
|
175
|
+
export type CouncilClose = EventEnvelope<"council.close", {
|
|
176
|
+
council_id: string;
|
|
177
|
+
closed_at: string;
|
|
178
|
+
}>;
|
|
179
|
+
export type CouncilArchive = EventEnvelope<"council.archive", {
|
|
180
|
+
council_id: string;
|
|
181
|
+
}>;
|
|
182
|
+
export type DecisionBlock = EventEnvelope<"decision.block", {
|
|
183
|
+
rule: string;
|
|
184
|
+
reason: string;
|
|
185
|
+
}>;
|
|
186
|
+
export type DecisionWarn = EventEnvelope<"decision.warn", {
|
|
187
|
+
rule: string;
|
|
188
|
+
reason: string;
|
|
189
|
+
}>;
|
|
190
|
+
export type DecisionAllow = EventEnvelope<"decision.allow", {
|
|
191
|
+
rule: string;
|
|
192
|
+
}>;
|
|
193
|
+
export type HealthHeartbeatHeal = EventEnvelope<"health.heartbeat_heal", {
|
|
194
|
+
reason: string;
|
|
195
|
+
}>;
|
|
196
|
+
export type HealthPidmapHeal = EventEnvelope<"health.pidmap_heal", {
|
|
197
|
+
reason: string;
|
|
198
|
+
}>;
|
|
199
|
+
/**
|
|
200
|
+
* A heartbeat file was removed by stale-sweep. Symmetric with
|
|
201
|
+
* `health.heartbeat_heal` so the full lifecycle (created → healed → swept) is
|
|
202
|
+
* auditable from the event stream alone. Sweeps were silent before, which
|
|
203
|
+
* made "why did this agent vanish?" un-answerable without guesswork.
|
|
204
|
+
* `reason`: "stale" (last_heartbeat past the freshness cutoff) | "unparseable"
|
|
205
|
+
* (JSON.parse failed AND mtime was old) | "missing_ts" (no last_heartbeat AND
|
|
206
|
+
* mtime was old). Fresh-mtime files are never swept regardless of content.
|
|
207
|
+
*/
|
|
208
|
+
export type HealthHeartbeatSwept = EventEnvelope<"health.heartbeat_swept", {
|
|
209
|
+
reason: "stale" | "unparseable" | "missing_ts";
|
|
210
|
+
age_secs?: number;
|
|
211
|
+
}>;
|
|
212
|
+
/**
|
|
213
|
+
* fail-open verdict failure mode. Emitted by agent-hooks when
|
|
214
|
+
* `agent-coord verdict` fails to spawn / exits non-zero / returns malformed
|
|
215
|
+
* JSON / times out. Adapter falls through to ALLOW; the event preserves the
|
|
216
|
+
* fail-open for audit.
|
|
217
|
+
*/
|
|
218
|
+
export type HealthVerdictFailure = EventEnvelope<"health.verdict_failure", {
|
|
219
|
+
failure_kind: "spawn_failed" | "nonzero_exit" | "malformed_json" | "timeout";
|
|
220
|
+
timeout_ms?: number;
|
|
221
|
+
fallback: "allow";
|
|
222
|
+
}>;
|
|
223
|
+
export type Event = SessionStart | SessionEnd | SubagentStart | SubagentStop | UserPromptSubmit | TurnStop | CommandStart | CommandOutput | CommandEnd | Narration | ToolPreUse | ToolPostUse | ToolPostUseFailure | ToolOutputChunk | ImageCaptured | ClaimAcquire | ClaimRelease | ClaimConflict | StateTaskSet | StateStatusChecked | StateScratchAppend | StatePresenceChange | StateHeartbeat | CouncilOpen | CouncilRoundOpen | CouncilContribution | CouncilRoundClose | CouncilClose | CouncilArchive | DecisionBlock | DecisionWarn | DecisionAllow | HealthHeartbeatHeal | HealthPidmapHeal | HealthHeartbeatSwept | HealthVerdictFailure;
|
|
224
|
+
export type EventType = Event["event_type"];
|
|
225
|
+
/**
|
|
226
|
+
* Redaction marker that may be attached to any `data` payload during emission.
|
|
227
|
+
* Tracked here so the schema documents the convention; the actual
|
|
228
|
+
* shape lives inside `data` so it doesn't widen the envelope.
|
|
229
|
+
*/
|
|
230
|
+
export interface RedactionMarker {
|
|
231
|
+
field: string;
|
|
232
|
+
kind: "secret_signature" | "env_secret_match" | "length_clamp";
|
|
233
|
+
count: number;
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/events/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,cAAc,EAAG,CAAU,CAAC;AAEzC,MAAM,MAAM,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEzD,MAAM,MAAM,MAAM,GAAG,aAAa,GAAG,aAAa,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,WAAW,aAAa,CAAC,KAAK,SAAS,MAAM,EAAE,KAAK;IACxD,cAAc,EAAE,OAAO,cAAc,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,KAAK,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,KAAK,CAAC;CACb;AAKD,MAAM,MAAM,YAAY,GAAG,aAAa,CACtC,eAAe,EACf;IACE,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb,CACF,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,aAAa,CACpC,aAAa,EACb;IACE,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;CACrB,CACF,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,aAAa,CACvC,gBAAgB,EAChB;IACE,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CACF,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,aAAa,CACtC,eAAe,EACf;IACE,WAAW,EAAE,IAAI,GAAG,OAAO,GAAG,aAAa,CAAC;CAC7C,CACF,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAC1C,oBAAoB,EACpB;IACE,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CACF,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,aAAa,CAClC,WAAW,EACX;IACE,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,OAAO,CAAC;CAC7B,CACF,CAAC;AAGF,MAAM,MAAM,YAAY,GAAG,aAAa,CACtC,eAAe,EACf;IACE,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb,CACF,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,aAAa,CACvC,gBAAgB,EAChB;IACE,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd,CACF,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,aAAa,CACpC,aAAa,EACb;IACE,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CACF,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,aAAa,CACnC,WAAW,EACX;IACE,OAAO,EAAE,MAAM,CAAC;CACjB,CACF,CAAC;AAGF,MAAM,MAAM,UAAU,GAAG,aAAa,CACpC,cAAc,EACd;IACE,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CACF,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,aAAa,CACrC,eAAe,EACf;IACE,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,IAAI,GAAG,OAAO,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CACF,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,aAAa,CAC5C,uBAAuB,EACvB;IACE,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB,CACF,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,aAAa,CACzC,mBAAmB,EACnB;IACE,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CACF,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GAAG,aAAa,CACvC,gBAAgB,EAChB;IACE,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CACF,CAAC;AAGF,MAAM,MAAM,YAAY,GAAG,aAAa,CACtC,eAAe,EACf;IACE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CACF,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,aAAa,CACtC,eAAe,EACf;IACE,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,aAAa,GAAG,MAAM,CAAC;CAC1D,CACF,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,aAAa,CACvC,gBAAgB,EAChB;IACE,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,oBAAoB,GAAG,kBAAkB,CAAC;CACpD,CACF,CAAC;AAGF,MAAM,MAAM,YAAY,GAAG,aAAa,CACtC,gBAAgB,EAChB;IACE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB,CACF,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,aAAa,CAC5C,sBAAsB,EACtB;IACE,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;CACxB,CACF,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,aAAa,CAC5C,sBAAsB,EACtB;IACE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;IACrF,YAAY,EAAE,MAAM,CAAC;CACtB,CACF,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,aAAa,CAC7C,uBAAuB,EACvB;IACE,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,EAAE,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;CACjC,CACF,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,aAAa,CAAC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AAGrF,MAAM,MAAM,WAAW,GAAG,aAAa,CACrC,cAAc,EACd;IACE,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CACF,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAC1C,oBAAoB,EACpB;IACE,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CACF,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,aAAa,CAC7C,sBAAsB,EACtB;IACE,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB,CACF,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,aAAa,CAC3C,qBAAqB,EACrB;IACE,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CACF,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,aAAa,CACtC,eAAe,EACf;IACE,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB,CACF,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,aAAa,CACxC,iBAAiB,EACjB;IACE,UAAU,EAAE,MAAM,CAAC;CACpB,CACF,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG,aAAa,CACvC,gBAAgB,EAChB;IACE,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CACF,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,aAAa,CACtC,eAAe,EACf;IACE,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CACF,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,aAAa,CACvC,gBAAgB,EAChB;IACE,IAAI,EAAE,MAAM,CAAC;CACd,CACF,CAAC;AAGF,MAAM,MAAM,mBAAmB,GAAG,aAAa,CAC7C,uBAAuB,EACvB;IACE,MAAM,EAAE,MAAM,CAAC;CAChB,CACF,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAC1C,oBAAoB,EACpB;IACE,MAAM,EAAE,MAAM,CAAC;CAChB,CACF,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,GAAG,aAAa,CAC9C,wBAAwB,EACxB;IACE,MAAM,EAAE,OAAO,GAAG,aAAa,GAAG,YAAY,CAAC;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CACF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,aAAa,CAC9C,wBAAwB,EACxB;IACE,YAAY,EAAE,cAAc,GAAG,cAAc,GAAG,gBAAgB,GAAG,SAAS,CAAC;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB,CACF,CAAC;AAIF,MAAM,MAAM,KAAK,GACb,YAAY,GACZ,UAAU,GACV,aAAa,GACb,YAAY,GACZ,gBAAgB,GAChB,QAAQ,GACR,YAAY,GACZ,aAAa,GACb,UAAU,GACV,SAAS,GACT,UAAU,GACV,WAAW,GACX,kBAAkB,GAClB,eAAe,GACf,aAAa,GACb,YAAY,GACZ,YAAY,GACZ,aAAa,GACb,YAAY,GACZ,kBAAkB,GAClB,kBAAkB,GAClB,mBAAmB,GACnB,cAAc,GACd,WAAW,GACX,gBAAgB,GAChB,mBAAmB,GACnB,iBAAiB,GACjB,YAAY,GACZ,cAAc,GACd,aAAa,GACb,YAAY,GACZ,aAAa,GACb,mBAAmB,GACnB,gBAAgB,GAChB,oBAAoB,GACpB,oBAAoB,CAAC;AAEzB,MAAM,MAAM,SAAS,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;AAE5C;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,kBAAkB,GAAG,kBAAkB,GAAG,cAAc,CAAC;IAC/D,KAAK,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical event schema v1. Inter-module contract between agent-hooks (writer)
|
|
3
|
+
* and agent-coord (consumer + projector).
|
|
4
|
+
*
|
|
5
|
+
* Schema evolution rules:
|
|
6
|
+
* - Forward-compatible only within a major version. Consumers ignore unknown
|
|
7
|
+
* fields. Adding an optional field is a minor bump; removing or retyping a
|
|
8
|
+
* field is a major bump.
|
|
9
|
+
* - Mixed-version streams are legal during migrations; consumers branch on
|
|
10
|
+
* `schema_version`.
|
|
11
|
+
*/
|
|
12
|
+
export const SCHEMA_VERSION = 1;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tiny ULID generator. Crockford-base32, 10-char timestamp (48-bit ms epoch)
|
|
3
|
+
* + 16-char random (80-bit). 26 chars total, monotonically-sortable.
|
|
4
|
+
*
|
|
5
|
+
* Library-free so the module stays dep-free (no `ulid` package). Quality is
|
|
6
|
+
* sufficient for event_id uniqueness: the kth event in a millisecond uses a
|
|
7
|
+
* fresh 80-bit random, collision probability negligible.
|
|
8
|
+
*/
|
|
9
|
+
export declare function ulid(): string;
|
|
10
|
+
//# sourceMappingURL=ulid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ulid.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/events/ulid.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,wBAAgB,IAAI,IAAI,MAAM,CAI7B"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tiny ULID generator. Crockford-base32, 10-char timestamp (48-bit ms epoch)
|
|
3
|
+
* + 16-char random (80-bit). 26 chars total, monotonically-sortable.
|
|
4
|
+
*
|
|
5
|
+
* Library-free so the module stays dep-free (no `ulid` package). Quality is
|
|
6
|
+
* sufficient for event_id uniqueness: the kth event in a millisecond uses a
|
|
7
|
+
* fresh 80-bit random, collision probability negligible.
|
|
8
|
+
*/
|
|
9
|
+
const ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
10
|
+
export function ulid() {
|
|
11
|
+
const ts = encodeTime(Date.now());
|
|
12
|
+
const rnd = encodeRandom();
|
|
13
|
+
return ts + rnd;
|
|
14
|
+
}
|
|
15
|
+
function encodeTime(ms) {
|
|
16
|
+
let out = "";
|
|
17
|
+
let n = BigInt(ms);
|
|
18
|
+
const base = BigInt(32);
|
|
19
|
+
for (let i = 0; i < 10; i++) {
|
|
20
|
+
const mod = Number(n % base);
|
|
21
|
+
out = ALPHABET[mod] + out;
|
|
22
|
+
n = n / base;
|
|
23
|
+
}
|
|
24
|
+
return out;
|
|
25
|
+
}
|
|
26
|
+
function encodeRandom() {
|
|
27
|
+
const bytes = new Uint8Array(10);
|
|
28
|
+
crypto.getRandomValues(bytes);
|
|
29
|
+
// Map each pair of bytes to 3 alphabet chars (5 bits per char, 16 chars).
|
|
30
|
+
let out = "";
|
|
31
|
+
let buf = 0n;
|
|
32
|
+
let bits = 0;
|
|
33
|
+
for (const b of bytes) {
|
|
34
|
+
buf = (buf << 8n) | BigInt(b);
|
|
35
|
+
bits += 8;
|
|
36
|
+
while (bits >= 5) {
|
|
37
|
+
bits -= 5;
|
|
38
|
+
const idx = Number((buf >> BigInt(bits)) & 0x1fn);
|
|
39
|
+
out += ALPHABET[idx];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (bits > 0) {
|
|
43
|
+
const idx = Number((buf << BigInt(5 - bits)) & 0x1fn);
|
|
44
|
+
out += ALPHABET[idx];
|
|
45
|
+
}
|
|
46
|
+
return out.slice(0, 16);
|
|
47
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Harness } from "../events/schema.js";
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the harness firing the hook. The dispatcher binary is always
|
|
4
|
+
* invoked with `--harness <name>` per the wiring in each harness's settings
|
|
5
|
+
* file (Phase 1). Returns null when the flag is missing; caller falls
|
|
6
|
+
* through to the env-based fallback or skips emission.
|
|
7
|
+
*/
|
|
8
|
+
export declare function detectHarness(argv: readonly string[]): Harness | null;
|
|
9
|
+
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/harness/detect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,GAAG,IAAI,CAWrE"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { coordEnv } from "../../../lib/env.js";
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the harness firing the hook. The dispatcher binary is always
|
|
4
|
+
* invoked with `--harness <name>` per the wiring in each harness's settings
|
|
5
|
+
* file (Phase 1). Returns null when the flag is missing; caller falls
|
|
6
|
+
* through to the env-based fallback or skips emission.
|
|
7
|
+
*/
|
|
8
|
+
export function detectHarness(argv) {
|
|
9
|
+
for (let i = 0; i < argv.length; i++) {
|
|
10
|
+
const a = argv[i];
|
|
11
|
+
if (a === "--harness") {
|
|
12
|
+
return validate(argv[i + 1]);
|
|
13
|
+
}
|
|
14
|
+
if (a.startsWith("--harness=")) {
|
|
15
|
+
return validate(a.slice("--harness=".length));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return validate(coordEnv("AGENT_COORD_HARNESS"));
|
|
19
|
+
}
|
|
20
|
+
function validate(v) {
|
|
21
|
+
if (v === "claude-code" || v === "cursor" || v === "codex")
|
|
22
|
+
return v;
|
|
23
|
+
// Legacy: some harnesses use `claude_code` (underscore). Map
|
|
24
|
+
// it through so the env-based fallback works for callers that haven't
|
|
25
|
+
// updated yet.
|
|
26
|
+
if (v === "claude_code")
|
|
27
|
+
return "claude-code";
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical hook-wiring spec per harness: which settings file to write, which
|
|
3
|
+
* event key maps to which `agent-hook <subcommand>`, and how each harness encodes
|
|
4
|
+
* a command hook. Single source of truth for `harn init` (and any future docs /
|
|
5
|
+
* installers) so the wired set can't drift from what agent-hook actually handles.
|
|
6
|
+
*
|
|
7
|
+
* The event lists + entry shapes mirror exactly what a fully-wired project uses
|
|
8
|
+
* for each harness (Claude Code `.claude/settings.json`, Cursor `.cursor/hooks.json`,
|
|
9
|
+
* Codex `.codex/hooks.json`).
|
|
10
|
+
*/
|
|
11
|
+
export type HarnessId = "claude-code" | "cursor" | "codex";
|
|
12
|
+
export interface HookEvent {
|
|
13
|
+
/** Key under the harness settings file's `hooks` map (e.g. `SessionStart`, `preToolUse`). */
|
|
14
|
+
settingsKey: string;
|
|
15
|
+
/** agent-hook subcommand to invoke for this event. */
|
|
16
|
+
subcommand: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* How a harness encodes a single command hook under `hooks.<settingsKey>`:
|
|
20
|
+
* - `claude`: `[{ hooks: [{ type: "command", command }] }]` (Claude Code + Codex)
|
|
21
|
+
* - `cursor`: `[{ command }]` (Cursor: flat entry, no inner `hooks` array)
|
|
22
|
+
*/
|
|
23
|
+
export type HookEntryShape = "claude" | "cursor";
|
|
24
|
+
export interface HarnessSpec {
|
|
25
|
+
/** Settings file to wire, relative to the project root. */
|
|
26
|
+
settingsFile: string;
|
|
27
|
+
/** Events this harness fires, mapped to agent-hook subcommands. */
|
|
28
|
+
events: HookEvent[];
|
|
29
|
+
/** Per-entry encoding under the root `hooks` object. */
|
|
30
|
+
entryShape: HookEntryShape;
|
|
31
|
+
/** When set, ensure this top-level `version` key in the file (Cursor requires `1`). */
|
|
32
|
+
rootVersion?: number;
|
|
33
|
+
}
|
|
34
|
+
/** Claude Code: `.claude/settings.json`. */
|
|
35
|
+
export declare const CLAUDE_CODE_EVENTS: HookEvent[];
|
|
36
|
+
/**
|
|
37
|
+
* Cursor: `.cursor/hooks.json`. camelCase event keys; flat `{ command }` entries;
|
|
38
|
+
* no `StopFailure` event, but a distinct `beforeShellExecution` (shell-mutation warn).
|
|
39
|
+
*/
|
|
40
|
+
export declare const CURSOR_EVENTS: HookEvent[];
|
|
41
|
+
/** Codex: `.codex/hooks.json`. PascalCase keys + the same entry shape as Claude Code. */
|
|
42
|
+
export declare const CODEX_EVENTS: HookEvent[];
|
|
43
|
+
/** Every supported harness, fully wireable by `harn init`. */
|
|
44
|
+
export declare const HARNESS_SPECS: Record<HarnessId, HarnessSpec>;
|
|
45
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/harness/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE3D,MAAM,WAAW,SAAS;IACxB,6FAA6F;IAC7F,WAAW,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,YAAY,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,wDAAwD;IACxD,UAAU,EAAE,cAAc,CAAC;IAC3B,uFAAuF;IACvF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,4CAA4C;AAC5C,eAAO,MAAM,kBAAkB,EAAE,SAAS,EAWzC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,EAWpC,CAAC;AAEF,yFAAyF;AACzF,eAAO,MAAM,YAAY,EAAE,SAAS,EAWnC,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE,WAAW,CAiBxD,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical hook-wiring spec per harness: which settings file to write, which
|
|
3
|
+
* event key maps to which `agent-hook <subcommand>`, and how each harness encodes
|
|
4
|
+
* a command hook. Single source of truth for `harn init` (and any future docs /
|
|
5
|
+
* installers) so the wired set can't drift from what agent-hook actually handles.
|
|
6
|
+
*
|
|
7
|
+
* The event lists + entry shapes mirror exactly what a fully-wired project uses
|
|
8
|
+
* for each harness (Claude Code `.claude/settings.json`, Cursor `.cursor/hooks.json`,
|
|
9
|
+
* Codex `.codex/hooks.json`).
|
|
10
|
+
*/
|
|
11
|
+
/** Claude Code: `.claude/settings.json`. */
|
|
12
|
+
export const CLAUDE_CODE_EVENTS = [
|
|
13
|
+
{ settingsKey: "SessionStart", subcommand: "session-start" },
|
|
14
|
+
{ settingsKey: "UserPromptSubmit", subcommand: "user-prompt-submit" },
|
|
15
|
+
{ settingsKey: "Stop", subcommand: "stop" },
|
|
16
|
+
{ settingsKey: "StopFailure", subcommand: "stop-failure" },
|
|
17
|
+
{ settingsKey: "SessionEnd", subcommand: "session-end" },
|
|
18
|
+
{ settingsKey: "SubagentStart", subcommand: "sub-agent-start" },
|
|
19
|
+
{ settingsKey: "SubagentStop", subcommand: "sub-agent-stop" },
|
|
20
|
+
{ settingsKey: "PreToolUse", subcommand: "pre-tool-use" },
|
|
21
|
+
{ settingsKey: "PostToolUse", subcommand: "post-tool-use" },
|
|
22
|
+
{ settingsKey: "PostToolUseFailure", subcommand: "post-tool-use-failure" },
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* Cursor: `.cursor/hooks.json`. camelCase event keys; flat `{ command }` entries;
|
|
26
|
+
* no `StopFailure` event, but a distinct `beforeShellExecution` (shell-mutation warn).
|
|
27
|
+
*/
|
|
28
|
+
export const CURSOR_EVENTS = [
|
|
29
|
+
{ settingsKey: "sessionStart", subcommand: "session-start" },
|
|
30
|
+
{ settingsKey: "sessionEnd", subcommand: "session-end" },
|
|
31
|
+
{ settingsKey: "preToolUse", subcommand: "pre-tool-use" },
|
|
32
|
+
{ settingsKey: "beforeShellExecution", subcommand: "before-shell-execution" },
|
|
33
|
+
{ settingsKey: "postToolUse", subcommand: "post-tool-use" },
|
|
34
|
+
{ settingsKey: "postToolUseFailure", subcommand: "post-tool-use-failure" },
|
|
35
|
+
{ settingsKey: "subagentStart", subcommand: "sub-agent-start" },
|
|
36
|
+
{ settingsKey: "subagentStop", subcommand: "sub-agent-stop" },
|
|
37
|
+
{ settingsKey: "beforeSubmitPrompt", subcommand: "user-prompt-submit" },
|
|
38
|
+
{ settingsKey: "stop", subcommand: "stop" },
|
|
39
|
+
];
|
|
40
|
+
/** Codex: `.codex/hooks.json`. PascalCase keys + the same entry shape as Claude Code. */
|
|
41
|
+
export const CODEX_EVENTS = [
|
|
42
|
+
{ settingsKey: "SessionStart", subcommand: "session-start" },
|
|
43
|
+
{ settingsKey: "SessionEnd", subcommand: "session-end" },
|
|
44
|
+
{ settingsKey: "PreToolUse", subcommand: "pre-tool-use" },
|
|
45
|
+
{ settingsKey: "PostToolUse", subcommand: "post-tool-use" },
|
|
46
|
+
{ settingsKey: "PostToolUseFailure", subcommand: "post-tool-use-failure" },
|
|
47
|
+
{ settingsKey: "UserPromptSubmit", subcommand: "user-prompt-submit" },
|
|
48
|
+
{ settingsKey: "SubagentStart", subcommand: "sub-agent-start" },
|
|
49
|
+
{ settingsKey: "SubagentStop", subcommand: "sub-agent-stop" },
|
|
50
|
+
{ settingsKey: "Stop", subcommand: "stop" },
|
|
51
|
+
{ settingsKey: "StopFailure", subcommand: "stop-failure" },
|
|
52
|
+
];
|
|
53
|
+
/** Every supported harness, fully wireable by `harn init`. */
|
|
54
|
+
export const HARNESS_SPECS = {
|
|
55
|
+
"claude-code": {
|
|
56
|
+
settingsFile: ".claude/settings.json",
|
|
57
|
+
events: CLAUDE_CODE_EVENTS,
|
|
58
|
+
entryShape: "claude",
|
|
59
|
+
},
|
|
60
|
+
cursor: {
|
|
61
|
+
settingsFile: ".cursor/hooks.json",
|
|
62
|
+
events: CURSOR_EVENTS,
|
|
63
|
+
entryShape: "cursor",
|
|
64
|
+
rootVersion: 1,
|
|
65
|
+
},
|
|
66
|
+
codex: {
|
|
67
|
+
settingsFile: ".codex/hooks.json",
|
|
68
|
+
events: CODEX_EVENTS,
|
|
69
|
+
entryShape: "claude",
|
|
70
|
+
},
|
|
71
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Harness-aware hook output JSON. Each adapter target has its own protocol
|
|
3
|
+
* shape, so encode it once here so post-emit handlers don't have to branch on
|
|
4
|
+
* `harness` everywhere.
|
|
5
|
+
*
|
|
6
|
+
* Shapes (verified against live dispatchers + each harness's upstream hooks docs):
|
|
7
|
+
*
|
|
8
|
+
* - **Claude Code**: `{hookSpecificOutput: {hookEventName, additionalContext}}`
|
|
9
|
+
* for SessionStart / UserPromptSubmit / SubagentStart; deny uses
|
|
10
|
+
* `{hookSpecificOutput: {hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason}}`.
|
|
11
|
+
* - **Cursor**: `{additional_context, env?}` flat for sessionStart /
|
|
12
|
+
* beforeSubmitPrompt; deny uses `{permission: "deny", agent_message, user_message}`.
|
|
13
|
+
* - **Codex**: structurally identical to Claude Code (confirmed by Phase 0
|
|
14
|
+
* probe + the matching shape in the Codex harness adapter).
|
|
15
|
+
*
|
|
16
|
+
* Every helper writes to process.stdout + newline-terminates so callers can
|
|
17
|
+
* fire-and-forget. Empty text → no-op (no JSON written).
|
|
18
|
+
*/
|
|
19
|
+
import type { Harness } from "../events/schema.js";
|
|
20
|
+
export type SystemEvent = "SessionStart" | "UserPromptSubmit" | "SubagentStart";
|
|
21
|
+
/** Emit a context-injection (peer table, wiring check, council pending, …). */
|
|
22
|
+
export declare function emitContext(harness: Harness, event: SystemEvent, text: string): void;
|
|
23
|
+
/** Emit a PreToolUse deny: blocks the tool call with `reason` shown to the model. */
|
|
24
|
+
export declare function emitDeny(harness: Harness, reason: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Emit a Stop-hook block in the firing harness's enforcement channel and return
|
|
27
|
+
* the process exit code the caller should use.
|
|
28
|
+
*
|
|
29
|
+
* The verdict (allow/block + reason) is computed harness-agnostically in
|
|
30
|
+
* agents/rules/stop-hook.ts; this function only shapes *how the block is
|
|
31
|
+
* communicated back*, because each harness has a different mechanism:
|
|
32
|
+
*
|
|
33
|
+
* - **Claude Code / Codex** honor `exit 2` + a stderr reason as a turn block,
|
|
34
|
+
* and the harness re-prompts the model with the stderr text.
|
|
35
|
+
* - **Cursor** ignores stop-hook exit codes (non-zero = fail-open, the turn
|
|
36
|
+
* proceeds) and re-prompts ONLY via a `followup_message` field in stdout
|
|
37
|
+
* JSON, which it auto-submits as the next user message: the sanctioned
|
|
38
|
+
* "iterate until a goal is met" channel, capped by `loop_limit` (default 5).
|
|
39
|
+
* We exit 0 so Cursor treats the run as a success and honors the output.
|
|
40
|
+
* (Confirmed against cursor.com/docs/agent/hooks.)
|
|
41
|
+
*/
|
|
42
|
+
export declare function emitStopBlock(harness: Harness, verdict: {
|
|
43
|
+
reason?: string;
|
|
44
|
+
rule: string;
|
|
45
|
+
}): 0 | 2;
|
|
46
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/harness/output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,kBAAkB,GAAG,eAAe,CAAC;AAEhF,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAIpF;AAED,qFAAqF;AACrF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAI/D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,CAAC,GAAG,CAAC,CAUjG"}
|