@opengsd/gsd-pi 1.1.1-dev.9bb7453 → 1.1.1-dev.9f86580

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 (219) hide show
  1. package/dist/resources/.managed-resources-content-hash +1 -1
  2. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +18 -2
  3. package/dist/resources/extensions/browser-tools/engine/selection.js +1 -1
  4. package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
  5. package/dist/resources/extensions/browser-tools/index.js +29 -2
  6. package/dist/resources/extensions/browser-tools/web-app-detect.js +52 -0
  7. package/dist/resources/extensions/gsd/auto/phases.js +45 -3
  8. package/dist/resources/extensions/gsd/auto/session.js +2 -0
  9. package/dist/resources/extensions/gsd/auto-dispatch.js +21 -2
  10. package/dist/resources/extensions/gsd/auto-model-selection.js +26 -0
  11. package/dist/resources/extensions/gsd/auto-prompts.js +4 -0
  12. package/dist/resources/extensions/gsd/auto-recovery.js +3 -4
  13. package/dist/resources/extensions/gsd/auto-timers.js +24 -10
  14. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +18 -66
  15. package/dist/resources/extensions/gsd/auto-worktree.js +18 -5
  16. package/dist/resources/extensions/gsd/auto.js +26 -4
  17. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +16 -10
  18. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +48 -29
  19. package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
  20. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +18 -29
  21. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +61 -0
  22. package/dist/resources/extensions/gsd/commands/handlers/auto.js +10 -0
  23. package/dist/resources/extensions/gsd/commands-mcp-status.js +1 -1
  24. package/dist/resources/extensions/gsd/config-overlay.js +1 -0
  25. package/dist/resources/extensions/gsd/context-masker.js +129 -5
  26. package/dist/resources/extensions/gsd/guided-flow.js +93 -108
  27. package/dist/resources/extensions/gsd/milestone-closeout.js +3 -1
  28. package/dist/resources/extensions/gsd/pending-auto-start.js +0 -1
  29. package/dist/resources/extensions/gsd/planner-handoff.js +98 -0
  30. package/dist/resources/extensions/gsd/preferences-models.js +1 -0
  31. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  32. package/dist/resources/extensions/gsd/prompts/run-uat.md +5 -19
  33. package/dist/resources/extensions/gsd/prompts/system.md +1 -1
  34. package/dist/resources/extensions/gsd/recovery-classification.js +20 -0
  35. package/dist/resources/extensions/gsd/skill-manifest.js +12 -0
  36. package/dist/resources/extensions/gsd/tool-contract.js +6 -1
  37. package/dist/resources/extensions/gsd/tool-presentation-plan.js +47 -7
  38. package/dist/resources/extensions/gsd/tools/complete-slice.js +28 -1
  39. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +113 -8
  40. package/dist/resources/extensions/gsd/unit-tool-contracts.js +193 -0
  41. package/dist/resources/extensions/gsd/workflow-mcp.js +5 -78
  42. package/dist/resources/extensions/gsd/worktree-manager.js +26 -0
  43. package/dist/resources/extensions/gsd/worktree-reentry.js +96 -0
  44. package/dist/resources/extensions/shared/gsd-browser-cli.js +6 -0
  45. package/dist/web/standalone/.next/BUILD_ID +1 -1
  46. package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
  47. package/dist/web/standalone/.next/build-manifest.json +2 -2
  48. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  49. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  50. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  51. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  56. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  57. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  58. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app/index.html +1 -1
  66. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  67. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  68. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  69. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  70. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app-paths-manifest.json +5 -5
  73. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  74. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  75. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  76. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  77. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  78. package/package.json +1 -1
  79. package/packages/cloud-mcp-gateway/package.json +2 -2
  80. package/packages/contracts/package.json +1 -1
  81. package/packages/daemon/package.json +4 -4
  82. package/packages/gsd-agent-core/package.json +5 -5
  83. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  84. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
  85. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  86. package/packages/gsd-agent-modes/package.json +7 -7
  87. package/packages/mcp-server/package.json +3 -3
  88. package/packages/native/package.json +1 -1
  89. package/packages/pi-agent-core/dist/agent-loop.js +4 -3
  90. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  91. package/packages/pi-agent-core/dist/harness/agent-harness.d.ts.map +1 -1
  92. package/packages/pi-agent-core/dist/harness/agent-harness.js +3 -1
  93. package/packages/pi-agent-core/dist/harness/agent-harness.js.map +1 -1
  94. package/packages/pi-agent-core/dist/harness/types.d.ts +1 -0
  95. package/packages/pi-agent-core/dist/harness/types.d.ts.map +1 -1
  96. package/packages/pi-agent-core/dist/harness/types.js.map +1 -1
  97. package/packages/pi-agent-core/dist/types.d.ts +3 -1
  98. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  99. package/packages/pi-agent-core/dist/types.js.map +1 -1
  100. package/packages/pi-agent-core/package.json +1 -1
  101. package/packages/pi-ai/dist/models.generated.d.ts +157 -18
  102. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  103. package/packages/pi-ai/dist/models.generated.js +159 -36
  104. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  105. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  106. package/packages/pi-ai/dist/providers/transform-messages.js +8 -1
  107. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  108. package/packages/pi-ai/package.json +1 -1
  109. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +3 -0
  110. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
  111. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
  112. package/packages/pi-coding-agent/dist/core/tools/bash.js +2 -2
  113. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  114. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  115. package/packages/pi-coding-agent/dist/core/tools/edit.js +3 -2
  116. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  117. package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts +1 -0
  118. package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts.map +1 -1
  119. package/packages/pi-coding-agent/dist/core/tools/render-utils.js +6 -0
  120. package/packages/pi-coding-agent/dist/core/tools/render-utils.js.map +1 -1
  121. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  122. package/packages/pi-coding-agent/dist/core/tools/write.js +3 -2
  123. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  124. package/packages/pi-coding-agent/package.json +7 -7
  125. package/packages/pi-tui/package.json +1 -1
  126. package/packages/rpc-client/package.json +2 -2
  127. package/pkg/package.json +1 -1
  128. package/scripts/install/handoff.js +16 -3
  129. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +21 -2
  130. package/src/resources/extensions/browser-tools/engine/selection.ts +1 -1
  131. package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
  132. package/src/resources/extensions/browser-tools/index.ts +36 -5
  133. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +2 -2
  134. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +37 -0
  135. package/src/resources/extensions/browser-tools/tests/web-app-detect.test.mjs +68 -0
  136. package/src/resources/extensions/browser-tools/web-app-detect.ts +63 -0
  137. package/src/resources/extensions/gsd/auto/phases.ts +48 -6
  138. package/src/resources/extensions/gsd/auto/session.ts +2 -0
  139. package/src/resources/extensions/gsd/auto-dispatch.ts +48 -2
  140. package/src/resources/extensions/gsd/auto-model-selection.ts +26 -0
  141. package/src/resources/extensions/gsd/auto-prompts.ts +4 -0
  142. package/src/resources/extensions/gsd/auto-recovery.ts +3 -3
  143. package/src/resources/extensions/gsd/auto-timers.ts +25 -9
  144. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +43 -74
  145. package/src/resources/extensions/gsd/auto-worktree.ts +23 -5
  146. package/src/resources/extensions/gsd/auto.ts +28 -4
  147. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +16 -10
  148. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +63 -29
  149. package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
  150. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +50 -54
  151. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +137 -0
  152. package/src/resources/extensions/gsd/commands/handlers/auto.ts +9 -0
  153. package/src/resources/extensions/gsd/commands-mcp-status.ts +1 -1
  154. package/src/resources/extensions/gsd/config-overlay.ts +1 -0
  155. package/src/resources/extensions/gsd/context-masker.ts +152 -5
  156. package/src/resources/extensions/gsd/guided-flow.ts +128 -135
  157. package/src/resources/extensions/gsd/milestone-closeout.ts +3 -1
  158. package/src/resources/extensions/gsd/pending-auto-start.ts +0 -2
  159. package/src/resources/extensions/gsd/planner-handoff.ts +149 -0
  160. package/src/resources/extensions/gsd/preferences-models.ts +1 -0
  161. package/src/resources/extensions/gsd/preferences-types.ts +8 -0
  162. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  163. package/src/resources/extensions/gsd/prompts/run-uat.md +5 -19
  164. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  165. package/src/resources/extensions/gsd/recovery-classification.ts +20 -0
  166. package/src/resources/extensions/gsd/skill-manifest.ts +12 -0
  167. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +99 -0
  168. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +66 -4
  169. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +10 -2
  170. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +4 -1
  171. package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +4 -0
  172. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +12 -2
  173. package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +9 -0
  174. package/src/resources/extensions/gsd/tests/check-auto-start-pending-gate.test.ts +9 -15
  175. package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +26 -16
  176. package/src/resources/extensions/gsd/tests/commands-dispatcher-unmerged-milestone.test.ts +21 -0
  177. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +118 -0
  178. package/src/resources/extensions/gsd/tests/context-masker.test.ts +56 -1
  179. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +1 -0
  180. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +40 -1
  181. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +24 -0
  182. package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +31 -79
  183. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +5 -3
  184. package/src/resources/extensions/gsd/tests/guided-flow-state-rebuild.test.ts +40 -4
  185. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +8 -0
  186. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +16 -0
  187. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +7 -1
  188. package/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +27 -0
  189. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +1 -0
  190. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +7 -1
  191. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +1 -1
  192. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +63 -0
  193. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +10 -1
  194. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +9 -1
  195. package/src/resources/extensions/gsd/tests/planner-handoff.test.ts +100 -0
  196. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +147 -5
  197. package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +55 -0
  198. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +44 -0
  199. package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +4 -0
  200. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +56 -0
  201. package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +4 -3
  202. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -4
  203. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +77 -10
  204. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +409 -0
  205. package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +102 -0
  206. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +15 -0
  207. package/src/resources/extensions/gsd/tool-contract.ts +7 -1
  208. package/src/resources/extensions/gsd/tool-presentation-plan.ts +82 -7
  209. package/src/resources/extensions/gsd/tools/complete-slice.ts +29 -1
  210. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +146 -9
  211. package/src/resources/extensions/gsd/unit-tool-contracts.ts +210 -0
  212. package/src/resources/extensions/gsd/workflow-mcp.ts +5 -78
  213. package/src/resources/extensions/gsd/worktree-manager.ts +32 -0
  214. package/src/resources/extensions/gsd/worktree-reentry.ts +103 -0
  215. package/src/resources/extensions/shared/gsd-browser-cli.ts +6 -0
  216. package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound-corrections.test.ts +0 -246
  217. package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound.test.ts +0 -218
  218. /package/dist/web/standalone/.next/static/{jBtwT9v1u2lUA3UEOy_ZH → zzYMrKpPGfRQRxSFO32Jr}/_buildManifest.js +0 -0
  219. /package/dist/web/standalone/.next/static/{jBtwT9v1u2lUA3UEOy_ZH → zzYMrKpPGfRQRxSFO32Jr}/_ssgManifest.js +0 -0
