@opengsd/gsd-pi 1.5.0-dev.4fb2d460 → 1.5.0-dev.c4c8885f

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 (234) hide show
  1. package/dist/resources/.managed-resources-content-hash +1 -1
  2. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +114 -36
  3. package/dist/resources/extensions/gsd/activity-log.js +1 -1
  4. package/dist/resources/extensions/gsd/auto/orchestrator.js +16 -10
  5. package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
  6. package/dist/resources/extensions/gsd/auto-dispatch.js +53 -15
  7. package/dist/resources/extensions/gsd/auto-model-selection.js +28 -1
  8. package/dist/resources/extensions/gsd/auto-post-unit.js +4 -3
  9. package/dist/resources/extensions/gsd/auto-prompts.js +29 -117
  10. package/dist/resources/extensions/gsd/auto-start.js +53 -30
  11. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +12 -2
  12. package/dist/resources/extensions/gsd/auto-timers.js +9 -2
  13. package/dist/resources/extensions/gsd/auto.js +97 -31
  14. package/dist/resources/extensions/gsd/compat/compat-marker.js +44 -0
  15. package/dist/resources/extensions/gsd/config-overlay.js +7 -2
  16. package/dist/resources/extensions/gsd/db/engine.js +33 -0
  17. package/dist/resources/extensions/gsd/db-adapter.js +30 -3
  18. package/dist/resources/extensions/gsd/docs/preferences-reference.md +3 -3
  19. package/dist/resources/extensions/gsd/journal.js +1 -1
  20. package/dist/resources/extensions/gsd/markdown-renderer.js +34 -91
  21. package/dist/resources/extensions/gsd/metrics.js +2 -2
  22. package/dist/resources/extensions/gsd/paths.js +70 -49
  23. package/dist/resources/extensions/gsd/post-unit-hooks.js +27 -0
  24. package/dist/resources/extensions/gsd/preferences-models.js +66 -15
  25. package/dist/resources/extensions/gsd/preferences-validation.js +66 -10
  26. package/dist/resources/extensions/gsd/rule-registry.js +106 -10
  27. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +1 -10
  28. package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +3 -24
  29. package/dist/resources/extensions/gsd/state-reconciliation/index.js +10 -0
  30. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -5
  31. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +16 -10
  32. package/dist/resources/extensions/gsd/tools/validate-milestone.js +3 -8
  33. package/dist/resources/extensions/gsd/uat-dispatch.js +94 -0
  34. package/dist/resources/extensions/gsd/uok/audit-toggle.js +31 -2
  35. package/dist/resources/extensions/gsd/uok/audit.js +3 -0
  36. package/dist/resources/extensions/gsd/uok/gate-runner.js +22 -30
  37. package/dist/resources/extensions/gsd/uok/gitops.js +18 -15
  38. package/dist/resources/extensions/gsd/uok/kernel.js +120 -46
  39. package/dist/resources/extensions/gsd/uok/model-policy.js +17 -14
  40. package/dist/resources/extensions/gsd/workflow-event-ledger.js +1 -1
  41. package/dist/resources/extensions/gsd/workflow-logger.js +1 -1
  42. package/dist/resources/extensions/gsd/workflow-projections.js +9 -26
  43. package/dist/resources/extensions/gsd/workspace.js +5 -14
  44. package/dist/resources/extensions/shared/gsd-browser-cli.js +29 -0
  45. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  46. package/dist/web/standalone/.next/BUILD_ID +1 -1
  47. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  48. package/dist/web/standalone/.next/build-manifest.json +2 -2
  49. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  50. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  51. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  56. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  57. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  58. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  59. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  66. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  67. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  68. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  69. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  70. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  71. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  72. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  73. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  74. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  75. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  76. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  77. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  78. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  79. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  80. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  81. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  82. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  83. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  84. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  85. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  86. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  87. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  88. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  89. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  90. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  91. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  92. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  93. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  94. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  95. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  96. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  97. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  98. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  99. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  100. package/dist/web/standalone/.next/server/app/index.html +1 -1
  101. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  108. package/dist/web/standalone/.next/server/chunks/{1128.js → 1991.js} +1 -1
  109. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  110. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  112. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  113. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  114. package/dist/worktree-cli-create.d.ts +10 -0
  115. package/dist/worktree-cli-create.js +11 -0
  116. package/dist/worktree-cli-format.d.ts +12 -0
  117. package/dist/worktree-cli-format.js +38 -0
  118. package/dist/worktree-cli-plan.d.ts +16 -0
  119. package/dist/worktree-cli-plan.js +19 -0
  120. package/dist/worktree-cli-session.d.ts +13 -0
  121. package/dist/worktree-cli-session.js +18 -0
  122. package/dist/worktree-cli-status.d.ts +35 -0
  123. package/dist/worktree-cli-status.js +54 -0
  124. package/dist/worktree-cli.d.ts +1 -16
  125. package/dist/worktree-cli.js +28 -122
  126. package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
  127. package/integrations/hermes/pyproject.toml +1 -1
  128. package/package.json +1 -1
  129. package/packages/cloud-mcp-gateway/package.json +2 -2
  130. package/packages/contracts/package.json +1 -1
  131. package/packages/daemon/dist/orchestrator-agent.d.ts +21 -0
  132. package/packages/daemon/dist/orchestrator-agent.d.ts.map +1 -0
  133. package/packages/daemon/dist/orchestrator-agent.js +113 -0
  134. package/packages/daemon/dist/orchestrator-agent.js.map +1 -0
  135. package/packages/daemon/dist/orchestrator-tools.d.ts +12 -0
  136. package/packages/daemon/dist/orchestrator-tools.d.ts.map +1 -0
  137. package/packages/daemon/dist/orchestrator-tools.js +137 -0
  138. package/packages/daemon/dist/orchestrator-tools.js.map +1 -0
  139. package/packages/daemon/dist/orchestrator.d.ts +4 -56
  140. package/packages/daemon/dist/orchestrator.d.ts.map +1 -1
  141. package/packages/daemon/dist/orchestrator.js +13 -303
  142. package/packages/daemon/dist/orchestrator.js.map +1 -1
  143. package/packages/daemon/dist/orchestrator.test.js +11 -1
  144. package/packages/daemon/dist/orchestrator.test.js.map +1 -1
  145. package/packages/daemon/package.json +4 -4
  146. package/packages/gsd-agent-core/package.json +5 -5
  147. package/packages/gsd-agent-modes/package.json +7 -7
  148. package/packages/mcp-server/package.json +4 -4
  149. package/packages/native/package.json +1 -1
  150. package/packages/pi-agent-core/package.json +1 -1
  151. package/packages/pi-ai/package.json +1 -1
  152. package/packages/pi-coding-agent/package.json +7 -7
  153. package/packages/pi-tui/package.json +2 -2
  154. package/packages/rpc-client/package.json +2 -2
  155. package/pkg/package.json +1 -1
  156. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +146 -33
  157. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +25 -0
  158. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +93 -0
  159. package/src/resources/extensions/gsd/activity-log.ts +1 -1
  160. package/src/resources/extensions/gsd/auto/orchestrator.ts +17 -11
  161. package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -1
  162. package/src/resources/extensions/gsd/auto-dispatch.ts +59 -14
  163. package/src/resources/extensions/gsd/auto-model-selection.ts +33 -1
  164. package/src/resources/extensions/gsd/auto-post-unit.ts +4 -2
  165. package/src/resources/extensions/gsd/auto-prompts.ts +53 -113
  166. package/src/resources/extensions/gsd/auto-start.ts +57 -28
  167. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -2
  168. package/src/resources/extensions/gsd/auto-timers.ts +9 -2
  169. package/src/resources/extensions/gsd/auto.ts +103 -30
  170. package/src/resources/extensions/gsd/compat/compat-marker.ts +47 -0
  171. package/src/resources/extensions/gsd/config-overlay.ts +7 -1
  172. package/src/resources/extensions/gsd/db/engine.ts +36 -0
  173. package/src/resources/extensions/gsd/db-adapter.ts +29 -3
  174. package/src/resources/extensions/gsd/docs/preferences-reference.md +3 -3
  175. package/src/resources/extensions/gsd/journal.ts +1 -1
  176. package/src/resources/extensions/gsd/markdown-renderer.ts +52 -103
  177. package/src/resources/extensions/gsd/metrics.ts +2 -2
  178. package/src/resources/extensions/gsd/paths.ts +87 -48
  179. package/src/resources/extensions/gsd/post-unit-hooks.ts +32 -0
  180. package/src/resources/extensions/gsd/preferences-models.ts +74 -20
  181. package/src/resources/extensions/gsd/preferences-types.ts +24 -1
  182. package/src/resources/extensions/gsd/preferences-validation.ts +77 -9
  183. package/src/resources/extensions/gsd/rule-registry.ts +111 -9
  184. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +1 -9
  185. package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +2 -22
  186. package/src/resources/extensions/gsd/state-reconciliation/index.ts +14 -0
  187. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +41 -2
  188. package/src/resources/extensions/gsd/tests/auto-post-unit-artifact-diagnostic.test.ts +48 -1
  189. package/src/resources/extensions/gsd/tests/auto-start-project-milestone-reconcile.test.ts +29 -1
  190. package/src/resources/extensions/gsd/tests/auto-timeout-recovery-supervisor-inflight-guard.test.ts +159 -0
  191. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +3 -1
  192. package/src/resources/extensions/gsd/tests/compat-marker.test.ts +85 -0
  193. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +45 -0
  194. package/src/resources/extensions/gsd/tests/db-adapter.test.ts +39 -0
  195. package/src/resources/extensions/gsd/tests/db-writable-probe.test.ts +66 -0
  196. package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +22 -1
  197. package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +72 -32
  198. package/src/resources/extensions/gsd/tests/integration/paths.test.ts +88 -1
  199. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +2 -1
  200. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +0 -1
  201. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +269 -0
  202. package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +8 -1
  203. package/src/resources/extensions/gsd/tests/read-uat-gate-verdict.test.ts +54 -0
  204. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +49 -1
  205. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +95 -1
  206. package/src/resources/extensions/gsd/tests/sibling-model-fallbacks.test.ts +189 -0
  207. package/src/resources/extensions/gsd/tests/single-field-model-thinking.test.ts +156 -0
  208. package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +6 -1
  209. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +32 -0
  210. package/src/resources/extensions/gsd/tests/supervisor-model-swap-inflight-guard.test.ts +181 -0
  211. package/src/resources/extensions/gsd/tests/supervisor-model-swap-thinking-clamp.test.ts +122 -0
  212. package/src/resources/extensions/gsd/tests/uat-dispatch.test.ts +211 -0
  213. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +39 -0
  214. package/src/resources/extensions/gsd/tests/uok-kernel-path.test.ts +226 -2
  215. package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +6 -0
  216. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +213 -2
  217. package/src/resources/extensions/gsd/tools/complete-milestone.ts +9 -5
  218. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +19 -8
  219. package/src/resources/extensions/gsd/tools/validate-milestone.ts +13 -9
  220. package/src/resources/extensions/gsd/types.ts +23 -4
  221. package/src/resources/extensions/gsd/uat-dispatch.ts +176 -0
  222. package/src/resources/extensions/gsd/uok/audit-toggle.ts +32 -2
  223. package/src/resources/extensions/gsd/uok/audit.ts +2 -0
  224. package/src/resources/extensions/gsd/uok/gate-runner.ts +26 -36
  225. package/src/resources/extensions/gsd/uok/gitops.ts +21 -18
  226. package/src/resources/extensions/gsd/uok/kernel.ts +169 -48
  227. package/src/resources/extensions/gsd/uok/model-policy.ts +20 -17
  228. package/src/resources/extensions/gsd/workflow-event-ledger.ts +1 -1
  229. package/src/resources/extensions/gsd/workflow-logger.ts +1 -1
  230. package/src/resources/extensions/gsd/workflow-projections.ts +9 -24
  231. package/src/resources/extensions/gsd/workspace.ts +5 -21
  232. package/src/resources/extensions/shared/gsd-browser-cli.ts +29 -0
  233. /package/dist/web/standalone/.next/static/{gXoWec4UNqcR0tkuHwYCr → NPMNi2HV8BuK3baQsEUhk}/_buildManifest.js +0 -0
  234. /package/dist/web/standalone/.next/static/{gXoWec4UNqcR0tkuHwYCr → NPMNi2HV8BuK3baQsEUhk}/_ssgManifest.js +0 -0
