@kynetic-ai/spec 0.11.0 → 0.12.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 +55 -455
- package/dist/agent-runtime/bootstrap.d.ts +31 -0
- package/dist/agent-runtime/bootstrap.d.ts.map +1 -0
- package/dist/agent-runtime/bootstrap.js +302 -0
- package/dist/agent-runtime/bootstrap.js.map +1 -0
- package/dist/agent-runtime/dispatch.d.ts +119 -10
- package/dist/agent-runtime/dispatch.d.ts.map +1 -1
- package/dist/agent-runtime/dispatch.js +1154 -219
- package/dist/agent-runtime/dispatch.js.map +1 -1
- package/dist/agent-runtime/invocation.d.ts +28 -1
- package/dist/agent-runtime/invocation.d.ts.map +1 -1
- package/dist/agent-runtime/invocation.js +171 -59
- package/dist/agent-runtime/invocation.js.map +1 -1
- package/dist/agent-runtime/prompts.d.ts +9 -0
- package/dist/agent-runtime/prompts.d.ts.map +1 -1
- package/dist/agent-runtime/prompts.js +42 -7
- package/dist/agent-runtime/prompts.js.map +1 -1
- package/dist/agent-runtime/session-event-accumulator.d.ts +83 -0
- package/dist/agent-runtime/session-event-accumulator.d.ts.map +1 -0
- package/dist/agent-runtime/session-event-accumulator.js +203 -0
- package/dist/agent-runtime/session-event-accumulator.js.map +1 -0
- package/dist/agent-runtime/session-event-types.d.ts +67 -0
- package/dist/agent-runtime/session-event-types.d.ts.map +1 -0
- package/dist/agent-runtime/session-event-types.js +13 -0
- package/dist/agent-runtime/session-event-types.js.map +1 -0
- package/dist/agent-runtime/workspace.d.ts +244 -0
- package/dist/agent-runtime/workspace.d.ts.map +1 -0
- package/dist/agent-runtime/workspace.js +2025 -0
- package/dist/agent-runtime/workspace.js.map +1 -0
- package/dist/agents/adapters.d.ts.map +1 -1
- package/dist/agents/adapters.js +58 -13
- package/dist/agents/adapters.js.map +1 -1
- package/dist/agents/spawner.d.ts +8 -0
- package/dist/agents/spawner.d.ts.map +1 -1
- package/dist/agents/spawner.js +25 -3
- package/dist/agents/spawner.js.map +1 -1
- package/dist/cli/batch-exec.js +1 -1
- package/dist/cli/batch-exec.js.map +1 -1
- package/dist/cli/command-annotations.d.ts +15 -3
- package/dist/cli/command-annotations.d.ts.map +1 -1
- package/dist/cli/command-annotations.js +23 -3
- package/dist/cli/command-annotations.js.map +1 -1
- package/dist/cli/commands/agent.d.ts +2 -0
- package/dist/cli/commands/agent.d.ts.map +1 -1
- package/dist/cli/commands/agent.js +144 -27
- package/dist/cli/commands/agent.js.map +1 -1
- package/dist/cli/commands/agents.d.ts.map +1 -1
- package/dist/cli/commands/agents.js +5 -5
- package/dist/cli/commands/agents.js.map +1 -1
- package/dist/cli/commands/derive.d.ts.map +1 -1
- package/dist/cli/commands/derive.js +118 -3
- package/dist/cli/commands/derive.js.map +1 -1
- package/dist/cli/commands/guard.d.ts.map +1 -1
- package/dist/cli/commands/guard.js +8 -6
- package/dist/cli/commands/guard.js.map +1 -1
- package/dist/cli/commands/index.d.ts +1 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +1 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +20 -0
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/item.d.ts.map +1 -1
- package/dist/cli/commands/item.js +205 -47
- package/dist/cli/commands/item.js.map +1 -1
- package/dist/cli/commands/log.d.ts.map +1 -1
- package/dist/cli/commands/log.js +24 -10
- package/dist/cli/commands/log.js.map +1 -1
- package/dist/cli/commands/plan-import.d.ts +3 -3
- package/dist/cli/commands/plan-import.d.ts.map +1 -1
- package/dist/cli/commands/plan-import.js +213 -528
- package/dist/cli/commands/plan-import.js.map +1 -1
- package/dist/cli/commands/plan.d.ts.map +1 -1
- package/dist/cli/commands/plan.js +533 -83
- package/dist/cli/commands/plan.js.map +1 -1
- package/dist/cli/commands/review.d.ts +14 -0
- package/dist/cli/commands/review.d.ts.map +1 -0
- package/dist/cli/commands/review.js +1142 -0
- package/dist/cli/commands/review.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +1 -0
- package/dist/cli/commands/serve.d.ts.map +1 -1
- package/dist/cli/commands/serve.js +33 -10
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/commands/session/checkpoint.d.ts +2 -4
- package/dist/cli/commands/session/checkpoint.d.ts.map +1 -1
- package/dist/cli/commands/session/checkpoint.js +6 -107
- package/dist/cli/commands/session/checkpoint.js.map +1 -1
- package/dist/cli/commands/session/commands.d.ts.map +1 -1
- package/dist/cli/commands/session/commands.js +33 -23
- package/dist/cli/commands/session/commands.js.map +1 -1
- package/dist/cli/commands/session/compact.js +4 -4
- package/dist/cli/commands/session/compact.js.map +1 -1
- package/dist/cli/commands/session/create.js +2 -2
- package/dist/cli/commands/session/create.js.map +1 -1
- package/dist/cli/commands/session/format.d.ts.map +1 -1
- package/dist/cli/commands/session/format.js +1 -6
- package/dist/cli/commands/session/format.js.map +1 -1
- package/dist/cli/commands/session/log.d.ts +32 -7
- package/dist/cli/commands/session/log.d.ts.map +1 -1
- package/dist/cli/commands/session/log.js +166 -60
- package/dist/cli/commands/session/log.js.map +1 -1
- package/dist/cli/commands/session/migrate.d.ts +9 -0
- package/dist/cli/commands/session/migrate.d.ts.map +1 -0
- package/dist/cli/commands/session/migrate.js +46 -0
- package/dist/cli/commands/session/migrate.js.map +1 -0
- package/dist/cli/commands/session/stale-close.d.ts.map +1 -1
- package/dist/cli/commands/session/stale-close.js +5 -8
- package/dist/cli/commands/session/stale-close.js.map +1 -1
- package/dist/cli/commands/session/types.d.ts +1 -1
- package/dist/cli/commands/session/types.d.ts.map +1 -1
- package/dist/cli/commands/setup.d.ts +2 -2
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +287 -257
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/shadow.d.ts.map +1 -1
- package/dist/cli/commands/shadow.js +147 -31
- package/dist/cli/commands/shadow.js.map +1 -1
- package/dist/cli/commands/skill-crud.d.ts +7 -0
- package/dist/cli/commands/skill-crud.d.ts.map +1 -1
- package/dist/cli/commands/skill-crud.js +41 -18
- package/dist/cli/commands/skill-crud.js.map +1 -1
- package/dist/cli/commands/skill-diff.d.ts.map +1 -1
- package/dist/cli/commands/skill-diff.js +29 -3
- package/dist/cli/commands/skill-diff.js.map +1 -1
- package/dist/cli/commands/skill-install.d.ts.map +1 -1
- package/dist/cli/commands/skill-install.js +5 -4
- package/dist/cli/commands/skill-install.js.map +1 -1
- package/dist/cli/commands/task.d.ts.map +1 -1
- package/dist/cli/commands/task.js +359 -49
- package/dist/cli/commands/task.js.map +1 -1
- package/dist/cli/commands/trait.d.ts.map +1 -1
- package/dist/cli/commands/trait.js +5 -27
- package/dist/cli/commands/trait.js.map +1 -1
- package/dist/cli/commands/validate.d.ts.map +1 -1
- package/dist/cli/commands/validate.js +113 -52
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +69 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/output.d.ts +26 -0
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +108 -1
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/sync-mode.d.ts +44 -0
- package/dist/cli/sync-mode.d.ts.map +1 -0
- package/dist/cli/sync-mode.js +64 -0
- package/dist/cli/sync-mode.js.map +1 -0
- package/dist/daemon/middleware/project-context.ts +25 -7
- package/dist/daemon/project-context.ts +18 -0
- package/dist/daemon/routes/agent-dispatch.ts +99 -22
- package/dist/daemon/routes/aggregation.ts +184 -0
- package/dist/daemon/routes/inbox.ts +5 -0
- package/dist/daemon/routes/items.ts +145 -0
- package/dist/daemon/routes/meta.ts +1 -1
- package/dist/daemon/routes/projects.ts +28 -6
- package/dist/daemon/routes/ref-resolution.ts +119 -0
- package/dist/daemon/routes/refs.ts +42 -0
- package/dist/daemon/routes/session-related.ts +140 -0
- package/dist/daemon/routes/sessions.ts +420 -19
- package/dist/daemon/routes/tasks.ts +62 -5
- package/dist/daemon/routes/triage.ts +40 -1
- package/dist/daemon/server.ts +143 -49
- package/dist/daemon/session-sync.ts +11 -0
- package/dist/daemon/shadow-sync.ts +11 -0
- package/dist/daemon/watcher.ts +56 -5
- package/dist/daemon/websocket/project-resolution.ts +77 -0
- package/dist/export/json.d.ts.map +1 -1
- package/dist/export/json.js +104 -1
- package/dist/export/json.js.map +1 -1
- package/dist/export/types.d.ts +52 -1
- package/dist/export/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/parser/agent-detection.d.ts +1 -1
- package/dist/parser/agent-detection.d.ts.map +1 -1
- package/dist/parser/agent-detection.js +10 -0
- package/dist/parser/agent-detection.js.map +1 -1
- package/dist/parser/config.d.ts +397 -2
- package/dist/parser/config.d.ts.map +1 -1
- package/dist/parser/config.js +125 -3
- package/dist/parser/config.js.map +1 -1
- package/dist/parser/dispatch-workspaces.d.ts +18 -0
- package/dist/parser/dispatch-workspaces.d.ts.map +1 -0
- package/dist/parser/dispatch-workspaces.js +209 -0
- package/dist/parser/dispatch-workspaces.js.map +1 -0
- package/dist/parser/doctor.d.ts.map +1 -1
- package/dist/parser/doctor.js +27 -8
- package/dist/parser/doctor.js.map +1 -1
- package/dist/parser/file-lock.d.ts.map +1 -1
- package/dist/parser/file-lock.js +9 -2
- package/dist/parser/file-lock.js.map +1 -1
- package/dist/parser/index.d.ts +6 -0
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/parser/index.js +6 -0
- package/dist/parser/index.js.map +1 -1
- package/dist/parser/plans.d.ts.map +1 -1
- package/dist/parser/plans.js +1 -0
- package/dist/parser/plans.js.map +1 -1
- package/dist/parser/refs.d.ts +8 -1
- package/dist/parser/refs.d.ts.map +1 -1
- package/dist/parser/refs.js +27 -1
- package/dist/parser/refs.js.map +1 -1
- package/dist/parser/review-operations.d.ts +72 -0
- package/dist/parser/review-operations.d.ts.map +1 -0
- package/dist/parser/review-operations.js +185 -0
- package/dist/parser/review-operations.js.map +1 -0
- package/dist/parser/review-task-integration.d.ts +78 -0
- package/dist/parser/review-task-integration.d.ts.map +1 -0
- package/dist/parser/review-task-integration.js +173 -0
- package/dist/parser/review-task-integration.js.map +1 -0
- package/dist/parser/review-threads.d.ts +101 -0
- package/dist/parser/review-threads.d.ts.map +1 -0
- package/dist/parser/review-threads.js +222 -0
- package/dist/parser/review-threads.js.map +1 -0
- package/dist/parser/review-validation.d.ts +69 -0
- package/dist/parser/review-validation.d.ts.map +1 -0
- package/dist/parser/review-validation.js +207 -0
- package/dist/parser/review-validation.js.map +1 -0
- package/dist/parser/reviews.d.ts +58 -0
- package/dist/parser/reviews.d.ts.map +1 -0
- package/dist/parser/reviews.js +230 -0
- package/dist/parser/reviews.js.map +1 -0
- package/dist/parser/session-branch.d.ts +91 -0
- package/dist/parser/session-branch.d.ts.map +1 -0
- package/dist/parser/session-branch.js +565 -0
- package/dist/parser/session-branch.js.map +1 -0
- package/dist/parser/session-sync-scheduler.d.ts +53 -0
- package/dist/parser/session-sync-scheduler.d.ts.map +1 -0
- package/dist/parser/session-sync-scheduler.js +100 -0
- package/dist/parser/session-sync-scheduler.js.map +1 -0
- package/dist/parser/setup-status.d.ts +7 -1
- package/dist/parser/setup-status.d.ts.map +1 -1
- package/dist/parser/setup-status.js +104 -39
- package/dist/parser/setup-status.js.map +1 -1
- package/dist/parser/shadow-sync-scheduler.d.ts +71 -0
- package/dist/parser/shadow-sync-scheduler.d.ts.map +1 -0
- package/dist/parser/shadow-sync-scheduler.js +139 -0
- package/dist/parser/shadow-sync-scheduler.js.map +1 -0
- package/dist/parser/shadow.d.ts +121 -14
- package/dist/parser/shadow.d.ts.map +1 -1
- package/dist/parser/shadow.js +752 -27
- package/dist/parser/shadow.js.map +1 -1
- package/dist/parser/skill-render.d.ts +24 -0
- package/dist/parser/skill-render.d.ts.map +1 -1
- package/dist/parser/skill-render.js +98 -26
- package/dist/parser/skill-render.js.map +1 -1
- package/dist/parser/validate.d.ts +43 -3
- package/dist/parser/validate.d.ts.map +1 -1
- package/dist/parser/validate.js +204 -30
- package/dist/parser/validate.js.map +1 -1
- package/dist/parser/yaml.d.ts +47 -11
- package/dist/parser/yaml.d.ts.map +1 -1
- package/dist/parser/yaml.js +329 -149
- package/dist/parser/yaml.js.map +1 -1
- package/dist/review/checks.d.ts +97 -0
- package/dist/review/checks.d.ts.map +1 -0
- package/dist/review/checks.js +175 -0
- package/dist/review/checks.js.map +1 -0
- package/dist/review/index.d.ts +3 -0
- package/dist/review/index.d.ts.map +1 -0
- package/dist/review/index.js +3 -0
- package/dist/review/index.js.map +1 -0
- package/dist/review/subject-bindings.d.ts +83 -0
- package/dist/review/subject-bindings.d.ts.map +1 -0
- package/dist/review/subject-bindings.js +175 -0
- package/dist/review/subject-bindings.js.map +1 -0
- package/dist/schema/common.d.ts +26 -0
- package/dist/schema/common.d.ts.map +1 -1
- package/dist/schema/common.js +13 -0
- package/dist/schema/common.js.map +1 -1
- package/dist/schema/dispatch-workspace.d.ts +2643 -0
- package/dist/schema/dispatch-workspace.d.ts.map +1 -0
- package/dist/schema/dispatch-workspace.js +187 -0
- package/dist/schema/dispatch-workspace.js.map +1 -0
- package/dist/schema/inbox.d.ts +8 -8
- package/dist/schema/index.d.ts +2 -0
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +2 -0
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/meta.d.ts +648 -116
- package/dist/schema/meta.d.ts.map +1 -1
- package/dist/schema/meta.js +27 -0
- package/dist/schema/meta.js.map +1 -1
- package/dist/schema/plan.d.ts +30 -19
- package/dist/schema/plan.d.ts.map +1 -1
- package/dist/schema/plan.js +3 -1
- package/dist/schema/plan.js.map +1 -1
- package/dist/schema/review-records.d.ts +2676 -0
- package/dist/schema/review-records.d.ts.map +1 -0
- package/dist/schema/review-records.js +232 -0
- package/dist/schema/review-records.js.map +1 -0
- package/dist/schema/spec.d.ts +32 -14
- package/dist/schema/spec.d.ts.map +1 -1
- package/dist/schema/spec.js +5 -0
- package/dist/schema/spec.js.map +1 -1
- package/dist/schema/task.d.ts +187 -29
- package/dist/schema/task.d.ts.map +1 -1
- package/dist/schema/task.js +12 -2
- package/dist/schema/task.js.map +1 -1
- package/dist/schema/triage.d.ts +22 -22
- package/dist/sessions/cache.d.ts +119 -0
- package/dist/sessions/cache.d.ts.map +1 -0
- package/dist/sessions/cache.js +284 -0
- package/dist/sessions/cache.js.map +1 -0
- package/dist/sessions/index.d.ts +1 -0
- package/dist/sessions/index.d.ts.map +1 -1
- package/dist/sessions/index.js +2 -0
- package/dist/sessions/index.js.map +1 -1
- package/dist/sessions/legacy.d.ts +77 -0
- package/dist/sessions/legacy.d.ts.map +1 -0
- package/dist/sessions/legacy.js +146 -0
- package/dist/sessions/legacy.js.map +1 -0
- package/dist/sessions/store.d.ts +103 -73
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +335 -186
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/types.d.ts +44 -16
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js +11 -2
- package/dist/sessions/types.js.map +1 -1
- package/dist/strings/errors.d.ts +32 -0
- package/dist/strings/errors.d.ts.map +1 -1
- package/dist/strings/errors.js +17 -0
- package/dist/strings/errors.js.map +1 -1
- package/dist/strings/labels.d.ts +1 -0
- package/dist/strings/labels.d.ts.map +1 -1
- package/dist/strings/labels.js +1 -0
- package/dist/strings/labels.js.map +1 -1
- package/dist/utils/activity.d.ts +101 -0
- package/dist/utils/activity.d.ts.map +1 -0
- package/dist/utils/activity.js +408 -0
- package/dist/utils/activity.js.map +1 -0
- package/dist/utils/git.d.ts +31 -0
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +87 -0
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/web-ui/_app/immutable/assets/0.tmlwn-Ih.css +1 -0
- package/dist/web-ui/_app/immutable/assets/9.BwwJybWx.css +1 -0
- package/dist/web-ui/_app/immutable/chunks/2KqE8gtn.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/70-t_QvE.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/AiWQj974.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{CPPfDSei.js → B25nWFyA.js} +4 -4
- package/dist/web-ui/_app/immutable/chunks/{DBYE9jOd.js → B2bcA_Q_.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/B5e5HYyB.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/B7-5z6eA.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/B7bGmhK0.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{DzO4hlg9.js → B8tYZKAE.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/{B5LJFxqa.js → BFGAyJjD.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/BG0850zf.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{DAMmvwn4.js → BG8eSzAd.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/BIMxXS8I.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/BSzL1fpU.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/BYtjHfeq.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{DxCk-KHc.js → Bp5pFYXL.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/{B8a0xDxR.js → BsJFsuAT.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/BvpNHcD6.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/BypqA25-.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{BVA9Exy-.js → C0w6WDm5.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/C5_PAZ0y.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/CDRO15Iv.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/CF1CoqD5.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/CS2sa4_m.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{BJ0JX3ea.js → CWUQwB9H.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/CY5FDdSU.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/C_7MTDoj.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{D3vxvonu.js → CaAJD3dl.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/{BP352uRn.js → ChB5iyEL.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/{pE6cYWlS.js → ChQD-6N8.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/{Eo4gF7ih.js → CqbsoCwA.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/DCeJW50p.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{Cncwi6fQ.js → DJtZNgcs.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/DKIeaprD.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/DLd2uVIA.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{DjcCz-PU.js → DW_subyT.js} +2 -2
- package/dist/web-ui/_app/immutable/chunks/DbU6lVn0.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/Dc7ZCC5m.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/Dd5umPsk.js +2 -0
- package/dist/web-ui/_app/immutable/chunks/{BysXJlZb.js → Dg_zDpDS.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/Dgqu8Yuc.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/DmxsPZTB.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/DphTaFUB.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/DqK4iHp0.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{D9QNBZM2.js → DqT6OH_u.js} +2 -2
- package/dist/web-ui/_app/immutable/chunks/Ds9I9wQb.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/Du5ng3u4.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/DxJw79Wi.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/GFTX8GgV.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{C076q4JN.js → HNjs76Zz.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/HVMjDi4_.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{BkOJ8DkV.js → P0A_fJvS.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/T3vGWjIL.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/VTmrX9Qu.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{k_Qegko0.js → Xvwhx_F1.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/Yyz1XMQA.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{62JVKtnb.js → dh5HeqUr.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/fZMteyca.js +62 -0
- package/dist/web-ui/_app/immutable/chunks/{D82RulSH.js → gPrj-hqC.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/htcWMiYN.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{CwELQvbx.js → oTsvd9y4.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/qJfLUwU4.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/xCtiO_JE.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{DvA-KON-.js → y4GeEH6k.js} +1 -1
- package/dist/web-ui/_app/immutable/entry/app.C4h_eOn6.js +2 -0
- package/dist/web-ui/_app/immutable/entry/start.CQFTf9ep.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/0.Dh1xO970.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/1.l75D3Opx.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/10.DBidBPc-.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/11.Ab0gUKWe.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/12.CMsnoxfs.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/13.D8YKuknB.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/14.DZ0aan7y.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/15.CUIKreDL.js +2 -0
- package/dist/web-ui/_app/immutable/nodes/16.BWc8--BO.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/2.CDUonbuh.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/3.Ctg3M00i.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/4.Ci-JDwbA.js +2 -0
- package/dist/web-ui/_app/immutable/nodes/5.CTyEDAq0.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/6.BTZZqsAb.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/7.BI52g_Jo.js +137 -0
- package/dist/web-ui/_app/immutable/nodes/8.3hZPaB9x.js +1 -0
- package/dist/web-ui/_app/immutable/nodes/9.DS49kvwl.js +29 -0
- package/dist/web-ui/_app/version.json +1 -1
- package/dist/web-ui/favicon-192.png +0 -0
- package/dist/web-ui/favicon-32.png +0 -0
- package/dist/web-ui/favicon.ico +0 -0
- package/dist/web-ui/index.html +14 -14
- package/package.json +12 -6
- package/plugin/.claude-plugin/marketplace.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/plugins/kspec/skills/merge/SKILL.md +127 -0
- package/plugin/plugins/kspec/skills/plan/SKILL.md +55 -26
- package/plugin/plugins/kspec/skills/review/SKILL.md +350 -133
- package/plugin/plugins/kspec/skills/task-work/SKILL.md +96 -106
- package/templates/agents-sections/04-pr-workflow.md +15 -12
- package/templates/agents-sections/06-ralph-loop.md +15 -10
- package/templates/skills/manifest.yaml +25 -7
- package/templates/skills/merge/SKILL.md +120 -0
- package/templates/skills/plan/SKILL.md +55 -26
- package/templates/skills/review/SKILL.md +346 -130
- package/templates/skills/task-work/SKILL.md +93 -103
- package/dist/web-ui/_app/immutable/assets/0.BJaYkGW2.css +0 -1
- package/dist/web-ui/_app/immutable/assets/9.SzGLxi4x.css +0 -1
- package/dist/web-ui/_app/immutable/chunks/-lc0BifF.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/8RBjHMN1.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/B5wTVqxm.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/B6VSmczZ.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/BEOQc37C.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/BHtYorjv.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/BMuCqDX8.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/BUZujXJ2.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/BWET-efb.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/BXkNecpt.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/BYzrIfX8.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/BpuwufMc.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/BwMO4RrG.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/C33JaVbg.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/CGtqifKp.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/CHDZZ7OG.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/CUir3f4J.js +0 -60
- package/dist/web-ui/_app/immutable/chunks/CrCIbn0C.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/D6TVmR9T.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/D7LTux4W.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/DAh4Wfku.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/DAx07bEQ.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/DOno4cA2.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/DQA8NZIH.js +0 -2
- package/dist/web-ui/_app/immutable/chunks/DRfPm2bo.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/DhQhksaB.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/DjG7s6hm.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/DkltRNvh.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/DlaTnPKL.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/ExCq5swK.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/T3zZGv51.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/XZumBYeP.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/_ySfNjkF.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/iEtR5cV6.js +0 -1
- package/dist/web-ui/_app/immutable/entry/app.Cgu6uKeS.js +0 -2
- package/dist/web-ui/_app/immutable/entry/start.9XifnLoB.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/0.DISwcKSK.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/1.Cx2Ufqp1.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/10.C3z8ijXL.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/11.DZdIjZmM.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/12.FsIGfAOa.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/13.DZoFwagf.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/14.DaIzDKbQ.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/15.BYyt4XWF.js +0 -2
- package/dist/web-ui/_app/immutable/nodes/16.CQkSqpOe.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/2.Bkf_j2UJ.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/3.kaMCurJG.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/4.BSsFPTHG.js +0 -2
- package/dist/web-ui/_app/immutable/nodes/5.CpPlcCEZ.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/6.BN4FqQmY.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/7.9kBYIZik.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/8.BuijtZ6B.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/9.C-Weba8R.js +0 -1
|
@@ -34,6 +34,8 @@ import {
|
|
|
34
34
|
} from '../../parser/index.js';
|
|
35
35
|
import { commitIfShadow } from '../../parser/shadow.js';
|
|
36
36
|
import type { PubSubManager } from '../websocket/pubsub';
|
|
37
|
+
import { getRelatedSessionsForTask } from './session-related.js';
|
|
38
|
+
import { resolveRefTitle, resolveRefEntries } from './ref-resolution.js';
|
|
37
39
|
|
|
38
40
|
interface TasksRouteOptions {
|
|
39
41
|
pubsub: PubSubManager;
|
|
@@ -110,6 +112,7 @@ export function createTasksRoutes(options: TasksRouteOptions) {
|
|
|
110
112
|
|
|
111
113
|
// AC: @api-contract ac-2 - Return with status, priority, spec_ref, notes count
|
|
112
114
|
// AC: @web-dashboard ac-1 - Include depends_on for blocked task computation
|
|
115
|
+
// AC: @ui-api-ref-resolution ac-1 - Include spec_title resolved server-side
|
|
113
116
|
const items = paginated.map((task) => ({
|
|
114
117
|
_ulid: task._ulid,
|
|
115
118
|
slugs: task.slugs,
|
|
@@ -118,6 +121,7 @@ export function createTasksRoutes(options: TasksRouteOptions) {
|
|
|
118
121
|
status: task.status,
|
|
119
122
|
priority: task.priority,
|
|
120
123
|
spec_ref: task.spec_ref,
|
|
124
|
+
spec_title: resolveRefTitle(index, task.spec_ref),
|
|
121
125
|
meta_ref: task.meta_ref,
|
|
122
126
|
tags: task.tags,
|
|
123
127
|
depends_on: task.depends_on || [],
|
|
@@ -158,7 +162,8 @@ export function createTasksRoutes(options: TasksRouteOptions) {
|
|
|
158
162
|
const ctx = await initContext(projectContext.path);
|
|
159
163
|
const tasks = await loadAllTasks(ctx);
|
|
160
164
|
const items = await loadAllItems(ctx);
|
|
161
|
-
const
|
|
165
|
+
const plans = await loadPlans(ctx);
|
|
166
|
+
const index = new ReferenceIndex(tasks, items, [], plans);
|
|
162
167
|
|
|
163
168
|
// AC: @api-contract ac-5, @trait-api-endpoint ac-2 - Resolve ref via ReferenceIndex
|
|
164
169
|
const result = index.resolve(params.ref);
|
|
@@ -184,6 +189,7 @@ export function createTasksRoutes(options: TasksRouteOptions) {
|
|
|
184
189
|
|
|
185
190
|
// AC: @api-contract ac-5 - Return full task with notes, todos, dependencies
|
|
186
191
|
// AC: @ui-task-board ac-3 - Include type, description, blocked_by, vcs_refs, plan_ref, session_ref
|
|
192
|
+
// AC: @ui-api-ref-resolution ac-1, ac-2 - Include resolved titles for refs
|
|
187
193
|
return {
|
|
188
194
|
_ulid: task._ulid,
|
|
189
195
|
slugs: task.slugs,
|
|
@@ -192,17 +198,21 @@ export function createTasksRoutes(options: TasksRouteOptions) {
|
|
|
192
198
|
status: task.status,
|
|
193
199
|
priority: task.priority,
|
|
194
200
|
spec_ref: task.spec_ref,
|
|
201
|
+
spec_title: resolveRefTitle(index, task.spec_ref),
|
|
195
202
|
meta_ref: task.meta_ref,
|
|
196
203
|
tags: task.tags,
|
|
197
204
|
description: task.description,
|
|
198
205
|
derivation: task.derivation,
|
|
199
206
|
depends_on: task.depends_on,
|
|
207
|
+
resolved_depends_on: resolveRefEntries(index, task.depends_on),
|
|
200
208
|
blocked_by: task.blocked_by || [],
|
|
209
|
+
resolved_blocked_by: resolveRefEntries(index, task.blocked_by),
|
|
201
210
|
context: task.context || [],
|
|
202
211
|
vcs_refs: (task.vcs_refs || []).map((v) =>
|
|
203
212
|
typeof v === 'string' ? v : v.type ? `${v.type}:${v.ref}` : v.ref
|
|
204
213
|
),
|
|
205
214
|
plan_ref: task.plan_ref,
|
|
215
|
+
plan_title: resolveRefTitle(index, task.plan_ref),
|
|
206
216
|
session_ref: task.session_id,
|
|
207
217
|
notes: task.notes,
|
|
208
218
|
notes_count: task.notes?.length || 0,
|
|
@@ -223,6 +233,37 @@ export function createTasksRoutes(options: TasksRouteOptions) {
|
|
|
223
233
|
}
|
|
224
234
|
)
|
|
225
235
|
|
|
236
|
+
.get(
|
|
237
|
+
'/:ref/sessions',
|
|
238
|
+
async ({ params, error: errorResponse, projectContext }) => {
|
|
239
|
+
const ctx = await initContext(projectContext.path);
|
|
240
|
+
const tasks = await loadAllTasks(ctx);
|
|
241
|
+
const items = await loadAllItems(ctx);
|
|
242
|
+
const result = await getRelatedSessionsForTask({
|
|
243
|
+
taskRef: params.ref,
|
|
244
|
+
tasks,
|
|
245
|
+
items,
|
|
246
|
+
sessionsDir: ctx.sessionsDir,
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
if ('error' in result) {
|
|
250
|
+
return errorResponse(404, result.error);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return {
|
|
254
|
+
items: result.sessions,
|
|
255
|
+
total: result.sessions.length,
|
|
256
|
+
offset: 0,
|
|
257
|
+
limit: result.sessions.length,
|
|
258
|
+
};
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
params: t.Object({
|
|
262
|
+
ref: t.String(),
|
|
263
|
+
}),
|
|
264
|
+
}
|
|
265
|
+
)
|
|
266
|
+
|
|
226
267
|
// AC: @api-contract ac-6 - Start task
|
|
227
268
|
.post(
|
|
228
269
|
'/:ref/start',
|
|
@@ -274,12 +315,15 @@ export function createTasksRoutes(options: TasksRouteOptions) {
|
|
|
274
315
|
await commitIfShadow(ctx.shadow, `task: start ${params.ref}`);
|
|
275
316
|
|
|
276
317
|
// AC: @api-contract ac-6, @trait-api-endpoint ac-5 - WebSocket broadcast
|
|
318
|
+
// AC: @ui-api-aggregation ac-4 - Include title and old/new status
|
|
277
319
|
// AC: @multi-directory-daemon ac-18 - Broadcast scoped to request project
|
|
278
320
|
pubsub.broadcast('tasks:updates', 'task_updated', {
|
|
279
321
|
ref: params.ref,
|
|
280
322
|
ulid: task._ulid,
|
|
281
323
|
action: 'start',
|
|
282
|
-
|
|
324
|
+
title: task.title,
|
|
325
|
+
old_status: task.status,
|
|
326
|
+
new_status: 'in_progress',
|
|
283
327
|
}, projectContext.path);
|
|
284
328
|
|
|
285
329
|
// AC: @api-contract ac-6 - Return updated task
|
|
@@ -346,11 +390,15 @@ export function createTasksRoutes(options: TasksRouteOptions) {
|
|
|
346
390
|
await commitIfShadow(ctx.shadow, `task: add note to ${params.ref}`);
|
|
347
391
|
|
|
348
392
|
// AC: @api-contract ac-7 - WebSocket broadcast
|
|
393
|
+
// AC: @ui-api-aggregation ac-4 - Include title (no status change for notes)
|
|
349
394
|
// AC: @multi-directory-daemon ac-18 - Broadcast scoped to request project
|
|
350
395
|
pubsub.broadcast('tasks:updates', 'task_updated', {
|
|
351
396
|
ref: params.ref,
|
|
352
397
|
ulid: task._ulid,
|
|
353
398
|
action: 'note_added',
|
|
399
|
+
title: task.title,
|
|
400
|
+
old_status: null,
|
|
401
|
+
new_status: null,
|
|
354
402
|
note_ulid: note._ulid,
|
|
355
403
|
}, projectContext.path);
|
|
356
404
|
|
|
@@ -409,11 +457,14 @@ export function createTasksRoutes(options: TasksRouteOptions) {
|
|
|
409
457
|
await syncSpecImplementationStatus(ctx, updatedTask, tasks, items, index);
|
|
410
458
|
await commitIfShadow(ctx.shadow, `task: submit ${params.ref}`);
|
|
411
459
|
|
|
460
|
+
// AC: @ui-api-aggregation ac-4 - Include title and old/new status
|
|
412
461
|
pubsub.broadcast('tasks:updates', 'task_updated', {
|
|
413
462
|
ref: params.ref,
|
|
414
463
|
ulid: task._ulid,
|
|
415
464
|
action: 'submit',
|
|
416
|
-
|
|
465
|
+
title: task.title,
|
|
466
|
+
old_status: task.status,
|
|
467
|
+
new_status: 'pending_review',
|
|
417
468
|
}, projectContext.path);
|
|
418
469
|
|
|
419
470
|
return updatedTask;
|
|
@@ -456,11 +507,14 @@ export function createTasksRoutes(options: TasksRouteOptions) {
|
|
|
456
507
|
await syncSpecImplementationStatus(ctx, updatedTask, tasks, items, index);
|
|
457
508
|
await commitIfShadow(ctx.shadow, `task: complete ${params.ref}`);
|
|
458
509
|
|
|
510
|
+
// AC: @ui-api-aggregation ac-4 - Include title and old/new status
|
|
459
511
|
pubsub.broadcast('tasks:updates', 'task_updated', {
|
|
460
512
|
ref: params.ref,
|
|
461
513
|
ulid: task._ulid,
|
|
462
514
|
action: 'complete',
|
|
463
|
-
|
|
515
|
+
title: task.title,
|
|
516
|
+
old_status: task.status,
|
|
517
|
+
new_status: 'completed',
|
|
464
518
|
}, projectContext.path);
|
|
465
519
|
|
|
466
520
|
return updatedTask;
|
|
@@ -508,11 +562,14 @@ export function createTasksRoutes(options: TasksRouteOptions) {
|
|
|
508
562
|
await syncSpecImplementationStatus(ctx, updatedTask, tasks, items, index);
|
|
509
563
|
await commitIfShadow(ctx.shadow, `task: block ${params.ref}`);
|
|
510
564
|
|
|
565
|
+
// AC: @ui-api-aggregation ac-4 - Include title and old/new status
|
|
511
566
|
pubsub.broadcast('tasks:updates', 'task_updated', {
|
|
512
567
|
ref: params.ref,
|
|
513
568
|
ulid: task._ulid,
|
|
514
569
|
action: 'block',
|
|
515
|
-
|
|
570
|
+
title: task.title,
|
|
571
|
+
old_status: task.status,
|
|
572
|
+
new_status: 'blocked',
|
|
516
573
|
}, projectContext.path);
|
|
517
574
|
|
|
518
575
|
return updatedTask;
|
|
@@ -25,6 +25,9 @@ import { Elysia, t } from 'elysia';
|
|
|
25
25
|
import { ulid } from 'ulidx';
|
|
26
26
|
import {
|
|
27
27
|
initContext,
|
|
28
|
+
loadAllTasks,
|
|
29
|
+
loadAllItems,
|
|
30
|
+
ReferenceIndex,
|
|
28
31
|
loadTriageRecords,
|
|
29
32
|
saveTriageRecord,
|
|
30
33
|
findTriageRecordByRef,
|
|
@@ -34,6 +37,7 @@ import {
|
|
|
34
37
|
getAuthor,
|
|
35
38
|
type LoadedTriageRecord,
|
|
36
39
|
} from '../../parser/index.js';
|
|
40
|
+
import { resolveRefEntries } from './ref-resolution.js';
|
|
37
41
|
import { commitIfShadow } from '../../parser/shadow.js';
|
|
38
42
|
import { normalizeRefInput } from '../../schema/index.js';
|
|
39
43
|
import type { TriageAction } from '../../schema/index.js';
|
|
@@ -87,8 +91,27 @@ export function createTriageRoutes(options: TriageRouteOptions) {
|
|
|
87
91
|
|
|
88
92
|
const paginated = filtered.slice(offset, offset + limit);
|
|
89
93
|
|
|
94
|
+
// AC: @ui-api-ref-resolution ac-2 - Resolve evidence_refs titles
|
|
95
|
+
const hasEvidenceRefs = paginated.some((r) => r.evidence_refs?.length > 0);
|
|
96
|
+
let refIndex: ReferenceIndex | null = null;
|
|
97
|
+
if (hasEvidenceRefs) {
|
|
98
|
+
try {
|
|
99
|
+
const tasks = await loadAllTasks(ctx);
|
|
100
|
+
const items = await loadAllItems(ctx);
|
|
101
|
+
refIndex = new ReferenceIndex(tasks, items);
|
|
102
|
+
} catch {
|
|
103
|
+
// Non-critical
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const enriched = refIndex
|
|
107
|
+
? paginated.map((r) => ({
|
|
108
|
+
...r,
|
|
109
|
+
resolved_evidence_refs: resolveRefEntries(refIndex!, r.evidence_refs),
|
|
110
|
+
}))
|
|
111
|
+
: paginated;
|
|
112
|
+
|
|
90
113
|
return {
|
|
91
|
-
items:
|
|
114
|
+
items: enriched,
|
|
92
115
|
total,
|
|
93
116
|
offset,
|
|
94
117
|
limit,
|
|
@@ -223,6 +246,7 @@ export function createTriageRoutes(options: TriageRouteOptions) {
|
|
|
223
246
|
)
|
|
224
247
|
|
|
225
248
|
// GET single triage record
|
|
249
|
+
// AC: @ui-api-ref-resolution ac-2 - Resolve evidence_refs titles
|
|
226
250
|
.get(
|
|
227
251
|
'/:ref',
|
|
228
252
|
async ({ params, error: errorResponse, projectContext }) => {
|
|
@@ -240,6 +264,21 @@ export function createTriageRoutes(options: TriageRouteOptions) {
|
|
|
240
264
|
});
|
|
241
265
|
}
|
|
242
266
|
|
|
267
|
+
// AC: @ui-api-ref-resolution ac-2 - Resolve evidence_refs
|
|
268
|
+
if (record.evidence_refs?.length > 0) {
|
|
269
|
+
try {
|
|
270
|
+
const tasks = await loadAllTasks(ctx);
|
|
271
|
+
const items = await loadAllItems(ctx);
|
|
272
|
+
const refIndex = new ReferenceIndex(tasks, items);
|
|
273
|
+
return {
|
|
274
|
+
...record,
|
|
275
|
+
resolved_evidence_refs: resolveRefEntries(refIndex, record.evidence_refs),
|
|
276
|
+
};
|
|
277
|
+
} catch {
|
|
278
|
+
// Non-critical
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
243
282
|
return record;
|
|
244
283
|
},
|
|
245
284
|
{
|
package/dist/daemon/server.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { PubSubManager } from './websocket/pubsub';
|
|
|
16
16
|
import { HeartbeatManager } from './websocket/heartbeat';
|
|
17
17
|
import { WebSocketHandler } from './websocket/handler';
|
|
18
18
|
import { handleWebSocketClose } from './websocket/lifecycle';
|
|
19
|
+
import { resolveWebSocketProject } from './websocket/project-resolution';
|
|
19
20
|
import type { ConnectionData, ConnectedEvent } from './websocket/types';
|
|
20
21
|
import { PidFileManager } from './pid';
|
|
21
22
|
import { projectContextMiddleware } from './middleware/project-context';
|
|
@@ -29,6 +30,10 @@ import { createTriageRoutes } from './routes/triage';
|
|
|
29
30
|
import { createAgentDispatchRoutes, getDispatchEngine, stopAllEngines } from './routes/agent-dispatch';
|
|
30
31
|
import { createSessionRoutes } from './routes/sessions';
|
|
31
32
|
import { createPlansRoutes } from './routes/plans';
|
|
33
|
+
import { createAggregationRoutes } from './routes/aggregation';
|
|
34
|
+
import { createRefsRoutes } from './routes/refs';
|
|
35
|
+
import { ShadowSyncScheduler } from './shadow-sync';
|
|
36
|
+
import { SessionSyncScheduler } from './session-sync';
|
|
32
37
|
import { join } from 'path';
|
|
33
38
|
|
|
34
39
|
export interface ServerOptions {
|
|
@@ -43,10 +48,9 @@ export interface ServerOptions {
|
|
|
43
48
|
* Tries multiple locations in order:
|
|
44
49
|
* 1. Explicit webUiDir option
|
|
45
50
|
* 2. WEB_UI_DIR environment variable
|
|
46
|
-
* 3.
|
|
47
|
-
* 4. web-ui/build in current working directory
|
|
48
|
-
* 5. Bundled dist/web-ui/ relative to this module (npm package installs)
|
|
51
|
+
* 3. Bundled dist/web-ui/ relative to this module (npm package installs)
|
|
49
52
|
*
|
|
53
|
+
* AC: @daemon-web-ui-bundle ac-4, ac-5
|
|
50
54
|
* Exported for testing only.
|
|
51
55
|
*/
|
|
52
56
|
export function resolveWebUiPath(webUiDir?: string): string | null {
|
|
@@ -61,20 +65,7 @@ export function resolveWebUiPath(webUiDir?: string): string | null {
|
|
|
61
65
|
return envPath;
|
|
62
66
|
}
|
|
63
67
|
|
|
64
|
-
// 3.
|
|
65
|
-
// The daemon is spawned with cwd set to project root
|
|
66
|
-
const monorepoPath = join(process.cwd(), 'packages', 'web-ui', 'build');
|
|
67
|
-
if (existsSync(monorepoPath)) {
|
|
68
|
-
return monorepoPath;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// 4. Alternate location: web-ui/build in cwd
|
|
72
|
-
const altPath = join(process.cwd(), 'web-ui', 'build');
|
|
73
|
-
if (existsSync(altPath)) {
|
|
74
|
-
return altPath;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// 5. Bundled assets: dist/web-ui/ relative to daemon module location
|
|
68
|
+
// 3. Bundled assets: dist/web-ui/ relative to daemon module location
|
|
78
69
|
// Covers npm package installs where no local web UI build exists.
|
|
79
70
|
// import.meta.url resolves to dist/daemon/server.js → sibling is dist/web-ui/
|
|
80
71
|
const selfDir = dirname(fileURLToPath(import.meta.url));
|
|
@@ -91,6 +82,66 @@ let pubsubManager: PubSubManager;
|
|
|
91
82
|
let heartbeatManager: HeartbeatManager;
|
|
92
83
|
let wsHandler: WebSocketHandler;
|
|
93
84
|
let projectManager: import('./project-context').ProjectContextManager | undefined;
|
|
85
|
+
let shadowSyncScheduler: ShadowSyncScheduler | undefined;
|
|
86
|
+
const sessionSyncSchedulers: Map<string, SessionSyncScheduler> = new Map();
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Start a session sync scheduler for a project if it has session branch configured.
|
|
90
|
+
* Safe to call multiple times — skips if scheduler already exists for that project.
|
|
91
|
+
*/
|
|
92
|
+
async function startSessionSyncForProject(
|
|
93
|
+
projectPath: string,
|
|
94
|
+
pubsub: PubSubManager,
|
|
95
|
+
): Promise<void> {
|
|
96
|
+
if (sessionSyncSchedulers.has(projectPath)) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const { loadProjectConfig } = await import('../parser/config.js');
|
|
101
|
+
const { config } = await loadProjectConfig(projectPath);
|
|
102
|
+
const specDir = join(projectPath, config.shadow.directory);
|
|
103
|
+
|
|
104
|
+
// AC: @multi-directory-daemon ac-31, @manifest-discovery ac-6
|
|
105
|
+
// Use discovery API instead of hardcoding kynetic.yaml
|
|
106
|
+
const { findManifestInDir, readYamlFile } = await import('../parser/yaml.js');
|
|
107
|
+
const manifestPath = await findManifestInDir(specDir);
|
|
108
|
+
if (!manifestPath) {
|
|
109
|
+
// No manifest found — gracefully skip session sync for this project
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const manifest = await readYamlFile<{ sessions?: { storage?: string; branch?: string } }>(manifestPath);
|
|
113
|
+
|
|
114
|
+
if (manifest?.sessions?.storage === 'branch') {
|
|
115
|
+
const syncInterval = config.shadow.sync_interval;
|
|
116
|
+
|
|
117
|
+
if (syncInterval > 0) {
|
|
118
|
+
const { resolveSessionBranchConfig } = await import('../parser/session-branch.js');
|
|
119
|
+
const sessionConfig = resolveSessionBranchConfig(projectPath, manifest);
|
|
120
|
+
|
|
121
|
+
if (sessionConfig) {
|
|
122
|
+
const scheduler = new SessionSyncScheduler({
|
|
123
|
+
worktreeDir: sessionConfig.worktreeDir,
|
|
124
|
+
intervalSeconds: syncInterval,
|
|
125
|
+
branchName: sessionConfig.branchName,
|
|
126
|
+
pubsub,
|
|
127
|
+
});
|
|
128
|
+
scheduler.start();
|
|
129
|
+
sessionSyncSchedulers.set(projectPath, scheduler);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Stop session sync scheduler for a specific project.
|
|
137
|
+
*/
|
|
138
|
+
function stopSessionSyncForProject(projectPath: string): void {
|
|
139
|
+
const scheduler = sessionSyncSchedulers.get(projectPath);
|
|
140
|
+
if (scheduler) {
|
|
141
|
+
scheduler.stop();
|
|
142
|
+
sessionSyncSchedulers.delete(projectPath);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
94
145
|
|
|
95
146
|
/**
|
|
96
147
|
* Middleware to enforce localhost-only connections.
|
|
@@ -201,10 +252,16 @@ export async function createServer(options: ServerOptions) {
|
|
|
201
252
|
// AC-3: Enforce localhost-only connections
|
|
202
253
|
.onRequest(localhostOnly());
|
|
203
254
|
|
|
255
|
+
// Shared callback for all registration paths (middleware, projects API, WebSocket)
|
|
256
|
+
const onProjectRegistered = async (projectPath: string) => {
|
|
257
|
+
await startSessionSyncForProject(projectPath, pubsubManager);
|
|
258
|
+
};
|
|
259
|
+
|
|
204
260
|
// AC: @multi-directory-daemon ac-1, ac-2, ac-3 - Project context middleware
|
|
205
261
|
const { manager: projectContextManager, middleware: projectMiddleware } = projectContextMiddleware({
|
|
206
262
|
startupProject: startupProjectPath,
|
|
207
|
-
pubsub: pubsubManager
|
|
263
|
+
pubsub: pubsubManager,
|
|
264
|
+
onProjectRegistered,
|
|
208
265
|
});
|
|
209
266
|
|
|
210
267
|
// Store manager globally for shutdown
|
|
@@ -240,7 +297,13 @@ export async function createServer(options: ServerOptions) {
|
|
|
240
297
|
.use(createValidationRoutes())
|
|
241
298
|
|
|
242
299
|
// AC: @multi-directory-daemon ac-28, ac-29, ac-30 - Projects management endpoints
|
|
243
|
-
.use(createProjectsRoutes({
|
|
300
|
+
.use(createProjectsRoutes({
|
|
301
|
+
projectManager: projectContextManager,
|
|
302
|
+
onProjectRegistered,
|
|
303
|
+
onProjectUnregistered: (projectPath) => {
|
|
304
|
+
stopSessionSyncForProject(projectPath);
|
|
305
|
+
},
|
|
306
|
+
}))
|
|
244
307
|
|
|
245
308
|
// AC: @ui-session-stream ac-1, ac-4 - Session data endpoints
|
|
246
309
|
.use(createSessionRoutes())
|
|
@@ -248,6 +311,12 @@ export async function createServer(options: ServerOptions) {
|
|
|
248
311
|
// AC: @ui-plans-view ac-1 - Plans data endpoints
|
|
249
312
|
.use(createPlansRoutes())
|
|
250
313
|
|
|
314
|
+
// AC: @ui-api-aggregation ac-1, ac-2, ac-3 - Aggregation endpoints
|
|
315
|
+
.use(createAggregationRoutes())
|
|
316
|
+
|
|
317
|
+
// AC: @ui-api-ref-resolution ac-4, ac-5 - Lightweight ref index endpoint
|
|
318
|
+
.use(createRefsRoutes())
|
|
319
|
+
|
|
251
320
|
// AC: @agent-dispatch-engine ac-4 - Agent dispatch API endpoints
|
|
252
321
|
// AC: @daemon-agent-dispatch ac-3, ac-4 - Pass pubsub for WebSocket broadcast on invocation events
|
|
253
322
|
.use(createAgentDispatchRoutes({ pubsub: pubsubManager }))
|
|
@@ -255,14 +324,6 @@ export async function createServer(options: ServerOptions) {
|
|
|
255
324
|
// AC-4: WebSocket endpoint for real-time updates
|
|
256
325
|
.ws<ConnectionData>('/ws', {
|
|
257
326
|
beforeHandle({ request, store }) {
|
|
258
|
-
// AC: @multi-directory-daemon ac-21, ac-22, ac-23, ac-34 - Extract and validate project binding
|
|
259
|
-
// AC: @multi-directory-daemon ac-34 - Browser WebSocket API doesn't support custom headers,
|
|
260
|
-
// so we also accept project path as query parameter
|
|
261
|
-
const url = new URL(request.url, `http://${request.headers.get('host')}`);
|
|
262
|
-
const projectPath = request.headers.get('X-Kspec-Dir')
|
|
263
|
-
|| url.searchParams.get('project')
|
|
264
|
-
|| undefined;
|
|
265
|
-
|
|
266
327
|
// IMPORTANT: Do NOT return a value from ws beforeHandle.
|
|
267
328
|
// In Elysia 1.4 with derive middleware, returning a value short-circuits
|
|
268
329
|
// the WebSocket upgrade and sends the value as an HTTP 200 response.
|
|
@@ -275,30 +336,15 @@ export async function createServer(options: ServerOptions) {
|
|
|
275
336
|
return;
|
|
276
337
|
}
|
|
277
338
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
// AC: @multi-directory-daemon ac-4 - auto-register
|
|
285
|
-
projectContext = manager.registerProject(projectPath);
|
|
286
|
-
}
|
|
287
|
-
} else {
|
|
288
|
-
// AC: @multi-directory-daemon ac-22, ac-23 - Use default or reject
|
|
289
|
-
try {
|
|
290
|
-
projectContext = manager.getProject();
|
|
291
|
-
} catch (err: unknown) {
|
|
292
|
-
// AC: @multi-directory-daemon ac-23 - Reject when no default
|
|
293
|
-
if (err instanceof Error && err.message.includes('No default project configured')) {
|
|
294
|
-
throw new Error('No project specified');
|
|
295
|
-
}
|
|
296
|
-
throw err;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
339
|
+
const { resolvedPath } = resolveWebSocketProject({
|
|
340
|
+
request,
|
|
341
|
+
manager,
|
|
342
|
+
fallbackPath: startupProjectPath,
|
|
343
|
+
onProjectRegistered,
|
|
344
|
+
});
|
|
299
345
|
|
|
300
346
|
// Store resolved path for open() handler via WeakMap
|
|
301
|
-
wsProjectPaths.set(request,
|
|
347
|
+
wsProjectPaths.set(request, resolvedPath);
|
|
302
348
|
} catch (err: unknown) {
|
|
303
349
|
console.error(`[daemon] WebSocket connection rejected: ${err instanceof Error ? err.message : String(err)}`);
|
|
304
350
|
throw err;
|
|
@@ -364,6 +410,7 @@ export async function createServer(options: ServerOptions) {
|
|
|
364
410
|
// SPA fallback routes for client-side routing
|
|
365
411
|
// These catch paths like /tasks, /items, /inbox that don't have static files
|
|
366
412
|
const spaRoutes = [
|
|
413
|
+
'/',
|
|
367
414
|
'/tasks', '/tasks/*',
|
|
368
415
|
'/items', '/items/*',
|
|
369
416
|
'/inbox',
|
|
@@ -416,6 +463,44 @@ export async function createServer(options: ServerOptions) {
|
|
|
416
463
|
}
|
|
417
464
|
}
|
|
418
465
|
|
|
466
|
+
// AC: @config-shadow ac-12 - Start periodic shadow sync if remote tracking configured
|
|
467
|
+
if (startupProjectPath) {
|
|
468
|
+
try {
|
|
469
|
+
const { loadProjectConfig } = await import('../parser/config.js');
|
|
470
|
+
const { config } = await loadProjectConfig(startupProjectPath);
|
|
471
|
+
const syncInterval = config.shadow.sync_interval;
|
|
472
|
+
const worktreeDir = join(startupProjectPath, config.shadow.directory);
|
|
473
|
+
|
|
474
|
+
if (syncInterval > 0) {
|
|
475
|
+
shadowSyncScheduler = new ShadowSyncScheduler({
|
|
476
|
+
worktreeDir,
|
|
477
|
+
intervalSeconds: syncInterval,
|
|
478
|
+
shadowOptions: {
|
|
479
|
+
branchName: config.shadow.branch,
|
|
480
|
+
directory: config.shadow.directory,
|
|
481
|
+
remote: config.shadow.remote?.value,
|
|
482
|
+
remoteType: config.shadow.remote?.type,
|
|
483
|
+
},
|
|
484
|
+
pubsub: pubsubManager,
|
|
485
|
+
});
|
|
486
|
+
shadowSyncScheduler.start();
|
|
487
|
+
}
|
|
488
|
+
} catch (error) {
|
|
489
|
+
console.error('[daemon] Failed to initialize shadow sync scheduler:', error);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// AC: @session-branch-worktree ac-sync - Start periodic session branch sync if configured
|
|
494
|
+
// Session sync runs independently from kspec-meta sync — failures in one do not affect the other
|
|
495
|
+
if (startupProjectPath) {
|
|
496
|
+
try {
|
|
497
|
+
await startSessionSyncForProject(startupProjectPath, pubsubManager);
|
|
498
|
+
} catch (error) {
|
|
499
|
+
// Session sync init failure does not block daemon startup
|
|
500
|
+
console.error('[daemon] Failed to initialize session sync scheduler:', error);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
419
504
|
// AC: @daemon-server ac-13, ac-14 - Start heartbeat monitoring
|
|
420
505
|
heartbeatManager.start(pubsubManager.getAllConnections());
|
|
421
506
|
|
|
@@ -427,6 +512,15 @@ export async function createServer(options: ServerOptions) {
|
|
|
427
512
|
// Stop heartbeat monitoring
|
|
428
513
|
heartbeatManager.stop();
|
|
429
514
|
|
|
515
|
+
// AC: @config-shadow ac-12 - Stop shadow sync scheduler
|
|
516
|
+
shadowSyncScheduler?.stop();
|
|
517
|
+
|
|
518
|
+
// AC: @session-branch-worktree ac-sync - Stop all session sync schedulers
|
|
519
|
+
for (const scheduler of sessionSyncSchedulers.values()) {
|
|
520
|
+
scheduler.stop();
|
|
521
|
+
}
|
|
522
|
+
sessionSyncSchedulers.clear();
|
|
523
|
+
|
|
430
524
|
// AC: @agent-dispatch-engine ac-11 - Stop all dispatch engines before shutting down
|
|
431
525
|
await stopAllEngines();
|
|
432
526
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-export SessionSyncScheduler from its canonical location in src/parser/.
|
|
3
|
+
* The daemon server.ts imports from this file; the actual implementation
|
|
4
|
+
* lives in src/parser/session-sync-scheduler.ts so that both daemon runtime
|
|
5
|
+
* (via dist/parser/) and vitest tests can import the same production code.
|
|
6
|
+
*
|
|
7
|
+
* AC: @session-branch-worktree ac-sync
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export { SessionSyncScheduler } from '../parser/session-sync-scheduler.js';
|
|
11
|
+
export type { SessionSyncSchedulerOptions, SessionSyncPubSub } from '../parser/session-sync-scheduler.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-export ShadowSyncScheduler from its canonical location in src/parser/.
|
|
3
|
+
* The daemon server.ts imports from this file; the actual implementation
|
|
4
|
+
* lives in src/parser/shadow-sync-scheduler.ts so that both daemon runtime
|
|
5
|
+
* (via dist/parser/) and vitest tests can import the same production code.
|
|
6
|
+
*
|
|
7
|
+
* AC: @config-shadow ac-12
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export { ShadowSyncScheduler } from '../parser/shadow-sync-scheduler.js';
|
|
11
|
+
export type { ShadowSyncSchedulerOptions, ShadowSyncPubSub } from '../parser/shadow-sync-scheduler.js';
|