gsd-pi 2.44.0-dev.62b5d6c → 2.44.0-dev.a5271fc

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 (198) hide show
  1. package/README.md +30 -12
  2. package/dist/resources/extensions/gsd/auto-start.js +10 -0
  3. package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -12
  4. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
  5. package/dist/resources/extensions/gsd/preferences.js +9 -1
  6. package/dist/resources/extensions/gsd/state.js +19 -2
  7. package/dist/web/standalone/.next/BUILD_ID +1 -1
  8. package/dist/web/standalone/.next/app-path-routes-manifest.json +19 -19
  9. package/dist/web/standalone/.next/build-manifest.json +2 -2
  10. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  11. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  12. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  13. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  14. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  15. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  16. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  17. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  18. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  19. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  20. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  21. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  22. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  23. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  24. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  25. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  26. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  27. package/dist/web/standalone/.next/server/app/index.html +1 -1
  28. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  29. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  30. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  31. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  32. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  33. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  34. package/dist/web/standalone/.next/server/app-paths-manifest.json +19 -19
  35. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  36. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  37. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  38. package/package.json +1 -1
  39. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
  40. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  41. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
  42. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  43. package/packages/pi-coding-agent/dist/core/fs-utils.test.js +29 -48
  44. package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
  45. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
  46. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  47. package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
  48. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  49. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
  50. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  51. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
  52. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
  53. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
  54. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
  55. package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
  56. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
  57. package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
  58. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
  59. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
  60. package/src/resources/extensions/gsd/auto-start.ts +14 -0
  61. package/src/resources/extensions/gsd/bootstrap/system-context.ts +48 -11
  62. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
  63. package/src/resources/extensions/gsd/preferences.ts +11 -1
  64. package/src/resources/extensions/gsd/state.ts +19 -1
  65. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
  66. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
  67. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
  68. package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
  69. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +465 -523
  70. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
  71. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
  72. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +533 -656
  73. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
  74. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
  75. package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
  76. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
  77. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
  78. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
  79. package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
  80. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +38 -59
  81. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +228 -263
  82. package/src/resources/extensions/gsd/tests/complete-task.test.ts +250 -302
  83. package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
  84. package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
  85. package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
  86. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
  87. package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
  88. package/src/resources/extensions/gsd/tests/db-writer.test.ts +390 -420
  89. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
  90. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +68 -83
  91. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +183 -181
  92. package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
  93. package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
  94. package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
  95. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
  96. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +164 -180
  97. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
  98. package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
  99. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +27 -29
  100. package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
  101. package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +54 -75
  102. package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +21 -32
  103. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
  104. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +38 -44
  105. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
  106. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
  107. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +54 -60
  108. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
  109. package/src/resources/extensions/gsd/tests/doctor.test.ts +104 -134
  110. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
  111. package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
  112. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
  113. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
  114. package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +30 -42
  115. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +198 -206
  116. package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
  117. package/src/resources/extensions/gsd/tests/git-service.test.ts +285 -388
  118. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
  119. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
  120. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
  121. package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
  122. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +81 -103
  123. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
  124. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
  125. package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
  126. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -102
  127. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
  128. package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
  129. package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
  130. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
  131. package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
  132. package/src/resources/extensions/gsd/tests/knowledge.test.ts +89 -0
  133. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +150 -194
  134. package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
  135. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
  136. package/src/resources/extensions/gsd/tests/memory-store.test.ts +80 -93
  137. package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
  138. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +83 -93
  139. package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
  140. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
  141. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
  142. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +87 -96
  143. package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +125 -164
  144. package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
  145. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +35 -36
  146. package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
  147. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
  148. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
  149. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
  150. package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
  151. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
  152. package/src/resources/extensions/gsd/tests/parsers.test.ts +546 -611
  153. package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
  154. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
  155. package/src/resources/extensions/gsd/tests/preferences.test.ts +27 -0
  156. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
  157. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
  158. package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
  159. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
  160. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
  161. package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
  162. package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
  163. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
  164. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
  165. package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
  166. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
  167. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
  168. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
  169. package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
  170. package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
  171. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
  172. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +19 -26
  173. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
  174. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
  175. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
  176. package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
  177. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
  178. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +9 -11
  179. package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
  180. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
  181. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
  182. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
  183. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
  184. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
  185. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
  186. package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
  187. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
  188. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
  189. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
  190. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
  191. package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
  192. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
  193. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
  194. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
  195. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
  196. package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
  197. /package/dist/web/standalone/.next/static/{fOnWQBjWXMKUs4bqTg530 → JyimLR2pZuvKEzv26gI3w}/_buildManifest.js +0 -0
  198. /package/dist/web/standalone/.next/static/{fOnWQBjWXMKUs4bqTg530 → JyimLR2pZuvKEzv26gI3w}/_ssgManifest.js +0 -0
