specweave 3.1.5 → 3.1.7

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.
Files changed (113) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/README.md +2 -2
  3. package/bin/specweave.js +17 -0
  4. package/dist/dashboard/assets/index-B4Xv671Q.css +1 -0
  5. package/dist/dashboard/assets/index-VnHjeVmH.js +16 -0
  6. package/dist/dashboard/index.html +2 -2
  7. package/dist/src/cli/commands/card.d.ts.map +1 -1
  8. package/dist/src/cli/commands/card.js +15 -10
  9. package/dist/src/cli/commands/card.js.map +1 -1
  10. package/dist/src/cli/commands/complete.d.ts.map +1 -1
  11. package/dist/src/cli/commands/complete.js +6 -0
  12. package/dist/src/cli/commands/complete.js.map +1 -1
  13. package/dist/src/cli/commands/create-increment.d.ts.map +1 -1
  14. package/dist/src/cli/commands/create-increment.js +4 -0
  15. package/dist/src/cli/commands/create-increment.js.map +1 -1
  16. package/dist/src/cli/commands/dashboard.d.ts.map +1 -1
  17. package/dist/src/cli/commands/dashboard.js +2 -0
  18. package/dist/src/cli/commands/dashboard.js.map +1 -1
  19. package/dist/src/cli/commands/jev-helpers.d.ts +12 -4
  20. package/dist/src/cli/commands/jev-helpers.d.ts.map +1 -1
  21. package/dist/src/cli/commands/jev-helpers.js +22 -13
  22. package/dist/src/cli/commands/jev-helpers.js.map +1 -1
  23. package/dist/src/cli/commands/pickup.d.ts.map +1 -1
  24. package/dist/src/cli/commands/pickup.js +8 -4
  25. package/dist/src/cli/commands/pickup.js.map +1 -1
  26. package/dist/src/cli/commands/require-increment.d.ts +18 -0
  27. package/dist/src/cli/commands/require-increment.d.ts.map +1 -0
  28. package/dist/src/cli/commands/require-increment.js +75 -0
  29. package/dist/src/cli/commands/require-increment.js.map +1 -0
  30. package/dist/src/cli/commands/small-fix.d.ts +14 -0
  31. package/dist/src/cli/commands/small-fix.d.ts.map +1 -0
  32. package/dist/src/cli/commands/small-fix.js +52 -0
  33. package/dist/src/cli/commands/small-fix.js.map +1 -0
  34. package/dist/src/cli/commands/verify.d.ts.map +1 -1
  35. package/dist/src/cli/commands/verify.js +3 -0
  36. package/dist/src/cli/commands/verify.js.map +1 -1
  37. package/dist/src/cli/helpers/init/gitignore-generator.d.ts.map +1 -1
  38. package/dist/src/cli/helpers/init/gitignore-generator.js +1 -0
  39. package/dist/src/cli/helpers/init/gitignore-generator.js.map +1 -1
  40. package/dist/src/core/config/types.d.ts +7 -0
  41. package/dist/src/core/config/types.d.ts.map +1 -1
  42. package/dist/src/core/config/types.js.map +1 -1
  43. package/dist/src/core/hooks/handlers/pre-compact.d.ts.map +1 -1
  44. package/dist/src/core/hooks/handlers/pre-compact.js +4 -1
  45. package/dist/src/core/hooks/handlers/pre-compact.js.map +1 -1
  46. package/dist/src/core/hooks/handlers/pre-tool-use.d.ts +5 -2
  47. package/dist/src/core/hooks/handlers/pre-tool-use.d.ts.map +1 -1
  48. package/dist/src/core/hooks/handlers/pre-tool-use.js +16 -3
  49. package/dist/src/core/hooks/handlers/pre-tool-use.js.map +1 -1
  50. package/dist/src/core/hooks/handlers/require-increment.d.ts +40 -0
  51. package/dist/src/core/hooks/handlers/require-increment.d.ts.map +1 -0
  52. package/dist/src/core/hooks/handlers/require-increment.js +128 -0
  53. package/dist/src/core/hooks/handlers/require-increment.js.map +1 -0
  54. package/dist/src/core/session/nested-repos.d.ts +16 -4
  55. package/dist/src/core/session/nested-repos.d.ts.map +1 -1
  56. package/dist/src/core/session/nested-repos.js +85 -23
  57. package/dist/src/core/session/nested-repos.js.map +1 -1
  58. package/dist/src/core/session/pickup.d.ts +2 -0
  59. package/dist/src/core/session/pickup.d.ts.map +1 -1
  60. package/dist/src/core/session/pickup.js +4 -3
  61. package/dist/src/core/session/pickup.js.map +1 -1
  62. package/dist/src/core/session/work-handoff.d.ts.map +1 -1
  63. package/dist/src/core/session/work-handoff.js +6 -3
  64. package/dist/src/core/session/work-handoff.js.map +1 -1
  65. package/dist/src/core/tasks/ledger.d.ts +7 -0
  66. package/dist/src/core/tasks/ledger.d.ts.map +1 -1
  67. package/dist/src/core/tasks/ledger.js +20 -4
  68. package/dist/src/core/tasks/ledger.js.map +1 -1
  69. package/dist/src/core/tasks/verify-runner.d.ts +21 -0
  70. package/dist/src/core/tasks/verify-runner.d.ts.map +1 -1
  71. package/dist/src/core/tasks/verify-runner.js +9 -4
  72. package/dist/src/core/tasks/verify-runner.js.map +1 -1
  73. package/dist/src/core/tasks/work-session.d.ts +58 -0
  74. package/dist/src/core/tasks/work-session.d.ts.map +1 -0
  75. package/dist/src/core/tasks/work-session.js +88 -0
  76. package/dist/src/core/tasks/work-session.js.map +1 -0
  77. package/dist/src/dashboard/server/dashboard-server.d.ts.map +1 -1
  78. package/dist/src/dashboard/server/dashboard-server.js +2 -0
  79. package/dist/src/dashboard/server/dashboard-server.js.map +1 -1
  80. package/dist/src/dashboard/server/data/plan-timeline.d.ts +40 -0
  81. package/dist/src/dashboard/server/data/plan-timeline.d.ts.map +1 -0
  82. package/dist/src/dashboard/server/data/plan-timeline.js +259 -0
  83. package/dist/src/dashboard/server/data/plan-timeline.js.map +1 -0
  84. package/dist/src/dashboard/server/data/work-projection.d.ts.map +1 -1
  85. package/dist/src/dashboard/server/data/work-projection.js +7 -2
  86. package/dist/src/dashboard/server/data/work-projection.js.map +1 -1
  87. package/dist/src/dashboard/server/routes/plan-routes.d.ts +4 -0
  88. package/dist/src/dashboard/server/routes/plan-routes.d.ts.map +1 -0
  89. package/dist/src/dashboard/server/routes/plan-routes.js +19 -0
  90. package/dist/src/dashboard/server/routes/plan-routes.js.map +1 -0
  91. package/dist/src/dashboard/work-types.d.ts +81 -0
  92. package/dist/src/dashboard/work-types.d.ts.map +1 -1
  93. package/dist/src/utils/find-project-root.d.ts +2 -0
  94. package/dist/src/utils/find-project-root.d.ts.map +1 -1
  95. package/dist/src/utils/find-project-root.js +8 -1
  96. package/dist/src/utils/find-project-root.js.map +1 -1
  97. package/dist/src/utils/main-checkout.d.ts +30 -0
  98. package/dist/src/utils/main-checkout.d.ts.map +1 -0
  99. package/dist/src/utils/main-checkout.js +74 -0
  100. package/dist/src/utils/main-checkout.js.map +1 -0
  101. package/package.json +1 -1
  102. package/plugins/specweave/.claude-plugin/plugin.json +1 -1
  103. package/plugins/specweave/hooks/run-worker.mjs +42 -5
  104. package/plugins/specweave/hooks/run.mjs +101 -6
  105. package/plugins/specweave/skills/do/SKILL.md +1 -1
  106. package/plugins/specweave/skills/handoff/SKILL.md +2 -2
  107. package/src/templates/.gitignore.template +1 -0
  108. package/src/templates/AGENTS.md.template +2 -2
  109. package/src/templates/environments/minimal/README.md +3 -3
  110. package/src/templates/environments/progressive/README.md +5 -6
  111. package/src/templates/environments/standard/README.md +4 -4
  112. package/dist/dashboard/assets/index-BFPKNEDz.css +0 -1
  113. package/dist/dashboard/assets/index-DVaY9gOX.js +0 -13
