@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,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projects API Routes
|
|
3
|
+
*
|
|
4
|
+
* REST endpoints for project management operations:
|
|
5
|
+
* - GET /api/projects - list all registered projects
|
|
6
|
+
* - POST /api/projects - manually register a project
|
|
7
|
+
* - DELETE /api/projects/:encodedPath - unregister a project
|
|
8
|
+
*
|
|
9
|
+
* All endpoints return JSON responses.
|
|
10
|
+
*
|
|
11
|
+
* AC Coverage:
|
|
12
|
+
* - ac-28: GET /api/projects returns list with paths, registration time, watcher status
|
|
13
|
+
* - ac-29: POST /api/projects with {path: string} body for manual registration
|
|
14
|
+
* - ac-30: DELETE /api/projects/:encodedPath unregisters and stops watcher
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { Elysia, t } from 'elysia';
|
|
18
|
+
import { isAbsolute } from 'path';
|
|
19
|
+
import type { ProjectContextManager } from '../project-context';
|
|
20
|
+
|
|
21
|
+
interface ProjectsRouteOptions {
|
|
22
|
+
projectManager: ProjectContextManager;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function createProjectsRoutes(options: ProjectsRouteOptions) {
|
|
26
|
+
const { projectManager } = options;
|
|
27
|
+
|
|
28
|
+
return new Elysia({ prefix: '/api/projects' })
|
|
29
|
+
// AC: @multi-directory-daemon ac-28 - List registered projects
|
|
30
|
+
.get('/', async () => {
|
|
31
|
+
const projects = projectManager.listProjects();
|
|
32
|
+
|
|
33
|
+
// AC: @multi-directory-daemon ac-28 - Include paths, registration time, watcher status
|
|
34
|
+
return {
|
|
35
|
+
projects: projects.map(project => ({
|
|
36
|
+
path: project.path,
|
|
37
|
+
registeredAt: project.registeredAt.toISOString(),
|
|
38
|
+
watcherStatus: project.watcherActive ? 'active' : 'stopped',
|
|
39
|
+
})),
|
|
40
|
+
total: projects.length,
|
|
41
|
+
};
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
// AC: @multi-directory-daemon ac-29 - Manual project registration
|
|
45
|
+
.post(
|
|
46
|
+
'/',
|
|
47
|
+
async ({ body, error: errorResponse }) => {
|
|
48
|
+
// AC: @multi-directory-daemon ac-29 - Accept {path: string} body
|
|
49
|
+
// Validate path is provided
|
|
50
|
+
if (!body.path || typeof body.path !== 'string' || body.path.trim().length === 0) {
|
|
51
|
+
return errorResponse(400, {
|
|
52
|
+
error: 'validation_error',
|
|
53
|
+
details: [
|
|
54
|
+
{
|
|
55
|
+
field: 'path',
|
|
56
|
+
message: 'Path is required and must be a non-empty string',
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// AC: @multi-directory-daemon ac-6 - Path must be absolute
|
|
63
|
+
if (!isAbsolute(body.path)) {
|
|
64
|
+
return errorResponse(400, {
|
|
65
|
+
error: 'Path must be absolute',
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// AC: @multi-directory-daemon ac-7 - Reject parent traversal (..)
|
|
70
|
+
if (body.path.includes('..')) {
|
|
71
|
+
return errorResponse(400, {
|
|
72
|
+
error: 'Path must not contain parent traversal',
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
// AC: @multi-directory-daemon ac-29 - Use ProjectContextManager.registerProject()
|
|
78
|
+
const context = projectManager.registerProject(body.path);
|
|
79
|
+
|
|
80
|
+
// Start watcher for the registered project
|
|
81
|
+
try {
|
|
82
|
+
await projectManager.startWatcher(body.path);
|
|
83
|
+
} catch (error: unknown) {
|
|
84
|
+
// AC: @multi-directory-daemon ac-19 - Handle OS limits
|
|
85
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
86
|
+
if (message.includes('resource limit')) {
|
|
87
|
+
return errorResponse(503, {
|
|
88
|
+
error: 'Unable to watch project - resource limit reached',
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
success: true,
|
|
96
|
+
project: {
|
|
97
|
+
path: context.path,
|
|
98
|
+
registeredAt: context.registeredAt.toISOString(),
|
|
99
|
+
watcherStatus: context.watcherActive ? 'active' : 'stopped',
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
} catch (error: unknown) {
|
|
103
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
104
|
+
const code = error instanceof Error && 'code' in error ? (error as NodeJS.ErrnoException).code : undefined;
|
|
105
|
+
|
|
106
|
+
// AC: @multi-directory-daemon ac-5 - Invalid project (no .kspec/)
|
|
107
|
+
if (message.includes('.kspec/ not found')) {
|
|
108
|
+
return errorResponse(400, {
|
|
109
|
+
error: `Invalid kspec project - .kspec/ not found at ${body.path}`,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// AC: @multi-directory-daemon ac-8b - Permission denied
|
|
114
|
+
if (code === 'EACCES' || code === 'EPERM') {
|
|
115
|
+
return errorResponse(403, {
|
|
116
|
+
error: `Permission denied - cannot read ${body.path}`,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Generic error
|
|
121
|
+
return errorResponse(500, {
|
|
122
|
+
error: message || 'Failed to register project',
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
body: t.Object({
|
|
128
|
+
path: t.String(),
|
|
129
|
+
}),
|
|
130
|
+
}
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
// AC: @multi-directory-daemon ac-30 - Unregister project
|
|
134
|
+
.delete('/:encodedPath', async ({ params, error: errorResponse }) => {
|
|
135
|
+
// AC: @multi-directory-daemon ac-30 - Decode path from URL parameter
|
|
136
|
+
const projectPath = decodeURIComponent(params.encodedPath);
|
|
137
|
+
|
|
138
|
+
// Validate project exists
|
|
139
|
+
if (!projectManager.hasProject(projectPath)) {
|
|
140
|
+
return errorResponse(404, {
|
|
141
|
+
error: `Project not registered: ${projectPath}`,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
// AC: @multi-directory-daemon ac-30 - Stop file watcher
|
|
147
|
+
await projectManager.stopWatcher(projectPath);
|
|
148
|
+
|
|
149
|
+
// AC: @multi-directory-daemon ac-30 - Unregister project
|
|
150
|
+
projectManager.unregisterProject(projectPath);
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
success: true,
|
|
154
|
+
message: `Project unregistered: ${projectPath}`,
|
|
155
|
+
};
|
|
156
|
+
} catch (error: unknown) {
|
|
157
|
+
return errorResponse(500, {
|
|
158
|
+
error: error instanceof Error ? error.message : 'Failed to unregister project',
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task API Routes
|
|
3
|
+
*
|
|
4
|
+
* REST endpoints for task operations:
|
|
5
|
+
* - GET /api/tasks - list with filters and pagination
|
|
6
|
+
* - GET /api/tasks/:ref - get single task
|
|
7
|
+
* - POST /api/tasks/:ref/start - start task
|
|
8
|
+
* - POST /api/tasks/:ref/note - add note
|
|
9
|
+
*
|
|
10
|
+
* AC Coverage:
|
|
11
|
+
* - ac-2: GET /api/tasks returns array with status, priority, spec_ref, notes count
|
|
12
|
+
* - ac-3: Status filter with multi-value support
|
|
13
|
+
* - ac-4: Pagination with {items, total, offset, limit} wrapper
|
|
14
|
+
* - ac-5: GET /api/tasks/:ref resolves via ReferenceIndex
|
|
15
|
+
* - ac-6: POST /api/tasks/:ref/start transitions state
|
|
16
|
+
* - ac-7: POST /api/tasks/:ref/note appends note
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { Elysia, t } from 'elysia';
|
|
20
|
+
import {
|
|
21
|
+
initContext,
|
|
22
|
+
loadAllTasks,
|
|
23
|
+
loadAllItems,
|
|
24
|
+
ReferenceIndex,
|
|
25
|
+
createNote,
|
|
26
|
+
saveTask,
|
|
27
|
+
getAuthor,
|
|
28
|
+
syncSpecImplementationStatus,
|
|
29
|
+
type LoadedTask,
|
|
30
|
+
} from '../../parser/index.js';
|
|
31
|
+
import { commitIfShadow } from '../../parser/shadow.js';
|
|
32
|
+
import type { PubSubManager } from '../websocket/pubsub';
|
|
33
|
+
|
|
34
|
+
interface TasksRouteOptions {
|
|
35
|
+
pubsub: PubSubManager;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function createTasksRoutes(options: TasksRouteOptions) {
|
|
39
|
+
const { pubsub } = options;
|
|
40
|
+
|
|
41
|
+
return new Elysia({ prefix: '/api/tasks' })
|
|
42
|
+
// AC: @api-contract ac-2, ac-3, ac-4 - List tasks with filters and pagination
|
|
43
|
+
.get(
|
|
44
|
+
'/',
|
|
45
|
+
async ({ query, projectContext }) => {
|
|
46
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
47
|
+
const ctx = await initContext(projectContext.path);
|
|
48
|
+
const tasks = await loadAllTasks(ctx);
|
|
49
|
+
const specItems = await loadAllItems(ctx);
|
|
50
|
+
const index = new ReferenceIndex(tasks, specItems);
|
|
51
|
+
|
|
52
|
+
// Apply filters
|
|
53
|
+
let filtered = tasks;
|
|
54
|
+
|
|
55
|
+
// AC: @api-contract ac-3 - Multi-value status filter
|
|
56
|
+
if (query.status) {
|
|
57
|
+
const statusFilters = Array.isArray(query.status) ? query.status : [query.status];
|
|
58
|
+
filtered = filtered.filter((task) => statusFilters.includes(task.status));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Type filter (optional, not in ACs but useful)
|
|
62
|
+
if (query.type) {
|
|
63
|
+
const typeFilters = Array.isArray(query.type) ? query.type : [query.type];
|
|
64
|
+
filtered = filtered.filter((task) => task.type && typeFilters.includes(task.type));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Tag filter (optional, not in ACs but useful)
|
|
68
|
+
if (query.tag) {
|
|
69
|
+
const tagFilters = Array.isArray(query.tag) ? query.tag : [query.tag];
|
|
70
|
+
filtered = filtered.filter((task) =>
|
|
71
|
+
task.tags?.some((t) => tagFilters.includes(t))
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// AC: @api-contract ac-4 - Pagination
|
|
76
|
+
const total = filtered.length;
|
|
77
|
+
const offset = Number(query.offset) || 0;
|
|
78
|
+
const limit = Number(query.limit) || total;
|
|
79
|
+
|
|
80
|
+
const paginated = filtered.slice(offset, offset + limit);
|
|
81
|
+
|
|
82
|
+
// AC: @api-contract ac-2 - Return with status, priority, spec_ref, notes count
|
|
83
|
+
// AC: @web-dashboard ac-1 - Include depends_on for blocked task computation
|
|
84
|
+
const items = paginated.map((task) => ({
|
|
85
|
+
_ulid: task._ulid,
|
|
86
|
+
slugs: task.slugs,
|
|
87
|
+
title: task.title,
|
|
88
|
+
status: task.status,
|
|
89
|
+
priority: task.priority,
|
|
90
|
+
spec_ref: task.spec_ref,
|
|
91
|
+
meta_ref: task.meta_ref,
|
|
92
|
+
tags: task.tags,
|
|
93
|
+
depends_on: task.depends_on || [],
|
|
94
|
+
notes_count: task.notes?.length || 0,
|
|
95
|
+
todos_count: task.todos?.length || 0,
|
|
96
|
+
started_at: task.started_at,
|
|
97
|
+
completed_at: task.completed_at,
|
|
98
|
+
created_at: task.created_at,
|
|
99
|
+
}));
|
|
100
|
+
|
|
101
|
+
// AC: @api-contract ac-4, @trait-api-endpoint ac-4 - Return pagination wrapper
|
|
102
|
+
return {
|
|
103
|
+
items,
|
|
104
|
+
total,
|
|
105
|
+
offset,
|
|
106
|
+
limit,
|
|
107
|
+
};
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
query: t.Object({
|
|
111
|
+
status: t.Optional(t.Union([t.String(), t.Array(t.String())])),
|
|
112
|
+
type: t.Optional(t.Union([t.String(), t.Array(t.String())])),
|
|
113
|
+
tag: t.Optional(t.Union([t.String(), t.Array(t.String())])),
|
|
114
|
+
limit: t.Optional(t.String()),
|
|
115
|
+
offset: t.Optional(t.String()),
|
|
116
|
+
}),
|
|
117
|
+
}
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
// AC: @api-contract ac-5 - Get single task by ref
|
|
121
|
+
.get(
|
|
122
|
+
'/:ref',
|
|
123
|
+
async ({ params, error: errorResponse, projectContext }) => {
|
|
124
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
125
|
+
const ctx = await initContext(projectContext.path);
|
|
126
|
+
const tasks = await loadAllTasks(ctx);
|
|
127
|
+
const items = await loadAllItems(ctx);
|
|
128
|
+
const index = new ReferenceIndex(tasks, items);
|
|
129
|
+
|
|
130
|
+
// AC: @api-contract ac-5, @trait-api-endpoint ac-2 - Resolve ref via ReferenceIndex
|
|
131
|
+
const result = index.resolve(params.ref);
|
|
132
|
+
|
|
133
|
+
if (!result.ok) {
|
|
134
|
+
// AC: @trait-api-endpoint ac-2 - Return 404 with error details
|
|
135
|
+
return errorResponse(404, {
|
|
136
|
+
error: 'not_found',
|
|
137
|
+
message: `Task reference "${params.ref}" not found`,
|
|
138
|
+
suggestion: 'Use kspec task list or kspec search to find valid task references',
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Find the task
|
|
143
|
+
const task = tasks.find((t) => t._ulid === result.ulid);
|
|
144
|
+
if (!task) {
|
|
145
|
+
return errorResponse(404, {
|
|
146
|
+
error: 'not_found',
|
|
147
|
+
message: `Reference "${params.ref}" is not a task`,
|
|
148
|
+
suggestion: 'This reference might point to a spec item instead',
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// AC: @api-contract ac-5 - Return full task with notes, todos, dependencies
|
|
153
|
+
return {
|
|
154
|
+
_ulid: task._ulid,
|
|
155
|
+
slugs: task.slugs,
|
|
156
|
+
title: task.title,
|
|
157
|
+
status: task.status,
|
|
158
|
+
priority: task.priority,
|
|
159
|
+
spec_ref: task.spec_ref,
|
|
160
|
+
meta_ref: task.meta_ref,
|
|
161
|
+
tags: task.tags,
|
|
162
|
+
description: task.description,
|
|
163
|
+
depends_on: task.depends_on,
|
|
164
|
+
notes: task.notes,
|
|
165
|
+
todos: task.todos,
|
|
166
|
+
started_at: task.started_at,
|
|
167
|
+
completed_at: task.completed_at,
|
|
168
|
+
cancelled_at: task.cancelled_at,
|
|
169
|
+
closed_reason: task.closed_reason,
|
|
170
|
+
automation: task.automation,
|
|
171
|
+
created_at: task.created_at,
|
|
172
|
+
};
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
params: t.Object({
|
|
176
|
+
ref: t.String(),
|
|
177
|
+
}),
|
|
178
|
+
}
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
// AC: @api-contract ac-6 - Start task
|
|
182
|
+
.post(
|
|
183
|
+
'/:ref/start',
|
|
184
|
+
async ({ params, error: errorResponse, projectContext }) => {
|
|
185
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
186
|
+
const ctx = await initContext(projectContext.path);
|
|
187
|
+
const tasks = await loadAllTasks(ctx);
|
|
188
|
+
const items = await loadAllItems(ctx);
|
|
189
|
+
const index = new ReferenceIndex(tasks, items);
|
|
190
|
+
|
|
191
|
+
// Resolve ref
|
|
192
|
+
const result = index.resolve(params.ref);
|
|
193
|
+
if (!result.ok) {
|
|
194
|
+
return errorResponse(404, {
|
|
195
|
+
error: 'not_found',
|
|
196
|
+
message: `Task reference "${params.ref}" not found`,
|
|
197
|
+
suggestion: 'Use kspec task list to find valid task references',
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const task = tasks.find((t) => t._ulid === result.ulid);
|
|
202
|
+
if (!task) {
|
|
203
|
+
return errorResponse(404, {
|
|
204
|
+
error: 'not_found',
|
|
205
|
+
message: `Reference "${params.ref}" is not a task`,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// AC: @api-contract ac-6 - Transition to in_progress
|
|
210
|
+
if (task.status === 'in_progress') {
|
|
211
|
+
return errorResponse(409, {
|
|
212
|
+
error: 'invalid_transition',
|
|
213
|
+
message: 'Task is already in_progress',
|
|
214
|
+
current: task.status,
|
|
215
|
+
valid_transitions: ['blocked', 'pending_review', 'completed', 'cancelled'],
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Update task status
|
|
220
|
+
const updatedTask: LoadedTask = {
|
|
221
|
+
...task,
|
|
222
|
+
status: 'in_progress',
|
|
223
|
+
started_at: task.started_at || new Date().toISOString(),
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
// Save and commit
|
|
227
|
+
await saveTask(ctx, updatedTask);
|
|
228
|
+
await syncSpecImplementationStatus(ctx, updatedTask, tasks, items, index);
|
|
229
|
+
await commitIfShadow(ctx.shadow, `task: start ${params.ref}`);
|
|
230
|
+
|
|
231
|
+
// AC: @api-contract ac-6, @trait-api-endpoint ac-5 - WebSocket broadcast
|
|
232
|
+
// AC: @multi-directory-daemon ac-18 - Broadcast scoped to request project
|
|
233
|
+
pubsub.broadcast('tasks:updates', 'task_updated', {
|
|
234
|
+
ref: params.ref,
|
|
235
|
+
ulid: task._ulid,
|
|
236
|
+
action: 'start',
|
|
237
|
+
status: 'in_progress',
|
|
238
|
+
}, projectContext.path);
|
|
239
|
+
|
|
240
|
+
// AC: @api-contract ac-6 - Return updated task
|
|
241
|
+
return updatedTask;
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
params: t.Object({
|
|
245
|
+
ref: t.String(),
|
|
246
|
+
}),
|
|
247
|
+
}
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
// AC: @api-contract ac-7 - Add note to task
|
|
251
|
+
.post(
|
|
252
|
+
'/:ref/note',
|
|
253
|
+
async ({ params, body, error: errorResponse, projectContext }) => {
|
|
254
|
+
// AC: @multi-directory-daemon ac-1, ac-24 - Use project context from middleware
|
|
255
|
+
const ctx = await initContext(projectContext.path);
|
|
256
|
+
const tasks = await loadAllTasks(ctx);
|
|
257
|
+
const items = await loadAllItems(ctx);
|
|
258
|
+
const index = new ReferenceIndex(tasks, items);
|
|
259
|
+
|
|
260
|
+
// Resolve ref
|
|
261
|
+
const result = index.resolve(params.ref);
|
|
262
|
+
if (!result.ok) {
|
|
263
|
+
return errorResponse(404, {
|
|
264
|
+
error: 'not_found',
|
|
265
|
+
message: `Task reference "${params.ref}" not found`,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const task = tasks.find((t) => t._ulid === result.ulid);
|
|
270
|
+
if (!task) {
|
|
271
|
+
return errorResponse(404, {
|
|
272
|
+
error: 'not_found',
|
|
273
|
+
message: `Reference "${params.ref}" is not a task`,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// AC: @trait-api-endpoint ac-3 - Validate body
|
|
278
|
+
if (!body.content || typeof body.content !== 'string') {
|
|
279
|
+
return errorResponse(400, {
|
|
280
|
+
error: 'validation_error',
|
|
281
|
+
details: [
|
|
282
|
+
{
|
|
283
|
+
field: 'content',
|
|
284
|
+
message: 'Content is required and must be a string',
|
|
285
|
+
},
|
|
286
|
+
],
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// AC: @api-contract ac-7 - Append note
|
|
291
|
+
const author = getAuthor(ctx.config?.identity?.author);
|
|
292
|
+
const note = createNote(body.content, author);
|
|
293
|
+
|
|
294
|
+
const updatedTask: LoadedTask = {
|
|
295
|
+
...task,
|
|
296
|
+
notes: [...(task.notes || []), note],
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
// AC: @api-contract ac-7, @trait-api-endpoint ac-5 - Shadow commit
|
|
300
|
+
await saveTask(ctx, updatedTask);
|
|
301
|
+
await commitIfShadow(ctx.shadow, `task: add note to ${params.ref}`);
|
|
302
|
+
|
|
303
|
+
// AC: @api-contract ac-7 - WebSocket broadcast
|
|
304
|
+
// AC: @multi-directory-daemon ac-18 - Broadcast scoped to request project
|
|
305
|
+
pubsub.broadcast('tasks:updates', 'task_updated', {
|
|
306
|
+
ref: params.ref,
|
|
307
|
+
ulid: task._ulid,
|
|
308
|
+
action: 'note_added',
|
|
309
|
+
note_ulid: note._ulid,
|
|
310
|
+
}, projectContext.path);
|
|
311
|
+
|
|
312
|
+
return {
|
|
313
|
+
success: true,
|
|
314
|
+
note,
|
|
315
|
+
task: updatedTask,
|
|
316
|
+
};
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
params: t.Object({
|
|
320
|
+
ref: t.String(),
|
|
321
|
+
}),
|
|
322
|
+
body: t.Object({
|
|
323
|
+
content: t.String(),
|
|
324
|
+
}),
|
|
325
|
+
}
|
|
326
|
+
);
|
|
327
|
+
}
|