@@ -0,0 +1,210 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Central Unit-to-tool contracts for phase-aware GSD tool surfaces.
3
+
4
+ export interface UnitToolSurfaceContract {
5
+ allowedGsdTools: readonly string[];
6
+ requiredWorkflowTools: readonly string[];
7
+ forbiddenGsdTools?: Readonly<Record<string, string>>;
8
+ }
9
+
10
+ export const RUN_UAT_WORKFLOW_TOOL_NAMES = [
11
+ "gsd_uat_exec",
12
+ "gsd_uat_result_save",
13
+ "gsd_resume",
14
+ "gsd_milestone_status",
15
+ "gsd_journal_query",
16
+ ] as const;
17
+
18
+ export const RUN_UAT_READ_ONLY_TOOL_NAMES = [
19
+ "find",
20
+ "glob",
21
+ "grep",
22
+ "ls",
23
+ "read",
24
+ ] as const;
25
+
26
+ export const RUN_UAT_BROWSER_TOOL_NAMES = [
27
+ "browser_navigate",
28
+ "browser_click",
29
+ "browser_type",
30
+ "browser_fill_form",
31
+ "browser_click_ref",
32
+ "browser_fill_ref",
33
+ "browser_wait_for",
34
+ "browser_assert",
35
+ "browser_verify",
36
+ "browser_screenshot",
37
+ "browser_snapshot_refs",
38
+ "browser_find",
39
+ "browser_get_console_logs",
40
+ "browser_get_network_logs",
41
+ "browser_evaluate",
42
+ "browser_reload",
43
+ "browser_batch",
44
+ "browser_act",
45
+ ] as const;
46
+
47
+ export const RUN_UAT_TOOL_PRESENTATION_PLAN_ID = "run-uat/default-v1";
48
+
49
+ export const UNIT_TOOL_CONTRACTS: Record<string, UnitToolSurfaceContract> = {
50
+ "research-milestone": {
51
+ allowedGsdTools: ["gsd_summary_save", "gsd_decision_save"],
52
+ requiredWorkflowTools: ["gsd_summary_save"],
53
+ },
54
+ "plan-milestone": {
55
+ allowedGsdTools: [
56
+ "gsd_milestone_status",
57
+ "gsd_plan_milestone",
58
+ "gsd_plan_slice",
59
+ "gsd_decision_save",
60
+ "gsd_requirement_update",
61
+ ],
62
+ requiredWorkflowTools: ["gsd_milestone_status", "gsd_plan_milestone", "gsd_plan_slice"],
63
+ },
64
+ "discuss-milestone": {
65
+ allowedGsdTools: [
66
+ "gsd_summary_save",
67
+ "gsd_decision_save",
68
+ "gsd_requirement_save",
69
+ "gsd_requirement_update",
70
+ "gsd_plan_milestone",
71
+ "gsd_milestone_generate_id",
72
+ ],
73
+ requiredWorkflowTools: [
74
+ "gsd_summary_save",
75
+ "gsd_requirement_save",
76
+ "gsd_requirement_update",
77
+ "gsd_plan_milestone",
78
+ "gsd_milestone_generate_id",
79
+ ],
80
+ },
81
+ "discuss-slice": {
82
+ allowedGsdTools: ["gsd_summary_save", "gsd_decision_save"],
83
+ requiredWorkflowTools: ["gsd_summary_save"],
84
+ },
85
+ "validate-milestone": {
86
+ allowedGsdTools: ["gsd_milestone_status", "gsd_validate_milestone", "gsd_reassess_roadmap", "subagent"],
87
+ requiredWorkflowTools: ["gsd_milestone_status", "gsd_validate_milestone", "gsd_reassess_roadmap"],
88
+ },
89
+ "complete-milestone": {
90
+ allowedGsdTools: [
91
+ "gsd_milestone_status",
92
+ "gsd_requirement_update",
93
+ "gsd_summary_save",
94
+ "gsd_complete_milestone",
95
+ "subagent",
96
+ ],
97
+ requiredWorkflowTools: [
98
+ "gsd_milestone_status",
99
+ "gsd_requirement_update",
100
+ "gsd_summary_save",
101
+ "gsd_complete_milestone",
102
+ ],
103
+ },
104
+ "research-slice": {
105
+ allowedGsdTools: ["gsd_summary_save", "gsd_decision_save"],
106
+ requiredWorkflowTools: ["gsd_summary_save"],
107
+ },
108
+ "plan-slice": {
109
+ allowedGsdTools: ["gsd_plan_slice", "gsd_reassess_roadmap", "gsd_decision_save"],
110
+ requiredWorkflowTools: ["gsd_plan_slice", "gsd_reassess_roadmap"],
111
+ },
112
+ "refine-slice": {
113
+ allowedGsdTools: ["gsd_plan_slice", "gsd_decision_save"],
114
+ requiredWorkflowTools: ["gsd_plan_slice"],
115
+ },
116
+ "replan-slice": {
117
+ allowedGsdTools: ["gsd_replan_slice", "gsd_decision_save"],
118
+ requiredWorkflowTools: ["gsd_replan_slice"],
119
+ },
120
+ "complete-slice": {
121
+ allowedGsdTools: [
122
+ "gsd_slice_complete",
123
+ "gsd_task_reopen",
124
+ "gsd_replan_slice",
125
+ "gsd_decision_save",
126
+ "gsd_requirement_update",
127
+ "gsd_summary_save",
128
+ "subagent",
129
+ ],
130
+ requiredWorkflowTools: [
131
+ "gsd_slice_complete",
132
+ "gsd_task_reopen",
133
+ "gsd_replan_slice",
134
+ "gsd_requirement_update",
135
+ "gsd_summary_save",
136
+ ],
137
+ forbiddenGsdTools: {
138
+ gsd_uat_result_save: "Run UAT owns persisted UAT Assessment.",
139
+ },
140
+ },
141
+ "reassess-roadmap": {
142
+ allowedGsdTools: ["gsd_milestone_status", "gsd_reassess_roadmap"],
143
+ requiredWorkflowTools: ["gsd_milestone_status", "gsd_reassess_roadmap"],
144
+ },
145
+ "execute-task": {
146
+ allowedGsdTools: ["gsd_task_complete", "gsd_decision_save"],
147
+ requiredWorkflowTools: ["gsd_task_complete"],
148
+ },
149
+ "execute-task-simple": {
150
+ allowedGsdTools: ["gsd_task_complete", "gsd_decision_save"],
151
+ requiredWorkflowTools: ["gsd_task_complete"],
152
+ },
153
+ "reactive-execute": {
154
+ allowedGsdTools: ["gsd_task_complete", "gsd_summary_save", "gsd_decision_save"],
155
+ requiredWorkflowTools: ["gsd_task_complete", "gsd_summary_save"],
156
+ },
157
+ "run-uat": {
158
+ allowedGsdTools: [...RUN_UAT_WORKFLOW_TOOL_NAMES, "subagent"],
159
+ requiredWorkflowTools: [...RUN_UAT_WORKFLOW_TOOL_NAMES],
160
+ forbiddenGsdTools: {
161
+ gsd_exec: "Use gsd_uat_exec so acceptance evidence is typed as UAT-owned.",
162
+ gsd_save_gate_result: "gsd_uat_result_save owns the aggregate UAT gate.",
163
+ gsd_summary_save: "gsd_uat_result_save owns persisted UAT Assessment writes.",
164
+ },
165
+ },
166
+ "gate-evaluate": {
167
+ allowedGsdTools: ["gsd_save_gate_result"],
168
+ requiredWorkflowTools: ["gsd_save_gate_result"],
169
+ },
170
+ "rewrite-docs": {
171
+ allowedGsdTools: ["gsd_summary_save", "gsd_decision_save"],
172
+ requiredWorkflowTools: [],
173
+ },
174
+ "workflow-preferences": {
175
+ allowedGsdTools: ["gsd_summary_save"],
176
+ requiredWorkflowTools: [],
177
+ },
178
+ "discuss-project": {
179
+ allowedGsdTools: ["gsd_summary_save", "gsd_decision_save", "gsd_requirement_save"],
180
+ requiredWorkflowTools: ["ask_user_questions", "gsd_summary_save"],
181
+ },
182
+ "discuss-requirements": {
183
+ allowedGsdTools: ["gsd_requirement_save", "gsd_summary_save"],
184
+ requiredWorkflowTools: ["ask_user_questions", "gsd_requirement_save", "gsd_summary_save"],
185
+ },
186
+ "research-decision": {
187
+ allowedGsdTools: ["gsd_summary_save"],
188
+ requiredWorkflowTools: ["ask_user_questions"],
189
+ },
190
+ "research-project": {
191
+ allowedGsdTools: ["gsd_summary_save", "gsd_decision_save"],
192
+ requiredWorkflowTools: [],
193
+ },
194
+ };
195
+
196
+ export const AUTO_UNIT_SCOPED_TOOLS: Record<string, readonly string[]> = Object.fromEntries(
197
+ Object.entries(UNIT_TOOL_CONTRACTS).map(([unitType, contract]) => [unitType, contract.allowedGsdTools]),
198
+ );
199
+
200
+ export function getUnitToolSurfaceContract(unitType: string): UnitToolSurfaceContract | undefined {
201
+ return UNIT_TOOL_CONTRACTS[unitType];
202
+ }
203
+
204
+ export function getRequiredWorkflowToolsForUnit(unitType: string): string[] {
205
+ return [...(UNIT_TOOL_CONTRACTS[unitType]?.requiredWorkflowTools ?? [])];
206
+ }
207
+
208
+ export function getForbiddenGsdToolReason(unitType: string, toolName: string): string | undefined {
209
+ return UNIT_TOOL_CONTRACTS[unitType]?.forbiddenGsdTools?.[toolName];
210
+ }
@@ -2,7 +2,7 @@ import { execSync } from "node:child_process";
2
2
  import { existsSync, realpathSync } from "node:fs";