@@ -1 +1 @@
1
- {"version":3,"file":"work-projection.d.ts","sourceRoot":"","sources":["../../../../../src/dashboard/server/data/work-projection.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAoB,QAAQ,EAAa,MAAM,qBAAqB,CAAC;AAEjF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM7C;AACD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAM1D;AACD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAc1E;AAQD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAqF1E;AAED,oFAAoF;AACpF,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CA2C1G"}
1
+ {"version":3,"file":"work-projection.d.ts","sourceRoot":"","sources":["../../../../../src/dashboard/server/data/work-projection.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAoB,QAAQ,EAAa,MAAM,qBAAqB,CAAC;AAEjF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM7C;AACD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAM1D;AACD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAc1E;AAQD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CA0F1E;AAED,oFAAoF;AACpF,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CA2C1G"}
@@ -86,8 +86,13 @@ export function projectIncrement(root, id) {
86
86
  const events = readLedger(path.join(dir, 'ledger.jsonl')).events.sort((a, b) => a.at.localeCompare(b.at));
87
87
  const executions = [];
88
88
  for (const [index, event] of events.entries()) {
89
- if (executions[executions.length - 1]?.actor === event.by)
89
+ const last = executions[executions.length - 1];
90
+ if (last?.actor === event.by && (!event.model || last.model === event.model))
90
91
  continue;
92
+ if (last?.actor === event.by && !last.model) {
93
+ last.model = event.model ?? null;
94
+ continue;
95
+ }
91
96
  const tool = event.by.split('@')[0];
92
97
  executions.push({
93
98
  id: `ledger-${index}`,
@@ -97,7 +102,7 @@ export function projectIncrement(root, id) {
97
102
  ? 'Claude Code'
98
103
  : tool
99
104
  : null,
100
- model: null,
105
+ model: event.model ?? null,
101
106
  effort: null,
102
107
  provider: null,
103
108
  surface: null,
@@ -1 +1 @@
1
- {"version":3,"file":"work-projection.js","sourceRoot":"","sources":["../../../../../src/dashboard/server/data/work-projection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"work-projection.js","sourceRoot":"","sources":["../../../../../src/dashboard/server/data/work-projection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type http from 'node:http';
2
+ import { type Router } from '../router.js';
3
+ export declare function registerPlanRoutes(router: Router, resolveRoot: (req: http.IncomingMessage) => string | undefined): void;
4
+ //# sourceMappingURL=plan-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-routes.d.ts","sourceRoot":"","sources":["../../../../../src/dashboard/server/routes/plan-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAY,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAMrD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,KAAK,MAAM,GAAG,SAAS,GAAG,IAAI,CAWvH"}
@@ -0,0 +1,19 @@
1
+ import { buildPlanTimeline } from '../data/plan-timeline.js';
2
+ import { sendJson } from '../router.js';
3
+ /** Reads every increment folder; a short cache keeps the Timeline's polling cheap. */
4
+ const CACHE_MS = 5000;
5
+ export function registerPlanRoutes(router, resolveRoot) {
6
+ const cache = new Map();
7
+ router.get('/api/plan', async (req, res) => {
8
+ const root = resolveRoot(req);
9
+ if (!root)
10
+ return sendJson(res, { ok: false, error: 'No project selected' }, 404);
11
+ const hit = cache.get(root);
12
+ if (hit && Date.now() - hit.at < CACHE_MS)
13
+ return sendJson(res, { ok: true, data: hit.data });
14
+ const data = buildPlanTimeline(root);
15
+ cache.set(root, { at: Date.now(), data });
16
+ sendJson(res, { ok: true, data });
17
+ });
18
+ }
19
+ //# sourceMappingURL=plan-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-routes.js","sourceRoot":"","sources":["../../../../../src/dashboard/server/routes/plan-routes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAe,MAAM,cAAc,CAAC;AAGrD,sFAAsF;AACtF,MAAM,QAAQ,GAAG,IAAI,CAAC;AAEtB,MAAM,UAAU,kBAAkB,CAAC,MAAc,EAAE,WAA8D;IAC/G,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqD,CAAC;IAC3E,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACzC,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI;YAAE,OAAO,QAAQ,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAAE,GAAG,CAAC,CAAC;QAClF,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,QAAQ;YAAE,OAAO,QAAQ,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9F,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACrC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,QAAQ,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -36,4 +36,85 @@ export interface WorkBoardPayload {
36
36
  generatedAt: string;
37
37
  warnings: string[];
38
38
  }
39
+ /** One increment on the Timeline page (`GET /api/plan`). */
40
+ export interface PlanRow {
41
+ incrementId: string;
42
+ title: string;
43
+ status: string;
44
+ state: WorkState;
45
+ /** Created, or the first ledger event when earlier. */
46
+ start: string;
47
+ /** Last ledger event or metadata update; null while nothing happened. */
48
+ end: string | null;
49
+ tasks: {
50
+ total: number;
51
+ done: number;
52
+ skipped: number;
53
+ open: number;
54
+ claimed: number;
55
+ blocked: number;
56
+ };
57
+ acs: {
58
+ total: number;
59
+ done: number;
60
+ };
61
+ tools: string[];
62
+ models: string[];
63
+ /** Most tasks were closed with no live claim-to-done span: the plan was written after the work. */
64
+ recordedAfter: boolean;
65
+ /** Open work only: remaining weight, minutes at the p50 and p80 rates and finish times, uninterrupted from now. */
66
+ remaining: {
67
+ tasks: number;
68
+ weight: number;
69
+ p50Minutes: number;
70
+ p80Minutes: number;
71
+ finishP50: string;
72
+ finishP80: string;
73
+ } | null;
74
+ lastEvent: {
75
+ at: string;
76
+ e: string;
77
+ t: string;
78
+ by: string;
79
+ } | null;
80
+ specPath: string;
81
+ }
82
+ export interface PlanActivity {
83
+ at: string;
84
+ incrementId: string;
85
+ title: string;
86
+ task: string;
87
+ event: string;
88
+ by: string;
89
+ tool: string;
90
+ model: string | null;
91
+ note: string | null;
92
+ }
93
+ export interface PlanRate {
94
+ key: string;
95
+ samples: number;
96
+ /** Minutes per weight unit of task work. */
97
+ p50: number;
98
+ p80: number;
99
+ }
100
+ export interface PlanTimelinePayload {
101
+ generatedAt: string;
102
+ rows: PlanRow[];
103
+ activity: PlanActivity[];
104
+ /** Every done or skipped task of the last 30 days, oldest first (throughput is computed from the filtered set). */
105
+ closes: Array<{
106
+ at: string;
107
+ incrementId: string;
108
+ tool: string;
109
+ }>;
110
+ rates: {
111
+ overall: PlanRate;
112
+ byTool: PlanRate[];
113
+ byModel: PlanRate[];
114
+ fallback: boolean;
115
+ };
116
+ /** Median agents finishing tasks per active day over the last week (at least 1): parallel lanes for the forecast. */
117
+ lanes: number;
118
+ smallFixes: number;
119
+ }
39
120
  //# sourceMappingURL=work-types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"work-types.d.ts","sourceRoot":"","sources":["../../../src/dashboard/work-types.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,cAAc,yBAAyB,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACrE,MAAM,WAAW,QAAS,SAAQ,UAAU;IAC1C,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,YAAY,EAAE;QAAE,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAC1F,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AACD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAClC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5E,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB"}
1
+ {"version":3,"file":"work-types.d.ts","sourceRoot":"","sources":["../../../src/dashboard/work-types.ts"],"names":[],"mappings":"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"}
@@ -92,6 +92,8 @@ export declare function findUmbrellaRoot(startDir?: string): string | null;
92
92
  *
93
93
  * - In a multi-repo umbrella: returns the umbrella root (increments belong there)
94
94
  * - In a single-repo project: returns the nearest project root
95
+ * - In a linked Git worktree outside the project (SpecWithCode threads): the
96
+ * same lookups from the worktree's main checkout
95
97
  * - Otherwise: null
96
98
  *
97
99
  * Use this instead of resolveEffectiveRoot() for any command that scans or
@@ -1 +1 @@
1
- {"version":3,"file":"find-project-root.d.ts","sourceRoot":"","sources":["../../../src/utils/find-project-root.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAmB/E;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,cAAc,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAEvE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,GAAE,MAAsB,GAAG,OAAO,CAElF;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQ3D;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAqBhF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAEjF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAE7E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMnE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,MAAM,EACpB,QAAQ,GAAE,MAAsB,GAC/B,MAAM,GAAG,IAAI,CAKf"}
1
+ {"version":3,"file":"find-project-root.d.ts","sourceRoot":"","sources":["../../../src/utils/find-project-root.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAmB/E;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,cAAc,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAEvE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,GAAE,MAAsB,GAAG,OAAO,CAElF;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQ3D;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAqBhF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAKjF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAE7E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMnE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,MAAM,EACpB,QAAQ,GAAE,MAAsB,GAC/B,MAAM,GAAG,IAAI,CAKf"}
@@ -15,6 +15,7 @@
15
15
  import * as fs from 'fs';
16
16
  import path from 'path';
17
17
  import { explicitWorkspaceRoot, isWorkspaceRoot, hasLegacyWorkspaceLayout, registeredRepositories, canonicalPath, isWithin } from '../core/workspace/context.js';
18
+ import { mainCheckoutOf } from './main-checkout.js';
18
19
  /**
19
20
  * Find project root by searching for .specweave/config.json
20
21
  *
@@ -148,6 +149,8 @@ export function findUmbrellaRoot(startDir = process.cwd()) {
148
149
  *
149
150
  * - In a multi-repo umbrella: returns the umbrella root (increments belong there)
150
151
  * - In a single-repo project: returns the nearest project root
152
+ * - In a linked Git worktree outside the project (SpecWithCode threads): the
153
+ * same lookups from the worktree's main checkout
151
154
  * - Otherwise: null
152
155
  *
153
156
  * Use this instead of resolveEffectiveRoot() for any command that scans or
@@ -158,7 +161,11 @@ export function findUmbrellaRoot(startDir = process.cwd()) {
158
161
  * @returns Effective project root path or null if not inside a SpecWeave project
159
162
  */
160
163
  export function findEffectiveRoot(startDir = process.cwd()) {
161
- return findUmbrellaRoot(startDir) ?? findProjectRoot(startDir);
164
+ const found = findUmbrellaRoot(startDir) ?? findProjectRoot(startDir);
165
+ if (found)
166
+ return found;
167
+ const main = mainCheckoutOf(startDir);
168
+ return main ? findUmbrellaRoot(main) ?? findProjectRoot(main) : null;
162
169
  }
163
170
  /**
164
171
  * Resolve the effective project root for increment operations.
@@ -1 +1 @@
1
- {"version":3,"file":"find-project-root.js","sourceRoot":"","sources":["../../../src/utils/find-project-root.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAEjK;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,eAAe,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IAC9D,MAAM,QAAQ,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;IAEtC,OAAO,OAAO,KAAK,IAAI,EAAE,CAAC;QACxB,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACvD,IACE,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC;YAC5B,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE;YACxC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC,EACtD,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IAC7D,OAAO,eAAe,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IACvE,OAAO,eAAe,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;AAC5C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAW;IAChD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;IAC1D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACzC,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IAC/D,MAAM,QAAQ,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,WAAW,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC9C,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAC9B,IAAI,OAAO,GAAG,WAAW,CAAC;IAC1B,OAAO,OAAO,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/F,MAAM,YAAY,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;YACvD,MAAM,MAAM,GAAG,OAAO,KAAK,WAAW,IAAI,YAAY;mBACjD,sBAAsB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACxG,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,OAAO,KAAK,WAAW,IAAI,sBAAsB,CAAC,WAAW,CAAC,EAAE,CAAC;oBACnE,MAAM,IAAI,KAAK,CAAC,+BAA+B,WAAW,QAAQ,OAAO,gCAAgC,CAAC,CAAC;gBAC7G,CAAC;gBACD,OAAO,OAAO,CAAC;YACjB,CAAC;QACH,CAAC;QACD,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IAChE,OAAO,gBAAgB,CAAC,QAAQ,CAAC,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC;AACjE,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IACnE,OAAO,iBAAiB,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;AACtD,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAiB;IAChD,OAAO,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC,CAAC;AACjE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,WAAoB;IAClD,MAAM,IAAI,GAAG,WAAW,IAAI,eAAe,EAAE,CAAC;IAC9C,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACpD,OAAO,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7D,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,sBAAsB,CACpC,YAAoB,EACpB,WAAmB,OAAO,CAAC,GAAG,EAAE;IAEhC,MAAM,WAAW,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC9C,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAE9B,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"find-project-root.js","sourceRoot":"","sources":["../../../src/utils/find-project-root.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Main checkout of a Git worktree.
3
+ *
4
+ * SpecWithCode runs threads in linked worktrees outside the project
5
+ * (`~/.specwithcode/<machine>/worktrees/*`), where no `.specweave/` is found by
6
+ * walking up. A linked worktree's `.git` is a file whose `gitdir:` line points
7
+ * into `<main>/.git/worktrees/<name>`, so the main checkout (and the planning
8
+ * root above it) can be found from that line alone.
9
+ *
10
+ * Sync `fs` only and no Git process: the hook launcher inlines the same logic
11
+ * (`plugins/specweave/hooks/run.mjs`, `run-worker.mjs`) and a parity test keeps
12
+ * the copies equal.
13
+ *
14
+ * @module utils/main-checkout
15
+ */
16
+ /**
17
+ * The main checkout of the linked worktree containing `dir`, or null when the
18
+ * nearest `.git` is a directory (an ordinary checkout), a submodule link
19
+ * (`.git/modules/`), unreadable, or absent.
20
+ */
21
+ export declare function mainCheckoutOf(dir: string): string | null;
22
+ /** Top of the linked worktree containing `dir` (the folder holding its `.git` file), or null. */
23
+ export declare function linkedWorktreeRoot(dir: string): string | null;
24
+ /**
25
+ * Where Git commands for work started in `startDir` run. Planning state may
26
+ * resolve to the main checkout (`findEffectiveRoot`), but a thread's branch,
27
+ * diff and pushes live in its own worktree.
28
+ */
29
+ export declare function gitCheckoutFor(startDir: string, planningRoot: string): string;
30
+ //# sourceMappingURL=main-checkout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main-checkout.d.ts","sourceRoot":"","sources":["../../../src/utils/main-checkout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEzD;AAED,iGAAiG;AACjG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAM7E"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Main checkout of a Git worktree.
3
+ *
4
+ * SpecWithCode runs threads in linked worktrees outside the project
5
+ * (`~/.specwithcode/<machine>/worktrees/*`), where no `.specweave/` is found by
6
+ * walking up. A linked worktree's `.git` is a file whose `gitdir:` line points
7
+ * into `<main>/.git/worktrees/<name>`, so the main checkout (and the planning
8
+ * root above it) can be found from that line alone.
9
+ *
10
+ * Sync `fs` only and no Git process: the hook launcher inlines the same logic
11
+ * (`plugins/specweave/hooks/run.mjs`, `run-worker.mjs`) and a parity test keeps
12
+ * the copies equal.
13
+ *
14
+ * @module utils/main-checkout
15
+ */
16
+ import * as fs from 'fs';
17
+ import path from 'path';
18
+ const WORKTREE_GITDIR = /^gitdir:\s*(.*?)[\\/]\.git[\\/]worktrees[\\/][^\\/]+[\\/]?\s*$/;
19
+ /**
20
+ * The main checkout of the linked worktree containing `dir`, or null when the
21
+ * nearest `.git` is a directory (an ordinary checkout), a submodule link
22
+ * (`.git/modules/`), unreadable, or absent.
23
+ */
24
+ export function mainCheckoutOf(dir) {
25
+ return worktreeLink(dir)?.main ?? null;
26
+ }
27
+ /** Top of the linked worktree containing `dir` (the folder holding its `.git` file), or null. */
28
+ export function linkedWorktreeRoot(dir) {
29
+ return worktreeLink(dir)?.root ?? null;
30
+ }
31
+ /**
32
+ * Where Git commands for work started in `startDir` run. Planning state may
33
+ * resolve to the main checkout (`findEffectiveRoot`), but a thread's branch,
34
+ * diff and pushes live in its own worktree.
35
+ */
36
+ export function gitCheckoutFor(startDir, planningRoot) {
37
+ const own = linkedWorktreeRoot(startDir);
38
+ if (!own)
39
+ return planningRoot;
40
+ const rel = path.relative(own, path.resolve(planningRoot));
41
+ const inside = rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel));
42
+ return inside ? planningRoot : own;
43
+ }
44
+ function worktreeLink(dir) {
45
+ let current;
46
+ try {
47
+ current = path.resolve(dir);
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ for (let depth = 0; depth < 100; depth++) {
53
+ const dotGit = path.join(current, '.git');
54
+ try {
55
+ const stat = fs.statSync(dotGit, { throwIfNoEntry: false });
56
+ if (stat) {
57
+ if (!stat.isFile())
58
+ return null;
59
+ const first = fs.readFileSync(dotGit, 'utf8').split(/\r?\n/, 1)[0] ?? '';
60
+ const match = WORKTREE_GITDIR.exec(first.trim());
61
+ return match && match[1] ? { root: current, main: path.resolve(current, match[1]) } : null;
62
+ }
63
+ }
64
+ catch {
65
+ return null;
66
+ }
67
+ const parent = path.dirname(current);
68
+ if (parent === current)
69
+ return null;
70
+ current = parent;
71
+ }
72
+ return null;
73
+ }
74
+ //# sourceMappingURL=main-checkout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main-checkout.js","sourceRoot":"","sources":["../../../src/utils/main-checkout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,eAAe,GAAG,gEAAgE,CAAC;AAEzF;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,YAAY,CAAC,GAAG,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC;AACzC,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,OAAO,YAAY,CAAC,GAAG,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,YAAoB;IACnE,MAAM,GAAG,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,GAAG;QAAE,OAAO,YAAY,CAAC;IAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9E,OAAO,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC;AACrC,CAAC;AAED,SAAS,YAAY,CAAC,GAAW;IAC/B,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;YAC5D,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;oBAAE,OAAO,IAAI,CAAC;gBAChC,MAAM,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBACzE,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;gBACjD,OAAO,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YAC7F,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,MAAM,KAAK,OAAO;YAAE,OAAO,IAAI,CAAC;QACpC,OAAO,GAAG,MAAM,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specweave",
3
- "version": "3.1.5",
3
+ "version": "3.1.7",
4
4
  "description": "Keep intent, specifications, and verified progress portable across AI coding tools. A local live work board, append-only task evidence, explicit handoffs, and optional GitHub/Jira/Azure DevOps integrations.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sw",
3
3
  "description": "Portable intent and verified progress across coding tools. Six core workflow skills plus opt-in grill-me, glossary, sync, project and jev, two default lifecycle hooks, and a deterministic CLI and live local dashboard.",
4
- "version": "3.1.5",
4
+ "version": "3.1.7",
5
5
  "author": {
6
6
  "name": "SpecWeave Team",
7
7
  "url": "https://spec-weave.com"
@@ -21,11 +21,13 @@
21
21
  * Fast path: PreToolUse for a file outside `.specweave/increments/` prints `{}`
22
22
  * without loading the CLI at all (the guards only concern increment files), and
23
23
  * PreToolUse for Bash prints `{}` unless the project opted into the Jev command
24
- * guard with a `.specweave/state/jev-guard.enabled` marker.
24
+ * guard with a `.specweave/state/jev-guard.enabled` marker. Edits outside
25
+ * increments reach the required-increment guard only under a
26
+ * `.specweave/state/require-increment.enabled` marker.
25
27
  */
26
28
  import { createRequire } from 'node:module';
27
29
  import { spawnSync } from 'node:child_process';
28
- import { existsSync, lstatSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
30
+ import { existsSync, lstatSync, mkdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';
29
31
  import { homedir } from 'node:os';
30
32
  import path from 'node:path';
31
33
  import { fileURLToPath, pathToFileURL } from 'node:url';
@@ -66,10 +68,44 @@ const event = process.argv[2] ?? '';
66
68
 
67
69
  /** Opt-in marker for the Jev Bash guard, searched upward from cwd / project dir. */
68
70
  const JEV_GUARD_MARKER = path.join('.specweave', 'state', 'jev-guard.enabled');
71
+ /** Opt-in marker for required increments (`specweave require-increment`): ordinary edits reach the guard. */
72
+ const REQUIRE_INCREMENT_MARKER = path.join('.specweave', 'state', 'require-increment.enabled');
73
+ const EDIT_TOOLS = new Set(['Edit', 'Write', 'MultiEdit', 'NotebookEdit']);
69
74
  const JEV_GUARD_MAX_DEPTH = 8;
70
75
 
71
76
  function hasJevGuardMarker(input) {
72
- const starts = [typeof input.cwd === 'string' ? input.cwd : process.cwd(), process.env.CLAUDE_PROJECT_DIR];
77
+ return hasMarker(input, JEV_GUARD_MARKER);
78
+ }
79
+
80
+ // Main checkout of the linked Git worktree containing `dir`, or null. Keep in
81
+ // step with src/utils/main-checkout.ts (a parity test compares them): the
82
+ // SpecWithCode worktrees live outside the project, so markers are searched from
83
+ // the main checkout too. Sync reads only, no Git process.
84
+ const WORKTREE_GITDIR = /^gitdir:\s*(.*?)[\\/]\.git[\\/]worktrees[\\/][^\\/]+[\\/]?\s*$/;
85
+ function mainCheckoutOf(dir) {
86
+ let current;
87
+ try { current = path.resolve(dir); } catch { return null; }
88
+ for (let depth = 0; depth < 100; depth++) {
89
+ const dotGit = path.join(current, '.git');
90
+ try {
91
+ const stat = statSync(dotGit, { throwIfNoEntry: false });
92
+ if (stat) {
93
+ if (!stat.isFile()) return null;
94
+ const first = readFileSync(dotGit, 'utf8').split(/\r?\n/, 1)[0] ?? '';
95
+ const match = WORKTREE_GITDIR.exec(first.trim());
96
+ return match && match[1] ? path.resolve(current, match[1]) : null;
97
+ }
98
+ } catch { return null; }
99
+ const parent = path.dirname(current);
100
+ if (parent === current) return null;
101
+ current = parent;
102
+ }
103
+ return null;
104
+ }
105
+
106
+ function hasMarker(input, marker) {
107
+ const first = [typeof input.cwd === 'string' ? input.cwd : process.cwd(), process.env.CLAUDE_PROJECT_DIR].filter(Boolean);
108
+ const starts = [...first, ...first.map(mainCheckoutOf)];
73
109
  for (const start of starts) {
74
110
  if (!start) continue;
75
111
  let current;
@@ -80,7 +116,7 @@ function hasJevGuardMarker(input) {
80
116
  }
81
117
  for (let depth = 0; depth < JEV_GUARD_MAX_DEPTH; depth++) {
82
118
  try {
83
- if (existsSync(path.join(current, JEV_GUARD_MARKER))) return true;
119
+ if (existsSync(path.join(current, marker))) return true;
84
120
  } catch {
85
121
  break;
86
122
  }
@@ -158,7 +194,8 @@ function normalizeInput(raw) {
158
194
  event === 'pre-tool-use' &&
159
195
  (tool === 'Bash'
160
196
  ? !hasJevGuardMarker(input)
161
- : !filePath.includes('.specweave/increments/'));
197
+ : !filePath.includes('.specweave/increments/') &&
198
+ !(EDIT_TOOLS.has(tool) && hasMarker(input, REQUIRE_INCREMENT_MARKER)));
162
199
  return { raw: JSON.stringify(input), skip };
163
200
  }
164
201
  } catch {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  // SpecWeave hook supervisor: parent deadline remains live while the worker blocks in Git.
3
3
  import { spawn, spawnSync } from 'node:child_process';
4
- import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
4
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, statSync } from 'node:fs';
5
5
  import { homedir } from 'node:os';
6
6
  import path from 'node:path';
7
7
  import { fileURLToPath } from 'node:url';
@@ -48,28 +48,123 @@ function hasClosePendingFor(data) {
48
48
  // Jev guard with a local marker file.
49
49
  const JEV_GUARD_MARKER = path.join('.specweave', 'state', 'jev-guard.enabled');
50
50
  const JEV_GUARD_MAX_DEPTH = 8;
51
- function hasJevGuardMarker(data) {
52
- const starts = [typeof data.cwd === 'string' ? data.cwd : process.cwd(), process.env.CLAUDE_PROJECT_DIR];
53
- for (const start of starts) {
51
+ // Edits outside increments only matter when the project opted into required
52
+ // increments (`specweave require-increment`), which leaves its own marker; a
53
+ // session or SpecWithCode thread with a small fix there, or a thread bound to
54
+ // an open increment there, skips too.
55
+ const REQUIRE_INCREMENT_MARKER = path.join('.specweave', 'state', 'require-increment.enabled');
56
+ const EDIT_TOOLS = new Set(['Edit', 'Write', 'MultiEdit', 'NotebookEdit']);
57
+ // Main checkout of the linked Git worktree containing `dir`, or null. Keep in
58
+ // step with src/utils/main-checkout.ts (a parity test compares them): the
59
+ // SpecWithCode worktrees live outside the project, so markers are searched from
60
+ // the main checkout too. Sync reads only, no Git process.
61
+ const WORKTREE_GITDIR = /^gitdir:\s*(.*?)[\\/]\.git[\\/]worktrees[\\/][^\\/]+[\\/]?\s*$/;
62
+ function mainCheckoutOf(dir) {
63
+ let current;
64
+ try { current = path.resolve(dir); } catch { return null; }
65
+ for (let depth = 0; depth < 100; depth++) {
66
+ const dotGit = path.join(current, '.git');
67
+ try {
68
+ const stat = statSync(dotGit, { throwIfNoEntry: false });
69
+ if (stat) {
70
+ if (!stat.isFile()) return null;
71
+ const first = readFileSync(dotGit, 'utf8').split(/\r?\n/, 1)[0] ?? '';
72
+ const match = WORKTREE_GITDIR.exec(first.trim());
73
+ return match && match[1] ? path.resolve(current, match[1]) : null;
74
+ }
75
+ } catch { return null; }
76
+ const parent = path.dirname(current);
77
+ if (parent === current) return null;
78
+ current = parent;
79
+ }
80
+ return null;
81
+ }
82
+ function markerStarts(data) {
83
+ const starts = [typeof data.cwd === 'string' ? data.cwd : process.cwd(), process.env.CLAUDE_PROJECT_DIR].filter(Boolean);
84
+ return [...starts, ...starts.map(mainCheckoutOf)];
85
+ }
86
+ function findMarker(data, marker) {
87
+ for (const start of markerStarts(data)) {
54
88
  if (!start) continue;
55
89
  let current;
56
90
  try { current = path.resolve(start); } catch { continue; }
57
91
  for (let depth = 0; depth < JEV_GUARD_MAX_DEPTH; depth++) {
58
- try { if (existsSync(path.join(current, JEV_GUARD_MARKER))) return true; } catch { break; }
92
+ try { if (existsSync(path.join(current, marker))) return current; } catch { break; }
59
93
  const parent = path.dirname(current);
60
94
  if (parent === current) break;
61
95
  current = parent;
62
96
  }
63
97
  }
98
+ return null;
99
+ }
100
+ function hasJevGuardMarker(data) {
101
+ return findMarker(data, JEV_GUARD_MARKER) !== null;
102
+ }
103
+ // A small fix declared in this project by the session, or (Codex, Pi: no
104
+ // session id) by the SpecWithCode thread, keyed `studio-<thread>` and sanitized
105
+ // like workSessionFile. Worktrees count as their main checkout.
106
+ const SAFE_ID = /^[A-Za-z0-9._-]{1,128}$/;
107
+ function sessionWorksIn(data, root) {
108
+ const session = typeof data.session_id === 'string' ? data.session_id : '';
109
+ const thread = (process.env.SPECWEAVE_STUDIO_THREAD_ID ?? '').trim();
110
+ const ids = [session, thread ? `studio-${thread}`.replace(/[^\w.-]/g, '_') : '']
111
+ .filter((id) => SAFE_ID.test(id) && id !== '.' && id !== '..');
112
+ const project = (dir) => path.resolve(mainCheckoutOf(dir) ?? dir);
113
+ for (const id of ids) {
114
+ try {
115
+ const marker = JSON.parse(readFileSync(path.join(homedir(), '.specweave', 'sessions', `${id}.json`), 'utf8'));
116
+ if (marker?.kind !== 'small-fix' || typeof marker.root !== 'string') continue;
117
+ if (path.resolve(marker.root) === root || project(marker.root) === project(root)) return true;
118
+ } catch {}
119
+ }
64
120
  return false;
65
121
  }
122
+ // The SpecWithCode thread is bound to an increment of this project that is not
123
+ // closed: the guard would pass, so skip the worker. Same rule as the guard's
124
+ // binding check, with an exact project match (anything else asks the worker).
125
+ const CLOSED_STATUSES = new Set(['completed', 'abandoned', 'cancelled']);
126
+ function threadBoundIn(root) {
127
+ const thread = (process.env.SPECWEAVE_STUDIO_THREAD_ID ?? '').trim();
128
+ if (!thread) return false;
129
+ try {
130
+ const file = path.join(homedir(), '.specweave', 'studio', 'threads', `${thread.replace(/[^\w.-]/g, '_')}.json`);
131
+ const binding = JSON.parse(readFileSync(file, 'utf8'));
132
+ const id = binding?.incrementId;
133
+ if (typeof binding?.root !== 'string' || !binding.root || typeof id !== 'string' || !SAFE_ID.test(id) || id === '.' || id === '..') return false;
134
+ const project = (dir) => path.resolve(mainCheckoutOf(dir) ?? dir);
135
+ if (path.resolve(binding.root) !== root && project(binding.root) !== project(root)) return false;
136
+ let status = '';
137
+ try { status = String(JSON.parse(readFileSync(path.join(binding.root, '.specweave', 'increments', id, 'metadata.json'), 'utf8'))?.status ?? ''); }
138
+ catch {}
139
+ return !CLOSED_STATUSES.has(status);
140
+ } catch { return false; }
141
+ }
142
+ // `--scope user`: the entry `specweave require-increment` writes to
143
+ // ~/.claude/settings.json runs in every project. It guards nothing (not even
144
+ // increment files) unless an opted-in project's marker is found, and leaves a
145
+ // project whose own entry Claude loaded to that entry (no second worker).
146
+ const USER_SCOPE = process.argv[3] === '--scope' && process.argv[4] === 'user';
147
+ const EDIT_HOOK_MATCHER = 'Edit|Write|MultiEdit|NotebookEdit';
148
+ function projectEntryLoaded(data) {
149
+ const dir = process.env.CLAUDE_PROJECT_DIR || (typeof data.cwd === 'string' ? data.cwd : '');
150
+ if (!dir) return false;
151
+ try {
152
+ const groups = JSON.parse(readFileSync(path.join(dir, '.claude', 'settings.json'), 'utf8'))?.hooks?.PreToolUse;
153
+ return Array.isArray(groups) && groups.some((g) => g?.matcher === EDIT_HOOK_MATCHER && Array.isArray(g.hooks)
154
+ && g.hooks.some((h) => typeof h?.command === 'string' && /hooks\/run\.mjs"?\s+pre-tool-use\s*$/.test(h.command.replace(/\\/g, '/'))));
155
+ } catch { return false; }
156
+ }
66
157
  function skipPreToolUse(data) {
67
158
  const tool = typeof data.tool_name === 'string' ? data.tool_name : '';
159
+ if (USER_SCOPE && (tool === 'Bash' || findMarker(data, REQUIRE_INCREMENT_MARKER) === null || projectEntryLoaded(data))) return true;
68
160
  if (tool === 'Bash') return !hasJevGuardMarker(data);
69
161
  const ti = data.tool_input;
70
162
  const filePath = ti && typeof ti === 'object' && typeof ti.file_path === 'string'
71
163
  ? ti.file_path.replace(/\\/g, '/') : '';
72
- return !filePath.includes('.specweave/increments/');
164
+ if (filePath.includes('.specweave/increments/')) return false;
165
+ if (!EDIT_TOOLS.has(tool)) return true;
166
+ const root = findMarker(data, REQUIRE_INCREMENT_MARKER);
167
+ return root === null || sessionWorksIn(data, root) || threadBoundIn(root);
73
168
  }
74
169
  function record(reason) {
75
170
  try {
@@ -65,7 +65,7 @@ merge and close; do not implement.
65
65
  1. Group tasks into 2 to 5 lanes whose `Files` do not overlap. Shared contracts
66
66
  (types, schema) go in an early task the others list under `**Dependencies**: T-01`.
67
67
  2. One worktree and branch per lane agent (your tool's or app's worktree feature, or
68
- `git worktree add ../0042-api -b inc/0042-api`), with `SPECWEAVE_AGENT=api` set.
68
+ `git worktree add .worktrees/0042-api -b inc/0042-api`, never `../`), with `SPECWEAVE_AGENT=api` set.
69
69
  Brief each one: its tasks, this loop, "edit only their Files", and on finish
70
70
  `specweave task release --all-mine` plus `specweave note "api: done" 0042`.
71
71
  3. Watch with `specweave task list 0042`; `blocked` rows are your queue. A claim older