@kynetic-ai/spec 0.10.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 +150 -10
- package/dist/agent-runtime/dispatch.d.ts.map +1 -1
- package/dist/agent-runtime/dispatch.js +1248 -244
- 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 +172 -60
- 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/meta.d.ts.map +1 -1
- package/dist/cli/commands/meta.js +10 -1
- package/dist/cli/commands/meta.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 +107 -23
- package/dist/daemon/routes/aggregation.ts +184 -0
- package/dist/daemon/routes/inbox.ts +5 -0
- package/dist/daemon/routes/items.ts +167 -0
- package/dist/daemon/routes/meta.ts +141 -1
- package/dist/daemon/routes/plans.ts +147 -0
- 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 +581 -0
- package/dist/daemon/routes/tasks.ts +257 -2
- package/dist/daemon/routes/triage.ts +40 -1
- package/dist/daemon/routes/validation.ts +1 -1
- package/dist/daemon/server.ts +165 -50
- 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/alignment.d.ts.map +1 -1
- package/dist/parser/alignment.js +4 -2
- package/dist/parser/alignment.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 +663 -116
- package/dist/schema/meta.d.ts.map +1 -1
- package/dist/schema/meta.js +28 -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 +115 -71
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +357 -182
- 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/B25nWFyA.js +5 -0
- package/dist/web-ui/_app/immutable/chunks/B2bcA_Q_.js +1 -0
- 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/B8tYZKAE.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/BFGAyJjD.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/BG0850zf.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/BG8eSzAd.js +1 -0
- 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/{D1ArdqNb.js → Bp5pFYXL.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/BsJFsuAT.js +1 -0
- 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/C0w6WDm5.js +1 -0
- 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/CWUQwB9H.js +1 -0
- 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/CaAJD3dl.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{i-XnOIX0.js → ChB5iyEL.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/ChQD-6N8.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/{BCkp8Hs8.js → CqbsoCwA.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/DCeJW50p.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/DJtZNgcs.js +1 -0
- 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/DW_subyT.js +2 -0
- 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/Dg_zDpDS.js +1 -0
- 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/DqT6OH_u.js +2 -0
- 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/HNjs76Zz.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/HVMjDi4_.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/P0A_fJvS.js +1 -0
- 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/Xvwhx_F1.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/Yyz1XMQA.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/dh5HeqUr.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/fZMteyca.js +62 -0
- package/dist/web-ui/_app/immutable/chunks/{D28BF5MJ.js → gPrj-hqC.js} +1 -1
- package/dist/web-ui/_app/immutable/chunks/htcWMiYN.js +1 -0
- package/dist/web-ui/_app/immutable/chunks/oTsvd9y4.js +1 -0
- 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/y4GeEH6k.js +1 -0
- 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 -11
- package/package.json +14 -7
- 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.BxCxvrZR.css +0 -1
- package/dist/web-ui/_app/immutable/chunks/B-CZR0q8.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/B1IR5Su5.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/B_Cvvtc4.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/BtFaGGII.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/Bu8JVsCH.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/C87u-CNA.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/CrFkBTYp.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/D6RtLpzL.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/D7FHSgx2.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/DBXrsxZQ.js +0 -2
- package/dist/web-ui/_app/immutable/chunks/Da_hHMuA.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/Do6LchSF.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/DoNPtcAw.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/DtUbXRZz.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/DyFPRlLl.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/DzAP8lRM.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/DzVXElzN.js +0 -2
- package/dist/web-ui/_app/immutable/chunks/aoPBFken.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/laxtrUO3.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/q1nIWgqB.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/sTLbk5Nm.js +0 -1
- package/dist/web-ui/_app/immutable/chunks/vwKgQu5P.js +0 -5
- package/dist/web-ui/_app/immutable/entry/app.BCwMcqnT.js +0 -2
- package/dist/web-ui/_app/immutable/entry/start.wKCQH-tt.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/0.CjGVMG74.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/1.B6_AIPan.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/2.q4oCS7Ws.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/3.rTKZf9o2.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/4.DVIDRu1d.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/5.8PtPXIOd.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/6.ZZrTemy_.js +0 -1
- package/dist/web-ui/_app/immutable/nodes/7.IP-gxCxi.js +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import { markMutating } from "../command-annotations.js";
|
|
3
|
-
import { AlignmentIndex, addChildItem, buildIndexes, checkSlugUniqueness, createNote, createSpecItem, deleteSpecItem, findChildItems, findDescendantItems, findTraitImplementors, initContext, loadAllItems, loadMetaContext, loadAllTasks, patchSpecItems, ReferenceIndex, resolveMetaRef, shortestUniqueUlid, updateSpecItem, } from "../../parser/index.js";
|
|
3
|
+
import { AlignmentIndex, addProjectLevelTraitItem, addChildItem, buildIndexes, checkSlugUniqueness, createNote, createSpecItem, deleteSpecItem, findChildItems, findDescendantItems, findTraitImplementors, initContext, loadAllItems, loadMetaContext, loadAllTasks, patchSpecItems, ReferenceIndex, resolveMetaRef, shortestUniqueUlid, updateSpecItem, } from "../../parser/index.js";
|
|
4
4
|
import { commitIfShadow } from "../../parser/shadow.js";
|
|
5
5
|
import { SpecItemPatchSchema } from "../../schema/index.js";
|
|
6
6
|
import { ImplementationStatusSchema, MaturitySchema, } from "../../schema/common.js";
|
|
@@ -8,8 +8,22 @@ import { errors } from "../../strings/errors.js";
|
|
|
8
8
|
import { fieldLabels, sectionHeaders } from "../../strings/labels.js";
|
|
9
9
|
import { formatMatchedFields, grepItem } from "../../utils/grep.js";
|
|
10
10
|
import { EXIT_CODES } from "../exit-codes.js";
|
|
11
|
-
import { error, isJsonMode, output, success, warn } from "../output.js";
|
|
11
|
+
import { error, isJsonMode, output, showChangeDiff, success, warn } from "../output.js";
|
|
12
12
|
import { parseTagsArray } from "../parse-utils.js";
|
|
13
|
+
/**
|
|
14
|
+
* Serialize a LoadedSpecItem for JSON output.
|
|
15
|
+
* Strips internal fields (_sourceFile, _path), renames _ulid → ulid,
|
|
16
|
+
* and adds a ref field with @ prefix for the primary slug.
|
|
17
|
+
* AC: @trait-json-output ac-4
|
|
18
|
+
*/
|
|
19
|
+
function serializeSpecItemForJson(item) {
|
|
20
|
+
const { _sourceFile, _path, _ulid, ...rest } = item;
|
|
21
|
+
return {
|
|
22
|
+
ulid: _ulid,
|
|
23
|
+
ref: item.slugs.length > 0 ? `@${item.slugs[0]}` : `@${_ulid}`,
|
|
24
|
+
...rest,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
13
27
|
/**
|
|
14
28
|
* Format a spec item for display
|
|
15
29
|
*/
|
|
@@ -290,12 +304,9 @@ export function registerItemCommands(program) {
|
|
|
290
304
|
return;
|
|
291
305
|
}
|
|
292
306
|
output({
|
|
293
|
-
items: specItems,
|
|
307
|
+
items: specItems.map(serializeSpecItemForJson),
|
|
294
308
|
total: effectiveTotal,
|
|
295
309
|
showing: specItems.length,
|
|
296
|
-
grepPattern: options.grep,
|
|
297
|
-
tree: options.tree,
|
|
298
|
-
under: options.under,
|
|
299
310
|
}, () => {
|
|
300
311
|
if (options.tree) {
|
|
301
312
|
// AC: @module-scoped-item-listing ac-under-with-tree
|
|
@@ -347,7 +358,7 @@ export function registerItemCommands(program) {
|
|
|
347
358
|
}
|
|
348
359
|
// Build JSON output with inherited traits
|
|
349
360
|
const jsonOutput = {
|
|
350
|
-
...item,
|
|
361
|
+
...serializeSpecItemForJson(item),
|
|
351
362
|
inherited_traits: Array.from(traitsByTrait.values()).map(({ trait, acs }) => ({
|
|
352
363
|
ref: `@${trait.slug}`,
|
|
353
364
|
title: trait.title,
|
|
@@ -493,8 +504,9 @@ export function registerItemCommands(program) {
|
|
|
493
504
|
});
|
|
494
505
|
// kspec item add - create a new spec item under a parent
|
|
495
506
|
markMutating(item.command("add"))
|
|
496
|
-
.description("Create a new spec item under a parent")
|
|
497
|
-
.
|
|
507
|
+
.description("Create a new spec item under a parent or in project root")
|
|
508
|
+
.option("--under <ref>", "Parent item reference (e.g., @core-primitives)")
|
|
509
|
+
.option("--root", "Create at project root (trait items only)")
|
|
498
510
|
.requiredOption("--title <title>", "Item title")
|
|
499
511
|
.option("--type <type>", "Item type (feature, requirement, constraint, decision)", "feature")
|
|
500
512
|
.option("--slug <slug>", "Human-friendly slug")
|
|
@@ -507,22 +519,47 @@ export function registerItemCommands(program) {
|
|
|
507
519
|
Examples:
|
|
508
520
|
$ kspec item add --under @parent --title "Feature name" --type feature
|
|
509
521
|
$ kspec item add --under @parent --title "Multi-tag" --tag api public
|
|
510
|
-
$ kspec item add --under @parent --title "API endpoint" --trait @trait-api-endpoint
|
|
522
|
+
$ kspec item add --under @parent --title "API endpoint" --trait @trait-api-endpoint
|
|
523
|
+
$ kspec item add --root --type trait --title "JSON Output" --slug trait-json-output`)
|
|
511
524
|
.action(async (options) => {
|
|
512
525
|
try {
|
|
513
526
|
const ctx = await initContext();
|
|
514
527
|
const { refIndex, items } = await buildIndexes(ctx);
|
|
515
|
-
|
|
516
|
-
const
|
|
517
|
-
|
|
518
|
-
error(
|
|
519
|
-
process.exit(EXIT_CODES.
|
|
528
|
+
const isRootAdd = Boolean(options.root);
|
|
529
|
+
const itemType = options.type;
|
|
530
|
+
const exitWithUsageGuidance = (message, suggestion, details) => {
|
|
531
|
+
error(message, { suggestion, ...details });
|
|
532
|
+
process.exit(EXIT_CODES.USAGE_ERROR);
|
|
533
|
+
};
|
|
534
|
+
if (options.under && isRootAdd) {
|
|
535
|
+
exitWithUsageGuidance(`Cannot use --under (${options.under}) and --root together`, "Use --root only for project-level traits in kynetic.yaml, or remove --root and keep --under for nested items.", {
|
|
536
|
+
field: "under",
|
|
537
|
+
value: options.under,
|
|
538
|
+
conflicting_field: "root",
|
|
539
|
+
});
|
|
520
540
|
}
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
541
|
+
if (!options.under && !isRootAdd) {
|
|
542
|
+
exitWithUsageGuidance("item add requires either --under <ref> or --root", "Use --under @parent to create a nested item, or use --root --type trait to create a project-level trait in kynetic.yaml.");
|
|
543
|
+
}
|
|
544
|
+
if (isRootAdd && itemType !== "trait") {
|
|
545
|
+
exitWithUsageGuidance(`--root is only supported for --type trait (received: ${itemType || "undefined"})`, "Change --type to trait for project-level creation, or remove --root and create the item under a parent with --under.", {
|
|
546
|
+
field: "type",
|
|
547
|
+
value: itemType || null,
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
let parent = null;
|
|
551
|
+
if (options.under) {
|
|
552
|
+
const parentResult = refIndex.resolve(options.under);
|
|
553
|
+
if (!parentResult.ok) {
|
|
554
|
+
error(errors.reference.itemNotFound(options.under));
|
|
555
|
+
process.exit(EXIT_CODES.ERROR);
|
|
556
|
+
}
|
|
557
|
+
parent = parentResult.item;
|
|
558
|
+
// Check it's not a task
|
|
559
|
+
if ("status" in parent && typeof parent.status === "string") {
|
|
560
|
+
error(errors.reference.parentIsTask(options.under));
|
|
561
|
+
process.exit(EXIT_CODES.ERROR);
|
|
562
|
+
}
|
|
526
563
|
}
|
|
527
564
|
// Check slug uniqueness if provided
|
|
528
565
|
if (options.slug) {
|
|
@@ -565,7 +602,7 @@ Examples:
|
|
|
565
602
|
}
|
|
566
603
|
const input = {
|
|
567
604
|
title: options.title,
|
|
568
|
-
type:
|
|
605
|
+
type: itemType,
|
|
569
606
|
slugs: options.slug ? [options.slug] : [],
|
|
570
607
|
priority: options.priority,
|
|
571
608
|
tags: parseTagsArray(options.tag),
|
|
@@ -578,20 +615,32 @@ Examples:
|
|
|
578
615
|
notes: [],
|
|
579
616
|
};
|
|
580
617
|
const newItem = createSpecItem(input);
|
|
581
|
-
const
|
|
618
|
+
const addResult = isRootAdd
|
|
619
|
+
? await addProjectLevelTraitItem(ctx, newItem)
|
|
620
|
+
: await addChildItem(ctx, parent, newItem, options.as);
|
|
621
|
+
const resultItem = {
|
|
622
|
+
...addResult.item,
|
|
623
|
+
...(isRootAdd
|
|
624
|
+
? {
|
|
625
|
+
_sourceFile: ctx.manifestPath,
|
|
626
|
+
_path: addResult.path,
|
|
627
|
+
}
|
|
628
|
+
: {}),
|
|
629
|
+
};
|
|
582
630
|
// Build index including the new item for accurate short ULID
|
|
583
|
-
const index = new ReferenceIndex([], [...items,
|
|
584
|
-
const itemSlug =
|
|
585
|
-
|
|
631
|
+
const index = new ReferenceIndex([], [...items, resultItem]);
|
|
632
|
+
const itemSlug = resultItem.slugs?.[0] || index.shortUlid(resultItem._ulid);
|
|
633
|
+
const itemRef = `@${itemSlug}`;
|
|
586
634
|
await commitIfShadow(ctx.shadow, "item-add", itemSlug);
|
|
587
|
-
success(
|
|
588
|
-
item:
|
|
589
|
-
|
|
635
|
+
success(isRootAdd
|
|
636
|
+
? `Created item: ${itemRef} in project root traits`
|
|
637
|
+
: `Created item: ${index.shortUlid(resultItem._ulid)} under @${parent.slugs[0] || index.shortUlid(parent._ulid)}`, {
|
|
638
|
+
item: resultItem,
|
|
639
|
+
path: addResult.path,
|
|
590
640
|
});
|
|
591
641
|
// Derive hint
|
|
592
642
|
if (!isJsonMode()) {
|
|
593
|
-
const refSlug =
|
|
594
|
-
index.shortUlid(result.item._ulid);
|
|
643
|
+
const refSlug = resultItem.slugs?.[0] || index.shortUlid(resultItem._ulid);
|
|
595
644
|
console.log(chalk.gray(`\nDerive implementation task? kspec derive @${refSlug}`));
|
|
596
645
|
}
|
|
597
646
|
}
|
|
@@ -615,20 +664,27 @@ Examples:
|
|
|
615
664
|
.option("--verified-by <agent-ref>", "Set verified_by (for retrospective specs)")
|
|
616
665
|
.option("--verified-at <iso-timestamp>", "Set verified_at (defaults to now if --verified-by provided)")
|
|
617
666
|
.option("--trait <trait...>", "Set traits (replaces existing)")
|
|
667
|
+
.option("--add-trait <trait...>", "Add traits (appends to existing)")
|
|
668
|
+
.option("--remove-trait <trait...>", "Remove specific traits")
|
|
669
|
+
.option("--clear-traits", "Clear all traits")
|
|
618
670
|
.option("--relates-to <ref>", "Add a relates_to reference")
|
|
619
671
|
.option("--implements <ref>", "Add an implements reference")
|
|
620
672
|
.option("--depends-on <ref>", "Add a depends_on reference")
|
|
621
673
|
.option("--clear-relates-to", "Clear all relates_to references")
|
|
622
674
|
.option("--clear-implements", "Clear all implements references")
|
|
623
675
|
.option("--clear-depends-on", "Clear all depends_on references")
|
|
676
|
+
.option("--no-cascade", "Skip child status cascade prompt (apply change only to target item)")
|
|
624
677
|
.addHelpText("after", `
|
|
625
678
|
Examples:
|
|
626
679
|
$ kspec item set @item-ref --title "New title"
|
|
627
680
|
$ kspec item set @item-ref --tag api internal security
|
|
628
|
-
$ kspec item set @item-ref --trait reusable testable
|
|
681
|
+
$ kspec item set @item-ref --trait @reusable @testable # replaces all traits
|
|
682
|
+
$ kspec item set @item-ref --add-trait @json-output # appends trait
|
|
683
|
+
$ kspec item set @item-ref --remove-trait @old-trait # removes trait
|
|
629
684
|
$ kspec item set @item-ref --relates-to @other-item
|
|
630
685
|
$ kspec item set @item-ref --implements @feature-spec
|
|
631
|
-
$ kspec item set @item-ref --depends-on @prereq-spec
|
|
686
|
+
$ kspec item set @item-ref --depends-on @prereq-spec
|
|
687
|
+
$ kspec item set @item-ref --status implemented --no-cascade`)
|
|
632
688
|
.action(async (ref, options) => {
|
|
633
689
|
try {
|
|
634
690
|
const ctx = await initContext();
|
|
@@ -678,6 +734,41 @@ Examples:
|
|
|
678
734
|
error("Cannot use --depends-on and --clear-depends-on together");
|
|
679
735
|
process.exit(EXIT_CODES.USAGE_ERROR);
|
|
680
736
|
}
|
|
737
|
+
// Mutual exclusivity for trait flags
|
|
738
|
+
const traitFlagCount = [options.trait, options.addTrait, options.removeTrait, options.clearTraits].filter(Boolean).length;
|
|
739
|
+
if (traitFlagCount > 1) {
|
|
740
|
+
error("Cannot combine --trait, --add-trait, --remove-trait, and --clear-traits. Use only one at a time.");
|
|
741
|
+
process.exit(EXIT_CODES.USAGE_ERROR);
|
|
742
|
+
}
|
|
743
|
+
// Helper to validate and canonicalize a list of trait refs
|
|
744
|
+
const validateTraitRefs = (traitRefs) => {
|
|
745
|
+
const validated = [];
|
|
746
|
+
const seenUlids = new Set();
|
|
747
|
+
let hasErrors = false;
|
|
748
|
+
for (const traitRef of traitRefs) {
|
|
749
|
+
const traitResult = refIndex.resolve(traitRef);
|
|
750
|
+
if (!traitResult.ok) {
|
|
751
|
+
error(`Trait not found: ${traitRef}`);
|
|
752
|
+
hasErrors = true;
|
|
753
|
+
continue;
|
|
754
|
+
}
|
|
755
|
+
const traitItem = traitResult.item;
|
|
756
|
+
if (traitItem.type !== "trait") {
|
|
757
|
+
error(`${traitRef} is not a trait (type: ${traitItem.type})`);
|
|
758
|
+
hasErrors = true;
|
|
759
|
+
continue;
|
|
760
|
+
}
|
|
761
|
+
if (seenUlids.has(traitItem._ulid))
|
|
762
|
+
continue;
|
|
763
|
+
seenUlids.add(traitItem._ulid);
|
|
764
|
+
const canonicalRef = `@${traitItem.slugs[0] || traitItem._ulid}`;
|
|
765
|
+
validated.push(canonicalRef);
|
|
766
|
+
}
|
|
767
|
+
if (hasErrors) {
|
|
768
|
+
process.exit(EXIT_CODES.NOT_FOUND);
|
|
769
|
+
}
|
|
770
|
+
return validated;
|
|
771
|
+
};
|
|
681
772
|
// Helper to validate relationship refs (must exist and be a spec item, not a task)
|
|
682
773
|
// Returns { ulid, canonicalRef } for deduplication and user-friendly storage
|
|
683
774
|
const validateRelationshipRef = (refStr, flagName) => {
|
|
@@ -744,8 +835,46 @@ Examples:
|
|
|
744
835
|
updates.priority = options.priority;
|
|
745
836
|
if (options.tag)
|
|
746
837
|
updates.tags = parseTagsArray(options.tag);
|
|
747
|
-
|
|
748
|
-
|
|
838
|
+
// Handle trait mutations (--trait replaces, --add-trait appends, --remove-trait removes, --clear-traits clears)
|
|
839
|
+
if (options.trait) {
|
|
840
|
+
updates.traits = validateTraitRefs(options.trait);
|
|
841
|
+
}
|
|
842
|
+
else if (options.addTrait) {
|
|
843
|
+
const validated = validateTraitRefs(options.addTrait);
|
|
844
|
+
const current = foundItem.traits || [];
|
|
845
|
+
// Resolve existing traits to ULIDs for deduplication
|
|
846
|
+
const existingUlids = new Set();
|
|
847
|
+
for (const ref of current) {
|
|
848
|
+
const result = refIndex.resolve(ref);
|
|
849
|
+
if (result.ok)
|
|
850
|
+
existingUlids.add(result.ulid);
|
|
851
|
+
}
|
|
852
|
+
const newTraits = validated.filter((ref) => {
|
|
853
|
+
const result = refIndex.resolve(ref);
|
|
854
|
+
return result.ok && !existingUlids.has(result.ulid);
|
|
855
|
+
});
|
|
856
|
+
if (newTraits.length > 0) {
|
|
857
|
+
updates.traits = [...current, ...newTraits];
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
else if (options.removeTrait) {
|
|
861
|
+
const validated = validateTraitRefs(options.removeTrait);
|
|
862
|
+
const current = foundItem.traits || [];
|
|
863
|
+
// Resolve removal targets to ULIDs
|
|
864
|
+
const removeUlids = new Set();
|
|
865
|
+
for (const ref of validated) {
|
|
866
|
+
const result = refIndex.resolve(ref);
|
|
867
|
+
if (result.ok)
|
|
868
|
+
removeUlids.add(result.ulid);
|
|
869
|
+
}
|
|
870
|
+
updates.traits = current.filter((ref) => {
|
|
871
|
+
const result = refIndex.resolve(ref);
|
|
872
|
+
return !result.ok || !removeUlids.has(result.ulid);
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
else if (options.clearTraits) {
|
|
876
|
+
updates.traits = [];
|
|
877
|
+
}
|
|
749
878
|
if (options.description)
|
|
750
879
|
updates.description = options.description;
|
|
751
880
|
// AC: @implementation-states ac-reject-invalid
|
|
@@ -825,18 +954,35 @@ Examples:
|
|
|
825
954
|
warn("No updates specified");
|
|
826
955
|
return;
|
|
827
956
|
}
|
|
957
|
+
// Build before→after changes for display
|
|
958
|
+
const changes = [];
|
|
959
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
960
|
+
const before = foundItem[key];
|
|
961
|
+
// Only record if value actually changed
|
|
962
|
+
if (JSON.stringify(before) !== JSON.stringify(value)) {
|
|
963
|
+
changes.push({ field: key, before, after: value });
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
if (changes.length === 0) {
|
|
967
|
+
warn("No changes: values are already set to the specified values");
|
|
968
|
+
return;
|
|
969
|
+
}
|
|
828
970
|
const updated = await updateSpecItem(ctx, foundItem, updates);
|
|
829
971
|
const itemSlug = foundItem.slugs[0] || refIndex.shortUlid(foundItem._ulid);
|
|
830
972
|
// Handle cascade for implementation status updates
|
|
831
973
|
const updatedItems = [updated];
|
|
832
|
-
if (options.status) {
|
|
974
|
+
if (options.status && options.cascade !== false) {
|
|
833
975
|
const cascadeResult = await handleStatusCascade(ctx, updated, options.status, items, refIndex);
|
|
834
976
|
updatedItems.push(...cascadeResult);
|
|
835
977
|
}
|
|
836
978
|
await commitIfShadow(ctx.shadow, "item-set", itemSlug);
|
|
837
|
-
|
|
979
|
+
const changedFields = changes.map((c) => c.field).join(", ");
|
|
980
|
+
success(`Updated item: ${refIndex.shortUlid(updated._ulid)} (${changedFields})`, {
|
|
838
981
|
item: updated,
|
|
982
|
+
changes,
|
|
839
983
|
});
|
|
984
|
+
// Show before→after diff in text mode
|
|
985
|
+
showChangeDiff(changes);
|
|
840
986
|
// Derive hint
|
|
841
987
|
if (!isJsonMode()) {
|
|
842
988
|
const refSlug = updated.slugs?.[0] || refIndex.shortUlid(updated._ulid);
|
|
@@ -1403,9 +1549,10 @@ Examples:
|
|
|
1403
1549
|
error(errors.conflict.acIdAlreadyExists(options.id));
|
|
1404
1550
|
process.exit(EXIT_CODES.CONFLICT);
|
|
1405
1551
|
}
|
|
1406
|
-
// Build updated AC
|
|
1552
|
+
// Build updated AC and track before→after changes
|
|
1407
1553
|
const updatedAc = [...existingAc];
|
|
1408
|
-
const
|
|
1554
|
+
const originalAc = { ...updatedAc[acIndex] };
|
|
1555
|
+
const changes = [];
|
|
1409
1556
|
updatedAc[acIndex] = {
|
|
1410
1557
|
...updatedAc[acIndex],
|
|
1411
1558
|
...(options.id && { id: options.id }),
|
|
@@ -1413,19 +1560,30 @@ Examples:
|
|
|
1413
1560
|
...(options.when && { when: options.when }),
|
|
1414
1561
|
...(options.then && { then: options.then }),
|
|
1415
1562
|
};
|
|
1416
|
-
if (options.id)
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
if (options.
|
|
1423
|
-
|
|
1563
|
+
if (options.id && options.id !== originalAc.id) {
|
|
1564
|
+
changes.push({ field: "id", before: originalAc.id, after: options.id });
|
|
1565
|
+
}
|
|
1566
|
+
if (options.given && options.given !== originalAc.given) {
|
|
1567
|
+
changes.push({ field: "given", before: originalAc.given, after: options.given });
|
|
1568
|
+
}
|
|
1569
|
+
if (options.when && options.when !== originalAc.when) {
|
|
1570
|
+
changes.push({ field: "when", before: originalAc.when, after: options.when });
|
|
1571
|
+
}
|
|
1572
|
+
if (options.then && options.then !== originalAc.then) {
|
|
1573
|
+
changes.push({ field: "then", before: originalAc.then, after: options.then });
|
|
1574
|
+
}
|
|
1575
|
+
if (changes.length === 0) {
|
|
1576
|
+
warn("No changes: values are already set to the specified values");
|
|
1577
|
+
return;
|
|
1578
|
+
}
|
|
1424
1579
|
// Update item
|
|
1425
1580
|
await updateSpecItem(ctx, item, { acceptance_criteria: updatedAc });
|
|
1426
1581
|
const itemSlug = item.slugs[0] || refIndex.shortUlid(item._ulid);
|
|
1427
1582
|
await commitIfShadow(ctx.shadow, "item-ac-set", itemSlug);
|
|
1428
|
-
|
|
1583
|
+
const changedFields = changes.map((c) => c.field).join(", ");
|
|
1584
|
+
success(`Updated acceptance criterion: ${acId} on @${itemSlug} (${changedFields})`, { ac: updatedAc[acIndex], changes });
|
|
1585
|
+
// Show before→after diff in text mode
|
|
1586
|
+
showChangeDiff(changes);
|
|
1429
1587
|
}
|
|
1430
1588
|
catch (err) {
|
|
1431
1589
|
error(errors.failures.updateAc, err);
|