@kynetic-ai/spec 0.1.2 → 0.3.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/README.md +250 -17
- package/dist/acp/client.d.ts +18 -4
- package/dist/acp/client.d.ts.map +1 -1
- package/dist/acp/client.js +44 -26
- package/dist/acp/client.js.map +1 -1
- package/dist/acp/framing.d.ts +2 -2
- package/dist/acp/framing.d.ts.map +1 -1
- package/dist/acp/framing.js +37 -29
- package/dist/acp/framing.js.map +1 -1
- package/dist/acp/index.d.ts +6 -7
- package/dist/acp/index.d.ts.map +1 -1
- package/dist/acp/index.js +3 -3
- package/dist/acp/index.js.map +1 -1
- package/dist/acp/types.d.ts +5 -5
- package/dist/acp/types.d.ts.map +1 -1
- package/dist/acp/types.js +18 -18
- package/dist/acp/types.js.map +1 -1
- package/dist/agents/adapters.d.ts.map +1 -1
- package/dist/agents/adapters.js +24 -13
- package/dist/agents/adapters.js.map +1 -1
- package/dist/agents/index.d.ts +2 -2
- package/dist/agents/index.js +2 -2
- package/dist/agents/spawner.d.ts +4 -4
- package/dist/agents/spawner.d.ts.map +1 -1
- package/dist/agents/spawner.js +6 -6
- package/dist/agents/spawner.js.map +1 -1
- package/dist/cli/batch-context.d.ts +43 -0
- package/dist/cli/batch-context.d.ts.map +1 -0
- package/dist/cli/batch-context.js +93 -0
- package/dist/cli/batch-context.js.map +1 -0
- package/dist/cli/batch-exec.d.ts +116 -0
- package/dist/cli/batch-exec.d.ts.map +1 -0
- package/dist/cli/batch-exec.js +694 -0
- package/dist/cli/batch-exec.js.map +1 -0
- package/dist/cli/batch.d.ts +4 -2
- package/dist/cli/batch.d.ts.map +1 -1
- package/dist/cli/batch.js +15 -14
- package/dist/cli/batch.js.map +1 -1
- package/dist/cli/command-annotations.d.ts +23 -0
- package/dist/cli/command-annotations.d.ts.map +1 -0
- package/dist/cli/command-annotations.js +27 -0
- package/dist/cli/command-annotations.js.map +1 -0
- package/dist/cli/commands/agents.d.ts +46 -0
- package/dist/cli/commands/agents.d.ts.map +1 -0
- package/dist/cli/commands/agents.js +377 -0
- package/dist/cli/commands/agents.js.map +1 -0
- package/dist/cli/commands/batch.d.ts +20 -0
- package/dist/cli/commands/batch.d.ts.map +1 -0
- package/dist/cli/commands/batch.js +214 -0
- package/dist/cli/commands/batch.js.map +1 -0
- package/dist/cli/commands/clone-for-testing.d.ts +1 -1
- package/dist/cli/commands/clone-for-testing.d.ts.map +1 -1
- package/dist/cli/commands/clone-for-testing.js +37 -47
- package/dist/cli/commands/clone-for-testing.js.map +1 -1
- package/dist/cli/commands/derive.d.ts +1 -1
- package/dist/cli/commands/derive.d.ts.map +1 -1
- package/dist/cli/commands/derive.js +140 -88
- package/dist/cli/commands/derive.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts +11 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +152 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/export.d.ts +12 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +134 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/help.d.ts +1 -1
- package/dist/cli/commands/help.d.ts.map +1 -1
- package/dist/cli/commands/help.js +163 -37
- package/dist/cli/commands/help.js.map +1 -1
- package/dist/cli/commands/inbox.d.ts +1 -1
- package/dist/cli/commands/inbox.d.ts.map +1 -1
- package/dist/cli/commands/inbox.js +178 -56
- package/dist/cli/commands/inbox.js.map +1 -1
- package/dist/cli/commands/index.d.ts +31 -19
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +31 -19
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.d.ts +5 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +108 -57
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/item.d.ts +1 -1
- package/dist/cli/commands/item.d.ts.map +1 -1
- package/dist/cli/commands/item.js +557 -274
- package/dist/cli/commands/item.js.map +1 -1
- package/dist/cli/commands/link.d.ts +1 -1
- package/dist/cli/commands/link.d.ts.map +1 -1
- package/dist/cli/commands/link.js +55 -46
- package/dist/cli/commands/link.js.map +1 -1
- package/dist/cli/commands/log.d.ts +1 -1
- package/dist/cli/commands/log.d.ts.map +1 -1
- package/dist/cli/commands/log.js +57 -51
- package/dist/cli/commands/log.js.map +1 -1
- package/dist/cli/commands/merge-driver.d.ts +19 -0
- package/dist/cli/commands/merge-driver.d.ts.map +1 -0
- package/dist/cli/commands/merge-driver.js +398 -0
- package/dist/cli/commands/merge-driver.js.map +1 -0
- package/dist/cli/commands/meta.d.ts +1 -1
- package/dist/cli/commands/meta.d.ts.map +1 -1
- package/dist/cli/commands/meta.js +533 -399
- package/dist/cli/commands/meta.js.map +1 -1
- package/dist/cli/commands/module.d.ts +1 -1
- package/dist/cli/commands/module.d.ts.map +1 -1
- package/dist/cli/commands/module.js +30 -25
- package/dist/cli/commands/module.js.map +1 -1
- package/dist/cli/commands/plan-import.d.ts +11 -0
- package/dist/cli/commands/plan-import.d.ts.map +1 -0
- package/dist/cli/commands/plan-import.js +516 -0
- package/dist/cli/commands/plan-import.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +10 -0
- package/dist/cli/commands/plan.d.ts.map +1 -0
- package/dist/cli/commands/plan.js +421 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/ralph.d.ts +1 -1
- package/dist/cli/commands/ralph.d.ts.map +1 -1
- package/dist/cli/commands/ralph.js +1097 -169
- package/dist/cli/commands/ralph.js.map +1 -1
- package/dist/cli/commands/refs.d.ts +13 -0
- package/dist/cli/commands/refs.d.ts.map +1 -0
- package/dist/cli/commands/refs.js +283 -0
- package/dist/cli/commands/refs.js.map +1 -0
- package/dist/cli/commands/search.d.ts +1 -1
- package/dist/cli/commands/search.d.ts.map +1 -1
- package/dist/cli/commands/search.js +199 -37
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/serve.d.ts +10 -0
- package/dist/cli/commands/serve.d.ts.map +1 -0
- package/dist/cli/commands/serve.js +491 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/session.d.ts +25 -6
- package/dist/cli/commands/session.d.ts.map +1 -1
- package/dist/cli/commands/session.js +811 -127
- package/dist/cli/commands/session.js.map +1 -1
- package/dist/cli/commands/setup-seeding.d.ts +81 -0
- package/dist/cli/commands/setup-seeding.d.ts.map +1 -0
- package/dist/cli/commands/setup-seeding.js +292 -0
- package/dist/cli/commands/setup-seeding.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +77 -3
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +1233 -274
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/shadow.d.ts +1 -1
- package/dist/cli/commands/shadow.d.ts.map +1 -1
- package/dist/cli/commands/shadow.js +70 -50
- package/dist/cli/commands/shadow.js.map +1 -1
- package/dist/cli/commands/skill-crud.d.ts +58 -0
- package/dist/cli/commands/skill-crud.d.ts.map +1 -0
- package/dist/cli/commands/skill-crud.js +753 -0
- package/dist/cli/commands/skill-crud.js.map +1 -0
- package/dist/cli/commands/skill-diff.d.ts +27 -0
- package/dist/cli/commands/skill-diff.d.ts.map +1 -0
- package/dist/cli/commands/skill-diff.js +840 -0
- package/dist/cli/commands/skill-diff.js.map +1 -0
- package/dist/cli/commands/skill-install.d.ts +53 -0
- package/dist/cli/commands/skill-install.d.ts.map +1 -0
- package/dist/cli/commands/skill-install.js +452 -0
- package/dist/cli/commands/skill-install.js.map +1 -0
- package/dist/cli/commands/skill.d.ts +20 -0
- package/dist/cli/commands/skill.d.ts.map +1 -0
- package/dist/cli/commands/skill.js +36 -0
- package/dist/cli/commands/skill.js.map +1 -0
- package/dist/cli/commands/task.d.ts +1 -1
- package/dist/cli/commands/task.d.ts.map +1 -1
- package/dist/cli/commands/task.js +569 -346
- package/dist/cli/commands/task.js.map +1 -1
- package/dist/cli/commands/tasks.d.ts +26 -1
- package/dist/cli/commands/tasks.d.ts.map +1 -1
- package/dist/cli/commands/tasks.js +227 -122
- package/dist/cli/commands/tasks.js.map +1 -1
- package/dist/cli/commands/trait.d.ts +1 -1
- package/dist/cli/commands/trait.d.ts.map +1 -1
- package/dist/cli/commands/trait.js +166 -101
- package/dist/cli/commands/trait.js.map +1 -1
- package/dist/cli/commands/triage.d.ts +7 -0
- package/dist/cli/commands/triage.d.ts.map +1 -0
- package/dist/cli/commands/triage.js +569 -0
- package/dist/cli/commands/triage.js.map +1 -0
- package/dist/cli/commands/util.d.ts +7 -0
- package/dist/cli/commands/util.d.ts.map +1 -0
- package/dist/cli/commands/util.js +30 -0
- package/dist/cli/commands/util.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +1 -1
- package/dist/cli/commands/validate.d.ts.map +1 -1
- package/dist/cli/commands/validate.js +264 -83
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/commands/workflow.d.ts +16 -0
- package/dist/cli/commands/workflow.d.ts.map +1 -0
- package/dist/cli/commands/workflow.js +851 -0
- package/dist/cli/commands/workflow.js.map +1 -0
- package/dist/cli/exit-codes.d.ts +7 -0
- package/dist/cli/exit-codes.d.ts.map +1 -1
- package/dist/cli/exit-codes.js +26 -18
- package/dist/cli/exit-codes.js.map +1 -1
- package/dist/cli/help/content.d.ts.map +1 -1
- package/dist/cli/help/content.js +86 -71
- package/dist/cli/help/content.js.map +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +131 -19
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/introspection.d.ts +6 -2
- package/dist/cli/introspection.d.ts.map +1 -1
- package/dist/cli/introspection.js +11 -8
- package/dist/cli/introspection.js.map +1 -1
- package/dist/cli/output.d.ts +64 -4
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +235 -85
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/parse-utils.d.ts +21 -0
- package/dist/cli/parse-utils.d.ts.map +1 -0
- package/dist/cli/parse-utils.js +32 -0
- package/dist/cli/parse-utils.js.map +1 -0
- package/dist/cli/pid-utils.d.ts +72 -0
- package/dist/cli/pid-utils.d.ts.map +1 -0
- package/dist/cli/pid-utils.js +174 -0
- package/dist/cli/pid-utils.js.map +1 -0
- package/dist/cli/suggest.d.ts.map +1 -1
- package/dist/cli/suggest.js +1 -2
- package/dist/cli/suggest.js.map +1 -1
- package/dist/cli/validators.d.ts +43 -0
- package/dist/cli/validators.d.ts.map +1 -0
- package/dist/cli/validators.js +84 -0
- package/dist/cli/validators.js.map +1 -0
- package/dist/daemon/index.ts +52 -0
- package/dist/daemon/middleware/project-context.ts +126 -0
- package/dist/daemon/pid.ts +179 -0
- package/dist/daemon/project-context.ts +343 -0
- package/dist/daemon/routes/inbox.ts +164 -0
- package/dist/daemon/routes/items.ts +322 -0
- package/dist/daemon/routes/meta.ts +118 -0
- package/dist/daemon/routes/projects.ts +162 -0
- package/dist/daemon/routes/tasks.ts +327 -0
- package/dist/daemon/routes/triage.ts +468 -0
- package/dist/daemon/routes/validation.ts +248 -0
- package/dist/daemon/server.ts +408 -0
- package/dist/daemon/watcher.ts +195 -0
- package/dist/daemon/websocket/handler.ts +138 -0
- package/dist/daemon/websocket/heartbeat.ts +71 -0
- package/dist/daemon/websocket/pubsub.ts +125 -0
- package/dist/daemon/websocket/types.ts +66 -0
- package/dist/export/html.d.ts +19 -0
- package/dist/export/html.d.ts.map +1 -0
- package/dist/export/html.js +239 -0
- package/dist/export/html.js.map +1 -0
- package/dist/export/index.d.ts +10 -0
- package/dist/export/index.d.ts.map +1 -0
- package/dist/export/index.js +10 -0
- package/dist/export/index.js.map +1 -0
- package/dist/export/json.d.ts +24 -0
- package/dist/export/json.d.ts.map +1 -0
- package/dist/export/json.js +198 -0
- package/dist/export/json.js.map +1 -0
- package/dist/export/triage.d.ts +51 -0
- package/dist/export/triage.d.ts.map +1 -0
- package/dist/export/triage.js +83 -0
- package/dist/export/triage.js.map +1 -0
- package/dist/export/types.d.ts +122 -0
- package/dist/export/types.d.ts.map +1 -0
- package/dist/export/types.js +9 -0
- package/dist/export/types.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/lib/claude-plugin-registry.d.ts +66 -0
- package/dist/lib/claude-plugin-registry.d.ts.map +1 -0
- package/dist/lib/claude-plugin-registry.js +318 -0
- package/dist/lib/claude-plugin-registry.js.map +1 -0
- package/dist/merge/arrays.d.ts +87 -0
- package/dist/merge/arrays.d.ts.map +1 -0
- package/dist/merge/arrays.js +164 -0
- package/dist/merge/arrays.js.map +1 -0
- package/dist/merge/file-type.d.ts +32 -0
- package/dist/merge/file-type.d.ts.map +1 -0
- package/dist/merge/file-type.js +70 -0
- package/dist/merge/file-type.js.map +1 -0
- package/dist/merge/index.d.ts +14 -0
- package/dist/merge/index.d.ts.map +1 -0
- package/dist/merge/index.js +11 -0
- package/dist/merge/index.js.map +1 -0
- package/dist/merge/objects.d.ts +46 -0
- package/dist/merge/objects.d.ts.map +1 -0
- package/dist/merge/objects.js +193 -0
- package/dist/merge/objects.js.map +1 -0
- package/dist/merge/parse.d.ts +23 -0
- package/dist/merge/parse.d.ts.map +1 -0
- package/dist/merge/parse.js +78 -0
- package/dist/merge/parse.js.map +1 -0
- package/dist/merge/resolve.d.ts +66 -0
- package/dist/merge/resolve.d.ts.map +1 -0
- package/dist/merge/resolve.js +189 -0
- package/dist/merge/resolve.js.map +1 -0
- package/dist/merge/types.d.ts +82 -0
- package/dist/merge/types.d.ts.map +1 -0
- package/dist/merge/types.js +8 -0
- package/dist/merge/types.js.map +1 -0
- package/dist/parser/agent-data-sections.d.ts +53 -0
- package/dist/parser/agent-data-sections.d.ts.map +1 -0
- package/dist/parser/agent-data-sections.js +118 -0
- package/dist/parser/agent-data-sections.js.map +1 -0
- package/dist/parser/alignment.d.ts +4 -4
- package/dist/parser/alignment.d.ts.map +1 -1
- package/dist/parser/alignment.js +27 -22
- package/dist/parser/alignment.js.map +1 -1
- package/dist/parser/assess.d.ts +5 -5
- package/dist/parser/assess.d.ts.map +1 -1
- package/dist/parser/assess.js +36 -32
- package/dist/parser/assess.js.map +1 -1
- package/dist/parser/config.d.ts +351 -0
- package/dist/parser/config.d.ts.map +1 -0
- package/dist/parser/config.js +326 -0
- package/dist/parser/config.js.map +1 -0
- package/dist/parser/convention-validation.d.ts +1 -1
- package/dist/parser/convention-validation.d.ts.map +1 -1
- package/dist/parser/convention-validation.js +21 -16
- package/dist/parser/convention-validation.js.map +1 -1
- package/dist/parser/coverage-cache.d.ts +49 -0
- package/dist/parser/coverage-cache.d.ts.map +1 -0
- package/dist/parser/coverage-cache.js +123 -0
- package/dist/parser/coverage-cache.js.map +1 -0
- package/dist/parser/daemon-status.d.ts +37 -0
- package/dist/parser/daemon-status.d.ts.map +1 -0
- package/dist/parser/daemon-status.js +67 -0
- package/dist/parser/daemon-status.js.map +1 -0
- package/dist/parser/doctor.d.ts +107 -0
- package/dist/parser/doctor.d.ts.map +1 -0
- package/dist/parser/doctor.js +366 -0
- package/dist/parser/doctor.js.map +1 -0
- package/dist/parser/fix.d.ts +1 -1
- package/dist/parser/fix.d.ts.map +1 -1
- package/dist/parser/fix.js +31 -27
- package/dist/parser/fix.js.map +1 -1
- package/dist/parser/index.d.ts +16 -11
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/parser/index.js +16 -11
- package/dist/parser/index.js.map +1 -1
- package/dist/parser/items.d.ts +8 -2
- package/dist/parser/items.d.ts.map +1 -1
- package/dist/parser/items.js +71 -35
- package/dist/parser/items.js.map +1 -1
- package/dist/parser/meta.d.ts +167 -9
- package/dist/parser/meta.d.ts.map +1 -1
- package/dist/parser/meta.js +379 -46
- package/dist/parser/meta.js.map +1 -1
- package/dist/parser/plan-document.d.ts +189 -0
- package/dist/parser/plan-document.d.ts.map +1 -0
- package/dist/parser/plan-document.js +340 -0
- package/dist/parser/plan-document.js.map +1 -0
- package/dist/parser/plans.d.ts +59 -0
- package/dist/parser/plans.d.ts.map +1 -0
- package/dist/parser/plans.js +239 -0
- package/dist/parser/plans.js.map +1 -0
- package/dist/parser/refs.d.ts +22 -9
- package/dist/parser/refs.d.ts.map +1 -1
- package/dist/parser/refs.js +102 -50
- package/dist/parser/refs.js.map +1 -1
- package/dist/parser/setup-status.d.ts +71 -0
- package/dist/parser/setup-status.d.ts.map +1 -0
- package/dist/parser/setup-status.js +269 -0
- package/dist/parser/setup-status.js.map +1 -0
- package/dist/parser/shadow.d.ts +150 -19
- package/dist/parser/shadow.d.ts.map +1 -1
- package/dist/parser/shadow.js +548 -187
- package/dist/parser/shadow.js.map +1 -1
- package/dist/parser/skill-render.d.ts +317 -0
- package/dist/parser/skill-render.d.ts.map +1 -0
- package/dist/parser/skill-render.js +943 -0
- package/dist/parser/skill-render.js.map +1 -0
- package/dist/parser/traits.d.ts +3 -3
- package/dist/parser/traits.d.ts.map +1 -1
- package/dist/parser/traits.js +2 -2
- package/dist/parser/traits.js.map +1 -1
- package/dist/parser/validate-skills.d.ts +32 -0
- package/dist/parser/validate-skills.d.ts.map +1 -0
- package/dist/parser/validate-skills.js +202 -0
- package/dist/parser/validate-skills.js.map +1 -0
- package/dist/parser/validate.d.ts +45 -3
- package/dist/parser/validate.d.ts.map +1 -1
- package/dist/parser/validate.js +622 -105
- package/dist/parser/validate.js.map +1 -1
- package/dist/parser/yaml.d.ts +83 -19
- package/dist/parser/yaml.d.ts.map +1 -1
- package/dist/parser/yaml.js +478 -173
- package/dist/parser/yaml.js.map +1 -1
- package/dist/ralph/cli-renderer.d.ts +8 -1
- package/dist/ralph/cli-renderer.d.ts.map +1 -1
- package/dist/ralph/cli-renderer.js +105 -34
- package/dist/ralph/cli-renderer.js.map +1 -1
- package/dist/ralph/events.d.ts +10 -10
- package/dist/ralph/events.d.ts.map +1 -1
- package/dist/ralph/events.js +277 -98
- package/dist/ralph/events.js.map +1 -1
- package/dist/ralph/index.d.ts +5 -2
- package/dist/ralph/index.d.ts.map +1 -1
- package/dist/ralph/index.js +9 -3
- package/dist/ralph/index.js.map +1 -1
- package/dist/ralph/loop-errors.d.ts +83 -0
- package/dist/ralph/loop-errors.d.ts.map +1 -0
- package/dist/ralph/loop-errors.js +150 -0
- package/dist/ralph/loop-errors.js.map +1 -0
- package/dist/ralph/subagent.d.ts +83 -0
- package/dist/ralph/subagent.d.ts.map +1 -0
- package/dist/ralph/subagent.js +174 -0
- package/dist/ralph/subagent.js.map +1 -0
- package/dist/ralph/wrap-up.d.ts +125 -0
- package/dist/ralph/wrap-up.d.ts.map +1 -0
- package/dist/ralph/wrap-up.js +270 -0
- package/dist/ralph/wrap-up.js.map +1 -0
- package/dist/schema/batch.d.ts +95 -0
- package/dist/schema/batch.d.ts.map +1 -0
- package/dist/schema/batch.js +24 -0
- package/dist/schema/batch.js.map +1 -0
- package/dist/schema/common.d.ts +2 -2
- package/dist/schema/common.d.ts.map +1 -1
- package/dist/schema/common.js +34 -31
- package/dist/schema/common.js.map +1 -1
- package/dist/schema/inbox.d.ts +12 -12
- package/dist/schema/inbox.js +4 -4
- package/dist/schema/inbox.js.map +1 -1
- package/dist/schema/index.d.ts +8 -5
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +8 -5
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/meta.d.ts +1454 -27
- package/dist/schema/meta.d.ts.map +1 -1
- package/dist/schema/meta.js +198 -21
- package/dist/schema/meta.js.map +1 -1
- package/dist/schema/plan.d.ts +285 -0
- package/dist/schema/plan.d.ts.map +1 -0
- package/dist/schema/plan.js +81 -0
- package/dist/schema/plan.js.map +1 -0
- package/dist/schema/spec.d.ts +72 -33
- package/dist/schema/spec.d.ts.map +1 -1
- package/dist/schema/spec.js +22 -9
- package/dist/schema/spec.js.map +1 -1
- package/dist/schema/task.d.ts +172 -161
- package/dist/schema/task.d.ts.map +1 -1
- package/dist/schema/task.js +21 -12
- package/dist/schema/task.js.map +1 -1
- package/dist/schema/triage.d.ts +266 -0
- package/dist/schema/triage.d.ts.map +1 -0
- package/dist/schema/triage.js +134 -0
- package/dist/schema/triage.js.map +1 -0
- package/dist/sessions/index.d.ts +2 -2
- package/dist/sessions/index.d.ts.map +1 -1
- package/dist/sessions/index.js +3 -3
- package/dist/sessions/index.js.map +1 -1
- package/dist/sessions/store.d.ts +233 -1
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +628 -31
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/types.d.ts +10 -10
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js +10 -9
- package/dist/sessions/types.js.map +1 -1
- package/dist/strings/errors.d.ts +51 -0
- package/dist/strings/errors.d.ts.map +1 -1
- package/dist/strings/errors.js +136 -106
- package/dist/strings/errors.js.map +1 -1
- package/dist/strings/guidance.d.ts.map +1 -1
- package/dist/strings/guidance.js +16 -16
- package/dist/strings/guidance.js.map +1 -1
- package/dist/strings/index.d.ts +4 -4
- package/dist/strings/index.d.ts.map +1 -1
- package/dist/strings/index.js +4 -4
- package/dist/strings/index.js.map +1 -1
- package/dist/strings/labels.d.ts +4 -0
- package/dist/strings/labels.d.ts.map +1 -1
- package/dist/strings/labels.js +45 -41
- package/dist/strings/labels.js.map +1 -1
- package/dist/strings/validation.d.ts.map +1 -1
- package/dist/strings/validation.js +71 -71
- package/dist/strings/validation.js.map +1 -1
- package/dist/utils/commit.d.ts +1 -1
- package/dist/utils/commit.d.ts.map +1 -1
- package/dist/utils/commit.js +28 -26
- package/dist/utils/commit.js.map +1 -1
- package/dist/utils/git.d.ts +1 -1
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +40 -38
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/grep.js +11 -11
- package/dist/utils/grep.js.map +1 -1
- package/dist/utils/index.d.ts +7 -7
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +4 -4
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/time.d.ts.map +1 -1
- package/dist/utils/time.js +10 -10
- package/dist/utils/time.js.map +1 -1
- package/package.json +28 -5
- package/plugin/.claude-plugin/marketplace.json +17 -0
- package/plugin/.claude-plugin/plugin.json +5 -0
- package/plugin/plugins/kspec/skills/help/SKILL.md +42 -0
- package/plugin/plugins/kspec/skills/triage/SKILL.md +206 -0
- package/plugin/plugins/kspec/skills/triage/docs/automation.md +120 -0
- package/plugin/plugins/kspec/skills/triage/docs/inbox.md +144 -0
- package/plugin/plugins/kspec/skills/triage/docs/observations.md +85 -0
- package/templates/agents-sections/01-quick-start.md +22 -0
- package/templates/agents-sections/02-shadow-branch.md +34 -0
- package/templates/agents-sections/03-task-lifecycle.md +48 -0
- package/templates/agents-sections/04-pr-workflow.md +17 -0
- package/templates/agents-sections/05-commit-convention.md +27 -0
- package/templates/agents-sections/06-ralph-loop.md +45 -0
- package/templates/hooks/pre-commit +34 -0
- package/templates/skills/help/SKILL.md +37 -0
- package/templates/skills/manifest.yaml +15 -0
- package/templates/skills/triage/SKILL.md +199 -0
- package/templates/skills/triage/docs/automation.md +120 -0
- package/templates/skills/triage/docs/inbox.md +144 -0
- package/templates/skills/triage/docs/observations.md +85 -0
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Triage API Routes
|
|
3
|
+
*
|
|
4
|
+
* REST endpoints for triage operations:
|
|
5
|
+
* - GET /api/triage - list records with filters and pagination
|
|
6
|
+
* - GET /api/triage/export - export records for agent handoff
|
|
7
|
+
* - POST /api/triage - record a triage decision
|
|
8
|
+
* - GET /api/triage/:ref - get single record
|
|
9
|
+
* - POST /api/triage/:ref/override - override a decision
|
|
10
|
+
* - POST /api/triage/:ref/act - execute a triage action
|
|
11
|
+
*
|
|
12
|
+
* AC Coverage:
|
|
13
|
+
* - @triage-daemon-api ac-1: GET list sorted by created_at desc
|
|
14
|
+
* - @triage-daemon-api ac-2: Status filter on GET list
|
|
15
|
+
* - @triage-daemon-api ac-3: POST creates record with snapshot
|
|
16
|
+
* - @triage-daemon-api ac-4: PUT override sets override fields
|
|
17
|
+
* - @triage-daemon-api ac-5: PUT act executes and transitions
|
|
18
|
+
* - @triage-daemon-api ac-6: GET export with format parameter
|
|
19
|
+
* - @triage-daemon-api ac-7: POST 404 for nonexistent inbox item
|
|
20
|
+
* - @triage-daemon-api ac-8: PUT act 409 for already acted
|
|
21
|
+
* - @triage-daemon-api ac-9: PUT act 422 for pending record
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { Elysia, t } from 'elysia';
|
|
25
|
+
import { ulid } from 'ulidx';
|
|
26
|
+
import {
|
|
27
|
+
initContext,
|
|
28
|
+
loadTriageRecords,
|
|
29
|
+
saveTriageRecord,
|
|
30
|
+
findTriageRecordByRef,
|
|
31
|
+
findTriageRecordByInboxRef,
|
|
32
|
+
loadInboxItems,
|
|
33
|
+
findInboxItemByRef,
|
|
34
|
+
loadAllTasks,
|
|
35
|
+
loadAllItems,
|
|
36
|
+
ReferenceIndex,
|
|
37
|
+
getAuthor,
|
|
38
|
+
createObservation,
|
|
39
|
+
saveObservation,
|
|
40
|
+
createTask,
|
|
41
|
+
saveTask,
|
|
42
|
+
deleteInboxItem,
|
|
43
|
+
type LoadedTriageRecord,
|
|
44
|
+
} from '../../parser/index.js';
|
|
45
|
+
import { commitIfShadow } from '../../parser/shadow.js';
|
|
46
|
+
import type { TriageAction } from '../../schema/index.js';
|
|
47
|
+
import { exportTriageRecords } from '../../export/triage.js';
|
|
48
|
+
import type { PubSubManager } from '../websocket/pubsub';
|
|
49
|
+
|
|
50
|
+
interface TriageRouteOptions {
|
|
51
|
+
pubsub: PubSubManager;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const VALID_ACTIONS = ['promote', 'delete', 'defer', 'spec-gap', 'duplicate'];
|
|
55
|
+
|
|
56
|
+
// formatTriageContext moved to shared export/triage.ts (exportTriageRecords)
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Execute a triage action (reused from CLI logic)
|
|
60
|
+
* AC: @triage-daemon-api ac-5
|
|
61
|
+
*/
|
|
62
|
+
async function executeTriageAction(
|
|
63
|
+
record: LoadedTriageRecord,
|
|
64
|
+
ctx: Awaited<ReturnType<typeof initContext>>,
|
|
65
|
+
): Promise<{ resultRef?: string }> {
|
|
66
|
+
const action = record.action;
|
|
67
|
+
if (!action) return {};
|
|
68
|
+
|
|
69
|
+
switch (action) {
|
|
70
|
+
case 'promote': {
|
|
71
|
+
const task = createTask({
|
|
72
|
+
title: record.item_snapshot.split('\n')[0].slice(0, 100),
|
|
73
|
+
type: 'task',
|
|
74
|
+
priority: 3,
|
|
75
|
+
spec_ref: null,
|
|
76
|
+
tags: [],
|
|
77
|
+
description: record.item_snapshot,
|
|
78
|
+
});
|
|
79
|
+
await saveTask(ctx, task);
|
|
80
|
+
const tasks = await loadAllTasks(ctx);
|
|
81
|
+
const items = await loadAllItems(ctx);
|
|
82
|
+
const index = new ReferenceIndex(tasks, items);
|
|
83
|
+
const taskRef = `@${index.shortUlid(task._ulid)}`;
|
|
84
|
+
return { resultRef: taskRef };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
case 'delete':
|
|
88
|
+
case 'duplicate': {
|
|
89
|
+
const inboxItems = await loadInboxItems(ctx);
|
|
90
|
+
const inboxItem = findInboxItemByRef(inboxItems, record.inbox_ref);
|
|
91
|
+
if (inboxItem) {
|
|
92
|
+
await deleteInboxItem(ctx, inboxItem._ulid);
|
|
93
|
+
}
|
|
94
|
+
return {};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
case 'defer': {
|
|
98
|
+
return {};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
case 'spec-gap': {
|
|
102
|
+
const content = `[spec-gap] ${record.item_snapshot}\n\nReasoning: ${record.reasoning || ''}`;
|
|
103
|
+
const observation = createObservation('question', content, {
|
|
104
|
+
configAuthor: ctx.config?.identity?.author,
|
|
105
|
+
});
|
|
106
|
+
await saveObservation(ctx, observation);
|
|
107
|
+
const obsRef = `@${observation._ulid.slice(0, 8)}`;
|
|
108
|
+
return { resultRef: obsRef };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
default:
|
|
112
|
+
return {};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function createTriageRoutes(options: TriageRouteOptions) {
|
|
117
|
+
const { pubsub } = options;
|
|
118
|
+
|
|
119
|
+
return new Elysia({ prefix: '/api/triage' })
|
|
120
|
+
// AC: @triage-daemon-api ac-1, ac-2 - List triage records with filters and pagination
|
|
121
|
+
// AC: @trait-api-endpoint ac-1, ac-4 - JSON response with pagination wrapper
|
|
122
|
+
.get(
|
|
123
|
+
'/',
|
|
124
|
+
async ({ query, projectContext }) => {
|
|
125
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
126
|
+
const ctx = await initContext(projectContext.path);
|
|
127
|
+
const records = await loadTriageRecords(ctx);
|
|
128
|
+
|
|
129
|
+
// Apply filters
|
|
130
|
+
let filtered = records;
|
|
131
|
+
|
|
132
|
+
// AC: @triage-daemon-api ac-2 - Status filter
|
|
133
|
+
if (query.status) {
|
|
134
|
+
const statusFilters = Array.isArray(query.status) ? query.status : [query.status];
|
|
135
|
+
filtered = filtered.filter((r) => statusFilters.includes(r.status));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Action filter
|
|
139
|
+
if (query.action) {
|
|
140
|
+
const actionFilters = Array.isArray(query.action) ? query.action : [query.action];
|
|
141
|
+
filtered = filtered.filter((r) => r.action && actionFilters.includes(r.action));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// AC: @triage-daemon-api ac-1 - Sort by created_at descending (newest first)
|
|
145
|
+
filtered.sort(
|
|
146
|
+
(a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
// AC: @trait-api-endpoint ac-4 - Pagination with limit and offset
|
|
150
|
+
const total = filtered.length;
|
|
151
|
+
const offset = Number(query.offset) || 0;
|
|
152
|
+
const limit = Number(query.limit) || total;
|
|
153
|
+
|
|
154
|
+
const paginated = filtered.slice(offset, offset + limit);
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
items: paginated,
|
|
158
|
+
total,
|
|
159
|
+
offset,
|
|
160
|
+
limit,
|
|
161
|
+
};
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
query: t.Object({
|
|
165
|
+
status: t.Optional(t.Union([t.String(), t.Array(t.String())])),
|
|
166
|
+
action: t.Optional(t.Union([t.String(), t.Array(t.String())])),
|
|
167
|
+
limit: t.Optional(t.String()),
|
|
168
|
+
offset: t.Optional(t.String()),
|
|
169
|
+
}),
|
|
170
|
+
}
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
// AC: @triage-daemon-api ac-6 - Export triage records
|
|
174
|
+
// NOTE: This route MUST be defined before /:ref to avoid "export" being parsed as a ref
|
|
175
|
+
.get(
|
|
176
|
+
'/export',
|
|
177
|
+
async ({ query, projectContext }) => {
|
|
178
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
179
|
+
const ctx = await initContext(projectContext.path);
|
|
180
|
+
let records = await loadTriageRecords(ctx);
|
|
181
|
+
|
|
182
|
+
// Optional status filter on export
|
|
183
|
+
if (query.status) {
|
|
184
|
+
const statusFilters = Array.isArray(query.status) ? query.status : [query.status];
|
|
185
|
+
records = records.filter((r) => statusFilters.includes(r.status));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const format = (query.format || 'json') as 'json' | 'context';
|
|
189
|
+
|
|
190
|
+
// AC: @triage-daemon-api ac-6 - Export via shared formatter
|
|
191
|
+
// AC: @triage-agent-export ac-1, ac-2, ac-3, ac-4
|
|
192
|
+
return exportTriageRecords(records, format);
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
query: t.Object({
|
|
196
|
+
format: t.Optional(t.String()),
|
|
197
|
+
status: t.Optional(t.Union([t.String(), t.Array(t.String())])),
|
|
198
|
+
}),
|
|
199
|
+
}
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
// AC: @triage-daemon-api ac-3 - Record a triage decision
|
|
203
|
+
// AC: @trait-api-endpoint ac-1, ac-3, ac-5 - JSON response, validation, shadow commit
|
|
204
|
+
.post(
|
|
205
|
+
'/',
|
|
206
|
+
async ({ body, error: errorResponse, projectContext }) => {
|
|
207
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
208
|
+
const ctx = await initContext(projectContext.path);
|
|
209
|
+
|
|
210
|
+
// AC: @trait-api-endpoint ac-3 - Validate action
|
|
211
|
+
if (!VALID_ACTIONS.includes(body.action)) {
|
|
212
|
+
return errorResponse(400, {
|
|
213
|
+
error: 'validation_error',
|
|
214
|
+
details: [
|
|
215
|
+
{
|
|
216
|
+
field: 'action',
|
|
217
|
+
message: `Action must be one of: ${VALID_ACTIONS.join(', ')}`,
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// AC: @triage-daemon-api ac-7 - Validate inbox item exists
|
|
224
|
+
const inboxItems = await loadInboxItems(ctx);
|
|
225
|
+
const inboxItem = findInboxItemByRef(inboxItems, body.inbox_ref);
|
|
226
|
+
if (!inboxItem) {
|
|
227
|
+
// AC: @trait-api-endpoint ac-2 - 404 with error guidance
|
|
228
|
+
return errorResponse(404, {
|
|
229
|
+
error: 'not_found',
|
|
230
|
+
message: `Inbox item reference "${body.inbox_ref}" not found`,
|
|
231
|
+
suggestion: 'Use kspec inbox list or GET /api/inbox to find valid inbox item references',
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const author = body.decided_by || getAuthor(ctx.config?.identity?.author);
|
|
236
|
+
const evidenceRefs = body.evidence_refs
|
|
237
|
+
? body.evidence_refs.map((r: string) => r.startsWith('@') ? r : `@${r}`)
|
|
238
|
+
: [];
|
|
239
|
+
|
|
240
|
+
// Check if a record already exists for this inbox item (upsert case)
|
|
241
|
+
const existingRecords = await loadTriageRecords(ctx);
|
|
242
|
+
const existing = findTriageRecordByInboxRef(existingRecords, inboxItem._ulid);
|
|
243
|
+
|
|
244
|
+
// AC: @triage-daemon-api ac-3 - Create record with item_snapshot
|
|
245
|
+
const record: LoadedTriageRecord = {
|
|
246
|
+
_ulid: existing?._ulid || ulid(),
|
|
247
|
+
inbox_ref: inboxItem._ulid,
|
|
248
|
+
item_snapshot: inboxItem.text,
|
|
249
|
+
status: 'triaged',
|
|
250
|
+
action: body.action as TriageAction,
|
|
251
|
+
reasoning: body.reasoning,
|
|
252
|
+
decided_by: author,
|
|
253
|
+
evidence_refs: evidenceRefs,
|
|
254
|
+
created_at: existing?.created_at || new Date().toISOString(),
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
await saveTriageRecord(ctx, record);
|
|
258
|
+
|
|
259
|
+
// Reload to get the persisted record (saveTriageRecord may upsert by inbox_ref)
|
|
260
|
+
const savedRecords = await loadTriageRecords(ctx);
|
|
261
|
+
const savedRecord = findTriageRecordByInboxRef(savedRecords, inboxItem._ulid) || record;
|
|
262
|
+
|
|
263
|
+
// AC: @trait-api-endpoint ac-5 - Shadow commit
|
|
264
|
+
await commitIfShadow(ctx.shadow, `triage: record ${savedRecord._ulid.slice(0, 8)} as ${savedRecord.action}`);
|
|
265
|
+
|
|
266
|
+
// AC: @triage-daemon-api ac-3 - Broadcast triage:updates via WebSocket
|
|
267
|
+
// AC: @trait-websocket-protocol ac-3 - Broadcast event
|
|
268
|
+
pubsub.broadcast('triage:updates', 'triage_record_created', {
|
|
269
|
+
ulid: savedRecord._ulid,
|
|
270
|
+
inbox_ref: savedRecord.inbox_ref,
|
|
271
|
+
action: savedRecord.action,
|
|
272
|
+
}, projectContext.path);
|
|
273
|
+
|
|
274
|
+
// AC: @trait-api-endpoint ac-1 - Return 2xx with JSON body
|
|
275
|
+
return {
|
|
276
|
+
success: true,
|
|
277
|
+
record: savedRecord,
|
|
278
|
+
};
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
body: t.Object({
|
|
282
|
+
inbox_ref: t.String(),
|
|
283
|
+
action: t.String(),
|
|
284
|
+
reasoning: t.String(),
|
|
285
|
+
decided_by: t.Optional(t.String()),
|
|
286
|
+
evidence_refs: t.Optional(t.Array(t.String())),
|
|
287
|
+
}),
|
|
288
|
+
}
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
// GET single triage record
|
|
292
|
+
.get(
|
|
293
|
+
'/:ref',
|
|
294
|
+
async ({ params, error: errorResponse, projectContext }) => {
|
|
295
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
296
|
+
const ctx = await initContext(projectContext.path);
|
|
297
|
+
const records = await loadTriageRecords(ctx);
|
|
298
|
+
|
|
299
|
+
// AC: @trait-api-endpoint ac-2 - Resolve ref
|
|
300
|
+
const record = findTriageRecordByRef(records, params.ref);
|
|
301
|
+
if (!record) {
|
|
302
|
+
return errorResponse(404, {
|
|
303
|
+
error: 'not_found',
|
|
304
|
+
message: `Triage record reference "${params.ref}" not found`,
|
|
305
|
+
suggestion: 'Use kspec triage list or GET /api/triage to find valid triage record references',
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return record;
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
params: t.Object({
|
|
313
|
+
ref: t.String(),
|
|
314
|
+
}),
|
|
315
|
+
}
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
// AC: @triage-daemon-api ac-4 - Override a triage decision
|
|
319
|
+
// AC: @trait-api-endpoint ac-1, ac-5 - JSON response, shadow commit
|
|
320
|
+
.post(
|
|
321
|
+
'/:ref/override',
|
|
322
|
+
async ({ params, body, error: errorResponse, projectContext }) => {
|
|
323
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
324
|
+
const ctx = await initContext(projectContext.path);
|
|
325
|
+
const records = await loadTriageRecords(ctx);
|
|
326
|
+
|
|
327
|
+
// AC: @trait-api-endpoint ac-2 - Resolve ref
|
|
328
|
+
const record = findTriageRecordByRef(records, params.ref);
|
|
329
|
+
if (!record) {
|
|
330
|
+
return errorResponse(404, {
|
|
331
|
+
error: 'not_found',
|
|
332
|
+
message: `Triage record reference "${params.ref}" not found`,
|
|
333
|
+
suggestion: 'Use kspec triage list or GET /api/triage to find valid triage record references',
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// AC: @trait-api-endpoint ac-3 - Validate action
|
|
338
|
+
if (!VALID_ACTIONS.includes(body.action)) {
|
|
339
|
+
return errorResponse(400, {
|
|
340
|
+
error: 'validation_error',
|
|
341
|
+
details: [
|
|
342
|
+
{
|
|
343
|
+
field: 'action',
|
|
344
|
+
message: `Action must be one of: ${VALID_ACTIONS.join(', ')}`,
|
|
345
|
+
},
|
|
346
|
+
],
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const overrideBy = body.override_by || getAuthor(ctx.config?.identity?.author);
|
|
351
|
+
|
|
352
|
+
// AC: @triage-daemon-api ac-4 - Set override fields and update action
|
|
353
|
+
record.override_reasoning = body.reasoning;
|
|
354
|
+
record.override_by = overrideBy;
|
|
355
|
+
record.override_at = new Date().toISOString();
|
|
356
|
+
record.action = body.action as TriageAction;
|
|
357
|
+
record.updated_at = new Date().toISOString();
|
|
358
|
+
|
|
359
|
+
// Re-triage if already acted on (allows re-acting with new action)
|
|
360
|
+
// Clear stale execution metadata to avoid leaking previous action results
|
|
361
|
+
if (record.status === 'acted_on') {
|
|
362
|
+
record.status = 'triaged';
|
|
363
|
+
record.acted_at = undefined;
|
|
364
|
+
record.result_ref = undefined;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
await saveTriageRecord(ctx, record);
|
|
368
|
+
|
|
369
|
+
// AC: @trait-api-endpoint ac-5 - Shadow commit
|
|
370
|
+
await commitIfShadow(ctx.shadow, `triage: override ${record._ulid.slice(0, 8)}`);
|
|
371
|
+
|
|
372
|
+
// AC: @triage-daemon-api ac-4 - Broadcast triage:updates
|
|
373
|
+
pubsub.broadcast('triage:updates', 'triage_record_updated', {
|
|
374
|
+
ulid: record._ulid,
|
|
375
|
+
action: 'override',
|
|
376
|
+
new_action: record.action,
|
|
377
|
+
}, projectContext.path);
|
|
378
|
+
|
|
379
|
+
return {
|
|
380
|
+
success: true,
|
|
381
|
+
record,
|
|
382
|
+
};
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
params: t.Object({
|
|
386
|
+
ref: t.String(),
|
|
387
|
+
}),
|
|
388
|
+
body: t.Object({
|
|
389
|
+
action: t.String(),
|
|
390
|
+
reasoning: t.String(),
|
|
391
|
+
override_by: t.Optional(t.String()),
|
|
392
|
+
}),
|
|
393
|
+
}
|
|
394
|
+
)
|
|
395
|
+
|
|
396
|
+
// AC: @triage-daemon-api ac-5, ac-8, ac-9 - Execute a triage action
|
|
397
|
+
// AC: @trait-api-endpoint ac-1, ac-5 - JSON response, shadow commit
|
|
398
|
+
.post(
|
|
399
|
+
'/:ref/act',
|
|
400
|
+
async ({ params, error: errorResponse, projectContext }) => {
|
|
401
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
402
|
+
const ctx = await initContext(projectContext.path);
|
|
403
|
+
const records = await loadTriageRecords(ctx);
|
|
404
|
+
|
|
405
|
+
// AC: @trait-api-endpoint ac-2 - Resolve ref
|
|
406
|
+
const record = findTriageRecordByRef(records, params.ref);
|
|
407
|
+
if (!record) {
|
|
408
|
+
return errorResponse(404, {
|
|
409
|
+
error: 'not_found',
|
|
410
|
+
message: `Triage record reference "${params.ref}" not found`,
|
|
411
|
+
suggestion: 'Use kspec triage list or GET /api/triage to find valid triage record references',
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// AC: @triage-daemon-api ac-8 - Already acted on → 409
|
|
416
|
+
if (record.status === 'acted_on') {
|
|
417
|
+
return errorResponse(409, {
|
|
418
|
+
error: 'invalid_transition',
|
|
419
|
+
message: 'Triage record has already been acted on',
|
|
420
|
+
current: record.status,
|
|
421
|
+
suggestion: 'Use override to change the decision before acting again',
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// AC: @triage-daemon-api ac-9 - Pending (no decision) → 422
|
|
426
|
+
if (record.status === 'pending') {
|
|
427
|
+
return errorResponse(422, {
|
|
428
|
+
error: 'incomplete_record',
|
|
429
|
+
message: 'No decision has been recorded for this triage record. Complete triage first.',
|
|
430
|
+
suggestion: 'Use POST /api/triage to record a decision, or kspec triage record <inbox-ref> --action <action> --reasoning <text>',
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// AC: @triage-daemon-api ac-5 - Execute the action
|
|
435
|
+
const result = await executeTriageAction(record, ctx);
|
|
436
|
+
|
|
437
|
+
// Transition to acted_on
|
|
438
|
+
record.status = 'acted_on';
|
|
439
|
+
record.acted_at = new Date().toISOString();
|
|
440
|
+
if (result.resultRef) {
|
|
441
|
+
record.result_ref = result.resultRef;
|
|
442
|
+
}
|
|
443
|
+
record.updated_at = new Date().toISOString();
|
|
444
|
+
|
|
445
|
+
await saveTriageRecord(ctx, record);
|
|
446
|
+
|
|
447
|
+
// AC: @trait-api-endpoint ac-5 - Shadow commit
|
|
448
|
+
await commitIfShadow(ctx.shadow, `triage: act ${record._ulid.slice(0, 8)}`);
|
|
449
|
+
|
|
450
|
+
// AC: @triage-daemon-api ac-5 - Broadcast triage:updates
|
|
451
|
+
pubsub.broadcast('triage:updates', 'triage_record_acted', {
|
|
452
|
+
ulid: record._ulid,
|
|
453
|
+
action: record.action,
|
|
454
|
+
result_ref: record.result_ref,
|
|
455
|
+
}, projectContext.path);
|
|
456
|
+
|
|
457
|
+
return {
|
|
458
|
+
success: true,
|
|
459
|
+
record,
|
|
460
|
+
};
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
params: t.Object({
|
|
464
|
+
ref: t.String(),
|
|
465
|
+
}),
|
|
466
|
+
}
|
|
467
|
+
);
|
|
468
|
+
}
|