3
3
  import { dirname, resolve, sep } from "node:path";
4
4
  import { fileURLToPath, pathToFileURL } from "node:url";
5
- import { RUN_UAT_WORKFLOW_TOOL_NAMES } from "./tool-presentation-plan.js";
5
+ import { getRequiredWorkflowToolsForUnit } from "./unit-tool-contracts.js";
6
6
 
7
7
  type WorkflowExecutorsModule = typeof import("./tools/workflow-tool-executors.js");
8
8
 
@@ -414,83 +414,11 @@ export function buildWorkflowMcpServers(
414
414
  }
415
415
 
416
416
  export function getRequiredWorkflowToolsForGuidedUnit(unitType: string): string[] {
417
- switch (unitType) {
418
- case "discuss-project":
419
- return ["ask_user_questions", "gsd_summary_save"];
420
- case "discuss-requirements":
421
- return ["ask_user_questions", "gsd_requirement_save", "gsd_summary_save"];
422
- case "research-decision":
423
- return ["ask_user_questions"];
424
- case "discuss-milestone":
425
- return [
426
- "gsd_summary_save",
427
- "gsd_requirement_save",
428
- "gsd_requirement_update",
429
- "gsd_plan_milestone",
430
- "gsd_milestone_generate_id",
431
- ];
432
- case "discuss-slice":
433
- return ["gsd_summary_save"];
434
- case "research-milestone":
435
- case "research-slice":
436
- return ["gsd_summary_save"];
437
- case "plan-milestone":
438
- return ["gsd_plan_milestone"];
439
- case "plan-slice":
440
- return ["gsd_plan_slice"];
441
- case "execute-task":
442
- return ["gsd_task_complete"];
443
- case "complete-slice":
444
- return ["gsd_slice_complete", "gsd_task_reopen", "gsd_replan_slice"];
445
- default:
446
- return [];
447
- }
417
+ return getRequiredWorkflowToolsForUnit(unitType);
448
418
  }