@@ -1,6 +1,7 @@
1
1
  import type { TaskMetadata } from "../complexity-classifier.js";
2
2
  import { computeTaskRequirements, filterToolsForProvider } from "../model-router.js";
3
3
  import { buildAuditEnvelope, emitUokAuditEvent } from "./audit.js";
4
+ import { isUnifiedAuditEnabled } from "./audit-toggle.js";
4
5
 
5
6
  export interface ModelCandidate {
6
7
  id: string;
@@ -83,23 +84,25 @@ export function applyModelPolicyFilter<T extends ModelCandidate>(
83
84
  };
84
85
  decisions.push(decision);
85
86
 
86
- emitUokAuditEvent(
87
- options.basePath,
88
- buildAuditEnvelope({
89
- traceId: options.traceId,
90
- turnId: options.turnId,
91
- category: "model-policy",
92
- type: allowed ? "model-policy-allow" : "model-policy-deny",
93
- payload: {
94
- modelId: model.id,
95
- provider: model.provider,
96
- api: model.api,
97
- reason,
98
- unitType: options.unitType,
99
- requirements,
100
- },
101
- }),
102
- );
87
+ if (isUnifiedAuditEnabled(options.basePath)) {
88
+ emitUokAuditEvent(
89
+ options.basePath,
90
+ buildAuditEnvelope({
91
+ traceId: options.traceId,
92
+ turnId: options.turnId,
93
+ category: "model-policy",
94
+ type: allowed ? "model-policy-allow" : "model-policy-deny",
95
+ payload: {
96
+ modelId: model.id,
97
+ provider: model.provider,
98
+ api: model.api,
99
+ reason,
100
+ unitType: options.unitType,
101
+ requirements,
102
+ },
103
+ }),
104
+ );
105
+ }
103
106
 
104
107
  if (allowed) eligible.push(model);
105
108
  }
