@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
|
@@ -23,8 +23,10 @@ import * as os from "node:os";
|
|
|
23
23
|
import * as path from "node:path";
|
|
24
24
|
import * as readline from "node:readline/promises";
|
|
25
25
|
import chalk from "chalk";
|
|
26
|
-
import { getGitRoot, getShadowStatus, repairShadow, SHADOW_BRANCH_NAME, } from "../../parser/shadow.js";
|
|
26
|
+
import { getGitRoot, getShadowStatus, repairShadow, remoteShadowBranchExists, SHADOW_BRANCH_NAME, SHADOW_WORKTREE_DIR, SESSIONS_WORKTREE_DIR, ensureSessionsGitignore, ensureShadowSessionsGitignore, needsSessionsGitignore, needsShadowSessionsGitignore, } from "../../parser/shadow.js";
|
|
27
|
+
import { loadProjectConfig } from "../../parser/config.js";
|
|
27
28
|
import { detectAgentFromEnv, } from "../../parser/agent-detection.js";
|
|
29
|
+
import { getSetupStatus as getSharedSetupStatus, } from "../../parser/setup-status.js";
|
|
28
30
|
import { errors } from "../../strings/index.js";
|
|
29
31
|
import { EXIT_CODES } from "../exit-codes.js";
|
|
30
32
|
import { error, output, success, warn } from "../output.js";
|
|
@@ -45,6 +47,7 @@ function debugLog(message, detail) {
|
|
|
45
47
|
const SETUP_AGENT_OVERRIDES = [
|
|
46
48
|
"claude-code",
|
|
47
49
|
"cline",
|
|
50
|
+
"droid",
|
|
48
51
|
"cursor",
|
|
49
52
|
"windsurf",
|
|
50
53
|
"unknown",
|
|
@@ -65,6 +68,13 @@ function buildDetectedAgent(type) {
|
|
|
65
68
|
configPath: path.join(os.homedir(), ".claude", "settings.json"),
|
|
66
69
|
};
|
|
67
70
|
}
|
|
71
|
+
if (type === "droid") {
|
|
72
|
+
return {
|
|
73
|
+
type,
|
|
74
|
+
confidence: "high",
|
|
75
|
+
configPath: path.join(os.homedir(), ".factory", "settings.json"),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
68
78
|
return { type, confidence: "high" };
|
|
69
79
|
}
|
|
70
80
|
/**
|
|
@@ -86,6 +96,13 @@ export function detectAgent() {
|
|
|
86
96
|
configPath: path.join(os.homedir(), ".claude", "settings.json"),
|
|
87
97
|
};
|
|
88
98
|
}
|
|
99
|
+
if (existsSync(path.join(os.homedir(), ".factory"))) {
|
|
100
|
+
return {
|
|
101
|
+
type: "droid",
|
|
102
|
+
confidence: "low",
|
|
103
|
+
configPath: path.join(os.homedir(), ".factory", "settings.json"),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
89
106
|
return detected;
|
|
90
107
|
}
|
|
91
108
|
/**
|
|
@@ -137,8 +154,9 @@ const OLD_GUARD_SCRIPTS = [
|
|
|
137
154
|
/**
|
|
138
155
|
* Install hooks to project-level Claude Code settings (.claude/settings.json)
|
|
139
156
|
* AC: @enhanced-setup ac-2 - all hook entries present
|
|
157
|
+
* AC: @project-config ac-hooks-section — respects per-hook enable/disable from config
|
|
140
158
|
*/
|
|
141
|
-
async function installClaudeCodeHooks(projectDir, dryRun = false) {
|
|
159
|
+
async function installClaudeCodeHooks(projectDir, dryRun = false, hooksPrefs) {
|
|
142
160
|
const configPath = path.join(projectDir, ".claude", "settings.json");
|
|
143
161
|
const configDir = path.dirname(configPath);
|
|
144
162
|
const hooksDir = path.join(projectDir, ".claude", "hooks");
|
|
@@ -165,48 +183,89 @@ async function installClaudeCodeHooks(projectDir, dryRun = false) {
|
|
|
165
183
|
}
|
|
166
184
|
// Get or create hooks object
|
|
167
185
|
const hooks = config.hooks || {};
|
|
168
|
-
//
|
|
186
|
+
// AC: @project-config ac-hooks-section — prompt-check independently controllable
|
|
187
|
+
// Default: enabled (lightweight spec-first reminder)
|
|
188
|
+
const promptCheckEnabled = hooksPrefs?.prompt_check ?? true;
|
|
169
189
|
const promptCheckCommand = "kspec session prompt-check";
|
|
170
190
|
const existingPromptHooks = hooks.UserPromptSubmit;
|
|
171
191
|
const promptAlreadyInstalled = existingPromptHooks?.some((entry) => entry.hooks?.some((hook) => hook.command?.includes("session prompt-check")));
|
|
172
|
-
if (
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
192
|
+
if (promptCheckEnabled) {
|
|
193
|
+
if (!promptAlreadyInstalled) {
|
|
194
|
+
hooks.UserPromptSubmit = [
|
|
195
|
+
...(existingPromptHooks || []),
|
|
196
|
+
{
|
|
197
|
+
hooks: [
|
|
198
|
+
{
|
|
199
|
+
type: "command",
|
|
200
|
+
command: promptCheckCommand,
|
|
201
|
+
},
|
|
202
|
+
],
|
|
203
|
+
},
|
|
204
|
+
];
|
|
205
|
+
result.promptCheck = true;
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
result.promptCheck = true; // Already configured
|
|
209
|
+
}
|
|
185
210
|
}
|
|
186
211
|
else {
|
|
187
|
-
|
|
212
|
+
// AC: @project-config ac-hooks-section — remove if disabled and previously installed
|
|
213
|
+
if (promptAlreadyInstalled) {
|
|
214
|
+
const filtered = (existingPromptHooks || []).map((entry) => ({
|
|
215
|
+
...entry,
|
|
216
|
+
hooks: entry.hooks?.filter((hook) => !hook.command?.includes("session prompt-check")),
|
|
217
|
+
})).filter((entry) => entry.hooks && entry.hooks.length > 0);
|
|
218
|
+
if (filtered.length > 0) {
|
|
219
|
+
hooks.UserPromptSubmit = filtered;
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
delete hooks.UserPromptSubmit;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
result.promptCheck = false;
|
|
188
226
|
}
|
|
189
|
-
//
|
|
227
|
+
// AC: @project-config ac-hooks-section — checkpoint independently controllable
|
|
228
|
+
// Default: disabled (dispatch handles task lifecycle)
|
|
229
|
+
const checkpointEnabled = hooksPrefs?.checkpoint ?? false;
|
|
190
230
|
const stopHookCommand = "kspec session checkpoint --json";
|
|
191
231
|
const existingStopHooks = hooks.Stop;
|
|
192
232
|
const stopAlreadyInstalled = existingStopHooks?.some((entry) => entry.hooks?.some((hook) => hook.command?.includes("session checkpoint")));
|
|
193
|
-
if (
|
|
194
|
-
hooks
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
233
|
+
if (checkpointEnabled) {
|
|
234
|
+
// AC: @project-config ac-hooks-section — install when enabled
|
|
235
|
+
if (!stopAlreadyInstalled) {
|
|
236
|
+
hooks.Stop = [
|
|
237
|
+
...(existingStopHooks || []),
|
|
238
|
+
{
|
|
239
|
+
matcher: "",
|
|
240
|
+
hooks: [
|
|
241
|
+
{
|
|
242
|
+
type: "command",
|
|
243
|
+
command: stopHookCommand,
|
|
244
|
+
},
|
|
245
|
+
],
|
|
246
|
+
},
|
|
247
|
+
];
|
|
248
|
+
result.stop = true;
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
result.stop = true; // Already configured
|
|
252
|
+
}
|
|
207
253
|
}
|
|
208
254
|
else {
|
|
209
|
-
|
|
255
|
+
// AC: @project-config ac-hooks-section — remove if disabled and previously installed
|
|
256
|
+
if (stopAlreadyInstalled) {
|
|
257
|
+
const filtered = (existingStopHooks || []).map((entry) => ({
|
|
258
|
+
...entry,
|
|
259
|
+
hooks: entry.hooks?.filter((hook) => !hook.command?.includes("session checkpoint")),
|
|
260
|
+
})).filter((entry) => entry.hooks && entry.hooks.length > 0);
|
|
261
|
+
if (filtered.length > 0) {
|
|
262
|
+
hooks.Stop = filtered;
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
delete hooks.Stop;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
result.stop = false;
|
|
210
269
|
}
|
|
211
270
|
// AC: @enhanced-setup ac-2 - Install PreToolUse hooks with guards
|
|
212
271
|
// AC: @native-guard-commands ac-setup-native - use native kspec guard worktree
|
|
@@ -352,6 +411,8 @@ function getDefaultAuthor(agentType) {
|
|
|
352
411
|
return "@gemini";
|
|
353
412
|
case "codex-cli":
|
|
354
413
|
return "@codex";
|
|
414
|
+
case "droid":
|
|
415
|
+
return "@droid";
|
|
355
416
|
case "aider":
|
|
356
417
|
return "@aider";
|
|
357
418
|
case "opencode":
|
|
@@ -391,19 +452,30 @@ async function ensureWorktree(autoWorktree) {
|
|
|
391
452
|
// Not in a git repo, skip worktree check
|
|
392
453
|
return true;
|
|
393
454
|
}
|
|
394
|
-
const
|
|
455
|
+
const { config } = await loadProjectConfig(projectRoot, projectRoot);
|
|
456
|
+
const shadowOptions = {
|
|
457
|
+
branchName: config.shadow.branch,
|
|
458
|
+
directory: config.shadow.directory,
|
|
459
|
+
remote: config.shadow.remote?.value,
|
|
460
|
+
remoteType: config.shadow.remote?.type,
|
|
461
|
+
};
|
|
462
|
+
const branchName = shadowOptions.branchName || SHADOW_BRANCH_NAME;
|
|
463
|
+
const worktreeDir = shadowOptions.directory || SHADOW_WORKTREE_DIR;
|
|
464
|
+
const status = await getShadowStatus(projectRoot, shadowOptions);
|
|
465
|
+
const remoteHasShadow = await remoteShadowBranchExists(projectRoot, shadowOptions);
|
|
466
|
+
const recoverableShadow = status.branchExists || remoteHasShadow;
|
|
395
467
|
// AC: worktree-already-exists - if already valid, skip
|
|
396
468
|
if (status.healthy) {
|
|
397
469
|
return true;
|
|
398
470
|
}
|
|
399
|
-
// AC: detect-existing-repo -
|
|
400
|
-
if (status.
|
|
471
|
+
// AC: detect-existing-repo - existing shadow state but missing/unhealthy worktree
|
|
472
|
+
if (recoverableShadow && (!status.worktreeExists || !status.worktreeLinked)) {
|
|
401
473
|
// AC: auto-worktree-flag - auto-create if flag set
|
|
402
474
|
if (autoWorktree) {
|
|
403
|
-
console.log(`Detected ${
|
|
404
|
-
const result = await repairShadow(projectRoot);
|
|
475
|
+
console.log(`Detected ${branchName} shadow state without a healthy ${worktreeDir} worktree. Creating...`);
|
|
476
|
+
const result = await repairShadow(projectRoot, shadowOptions);
|
|
405
477
|
if (result.success) {
|
|
406
|
-
success(
|
|
478
|
+
success(`Created ${worktreeDir} worktree`);
|
|
407
479
|
return true;
|
|
408
480
|
}
|
|
409
481
|
else {
|
|
@@ -412,12 +484,12 @@ async function ensureWorktree(autoWorktree) {
|
|
|
412
484
|
}
|
|
413
485
|
}
|
|
414
486
|
// AC: detect-existing-repo - prompt user
|
|
415
|
-
const shouldCreate = await promptYesNo(`${
|
|
487
|
+
const shouldCreate = await promptYesNo(`${branchName} shadow state exists but ${worktreeDir} worktree is missing or unhealthy. Create it? (y/N)`);
|
|
416
488
|
if (shouldCreate) {
|
|
417
|
-
console.log(
|
|
418
|
-
const result = await repairShadow(projectRoot);
|
|
489
|
+
console.log(`Creating ${worktreeDir} worktree...`);
|
|
490
|
+
const result = await repairShadow(projectRoot, shadowOptions);
|
|
419
491
|
if (result.success) {
|
|
420
|
-
success(
|
|
492
|
+
success(`Created ${worktreeDir} worktree`);
|
|
421
493
|
return true;
|
|
422
494
|
}
|
|
423
495
|
else {
|
|
@@ -474,6 +546,13 @@ function printManualInstructions(agentType) {
|
|
|
474
546
|
console.log(`set = { KSPEC_AUTHOR = "${author}" }`);
|
|
475
547
|
console.log("```");
|
|
476
548
|
break;
|
|
549
|
+
case "droid":
|
|
550
|
+
console.log("Add to .factory/settings.json:");
|
|
551
|
+
console.log("```json");
|
|
552
|
+
console.log(JSON.stringify({ env: { KSPEC_AUTHOR: author } }, null, 2));
|
|
553
|
+
console.log("```");
|
|
554
|
+
console.log("\nDroid reads project environment variables from the env section of .factory/settings.json.");
|
|
555
|
+
break;
|
|
477
556
|
case "opencode":
|
|
478
557
|
console.log("Add to ~/.config/opencode/opencode.json:");
|
|
479
558
|
console.log("```json");
|
|
@@ -494,210 +573,6 @@ function printManualInstructions(agentType) {
|
|
|
494
573
|
console.log("\nOr add to your shell profile (~/.bashrc, ~/.zshrc, etc.)");
|
|
495
574
|
}
|
|
496
575
|
}
|
|
497
|
-
/**
|
|
498
|
-
* Check the current setup status
|
|
499
|
-
* AC: @enhanced-setup ac-7, ac-8
|
|
500
|
-
*/
|
|
501
|
-
async function getSetupStatus(projectDir, agentOverride) {
|
|
502
|
-
const detected = agentOverride
|
|
503
|
-
? buildDetectedAgent(agentOverride)
|
|
504
|
-
: detectAgent();
|
|
505
|
-
const configPath = path.join(projectDir, ".claude", "settings.json");
|
|
506
|
-
const hooksDir = path.join(projectDir, ".claude", "hooks");
|
|
507
|
-
const agentsMdPath = path.join(projectDir, "kspec-agents.md");
|
|
508
|
-
const hashPath = path.join(projectDir, ".kspec", ".kspec-agents-hash");
|
|
509
|
-
const skillsDir = path.join(projectDir, ".claude", "skills");
|
|
510
|
-
// Check hooks
|
|
511
|
-
const hooks = {
|
|
512
|
-
promptCheck: false,
|
|
513
|
-
stop: false,
|
|
514
|
-
preToolUse: false,
|
|
515
|
-
guardsPresent: [],
|
|
516
|
-
};
|
|
517
|
-
try {
|
|
518
|
-
const configContent = await fs.readFile(configPath, "utf-8");
|
|
519
|
-
const config = JSON.parse(configContent);
|
|
520
|
-
const hooksConfig = config.hooks || {};
|
|
521
|
-
// Check UserPromptSubmit
|
|
522
|
-
const promptHooks = hooksConfig.UserPromptSubmit;
|
|
523
|
-
hooks.promptCheck = promptHooks?.some((entry) => entry.hooks?.some((h) => h.command?.includes("prompt-check"))) ?? false;
|
|
524
|
-
// Check Stop
|
|
525
|
-
const stopHooks = hooksConfig.Stop;
|
|
526
|
-
hooks.stop = stopHooks?.some((entry) => entry.hooks?.some((h) => h.command?.includes("checkpoint"))) ?? false;
|
|
527
|
-
// Check PreToolUse — look for native kspec guard worktree command
|
|
528
|
-
const preToolUseHooks = hooksConfig.PreToolUse;
|
|
529
|
-
hooks.preToolUse = preToolUseHooks?.some((entry) => entry.hooks?.some((h) => h.command === NATIVE_GUARD_COMMAND || h.command?.includes(".claude/hooks/"))) ?? false;
|
|
530
|
-
// Check for native guard command
|
|
531
|
-
if (preToolUseHooks?.some((entry) => entry.hooks?.some((h) => h.command === NATIVE_GUARD_COMMAND))) {
|
|
532
|
-
hooks.guardsPresent.push("kspec guard worktree");
|
|
533
|
-
}
|
|
534
|
-
// Check for legacy bash scripts still present
|
|
535
|
-
if (preToolUseHooks?.some((entry) => entry.hooks?.some((h) => OLD_GUARD_SCRIPTS.some((name) => h.command?.includes(name))))) {
|
|
536
|
-
hooks.guardsPresent.push("legacy:bash-scripts");
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
catch (err) {
|
|
540
|
-
debugLog("Failed to read hooks config for status", err);
|
|
541
|
-
}
|
|
542
|
-
// Check for legacy guard script files on disk
|
|
543
|
-
try {
|
|
544
|
-
const guardFiles = await fs.readdir(hooksDir);
|
|
545
|
-
for (const name of OLD_GUARD_SCRIPTS) {
|
|
546
|
-
if (guardFiles.includes(name)) {
|
|
547
|
-
hooks.guardsPresent.push(`legacy-file:${name}`);
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
catch (err) {
|
|
552
|
-
debugLog("Hooks dir doesn't exist", err);
|
|
553
|
-
}
|
|
554
|
-
// Check skills
|
|
555
|
-
const skills = {
|
|
556
|
-
total: 0,
|
|
557
|
-
rendered: 0,
|
|
558
|
-
drifted: 0,
|
|
559
|
-
};
|
|
560
|
-
// Helper to scan a directory for skill subdirs with kspec-managed SKILL.md
|
|
561
|
-
async function scanForSkills(baseDir) {
|
|
562
|
-
try {
|
|
563
|
-
const dirs = await fs.readdir(baseDir, { withFileTypes: true });
|
|
564
|
-
for (const dir of dirs) {
|
|
565
|
-
if (dir.isDirectory()) {
|
|
566
|
-
const skillMdPath = path.join(baseDir, dir.name, "SKILL.md");
|
|
567
|
-
try {
|
|
568
|
-
const content = await fs.readFile(skillMdPath, "utf-8");
|
|
569
|
-
if (content.includes("<!-- kspec-managed -->")) {
|
|
570
|
-
skills.total++;
|
|
571
|
-
skills.rendered++;
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
catch (_noSkillMd) {
|
|
575
|
-
// No SKILL.md
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
catch (_notReadable) {
|
|
581
|
-
// Directory doesn't exist
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
// Scan .claude/skills/ (project/local skills)
|
|
585
|
-
await scanForSkills(skillsDir);
|
|
586
|
-
// Check plugin marketplace health
|
|
587
|
-
// AC: @enhanced-setup ac-7, ac-8
|
|
588
|
-
const plugin = {
|
|
589
|
-
marketplaceRegistered: false,
|
|
590
|
-
marketplaceHealthy: false,
|
|
591
|
-
pluginEnabled: false,
|
|
592
|
-
};
|
|
593
|
-
try {
|
|
594
|
-
const { checkMarketplaceHealth } = await import("../../lib/claude-plugin-registry.js");
|
|
595
|
-
const health = await checkMarketplaceHealth();
|
|
596
|
-
plugin.marketplaceRegistered = health.status !== "missing";
|
|
597
|
-
plugin.marketplaceHealthy = health.status === "healthy";
|
|
598
|
-
plugin.registeredPath = health.registeredPath;
|
|
599
|
-
plugin.healthMessage = health.message;
|
|
600
|
-
}
|
|
601
|
-
catch (err) {
|
|
602
|
-
debugLog("Could not check marketplace health", err);
|
|
603
|
-
plugin.healthMessage = "Health check unavailable";
|
|
604
|
-
}
|
|
605
|
-
// Check if plugin is enabled in project settings
|
|
606
|
-
try {
|
|
607
|
-
const configContent = await fs.readFile(configPath, "utf-8");
|
|
608
|
-
const config = JSON.parse(configContent);
|
|
609
|
-
plugin.pluginEnabled = config.enabledPlugins?.["kspec@kspec-plugins"] === true;
|
|
610
|
-
}
|
|
611
|
-
catch (err) {
|
|
612
|
-
debugLog("Could not check plugin enablement", err);
|
|
613
|
-
}
|
|
614
|
-
// Check agents.md
|
|
615
|
-
const agentsMd = {
|
|
616
|
-
exists: false,
|
|
617
|
-
status: "missing",
|
|
618
|
-
};
|
|
619
|
-
try {
|
|
620
|
-
await fs.access(agentsMdPath);
|
|
621
|
-
agentsMd.exists = true;
|
|
622
|
-
try {
|
|
623
|
-
const hashContent = await fs.readFile(hashPath, "utf-8");
|
|
624
|
-
const hashData = JSON.parse(hashContent);
|
|
625
|
-
agentsMd.generatedAt = hashData.generatedAt;
|
|
626
|
-
// AC: @cross-platform-and-version-robustness ac-4
|
|
627
|
-
// Compare stored hash against current meta to detect staleness
|
|
628
|
-
try {
|
|
629
|
-
const { initContext, loadMetaContext } = await import("../../parser/index.js");
|
|
630
|
-
const { computeMetaHash, loadTemplateSections, getPackageRoot } = await import("./agents.js");
|
|
631
|
-
const ctx = await initContext();
|
|
632
|
-
if (ctx.manifestPath) {
|
|
633
|
-
const metaCtx = await loadMetaContext(ctx);
|
|
634
|
-
let templateSections = [];
|
|
635
|
-
try {
|
|
636
|
-
templateSections = await loadTemplateSections(getPackageRoot());
|
|
637
|
-
}
|
|
638
|
-
catch (err) {
|
|
639
|
-
debugLog("Templates not available for staleness check", err);
|
|
640
|
-
}
|
|
641
|
-
const currentHash = computeMetaHash(metaCtx.skills, metaCtx.conventions, metaCtx.workflows, templateSections);
|
|
642
|
-
agentsMd.status = hashData.metaHash === currentHash ? "current" : "stale";
|
|
643
|
-
}
|
|
644
|
-
else {
|
|
645
|
-
// AC: @doctor-command ac-staleness-unknown — no manifest means we can't determine staleness
|
|
646
|
-
agentsMd.status = "unknown";
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
catch (err) {
|
|
650
|
-
// AC: @doctor-command ac-staleness-unknown — hash computation failed
|
|
651
|
-
debugLog("Could not compute meta hash for staleness check", err);
|
|
652
|
-
agentsMd.status = "unknown";
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
catch (err) {
|
|
656
|
-
debugLog("Hash file missing or invalid, marking stale", err);
|
|
657
|
-
agentsMd.status = "stale";
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
catch (err) {
|
|
661
|
-
debugLog("kspec-agents.md doesn't exist", err);
|
|
662
|
-
}
|
|
663
|
-
// Check seeding state
|
|
664
|
-
const seeding = {
|
|
665
|
-
permissionsSeeded: false,
|
|
666
|
-
memorySeeded: false,
|
|
667
|
-
};
|
|
668
|
-
try {
|
|
669
|
-
const configContent = await fs.readFile(path.join(projectDir, ".claude", "settings.json"), "utf-8");
|
|
670
|
-
const config = JSON.parse(configContent);
|
|
671
|
-
seeding.permissionsSeeded = !!config.permissions;
|
|
672
|
-
}
|
|
673
|
-
catch (err) {
|
|
674
|
-
debugLog("Could not check permissions seeding state", err);
|
|
675
|
-
}
|
|
676
|
-
if (detected.type === "claude-code") {
|
|
677
|
-
try {
|
|
678
|
-
const { claudeCodeMemoryWriter } = await import("./setup-seeding.js");
|
|
679
|
-
const memoryExists = await claudeCodeMemoryWriter.exists(projectDir);
|
|
680
|
-
seeding.memorySeeded = memoryExists;
|
|
681
|
-
if (memoryExists) {
|
|
682
|
-
seeding.memoryPath = claudeCodeMemoryWriter.getMemoryPath(projectDir);
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
catch (err) {
|
|
686
|
-
debugLog("Could not check memory seeding state", err);
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
return {
|
|
690
|
-
agent: {
|
|
691
|
-
detected: detected.type,
|
|
692
|
-
confidence: detected.confidence,
|
|
693
|
-
},
|
|
694
|
-
hooks,
|
|
695
|
-
skills,
|
|
696
|
-
plugin,
|
|
697
|
-
agentsMd,
|
|
698
|
-
seeding,
|
|
699
|
-
};
|
|
700
|
-
}
|
|
701
576
|
/**
|
|
702
577
|
* Render skills using the platform renderer registry
|
|
703
578
|
* AC: @setup-pipeline-unification ac-2 - uses getRenderer/getAllRenderers, not legacy renderClaudeCodeSkill
|
|
@@ -761,6 +636,12 @@ async function renderSkillsForSetup(projectDir, dryRun) {
|
|
|
761
636
|
return { rendered: 0, skipped: 0, pluginProvided: 0, skillIds: [] };
|
|
762
637
|
}
|
|
763
638
|
}
|
|
639
|
+
function getHookInstallSkipMessage(agentType) {
|
|
640
|
+
if (agentType === "droid") {
|
|
641
|
+
return "droid hooks are not yet supported; skipping .factory/settings.json hook installation";
|
|
642
|
+
}
|
|
643
|
+
return `not applicable for ${agentType}`;
|
|
644
|
+
}
|
|
764
645
|
/**
|
|
765
646
|
* Ensure built-in worker and reviewer agent definitions exist in the project meta.
|
|
766
647
|
*
|
|
@@ -1069,8 +950,15 @@ export async function runSetupPipeline(projectDir, options) {
|
|
|
1069
950
|
}
|
|
1070
951
|
// Step 3: Install hooks (Claude Code only)
|
|
1071
952
|
// AC: @init-setup-integration ac-3 - hooks present
|
|
953
|
+
// AC: @project-config ac-hooks-section — read config to determine hook preferences
|
|
1072
954
|
if (detected.type === "claude-code" && installHooksFlag) {
|
|
1073
|
-
|
|
955
|
+
// Load project config to get hooks preferences
|
|
956
|
+
const { config: projectConfig } = await loadProjectConfig(projectDir, projectDir);
|
|
957
|
+
const hooksPrefs = {
|
|
958
|
+
checkpoint: projectConfig.hooks.checkpoint,
|
|
959
|
+
prompt_check: projectConfig.hooks.prompt_check,
|
|
960
|
+
};
|
|
961
|
+
const hooksResult = await installClaudeCodeHooks(projectDir, dryRun, hooksPrefs);
|
|
1074
962
|
const installedHooks = [];
|
|
1075
963
|
if (hooksResult.promptCheck)
|
|
1076
964
|
installedHooks.push("UserPromptSubmit");
|
|
@@ -1100,7 +988,7 @@ export async function runSetupPipeline(projectDir, options) {
|
|
|
1100
988
|
steps.push({
|
|
1101
989
|
name: "Install hooks",
|
|
1102
990
|
status: "skipped",
|
|
1103
|
-
message:
|
|
991
|
+
message: getHookInstallSkipMessage(detected.type),
|
|
1104
992
|
});
|
|
1105
993
|
}
|
|
1106
994
|
// Step 3a: Ensure artifacts directory exists
|
|
@@ -1123,6 +1011,108 @@ export async function runSetupPipeline(projectDir, options) {
|
|
|
1123
1011
|
message: artifactsCreated ? "created .kspec/artifacts/" : "already exists",
|
|
1124
1012
|
});
|
|
1125
1013
|
}
|
|
1014
|
+
// Step 3a-ii: Ensure sessions directory and gitignore entries
|
|
1015
|
+
// AC: @session-storage-modes ac-gitignore, ac-sessions-dir-autocreate
|
|
1016
|
+
// AC: @session-legacy-migration ac-shadow-gitignore
|
|
1017
|
+
{
|
|
1018
|
+
const actions = [];
|
|
1019
|
+
// Create .kspec-sessions/ directory
|
|
1020
|
+
const sessionsDirPath = path.join(projectDir, SESSIONS_WORKTREE_DIR);
|
|
1021
|
+
let sessionsCreated = false;
|
|
1022
|
+
try {
|
|
1023
|
+
await fs.access(sessionsDirPath);
|
|
1024
|
+
}
|
|
1025
|
+
catch (_e) {
|
|
1026
|
+
if (!dryRun) {
|
|
1027
|
+
await fs.mkdir(sessionsDirPath, { recursive: true });
|
|
1028
|
+
}
|
|
1029
|
+
sessionsCreated = true;
|
|
1030
|
+
}
|
|
1031
|
+
if (sessionsCreated) {
|
|
1032
|
+
actions.push(`${dryRun ? "create" : "created"} ${SESSIONS_WORKTREE_DIR}/`);
|
|
1033
|
+
}
|
|
1034
|
+
// Add .kspec-sessions/ to root .gitignore
|
|
1035
|
+
if (dryRun) {
|
|
1036
|
+
const rootNeeded = await needsSessionsGitignore(projectDir);
|
|
1037
|
+
if (rootNeeded) {
|
|
1038
|
+
actions.push(`add ${SESSIONS_WORKTREE_DIR}/ to .gitignore`);
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
else {
|
|
1042
|
+
const rootAdded = await ensureSessionsGitignore(projectDir);
|
|
1043
|
+
if (rootAdded) {
|
|
1044
|
+
actions.push(`added ${SESSIONS_WORKTREE_DIR}/ to .gitignore`);
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
// Add sessions/ to .kspec/.gitignore
|
|
1048
|
+
if (dryRun) {
|
|
1049
|
+
const shadowNeeded = await needsShadowSessionsGitignore(projectDir);
|
|
1050
|
+
if (shadowNeeded) {
|
|
1051
|
+
actions.push("add sessions/ to .kspec/.gitignore");
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
else {
|
|
1055
|
+
const shadowAdded = await ensureShadowSessionsGitignore(projectDir);
|
|
1056
|
+
if (shadowAdded) {
|
|
1057
|
+
actions.push("added sessions/ to .kspec/.gitignore");
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
steps.push({
|
|
1061
|
+
name: "Ensure sessions directory",
|
|
1062
|
+
status: actions.length > 0 ? "done" : "skipped",
|
|
1063
|
+
message: actions.length > 0 ? actions.join(", ") : "already configured",
|
|
1064
|
+
});
|
|
1065
|
+
}
|
|
1066
|
+
// Step 3a-iii: Initialize session branch worktree if sessions.storage is "branch"
|
|
1067
|
+
// AC: @session-branch-worktree ac-init
|
|
1068
|
+
{
|
|
1069
|
+
try {
|
|
1070
|
+
const { initContext } = await import("../../parser/index.js");
|
|
1071
|
+
const ctx = await initContext();
|
|
1072
|
+
const sessionStorage = ctx.manifest?.sessions?.storage;
|
|
1073
|
+
if (sessionStorage === "branch") {
|
|
1074
|
+
const { initializeSessionBranch, getSessionBranchStatus } = await import("../../parser/session-branch.js");
|
|
1075
|
+
const sessionBranchName = ctx.manifest?.sessions?.branch || "kspec-sessions";
|
|
1076
|
+
const sessionStatus = await getSessionBranchStatus(projectDir, sessionBranchName);
|
|
1077
|
+
if (sessionStatus.healthy) {
|
|
1078
|
+
steps.push({
|
|
1079
|
+
name: "Session branch worktree",
|
|
1080
|
+
status: "skipped",
|
|
1081
|
+
message: "already initialized",
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
else if (dryRun) {
|
|
1085
|
+
steps.push({
|
|
1086
|
+
name: "Session branch worktree",
|
|
1087
|
+
status: "done",
|
|
1088
|
+
message: `create orphan branch "${sessionBranchName}" with worktree at ${SESSIONS_WORKTREE_DIR}/`,
|
|
1089
|
+
});
|
|
1090
|
+
}
|
|
1091
|
+
else {
|
|
1092
|
+
const sessionResult = await initializeSessionBranch(projectDir, sessionBranchName);
|
|
1093
|
+
if (sessionResult.success) {
|
|
1094
|
+
steps.push({
|
|
1095
|
+
name: "Session branch worktree",
|
|
1096
|
+
status: "done",
|
|
1097
|
+
message: sessionResult.alreadyExists
|
|
1098
|
+
? "already initialized"
|
|
1099
|
+
: `created branch "${sessionBranchName}" with worktree at ${SESSIONS_WORKTREE_DIR}/`,
|
|
1100
|
+
});
|
|
1101
|
+
}
|
|
1102
|
+
else {
|
|
1103
|
+
steps.push({
|
|
1104
|
+
name: "Session branch worktree",
|
|
1105
|
+
status: "failed",
|
|
1106
|
+
message: sessionResult.error || "unknown error",
|
|
1107
|
+
});
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
catch {
|
|
1113
|
+
// Session branch init is optional — don't block setup
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1126
1116
|
// Step 3b: Seed permissions (Claude Code only)
|
|
1127
1117
|
// AC: @new-project-bootstrapping ac-1
|
|
1128
1118
|
{
|
|
@@ -1252,6 +1242,9 @@ export async function runSetupPipeline(projectDir, options) {
|
|
|
1252
1242
|
authorInstalled = true;
|
|
1253
1243
|
}
|
|
1254
1244
|
break;
|
|
1245
|
+
case "droid":
|
|
1246
|
+
authorInstalled = false;
|
|
1247
|
+
break;
|
|
1255
1248
|
case "aider":
|
|
1256
1249
|
if (!dryRun) {
|
|
1257
1250
|
authorInstalled = await installAiderConfig(author);
|
|
@@ -1270,6 +1263,21 @@ export async function runSetupPipeline(projectDir, options) {
|
|
|
1270
1263
|
message: `KSPEC_AUTHOR="${author}"`,
|
|
1271
1264
|
});
|
|
1272
1265
|
}
|
|
1266
|
+
else if (detected.type === "droid") {
|
|
1267
|
+
steps.push({
|
|
1268
|
+
name: "Configure author",
|
|
1269
|
+
status: "skipped",
|
|
1270
|
+
message: "add KSPEC_AUTHOR to the .factory/settings.json env section",
|
|
1271
|
+
});
|
|
1272
|
+
}
|
|
1273
|
+
else if (detected.type === "unknown") {
|
|
1274
|
+
// AC: @cmd-setup ac-1 - show manual instructions for unknown agents
|
|
1275
|
+
steps.push({
|
|
1276
|
+
name: "Configure author",
|
|
1277
|
+
status: "skipped",
|
|
1278
|
+
message: `no auto-config for unknown agent — set KSPEC_AUTHOR manually`,
|
|
1279
|
+
});
|
|
1280
|
+
}
|
|
1273
1281
|
}
|
|
1274
1282
|
}
|
|
1275
1283
|
// Output summary
|
|
@@ -1326,7 +1334,7 @@ export function registerSetupCommand(program) {
|
|
|
1326
1334
|
program
|
|
1327
1335
|
.command("setup")
|
|
1328
1336
|
.description("Configure agent environment for kspec (orchestrated pipeline)")
|
|
1329
|
-
.option("--agent <type>", "Explicit agent type override (claude-code|cline|cursor|windsurf|unknown)")
|
|
1337
|
+
.option("--agent <type>", "Explicit agent type override (claude-code|cline|droid|cursor|windsurf|unknown)")
|
|
1330
1338
|
.option("--dry-run", "Show what would be done without making changes")
|
|
1331
1339
|
.option("--author <author>", "Custom author string (default: auto-detected based on agent)")
|
|
1332
1340
|
.option("--no-hooks", "Skip installing hooks")
|
|
@@ -1342,18 +1350,34 @@ export function registerSetupCommand(program) {
|
|
|
1342
1350
|
: undefined;
|
|
1343
1351
|
// AC: @enhanced-setup ac-7, ac-8 - --status mode
|
|
1344
1352
|
if (options.status) {
|
|
1345
|
-
const status = await
|
|
1353
|
+
const status = await getSharedSetupStatus(projectDir, {
|
|
1354
|
+
agentOverride,
|
|
1355
|
+
});
|
|
1346
1356
|
output(status, () => {
|
|
1347
1357
|
console.log(chalk.bold("kspec Setup Status\n"));
|
|
1348
1358
|
// Agent detection
|
|
1349
1359
|
console.log(chalk.gray("Agent:"));
|
|
1350
1360
|
console.log(` Detected: ${status.agent.detected} (${status.agent.confidence} confidence)`);
|
|
1361
|
+
if (status.agent.configPath) {
|
|
1362
|
+
console.log(` Config: ${status.agent.configPath}`);
|
|
1363
|
+
}
|
|
1351
1364
|
console.log();
|
|
1352
1365
|
// Hooks status
|
|
1353
1366
|
console.log(chalk.gray("Hooks:"));
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1367
|
+
if (status.hooks.supported) {
|
|
1368
|
+
console.log(` UserPromptSubmit: ${status.hooks.promptCheck ? chalk.green("✓") : chalk.red("✗")}`);
|
|
1369
|
+
console.log(` Stop: ${status.hooks.stop ? chalk.green("✓") : chalk.red("✗")}`);
|
|
1370
|
+
console.log(` PreToolUse: ${status.hooks.preToolUse ? chalk.green("✓") : chalk.red("✗")}`);
|
|
1371
|
+
}
|
|
1372
|
+
else {
|
|
1373
|
+
const unsupported = chalk.yellow("unsupported");
|
|
1374
|
+
console.log(` UserPromptSubmit: ${unsupported}`);
|
|
1375
|
+
console.log(` Stop: ${unsupported}`);
|
|
1376
|
+
console.log(` PreToolUse: ${unsupported}`);
|
|
1377
|
+
if (status.agent.detected === "droid") {
|
|
1378
|
+
console.log(" Note: droid hooks are not yet supported");
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1357
1381
|
if (status.hooks.guardsPresent.length > 0) {
|
|
1358
1382
|
console.log(` Guards: ${status.hooks.guardsPresent.join(", ")}`);
|
|
1359
1383
|
}
|
|
@@ -1419,10 +1443,9 @@ export function registerSetupCommand(program) {
|
|
|
1419
1443
|
? buildDetectedAgent(agentOverride)
|
|
1420
1444
|
: detectAgent();
|
|
1421
1445
|
const dryRun = options.dryRun || false;
|
|
1446
|
+
// AC: @cmd-setup ac-1 - proceed with setup even when no agent is detected
|
|
1422
1447
|
if (detected.type === "unknown") {
|
|
1423
|
-
warn("Could not auto-detect agent environment");
|
|
1424
|
-
printManualInstructions("unknown");
|
|
1425
|
-
return;
|
|
1448
|
+
warn("Could not auto-detect agent environment — proceeding with core setup steps");
|
|
1426
1449
|
}
|
|
1427
1450
|
// AC: @setup-pipeline-unification ac-3 - delegate to runSetupPipeline()
|
|
1428
1451
|
// One code path for both 'kspec setup' and 'kspec init --setup'
|
|
@@ -1478,6 +1501,13 @@ export function registerSetupCommand(program) {
|
|
|
1478
1501
|
console.log(chalk.green("Setup complete."));
|
|
1479
1502
|
console.log(chalk.gray("Restart your agent session for changes to take effect."));
|
|
1480
1503
|
}
|
|
1504
|
+
const configureAuthorStep = result.steps.find((step) => step.name === "Configure author");
|
|
1505
|
+
const needsManualInstructions = configureAuthorStep?.status === "skipped" &&
|
|
1506
|
+
!configureAuthorStep.message?.includes("already set") &&
|
|
1507
|
+
(detected.type === "unknown" || detected.type === "droid");
|
|
1508
|
+
if (needsManualInstructions) {
|
|
1509
|
+
printManualInstructions(detected.type);
|
|
1510
|
+
}
|
|
1481
1511
|
});
|
|
1482
1512
|
}
|
|
1483
1513
|
catch (err) {
|