@moreih29/nexus-core 0.17.0 → 0.18.2
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/README.md +101 -67
- package/dist/cli/sync.d.ts +3 -0
- package/dist/cli/sync.d.ts.map +1 -0
- package/dist/cli/sync.js +59 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/generate/index.d.ts +3 -0
- package/dist/generate/index.d.ts.map +1 -0
- package/dist/generate/index.js +2 -0
- package/dist/generate/index.js.map +1 -0
- package/dist/generate/load-data.d.ts +8 -0
- package/dist/generate/load-data.d.ts.map +1 -0
- package/dist/generate/load-data.js +45 -0
- package/dist/generate/load-data.js.map +1 -0
- package/dist/generate/load-spec.d.ts +3 -0
- package/dist/generate/load-spec.d.ts.map +1 -0
- package/dist/generate/load-spec.js +48 -0
- package/dist/generate/load-spec.js.map +1 -0
- package/dist/generate/macros/expand.d.ts +3 -0
- package/dist/generate/macros/expand.d.ts.map +1 -0
- package/dist/generate/macros/expand.js +48 -0
- package/dist/generate/macros/expand.js.map +1 -0
- package/dist/generate/macros/parse.d.ts +4 -0
- package/dist/generate/macros/parse.d.ts.map +1 -0
- package/dist/generate/macros/parse.js +142 -0
- package/dist/generate/macros/parse.js.map +1 -0
- package/dist/generate/macros/validate.d.ts +3 -0
- package/dist/generate/macros/validate.d.ts.map +1 -0
- package/dist/generate/macros/validate.js +23 -0
- package/dist/generate/macros/validate.js.map +1 -0
- package/dist/generate/renderers/claude.d.ts +3 -0
- package/dist/generate/renderers/claude.d.ts.map +1 -0
- package/dist/generate/renderers/claude.js +48 -0
- package/dist/generate/renderers/claude.js.map +1 -0
- package/dist/generate/renderers/codex.d.ts +3 -0
- package/dist/generate/renderers/codex.d.ts.map +1 -0
- package/dist/generate/renderers/codex.js +79 -0
- package/dist/generate/renderers/codex.js.map +1 -0
- package/dist/generate/renderers/markdown.d.ts +2 -0
- package/dist/generate/renderers/markdown.d.ts.map +1 -0
- package/dist/generate/renderers/markdown.js +6 -0
- package/dist/generate/renderers/markdown.js.map +1 -0
- package/dist/generate/renderers/opencode.d.ts +3 -0
- package/dist/generate/renderers/opencode.d.ts.map +1 -0
- package/dist/generate/renderers/opencode.js +69 -0
- package/dist/generate/renderers/opencode.js.map +1 -0
- package/dist/generate/sync.d.ts +4 -0
- package/dist/generate/sync.d.ts.map +1 -0
- package/dist/generate/sync.js +60 -0
- package/dist/generate/sync.js.map +1 -0
- package/dist/generate/types.d.ts +74 -0
- package/dist/generate/types.d.ts.map +1 -0
- package/dist/generate/types.js +2 -0
- package/dist/generate/types.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/definitions/artifact.d.ts +20 -0
- package/dist/mcp/definitions/artifact.d.ts.map +1 -0
- package/dist/mcp/definitions/artifact.js +14 -0
- package/dist/mcp/definitions/artifact.js.map +1 -0
- package/dist/mcp/definitions/history.d.ts +20 -0
- package/dist/mcp/definitions/history.d.ts.map +1 -0
- package/dist/mcp/definitions/history.js +18 -0
- package/dist/mcp/definitions/history.js.map +1 -0
- package/dist/mcp/definitions/index.d.ts +276 -0
- package/dist/mcp/definitions/index.d.ts.map +1 -0
- package/dist/mcp/definitions/index.js +16 -0
- package/dist/mcp/definitions/index.js.map +1 -0
- package/dist/mcp/definitions/plan.d.ts +111 -0
- package/dist/mcp/definitions/plan.d.ts.map +1 -0
- package/dist/mcp/definitions/plan.js +89 -0
- package/dist/mcp/definitions/plan.js.map +1 -0
- package/dist/mcp/definitions/task.d.ts +138 -0
- package/dist/mcp/definitions/task.d.ts.map +1 -0
- package/dist/mcp/definitions/task.js +78 -0
- package/dist/mcp/definitions/task.js.map +1 -0
- package/dist/mcp/handlers/artifact.d.ts.map +1 -0
- package/dist/mcp/handlers/artifact.js +42 -0
- package/dist/mcp/handlers/artifact.js.map +1 -0
- package/dist/mcp/handlers/history.d.ts.map +1 -0
- package/dist/mcp/handlers/history.js +35 -0
- package/dist/mcp/handlers/history.js.map +1 -0
- package/dist/mcp/handlers/plan.d.ts.map +1 -0
- package/dist/mcp/handlers/plan.js +324 -0
- package/dist/mcp/handlers/plan.js.map +1 -0
- package/dist/mcp/handlers/task.d.ts.map +1 -0
- package/dist/mcp/handlers/task.js +216 -0
- package/dist/mcp/handlers/task.js.map +1 -0
- package/dist/{src/mcp → mcp}/server.d.ts +1 -1
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +58 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/shared/json-store.d.ts.map +1 -0
- package/dist/{src/shared → shared}/json-store.js +5 -4
- package/dist/shared/json-store.js.map +1 -0
- package/dist/shared/mcp-utils.d.ts.map +1 -0
- package/dist/shared/mcp-utils.js.map +1 -0
- package/dist/{src/shared → shared}/paths.d.ts +0 -6
- package/dist/shared/paths.d.ts.map +1 -0
- package/dist/shared/paths.js +62 -0
- package/dist/shared/paths.js.map +1 -0
- package/dist/shared/register-tool.d.ts +20 -0
- package/dist/shared/register-tool.d.ts.map +1 -0
- package/dist/shared/register-tool.js +15 -0
- package/dist/shared/register-tool.js.map +1 -0
- package/dist/{src/types → types}/state.d.ts +65 -65
- package/dist/types/state.d.ts.map +1 -0
- package/dist/{src/types → types}/state.js +1 -1
- package/dist/types/state.js.map +1 -0
- package/harness/claude/agent-rules.yml +21 -0
- package/harness/claude/invocations.yml +11 -0
- package/harness/claude/layout.yml +3 -0
- package/harness/codex/agent-rules.yml +28 -0
- package/harness/codex/invocations.yml +13 -0
- package/harness/codex/layout.yml +3 -0
- package/harness/opencode/agent-rules.yml +18 -0
- package/harness/opencode/invocations.yml +12 -0
- package/harness/opencode/layout.yml +3 -0
- package/package.json +38 -43
- package/{assets → spec}/agents/architect/body.ko.md +92 -84
- package/spec/agents/architect/body.md +185 -0
- package/spec/agents/designer/body.ko.md +330 -0
- package/spec/agents/designer/body.md +330 -0
- package/spec/agents/engineer/body.ko.md +166 -0
- package/spec/agents/engineer/body.md +166 -0
- package/spec/agents/lead/body.ko.md +276 -0
- package/spec/agents/lead/body.md +276 -0
- package/{assets → spec}/agents/postdoc/body.ko.md +116 -46
- package/spec/agents/postdoc/body.md +192 -0
- package/{assets → spec}/agents/researcher/body.ko.md +131 -45
- package/spec/agents/researcher/body.md +223 -0
- package/spec/agents/reviewer/body.ko.md +219 -0
- package/spec/agents/reviewer/body.md +219 -0
- package/{assets → spec}/agents/strategist/body.ko.md +108 -35
- package/spec/agents/strategist/body.md +187 -0
- package/spec/agents/tester/body.ko.md +272 -0
- package/spec/agents/tester/body.md +272 -0
- package/{assets → spec}/agents/writer/body.ko.md +109 -33
- package/spec/agents/writer/body.md +198 -0
- package/spec/skills/nx-auto-plan/body.ko.md +150 -0
- package/spec/skills/nx-auto-plan/body.md +150 -0
- package/spec/skills/nx-plan/body.ko.md +159 -0
- package/spec/skills/nx-plan/body.md +159 -0
- package/spec/skills/nx-run/body.ko.md +132 -0
- package/spec/skills/nx-run/body.md +132 -0
- package/vocabulary/enums/task-register-state.yml +4 -0
- package/vocabulary/invocations.yml +43 -0
- package/assets/agents/architect/body.md +0 -177
- package/assets/agents/designer/body.ko.md +0 -125
- package/assets/agents/designer/body.md +0 -125
- package/assets/agents/engineer/body.ko.md +0 -106
- package/assets/agents/engineer/body.md +0 -106
- package/assets/agents/lead/body.ko.md +0 -70
- package/assets/agents/lead/body.md +0 -70
- package/assets/agents/postdoc/body.md +0 -122
- package/assets/agents/researcher/body.md +0 -137
- package/assets/agents/reviewer/body.ko.md +0 -138
- package/assets/agents/reviewer/body.md +0 -138
- package/assets/agents/strategist/body.md +0 -116
- package/assets/agents/tester/body.ko.md +0 -195
- package/assets/agents/tester/body.md +0 -195
- package/assets/agents/writer/body.md +0 -122
- package/assets/capability-matrix.yml +0 -200
- package/assets/hooks/agent-bootstrap/handler.test.ts +0 -369
- package/assets/hooks/agent-bootstrap/handler.ts +0 -132
- package/assets/hooks/agent-bootstrap/meta.yml +0 -10
- package/assets/hooks/agent-finalize/handler.test.ts +0 -368
- package/assets/hooks/agent-finalize/handler.ts +0 -76
- package/assets/hooks/agent-finalize/meta.yml +0 -10
- package/assets/hooks/capability-matrix.yml +0 -313
- package/assets/hooks/post-tool-telemetry/handler.test.ts +0 -302
- package/assets/hooks/post-tool-telemetry/handler.ts +0 -49
- package/assets/hooks/post-tool-telemetry/meta.yml +0 -10
- package/assets/hooks/prompt-router/handler.test.ts +0 -801
- package/assets/hooks/prompt-router/handler.ts +0 -272
- package/assets/hooks/prompt-router/meta.yml +0 -11
- package/assets/hooks/session-init/handler.test.ts +0 -274
- package/assets/hooks/session-init/handler.ts +0 -31
- package/assets/hooks/session-init/meta.yml +0 -9
- package/assets/lsp-servers.json +0 -55
- package/assets/schema/lsp-servers.schema.json +0 -67
- package/assets/skills/nx-init/body.ko.md +0 -197
- package/assets/skills/nx-init/body.md +0 -197
- package/assets/skills/nx-plan/body.ko.md +0 -361
- package/assets/skills/nx-plan/body.md +0 -361
- package/assets/skills/nx-run/body.ko.md +0 -161
- package/assets/skills/nx-run/body.md +0 -160
- package/assets/skills/nx-sync/body.ko.md +0 -92
- package/assets/skills/nx-sync/body.md +0 -92
- package/assets/tools/tool-name-map.yml +0 -353
- package/dist/assets/hooks/agent-bootstrap/handler.d.ts +0 -4
- package/dist/assets/hooks/agent-bootstrap/handler.d.ts.map +0 -1
- package/dist/assets/hooks/agent-bootstrap/handler.js +0 -114
- package/dist/assets/hooks/agent-bootstrap/handler.js.map +0 -1
- package/dist/assets/hooks/agent-finalize/handler.d.ts +0 -4
- package/dist/assets/hooks/agent-finalize/handler.d.ts.map +0 -1
- package/dist/assets/hooks/agent-finalize/handler.js +0 -63
- package/dist/assets/hooks/agent-finalize/handler.js.map +0 -1
- package/dist/assets/hooks/post-tool-telemetry/handler.d.ts +0 -4
- package/dist/assets/hooks/post-tool-telemetry/handler.d.ts.map +0 -1
- package/dist/assets/hooks/post-tool-telemetry/handler.js +0 -40
- package/dist/assets/hooks/post-tool-telemetry/handler.js.map +0 -1
- package/dist/assets/hooks/prompt-router/handler.d.ts +0 -4
- package/dist/assets/hooks/prompt-router/handler.d.ts.map +0 -1
- package/dist/assets/hooks/prompt-router/handler.js +0 -214
- package/dist/assets/hooks/prompt-router/handler.js.map +0 -1
- package/dist/assets/hooks/session-init/handler.d.ts +0 -4
- package/dist/assets/hooks/session-init/handler.d.ts.map +0 -1
- package/dist/assets/hooks/session-init/handler.js +0 -22
- package/dist/assets/hooks/session-init/handler.js.map +0 -1
- package/dist/claude/.claude-plugin/marketplace.json +0 -75
- package/dist/claude/.claude-plugin/plugin.json +0 -67
- package/dist/claude/agents/architect.md +0 -172
- package/dist/claude/agents/designer.md +0 -120
- package/dist/claude/agents/engineer.md +0 -98
- package/dist/claude/agents/lead.md +0 -59
- package/dist/claude/agents/postdoc.md +0 -117
- package/dist/claude/agents/researcher.md +0 -132
- package/dist/claude/agents/reviewer.md +0 -133
- package/dist/claude/agents/strategist.md +0 -111
- package/dist/claude/agents/tester.md +0 -190
- package/dist/claude/agents/writer.md +0 -114
- package/dist/claude/dist/hooks/agent-bootstrap.js +0 -238
- package/dist/claude/dist/hooks/agent-finalize.js +0 -180
- package/dist/claude/dist/hooks/post-tool-telemetry.js +0 -71
- package/dist/claude/dist/hooks/prompt-router.js +0 -7336
- package/dist/claude/dist/hooks/session-init.js +0 -50
- package/dist/claude/hooks/hooks.json +0 -64
- package/dist/claude/settings.json +0 -3
- package/dist/claude/skills/nx-init/SKILL.md +0 -189
- package/dist/claude/skills/nx-plan/SKILL.md +0 -353
- package/dist/claude/skills/nx-run/SKILL.md +0 -154
- package/dist/claude/skills/nx-sync/SKILL.md +0 -87
- package/dist/codex/agents/architect.toml +0 -175
- package/dist/codex/agents/designer.toml +0 -123
- package/dist/codex/agents/engineer.toml +0 -105
- package/dist/codex/agents/lead.toml +0 -64
- package/dist/codex/agents/postdoc.toml +0 -120
- package/dist/codex/agents/researcher.toml +0 -136
- package/dist/codex/agents/reviewer.toml +0 -137
- package/dist/codex/agents/strategist.toml +0 -114
- package/dist/codex/agents/tester.toml +0 -194
- package/dist/codex/agents/writer.toml +0 -121
- package/dist/codex/dist/hooks/agent-bootstrap.js +0 -238
- package/dist/codex/dist/hooks/agent-finalize.js +0 -180
- package/dist/codex/dist/hooks/prompt-router.js +0 -7336
- package/dist/codex/dist/hooks/session-init.js +0 -50
- package/dist/codex/hooks/hooks.json +0 -28
- package/dist/codex/install/AGENTS.fragment.md +0 -60
- package/dist/codex/install/config.fragment.toml +0 -5
- package/dist/codex/install/install.sh +0 -60
- package/dist/codex/package.json +0 -20
- package/dist/codex/plugin/.codex-plugin/plugin.json +0 -57
- package/dist/codex/plugin/skills/nx-init/SKILL.md +0 -189
- package/dist/codex/plugin/skills/nx-plan/SKILL.md +0 -353
- package/dist/codex/plugin/skills/nx-run/SKILL.md +0 -154
- package/dist/codex/plugin/skills/nx-sync/SKILL.md +0 -87
- package/dist/codex/prompts/architect.md +0 -166
- package/dist/codex/prompts/designer.md +0 -114
- package/dist/codex/prompts/engineer.md +0 -97
- package/dist/codex/prompts/lead.md +0 -60
- package/dist/codex/prompts/postdoc.md +0 -111
- package/dist/codex/prompts/researcher.md +0 -127
- package/dist/codex/prompts/reviewer.md +0 -128
- package/dist/codex/prompts/strategist.md +0 -105
- package/dist/codex/prompts/tester.md +0 -185
- package/dist/codex/prompts/writer.md +0 -113
- package/dist/hooks/agent-bootstrap.js +0 -238
- package/dist/hooks/agent-finalize.js +0 -180
- package/dist/hooks/post-tool-telemetry.js +0 -71
- package/dist/hooks/prompt-router.js +0 -7336
- package/dist/hooks/session-init.js +0 -50
- package/dist/manifests/claude-hooks.json +0 -64
- package/dist/manifests/codex-hooks.json +0 -28
- package/dist/manifests/opencode-manifest.json +0 -54
- package/dist/manifests/portability-report.json +0 -75
- package/dist/opencode/.opencode/skills/nx-init/SKILL.md +0 -189
- package/dist/opencode/.opencode/skills/nx-plan/SKILL.md +0 -353
- package/dist/opencode/.opencode/skills/nx-run/SKILL.md +0 -154
- package/dist/opencode/.opencode/skills/nx-sync/SKILL.md +0 -87
- package/dist/opencode/package.json +0 -23
- package/dist/opencode/src/agents/architect.ts +0 -176
- package/dist/opencode/src/agents/designer.ts +0 -124
- package/dist/opencode/src/agents/engineer.ts +0 -105
- package/dist/opencode/src/agents/lead.ts +0 -66
- package/dist/opencode/src/agents/postdoc.ts +0 -121
- package/dist/opencode/src/agents/researcher.ts +0 -136
- package/dist/opencode/src/agents/reviewer.ts +0 -137
- package/dist/opencode/src/agents/strategist.ts +0 -115
- package/dist/opencode/src/agents/tester.ts +0 -194
- package/dist/opencode/src/agents/writer.ts +0 -121
- package/dist/opencode/src/index.ts +0 -25
- package/dist/opencode/src/plugin.ts +0 -6
- package/dist/scripts/build-agents.d.ts +0 -170
- package/dist/scripts/build-agents.d.ts.map +0 -1
- package/dist/scripts/build-agents.js +0 -907
- package/dist/scripts/build-agents.js.map +0 -1
- package/dist/scripts/build-hooks.d.ts +0 -57
- package/dist/scripts/build-hooks.d.ts.map +0 -1
- package/dist/scripts/build-hooks.js +0 -562
- package/dist/scripts/build-hooks.js.map +0 -1
- package/dist/scripts/cli.d.ts +0 -54
- package/dist/scripts/cli.d.ts.map +0 -1
- package/dist/scripts/cli.js +0 -504
- package/dist/scripts/cli.js.map +0 -1
- package/dist/scripts/smoke/smoke-claude.d.ts +0 -2
- package/dist/scripts/smoke/smoke-claude.d.ts.map +0 -1
- package/dist/scripts/smoke/smoke-claude.js +0 -58
- package/dist/scripts/smoke/smoke-claude.js.map +0 -1
- package/dist/scripts/smoke/smoke-codex.d.ts +0 -2
- package/dist/scripts/smoke/smoke-codex.d.ts.map +0 -1
- package/dist/scripts/smoke/smoke-codex.js +0 -50
- package/dist/scripts/smoke/smoke-codex.js.map +0 -1
- package/dist/scripts/smoke/smoke-consumer.d.ts +0 -2
- package/dist/scripts/smoke/smoke-consumer.d.ts.map +0 -1
- package/dist/scripts/smoke/smoke-consumer.js +0 -230
- package/dist/scripts/smoke/smoke-consumer.js.map +0 -1
- package/dist/scripts/smoke/smoke-opencode.d.ts +0 -2
- package/dist/scripts/smoke/smoke-opencode.d.ts.map +0 -1
- package/dist/scripts/smoke/smoke-opencode.js +0 -99
- package/dist/scripts/smoke/smoke-opencode.js.map +0 -1
- package/dist/src/hooks/opencode-mount.d.ts +0 -35
- package/dist/src/hooks/opencode-mount.d.ts.map +0 -1
- package/dist/src/hooks/opencode-mount.js +0 -352
- package/dist/src/hooks/opencode-mount.js.map +0 -1
- package/dist/src/hooks/runtime.d.ts +0 -37
- package/dist/src/hooks/runtime.d.ts.map +0 -1
- package/dist/src/hooks/runtime.js +0 -274
- package/dist/src/hooks/runtime.js.map +0 -1
- package/dist/src/hooks/types.d.ts +0 -196
- package/dist/src/hooks/types.d.ts.map +0 -1
- package/dist/src/hooks/types.js +0 -85
- package/dist/src/hooks/types.js.map +0 -1
- package/dist/src/lsp/cache.d.ts +0 -9
- package/dist/src/lsp/cache.d.ts.map +0 -1
- package/dist/src/lsp/cache.js +0 -216
- package/dist/src/lsp/cache.js.map +0 -1
- package/dist/src/lsp/client.d.ts +0 -24
- package/dist/src/lsp/client.d.ts.map +0 -1
- package/dist/src/lsp/client.js +0 -166
- package/dist/src/lsp/client.js.map +0 -1
- package/dist/src/lsp/detect.d.ts +0 -77
- package/dist/src/lsp/detect.d.ts.map +0 -1
- package/dist/src/lsp/detect.js +0 -116
- package/dist/src/lsp/detect.js.map +0 -1
- package/dist/src/mcp/server.d.ts.map +0 -1
- package/dist/src/mcp/server.js +0 -34
- package/dist/src/mcp/server.js.map +0 -1
- package/dist/src/mcp/tools/artifact.d.ts.map +0 -1
- package/dist/src/mcp/tools/artifact.js +0 -36
- package/dist/src/mcp/tools/artifact.js.map +0 -1
- package/dist/src/mcp/tools/history.d.ts.map +0 -1
- package/dist/src/mcp/tools/history.js +0 -29
- package/dist/src/mcp/tools/history.js.map +0 -1
- package/dist/src/mcp/tools/lsp.d.ts +0 -13
- package/dist/src/mcp/tools/lsp.d.ts.map +0 -1
- package/dist/src/mcp/tools/lsp.js +0 -225
- package/dist/src/mcp/tools/lsp.js.map +0 -1
- package/dist/src/mcp/tools/plan.d.ts.map +0 -1
- package/dist/src/mcp/tools/plan.js +0 -317
- package/dist/src/mcp/tools/plan.js.map +0 -1
- package/dist/src/mcp/tools/task.d.ts.map +0 -1
- package/dist/src/mcp/tools/task.js +0 -252
- package/dist/src/mcp/tools/task.js.map +0 -1
- package/dist/src/shared/invocations.d.ts +0 -74
- package/dist/src/shared/invocations.d.ts.map +0 -1
- package/dist/src/shared/invocations.js +0 -247
- package/dist/src/shared/invocations.js.map +0 -1
- package/dist/src/shared/json-store.d.ts.map +0 -1
- package/dist/src/shared/json-store.js.map +0 -1
- package/dist/src/shared/mcp-utils.d.ts.map +0 -1
- package/dist/src/shared/mcp-utils.js.map +0 -1
- package/dist/src/shared/package-root.d.ts +0 -6
- package/dist/src/shared/package-root.d.ts.map +0 -1
- package/dist/src/shared/package-root.js +0 -19
- package/dist/src/shared/package-root.js.map +0 -1
- package/dist/src/shared/paths.d.ts.map +0 -1
- package/dist/src/shared/paths.js +0 -117
- package/dist/src/shared/paths.js.map +0 -1
- package/dist/src/shared/tool-log.d.ts +0 -8
- package/dist/src/shared/tool-log.d.ts.map +0 -1
- package/dist/src/shared/tool-log.js +0 -22
- package/dist/src/shared/tool-log.js.map +0 -1
- package/dist/src/types/agent-config.d.ts +0 -22
- package/dist/src/types/agent-config.d.ts.map +0 -1
- package/dist/src/types/agent-config.js +0 -2
- package/dist/src/types/agent-config.js.map +0 -1
- package/dist/src/types/index.d.ts +0 -2
- package/dist/src/types/index.d.ts.map +0 -1
- package/dist/src/types/index.js +0 -2
- package/dist/src/types/index.js.map +0 -1
- package/dist/src/types/state.d.ts.map +0 -1
- package/dist/src/types/state.js.map +0 -1
- package/docs/consuming/codex-lead-merge.md +0 -106
- package/docs/contract/harness-io.md +0 -333
- package/docs/plugin-guide.md +0 -355
- package/docs/plugin-template/claude/.github/workflows/build.yml +0 -60
- package/docs/plugin-template/claude/README.md +0 -110
- package/docs/plugin-template/claude/package.json +0 -16
- package/docs/plugin-template/codex/.github/workflows/build.yml +0 -51
- package/docs/plugin-template/codex/README.md +0 -147
- package/docs/plugin-template/codex/install/install.sh +0 -60
- package/docs/plugin-template/codex/package.json +0 -17
- package/docs/plugin-template/opencode/.github/workflows/build.yml +0 -61
- package/docs/plugin-template/opencode/README.md +0 -121
- package/docs/plugin-template/opencode/package.json +0 -25
- package/docs/plugin-template/opencode/src/plugin.ts +0 -6
- /package/dist/{src/mcp/tools → mcp/handlers}/artifact.d.ts +0 -0
- /package/dist/{src/mcp/tools → mcp/handlers}/history.d.ts +0 -0
- /package/dist/{src/mcp/tools → mcp/handlers}/plan.d.ts +0 -0
- /package/dist/{src/mcp/tools → mcp/handlers}/task.d.ts +0 -0
- /package/dist/{src/shared → shared}/json-store.d.ts +0 -0
- /package/dist/{src/shared → shared}/mcp-utils.d.ts +0 -0
- /package/dist/{src/shared → shared}/mcp-utils.js +0 -0
|
@@ -1,368 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach } from "bun:test";
|
|
2
|
-
import fs from "node:fs";
|
|
3
|
-
import fsPromises from "node:fs/promises";
|
|
4
|
-
import os from "node:os";
|
|
5
|
-
import path from "node:path";
|
|
6
|
-
import handler from "./handler.ts";
|
|
7
|
-
|
|
8
|
-
// ---------------------------------------------------------------------------
|
|
9
|
-
// Helpers
|
|
10
|
-
// ---------------------------------------------------------------------------
|
|
11
|
-
|
|
12
|
-
let tmpDir: string;
|
|
13
|
-
let sessionDir: string;
|
|
14
|
-
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nexus-agent-finalize-"));
|
|
17
|
-
// Mimic .nexus/state/<session_id> layout expected by handler.ts
|
|
18
|
-
sessionDir = path.join(tmpDir, ".nexus", "state", "sess-test");
|
|
19
|
-
fs.mkdirSync(sessionDir, { recursive: true });
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
afterEach(async () => {
|
|
23
|
-
await fsPromises.rm(tmpDir, { recursive: true, force: true });
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
function trackerPath(): string {
|
|
27
|
-
return path.join(sessionDir, "agent-tracker.json");
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function toolLogPath(): string {
|
|
31
|
-
return path.join(sessionDir, "tool-log.jsonl");
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function tasksPath(): string {
|
|
35
|
-
return path.join(sessionDir, "tasks.json");
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function writeTracker(entries: Record<string, unknown>[]): void {
|
|
39
|
-
fs.writeFileSync(trackerPath(), JSON.stringify(entries, null, 2));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function writeToolLog(lines: Record<string, unknown>[]): void {
|
|
43
|
-
const content = lines.map((l) => JSON.stringify(l)).join("\n") + "\n";
|
|
44
|
-
fs.writeFileSync(toolLogPath(), content);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function writeTasks(tasks: Record<string, unknown>[]): void {
|
|
48
|
-
fs.writeFileSync(tasksPath(), JSON.stringify({ tasks }, null, 2));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function readTracker(): Record<string, unknown>[] {
|
|
52
|
-
return JSON.parse(fs.readFileSync(trackerPath(), "utf-8")) as Record<string, unknown>[];
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function makeInput(overrides: Record<string, unknown> = {}) {
|
|
56
|
-
return {
|
|
57
|
-
hook_event_name: "SubagentStop" as const,
|
|
58
|
-
session_id: "sess-test",
|
|
59
|
-
cwd: tmpDir,
|
|
60
|
-
agent_type: "engineer",
|
|
61
|
-
agent_id: "agent-abc",
|
|
62
|
-
last_assistant_message: "done",
|
|
63
|
-
...overrides,
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// ---------------------------------------------------------------------------
|
|
68
|
-
// Scenario 1: pending task exists — additional_context returned (English + <system-notice>)
|
|
69
|
-
// ---------------------------------------------------------------------------
|
|
70
|
-
|
|
71
|
-
describe("Scenario 1: pending task for same role returns additional_context", () => {
|
|
72
|
-
it("returns additional_context containing <system-notice> when pending tasks exist for the same agent_type", async () => {
|
|
73
|
-
writeTracker([{ agent_id: "agent-abc", status: "running" }]);
|
|
74
|
-
writeTasks([
|
|
75
|
-
{ id: "task-1", status: "pending", owner: { role: "engineer" } },
|
|
76
|
-
{ id: "task-2", status: "completed", owner: { role: "engineer" } },
|
|
77
|
-
]);
|
|
78
|
-
|
|
79
|
-
const result = await handler(makeInput());
|
|
80
|
-
|
|
81
|
-
expect(result).toBeDefined();
|
|
82
|
-
expect(typeof result?.additional_context).toBe("string");
|
|
83
|
-
const ctx = result!.additional_context!;
|
|
84
|
-
|
|
85
|
-
// Must contain <system-notice> wrapper tags
|
|
86
|
-
expect(ctx).toContain("<system-notice>");
|
|
87
|
-
expect(ctx).toContain("</system-notice>");
|
|
88
|
-
|
|
89
|
-
// Must mention "coordinate remaining subagent delegation"
|
|
90
|
-
expect(ctx).toContain("coordinate remaining subagent delegation");
|
|
91
|
-
|
|
92
|
-
// Must be in English — no Korean characters
|
|
93
|
-
expect(/[\u3131-\uD7A3]/.test(ctx)).toBe(false);
|
|
94
|
-
|
|
95
|
-
// Must include the pending task id but not the completed one
|
|
96
|
-
expect(ctx).toContain("task-1");
|
|
97
|
-
expect(ctx).not.toContain("task-2");
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it("includes all pending task ids when multiple tasks are pending for the role", async () => {
|
|
101
|
-
writeTracker([{ agent_id: "agent-abc", status: "running" }]);
|
|
102
|
-
writeTasks([
|
|
103
|
-
{ id: "task-A", status: "pending", owner: { role: "engineer" } },
|
|
104
|
-
{ id: "task-B", status: "in_progress", owner: { role: "engineer" } },
|
|
105
|
-
]);
|
|
106
|
-
|
|
107
|
-
const result = await handler(makeInput());
|
|
108
|
-
const ctx = result?.additional_context ?? "";
|
|
109
|
-
expect(ctx).toContain("task-A");
|
|
110
|
-
expect(ctx).toContain("task-B");
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
// ---------------------------------------------------------------------------
|
|
115
|
-
// Scenario 2: no pending tasks — returns undefined (no additional_context)
|
|
116
|
-
// ---------------------------------------------------------------------------
|
|
117
|
-
|
|
118
|
-
describe("Scenario 2: no pending tasks returns undefined", () => {
|
|
119
|
-
it("returns undefined when all tasks for the role are completed", async () => {
|
|
120
|
-
writeTracker([{ agent_id: "agent-abc", status: "running" }]);
|
|
121
|
-
writeTasks([
|
|
122
|
-
{ id: "task-1", status: "completed", owner: { role: "engineer" } },
|
|
123
|
-
]);
|
|
124
|
-
|
|
125
|
-
const result = await handler(makeInput());
|
|
126
|
-
|
|
127
|
-
expect(result).toBeUndefined();
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it("returns undefined when tasks.json has tasks with a different role only", async () => {
|
|
131
|
-
writeTracker([{ agent_id: "agent-abc", status: "running" }]);
|
|
132
|
-
writeTasks([
|
|
133
|
-
{ id: "task-x", status: "in_progress", owner: { role: "architect" } },
|
|
134
|
-
]);
|
|
135
|
-
|
|
136
|
-
const result = await handler(makeInput());
|
|
137
|
-
|
|
138
|
-
expect(result).toBeUndefined();
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
it("returns undefined when tasks.json is empty", async () => {
|
|
142
|
-
writeTracker([{ agent_id: "agent-abc", status: "running" }]);
|
|
143
|
-
writeTasks([]);
|
|
144
|
-
|
|
145
|
-
const result = await handler(makeInput());
|
|
146
|
-
|
|
147
|
-
expect(result).toBeUndefined();
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
// ---------------------------------------------------------------------------
|
|
152
|
-
// Scenario 3: tool-log.jsonl with 3 files for the same agent_id → files_touched stored
|
|
153
|
-
// ---------------------------------------------------------------------------
|
|
154
|
-
|
|
155
|
-
describe("Scenario 3: files_touched aggregation from tool-log.jsonl", () => {
|
|
156
|
-
it("stores exactly 3 unique file paths when tool-log has 3 matching entries for agent_id", async () => {
|
|
157
|
-
writeTracker([{ agent_id: "agent-abc", status: "running" }]);
|
|
158
|
-
writeToolLog([
|
|
159
|
-
{ agent_id: "agent-abc", file: "src/foo.ts" },
|
|
160
|
-
{ agent_id: "agent-abc", file: "src/bar.ts" },
|
|
161
|
-
{ agent_id: "agent-abc", file: "src/baz.ts" },
|
|
162
|
-
// entry with a different agent_id — must NOT be included
|
|
163
|
-
{ agent_id: "agent-xyz", file: "src/other.ts" },
|
|
164
|
-
]);
|
|
165
|
-
writeTasks([]);
|
|
166
|
-
|
|
167
|
-
await handler(makeInput());
|
|
168
|
-
|
|
169
|
-
const tracker = readTracker();
|
|
170
|
-
const entry = tracker.find((e) => e["agent_id"] === "agent-abc");
|
|
171
|
-
expect(entry).toBeDefined();
|
|
172
|
-
const touched = entry!["files_touched"] as string[];
|
|
173
|
-
expect(Array.isArray(touched)).toBe(true);
|
|
174
|
-
expect(touched).toHaveLength(3);
|
|
175
|
-
expect(touched).toContain("src/foo.ts");
|
|
176
|
-
expect(touched).toContain("src/bar.ts");
|
|
177
|
-
expect(touched).toContain("src/baz.ts");
|
|
178
|
-
expect(touched).not.toContain("src/other.ts");
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
it("deduplicates repeated file paths — files_touched contains only unique entries", async () => {
|
|
182
|
-
writeTracker([{ agent_id: "agent-abc", status: "running" }]);
|
|
183
|
-
writeToolLog([
|
|
184
|
-
{ agent_id: "agent-abc", file: "src/foo.ts" },
|
|
185
|
-
{ agent_id: "agent-abc", file: "src/foo.ts" }, // duplicate
|
|
186
|
-
{ agent_id: "agent-abc", file: "src/bar.ts" },
|
|
187
|
-
]);
|
|
188
|
-
writeTasks([]);
|
|
189
|
-
|
|
190
|
-
await handler(makeInput());
|
|
191
|
-
|
|
192
|
-
const tracker = readTracker();
|
|
193
|
-
const entry = tracker.find((e) => e["agent_id"] === "agent-abc");
|
|
194
|
-
const touched = entry!["files_touched"] as string[];
|
|
195
|
-
expect(touched).toHaveLength(2);
|
|
196
|
-
expect(touched).toContain("src/foo.ts");
|
|
197
|
-
expect(touched).toContain("src/bar.ts");
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
// ---------------------------------------------------------------------------
|
|
202
|
-
// Scenario 4: entry missing (tracker empty or agent_id mismatch) → silent skip
|
|
203
|
-
// ---------------------------------------------------------------------------
|
|
204
|
-
|
|
205
|
-
describe("Scenario 4: missing tracker entry — silent skip (tracker not modified)", () => {
|
|
206
|
-
it("does not modify the tracker and does not throw when tracker array is empty", async () => {
|
|
207
|
-
writeTracker([]);
|
|
208
|
-
writeTasks([]);
|
|
209
|
-
|
|
210
|
-
const result = await handler(makeInput());
|
|
211
|
-
|
|
212
|
-
// No pending tasks → no additional_context
|
|
213
|
-
expect(result).toBeUndefined();
|
|
214
|
-
// Tracker must remain unchanged (empty)
|
|
215
|
-
const tracker = readTracker();
|
|
216
|
-
expect(tracker).toHaveLength(0);
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
it("does not modify the non-matching entry and returns undefined when agent_id is not found", async () => {
|
|
220
|
-
writeTracker([{ agent_id: "agent-OTHER", status: "running" }]);
|
|
221
|
-
writeTasks([]);
|
|
222
|
-
|
|
223
|
-
const result = await handler(makeInput());
|
|
224
|
-
|
|
225
|
-
expect(result).toBeUndefined();
|
|
226
|
-
// Tracker entry for unmatched agent must remain unchanged
|
|
227
|
-
const tracker = readTracker();
|
|
228
|
-
expect(tracker).toHaveLength(1);
|
|
229
|
-
expect(tracker[0]["status"]).toBe("running");
|
|
230
|
-
// No status update, stopped_at, last_message, or files_touched was added
|
|
231
|
-
expect(tracker[0]["stopped_at"]).toBeUndefined();
|
|
232
|
-
expect(tracker[0]["files_touched"]).toBeUndefined();
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
it("does not throw and returns undefined when tasks.json is absent and tracker has no matching entry", async () => {
|
|
236
|
-
writeTracker([{ agent_id: "agent-OTHER", status: "running" }]);
|
|
237
|
-
// tasks.json intentionally absent
|
|
238
|
-
|
|
239
|
-
const result = await handler(makeInput());
|
|
240
|
-
|
|
241
|
-
expect(result).toBeUndefined();
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
// ---------------------------------------------------------------------------
|
|
246
|
-
// Scenario 5: tracker entry updated with status="completed", stopped_at, last_message
|
|
247
|
-
// ---------------------------------------------------------------------------
|
|
248
|
-
|
|
249
|
-
describe("Scenario 5: tracker entry fields updated on agent stop", () => {
|
|
250
|
-
it("sets status to 'completed' and records stopped_at as a valid ISO timestamp", async () => {
|
|
251
|
-
const before = new Date();
|
|
252
|
-
writeTracker([{ agent_id: "agent-abc", status: "running" }]);
|
|
253
|
-
writeTasks([]);
|
|
254
|
-
|
|
255
|
-
await handler(makeInput({ last_assistant_message: "Task finished." }));
|
|
256
|
-
|
|
257
|
-
const after = new Date();
|
|
258
|
-
const tracker = readTracker();
|
|
259
|
-
const entry = tracker.find((e) => e["agent_id"] === "agent-abc");
|
|
260
|
-
expect(entry).toBeDefined();
|
|
261
|
-
|
|
262
|
-
expect(entry!["status"]).toBe("completed");
|
|
263
|
-
|
|
264
|
-
const stoppedAt = entry!["stopped_at"] as string;
|
|
265
|
-
expect(typeof stoppedAt).toBe("string");
|
|
266
|
-
const stoppedDate = new Date(stoppedAt);
|
|
267
|
-
// Must be a valid date in the range [before, after]
|
|
268
|
-
expect(stoppedDate.getTime()).toBeGreaterThanOrEqual(before.getTime());
|
|
269
|
-
expect(stoppedDate.getTime()).toBeLessThanOrEqual(after.getTime());
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
it("records last_message in the tracker entry", async () => {
|
|
273
|
-
writeTracker([{ agent_id: "agent-abc", status: "running" }]);
|
|
274
|
-
writeTasks([]);
|
|
275
|
-
|
|
276
|
-
await handler(makeInput({ last_assistant_message: "Short message." }));
|
|
277
|
-
|
|
278
|
-
const tracker = readTracker();
|
|
279
|
-
const entry = tracker.find((e) => e["agent_id"] === "agent-abc");
|
|
280
|
-
expect(entry!["last_message"]).toBe("Short message.");
|
|
281
|
-
});
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
// ---------------------------------------------------------------------------
|
|
285
|
-
// Scenario 6: last_assistant_message > 500 chars → last_message sliced to 500 chars
|
|
286
|
-
// ---------------------------------------------------------------------------
|
|
287
|
-
|
|
288
|
-
describe("Scenario 6: last_assistant_message truncated to 500 chars in last_message", () => {
|
|
289
|
-
it("stores only the first 500 characters of a message exceeding 500 chars", async () => {
|
|
290
|
-
const longMessage = "A".repeat(501);
|
|
291
|
-
writeTracker([{ agent_id: "agent-abc", status: "running" }]);
|
|
292
|
-
writeTasks([]);
|
|
293
|
-
|
|
294
|
-
await handler(makeInput({ last_assistant_message: longMessage }));
|
|
295
|
-
|
|
296
|
-
const tracker = readTracker();
|
|
297
|
-
const entry = tracker.find((e) => e["agent_id"] === "agent-abc");
|
|
298
|
-
expect(entry).toBeDefined();
|
|
299
|
-
|
|
300
|
-
const stored = entry!["last_message"] as string;
|
|
301
|
-
expect(stored.length).toBe(500);
|
|
302
|
-
expect(stored).toBe("A".repeat(500));
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
it("stores the message unchanged when it is exactly 500 chars", async () => {
|
|
306
|
-
const exactMessage = "B".repeat(500);
|
|
307
|
-
writeTracker([{ agent_id: "agent-abc", status: "running" }]);
|
|
308
|
-
writeTasks([]);
|
|
309
|
-
|
|
310
|
-
await handler(makeInput({ last_assistant_message: exactMessage }));
|
|
311
|
-
|
|
312
|
-
const tracker = readTracker();
|
|
313
|
-
const entry = tracker.find((e) => e["agent_id"] === "agent-abc");
|
|
314
|
-
const stored = entry!["last_message"] as string;
|
|
315
|
-
expect(stored.length).toBe(500);
|
|
316
|
-
expect(stored).toBe(exactMessage);
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
it("stores the full message unchanged when it is under 500 chars", async () => {
|
|
320
|
-
const shortMessage = "Hello world";
|
|
321
|
-
writeTracker([{ agent_id: "agent-abc", status: "running" }]);
|
|
322
|
-
writeTasks([]);
|
|
323
|
-
|
|
324
|
-
await handler(makeInput({ last_assistant_message: shortMessage }));
|
|
325
|
-
|
|
326
|
-
const tracker = readTracker();
|
|
327
|
-
const entry = tracker.find((e) => e["agent_id"] === "agent-abc");
|
|
328
|
-
expect(entry!["last_message"]).toBe(shortMessage);
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
it("handles missing last_assistant_message as empty string (no throw, last_message is empty)", async () => {
|
|
332
|
-
writeTracker([{ agent_id: "agent-abc", status: "running" }]);
|
|
333
|
-
writeTasks([]);
|
|
334
|
-
|
|
335
|
-
const inputWithoutMessage = {
|
|
336
|
-
hook_event_name: "SubagentStop" as const,
|
|
337
|
-
session_id: "sess-test",
|
|
338
|
-
cwd: tmpDir,
|
|
339
|
-
agent_type: "engineer",
|
|
340
|
-
agent_id: "agent-abc",
|
|
341
|
-
// last_assistant_message intentionally omitted
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
await handler(inputWithoutMessage);
|
|
345
|
-
|
|
346
|
-
const tracker = readTracker();
|
|
347
|
-
const entry = tracker.find((e) => e["agent_id"] === "agent-abc");
|
|
348
|
-
expect(entry!["last_message"]).toBe("");
|
|
349
|
-
});
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
// ---------------------------------------------------------------------------
|
|
353
|
-
// Guard: non-SubagentStop events are silently ignored
|
|
354
|
-
// ---------------------------------------------------------------------------
|
|
355
|
-
|
|
356
|
-
describe("Guard: non-SubagentStop events", () => {
|
|
357
|
-
it("returns undefined immediately for non-SubagentStop events without touching any files", async () => {
|
|
358
|
-
const result = await handler({
|
|
359
|
-
hook_event_name: "SessionStart",
|
|
360
|
-
session_id: "sess-test",
|
|
361
|
-
cwd: tmpDir,
|
|
362
|
-
});
|
|
363
|
-
|
|
364
|
-
expect(result).toBeUndefined();
|
|
365
|
-
// No tracker file should have been created
|
|
366
|
-
expect(fs.existsSync(trackerPath())).toBe(false);
|
|
367
|
-
});
|
|
368
|
-
});
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import type { HookHandler } from "../../../src/hooks/types.js";
|
|
2
|
-
import { updateJsonFileLocked } from "../../../src/shared/json-store.js";
|
|
3
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
|
|
6
|
-
const handler: HookHandler = async (input) => {
|
|
7
|
-
if (input.hook_event_name !== "SubagentStop") return;
|
|
8
|
-
|
|
9
|
-
const { cwd, session_id, agent_type, agent_id } = input;
|
|
10
|
-
const lastMessage = (input.last_assistant_message ?? "").slice(0, 500);
|
|
11
|
-
|
|
12
|
-
const sessionDir = join(cwd, ".nexus/state", session_id);
|
|
13
|
-
const trackerPath = join(sessionDir, "agent-tracker.json");
|
|
14
|
-
const toolLogPath = join(sessionDir, "tool-log.jsonl");
|
|
15
|
-
const tasksPath = join(sessionDir, "tasks.json");
|
|
16
|
-
|
|
17
|
-
// 1. tracker update + files_touched aggregation (locked)
|
|
18
|
-
await updateJsonFileLocked(trackerPath, [], (tracker: unknown[]) => {
|
|
19
|
-
const entry = (tracker as Record<string, unknown>[]).find(
|
|
20
|
-
(e) => e["agent_id"] === agent_id,
|
|
21
|
-
);
|
|
22
|
-
if (!entry) return tracker;
|
|
23
|
-
|
|
24
|
-
entry["status"] = "completed";
|
|
25
|
-
entry["stopped_at"] = new Date().toISOString();
|
|
26
|
-
entry["last_message"] = lastMessage;
|
|
27
|
-
|
|
28
|
-
if (existsSync(toolLogPath)) {
|
|
29
|
-
const files = new Set<string>();
|
|
30
|
-
const raw = readFileSync(toolLogPath, "utf-8");
|
|
31
|
-
for (const line of raw.split("\n")) {
|
|
32
|
-
if (!line.trim()) continue;
|
|
33
|
-
try {
|
|
34
|
-
const log = JSON.parse(line) as Record<string, unknown>;
|
|
35
|
-
if (log["agent_id"] === agent_id && typeof log["file"] === "string") {
|
|
36
|
-
files.add(log["file"]);
|
|
37
|
-
}
|
|
38
|
-
} catch {
|
|
39
|
-
// skip malformed lines
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
entry["files_touched"] = [...files];
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return tracker;
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
// 2. pending tasks alert (owner.role === agent_type)
|
|
49
|
-
if (!existsSync(tasksPath)) return;
|
|
50
|
-
|
|
51
|
-
try {
|
|
52
|
-
const tasksData = JSON.parse(readFileSync(tasksPath, "utf-8")) as unknown;
|
|
53
|
-
const tasks: Record<string, unknown>[] = Array.isArray(
|
|
54
|
-
(tasksData as Record<string, unknown>)?.["tasks"],
|
|
55
|
-
)
|
|
56
|
-
? ((tasksData as Record<string, unknown>)["tasks"] as Record<string, unknown>[])
|
|
57
|
-
: [];
|
|
58
|
-
|
|
59
|
-
const incomplete = tasks.filter(
|
|
60
|
-
(t) =>
|
|
61
|
-
(t["owner"] as Record<string, unknown> | undefined)?.["role"] === agent_type &&
|
|
62
|
-
t["status"] !== "completed",
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
if (incomplete.length === 0) return;
|
|
66
|
-
|
|
67
|
-
const ids = incomplete.map((t) => t["id"]).join(", ");
|
|
68
|
-
return {
|
|
69
|
-
additional_context: `<system-notice>\nSubagent "${agent_type}" finished. Tasks still pending with this role: ${ids}. Review status and coordinate remaining subagent delegation.\n</system-notice>`,
|
|
70
|
-
};
|
|
71
|
-
} catch {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
export default handler;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
name: agent-finalize
|
|
2
|
-
description: Finalize subagent tracker, aggregate files_touched, alert pending tasks with same role
|
|
3
|
-
events: [SubagentStop]
|
|
4
|
-
matcher: "*"
|
|
5
|
-
timeout: 10
|
|
6
|
-
fallback: warn
|
|
7
|
-
priority: 0
|
|
8
|
-
requires_capabilities:
|
|
9
|
-
- event.subagent_stop
|
|
10
|
-
- output.additional_context.subagent_stop
|