@@ -105,7 +105,7 @@ export function writeWorktreeEventLog(
105
105
  }
106
106
 
107
107
  function emitWorkflowEventAudit(basePath: string, event: WorkflowEvent): void {
108
- if (!isUnifiedAuditEnabled()) return;
108
+ if (!isUnifiedAuditEnabled(basePath)) return;
109
109
  try {
110
110
  const normalized = normalizeWorkflowEventCommand(event.cmd) ?? "unknown";
111
111
  emitUokAuditEvent(
@@ -302,7 +302,7 @@ function _push(
302
302
  _buffer.shift();
303
303
  }
304
304
 
305
- if (_auditBasePath && isUnifiedAuditEnabled()) {
305
+ if (_auditBasePath && isUnifiedAuditEnabled(_auditBasePath)) {
306
306
  try {
307
307
  emitUokAuditEvent(
308
308
  _auditBasePath,
@@ -17,7 +17,7 @@ import type { MilestoneRow } from "./db-milestone-artifact-rows.js";
17
17
  import type { SliceRow, TaskRow } from "./db-task-slice-rows.js";
18
18
  import type { VerificationEvidenceRow } from "./db-verification-evidence-rows.js";
19
19
  import { atomicWriteSync } from "./atomic-write.js";
20
- import { join } from "node:path";
20
+ import { dirname, join } from "node:path";
21
21
  import { mkdirSync, existsSync } from "node:fs";
22
22
  import { readFile } from "node:fs/promises";
23
23
  import { logWarning } from "./workflow-logger.js";
@@ -26,7 +26,7 @@ import { deriveState } from "./state.js";
26
26
  import type { GSDState } from "./types.js";
27
27
  import { renderPlanFromDb, renderRoadmapFromDb } from "./markdown-renderer.js";
28
28
  import { readManifest } from "./workflow-manifest.js";
29
- import { gsdRoot, resolveSliceFile, resolveMilestonePath, resolveSlicePath, gsdProjectionRoot } from "./paths.js";
29
+ import { gsdRoot, resolveMilestoneFile, resolveSliceFile, resolveTaskFile, relTaskFile } from "./paths.js";
30
30
 
31
31
  // ─── Helpers ─────────────────────────────────────────────────────────────
32
32
 
@@ -329,24 +329,10 @@ export function renderSummaryProjection(basePath: string, milestoneId: string, s
329
329
  const evidenceRows = getVerificationEvidence(milestoneId, sliceId, taskId);
330
330
  const content = renderSummaryContent(taskRow, sliceId, milestoneId, evidenceRows);
331
331
 
332
- // Layout-aware: avoid creating a milestones/ directory as a side effect for
333
- // flat-phase projects. If milestonesDir() sees a freshly-created milestones/
334
- // dir it treats the project as legacy, breaking all subsequent path resolution.
335
- const slicePath = resolveSlicePath(basePath, milestoneId, sliceId);
336
- const phaseDir = resolveMilestonePath(basePath, milestoneId);
337
- let dir: string;
338
- if (slicePath && phaseDir && slicePath !== phaseDir) {
339
- // Legacy layout: slice has its own slices/SID/ subdir → tasks/ subdir
340
- dir = join(slicePath, "tasks");
341
- } else if (phaseDir) {
342
- // Flat-phase: task summaries go in the phase dir (no tasks/ subdir needed)
343
- dir = phaseDir;
344
- } else {
345
- // Fallback: legacy hardcoded path (milestone dir not on disk yet)
346
- dir = join(gsdProjectionRoot(basePath), "milestones", milestoneId, "slices", sliceId, "tasks");
347
- }
348
- mkdirSync(dir, { recursive: true });
349
- atomicWriteSync(join(dir, `${taskId}-SUMMARY.md`), content);
332
+ const summaryPath = resolveTaskFile(basePath, milestoneId, sliceId, taskId, "SUMMARY")
333
+ ?? join(basePath, relTaskFile(basePath, milestoneId, sliceId, taskId, "SUMMARY", getMilestone(milestoneId)?.title));
334
+ mkdirSync(dirname(summaryPath), { recursive: true });
335
+ atomicWriteSync(summaryPath, content);
350
336
  }
351
337
 
352
338
  // ─── STATE.md Projection ────────────────────────────────────────────────
@@ -536,7 +522,7 @@ export async function regenerateIfMissing(
536
522
  filePath = resolveSliceFile(basePath, milestoneId, sliceId, "PLAN") ?? "";
537
523
  break;
538
524
  case "ROADMAP":
539
- filePath = join(basePath, ".gsd", "milestones", milestoneId, `${milestoneId}-ROADMAP.md`);
525
+ filePath = resolveMilestoneFile(basePath, milestoneId, "ROADMAP") ?? "";
540
526
  break;
541
527
  case "SUMMARY":
542
528
  // For SUMMARY, we regenerate all task summaries in the slice
@@ -553,8 +539,7 @@ export async function regenerateIfMissing(
553
539
  const doneTasks = taskRows.filter(t => t.status === "done" || t.status === "complete");
554
540
  let regenerated = 0;
555
541
  for (const task of doneTasks) {
556
- const summaryPath = join(basePath, ".gsd", "milestones", milestoneId, "slices", sliceId, "tasks", `${task.id}-SUMMARY.md`);
557
- if (!existsSync(summaryPath)) {
542
+ if (!resolveTaskFile(basePath, milestoneId, sliceId, task.id, "SUMMARY")) {
558
543
  try {
559
544
  renderSummaryProjection(basePath, milestoneId, sliceId, task.id);
560
545
  regenerated++;
@@ -591,7 +576,7 @@ export async function regenerateIfMissing(
591
576
  return !!(resolveSliceFile(basePath, milestoneId, sliceId, "PLAN"));
592
577
  case "ROADMAP":
593
578
  await renderRoadmapFromDb(basePath, milestoneId);
594
- return existsSync(filePath);
579
+ return !!resolveMilestoneFile(basePath, milestoneId, "ROADMAP");
595
580
  case "STATE":
596
581
  await renderStateProjection(basePath);
597
582
  return existsSync(filePath);
@@ -2,14 +2,11 @@
2
2
 
3
3
  import { dirname, join, resolve } from "node:path";
4
4
  import {
5
- buildMilestoneFileName,
6
- canonicalPhaseDirName,
7
- isLegacyMilestonesLayout,
8
- milestonesDir,
9
5
  type GsdPathContract,
10
6
  resolveGsdPathContract,
11
7
  resolveMilestoneFile,
12
8
  resolveMilestonePath,
9
+ targetMilestoneFile,
13
10
  normalizeRealPath,
14
11
  } from "./paths.js";
15
12
  import { isGsdWorktreePath, resolveWorktreeProjectRoot } from "./worktree-root.js";
@@ -41,27 +38,14 @@ function tryRealpath(p: string): string {
41
38
  return normalizeRealPath(p);
42
39
  }
43
40
 
44
- function isLegacyMilestoneDirectory(dir: string): boolean {
45
- const parent = dirname(dir);
46
- return parent.endsWith("/milestones") || parent.endsWith("\\milestones");
47
- }
48
-
49
41
  function scopeMilestoneDir(basePath: string, milestoneId: string): string {
50
- return resolveMilestonePath(basePath, milestoneId) ?? join(
51
- milestonesDir(basePath),
52
- isLegacyMilestonesLayout(basePath) ? milestoneId : canonicalPhaseDirName(milestoneId),
53
- );
42
+ return resolveMilestonePath(basePath, milestoneId)
43
+ ?? dirname(targetMilestoneFile(basePath, milestoneId, "ROADMAP"));
54
44
  }
55
45
 
56
46
  function scopeMilestoneFile(basePath: string, milestoneId: string, suffix: string): string {
57
- const existing = resolveMilestoneFile(basePath, milestoneId, suffix);
58
- if (existing) return existing;
59
-
60
- const dir = scopeMilestoneDir(basePath, milestoneId);
61
- const filename = isLegacyMilestoneDirectory(dir)
62
- ? `${milestoneId}-${suffix}.md`
63
- : buildMilestoneFileName(milestoneId, suffix);
64
- return join(dir, filename);
47
+ return resolveMilestoneFile(basePath, milestoneId, suffix)
48
+ ?? targetMilestoneFile(basePath, milestoneId, suffix);
65
49
  }
66
50
 
67
51
  /**
@@ -66,6 +66,30 @@ function splitCommandLine(commandLine: string): string[] {
66
66
  });
67
67
  }
68
68
 
69
+ /**
70
+ * Extra gsd-browser CLI flags to forward verbatim to the launched daemon, from
71
+ * GSD_BROWSER_MCP_EXTRA_ARGS. Unlike GSD_BROWSER_MCP_ARGS (a full args override),
72
+ * these are *appended* to the default `mcp`/`daemon start` invocation so callers
73
+ * keep the managed session/identity flags. Accepts a JSON array (e.g.
74
+ * `["--stealth"]`) or a plain, optionally-quoted command-line string
75
+ * (e.g. `--stealth --browser-path /usr/bin/chromium`). This is the config-level
76
+ * knob for environments where Chrome needs extra launch flags — e.g. containers
77
+ * without unprivileged user namespaces, where `--stealth` supplies Chrome's
78
+ * `--no-sandbox`.
79
+ */
80
+ function resolveExtraGsdBrowserArgs(env: NodeJS.ProcessEnv): string[] {
81
+ const raw = env.GSD_BROWSER_MCP_EXTRA_ARGS?.trim();
82
+ if (!raw) return [];
83
+ if (raw.startsWith("[")) {
84
+ const parsed = parseJsonEnv<unknown>(env, "GSD_BROWSER_MCP_EXTRA_ARGS");
85
+ if (!Array.isArray(parsed)) {
86
+ throw new Error("GSD_BROWSER_MCP_EXTRA_ARGS JSON must be an array of strings");
87
+ }
88
+ return parsed.map(String);
89
+ }
90
+ return splitCommandLine(raw);
91
+ }
92
+
69
93
  function buildPathGsdBrowserVersionInvocation(platform: NodeJS.Platform): { command: string; args: string[] } {
70
94
  if (platform === "win32") {
71
95
  return { command: "cmd", args: ["/d", "/s", "/c", "gsd-browser", "--version"] };
@@ -297,6 +321,10 @@ export function resolveGsdBrowserMcpLaunchConfig(
297
321
  || (preferPathCli ? "gsd-browser" : undefined)
298
322
  || (bundledCliPath ? process.execPath : undefined)
299
323
  || "gsd-browser";
324
+ // Appended after the managed session/identity flags so they survive the
325
+ // daemon-start transformation (which forwards everything after `mcp`), letting
326
+ // callers add extra Chrome/gsd-browser launch flags via one config knob.
327
+ const extraArgs = resolveExtraGsdBrowserArgs(env);
300
328
  const args = Array.isArray(explicitArgs) && explicitArgs.length > 0
301
329
  ? explicitArgs.map(String)
302
330
  : [
@@ -311,6 +339,7 @@ export function resolveGsdBrowserMcpLaunchConfig(
311
339
  identityKey,
312
340
  "--identity-project",
313
341
  identityProject,
342
+ ...extraArgs,
314
343
  ];
315
344
  const cwd = env.GSD_BROWSER_MCP_CWD?.trim() || resolvedProjectRoot;
316
345