@@ -17,9 +17,9 @@ import {
17
17
  } from "../worktree.ts";
18
18
  import { readIntegrationBranch } from "../git-service.ts";
19
19
  import { _resetHasChangesCache } from "../native-git-bridge.ts";
20
- import { createTestContext } from './test-helpers.ts';
20
+ import { describe, test } from 'node:test';
21
+ import assert from 'node:assert/strict';
21
22
 
22
- const { assertEq, assertTrue, report } = createTestContext();
23
23
 
24
24
  /**
25
25
  * Normalize a path for reliable comparison on Windows CI runners.
@@ -47,56 +47,56 @@ writeFileSync(join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-PLA
47
47
  run("git add .", base);
48
48
  run('git commit -m "chore: init"', base);
49
49
 
50
- async function main(): Promise<void> {
50
+ describe('worktree', async () => {
51
51
 
52
52
  console.log("\n=== autoCommitCurrentBranch ===");
53
53
  // Clean — should return null
54
54
  const cleanResult = autoCommitCurrentBranch(base, "execute-task", "M001/S01/T01");
55
- assertEq(cleanResult, null, "returns null for clean repo");
55
+ assert.deepStrictEqual(cleanResult, null, "returns null for clean repo");
56
56
 
57
57
  // Make dirty — reset the nativeHasChanges cache so the fresh dirt is detected
58
58
  _resetHasChangesCache();
59
59
  writeFileSync(join(base, "dirty.txt"), "uncommitted\n", "utf-8");
60
60
  const dirtyResult = autoCommitCurrentBranch(base, "execute-task", "M001/S01/T01");
61
- assertTrue(dirtyResult !== null, "returns commit message for dirty repo");
62
- assertTrue(dirtyResult!.includes("M001/S01/T01"), "commit message includes unit id");
63
- assertEq(run("git status --short", base), "", "repo is clean after auto-commit");
61
+ assert.ok(dirtyResult !== null, "returns commit message for dirty repo");
62
+ assert.ok(dirtyResult!.includes("M001/S01/T01"), "commit message includes unit id");
63
+ assert.deepStrictEqual(run("git status --short", base), "", "repo is clean after auto-commit");
64
64
 
65
65
  console.log("\n=== getSliceBranchName ===");
66
- assertEq(getSliceBranchName("M001", "S01"), "gsd/M001/S01", "branch name format correct");
67
- assertEq(getSliceBranchName("M001", "S01", null), "gsd/M001/S01", "null worktree = plain branch");
68
- assertEq(getSliceBranchName("M001", "S01", "my-wt"), "gsd/my-wt/M001/S01", "worktree-namespaced branch");
66
+ assert.deepStrictEqual(getSliceBranchName("M001", "S01"), "gsd/M001/S01", "branch name format correct");
67
+ assert.deepStrictEqual(getSliceBranchName("M001", "S01", null), "gsd/M001/S01", "null worktree = plain branch");
68
+ assert.deepStrictEqual(getSliceBranchName("M001", "S01", "my-wt"), "gsd/my-wt/M001/S01", "worktree-namespaced branch");
69
69
 
70
70
  console.log("\n=== parseSliceBranch ===");
71
71
  const plain = parseSliceBranch("gsd/M001/S01");
72
- assertTrue(plain !== null, "parses plain branch");
73
- assertEq(plain!.worktreeName, null, "plain branch has no worktree name");
74
- assertEq(plain!.milestoneId, "M001", "plain branch milestone");
75
- assertEq(plain!.sliceId, "S01", "plain branch slice");
72
+ assert.ok(plain !== null, "parses plain branch");
73
+ assert.deepStrictEqual(plain!.worktreeName, null, "plain branch has no worktree name");
74
+ assert.deepStrictEqual(plain!.milestoneId, "M001", "plain branch milestone");
75
+ assert.deepStrictEqual(plain!.sliceId, "S01", "plain branch slice");
76
76
 
77
77
  const namespaced = parseSliceBranch("gsd/feature-auth/M001/S01");
78
- assertTrue(namespaced !== null, "parses worktree-namespaced branch");
79
- assertEq(namespaced!.worktreeName, "feature-auth", "worktree name extracted");
80
- assertEq(namespaced!.milestoneId, "M001", "namespaced branch milestone");
81
- assertEq(namespaced!.sliceId, "S01", "namespaced branch slice");
78
+ assert.ok(namespaced !== null, "parses worktree-namespaced branch");
79
+ assert.deepStrictEqual(namespaced!.worktreeName, "feature-auth", "worktree name extracted");
80
+ assert.deepStrictEqual(namespaced!.milestoneId, "M001", "namespaced branch milestone");
81
+ assert.deepStrictEqual(namespaced!.sliceId, "S01", "namespaced branch slice");
82
82
 
83
83
  const invalid = parseSliceBranch("main");
84
- assertEq(invalid, null, "non-slice branch returns null");
84
+ assert.deepStrictEqual(invalid, null, "non-slice branch returns null");
85
85
 
86
86
  const worktreeBranch = parseSliceBranch("worktree/foo");
87
- assertEq(worktreeBranch, null, "worktree/ prefix is not a slice branch");
87
+ assert.deepStrictEqual(worktreeBranch, null, "worktree/ prefix is not a slice branch");
88
88
 
89
89
  console.log("\n=== SLICE_BRANCH_RE ===");
90
- assertTrue(SLICE_BRANCH_RE.test("gsd/M001/S01"), "regex matches plain branch");
91
- assertTrue(SLICE_BRANCH_RE.test("gsd/my-wt/M001/S01"), "regex matches worktree branch");
92
- assertTrue(!SLICE_BRANCH_RE.test("main"), "regex rejects main");
93
- assertTrue(!SLICE_BRANCH_RE.test("gsd/"), "regex rejects bare gsd/");
94
- assertTrue(!SLICE_BRANCH_RE.test("worktree/foo"), "regex rejects worktree/foo");
90
+ assert.ok(SLICE_BRANCH_RE.test("gsd/M001/S01"), "regex matches plain branch");
91
+ assert.ok(SLICE_BRANCH_RE.test("gsd/my-wt/M001/S01"), "regex matches worktree branch");
92
+ assert.ok(!SLICE_BRANCH_RE.test("main"), "regex rejects main");
93
+ assert.ok(!SLICE_BRANCH_RE.test("gsd/"), "regex rejects bare gsd/");
94
+ assert.ok(!SLICE_BRANCH_RE.test("worktree/foo"), "regex rejects worktree/foo");
95
95
 
96
96
  console.log("\n=== detectWorktreeName ===");
97
- assertEq(detectWorktreeName("/projects/myapp"), null, "no worktree in plain path");
98
- assertEq(detectWorktreeName("/projects/myapp/.gsd/worktrees/feature-auth"), "feature-auth", "detects worktree name");
99
- assertEq(detectWorktreeName("/projects/myapp/.gsd/worktrees/my-wt/subdir"), "my-wt", "detects worktree with subdir");
97
+ assert.deepStrictEqual(detectWorktreeName("/projects/myapp"), null, "no worktree in plain path");
98
+ assert.deepStrictEqual(detectWorktreeName("/projects/myapp/.gsd/worktrees/feature-auth"), "feature-auth", "detects worktree name");
99
+ assert.deepStrictEqual(detectWorktreeName("/projects/myapp/.gsd/worktrees/my-wt/subdir"), "my-wt", "detects worktree with subdir");
100
100
 
101
101
  // ═══════════════════════════════════════════════════════════════════════
102
102
  // Integration branch — facade-level tests
@@ -115,16 +115,16 @@ async function main(): Promise<void> {
115
115
  run("git add -A && git commit -m init", repo);
116
116
 
117
117
  run("git checkout -b f-123-thing", repo);
118
- assertEq(getCurrentBranch(repo), "f-123-thing", "on feature branch");
118
+ assert.deepStrictEqual(getCurrentBranch(repo), "f-123-thing", "on feature branch");
119
119
 
120
120
  const commitsBefore = run("git rev-list --count HEAD", repo);
121
121
  captureIntegrationBranch(repo, "M001");
122
- assertEq(readIntegrationBranch(repo, "M001"), "f-123-thing",
122
+ assert.deepStrictEqual(readIntegrationBranch(repo, "M001"), "f-123-thing",
123
123
  "captureIntegrationBranch records the current branch");
124
124
 
125
125
  // Metadata is stored in external state, not committed to git.
126
126
  const commitsAfter = run("git rev-list --count HEAD", repo);
127
- assertEq(commitsAfter, commitsBefore, "captureIntegrationBranch does not create a git commit");
127
+ assert.deepStrictEqual(commitsAfter, commitsBefore, "captureIntegrationBranch does not create a git commit");
128
128
 
129
129
  rmSync(repo, { recursive: true, force: true });
130
130
  }
@@ -144,7 +144,7 @@ async function main(): Promise<void> {
144
144
  run("git checkout -b gsd/M001/S01", repo);
145
145
  captureIntegrationBranch(repo, "M001");
146
146
 
147
- assertEq(readIntegrationBranch(repo, "M001"), null,
147
+ assert.deepStrictEqual(readIntegrationBranch(repo, "M001"), null,
148
148
  "capture from slice branch is a no-op");
149
149
 
150
150
  rmSync(repo, { recursive: true, force: true });
@@ -167,12 +167,12 @@ async function main(): Promise<void> {
167
167
 
168
168
  // Without milestone set, getMainBranch returns "main"
169
169
  setActiveMilestoneId(repo, null);
170
- assertEq(getMainBranch(repo), "main",
170
+ assert.deepStrictEqual(getMainBranch(repo), "main",
171
171
  "getMainBranch returns main without milestone set");
172
172
 
173
173
  // With milestone set, getMainBranch returns feature branch
174
174
  setActiveMilestoneId(repo, "M001");
175
- assertEq(getMainBranch(repo), "my-feature",
175
+ assert.deepStrictEqual(getMainBranch(repo), "my-feature",
176
176
  "getMainBranch returns integration branch with milestone set");
177
177
 
178
178
  rmSync(repo, { recursive: true, force: true });
@@ -180,22 +180,22 @@ async function main(): Promise<void> {
180
180
 
181
181
  // ── detectWorktreeName: symlink-resolved paths ───────────────────────────
182
182
  console.log("\n=== detectWorktreeName (symlink-resolved paths) ===");
183
- assertEq(
183
+ assert.deepStrictEqual(
184
184
  detectWorktreeName("/Users/fran/.gsd/projects/89e1c9ad49bf/worktrees/M001"),
185
185
  "M001",
186
186
  "detects milestone in symlink-resolved path",
187
187
  );
188
- assertEq(
188
+ assert.deepStrictEqual(
189
189
  detectWorktreeName("/Users/fran/.gsd/projects/abc123/worktrees/M002/subdir"),
190
190
  "M002",
191
191
  "detects milestone with trailing subdir in symlink-resolved path",
192
192
  );
193
- assertEq(
193
+ assert.deepStrictEqual(
194
194
  detectWorktreeName("/Users/fran/.gsd/projects/abc123"),
195
195
  null,
196
196
  "returns null for project root without worktrees segment",
197
197
  );
198
- assertEq(
198
+ assert.deepStrictEqual(
199
199
  detectWorktreeName("/foo/.gsd/worktrees/M001"),
200
200
  "M001",
201
201
  "still detects direct layout path",
@@ -211,7 +211,7 @@ async function main(): Promise<void> {
211
211
 
212
212
  // With GSD_PROJECT_ROOT env var set (layer 1 — coordinator passes it)
213
213
  process.env.GSD_PROJECT_ROOT = "/real/project";
214
- assertEq(
214
+ assert.deepStrictEqual(
215
215
  resolveProjectRoot("/Users/fran/.gsd/projects/89e1c9ad49bf/worktrees/M001"),
216
216
  "/real/project",
217
217
  "uses GSD_PROJECT_ROOT when set",
@@ -219,7 +219,7 @@ async function main(): Promise<void> {
219
219
  delete process.env.GSD_PROJECT_ROOT;
220
220
 
221
221
  // Without GSD_PROJECT_ROOT, direct layout still works (no ~/.gsd collision)
222
- assertEq(
222
+ assert.deepStrictEqual(
223
223
  resolveProjectRoot("/some/repo"),
224
224
  "/some/repo",
225
225
  "ignores GSD_PROJECT_ROOT override for non-worktree paths",
@@ -227,19 +227,19 @@ async function main(): Promise<void> {
227
227
  delete process.env.GSD_PROJECT_ROOT;
228
228
 
229
229
  // Without GSD_PROJECT_ROOT, direct layout still works (no ~/.gsd collision)
230
- assertEq(
230
+ assert.deepStrictEqual(
231
231
  resolveProjectRoot("/foo/.gsd/worktrees/M001"),
232
232
  "/foo",
233
233
  "still resolves direct layout path",
234
234
  );
235
- assertEq(
235
+ assert.deepStrictEqual(
236
236
  resolveProjectRoot("/some/repo"),
237
237
  "/some/repo",
238
238
  "returns unchanged for non-worktree path",
239
239
  );
240
240
 
241
241
  // Without GSD_PROJECT_ROOT, direct layout with nested subdirs
242
- assertEq(
242
+ assert.deepStrictEqual(
243
243
  resolveProjectRoot("/data/.gsd/worktrees/M003/nested"),
244
244
  "/data",
245
245
  "resolves correctly with nested subdirs after worktree name (direct layout)",
@@ -264,7 +264,7 @@ async function main(): Promise<void> {
264
264
  mkdirSync(deep, { recursive: true });
265
265
 
266
266
  process.env.GSD_HOME = join(fakeHome, ".gsd");
267
- assertEq(
267
+ assert.deepStrictEqual(
268
268
  normalizePath(resolveProjectRoot(realpathSync(deep))),
269
269
  normalizePath(project),
270
270
  "resolves to real project root from deep symlink-resolved worktree path",
@@ -276,10 +276,4 @@ async function main(): Promise<void> {
276
276
  }
277
277
 
278
278
  rmSync(base, { recursive: true, force: true });
279
- report();
280
- }
281
-
282
- main().catch((error) => {
283
- console.error(error);
284
- process.exit(1);
285
279
  });