@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,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket message handler
|
|
3
|
+
*
|
|
4
|
+
* AC coverage:
|
|
5
|
+
* - ac-26 (@api-contract): Command format
|
|
6
|
+
* - ac-27 (@api-contract): Ack response
|
|
7
|
+
* - ac-28 (@api-contract): Subscribe to topics
|
|
8
|
+
* - ac-30 (@api-contract): Malformed command error
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { ServerWebSocket } from 'bun';
|
|
12
|
+
import type { WebSocketCommand, CommandAck, ConnectionData } from './types';
|
|
13
|
+
import type { PubSubManager } from './pubsub';
|
|
14
|
+
|
|
15
|
+
export class WebSocketHandler {
|
|
16
|
+
constructor(private pubsub: PubSubManager) {}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Handle incoming WebSocket command
|
|
20
|
+
* AC: @api-contract ac-26, ac-27, ac-28, ac-30
|
|
21
|
+
*/
|
|
22
|
+
handleMessage(ws: ServerWebSocket<ConnectionData>, rawMessage: string | Buffer) {
|
|
23
|
+
let command: WebSocketCommand;
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
// Parse command
|
|
27
|
+
const messageStr = typeof rawMessage === 'string' ? rawMessage : rawMessage.toString();
|
|
28
|
+
command = JSON.parse(messageStr);
|
|
29
|
+
|
|
30
|
+
// Validate command structure
|
|
31
|
+
if (!command.action) {
|
|
32
|
+
// AC: @api-contract ac-30
|
|
33
|
+
this.sendAck(ws, undefined, false, 'validation_error', 'Missing action field');
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
} catch (error) {
|
|
37
|
+
// AC: @api-contract ac-30
|
|
38
|
+
this.sendAck(ws, undefined, false, 'validation_error', 'Invalid JSON');
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Process command
|
|
43
|
+
try {
|
|
44
|
+
switch (command.action) {
|
|
45
|
+
case 'subscribe':
|
|
46
|
+
this.handleSubscribe(ws, command);
|
|
47
|
+
break;
|
|
48
|
+
|
|
49
|
+
case 'unsubscribe':
|
|
50
|
+
this.handleUnsubscribe(ws, command);
|
|
51
|
+
break;
|
|
52
|
+
|
|
53
|
+
case 'ping':
|
|
54
|
+
this.handlePing(ws, command);
|
|
55
|
+
break;
|
|
56
|
+
|
|
57
|
+
default:
|
|
58
|
+
// AC: @api-contract ac-30
|
|
59
|
+
this.sendAck(ws, command.request_id, false, 'unknown_action', `Unknown action: ${command.action}`);
|
|
60
|
+
}
|
|
61
|
+
} catch (error) {
|
|
62
|
+
const errorMsg = error instanceof Error ? error.message : 'Internal error';
|
|
63
|
+
this.sendAck(ws, command.request_id, false, 'error', errorMsg);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Handle subscribe command
|
|
69
|
+
* AC: @api-contract ac-28
|
|
70
|
+
*/
|
|
71
|
+
private handleSubscribe(ws: ServerWebSocket<ConnectionData>, command: WebSocketCommand) {
|
|
72
|
+
const topics = command.payload?.topics;
|
|
73
|
+
|
|
74
|
+
if (!topics || !Array.isArray(topics) || topics.length === 0) {
|
|
75
|
+
this.sendAck(ws, command.request_id, false, 'validation_error', 'Missing or invalid topics array');
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const success = this.pubsub.subscribe(ws.data.sessionId, topics);
|
|
80
|
+
|
|
81
|
+
if (success) {
|
|
82
|
+
this.sendAck(ws, command.request_id, true);
|
|
83
|
+
console.log(`[ws] ${ws.data.sessionId} subscribed to: ${topics.join(', ')}`);
|
|
84
|
+
} else {
|
|
85
|
+
this.sendAck(ws, command.request_id, false, 'not_found', 'Session not found');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Handle unsubscribe command
|
|
91
|
+
*/
|
|
92
|
+
private handleUnsubscribe(ws: ServerWebSocket<ConnectionData>, command: WebSocketCommand) {
|
|
93
|
+
const topics = command.payload?.topics;
|
|
94
|
+
|
|
95
|
+
if (!topics || !Array.isArray(topics) || topics.length === 0) {
|
|
96
|
+
this.sendAck(ws, command.request_id, false, 'validation_error', 'Missing or invalid topics array');
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const success = this.pubsub.unsubscribe(ws.data.sessionId, topics);
|
|
101
|
+
|
|
102
|
+
if (success) {
|
|
103
|
+
this.sendAck(ws, command.request_id, true);
|
|
104
|
+
console.log(`[ws] ${ws.data.sessionId} unsubscribed from: ${topics.join(', ')}`);
|
|
105
|
+
} else {
|
|
106
|
+
this.sendAck(ws, command.request_id, false, 'not_found', 'Session not found');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Handle ping command (application-level ping, not WebSocket frame)
|
|
112
|
+
*/
|
|
113
|
+
private handlePing(ws: ServerWebSocket<ConnectionData>, command: WebSocketCommand) {
|
|
114
|
+
this.sendAck(ws, command.request_id, true);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Send ack response
|
|
119
|
+
* AC: @api-contract ac-27
|
|
120
|
+
*/
|
|
121
|
+
private sendAck(
|
|
122
|
+
ws: ServerWebSocket<ConnectionData>,
|
|
123
|
+
request_id: string | undefined,
|
|
124
|
+
success: boolean,
|
|
125
|
+
error?: string,
|
|
126
|
+
details?: string
|
|
127
|
+
) {
|
|
128
|
+
const ack: CommandAck = {
|
|
129
|
+
ack: true,
|
|
130
|
+
request_id,
|
|
131
|
+
success,
|
|
132
|
+
error,
|
|
133
|
+
details
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
ws.send(JSON.stringify(ack));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket heartbeat (ping/pong) management
|
|
3
|
+
*
|
|
4
|
+
* AC coverage:
|
|
5
|
+
* - ac-13 (@daemon-server): Heartbeat ping every 30s
|
|
6
|
+
* - ac-14 (@daemon-server): Timeout close after 90s without pong
|
|
7
|
+
* - ac-4 (@trait-websocket-protocol): Send ping after 30s inactivity
|
|
8
|
+
* - ac-5 (@trait-websocket-protocol): Close after 90s without pong
|
|
9
|
+
* - ac-7 (@trait-websocket-protocol): Close code 1001 for timeout
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { ServerWebSocket } from 'bun';
|
|
13
|
+
import type { ConnectionData } from './types';
|
|
14
|
+
|
|
15
|
+
export class HeartbeatManager {
|
|
16
|
+
private pingInterval?: NodeJS.Timeout;
|
|
17
|
+
private readonly PING_INTERVAL = 30_000; // 30 seconds
|
|
18
|
+
private readonly PONG_TIMEOUT = 90_000; // 90 seconds
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Start heartbeat monitoring for all connections
|
|
22
|
+
* AC: @daemon-server ac-13, @trait-websocket-protocol ac-4
|
|
23
|
+
*/
|
|
24
|
+
start(connections: Map<string, ServerWebSocket<ConnectionData>>) {
|
|
25
|
+
this.pingInterval = setInterval(() => {
|
|
26
|
+
const now = Date.now();
|
|
27
|
+
|
|
28
|
+
for (const [sessionId, ws] of connections) {
|
|
29
|
+
// Check if pong timeout exceeded
|
|
30
|
+
if (ws.data.lastPing && !ws.data.lastPong) {
|
|
31
|
+
const timeSincePing = now - ws.data.lastPing;
|
|
32
|
+
|
|
33
|
+
// AC: @daemon-server ac-14, @trait-websocket-protocol ac-5, ac-7
|
|
34
|
+
if (timeSincePing > this.PONG_TIMEOUT) {
|
|
35
|
+
console.warn(`[heartbeat] Closing ${sessionId} - no pong for ${timeSincePing}ms`);
|
|
36
|
+
ws.close(1001, 'Ping timeout'); // AC: @trait-websocket-protocol ac-7
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Send ping if no recent activity
|
|
42
|
+
const lastActivity = ws.data.lastPong ?? ws.data.lastPing ?? 0;
|
|
43
|
+
const timeSinceActivity = now - lastActivity;
|
|
44
|
+
|
|
45
|
+
if (timeSinceActivity >= this.PING_INTERVAL) {
|
|
46
|
+
ws.data.lastPing = now;
|
|
47
|
+
ws.data.lastPong = undefined; // Reset pong until received
|
|
48
|
+
ws.ping();
|
|
49
|
+
console.debug(`[heartbeat] Sent ping to ${sessionId}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}, this.PING_INTERVAL);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Stop heartbeat monitoring
|
|
57
|
+
*/
|
|
58
|
+
stop() {
|
|
59
|
+
if (this.pingInterval) {
|
|
60
|
+
clearInterval(this.pingInterval);
|
|
61
|
+
this.pingInterval = undefined;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Record pong received from connection
|
|
67
|
+
*/
|
|
68
|
+
recordPong(ws: ServerWebSocket<ConnectionData>) {
|
|
69
|
+
ws.data.lastPong = Date.now();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Topic-based pub/sub system for WebSocket connections
|
|
3
|
+
*
|
|
4
|
+
* AC coverage:
|
|
5
|
+
* - ac-28 (@api-contract): Subscribe to topics
|
|
6
|
+
* - ac-29 (@api-contract): Event format with seq
|
|
7
|
+
* - ac-32 (@api-contract): Backpressure handling
|
|
8
|
+
* - ac-2 (@trait-websocket-protocol): Subscribe command tracking
|
|
9
|
+
* - ac-3 (@trait-websocket-protocol): Broadcast event format
|
|
10
|
+
* - ac-6 (@trait-websocket-protocol): Backpressure pause
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { ServerWebSocket } from 'bun';
|
|
14
|
+
import { ulid } from 'ulidx';
|
|
15
|
+
import type { BroadcastEvent, ConnectionData } from './types';
|
|
16
|
+
|
|
17
|
+
export class PubSubManager {
|
|
18
|
+
private connections = new Map<string, ServerWebSocket<ConnectionData>>();
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Register a new WebSocket connection
|
|
22
|
+
* AC: @trait-websocket-protocol ac-1
|
|
23
|
+
*/
|
|
24
|
+
addConnection(sessionId: string, ws: ServerWebSocket<ConnectionData>) {
|
|
25
|
+
this.connections.set(sessionId, ws);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Remove a WebSocket connection
|
|
30
|
+
*/
|
|
31
|
+
removeConnection(sessionId: string) {
|
|
32
|
+
this.connections.delete(sessionId);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Subscribe a connection to topics
|
|
37
|
+
* AC: @api-contract ac-28, @trait-websocket-protocol ac-2
|
|
38
|
+
*/
|
|
39
|
+
subscribe(sessionId: string, topics: string[]): boolean {
|
|
40
|
+
const ws = this.connections.get(sessionId);
|
|
41
|
+
if (!ws) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
for (const topic of topics) {
|
|
46
|
+
ws.data.topics.add(topic);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Unsubscribe a connection from topics
|
|
54
|
+
*/
|
|
55
|
+
unsubscribe(sessionId: string, topics: string[]): boolean {
|
|
56
|
+
const ws = this.connections.get(sessionId);
|
|
57
|
+
if (!ws) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
for (const topic of topics) {
|
|
62
|
+
ws.data.topics.delete(topic);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Broadcast event to all connections subscribed to a topic
|
|
70
|
+
* AC: @api-contract ac-29, @trait-websocket-protocol ac-3, ac-6
|
|
71
|
+
* AC: @multi-directory-daemon ac-18, ac-21 - Filter by project binding
|
|
72
|
+
*/
|
|
73
|
+
broadcast(topic: string, event: string, data: Record<string, unknown>, projectPath?: string) {
|
|
74
|
+
for (const [sessionId, ws] of this.connections) {
|
|
75
|
+
// AC: @multi-directory-daemon ac-18 - Only send to connections bound to same project
|
|
76
|
+
if (projectPath && ws.data.projectPath !== projectPath) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Only send to connections subscribed to this topic
|
|
81
|
+
if (!ws.data.topics.has(topic)) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// AC: @trait-websocket-protocol ac-6 - Check backpressure
|
|
86
|
+
// Bun's ServerWebSocket doesn't have bufferedAmount, so we use getBufferedAmount()
|
|
87
|
+
const buffered = ws.getBufferedAmount?.() ?? 0;
|
|
88
|
+
const MAX_BUFFER = 1024 * 1024; // 1MB threshold
|
|
89
|
+
|
|
90
|
+
if (buffered > MAX_BUFFER) {
|
|
91
|
+
console.warn(`[pubsub] Skipping broadcast to ${sessionId} - backpressure (${buffered} bytes buffered)`);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Increment sequence number for this connection
|
|
96
|
+
ws.data.seq++;
|
|
97
|
+
|
|
98
|
+
// AC: @api-contract ac-29, @trait-websocket-protocol ac-3
|
|
99
|
+
const message: BroadcastEvent = {
|
|
100
|
+
msg_id: ulid(),
|
|
101
|
+
seq: ws.data.seq,
|
|
102
|
+
timestamp: new Date().toISOString(),
|
|
103
|
+
topic,
|
|
104
|
+
event,
|
|
105
|
+
data
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
ws.send(JSON.stringify(message));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Get all connections (for heartbeat checks)
|
|
114
|
+
*/
|
|
115
|
+
getAllConnections(): Map<string, ServerWebSocket<ConnectionData>> {
|
|
116
|
+
return this.connections;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Get connection count
|
|
121
|
+
*/
|
|
122
|
+
getConnectionCount(): number {
|
|
123
|
+
return this.connections.size;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket Protocol Types
|
|
3
|
+
*
|
|
4
|
+
* AC coverage:
|
|
5
|
+
* - ac-25 (@api-contract): Connected event with session_id
|
|
6
|
+
* - ac-26 (@api-contract): Command format
|
|
7
|
+
* - ac-27 (@api-contract): Ack response format
|
|
8
|
+
* - ac-28 (@api-contract): Subscribe to topics
|
|
9
|
+
* - ac-29 (@api-contract): Event format with seq
|
|
10
|
+
* - ac-1 (@trait-websocket-protocol): Connection ID and connected event
|
|
11
|
+
* - ac-2 (@trait-websocket-protocol): Subscribe command tracking
|
|
12
|
+
* - ac-3 (@trait-websocket-protocol): Broadcast event format
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { ServerWebSocket } from 'bun';
|
|
16
|
+
|
|
17
|
+
// AC: @api-contract ac-26
|
|
18
|
+
export interface WebSocketCommand {
|
|
19
|
+
action: 'subscribe' | 'unsubscribe' | 'ping';
|
|
20
|
+
request_id?: string;
|
|
21
|
+
payload?: {
|
|
22
|
+
topics?: string[];
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// AC: @api-contract ac-27
|
|
27
|
+
export interface CommandAck {
|
|
28
|
+
ack: boolean;
|
|
29
|
+
request_id?: string;
|
|
30
|
+
success: boolean;
|
|
31
|
+
error?: string;
|
|
32
|
+
details?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// AC: @api-contract ac-25, @trait-websocket-protocol ac-1
|
|
36
|
+
export interface ConnectedEvent {
|
|
37
|
+
event: 'connected';
|
|
38
|
+
data: {
|
|
39
|
+
session_id: string;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// AC: @api-contract ac-29, @trait-websocket-protocol ac-3
|
|
44
|
+
export interface BroadcastEvent {
|
|
45
|
+
msg_id: string;
|
|
46
|
+
seq: number;
|
|
47
|
+
timestamp: string;
|
|
48
|
+
topic: string;
|
|
49
|
+
event: string;
|
|
50
|
+
data: Record<string, unknown>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Internal connection metadata
|
|
54
|
+
export interface ConnectionData {
|
|
55
|
+
sessionId: string;
|
|
56
|
+
topics: Set<string>;
|
|
57
|
+
lastPing?: number;
|
|
58
|
+
lastPong?: number;
|
|
59
|
+
seq: number; // Per-connection sequence number
|
|
60
|
+
projectPath: string; // AC: @multi-directory-daemon ac-21 - bound project path
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface WebSocketContext {
|
|
64
|
+
ws: ServerWebSocket<ConnectionData>;
|
|
65
|
+
connections: Map<string, ServerWebSocket<ConnectionData>>;
|
|
66
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTML Export Module
|
|
3
|
+
*
|
|
4
|
+
* Generates self-contained HTML files with embedded JSON and SPA loader.
|
|
5
|
+
* AC: @gh-pages-export ac-6
|
|
6
|
+
*/
|
|
7
|
+
import type { KspecSnapshot } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Generate a self-contained HTML file with embedded JSON snapshot.
|
|
10
|
+
*
|
|
11
|
+
* The HTML includes:
|
|
12
|
+
* - Embedded JSON data in a script tag
|
|
13
|
+
* - Redirect to hosted SPA (or minimal inline viewer)
|
|
14
|
+
* - Fallback for viewing raw data
|
|
15
|
+
*
|
|
16
|
+
* AC: @gh-pages-export ac-6
|
|
17
|
+
*/
|
|
18
|
+
export declare function generateHtmlExport(snapshot: KspecSnapshot): string;
|
|
19
|
+
//# sourceMappingURL=html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/export/html.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAmNlE"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTML Export Module
|
|
3
|
+
*
|
|
4
|
+
* Generates self-contained HTML files with embedded JSON and SPA loader.
|
|
5
|
+
* AC: @gh-pages-export ac-6
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Generate a self-contained HTML file with embedded JSON snapshot.
|
|
9
|
+
*
|
|
10
|
+
* The HTML includes:
|
|
11
|
+
* - Embedded JSON data in a script tag
|
|
12
|
+
* - Redirect to hosted SPA (or minimal inline viewer)
|
|
13
|
+
* - Fallback for viewing raw data
|
|
14
|
+
*
|
|
15
|
+
* AC: @gh-pages-export ac-6
|
|
16
|
+
*/
|
|
17
|
+
export function generateHtmlExport(snapshot) {
|
|
18
|
+
const jsonData = JSON.stringify(snapshot, null, 2);
|
|
19
|
+
const escapedJson = jsonData
|
|
20
|
+
.replace(/</g, "\\u003c")
|
|
21
|
+
.replace(/>/g, "\\u003e")
|
|
22
|
+
.replace(/&/g, "\\u0026");
|
|
23
|
+
return `<!DOCTYPE html>
|
|
24
|
+
<html lang="en">
|
|
25
|
+
<head>
|
|
26
|
+
<meta charset="UTF-8">
|
|
27
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
28
|
+
<title>${escapeHtml(snapshot.project.name)} - kspec Export</title>
|
|
29
|
+
<style>
|
|
30
|
+
:root {
|
|
31
|
+
--bg: #1a1a2e;
|
|
32
|
+
--fg: #eee;
|
|
33
|
+
--accent: #4ade80;
|
|
34
|
+
--muted: #666;
|
|
35
|
+
--border: #333;
|
|
36
|
+
}
|
|
37
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
38
|
+
body {
|
|
39
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
40
|
+
background: var(--bg);
|
|
41
|
+
color: var(--fg);
|
|
42
|
+
line-height: 1.6;
|
|
43
|
+
padding: 2rem;
|
|
44
|
+
}
|
|
45
|
+
.container { max-width: 1200px; margin: 0 auto; }
|
|
46
|
+
header {
|
|
47
|
+
display: flex;
|
|
48
|
+
justify-content: space-between;
|
|
49
|
+
align-items: center;
|
|
50
|
+
margin-bottom: 2rem;
|
|
51
|
+
padding-bottom: 1rem;
|
|
52
|
+
border-bottom: 1px solid var(--border);
|
|
53
|
+
}
|
|
54
|
+
h1 { font-size: 1.5rem; font-weight: 600; }
|
|
55
|
+
.meta { color: var(--muted); font-size: 0.875rem; }
|
|
56
|
+
.badge {
|
|
57
|
+
display: inline-flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
gap: 0.5rem;
|
|
60
|
+
padding: 0.25rem 0.75rem;
|
|
61
|
+
border-radius: 9999px;
|
|
62
|
+
font-size: 0.75rem;
|
|
63
|
+
font-weight: 500;
|
|
64
|
+
}
|
|
65
|
+
.badge.valid { background: rgba(74, 222, 128, 0.2); color: var(--accent); }
|
|
66
|
+
.badge.invalid { background: rgba(239, 68, 68, 0.2); color: #ef4444; }
|
|
67
|
+
.stats {
|
|
68
|
+
display: grid;
|
|
69
|
+
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
70
|
+
gap: 1rem;
|
|
71
|
+
margin-bottom: 2rem;
|
|
72
|
+
}
|
|
73
|
+
.stat {
|
|
74
|
+
background: rgba(255, 255, 255, 0.05);
|
|
75
|
+
padding: 1rem;
|
|
76
|
+
border-radius: 0.5rem;
|
|
77
|
+
border: 1px solid var(--border);
|
|
78
|
+
}
|
|
79
|
+
.stat-value { font-size: 2rem; font-weight: 700; color: var(--accent); }
|
|
80
|
+
.stat-label { color: var(--muted); font-size: 0.875rem; }
|
|
81
|
+
.section { margin-bottom: 2rem; }
|
|
82
|
+
.section-title {
|
|
83
|
+
font-size: 1rem;
|
|
84
|
+
font-weight: 600;
|
|
85
|
+
margin-bottom: 1rem;
|
|
86
|
+
color: var(--muted);
|
|
87
|
+
text-transform: uppercase;
|
|
88
|
+
letter-spacing: 0.05em;
|
|
89
|
+
}
|
|
90
|
+
.list { display: flex; flex-direction: column; gap: 0.5rem; }
|
|
91
|
+
.item {
|
|
92
|
+
background: rgba(255, 255, 255, 0.05);
|
|
93
|
+
padding: 1rem;
|
|
94
|
+
border-radius: 0.5rem;
|
|
95
|
+
border: 1px solid var(--border);
|
|
96
|
+
}
|
|
97
|
+
.item-title { font-weight: 500; }
|
|
98
|
+
.item-meta { color: var(--muted); font-size: 0.875rem; }
|
|
99
|
+
.status {
|
|
100
|
+
display: inline-block;
|
|
101
|
+
padding: 0.125rem 0.5rem;
|
|
102
|
+
border-radius: 0.25rem;
|
|
103
|
+
font-size: 0.75rem;
|
|
104
|
+
font-weight: 500;
|
|
105
|
+
}
|
|
106
|
+
.status-pending { background: rgba(251, 191, 36, 0.2); color: #fbbf24; }
|
|
107
|
+
.status-in_progress { background: rgba(59, 130, 246, 0.2); color: #3b82f6; }
|
|
108
|
+
.status-pending_review { background: rgba(168, 85, 247, 0.2); color: #a855f7; }
|
|
109
|
+
.status-needs_work { background: rgba(249, 115, 22, 0.2); color: #f97316; }
|
|
110
|
+
.status-completed { background: rgba(74, 222, 128, 0.2); color: #4ade80; }
|
|
111
|
+
.status-cancelled { background: rgba(239, 68, 68, 0.2); color: #ef4444; }
|
|
112
|
+
.status-blocked { background: rgba(239, 68, 68, 0.2); color: #ef4444; }
|
|
113
|
+
.read-only-banner {
|
|
114
|
+
background: rgba(251, 191, 36, 0.2);
|
|
115
|
+
color: #fbbf24;
|
|
116
|
+
padding: 0.75rem 1rem;
|
|
117
|
+
border-radius: 0.5rem;
|
|
118
|
+
margin-bottom: 1rem;
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
gap: 0.5rem;
|
|
122
|
+
}
|
|
123
|
+
footer {
|
|
124
|
+
margin-top: 2rem;
|
|
125
|
+
padding-top: 1rem;
|
|
126
|
+
border-top: 1px solid var(--border);
|
|
127
|
+
color: var(--muted);
|
|
128
|
+
font-size: 0.875rem;
|
|
129
|
+
text-align: center;
|
|
130
|
+
}
|
|
131
|
+
a { color: var(--accent); text-decoration: none; }
|
|
132
|
+
a:hover { text-decoration: underline; }
|
|
133
|
+
</style>
|
|
134
|
+
</head>
|
|
135
|
+
<body>
|
|
136
|
+
<div class="container">
|
|
137
|
+
<header>
|
|
138
|
+
<div>
|
|
139
|
+
<h1>${escapeHtml(snapshot.project.name)}</h1>
|
|
140
|
+
<div class="meta">
|
|
141
|
+
Exported: ${new Date(snapshot.exported_at).toLocaleString()}
|
|
142
|
+
${snapshot.project.version ? ` • v${escapeHtml(snapshot.project.version)}` : ""}
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
${snapshot.validation ? `
|
|
146
|
+
<span class="badge ${snapshot.validation.valid ? "valid" : "invalid"}">
|
|
147
|
+
${snapshot.validation.valid ? "✓ Valid" : `✗ ${snapshot.validation.errorCount} errors`}
|
|
148
|
+
</span>
|
|
149
|
+
` : ""}
|
|
150
|
+
</header>
|
|
151
|
+
|
|
152
|
+
<div class="read-only-banner">
|
|
153
|
+
<span>📖</span>
|
|
154
|
+
<span>Read-only view. Use the kspec CLI to make changes.</span>
|
|
155
|
+
</div>
|
|
156
|
+
|
|
157
|
+
<div class="stats">
|
|
158
|
+
<div class="stat">
|
|
159
|
+
<div class="stat-value">${snapshot.tasks.length}</div>
|
|
160
|
+
<div class="stat-label">Tasks</div>
|
|
161
|
+
</div>
|
|
162
|
+
<div class="stat">
|
|
163
|
+
<div class="stat-value">${snapshot.items.length}</div>
|
|
164
|
+
<div class="stat-label">Spec Items</div>
|
|
165
|
+
</div>
|
|
166
|
+
<div class="stat">
|
|
167
|
+
<div class="stat-value">${snapshot.inbox.length}</div>
|
|
168
|
+
<div class="stat-label">Inbox Items</div>
|
|
169
|
+
</div>
|
|
170
|
+
<div class="stat">
|
|
171
|
+
<div class="stat-value">${snapshot.observations.length}</div>
|
|
172
|
+
<div class="stat-label">Observations</div>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
|
|
176
|
+
<div class="section">
|
|
177
|
+
<div class="section-title">Recent Tasks</div>
|
|
178
|
+
<div class="list">
|
|
179
|
+
${snapshot.tasks.slice(0, 10).map(task => `
|
|
180
|
+
<div class="item">
|
|
181
|
+
<div class="item-title">
|
|
182
|
+
<span class="status status-${task.status}">${task.status}</span>
|
|
183
|
+
${escapeHtml(task.title)}
|
|
184
|
+
</div>
|
|
185
|
+
<div class="item-meta">
|
|
186
|
+
@${task.slugs[0] || task._ulid.slice(0, 8)}
|
|
187
|
+
${task.spec_ref_title ? ` • ${escapeHtml(task.spec_ref_title)}` : ""}
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
`).join("")}
|
|
191
|
+
${snapshot.tasks.length > 10 ? `<div class="item-meta">... and ${snapshot.tasks.length - 10} more tasks</div>` : ""}
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
|
|
195
|
+
<div class="section">
|
|
196
|
+
<div class="section-title">Spec Items</div>
|
|
197
|
+
<div class="list">
|
|
198
|
+
${snapshot.items.slice(0, 10).map(item => `
|
|
199
|
+
<div class="item">
|
|
200
|
+
<div class="item-title">${escapeHtml(item.title)}</div>
|
|
201
|
+
<div class="item-meta">
|
|
202
|
+
${item.type || "item"} • @${item.slugs[0] || item._ulid.slice(0, 8)}
|
|
203
|
+
${item.acceptance_criteria?.length ? ` • ${item.acceptance_criteria.length} ACs` : ""}
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
`).join("")}
|
|
207
|
+
${snapshot.items.length > 10 ? `<div class="item-meta">... and ${snapshot.items.length - 10} more items</div>` : ""}
|
|
208
|
+
</div>
|
|
209
|
+
</div>
|
|
210
|
+
|
|
211
|
+
<footer>
|
|
212
|
+
Generated by <a href="https://github.com/chapel/kynetic-spec">kspec</a> v${escapeHtml(snapshot.version)}
|
|
213
|
+
</footer>
|
|
214
|
+
</div>
|
|
215
|
+
|
|
216
|
+
<!-- Embedded snapshot data -->
|
|
217
|
+
<script id="kspec-data" type="application/json">
|
|
218
|
+
${escapedJson}
|
|
219
|
+
</script>
|
|
220
|
+
|
|
221
|
+
<script>
|
|
222
|
+
// Make snapshot available globally
|
|
223
|
+
window.KSPEC_STATIC_DATA = JSON.parse(document.getElementById('kspec-data').textContent);
|
|
224
|
+
</script>
|
|
225
|
+
</body>
|
|
226
|
+
</html>`;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Escape HTML special characters.
|
|
230
|
+
*/
|
|
231
|
+
function escapeHtml(str) {
|
|
232
|
+
return str
|
|
233
|
+
.replace(/&/g, "&")
|
|
234
|
+
.replace(/</g, "<")
|
|
235
|
+
.replace(/>/g, ">")
|
|
236
|
+
.replace(/"/g, """)
|
|
237
|
+
.replace(/'/g, "'");
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/export/html.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/export/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC"}
|