449
419
 
450
420
  export function getRequiredWorkflowToolsForAutoUnit(unitType: string): string[] {
451
- switch (unitType) {
452
- case "discuss-project":
453
- return ["ask_user_questions", "gsd_summary_save"];
454
- case "discuss-requirements":
455
- return ["ask_user_questions", "gsd_requirement_save", "gsd_summary_save"];
456
- case "research-decision":
457
- return ["ask_user_questions"];
458
- case "discuss-milestone":
459
- return [
460
- "gsd_summary_save",
461
- "gsd_requirement_save",
462
- "gsd_requirement_update",
463
- "gsd_plan_milestone",
464
- "gsd_milestone_generate_id",
465
- ];
466
- case "research-milestone":
467
- case "research-slice":
468
- return ["gsd_summary_save"];
469
- case "run-uat":
470
- return [...RUN_UAT_WORKFLOW_TOOL_NAMES];
471
- case "plan-milestone":
472
- return ["gsd_plan_milestone"];
473
- case "plan-slice":
474
- return ["gsd_plan_slice"];
475
- case "execute-task":
476
- case "execute-task-simple":
477
- case "reactive-execute":
478
- return ["gsd_task_complete"];
479
- case "complete-slice":
480
- return ["gsd_slice_complete", "gsd_task_reopen", "gsd_replan_slice"];
481
- case "replan-slice":
482
- return ["gsd_replan_slice"];
483
- case "reassess-roadmap":
484
- return ["gsd_milestone_status", "gsd_reassess_roadmap"];
485
- case "gate-evaluate":
486
- return ["gsd_save_gate_result"];
487
- case "validate-milestone":
488
- return ["gsd_milestone_status", "gsd_validate_milestone", "gsd_reassess_roadmap"];
489
- case "complete-milestone":
490
- return ["gsd_milestone_status", "gsd_complete_milestone"];
491
- default:
492
- return [];
493
- }
421
+ return getRequiredWorkflowToolsForUnit(unitType);
494
422
  }
