@kynetic-ai/spec 0.1.2 → 0.4.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 +107 -0
- package/dist/cli/batch-exec.d.ts.map +1 -0
- package/dist/cli/batch-exec.js +706 -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 +141 -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 +58 -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 +534 -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 +547 -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 +1109 -170
- 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 +810 -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 +1267 -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 +56 -0
- package/dist/cli/commands/skill-install.d.ts.map +1 -0
- package/dist/cli/commands/skill-install.js +509 -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 +584 -350
- 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 +225 -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 +483 -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 +237 -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 +402 -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 +457 -0
- package/dist/parser/config.d.ts.map +1 -0
- package/dist/parser/config.js +373 -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 +197 -0
- package/dist/parser/plan-document.d.ts.map +1 -0
- package/dist/parser/plan-document.js +341 -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 +301 -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 +94 -0
- package/dist/ralph/subagent.d.ts.map +1 -0
- package/dist/ralph/subagent.js +193 -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 +97 -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 +8 -2
- package/dist/schema/common.d.ts.map +1 -1
- package/dist/schema/common.js +42 -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 +241 -1
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +810 -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 +55 -0
- package/dist/strings/errors.d.ts.map +1 -1
- package/dist/strings/errors.js +138 -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/triage/actions.d.ts +27 -0
- package/dist/triage/actions.d.ts.map +1 -0
- package/dist/triage/actions.js +95 -0
- package/dist/triage/actions.js.map +1 -0
- package/dist/triage/constants.d.ts +6 -0
- package/dist/triage/constants.d.ts.map +1 -0
- package/dist/triage/constants.js +7 -0
- package/dist/triage/constants.js.map +1 -0
- package/dist/triage/index.d.ts +3 -0
- package/dist/triage/index.d.ts.map +1 -0
- package/dist/triage/index.js +3 -0
- package/dist/triage/index.js.map +1 -0
- 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/create-workflow/SKILL.md +235 -0
- package/plugin/plugins/kspec/skills/help/SKILL.md +42 -0
- package/plugin/plugins/kspec/skills/observations/SKILL.md +143 -0
- package/plugin/plugins/kspec/skills/plan/SKILL.md +343 -0
- package/plugin/plugins/kspec/skills/reflect/SKILL.md +161 -0
- package/plugin/plugins/kspec/skills/review/SKILL.md +193 -0
- package/plugin/plugins/kspec/skills/task-work/SKILL.md +303 -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/plugin/plugins/kspec/skills/triage-automation/SKILL.md +140 -0
- package/plugin/plugins/kspec/skills/triage-inbox/SKILL.md +232 -0
- package/plugin/plugins/kspec/skills/writing-specs/SKILL.md +340 -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/create-workflow/SKILL.md +228 -0
- package/templates/skills/help/SKILL.md +37 -0
- package/templates/skills/manifest.yaml +60 -0
- package/templates/skills/observations/SKILL.md +137 -0
- package/templates/skills/plan/SKILL.md +336 -0
- package/templates/skills/reflect/SKILL.md +155 -0
- package/templates/skills/review/SKILL.md +186 -0
- package/templates/skills/task-work/SKILL.md +296 -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
- package/templates/skills/triage-automation/SKILL.md +134 -0
- package/templates/skills/triage-inbox/SKILL.md +225 -0
- package/templates/skills/writing-specs/SKILL.md +333 -0
|
@@ -0,0 +1,402 @@
|
|
|
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
|
+
getAuthor,
|
|
35
|
+
type LoadedTriageRecord,
|
|
36
|
+
} from '../../parser/index.js';
|
|
37
|
+
import { commitIfShadow } from '../../parser/shadow.js';
|
|
38
|
+
import { normalizeRefInput } from '../../schema/index.js';
|
|
39
|
+
import type { TriageAction } from '../../schema/index.js';
|
|
40
|
+
import { exportTriageRecords } from '../../export/triage.js';
|
|
41
|
+
import { executeTriageAction, VALID_ACTIONS } from '../../triage/index.js';
|
|
42
|
+
import type { PubSubManager } from '../websocket/pubsub';
|
|
43
|
+
|
|
44
|
+
interface TriageRouteOptions {
|
|
45
|
+
pubsub: PubSubManager;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// VALID_ACTIONS and executeTriageAction imported from shared triage module
|
|
49
|
+
|
|
50
|
+
export function createTriageRoutes(options: TriageRouteOptions) {
|
|
51
|
+
const { pubsub } = options;
|
|
52
|
+
|
|
53
|
+
return new Elysia({ prefix: '/api/triage' })
|
|
54
|
+
// AC: @triage-daemon-api ac-1, ac-2 - List triage records with filters and pagination
|
|
55
|
+
// AC: @trait-api-endpoint ac-1, ac-4 - JSON response with pagination wrapper
|
|
56
|
+
.get(
|
|
57
|
+
'/',
|
|
58
|
+
async ({ query, projectContext }) => {
|
|
59
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
60
|
+
const ctx = await initContext(projectContext.path);
|
|
61
|
+
const records = await loadTriageRecords(ctx);
|
|
62
|
+
|
|
63
|
+
// Apply filters
|
|
64
|
+
let filtered = records;
|
|
65
|
+
|
|
66
|
+
// AC: @triage-daemon-api ac-2 - Status filter
|
|
67
|
+
if (query.status) {
|
|
68
|
+
const statusFilters = Array.isArray(query.status) ? query.status : [query.status];
|
|
69
|
+
filtered = filtered.filter((r) => statusFilters.includes(r.status));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Action filter
|
|
73
|
+
if (query.action) {
|
|
74
|
+
const actionFilters = Array.isArray(query.action) ? query.action : [query.action];
|
|
75
|
+
filtered = filtered.filter((r) => r.action && actionFilters.includes(r.action));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// AC: @triage-daemon-api ac-1 - Sort by created_at descending (newest first)
|
|
79
|
+
filtered.sort(
|
|
80
|
+
(a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
// AC: @trait-api-endpoint ac-4 - Pagination with limit and offset
|
|
84
|
+
const total = filtered.length;
|
|
85
|
+
const offset = Number(query.offset) || 0;
|
|
86
|
+
const limit = Number(query.limit) || total;
|
|
87
|
+
|
|
88
|
+
const paginated = filtered.slice(offset, offset + limit);
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
items: paginated,
|
|
92
|
+
total,
|
|
93
|
+
offset,
|
|
94
|
+
limit,
|
|
95
|
+
};
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
query: t.Object({
|
|
99
|
+
status: t.Optional(t.Union([t.String(), t.Array(t.String())])),
|
|
100
|
+
action: t.Optional(t.Union([t.String(), t.Array(t.String())])),
|
|
101
|
+
limit: t.Optional(t.String()),
|
|
102
|
+
offset: t.Optional(t.String()),
|
|
103
|
+
}),
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
// AC: @triage-daemon-api ac-6 - Export triage records
|
|
108
|
+
// NOTE: This route MUST be defined before /:ref to avoid "export" being parsed as a ref
|
|
109
|
+
.get(
|
|
110
|
+
'/export',
|
|
111
|
+
async ({ query, projectContext }) => {
|
|
112
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
113
|
+
const ctx = await initContext(projectContext.path);
|
|
114
|
+
let records = await loadTriageRecords(ctx);
|
|
115
|
+
|
|
116
|
+
// Optional status filter on export
|
|
117
|
+
if (query.status) {
|
|
118
|
+
const statusFilters = Array.isArray(query.status) ? query.status : [query.status];
|
|
119
|
+
records = records.filter((r) => statusFilters.includes(r.status));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const format = (query.format || 'json') as 'json' | 'context';
|
|
123
|
+
|
|
124
|
+
// AC: @triage-daemon-api ac-6 - Export via shared formatter
|
|
125
|
+
// AC: @triage-agent-export ac-1, ac-2, ac-3, ac-4
|
|
126
|
+
return exportTriageRecords(records, format);
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
query: t.Object({
|
|
130
|
+
format: t.Optional(t.String()),
|
|
131
|
+
status: t.Optional(t.Union([t.String(), t.Array(t.String())])),
|
|
132
|
+
}),
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
// AC: @triage-daemon-api ac-3 - Record a triage decision
|
|
137
|
+
// AC: @trait-api-endpoint ac-1, ac-3, ac-5 - JSON response, validation, shadow commit
|
|
138
|
+
.post(
|
|
139
|
+
'/',
|
|
140
|
+
async ({ body, error: errorResponse, projectContext }) => {
|
|
141
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
142
|
+
const ctx = await initContext(projectContext.path);
|
|
143
|
+
|
|
144
|
+
// AC: @trait-api-endpoint ac-3 - Validate action
|
|
145
|
+
if (!VALID_ACTIONS.includes(body.action)) {
|
|
146
|
+
return errorResponse(400, {
|
|
147
|
+
error: 'validation_error',
|
|
148
|
+
details: [
|
|
149
|
+
{
|
|
150
|
+
field: 'action',
|
|
151
|
+
message: `Action must be one of: ${VALID_ACTIONS.join(', ')}`,
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// AC: @triage-daemon-api ac-7 - Validate inbox item exists
|
|
158
|
+
const inboxItems = await loadInboxItems(ctx);
|
|
159
|
+
const inboxItem = findInboxItemByRef(inboxItems, body.inbox_ref);
|
|
160
|
+
if (!inboxItem) {
|
|
161
|
+
// AC: @trait-api-endpoint ac-2 - 404 with error guidance
|
|
162
|
+
return errorResponse(404, {
|
|
163
|
+
error: 'not_found',
|
|
164
|
+
message: `Inbox item reference "${body.inbox_ref}" not found`,
|
|
165
|
+
suggestion: 'Use kspec inbox list or GET /api/inbox to find valid inbox item references',
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const author = body.decided_by || getAuthor(ctx.config?.identity?.author);
|
|
170
|
+
const evidenceRefs = body.evidence_refs
|
|
171
|
+
? body.evidence_refs.map(normalizeRefInput)
|
|
172
|
+
: [];
|
|
173
|
+
|
|
174
|
+
// Check if a record already exists for this inbox item (upsert case)
|
|
175
|
+
const existingRecords = await loadTriageRecords(ctx);
|
|
176
|
+
const existing = findTriageRecordByInboxRef(existingRecords, inboxItem._ulid);
|
|
177
|
+
|
|
178
|
+
// AC: @triage-daemon-api ac-3 - Create record with item_snapshot
|
|
179
|
+
const record: LoadedTriageRecord = {
|
|
180
|
+
_ulid: existing?._ulid || ulid(),
|
|
181
|
+
inbox_ref: inboxItem._ulid,
|
|
182
|
+
item_snapshot: inboxItem.text,
|
|
183
|
+
status: 'triaged',
|
|
184
|
+
action: body.action as TriageAction,
|
|
185
|
+
reasoning: body.reasoning,
|
|
186
|
+
decided_by: author,
|
|
187
|
+
evidence_refs: evidenceRefs,
|
|
188
|
+
created_at: existing?.created_at || new Date().toISOString(),
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
await saveTriageRecord(ctx, record);
|
|
192
|
+
|
|
193
|
+
// Reload to get the persisted record (saveTriageRecord may upsert by inbox_ref)
|
|
194
|
+
const savedRecords = await loadTriageRecords(ctx);
|
|
195
|
+
const savedRecord = findTriageRecordByInboxRef(savedRecords, inboxItem._ulid) || record;
|
|
196
|
+
|
|
197
|
+
// AC: @trait-api-endpoint ac-5 - Shadow commit
|
|
198
|
+
await commitIfShadow(ctx.shadow, `triage: record ${savedRecord._ulid.slice(0, 8)} as ${savedRecord.action}`);
|
|
199
|
+
|
|
200
|
+
// AC: @triage-daemon-api ac-3 - Broadcast triage:updates via WebSocket
|
|
201
|
+
// AC: @trait-websocket-protocol ac-3 - Broadcast event
|
|
202
|
+
pubsub.broadcast('triage:updates', 'triage_record_created', {
|
|
203
|
+
ulid: savedRecord._ulid,
|
|
204
|
+
inbox_ref: savedRecord.inbox_ref,
|
|
205
|
+
action: savedRecord.action,
|
|
206
|
+
}, projectContext.path);
|
|
207
|
+
|
|
208
|
+
// AC: @trait-api-endpoint ac-1 - Return 2xx with JSON body
|
|
209
|
+
return {
|
|
210
|
+
success: true,
|
|
211
|
+
record: savedRecord,
|
|
212
|
+
};
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
body: t.Object({
|
|
216
|
+
inbox_ref: t.String(),
|
|
217
|
+
action: t.String(),
|
|
218
|
+
reasoning: t.String(),
|
|
219
|
+
decided_by: t.Optional(t.String()),
|
|
220
|
+
evidence_refs: t.Optional(t.Array(t.String())),
|
|
221
|
+
}),
|
|
222
|
+
}
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
// GET single triage record
|
|
226
|
+
.get(
|
|
227
|
+
'/:ref',
|
|
228
|
+
async ({ params, error: errorResponse, projectContext }) => {
|
|
229
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
230
|
+
const ctx = await initContext(projectContext.path);
|
|
231
|
+
const records = await loadTriageRecords(ctx);
|
|
232
|
+
|
|
233
|
+
// AC: @trait-api-endpoint ac-2 - Resolve ref
|
|
234
|
+
const record = findTriageRecordByRef(records, params.ref);
|
|
235
|
+
if (!record) {
|
|
236
|
+
return errorResponse(404, {
|
|
237
|
+
error: 'not_found',
|
|
238
|
+
message: `Triage record reference "${params.ref}" not found`,
|
|
239
|
+
suggestion: 'Use kspec triage list or GET /api/triage to find valid triage record references',
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return record;
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
params: t.Object({
|
|
247
|
+
ref: t.String(),
|
|
248
|
+
}),
|
|
249
|
+
}
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
// AC: @triage-daemon-api ac-4 - Override a triage decision
|
|
253
|
+
// AC: @trait-api-endpoint ac-1, ac-5 - JSON response, shadow commit
|
|
254
|
+
.post(
|
|
255
|
+
'/:ref/override',
|
|
256
|
+
async ({ params, body, error: errorResponse, projectContext }) => {
|
|
257
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
258
|
+
const ctx = await initContext(projectContext.path);
|
|
259
|
+
const records = await loadTriageRecords(ctx);
|
|
260
|
+
|
|
261
|
+
// AC: @trait-api-endpoint ac-2 - Resolve ref
|
|
262
|
+
const record = findTriageRecordByRef(records, params.ref);
|
|
263
|
+
if (!record) {
|
|
264
|
+
return errorResponse(404, {
|
|
265
|
+
error: 'not_found',
|
|
266
|
+
message: `Triage record reference "${params.ref}" not found`,
|
|
267
|
+
suggestion: 'Use kspec triage list or GET /api/triage to find valid triage record references',
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// AC: @trait-api-endpoint ac-3 - Validate action
|
|
272
|
+
if (!VALID_ACTIONS.includes(body.action)) {
|
|
273
|
+
return errorResponse(400, {
|
|
274
|
+
error: 'validation_error',
|
|
275
|
+
details: [
|
|
276
|
+
{
|
|
277
|
+
field: 'action',
|
|
278
|
+
message: `Action must be one of: ${VALID_ACTIONS.join(', ')}`,
|
|
279
|
+
},
|
|
280
|
+
],
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const overrideBy = body.override_by || getAuthor(ctx.config?.identity?.author);
|
|
285
|
+
|
|
286
|
+
// AC: @triage-daemon-api ac-4 - Set override fields and update action
|
|
287
|
+
record.override_reasoning = body.reasoning;
|
|
288
|
+
record.override_by = overrideBy;
|
|
289
|
+
record.override_at = new Date().toISOString();
|
|
290
|
+
record.action = body.action as TriageAction;
|
|
291
|
+
record.updated_at = new Date().toISOString();
|
|
292
|
+
|
|
293
|
+
// Re-triage if already acted on (allows re-acting with new action)
|
|
294
|
+
// Clear stale execution metadata to avoid leaking previous action results
|
|
295
|
+
if (record.status === 'acted_on') {
|
|
296
|
+
record.status = 'triaged';
|
|
297
|
+
record.acted_at = undefined;
|
|
298
|
+
record.result_ref = undefined;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
await saveTriageRecord(ctx, record);
|
|
302
|
+
|
|
303
|
+
// AC: @trait-api-endpoint ac-5 - Shadow commit
|
|
304
|
+
await commitIfShadow(ctx.shadow, `triage: override ${record._ulid.slice(0, 8)}`);
|
|
305
|
+
|
|
306
|
+
// AC: @triage-daemon-api ac-4 - Broadcast triage:updates
|
|
307
|
+
pubsub.broadcast('triage:updates', 'triage_record_updated', {
|
|
308
|
+
ulid: record._ulid,
|
|
309
|
+
action: 'override',
|
|
310
|
+
new_action: record.action,
|
|
311
|
+
}, projectContext.path);
|
|
312
|
+
|
|
313
|
+
return {
|
|
314
|
+
success: true,
|
|
315
|
+
record,
|
|
316
|
+
};
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
params: t.Object({
|
|
320
|
+
ref: t.String(),
|
|
321
|
+
}),
|
|
322
|
+
body: t.Object({
|
|
323
|
+
action: t.String(),
|
|
324
|
+
reasoning: t.String(),
|
|
325
|
+
override_by: t.Optional(t.String()),
|
|
326
|
+
}),
|
|
327
|
+
}
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
// AC: @triage-daemon-api ac-5, ac-8, ac-9 - Execute a triage action
|
|
331
|
+
// AC: @trait-api-endpoint ac-1, ac-5 - JSON response, shadow commit
|
|
332
|
+
.post(
|
|
333
|
+
'/:ref/act',
|
|
334
|
+
async ({ params, error: errorResponse, projectContext }) => {
|
|
335
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
336
|
+
const ctx = await initContext(projectContext.path);
|
|
337
|
+
const records = await loadTriageRecords(ctx);
|
|
338
|
+
|
|
339
|
+
// AC: @trait-api-endpoint ac-2 - Resolve ref
|
|
340
|
+
const record = findTriageRecordByRef(records, params.ref);
|
|
341
|
+
if (!record) {
|
|
342
|
+
return errorResponse(404, {
|
|
343
|
+
error: 'not_found',
|
|
344
|
+
message: `Triage record reference "${params.ref}" not found`,
|
|
345
|
+
suggestion: 'Use kspec triage list or GET /api/triage to find valid triage record references',
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// AC: @triage-daemon-api ac-8 - Already acted on → 409
|
|
350
|
+
if (record.status === 'acted_on') {
|
|
351
|
+
return errorResponse(409, {
|
|
352
|
+
error: 'invalid_transition',
|
|
353
|
+
message: 'Triage record has already been acted on',
|
|
354
|
+
current: record.status,
|
|
355
|
+
suggestion: 'Use override to change the decision before acting again',
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// AC: @triage-daemon-api ac-9 - Pending (no decision) → 422
|
|
360
|
+
if (record.status === 'pending') {
|
|
361
|
+
return errorResponse(422, {
|
|
362
|
+
error: 'incomplete_record',
|
|
363
|
+
message: 'No decision has been recorded for this triage record. Complete triage first.',
|
|
364
|
+
suggestion: 'Use POST /api/triage to record a decision, or kspec triage record <inbox-ref> --action <action> --reasoning <text>',
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// AC: @triage-daemon-api ac-5 - Execute the action
|
|
369
|
+
const result = await executeTriageAction(record, ctx);
|
|
370
|
+
|
|
371
|
+
// Transition to acted_on
|
|
372
|
+
record.status = 'acted_on';
|
|
373
|
+
record.acted_at = new Date().toISOString();
|
|
374
|
+
if (result.resultRef) {
|
|
375
|
+
record.result_ref = result.resultRef;
|
|
376
|
+
}
|
|
377
|
+
record.updated_at = new Date().toISOString();
|
|
378
|
+
|
|
379
|
+
await saveTriageRecord(ctx, record);
|
|
380
|
+
|
|
381
|
+
// AC: @trait-api-endpoint ac-5 - Shadow commit
|
|
382
|
+
await commitIfShadow(ctx.shadow, `triage: act ${record._ulid.slice(0, 8)}`);
|
|
383
|
+
|
|
384
|
+
// AC: @triage-daemon-api ac-5 - Broadcast triage:updates
|
|
385
|
+
pubsub.broadcast('triage:updates', 'triage_record_acted', {
|
|
386
|
+
ulid: record._ulid,
|
|
387
|
+
action: record.action,
|
|
388
|
+
result_ref: record.result_ref,
|
|
389
|
+
}, projectContext.path);
|
|
390
|
+
|
|
391
|
+
return {
|
|
392
|
+
success: true,
|
|
393
|
+
record,
|
|
394
|
+
};
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
params: t.Object({
|
|
398
|
+
ref: t.String(),
|
|
399
|
+
}),
|
|
400
|
+
}
|
|
401
|
+
);
|
|
402
|
+
}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation and Search API Routes
|
|
3
|
+
*
|
|
4
|
+
* REST endpoints for search and validation operations:
|
|
5
|
+
* - GET /api/search?q=query - Search across all items/tasks/inbox/meta
|
|
6
|
+
* - GET /api/validate - Run full validation
|
|
7
|
+
* - GET /api/alignment - Get alignment stats and warnings
|
|
8
|
+
*
|
|
9
|
+
* AC Coverage:
|
|
10
|
+
* - ac-19: GET /api/search?q=query searches across all entities
|
|
11
|
+
* - ac-20: GET /api/validate returns ValidationResult
|
|
12
|
+
* - ac-21: GET /api/alignment returns AlignmentIndex stats
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { Elysia, t } from 'elysia';
|
|
16
|
+
import {
|
|
17
|
+
initContext,
|
|
18
|
+
buildIndexes,
|
|
19
|
+
loadInboxItems,
|
|
20
|
+
loadMetaContext,
|
|
21
|
+
validate,
|
|
22
|
+
AlignmentIndex,
|
|
23
|
+
type LoadedSpecItem,
|
|
24
|
+
type LoadedTask,
|
|
25
|
+
type LoadedInboxItem,
|
|
26
|
+
} from '../../parser/index.js';
|
|
27
|
+
import type {
|
|
28
|
+
LoadedAgent,
|
|
29
|
+
LoadedWorkflow,
|
|
30
|
+
LoadedObservation,
|
|
31
|
+
LoadedConvention,
|
|
32
|
+
} from '../../parser/meta.js';
|
|
33
|
+
import { grepItem } from '../../utils/grep.js';
|
|
34
|
+
|
|
35
|
+
interface ValidationRouteOptions {}
|
|
36
|
+
|
|
37
|
+
export function createValidationRoutes(options: ValidationRouteOptions = {}) {
|
|
38
|
+
// No closure-scoped kspecDir needed - comes from middleware
|
|
39
|
+
|
|
40
|
+
return new Elysia({ prefix: '/api' })
|
|
41
|
+
// AC: @api-contract ac-19 - Search across all entities
|
|
42
|
+
.get(
|
|
43
|
+
'/search',
|
|
44
|
+
async ({ query, projectContext }) => {
|
|
45
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
46
|
+
const ctx = await initContext(projectContext.path);
|
|
47
|
+
const { tasks, items } = await buildIndexes(ctx);
|
|
48
|
+
|
|
49
|
+
const pattern = query.q;
|
|
50
|
+
if (!pattern) {
|
|
51
|
+
return {
|
|
52
|
+
results: [],
|
|
53
|
+
total: 0,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const limit = query.limit ? parseInt(query.limit, 10) : 50;
|
|
58
|
+
|
|
59
|
+
interface SearchResult {
|
|
60
|
+
type:
|
|
61
|
+
| 'item'
|
|
62
|
+
| 'task'
|
|
63
|
+
| 'inbox'
|
|
64
|
+
| 'observation'
|
|
65
|
+
| 'agent'
|
|
66
|
+
| 'workflow'
|
|
67
|
+
| 'convention';
|
|
68
|
+
ulid: string;
|
|
69
|
+
title: string;
|
|
70
|
+
matchedFields: string[];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const results: SearchResult[] = [];
|
|
74
|
+
|
|
75
|
+
// AC: @api-contract ac-19 - Search spec items
|
|
76
|
+
if (!query.tasksOnly) {
|
|
77
|
+
for (const item of items) {
|
|
78
|
+
// Apply type filter if provided
|
|
79
|
+
if (query.type && item.type !== query.type) continue;
|
|
80
|
+
|
|
81
|
+
const match = grepItem(item as unknown as Record<string, unknown>, pattern);
|
|
82
|
+
if (match) {
|
|
83
|
+
results.push({
|
|
84
|
+
type: 'item',
|
|
85
|
+
ulid: item._ulid,
|
|
86
|
+
title: item.title,
|
|
87
|
+
matchedFields: match.matchedFields,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// AC: @api-contract ac-19 - Search tasks
|
|
94
|
+
if (!query.itemsOnly) {
|
|
95
|
+
for (const task of tasks) {
|
|
96
|
+
// Apply status filter if provided
|
|
97
|
+
if (query.status && task.status !== query.status) continue;
|
|
98
|
+
|
|
99
|
+
const match = grepItem(task as unknown as Record<string, unknown>, pattern);
|
|
100
|
+
if (match) {
|
|
101
|
+
results.push({
|
|
102
|
+
type: 'task',
|
|
103
|
+
ulid: task._ulid,
|
|
104
|
+
title: task.title,
|
|
105
|
+
matchedFields: match.matchedFields,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// AC: @api-contract ac-19 - Search inbox items
|
|
112
|
+
if (!query.itemsOnly && !query.tasksOnly) {
|
|
113
|
+
const inboxItems = await loadInboxItems(ctx);
|
|
114
|
+
for (const inboxItem of inboxItems) {
|
|
115
|
+
const match = grepItem(inboxItem as unknown as Record<string, unknown>, pattern);
|
|
116
|
+
if (match) {
|
|
117
|
+
results.push({
|
|
118
|
+
type: 'inbox',
|
|
119
|
+
ulid: inboxItem._ulid,
|
|
120
|
+
title: inboxItem.text,
|
|
121
|
+
matchedFields: match.matchedFields,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// AC: @api-contract ac-19 - Search meta entities
|
|
128
|
+
if (!query.itemsOnly && !query.tasksOnly) {
|
|
129
|
+
const metaCtx = await loadMetaContext(ctx);
|
|
130
|
+
|
|
131
|
+
// Search observations
|
|
132
|
+
for (const observation of metaCtx.observations) {
|
|
133
|
+
const match = grepItem(observation as unknown as Record<string, unknown>, pattern);
|
|
134
|
+
if (match) {
|
|
135
|
+
results.push({
|
|
136
|
+
type: 'observation',
|
|
137
|
+
ulid: observation._ulid,
|
|
138
|
+
title: observation.content,
|
|
139
|
+
matchedFields: match.matchedFields,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Search agents
|
|
145
|
+
for (const agent of metaCtx.agents) {
|
|
146
|
+
const match = grepItem(agent as unknown as Record<string, unknown>, pattern);
|
|
147
|
+
if (match) {
|
|
148
|
+
results.push({
|
|
149
|
+
type: 'agent',
|
|
150
|
+
ulid: agent._ulid,
|
|
151
|
+
title: `${agent.id} - ${agent.name}`,
|
|
152
|
+
matchedFields: match.matchedFields,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Search workflows
|
|
158
|
+
for (const workflow of metaCtx.workflows) {
|
|
159
|
+
const match = grepItem(workflow as unknown as Record<string, unknown>, pattern);
|
|
160
|
+
if (match) {
|
|
161
|
+
results.push({
|
|
162
|
+
type: 'workflow',
|
|
163
|
+
ulid: workflow._ulid,
|
|
164
|
+
title: workflow.id,
|
|
165
|
+
matchedFields: match.matchedFields,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Search conventions
|
|
171
|
+
for (const convention of metaCtx.conventions) {
|
|
172
|
+
const match = grepItem(convention as unknown as Record<string, unknown>, pattern);
|
|
173
|
+
if (match) {
|
|
174
|
+
results.push({
|
|
175
|
+
type: 'convention',
|
|
176
|
+
ulid: convention._ulid,
|
|
177
|
+
title: convention.domain,
|
|
178
|
+
matchedFields: match.matchedFields,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Apply limit
|
|
185
|
+
const limitedResults = results.slice(0, limit);
|
|
186
|
+
|
|
187
|
+
// AC: @api-contract ac-19 - Return search results with matched fields
|
|
188
|
+
return {
|
|
189
|
+
results: limitedResults,
|
|
190
|
+
total: results.length,
|
|
191
|
+
showing: limitedResults.length,
|
|
192
|
+
};
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
query: t.Object({
|
|
196
|
+
q: t.Optional(t.String()),
|
|
197
|
+
type: t.Optional(t.String()),
|
|
198
|
+
status: t.Optional(t.String()),
|
|
199
|
+
itemsOnly: t.Optional(t.String()),
|
|
200
|
+
tasksOnly: t.Optional(t.String()),
|
|
201
|
+
limit: t.Optional(t.String()),
|
|
202
|
+
}),
|
|
203
|
+
}
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
// AC: @api-contract ac-20 - Run full validation
|
|
207
|
+
.get('/validate', async ({ projectContext }) => {
|
|
208
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
209
|
+
const ctx = await initContext(projectContext.path);
|
|
210
|
+
|
|
211
|
+
// AC: @api-contract ac-20 - Run validation and return ValidationResult
|
|
212
|
+
const result = await validate(ctx);
|
|
213
|
+
|
|
214
|
+
return {
|
|
215
|
+
valid: result.valid,
|
|
216
|
+
schemaErrors: result.schemaErrors,
|
|
217
|
+
refErrors: result.refErrors,
|
|
218
|
+
refWarnings: result.refWarnings,
|
|
219
|
+
orphans: result.orphans,
|
|
220
|
+
completenessWarnings: result.completenessWarnings,
|
|
221
|
+
traitCycles: result.traitCycles,
|
|
222
|
+
};
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
// AC: @api-contract ac-21 - Get alignment stats and warnings
|
|
226
|
+
.get('/alignment', async ({ projectContext }) => {
|
|
227
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
228
|
+
const ctx = await initContext(projectContext.path);
|
|
229
|
+
const { tasks, items, refIndex } = await buildIndexes(ctx);
|
|
230
|
+
|
|
231
|
+
// AC: @api-contract ac-21 - Create AlignmentIndex and get stats
|
|
232
|
+
const alignIndex = new AlignmentIndex(tasks, items);
|
|
233
|
+
alignIndex.buildLinks(refIndex);
|
|
234
|
+
|
|
235
|
+
const stats = alignIndex.getStats();
|
|
236
|
+
const warnings = alignIndex.findAlignmentWarnings();
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
stats: {
|
|
240
|
+
totalSpecs: stats.totalSpecs,
|
|
241
|
+
specsWithTasks: stats.specsWithTasks,
|
|
242
|
+
alignedSpecs: stats.alignedSpecs,
|
|
243
|
+
orphanedSpecs: stats.orphanedSpecs,
|
|
244
|
+
},
|
|
245
|
+
warnings,
|
|
246
|
+
};
|
|
247
|
+
});
|
|
248
|
+
}
|