@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
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import * as path from
|
|
2
|
-
import chalk from
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { validation as validationStrings } from
|
|
6
|
-
import { EXIT_CODES } from
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { AlignmentIndex, checkACSchemaReferences, expandIncludePattern, findTaskFiles, fixFiles, initContext, loadAllItems, loadAllTasks, loadMetaContext, ReferenceIndex, validate, validateConventions, } from "../../parser/index.js";
|
|
4
|
+
import { validateSkills, } from "../../parser/validate-skills.js";
|
|
5
|
+
import { validation as validationStrings } from "../../strings/index.js";
|
|
6
|
+
import { EXIT_CODES } from "../exit-codes.js";
|
|
7
|
+
import { error, output } from "../output.js";
|
|
7
8
|
/**
|
|
8
9
|
* Check for stale status mismatches between specs and tasks
|
|
9
10
|
* AC: @stale-status-detection ac-1, ac-2, ac-3
|
|
@@ -14,39 +15,39 @@ function checkStaleness(items, tasks, refIndex) {
|
|
|
14
15
|
// Check if task with dependencies is pending but all dependencies are completed
|
|
15
16
|
for (const task of tasks) {
|
|
16
17
|
// Only check pending/in_progress tasks with dependencies
|
|
17
|
-
if (task.status !==
|
|
18
|
+
if (task.status !== "pending" && task.status !== "in_progress")
|
|
18
19
|
continue;
|
|
19
20
|
if (!task.depends_on || task.depends_on.length === 0)
|
|
20
21
|
continue;
|
|
21
22
|
// Resolve all dependency tasks
|
|
22
23
|
const depTasks = task.depends_on
|
|
23
|
-
.map(depRef => {
|
|
24
|
+
.map((depRef) => {
|
|
24
25
|
const result = refIndex.resolve(depRef);
|
|
25
26
|
if (!result.ok)
|
|
26
27
|
return null;
|
|
27
|
-
return tasks.find(t => t._ulid === result.ulid);
|
|
28
|
+
return tasks.find((t) => t._ulid === result.ulid);
|
|
28
29
|
})
|
|
29
30
|
.filter((t) => t !== null);
|
|
30
31
|
if (depTasks.length === 0)
|
|
31
32
|
continue;
|
|
32
33
|
// Check if all dependencies are completed and their linked specs are implemented
|
|
33
|
-
const allDepsDone = depTasks.every(depTask => {
|
|
34
|
-
if (depTask.status !==
|
|
34
|
+
const allDepsDone = depTasks.every((depTask) => {
|
|
35
|
+
if (depTask.status !== "completed")
|
|
35
36
|
return false;
|
|
36
37
|
// If the dep task has a spec_ref, check if that spec is implemented
|
|
37
38
|
if (depTask.spec_ref) {
|
|
38
39
|
const result = refIndex.resolve(depTask.spec_ref);
|
|
39
40
|
if (!result.ok)
|
|
40
41
|
return true; // Missing spec ref doesn't block
|
|
41
|
-
const spec = items.find(item => item._ulid === result.ulid);
|
|
42
|
-
return spec?.status?.implementation ===
|
|
42
|
+
const spec = items.find((item) => item._ulid === result.ulid);
|
|
43
|
+
return spec?.status?.implementation === "implemented";
|
|
43
44
|
}
|
|
44
45
|
return true;
|
|
45
46
|
});
|
|
46
47
|
if (allDepsDone) {
|
|
47
48
|
const taskRef = task.slugs[0] || refIndex.shortUlid(task._ulid);
|
|
48
49
|
warnings.push({
|
|
49
|
-
type:
|
|
50
|
+
type: "parent-pending-children-done",
|
|
50
51
|
message: `Task @${taskRef} is ${task.status} but all dependencies are completed. Consider completing or reviewing.`,
|
|
51
52
|
refs: [task._ulid],
|
|
52
53
|
});
|
|
@@ -55,11 +56,16 @@ function checkStaleness(items, tasks, refIndex) {
|
|
|
55
56
|
// AC: @stale-status-detection ac-2 (spec-implemented-no-task)
|
|
56
57
|
// Check if spec is implemented but has no completed tasks
|
|
57
58
|
for (const item of items) {
|
|
58
|
-
if (item.status?.implementation !==
|
|
59
|
+
if (item.status?.implementation !== "implemented")
|
|
60
|
+
continue;
|
|
61
|
+
// AC: @trait-retrospective ac-1
|
|
62
|
+
// Skip retrospective specs from staleness warnings
|
|
63
|
+
const isRetrospective = item.traits?.includes("@trait-retrospective");
|
|
64
|
+
if (isRetrospective)
|
|
59
65
|
continue;
|
|
60
66
|
// Find completed tasks that reference this spec
|
|
61
|
-
const completedTasks = tasks.filter(task => {
|
|
62
|
-
if (task.status !==
|
|
67
|
+
const completedTasks = tasks.filter((task) => {
|
|
68
|
+
if (task.status !== "completed" || !task.spec_ref)
|
|
63
69
|
return false;
|
|
64
70
|
const result = refIndex.resolve(task.spec_ref);
|
|
65
71
|
return result.ok && result.ulid === item._ulid;
|
|
@@ -67,7 +73,7 @@ function checkStaleness(items, tasks, refIndex) {
|
|
|
67
73
|
if (completedTasks.length === 0) {
|
|
68
74
|
const specRef = item.slugs[0] || refIndex.shortUlid(item._ulid);
|
|
69
75
|
warnings.push({
|
|
70
|
-
type:
|
|
76
|
+
type: "spec-implemented-no-task",
|
|
71
77
|
message: `Spec @${specRef} is implemented but has no completed tasks. Verify implementation or link existing task.`,
|
|
72
78
|
refs: [item._ulid],
|
|
73
79
|
});
|
|
@@ -76,7 +82,7 @@ function checkStaleness(items, tasks, refIndex) {
|
|
|
76
82
|
// AC: @stale-status-detection ac-3 (task-done-spec-not-started)
|
|
77
83
|
// Check if task is completed but spec is still not_started
|
|
78
84
|
for (const task of tasks) {
|
|
79
|
-
if (task.status !==
|
|
85
|
+
if (task.status !== "completed")
|
|
80
86
|
continue;
|
|
81
87
|
if (!task.spec_ref)
|
|
82
88
|
continue;
|
|
@@ -84,19 +90,41 @@ function checkStaleness(items, tasks, refIndex) {
|
|
|
84
90
|
const result = refIndex.resolve(task.spec_ref);
|
|
85
91
|
if (!result.ok)
|
|
86
92
|
continue;
|
|
87
|
-
const spec = items.find(item => item._ulid === result.ulid);
|
|
93
|
+
const spec = items.find((item) => item._ulid === result.ulid);
|
|
88
94
|
if (!spec)
|
|
89
95
|
continue;
|
|
90
|
-
if (spec.status?.implementation ===
|
|
96
|
+
if (spec.status?.implementation === "not_started") {
|
|
91
97
|
const taskRef = task.slugs[0] || refIndex.shortUlid(task._ulid);
|
|
92
98
|
const specRef = spec.slugs[0] || refIndex.shortUlid(spec._ulid);
|
|
93
99
|
warnings.push({
|
|
94
|
-
type:
|
|
100
|
+
type: "task-done-spec-not-started",
|
|
95
101
|
message: `Task @${taskRef} completed but spec @${specRef} is not_started. Update spec status.`,
|
|
96
102
|
refs: [task._ulid, spec._ulid],
|
|
97
103
|
});
|
|
98
104
|
}
|
|
99
105
|
}
|
|
106
|
+
// AC: @validation ac-1
|
|
107
|
+
// Check for manual_only parents blocking eligible children
|
|
108
|
+
for (const parentTask of tasks) {
|
|
109
|
+
if (parentTask.automation !== "manual_only")
|
|
110
|
+
continue;
|
|
111
|
+
// Find tasks that depend on this parent
|
|
112
|
+
const dependentTasks = tasks.filter((t) => t.depends_on?.some((depRef) => {
|
|
113
|
+
const result = refIndex.resolve(depRef);
|
|
114
|
+
return result.ok && result.ulid === parentTask._ulid;
|
|
115
|
+
}));
|
|
116
|
+
// Filter for eligible children
|
|
117
|
+
const eligibleChildren = dependentTasks.filter((t) => t.automation === "eligible");
|
|
118
|
+
if (eligibleChildren.length > 0) {
|
|
119
|
+
const parentRef = parentTask.slugs[0] || refIndex.shortUlid(parentTask._ulid);
|
|
120
|
+
const childRefs = eligibleChildren.map((c) => `@${c.slugs[0] || refIndex.shortUlid(c._ulid)}`);
|
|
121
|
+
warnings.push({
|
|
122
|
+
type: "automation-blocking",
|
|
123
|
+
message: `Task @${parentRef} is manual_only and blocks ${eligibleChildren.length} eligible child task(s): ${childRefs.join(", ")}`,
|
|
124
|
+
refs: [parentTask._ulid, ...eligibleChildren.map((c) => c._ulid)],
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
100
128
|
return warnings;
|
|
101
129
|
}
|
|
102
130
|
/**
|
|
@@ -105,14 +133,15 @@ function checkStaleness(items, tasks, refIndex) {
|
|
|
105
133
|
*/
|
|
106
134
|
function formatStalenessWarnings(warnings, verbose) {
|
|
107
135
|
if (warnings.length === 0) {
|
|
108
|
-
console.log(chalk.green(
|
|
136
|
+
console.log(chalk.green("Staleness: OK"));
|
|
109
137
|
return;
|
|
110
138
|
}
|
|
111
139
|
console.log(chalk.yellow(`\nStaleness warnings: ${warnings.length}`));
|
|
112
140
|
// Group by type
|
|
113
|
-
const parentPending = warnings.filter(w => w.type ===
|
|
114
|
-
const specNoTask = warnings.filter(w => w.type ===
|
|
115
|
-
const taskDoneSpecNot = warnings.filter(w => w.type ===
|
|
141
|
+
const parentPending = warnings.filter((w) => w.type === "parent-pending-children-done");
|
|
142
|
+
const specNoTask = warnings.filter((w) => w.type === "spec-implemented-no-task");
|
|
143
|
+
const taskDoneSpecNot = warnings.filter((w) => w.type === "task-done-spec-not-started");
|
|
144
|
+
const automationBlocking = warnings.filter((w) => w.type === "automation-blocking");
|
|
116
145
|
if (parentPending.length > 0) {
|
|
117
146
|
console.log(chalk.yellow(` Parent pending, children done: ${parentPending.length}`));
|
|
118
147
|
const shown = verbose ? parentPending : parentPending.slice(0, 3);
|
|
@@ -143,6 +172,50 @@ function formatStalenessWarnings(warnings, verbose) {
|
|
|
143
172
|
console.log(chalk.gray(` ... and ${taskDoneSpecNot.length - 3} more`));
|
|
144
173
|
}
|
|
145
174
|
}
|
|
175
|
+
if (automationBlocking.length > 0) {
|
|
176
|
+
console.log(chalk.yellow(` Automation blocking: ${automationBlocking.length}`));
|
|
177
|
+
const shown = verbose ? automationBlocking : automationBlocking.slice(0, 3);
|
|
178
|
+
for (const w of shown) {
|
|
179
|
+
console.log(chalk.yellow(` ! ${w.message}`));
|
|
180
|
+
}
|
|
181
|
+
if (!verbose && automationBlocking.length > 3) {
|
|
182
|
+
console.log(chalk.gray(` ... and ${automationBlocking.length - 3} more`));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Format AC schema drift warnings for display
|
|
188
|
+
*/
|
|
189
|
+
function formatDriftWarnings(warnings, verbose) {
|
|
190
|
+
// Filter to only drift warnings
|
|
191
|
+
const driftWarnings = warnings.filter((w) => w.type === "ac_schema_field_mismatch");
|
|
192
|
+
if (driftWarnings.length === 0) {
|
|
193
|
+
console.log(chalk.green("AC Schema Drift: OK"));
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
console.log(chalk.yellow(`\nAC Schema Drift warnings: ${driftWarnings.length}`));
|
|
197
|
+
// Group by item
|
|
198
|
+
const byItem = new Map();
|
|
199
|
+
for (const w of driftWarnings) {
|
|
200
|
+
const existing = byItem.get(w.itemRef) || [];
|
|
201
|
+
existing.push(w);
|
|
202
|
+
byItem.set(w.itemRef, existing);
|
|
203
|
+
}
|
|
204
|
+
const itemEntries = [...byItem.entries()];
|
|
205
|
+
const shown = verbose ? itemEntries : itemEntries.slice(0, 5);
|
|
206
|
+
for (const [itemRef, itemWarnings] of shown) {
|
|
207
|
+
const firstWarning = itemWarnings[0];
|
|
208
|
+
console.log(chalk.yellow(` ${itemRef} - ${firstWarning.itemTitle}`));
|
|
209
|
+
for (const w of itemWarnings) {
|
|
210
|
+
console.log(chalk.yellow(` ! ${w.message}`));
|
|
211
|
+
if (w.details) {
|
|
212
|
+
console.log(chalk.gray(` ${w.details}`));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (!verbose && itemEntries.length > 5) {
|
|
217
|
+
console.log(chalk.gray(` ... and ${itemEntries.length - 5} more items with drift`));
|
|
218
|
+
}
|
|
146
219
|
}
|
|
147
220
|
/**
|
|
148
221
|
* Format convention validation results for display
|
|
@@ -150,7 +223,7 @@ function formatStalenessWarnings(warnings, verbose) {
|
|
|
150
223
|
*/
|
|
151
224
|
function formatConventionValidationResult(result) {
|
|
152
225
|
if (result.valid && result.skipped.length === 0) {
|
|
153
|
-
console.log(chalk.green(
|
|
226
|
+
console.log(chalk.green("Conventions: OK"));
|
|
154
227
|
return;
|
|
155
228
|
}
|
|
156
229
|
// AC: @convention-definitions ac-4
|
|
@@ -176,28 +249,62 @@ function formatConventionValidationResult(result) {
|
|
|
176
249
|
}
|
|
177
250
|
}
|
|
178
251
|
else {
|
|
179
|
-
console.log(chalk.green(
|
|
252
|
+
console.log(chalk.green("\nConventions: OK"));
|
|
180
253
|
}
|
|
181
254
|
// Stats
|
|
182
255
|
console.log(chalk.gray(`\nConventions checked: ${result.stats.conventionsChecked}`));
|
|
183
256
|
console.log(chalk.gray(`Conventions skipped: ${result.stats.conventionsSkipped}`));
|
|
184
257
|
}
|
|
258
|
+
/**
|
|
259
|
+
* Format skill validation results for display
|
|
260
|
+
*/
|
|
261
|
+
function formatSkillValidationResult(result, verbose) {
|
|
262
|
+
if (result.filesChecked === 0) {
|
|
263
|
+
console.log(chalk.gray("Skills: No skill files found"));
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
if (result.valid) {
|
|
267
|
+
console.log(chalk.green(`Skills: OK (${result.filesChecked} files checked)`));
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
console.log(chalk.red(`\nSkill validation errors: ${result.errors.length}`));
|
|
271
|
+
console.log(chalk.gray(`Files checked: ${result.filesChecked}`));
|
|
272
|
+
// Group errors by file
|
|
273
|
+
const errorsByFile = new Map();
|
|
274
|
+
for (const err of result.errors) {
|
|
275
|
+
const existing = errorsByFile.get(err.file) || [];
|
|
276
|
+
existing.push(err);
|
|
277
|
+
errorsByFile.set(err.file, existing);
|
|
278
|
+
}
|
|
279
|
+
for (const [file, errors] of errorsByFile.entries()) {
|
|
280
|
+
console.log(chalk.yellow(`\n ${file}:`));
|
|
281
|
+
const shown = verbose ? errors : errors.slice(0, 5);
|
|
282
|
+
for (const err of shown) {
|
|
283
|
+
const location = err.line ? `:${err.line}` : "";
|
|
284
|
+
console.log(chalk.red(` ✗ ${err.type}${location}`));
|
|
285
|
+
console.log(chalk.gray(` ${err.message}`));
|
|
286
|
+
}
|
|
287
|
+
if (!verbose && errors.length > 5) {
|
|
288
|
+
console.log(chalk.gray(` ... and ${errors.length - 5} more`));
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
185
292
|
/**
|
|
186
293
|
* Format completeness warnings for display
|
|
187
294
|
* AC: @spec-completeness ac-4
|
|
188
295
|
*/
|
|
189
296
|
function formatCompletenessWarnings(warnings, verbose) {
|
|
190
297
|
if (warnings.length === 0) {
|
|
191
|
-
console.log(chalk.green(
|
|
298
|
+
console.log(chalk.green("Completeness: OK"));
|
|
192
299
|
return;
|
|
193
300
|
}
|
|
194
301
|
console.log(chalk.yellow(`\nCompleteness warnings: ${warnings.length}`));
|
|
195
302
|
// Group by type
|
|
196
|
-
const missingAC = warnings.filter(w => w.type ===
|
|
197
|
-
const missingDesc = warnings.filter(w => w.type ===
|
|
198
|
-
const statusMismatch = warnings.filter(w => w.type ===
|
|
199
|
-
const missingTestCoverage = warnings.filter(w => w.type ===
|
|
200
|
-
const automationNoSpec = warnings.filter(w => w.type ===
|
|
303
|
+
const missingAC = warnings.filter((w) => w.type === "missing_acceptance_criteria");
|
|
304
|
+
const missingDesc = warnings.filter((w) => w.type === "missing_description");
|
|
305
|
+
const statusMismatch = warnings.filter((w) => w.type === "status_inconsistency");
|
|
306
|
+
const missingTestCoverage = warnings.filter((w) => w.type === "missing_test_coverage");
|
|
307
|
+
const automationNoSpec = warnings.filter((w) => w.type === "automation_eligible_no_spec");
|
|
201
308
|
// AC: @spec-completeness ac-4
|
|
202
309
|
// Show summary with counts by issue type
|
|
203
310
|
if (missingAC.length > 0) {
|
|
@@ -231,7 +338,9 @@ function formatCompletenessWarnings(warnings, verbose) {
|
|
|
231
338
|
}
|
|
232
339
|
if (missingTestCoverage.length > 0) {
|
|
233
340
|
console.log(chalk.yellow(` Missing test coverage: ${missingTestCoverage.length}`));
|
|
234
|
-
const shown = verbose
|
|
341
|
+
const shown = verbose
|
|
342
|
+
? missingTestCoverage
|
|
343
|
+
: missingTestCoverage.slice(0, 3);
|
|
235
344
|
for (const w of shown) {
|
|
236
345
|
console.log(chalk.yellow(` ! ${w.itemRef} - ${w.itemTitle}`));
|
|
237
346
|
if (w.details) {
|
|
@@ -260,14 +369,14 @@ function formatCompletenessWarnings(warnings, verbose) {
|
|
|
260
369
|
*/
|
|
261
370
|
function formatAlignmentWarnings(warnings, verbose) {
|
|
262
371
|
if (warnings.length === 0) {
|
|
263
|
-
console.log(chalk.green(
|
|
372
|
+
console.log(chalk.green("Alignment: OK"));
|
|
264
373
|
return;
|
|
265
374
|
}
|
|
266
375
|
console.log(chalk.yellow(`\nAlignment warnings: ${warnings.length}`));
|
|
267
376
|
// Group by type
|
|
268
|
-
const orphaned = warnings.filter(w => w.type ===
|
|
269
|
-
const mismatches = warnings.filter(w => w.type ===
|
|
270
|
-
const stale = warnings.filter(w => w.type ===
|
|
377
|
+
const orphaned = warnings.filter((w) => w.type === "orphaned_spec");
|
|
378
|
+
const mismatches = warnings.filter((w) => w.type === "status_mismatch");
|
|
379
|
+
const stale = warnings.filter((w) => w.type === "stale_implementation");
|
|
271
380
|
if (orphaned.length > 0) {
|
|
272
381
|
console.log(chalk.yellow(` Orphaned specs (no tasks): ${orphaned.length}`));
|
|
273
382
|
const shown = verbose ? orphaned : orphaned.slice(0, 3);
|
|
@@ -297,15 +406,15 @@ function formatAlignmentWarnings(warnings, verbose) {
|
|
|
297
406
|
*/
|
|
298
407
|
function formatFixResult(result) {
|
|
299
408
|
if (result.fixesApplied.length === 0) {
|
|
300
|
-
console.log(chalk.gray(
|
|
409
|
+
console.log(chalk.gray("\nNo auto-fixable issues found."));
|
|
301
410
|
return;
|
|
302
411
|
}
|
|
303
412
|
console.log(chalk.cyan(`\n✓ Applied ${result.fixesApplied.length} fix(es) to ${result.filesModified} file(s):`));
|
|
304
413
|
for (const fix of result.fixesApplied) {
|
|
305
414
|
const typeLabel = {
|
|
306
|
-
ulid_regenerated:
|
|
307
|
-
timestamp_added:
|
|
308
|
-
status_added:
|
|
415
|
+
ulid_regenerated: "ULID regenerated",
|
|
416
|
+
timestamp_added: "Timestamp added",
|
|
417
|
+
status_added: "Status added",
|
|
309
418
|
}[fix.type];
|
|
310
419
|
const shortFile = path.basename(fix.file);
|
|
311
420
|
console.log(chalk.cyan(` ✓ ${shortFile}:${fix.path} - ${typeLabel}`));
|
|
@@ -324,9 +433,9 @@ async function collectFixableFiles(ctx) {
|
|
|
324
433
|
const files = [];
|
|
325
434
|
// Task files (exclude test fixtures)
|
|
326
435
|
const taskFiles = await findTaskFiles(ctx.rootDir);
|
|
327
|
-
const specTaskFiles = await findTaskFiles(path.join(ctx.rootDir,
|
|
436
|
+
const specTaskFiles = await findTaskFiles(path.join(ctx.rootDir, "spec"));
|
|
328
437
|
const allTaskFiles = [...new Set([...taskFiles, ...specTaskFiles])];
|
|
329
|
-
files.push(...allTaskFiles.filter(f => !f.includes(
|
|
438
|
+
files.push(...allTaskFiles.filter((f) => !f.includes("fixtures") && !f.includes("test")));
|
|
330
439
|
// Spec files from includes
|
|
331
440
|
if (ctx.manifest && ctx.manifestPath) {
|
|
332
441
|
const manifestDir = path.dirname(ctx.manifestPath);
|
|
@@ -337,9 +446,9 @@ async function collectFixableFiles(ctx) {
|
|
|
337
446
|
}
|
|
338
447
|
}
|
|
339
448
|
// Inbox file
|
|
340
|
-
const inboxPath = path.join(ctx.rootDir,
|
|
449
|
+
const inboxPath = path.join(ctx.rootDir, "spec", "kynetic.inbox.yaml");
|
|
341
450
|
try {
|
|
342
|
-
await import(
|
|
451
|
+
await import("node:fs/promises").then((fs) => fs.access(inboxPath));
|
|
343
452
|
files.push(inboxPath);
|
|
344
453
|
}
|
|
345
454
|
catch {
|
|
@@ -353,12 +462,12 @@ async function collectFixableFiles(ctx) {
|
|
|
353
462
|
function formatValidationResult(result, verbose) {
|
|
354
463
|
// Header
|
|
355
464
|
if (result.valid) {
|
|
356
|
-
console.log(chalk.green.bold(
|
|
465
|
+
console.log(chalk.green.bold("✓ Validation passed"));
|
|
357
466
|
}
|
|
358
467
|
else {
|
|
359
|
-
console.log(chalk.red.bold(
|
|
468
|
+
console.log(chalk.red.bold("✗ Validation failed"));
|
|
360
469
|
}
|
|
361
|
-
console.log(chalk.gray(
|
|
470
|
+
console.log(chalk.gray("─".repeat(40)));
|
|
362
471
|
console.log(`Files checked: ${result.stats.filesChecked}`);
|
|
363
472
|
console.log(`Items checked: ${result.stats.itemsChecked}`);
|
|
364
473
|
console.log(`Tasks checked: ${result.stats.tasksChecked}`);
|
|
@@ -379,7 +488,7 @@ function formatValidationResult(result, verbose) {
|
|
|
379
488
|
}
|
|
380
489
|
}
|
|
381
490
|
else {
|
|
382
|
-
console.log(chalk.green(
|
|
491
|
+
console.log(chalk.green("\nSchema: OK"));
|
|
383
492
|
}
|
|
384
493
|
// Reference errors
|
|
385
494
|
if (result.refErrors.length > 0) {
|
|
@@ -394,7 +503,7 @@ function formatValidationResult(result, verbose) {
|
|
|
394
503
|
}
|
|
395
504
|
}
|
|
396
505
|
else {
|
|
397
|
-
console.log(chalk.green(
|
|
506
|
+
console.log(chalk.green("References: OK"));
|
|
398
507
|
}
|
|
399
508
|
// Reference warnings (deprecated targets)
|
|
400
509
|
if (result.refWarnings.length > 0) {
|
|
@@ -446,18 +555,20 @@ function formatValidationResult(result, verbose) {
|
|
|
446
555
|
*/
|
|
447
556
|
export function registerValidateCommand(program) {
|
|
448
557
|
program
|
|
449
|
-
.command(
|
|
450
|
-
.description(
|
|
451
|
-
.option(
|
|
452
|
-
.option(
|
|
453
|
-
.option(
|
|
454
|
-
.option(
|
|
455
|
-
.option(
|
|
456
|
-
.option(
|
|
457
|
-
.option(
|
|
458
|
-
.option(
|
|
459
|
-
.option(
|
|
460
|
-
.option(
|
|
558
|
+
.command("validate")
|
|
559
|
+
.description("Validate spec files")
|
|
560
|
+
.option("--schema", "Check schema conformance only")
|
|
561
|
+
.option("--refs", "Check reference resolution only")
|
|
562
|
+
.option("--orphans", "Find orphaned items only")
|
|
563
|
+
.option("--alignment", "Check spec-task alignment")
|
|
564
|
+
.option("--completeness", "Check spec completeness (missing AC, descriptions, status inconsistencies)")
|
|
565
|
+
.option("--conventions", "Validate conventions")
|
|
566
|
+
.option("--staleness", "Check for stale status mismatches between specs and tasks")
|
|
567
|
+
.option("--skills", "Validate skill files (.claude/skills/*/SKILL.md)")
|
|
568
|
+
.option("--drift", "Check AC field references against actual schema (catches spec prose drift)")
|
|
569
|
+
.option("--fix", "Auto-fix issues where possible (invalid ULIDs, missing timestamps)")
|
|
570
|
+
.option("-v, --verbose", "Show detailed output")
|
|
571
|
+
.option("--strict", "Treat orphans and staleness warnings as errors")
|
|
461
572
|
.action(async (options) => {
|
|
462
573
|
try {
|
|
463
574
|
const ctx = await initContext();
|
|
@@ -466,13 +577,29 @@ export function registerValidateCommand(program) {
|
|
|
466
577
|
console.log(validationStrings.initHint);
|
|
467
578
|
process.exit(EXIT_CODES.ERROR);
|
|
468
579
|
}
|
|
580
|
+
// Track warnings from all sources for exit code determination
|
|
581
|
+
let additionalWarningCount = 0;
|
|
469
582
|
// Determine which checks to run
|
|
470
|
-
const runAll = !options.schema &&
|
|
583
|
+
const runAll = !options.schema &&
|
|
584
|
+
!options.refs &&
|
|
585
|
+
!options.orphans &&
|
|
586
|
+
!options.alignment &&
|
|
587
|
+
!options.completeness &&
|
|
588
|
+
!options.conventions &&
|
|
589
|
+
!options.skills;
|
|
590
|
+
// AC: @config-validation ac-4 — CLI --strict overrides config strict_refs
|
|
591
|
+
// If --strict is passed, use strict behavior regardless of config
|
|
592
|
+
// Otherwise, use config value (which defaults to false)
|
|
593
|
+
const strictRefs = options.strict ? true : ctx.config.validation.strict_refs;
|
|
594
|
+
const requireAcceptance = ctx.config.validation.require_acceptance;
|
|
471
595
|
const validateOptions = {
|
|
472
596
|
schema: runAll || options.schema,
|
|
473
597
|
refs: runAll || options.refs,
|
|
474
598
|
orphans: runAll || options.orphans,
|
|
475
599
|
completeness: runAll || options.completeness,
|
|
600
|
+
// AC: @config-validation ac-2 ac-3 ac-4 — wire config into validation
|
|
601
|
+
strictRefs,
|
|
602
|
+
requireAcceptance,
|
|
476
603
|
};
|
|
477
604
|
const result = await validate(ctx, validateOptions);
|
|
478
605
|
// In strict mode, orphans are errors
|
|
@@ -510,6 +637,7 @@ export function registerValidateCommand(program) {
|
|
|
510
637
|
alignmentIndex.buildLinks(refIndex);
|
|
511
638
|
const alignmentWarnings = alignmentIndex.findAlignmentWarnings();
|
|
512
639
|
formatAlignmentWarnings(alignmentWarnings, options.verbose);
|
|
640
|
+
additionalWarningCount += alignmentWarnings.length;
|
|
513
641
|
// Show alignment stats
|
|
514
642
|
const stats = alignmentIndex.getStats();
|
|
515
643
|
console.log(validationStrings.alignmentStats(stats.specsWithTasks, stats.totalSpecs, stats.alignedSpecs));
|
|
@@ -535,30 +663,66 @@ export function registerValidateCommand(program) {
|
|
|
535
663
|
}
|
|
536
664
|
}
|
|
537
665
|
else {
|
|
538
|
-
console.log(chalk.gray(
|
|
666
|
+
console.log(chalk.gray("No conventions defined in meta manifest"));
|
|
539
667
|
}
|
|
540
668
|
}
|
|
541
|
-
catch (
|
|
542
|
-
console.log(chalk.yellow(
|
|
669
|
+
catch (_err) {
|
|
670
|
+
console.log(chalk.yellow("Warning: Could not load meta manifest for convention validation"));
|
|
543
671
|
}
|
|
544
672
|
}
|
|
545
673
|
// Run staleness checks if requested
|
|
546
674
|
// AC: @stale-status-detection ac-4, ac-5
|
|
675
|
+
let stalenessWarningCount = 0;
|
|
547
676
|
if (options.staleness) {
|
|
548
677
|
const tasks = await loadAllTasks(ctx);
|
|
549
678
|
const items = await loadAllItems(ctx);
|
|
550
679
|
const refIndex = new ReferenceIndex(tasks, items);
|
|
551
680
|
const stalenessWarnings = checkStaleness(items, tasks, refIndex);
|
|
552
681
|
formatStalenessWarnings(stalenessWarnings, options.verbose);
|
|
682
|
+
stalenessWarningCount = stalenessWarnings.length;
|
|
553
683
|
// AC: @stale-status-detection ac-5 (staleness-exit-code)
|
|
554
684
|
// With --strict, staleness warnings cause validation failure
|
|
555
685
|
if (options.strict && stalenessWarnings.length > 0) {
|
|
556
|
-
|
|
686
|
+
result.valid = false;
|
|
557
687
|
}
|
|
558
688
|
}
|
|
559
|
-
if
|
|
560
|
-
|
|
689
|
+
// Run skill file validation if requested or running all checks
|
|
690
|
+
if (runAll || options.skills) {
|
|
691
|
+
const skillResult = await validateSkills(ctx.rootDir);
|
|
692
|
+
formatSkillValidationResult(skillResult, options.verbose);
|
|
693
|
+
if (!skillResult.valid) {
|
|
694
|
+
result.valid = false;
|
|
695
|
+
}
|
|
561
696
|
}
|
|
697
|
+
// Run AC schema drift checks if requested
|
|
698
|
+
let driftWarningCount = 0;
|
|
699
|
+
if (options.drift) {
|
|
700
|
+
const items = await loadAllItems(ctx);
|
|
701
|
+
const driftWarnings = checkACSchemaReferences(items);
|
|
702
|
+
formatDriftWarnings(driftWarnings, options.verbose);
|
|
703
|
+
driftWarningCount = driftWarnings.length;
|
|
704
|
+
// With --strict, drift warnings cause validation failure
|
|
705
|
+
if (options.strict && driftWarnings.length > 0) {
|
|
706
|
+
result.valid = false;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
// Determine exit code based on errors vs warnings
|
|
710
|
+
// Errors: schema, refs, trait cycles, conventions, skills (result.valid = false)
|
|
711
|
+
// Warnings: orphans, alignment, completeness, staleness, drift, ref warnings
|
|
712
|
+
const hasErrors = !result.valid;
|
|
713
|
+
const hasWarnings = result.orphans.length > 0 ||
|
|
714
|
+
result.refWarnings.length > 0 ||
|
|
715
|
+
result.completenessWarnings.length > 0 ||
|
|
716
|
+
additionalWarningCount > 0 ||
|
|
717
|
+
stalenessWarningCount > 0 ||
|
|
718
|
+
driftWarningCount > 0;
|
|
719
|
+
if (hasErrors) {
|
|
720
|
+
process.exit(EXIT_CODES.VALIDATION_FAILED);
|
|
721
|
+
}
|
|
722
|
+
else if (hasWarnings) {
|
|
723
|
+
process.exit(EXIT_CODES.VALIDATION_WARNINGS);
|
|
724
|
+
}
|
|
725
|
+
// Otherwise exit 0 (success)
|
|
562
726
|
}
|
|
563
727
|
catch (err) {
|
|
564
728
|
error(validationStrings.failed, err);
|
|
@@ -567,15 +731,15 @@ export function registerValidateCommand(program) {
|
|
|
567
731
|
});
|
|
568
732
|
// Alias: kspec lint
|
|
569
733
|
program
|
|
570
|
-
.command(
|
|
571
|
-
.description(
|
|
572
|
-
.option(
|
|
573
|
-
.option(
|
|
574
|
-
.option(
|
|
575
|
-
.option(
|
|
576
|
-
.option(
|
|
577
|
-
.option(
|
|
578
|
-
.option(
|
|
734
|
+
.command("lint")
|
|
735
|
+
.description("Alias for validate with style checks")
|
|
736
|
+
.option("--schema", "Check schema conformance only")
|
|
737
|
+
.option("--refs", "Check reference resolution only")
|
|
738
|
+
.option("--orphans", "Find orphaned items only")
|
|
739
|
+
.option("--completeness", "Check spec completeness (missing AC, descriptions, status inconsistencies)")
|
|
740
|
+
.option("--fix", "Auto-fix issues where possible (invalid ULIDs, missing timestamps)")
|
|
741
|
+
.option("-v, --verbose", "Show detailed output")
|
|
742
|
+
.option("--strict", "Treat orphans as errors")
|
|
579
743
|
.action(async (options) => {
|
|
580
744
|
try {
|
|
581
745
|
const ctx = await initContext();
|
|
@@ -583,12 +747,20 @@ export function registerValidateCommand(program) {
|
|
|
583
747
|
error(validationStrings.noManifest);
|
|
584
748
|
process.exit(EXIT_CODES.ERROR);
|
|
585
749
|
}
|
|
586
|
-
const runAll = !options.schema &&
|
|
750
|
+
const runAll = !options.schema &&
|
|
751
|
+
!options.refs &&
|
|
752
|
+
!options.orphans &&
|
|
753
|
+
!options.completeness;
|
|
754
|
+
// AC: @config-validation ac-4 — CLI --strict overrides config strict_refs
|
|
755
|
+
const strictRefs = options.strict ? true : ctx.config.validation.strict_refs;
|
|
756
|
+
const requireAcceptance = ctx.config.validation.require_acceptance;
|
|
587
757
|
const validateOptions = {
|
|
588
758
|
schema: runAll || options.schema,
|
|
589
759
|
refs: runAll || options.refs,
|
|
590
760
|
orphans: runAll || options.orphans,
|
|
591
761
|
completeness: runAll || options.completeness,
|
|
762
|
+
strictRefs,
|
|
763
|
+
requireAcceptance,
|
|
592
764
|
};
|
|
593
765
|
const result = await validate(ctx, validateOptions);
|
|
594
766
|
if (options.strict && result.orphans.length > 0) {
|
|
@@ -613,9 +785,18 @@ export function registerValidateCommand(program) {
|
|
|
613
785
|
result.valid = revalidateResult.valid;
|
|
614
786
|
}
|
|
615
787
|
}
|
|
616
|
-
|
|
617
|
-
|
|
788
|
+
// Determine exit code based on errors vs warnings
|
|
789
|
+
const hasErrors = !result.valid;
|
|
790
|
+
const hasWarnings = result.orphans.length > 0 ||
|
|
791
|
+
result.refWarnings.length > 0 ||
|
|
792
|
+
result.completenessWarnings.length > 0;
|
|
793
|
+
if (hasErrors) {
|
|
794
|
+
process.exit(EXIT_CODES.VALIDATION_FAILED);
|
|
795
|
+
}
|
|
796
|
+
else if (hasWarnings) {
|
|
797
|
+
process.exit(EXIT_CODES.VALIDATION_WARNINGS);
|
|
618
798
|
}
|
|
799
|
+
// Otherwise exit 0 (success)
|
|
619
800
|
}
|
|
620
801
|
catch (err) {
|
|
621
802
|
error(validationStrings.lintFailed, err);
|