495
423
 
496
424
  export function usesWorkflowMcpTransport(
@@ -559,10 +487,9 @@ export function getWorkflowTransportSupportError(
559
487
  }
560
488
 
561
489
  const uniqueRequired = [...new Set(requiredTools)];
562
- const piRuntimeRequired = uniqueRequired.filter((tool) => !MCP_WORKFLOW_TOOL_SURFACE.has(tool));
563
490
  const missing = (options.activeTools && options.activeTools.length > 0)
564
- ? piRuntimeRequired.filter((tool) => !hasRequiredTool(tool, options.activeTools!))
565
- : piRuntimeRequired;
491
+ ? uniqueRequired.filter((tool) => !hasRequiredTool(tool, options.activeTools!))
492
+ : uniqueRequired.filter((tool) => !MCP_WORKFLOW_TOOL_SURFACE.has(tool));
566
493
  if (missing.length === 0) return null;
567
494
 
568
495
  if (options.activeTools && options.activeTools.length > 0) {
@@ -259,6 +259,38 @@ export function resolveCanonicalMilestoneRoot(
259
259
  return wtPath;
260
260
  }
261
261
 
262
+ /**
263
+ * Build human-facing guidance for manually validating a milestone's work.
264
+ *
265
+ * When a milestone runs in a git worktree, its checkout lives under the hidden
266
+ * `.gsd/worktrees/<MID>/` path that a human can't easily discover. The UAT
267
+ * pause/handoff and the saved assessment use this to tell the human exactly
268
+ * where to `cd` to run or inspect the app before signing off on NEEDS-HUMAN
269
+ * checks, rather than leaving them to hunt for a buried path.
270
+ *
271
+ * Returns null when no milestone id is available.
272
+ */
273
+ export function buildManualValidationGuidance(
274
+ basePath: string,
275
+ milestoneId: string,
276
+ opts: { uatPath?: string } = {},
277
+ ): string | null {
278
+ if (!milestoneId) return null;
279
+ const validationRoot = resolveCanonicalMilestoneRoot(basePath, milestoneId);
280
+ const inWorktree = validationRoot.includes(`${sep}.gsd${sep}worktrees${sep}`);
281
+ const lines: string[] = [`Validate the work here: ${validationRoot}`];
282
+ if (inWorktree) {
283
+ lines.push(
284
+ "This milestone runs in a git worktree, so the code lives under the hidden " +
285
+ `\`.gsd/worktrees/\` path. Open it with: cd "${validationRoot}"`,
286
+ );
287
+ }
288
+ if (opts.uatPath) {
289
+ lines.push(`Follow the UAT checklist at: ${opts.uatPath}`);
290
+ }
291
+ return lines.join("\n");
292
+ }
293
+
262
294
  // ─── Core Operations ───────────────────────────────────────────────────────
263
295
 
264
296
  /**
@@ -0,0 +1,103 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Deterministically re-enter the active milestone's worktree on a
3
+ // cold start (after /quit + relaunch). Without this, Claude Code relaunches with
4
+ // cwd at the project root, and a bare /gsd leaves the agent there — forcing it to
5
+ // search the filesystem ("git worktree list", branch sniffing) to find its way
6
+ // back into the worktree. The worktree path is fully derivable from state, so we
7
+ // resolve and chdir into it directly instead.
8
+
9
+ import { readdirSync } from "node:fs";
10
+
11
+ import { enterAutoWorktree, getAutoWorktreePath } from "./auto-worktree.js";
12
+ import { getIsolationMode } from "./preferences.js";
13
+ import { worktreesDir } from "./worktree-manager.js";
14
+ import { isGsdWorktreePath, resolveWorktreeProjectRoot } from "./worktree-root.js";
15
+
16
+ interface LiveWorktree {
17
+ id: string;
18
+ path: string;
19
+ }
20
+
21
+ /**
22
+ * Enumerate the live (valid git) auto-worktrees under <projectRoot>/.gsd/worktrees/.
23
+ * Reuses getAutoWorktreePath's validation so stray directories are ignored.
24
+ */
25
+ function liveMilestoneWorktrees(projectRoot: string): LiveWorktree[] {
26
+ let names: string[];
27
+ try {
28
+ names = readdirSync(worktreesDir(projectRoot));
29
+ } catch {
30
+ return [];
31
+ }
32
+ const live: LiveWorktree[] = [];
33
+ for (const id of names) {
34
+ const path = getAutoWorktreePath(projectRoot, id);
35
+ if (path) live.push({ id, path });
36
+ }
37
+ return live;
38
+ }
39
+
40
+ /**
41
+ * If we're sitting at the project root with worktree isolation enabled and the
42
+ * active milestone has a live worktree, chdir into it. No-op when already inside
43
+ * a worktree, when isolation is off, or when the target is ambiguous.
44
+ *
45
+ * Single live worktree → enter it (covers the common case without deriveState).
46
+ * Multiple live worktrees → disambiguate by the active milestone from state;
47
+ * if that can't be resolved unambiguously, do nothing.
48
+ *
49
+ * Best-effort: any failure resolves to a no-op so it can never block startup.
50
+ *
51
+ * @returns the worktree path entered, or null when nothing was done.
52
+ */
53
+ export async function reenterActiveWorktreeIfNeeded(
54
+ basePath: string,
55
+ opts: { notify?: (message: string) => void } = {},
56
+ ): Promise<string | null> {
57
+ let projectRoot: string;
58
+ try {
59
+ projectRoot = resolveWorktreeProjectRoot(basePath);
60
+ } catch {
61
+ return null;
62
+ }
63
+
64
+ // Only worktree-isolation projects have worktrees to re-enter.
65
+ if (getIsolationMode(projectRoot) !== "worktree") return null;
66
+
67
+ // Already inside a worktree (warm session, or auto-mode already entered) —
68
+ // nothing to do.
69
+ let cwd: string;
70
+ try {
71
+ cwd = process.cwd();
72
+ } catch {
73
+ return null;
74
+ }
75
+ if (isGsdWorktreePath(cwd)) return null;
76
+
77
+ const live = liveMilestoneWorktrees(projectRoot);
78
+ if (live.length === 0) return null;
79
+
80
+ let target: LiveWorktree | null = live.length === 1 ? live[0]! : null;
81
+ if (!target) {
82
+ // Multiple live worktrees — disambiguate by the active milestone.
83
+ try {
84
+ const { deriveState } = await import("./state.js");
85
+ const state = await deriveState(projectRoot);
86
+ const activeId = state.activeMilestone?.id;
87
+ target = activeId ? live.find((w) => w.id === activeId) ?? null : null;
88
+ } catch {
89
+ target = null;
90
+ }
91
+ }
92
+ if (!target) return null;
93
+
94
+ try {
95
+ const entered = enterAutoWorktree(projectRoot, target.id);
96
+ opts.notify?.(`Resumed in worktree for ${target.id}.`);
97
+ return entered;
98
+ } catch {
99
+ // Worktree vanished or chdir failed — leave cwd as-is, caller falls back to
100
+ // the project root.
101
+ return null;
102
+ }
103
+ }
@@ -140,6 +140,10 @@ export function resolveGsdBrowserMcpLaunchConfig(
140
140
  : null;
141
141
  const sessionName =
142
142
  options.sessionName?.trim() || buildGsdBrowserSessionName(resolvedProjectRoot, options.sessionSuffix);
143
+ // Stable per-project identity key (no per-session suffix) so the browser
144
+ // profile/cookies persist across pi sessions for the same project. gsd-browser
145
+ // rejects --identity-scope unless --identity-key is also supplied.
146
+ const identityKey = env.GSD_BROWSER_IDENTITY_KEY?.trim() || buildGsdBrowserSessionName(resolvedProjectRoot);
143
147
  const command =
144
148
  explicitCommand
145
149
  || explicitCliPath
@@ -155,6 +159,8 @@ export function resolveGsdBrowserMcpLaunchConfig(
155
159
  sessionName,
156
160
  "--identity-scope",
157
161
  "project",
162
+ "--identity-key",
163
+ identityKey,
158
164
  "--identity-project",
159
165
  resolvedProjectRoot,
160
166
  ];