@opengsd/gsd-pi 1.2.0-dev.844675c9 → 1.2.0-dev.955e4da0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-web-branch.d.ts +2 -0
- package/dist/cli-web-branch.js +9 -2
- package/dist/help-text.js +5 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/ask-user-questions.js +78 -23
- package/dist/resources/extensions/bg-shell/utilities.js +2 -2
- package/dist/resources/extensions/claude-code-cli/models.js +9 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +92 -230
- package/dist/resources/extensions/claude-code-cli/turn-assembler.js +224 -0
- package/dist/resources/extensions/github-sync/templates.js +3 -3
- package/dist/resources/extensions/gsd/artifact-projection.js +14 -0
- package/dist/resources/extensions/gsd/auto/loop.js +74 -56
- package/dist/resources/extensions/gsd/auto/orchestrator.js +142 -15
- package/dist/resources/extensions/gsd/auto/phases.js +34 -4
- package/dist/resources/extensions/gsd/auto/run-unit.js +2 -1
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +16 -4
- package/dist/resources/extensions/gsd/auto-dispatch.js +6 -5
- package/dist/resources/extensions/gsd/auto-model-selection.js +8 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +12 -9
- package/dist/resources/extensions/gsd/auto-prompts.js +81 -8
- package/dist/resources/extensions/gsd/auto-recovery.js +48 -49
- package/dist/resources/extensions/gsd/auto-runtime-state.js +14 -0
- package/dist/resources/extensions/gsd/auto-start.js +20 -36
- package/dist/resources/extensions/gsd/auto-timers.js +16 -2
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +32 -0
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +4 -29
- package/dist/resources/extensions/gsd/auto-verification.js +7 -7
- package/dist/resources/extensions/gsd/auto-worktree-repair.js +10 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +34 -289
- package/dist/resources/extensions/gsd/auto.js +15 -14
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +28 -37
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +20 -43
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +131 -140
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +89 -8
- package/dist/resources/extensions/gsd/captures.js +5 -13
- package/dist/resources/extensions/gsd/closeout-consistency-gate.js +21 -4
- package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
- package/dist/resources/extensions/gsd/codebase-generator.js +8 -4
- package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +3 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +20 -0
- package/dist/resources/extensions/gsd/commands-inspect.js +4 -8
- package/dist/resources/extensions/gsd/commands-maintenance.js +61 -41
- package/dist/resources/extensions/gsd/commands-ship.js +2 -2
- package/dist/resources/extensions/gsd/commands-verdict.js +12 -2
- package/dist/resources/extensions/gsd/db/engine.js +755 -0
- package/dist/resources/extensions/gsd/db/queries.js +372 -0
- package/dist/resources/extensions/gsd/db/sql-constants.js +11 -0
- package/dist/resources/extensions/gsd/db/writers/cascades.js +194 -0
- package/dist/resources/extensions/gsd/db/writers/import-restore.js +182 -0
- package/dist/resources/extensions/gsd/db/writers/memory.js +149 -0
- package/dist/resources/extensions/gsd/db/writers/reconcile.js +458 -0
- package/dist/resources/extensions/gsd/db/writers/status.js +70 -0
- package/dist/resources/extensions/gsd/db-workspace.js +103 -0
- package/dist/resources/extensions/gsd/delegation-policy.js +2 -10
- package/dist/resources/extensions/gsd/discussion-handoff.js +218 -0
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -0
- package/dist/resources/extensions/gsd/doctor-environment.js +8 -10
- package/dist/resources/extensions/gsd/doctor-git-checks.js +4 -3
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +9 -2
- package/dist/resources/extensions/gsd/doctor.js +16 -9
- package/dist/resources/extensions/gsd/error-classifier.js +1 -1
- package/dist/resources/extensions/gsd/git-conflict-state.js +16 -1
- package/dist/resources/extensions/gsd/git-service.js +1 -0
- package/dist/resources/extensions/gsd/gitignore.js +3 -0
- package/dist/resources/extensions/gsd/gsd-db.js +183 -2048
- package/dist/resources/extensions/gsd/guided-flow.js +68 -471
- package/dist/resources/extensions/gsd/guided-unit-completion.js +225 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +2 -1
- package/dist/resources/extensions/gsd/mcp-filter.js +2 -1
- package/dist/resources/extensions/gsd/mcp-tool-name.js +26 -0
- package/dist/resources/extensions/gsd/md-importer.js +4 -3
- package/dist/resources/extensions/gsd/migrate/safety.js +19 -11
- package/dist/resources/extensions/gsd/migration-auto-check.js +27 -5
- package/dist/resources/extensions/gsd/milestone-closeout-proof.js +72 -0
- package/dist/resources/extensions/gsd/milestone-closeout.js +12 -4
- package/dist/resources/extensions/gsd/milestone-merge-transaction.js +10 -0
- package/dist/resources/extensions/gsd/milestone-planning-persistence.js +156 -0
- package/dist/resources/extensions/gsd/milestone-readiness.js +77 -0
- package/dist/resources/extensions/gsd/milestone-settlement.js +50 -0
- package/dist/resources/extensions/gsd/milestone-validation-evidence.js +73 -0
- package/dist/resources/extensions/gsd/milestone-validation-verdict.js +57 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +1 -0
- package/dist/resources/extensions/gsd/model-router.js +3 -0
- package/dist/resources/extensions/gsd/parallel-eligibility.js +3 -6
- package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +7 -5
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -2
- package/dist/resources/extensions/gsd/paths.js +10 -24
- package/dist/resources/extensions/gsd/preferences-diagnostics.js +67 -0
- package/dist/resources/extensions/gsd/preferences.js +161 -29
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/provider-payload-policy.js +83 -0
- package/dist/resources/extensions/gsd/pull-request-process.js +13 -0
- package/dist/resources/extensions/gsd/quality-gate-closure.js +109 -0
- package/dist/resources/extensions/gsd/question-transport.js +86 -0
- package/dist/resources/extensions/gsd/recovery-classification.js +12 -1
- package/dist/resources/extensions/gsd/roadmap-slices.js +8 -2
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +37 -4
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +7 -2
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +10 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -2
- package/dist/resources/extensions/gsd/state-transition-matrix.js +38 -0
- package/dist/resources/extensions/gsd/state.js +13 -5
- package/dist/resources/extensions/gsd/status-guards.js +56 -8
- package/dist/resources/extensions/gsd/templates/plan.md +7 -0
- package/dist/resources/extensions/gsd/templates/project.md +1 -0
- package/dist/resources/extensions/gsd/templates/roadmap.md +1 -1
- package/dist/resources/extensions/gsd/templates/uat.md +5 -1
- package/dist/resources/extensions/gsd/tool-contract.js +52 -8
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +15 -34
- package/dist/resources/extensions/gsd/tool-surface-snapshot.js +17 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +24 -43
- package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -5
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +15 -143
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +39 -0
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +11 -29
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +14 -33
- package/dist/resources/extensions/gsd/tools/skip-slice.js +18 -36
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +15 -78
- package/dist/resources/extensions/gsd/uat-policy.js +16 -10
- package/dist/resources/extensions/gsd/uat-run.js +9 -14
- package/dist/resources/extensions/gsd/undo.js +8 -7
- package/dist/resources/extensions/gsd/unit-context-composer.js +40 -20
- package/dist/resources/extensions/gsd/unit-runtime.js +3 -2
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +2 -1
- package/dist/resources/extensions/gsd/user-input-boundary.js +23 -0
- package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
- package/dist/resources/extensions/gsd/web-app-uat.js +80 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +15 -102
- package/dist/resources/extensions/gsd/workflow-reconcile.js +4 -3
- package/dist/resources/extensions/gsd/workflow-tool-surface.js +46 -0
- package/dist/resources/extensions/gsd/workspace-git-guard.js +2 -0
- package/dist/resources/extensions/gsd/worktree-git-recovery.js +287 -0
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +9 -1
- package/dist/resources/extensions/gsd/worktree-manager.js +45 -28
- package/dist/resources/extensions/gsd/worktree-placement.js +59 -0
- package/dist/resources/extensions/gsd/worktree-reentry.js +12 -8
- package/dist/resources/extensions/gsd/worktree-root.js +17 -6
- package/dist/resources/extensions/gsd/worktree-safety.js +8 -5
- package/dist/resources/extensions/gsd/worktree-session-state.js +12 -10
- package/dist/resources/extensions/gsd/worktree-state-projection.js +33 -4
- package/dist/resources/extensions/gsd/worktree-telemetry.js +12 -0
- package/dist/resources/extensions/shared/interview-ui.js +2 -2
- package/dist/resources/shared/claude-runtime-floor.js +182 -0
- package/dist/resources/skills/gsd-browser/SKILL.md +1 -1
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/update-cmd.js +20 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +8 -8
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
- package/dist/web/standalone/.next/server/chunks/{5047.js → 5942.js} +2 -2
- package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/2659.b7b129ee6a769448.js +1 -0
- package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{3616.4113d484a994e411.js → 3616.3c60753b8ffcbd2e.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/4283.e4873b058df143a1.js +2 -0
- package/dist/web/standalone/.next/static/chunks/5826.a46ecdd1cfe8dabc.js +1 -0
- package/dist/web/standalone/.next/static/chunks/796.cf859a427a2cb2ac.js +10 -0
- package/dist/web/standalone/.next/static/chunks/8785.2e5a118797fb2dd2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-dda80a1ef5587410.js → webpack-fbea77b5f9953368.js} +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/dist/web-mode.d.ts +2 -0
- package/dist/web-mode.js +20 -8
- package/dist/worktree-status-banner.js +7 -3
- package/package.json +2 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +2 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +14 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +106 -40
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js +6 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/server.d.ts +10 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +8 -0
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +41 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +32 -22
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
- package/packages/pi-ai/dist/image-models.generated.js +6 -6
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +295 -98
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +309 -154
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js +3 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/components/input.js +1 -1
- package/packages/pi-tui/dist/components/input.js.map +1 -1
- package/packages/pi-tui/dist/keys.d.ts.map +1 -1
- package/packages/pi-tui/dist/keys.js +39 -30
- package/packages/pi-tui/dist/keys.js.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.js +22 -0
- package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/extensions/ask-user-questions.ts +87 -24
- package/src/resources/extensions/bg-shell/utilities.ts +2 -2
- package/src/resources/extensions/claude-code-cli/models.ts +9 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +114 -281
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +268 -0
- package/src/resources/extensions/claude-code-cli/turn-assembler.ts +287 -0
- package/src/resources/extensions/github-sync/templates.ts +3 -3
- package/src/resources/extensions/github-sync/tests/templates.test.ts +2 -2
- package/src/resources/extensions/gsd/artifact-projection.ts +31 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +32 -2
- package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -1
- package/src/resources/extensions/gsd/auto/loop.ts +83 -61
- package/src/resources/extensions/gsd/auto/orchestrator.ts +164 -17
- package/src/resources/extensions/gsd/auto/phases.ts +45 -4
- package/src/resources/extensions/gsd/auto/run-unit.ts +2 -1
- package/src/resources/extensions/gsd/auto/session.ts +4 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +18 -4
- package/src/resources/extensions/gsd/auto-dispatch.ts +20 -7
- package/src/resources/extensions/gsd/auto-model-selection.ts +8 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +16 -8
- package/src/resources/extensions/gsd/auto-prompts.ts +107 -9
- package/src/resources/extensions/gsd/auto-recovery.ts +50 -50
- package/src/resources/extensions/gsd/auto-runtime-state.ts +26 -0
- package/src/resources/extensions/gsd/auto-start.ts +25 -34
- package/src/resources/extensions/gsd/auto-timers.ts +16 -2
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +35 -0
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +9 -30
- package/src/resources/extensions/gsd/auto-verification.ts +7 -8
- package/src/resources/extensions/gsd/auto-worktree-repair.ts +13 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +53 -306
- package/src/resources/extensions/gsd/auto.ts +27 -17
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +29 -37
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +20 -43
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +147 -153
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +132 -6
- package/src/resources/extensions/gsd/captures.ts +5 -14
- package/src/resources/extensions/gsd/closeout-consistency-gate.ts +27 -5
- package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
- package/src/resources/extensions/gsd/codebase-generator.ts +9 -5
- package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +3 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +18 -0
- package/src/resources/extensions/gsd/commands-inspect.ts +7 -8
- package/src/resources/extensions/gsd/commands-maintenance.ts +74 -40
- package/src/resources/extensions/gsd/commands-ship.ts +2 -2
- package/src/resources/extensions/gsd/commands-verdict.ts +19 -2
- package/src/resources/extensions/gsd/db/engine.ts +809 -0
- package/src/resources/extensions/gsd/db/queries.ts +453 -0
- package/src/resources/extensions/gsd/db/sql-constants.ts +12 -0
- package/src/resources/extensions/gsd/db/writers/cascades.ts +237 -0
- package/src/resources/extensions/gsd/db/writers/import-restore.ts +310 -0
- package/src/resources/extensions/gsd/db/writers/memory.ts +220 -0
- package/src/resources/extensions/gsd/db/writers/reconcile.ts +500 -0
- package/src/resources/extensions/gsd/db/writers/status.ts +88 -0
- package/src/resources/extensions/gsd/db-workspace.ts +170 -0
- package/src/resources/extensions/gsd/delegation-policy.ts +3 -11
- package/src/resources/extensions/gsd/discussion-handoff.ts +276 -0
- package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -0
- package/src/resources/extensions/gsd/doctor-environment.ts +8 -11
- package/src/resources/extensions/gsd/doctor-git-checks.ts +3 -3
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +10 -3
- package/src/resources/extensions/gsd/doctor.ts +15 -5
- package/src/resources/extensions/gsd/error-classifier.ts +1 -1
- package/src/resources/extensions/gsd/git-conflict-state.ts +17 -1
- package/src/resources/extensions/gsd/git-service.ts +1 -0
- package/src/resources/extensions/gsd/gitignore.ts +3 -0
- package/src/resources/extensions/gsd/gsd-db.ts +185 -2373
- package/src/resources/extensions/gsd/guided-flow.ts +81 -561
- package/src/resources/extensions/gsd/guided-unit-completion.ts +275 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +2 -1
- package/src/resources/extensions/gsd/mcp-filter.ts +2 -1
- package/src/resources/extensions/gsd/mcp-tool-name.ts +35 -0
- package/src/resources/extensions/gsd/md-importer.ts +3 -3
- package/src/resources/extensions/gsd/migrate/safety.ts +17 -9
- package/src/resources/extensions/gsd/migration-auto-check.ts +30 -5
- package/src/resources/extensions/gsd/milestone-closeout-proof.ts +131 -0
- package/src/resources/extensions/gsd/milestone-closeout.ts +12 -4
- package/src/resources/extensions/gsd/milestone-merge-transaction.ts +47 -0
- package/src/resources/extensions/gsd/milestone-planning-persistence.ts +224 -0
- package/src/resources/extensions/gsd/milestone-readiness.ts +125 -0
- package/src/resources/extensions/gsd/milestone-settlement.ts +81 -0
- package/src/resources/extensions/gsd/milestone-validation-evidence.ts +95 -0
- package/src/resources/extensions/gsd/milestone-validation-verdict.ts +80 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +1 -0
- package/src/resources/extensions/gsd/model-router.ts +3 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +4 -5
- package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +6 -5
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +6 -2
- package/src/resources/extensions/gsd/paths.ts +9 -22
- package/src/resources/extensions/gsd/preferences-diagnostics.ts +98 -0
- package/src/resources/extensions/gsd/preferences-types.ts +16 -0
- package/src/resources/extensions/gsd/preferences.ts +191 -28
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/provider-payload-policy.ts +140 -0
- package/src/resources/extensions/gsd/pull-request-process.ts +41 -0
- package/src/resources/extensions/gsd/quality-gate-closure.ts +140 -0
- package/src/resources/extensions/gsd/question-transport.ts +138 -0
- package/src/resources/extensions/gsd/recovery-classification.ts +14 -1
- package/src/resources/extensions/gsd/roadmap-slices.ts +8 -2
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +36 -4
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +7 -2
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +14 -0
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +6 -2
- package/src/resources/extensions/gsd/state-transition-matrix.ts +42 -0
- package/src/resources/extensions/gsd/state.ts +15 -5
- package/src/resources/extensions/gsd/status-guards.ts +59 -8
- package/src/resources/extensions/gsd/templates/plan.md +7 -0
- package/src/resources/extensions/gsd/templates/project.md +1 -0
- package/src/resources/extensions/gsd/templates/roadmap.md +1 -1
- package/src/resources/extensions/gsd/templates/uat.md +5 -1
- package/src/resources/extensions/gsd/tests/ask-user-questions-render.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +444 -5
- package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +133 -4
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-worktree-repair.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +38 -1
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +34 -3
- package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +1 -5
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +1 -5
- package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +48 -1
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +5 -4
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/mcp-tool-name.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +143 -1
- package/src/resources/extensions/gsd/tests/milestone-closeout-proof.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/milestone-readiness.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/milestone-validation-evidence.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/milestone-validation-verdict.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/preferences-diagnostics.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +183 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/provider-payload-policy.test.ts +165 -0
- package/src/resources/extensions/gsd/tests/pull-request-process.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/recovery-classification-illegal-transition.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +185 -1
- package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +25 -1
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +80 -0
- package/src/resources/extensions/gsd/tests/session-switch-clears-pending-autostart.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +144 -7
- package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/tool-availability-audit.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +35 -42
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +86 -1
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +126 -9
- package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +41 -4
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +43 -1
- package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/worktree-projection-writers.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +12 -6
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +121 -0
- package/src/resources/extensions/gsd/tool-contract.ts +86 -8
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +16 -33
- package/src/resources/extensions/gsd/tool-surface-snapshot.ts +47 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +23 -58
- package/src/resources/extensions/gsd/tools/exec-tool.ts +5 -5
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +19 -160
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +43 -0
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +11 -38
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +14 -42
- package/src/resources/extensions/gsd/tools/skip-slice.ts +18 -44
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -84
- package/src/resources/extensions/gsd/uat-policy.ts +19 -10
- package/src/resources/extensions/gsd/uat-run.ts +10 -14
- package/src/resources/extensions/gsd/undo.ts +9 -8
- package/src/resources/extensions/gsd/unit-context-composer.ts +85 -20
- package/src/resources/extensions/gsd/unit-runtime.ts +3 -2
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +2 -1
- package/src/resources/extensions/gsd/user-input-boundary.ts +18 -0
- package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
- package/src/resources/extensions/gsd/web-app-uat.ts +101 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +22 -110
- package/src/resources/extensions/gsd/workflow-reconcile.ts +3 -3
- package/src/resources/extensions/gsd/workflow-tool-surface.ts +73 -0
- package/src/resources/extensions/gsd/workspace-git-guard.ts +1 -0
- package/src/resources/extensions/gsd/worktree-git-recovery.ts +308 -0
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +17 -17
- package/src/resources/extensions/gsd/worktree-manager.ts +47 -28
- package/src/resources/extensions/gsd/worktree-placement.ts +63 -0
- package/src/resources/extensions/gsd/worktree-reentry.ts +10 -7
- package/src/resources/extensions/gsd/worktree-root.ts +17 -6
- package/src/resources/extensions/gsd/worktree-safety.ts +8 -5
- package/src/resources/extensions/gsd/worktree-session-state.ts +12 -10
- package/src/resources/extensions/gsd/worktree-state-projection.ts +55 -7
- package/src/resources/extensions/gsd/worktree-telemetry.ts +16 -0
- package/src/resources/extensions/shared/interview-ui.ts +15 -2
- package/src/resources/shared/claude-runtime-floor.ts +248 -0
- package/src/resources/skills/gsd-browser/SKILL.md +1 -1
- package/dist/web/standalone/.next/static/chunks/2659.feb6499ca863ebfc.js +0 -1
- package/dist/web/standalone/.next/static/chunks/2772.151789db0edea835.js +0 -1
- package/dist/web/standalone/.next/static/chunks/4283.10a065467b5340d8.js +0 -2
- package/dist/web/standalone/.next/static/chunks/5826.960dc4634cc9b0d3.js +0 -1
- package/dist/web/standalone/.next/static/chunks/796.46f811c0fac23aab.js +0 -10
- package/dist/web/standalone/.next/static/chunks/8785.d32f7a61f55c1600.js +0 -1
- /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → C24pqUd-aru-l0Dp0gLZP}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → C24pqUd-aru-l0Dp0gLZP}/_ssgManifest.js +0 -0
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* dependency satisfaction and file overlap across slice plans.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { existsSync } from "node:fs";
|
|
9
8
|
import { deriveState } from "./state.js";
|
|
10
|
-
import {
|
|
9
|
+
import { resolveMilestoneFile, resolveSliceFile } from "./paths.js";
|
|
11
10
|
import { findMilestoneIds } from "./guided-flow.js";
|
|
12
|
-
import { isDbAvailable, getMilestoneSlices, getSliceTasks
|
|
11
|
+
import { isDbAvailable, getMilestoneSlices, getSliceTasks } from "./gsd-db.js";
|
|
12
|
+
import { openExistingWorkflowDatabase } from "./db-workspace.js";
|
|
13
13
|
import type { MilestoneRegistryEntry } from "./types.js";
|
|
14
14
|
|
|
15
15
|
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
@@ -98,8 +98,7 @@ export async function analyzeParallelEligibility(
|
|
|
98
98
|
basePath: string,
|
|
99
99
|
): Promise<ParallelCandidates> {
|
|
100
100
|
if (!isDbAvailable()) {
|
|
101
|
-
|
|
102
|
-
if (existsSync(projectDb)) openDatabase(projectDb);
|
|
101
|
+
openExistingWorkflowDatabase(basePath);
|
|
103
102
|
}
|
|
104
103
|
|
|
105
104
|
const milestoneIds = findMilestoneIds(basePath);
|
|
@@ -9,6 +9,7 @@ import { existsSync, readdirSync } from "node:fs";
|
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import { spawnSync } from "node:child_process";
|
|
11
11
|
import { resolveGsdPathContract } from "./paths.js";
|
|
12
|
+
import { worktreePathFor, worktreesDirs } from "./worktree-placement.js";
|
|
12
13
|
import { getAutoWorktreePath } from "./auto-worktree.js";
|
|
13
14
|
import { buildWorktreeLifecycleDeps } from "./auto.js";
|
|
14
15
|
import {
|
|
@@ -42,7 +43,7 @@ export type MergeOrder = "sequential" | "by-completion";
|
|
|
42
43
|
* Returns true when milestones.status = 'complete' in project gsd.db.
|
|
43
44
|
*/
|
|
44
45
|
export function isMilestoneCompleteInProjectDb(basePath: string, mid: string): boolean {
|
|
45
|
-
const workRoot =
|
|
46
|
+
const workRoot = worktreePathFor(basePath, mid);
|
|
46
47
|
const dbPath = resolveGsdPathContract(workRoot, basePath).projectDb;
|
|
47
48
|
if (!existsSync(dbPath)) return false;
|
|
48
49
|
|
|
@@ -65,15 +66,17 @@ export function isMilestoneCompleteInProjectDb(basePath: string, mid: string): b
|
|
|
65
66
|
*/
|
|
66
67
|
function discoverDbCompletedMilestones(basePath: string): Set<string> {
|
|
67
68
|
const completed = new Set<string>();
|
|
68
|
-
const worktreeDir
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
for (const worktreeDir of worktreesDirs(basePath)) {
|
|
70
|
+
if (!existsSync(worktreeDir)) continue;
|
|
71
|
+
try {
|
|
72
|
+
for (const entry of readdirSync(worktreeDir)) {
|
|
73
|
+
if (entry.startsWith("M") && isMilestoneCompleteInProjectDb(basePath, entry)) {
|
|
74
|
+
completed.add(entry);
|
|
75
|
+
}
|
|
73
76
|
}
|
|
77
|
+
} catch (e) {
|
|
78
|
+
logWarning("parallel", `readdirSync for completed set failed: ${(e as Error).message}`);
|
|
74
79
|
}
|
|
75
|
-
} catch (e) {
|
|
76
|
-
logWarning("parallel", `readdirSync for completed set failed: ${(e as Error).message}`);
|
|
77
80
|
}
|
|
78
81
|
return completed;
|
|
79
82
|
}
|
|
@@ -120,7 +123,7 @@ export function determineMergeOrder(
|
|
|
120
123
|
title: mid,
|
|
121
124
|
pid: 0,
|
|
122
125
|
process: null,
|
|
123
|
-
worktreePath: basePath ?
|
|
126
|
+
worktreePath: basePath ? worktreePathFor(basePath, mid) : "",
|
|
124
127
|
startedAt: 0,
|
|
125
128
|
state: "stopped",
|
|
126
129
|
cost: 0,
|
|
@@ -11,6 +11,7 @@ import { matchesKey, Key } from "@gsd/pi-tui";
|
|
|
11
11
|
import { formatDuration } from "../shared/mod.js";
|
|
12
12
|
import { formattedShortcutPair } from "./shortcut-defs.js";
|
|
13
13
|
import { resolveGsdPathContract } from "./paths.js";
|
|
14
|
+
import { worktreePathFor, worktreesDirs } from "./worktree-placement.js";
|
|
14
15
|
import {
|
|
15
16
|
renderBar,
|
|
16
17
|
renderDialogFrame,
|
|
@@ -101,7 +102,6 @@ function tailRead(filePath: string, maxBytes: number): string {
|
|
|
101
102
|
|
|
102
103
|
function discoverWorkers(basePath: string): string[] {
|
|
103
104
|
const parallelDir = join(basePath, ".gsd", "parallel");
|
|
104
|
-
const worktreeDir = join(basePath, ".gsd", "worktrees");
|
|
105
105
|
const mids = new Set<string>();
|
|
106
106
|
|
|
107
107
|
if (existsSync(parallelDir)) {
|
|
@@ -114,7 +114,8 @@ function discoverWorkers(basePath: string): string[] {
|
|
|
114
114
|
} catch { /* skip */ }
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
for (const worktreeDir of worktreesDirs(basePath)) {
|
|
118
|
+
if (!existsSync(worktreeDir)) continue;
|
|
118
119
|
try {
|
|
119
120
|
for (const d of readdirSync(worktreeDir)) {
|
|
120
121
|
if (d.startsWith("M") && existsSync(join(worktreeDir, d, ".gsd", "auto.lock"))) {
|
|
@@ -128,7 +129,7 @@ function discoverWorkers(basePath: string): string[] {
|
|
|
128
129
|
}
|
|
129
130
|
|
|
130
131
|
function querySliceProgress(basePath: string, mid: string): SliceProgress[] {
|
|
131
|
-
const workRoot =
|
|
132
|
+
const workRoot = worktreePathFor(basePath, mid);
|
|
132
133
|
const dbPath = resolveGsdPathContract(workRoot, basePath).projectDb;
|
|
133
134
|
if (!existsSync(dbPath)) return [];
|
|
134
135
|
|
|
@@ -169,7 +170,7 @@ function extractCostFromNdjson(basePath: string, mid: string): number {
|
|
|
169
170
|
}
|
|
170
171
|
|
|
171
172
|
function queryRecentCompletions(basePath: string, mid: string): string[] {
|
|
172
|
-
const workRoot =
|
|
173
|
+
const workRoot = worktreePathFor(basePath, mid);
|
|
173
174
|
const dbPath = resolveGsdPathContract(workRoot, basePath).projectDb;
|
|
174
175
|
if (!existsSync(dbPath)) return [];
|
|
175
176
|
try {
|
|
@@ -193,7 +194,7 @@ function collectWorkerData(basePath: string): WorkerView[] {
|
|
|
193
194
|
|
|
194
195
|
for (const mid of mids) {
|
|
195
196
|
const status = readJsonSafe<StatusJson>(join(parallelDir, `${mid}.status.json`));
|
|
196
|
-
const lock = readJsonSafe<AutoLock>(join(basePath,
|
|
197
|
+
const lock = readJsonSafe<AutoLock>(join(worktreePathFor(basePath, mid), ".gsd", "auto.lock"));
|
|
197
198
|
const slices = querySliceProgress(basePath, mid);
|
|
198
199
|
|
|
199
200
|
const pid = lock?.pid || status?.pid || 0;
|
|
@@ -21,9 +21,10 @@ import { join, dirname } from "node:path";
|
|
|
21
21
|
import { fileURLToPath } from "node:url";
|
|
22
22
|
import { gsdRoot } from "./paths.js";
|
|
23
23
|
import { createWorktree, worktreePath } from "./worktree-manager.js";
|
|
24
|
-
import { autoWorktreeBranch, fastForwardReusedMilestoneBranchIfSafe, runWorktreePostCreateHook,
|
|
24
|
+
import { autoWorktreeBranch, fastForwardReusedMilestoneBranchIfSafe, runWorktreePostCreateHook, syncGsdStateToWorktreeByScope } from "./auto-worktree.js";
|
|
25
25
|
import { nativeBranchExists } from "./native-git-bridge.js";
|
|
26
26
|
import { readIntegrationBranch } from "./git-service.js";
|
|
27
|
+
import { createWorkspace, scopeMilestone } from "./workspace.js";
|
|
27
28
|
import { resolveParallelConfig } from "./preferences.js";
|
|
28
29
|
import type { GSDPreferences } from "./preferences.js";
|
|
29
30
|
import type { ParallelConfig } from "./types.js";
|
|
@@ -561,7 +562,10 @@ export function _createMilestoneWorktree(basePath: string, milestoneId: string):
|
|
|
561
562
|
// Copy .gsd/ planning artifacts (milestones, CONTEXT, ROADMAP, etc.) from the
|
|
562
563
|
// project root into the worktree. Without this, workers for newly-planned
|
|
563
564
|
// milestones can't find their roadmap and exit immediately (#2184 Bug 4).
|
|
564
|
-
|
|
565
|
+
syncGsdStateToWorktreeByScope(
|
|
566
|
+
scopeMilestone(createWorkspace(basePath), milestoneId),
|
|
567
|
+
scopeMilestone(createWorkspace(info.path), milestoneId),
|
|
568
|
+
);
|
|
565
569
|
|
|
566
570
|
return info.path;
|
|
567
571
|
}
|
|
@@ -17,7 +17,7 @@ import { spawnSync } from "node:child_process";
|
|
|
17
17
|
import { nativeScanGsdTree, type GsdTreeEntry } from "./native-parser-bridge.js";
|
|
18
18
|
import { DIR_CACHE_MAX } from "./constants.js";
|
|
19
19
|
import { gsdHome } from "./gsd-home.js";
|
|
20
|
-
import { isGsdWorktreePath, resolveExternalStateProjectGsdFromWorktreePath, resolveWorktreeProjectRoot } from "./worktree-root.js";
|
|
20
|
+
import { findWorktreeSegment, isGsdWorktreePath, resolveExternalStateProjectGsdFromWorktreePath, resolveWorktreeProjectRoot } from "./worktree-root.js";
|
|
21
21
|
|
|
22
22
|
// ─── Directory Listing Cache ──────────────────────────────────────────────────
|
|
23
23
|
|
|
@@ -458,29 +458,16 @@ function assertNotGlobalGsdHome(basePath: string, result: string): void {
|
|
|
458
458
|
* When gsdRoot() is called with such a path, we must NOT walk up to the
|
|
459
459
|
* project root's .gsd — each worktree manages its own .gsd state (#2594).
|
|
460
460
|
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
461
|
+
* Layout matching is owned by worktree-root's findWorktreeSegment; this
|
|
462
|
+
* only adds the requirement that a non-empty worktree name follows the
|
|
463
|
+
* marker (the worktrees container dir itself is not a worktree).
|
|
463
464
|
*/
|
|
464
465
|
function isInsideGsdWorktree(p: string): boolean {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
const
|
|
469
|
-
|
|
470
|
-
`${sepFwd}.gsd${sepFwd}worktrees${sepFwd}`,
|
|
471
|
-
`${sepNative}.gsd${sepNative}worktrees${sepNative}`,
|
|
472
|
-
];
|
|
473
|
-
for (const marker of markers) {
|
|
474
|
-
const idx = p.indexOf(marker);
|
|
475
|
-
if (idx === -1) continue;
|
|
476
|
-
// Verify there's a non-empty worktree name after the marker
|
|
477
|
-
const afterMarker = p.slice(idx + marker.length);
|
|
478
|
-
// The name is everything up to the next separator (or end of string)
|
|
479
|
-
const nameEnd = afterMarker.search(/[/\\]/);
|
|
480
|
-
const name = nameEnd === -1 ? afterMarker : afterMarker.slice(0, nameEnd);
|
|
481
|
-
if (name.length > 0) return true;
|
|
482
|
-
}
|
|
483
|
-
return false;
|
|
466
|
+
const normalized = p.replaceAll("\\", "/");
|
|
467
|
+
const segment = findWorktreeSegment(normalized);
|
|
468
|
+
if (!segment) return false;
|
|
469
|
+
const name = normalized.slice(segment.afterWorktrees).split("/")[0];
|
|
470
|
+
return name.length > 0;
|
|
484
471
|
}
|
|
485
472
|
|
|
486
473
|
function probeGsdRoot(rawBasePath: string): string {
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { PreferenceDiagnostic } from "./preferences-types.js";
|
|
2
|
+
import {
|
|
3
|
+
loadGlobalGSDPreferences,
|
|
4
|
+
loadProjectGSDPreferences,
|
|
5
|
+
} from "./preferences.js";
|
|
6
|
+
|
|
7
|
+
interface PreferenceNotificationContext {
|
|
8
|
+
ui: {
|
|
9
|
+
notify(message: string, type?: "info" | "warning" | "error" | "success"): void;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface PreferenceDiagnosticNotificationOptions {
|
|
14
|
+
surface?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const notifiedPreferenceDiagnostics = new Set<string>();
|
|
18
|
+
|
|
19
|
+
export function collectPreferenceDiagnostics(basePath?: string): PreferenceDiagnostic[] {
|
|
20
|
+
const diagnostics = [
|
|
21
|
+
...(loadGlobalGSDPreferences()?.diagnostics ?? []),
|
|
22
|
+
...(loadProjectGSDPreferences(basePath)?.diagnostics ?? []),
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const seen = new Set<string>();
|
|
26
|
+
const unique: PreferenceDiagnostic[] = [];
|
|
27
|
+
for (const diagnostic of diagnostics) {
|
|
28
|
+
const signature = preferenceDiagnosticSignature(diagnostic);
|
|
29
|
+
if (seen.has(signature)) continue;
|
|
30
|
+
seen.add(signature);
|
|
31
|
+
unique.push(diagnostic);
|
|
32
|
+
}
|
|
33
|
+
return unique;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function formatPreferenceDiagnostic(diagnostic: PreferenceDiagnostic): string {
|
|
37
|
+
const scope = diagnostic.scope === "global" ? "global" : "project";
|
|
38
|
+
const level = diagnostic.severity === "error" ? "error" : "warning";
|
|
39
|
+
const heading = diagnostic.kind === "parse"
|
|
40
|
+
? `GSD ${scope} preferences ${level}: ${diagnostic.path} could not be parsed.`
|
|
41
|
+
: `GSD ${scope} preferences ${level}: ${diagnostic.path} contains invalid settings.`;
|
|
42
|
+
const detail = formatPreferenceDiagnosticDetail(diagnostic);
|
|
43
|
+
const impact = diagnostic.ignored
|
|
44
|
+
? "Preferences from this file were ignored; auto-mode may be using defaults."
|
|
45
|
+
: "Invalid settings were ignored or sanitized; auto-mode may be using defaults for them.";
|
|
46
|
+
return `${heading}\n${detail}\n${impact}\nRun /gsd doctor for details.`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function formatPreferenceDiagnosticDetail(diagnostic: PreferenceDiagnostic): string {
|
|
50
|
+
if (diagnostic.line !== undefined && diagnostic.column !== undefined) {
|
|
51
|
+
return `YAML error at line ${diagnostic.line}, column ${diagnostic.column}: ${diagnostic.message}`;
|
|
52
|
+
}
|
|
53
|
+
return diagnostic.message;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function notifyPreferenceDiagnostics(
|
|
57
|
+
ctx: PreferenceNotificationContext,
|
|
58
|
+
basePath?: string,
|
|
59
|
+
options?: PreferenceDiagnosticNotificationOptions,
|
|
60
|
+
): number {
|
|
61
|
+
let notified = 0;
|
|
62
|
+
for (const diagnostic of collectPreferenceDiagnostics(basePath)) {
|
|
63
|
+
const signature = preferenceDiagnosticNotificationSignature(diagnostic, options?.surface);
|
|
64
|
+
if (notifiedPreferenceDiagnostics.has(signature)) continue;
|
|
65
|
+
notifiedPreferenceDiagnostics.add(signature);
|
|
66
|
+
ctx.ui.notify(
|
|
67
|
+
formatPreferenceDiagnostic(diagnostic),
|
|
68
|
+
diagnostic.severity === "error" ? "error" : "warning",
|
|
69
|
+
);
|
|
70
|
+
notified++;
|
|
71
|
+
}
|
|
72
|
+
return notified;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function _resetPreferenceDiagnosticNotificationsForTests(): void {
|
|
76
|
+
notifiedPreferenceDiagnostics.clear();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function preferenceDiagnosticSignature(diagnostic: PreferenceDiagnostic): string {
|
|
80
|
+
return [
|
|
81
|
+
diagnostic.path,
|
|
82
|
+
diagnostic.scope,
|
|
83
|
+
diagnostic.severity,
|
|
84
|
+
diagnostic.kind,
|
|
85
|
+
diagnostic.message,
|
|
86
|
+
diagnostic.line ?? "",
|
|
87
|
+
diagnostic.column ?? "",
|
|
88
|
+
diagnostic.ignored === true ? "ignored" : "",
|
|
89
|
+
diagnostic.sanitized === true ? "sanitized" : "",
|
|
90
|
+
].join("\u0000");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function preferenceDiagnosticNotificationSignature(
|
|
94
|
+
diagnostic: PreferenceDiagnostic,
|
|
95
|
+
surface = "default",
|
|
96
|
+
): string {
|
|
97
|
+
return `${surface}\u0000${preferenceDiagnosticSignature(diagnostic)}`;
|
|
98
|
+
}
|
|
@@ -594,8 +594,24 @@ export interface LoadedGSDPreferences {
|
|
|
594
594
|
path: string;
|
|
595
595
|
scope: "global" | "project";
|
|
596
596
|
preferences: GSDPreferences;
|
|
597
|
+
/** True when the file exists but its contents were ignored before merging. */
|
|
598
|
+
ignored?: boolean;
|
|
597
599
|
/** Validation warnings (unknown keys, type mismatches, deprecations). Empty when preferences are clean. */
|
|
598
600
|
warnings?: string[];
|
|
601
|
+
/** Structured parse/validation diagnostics for user-visible reporting. */
|
|
602
|
+
diagnostics?: PreferenceDiagnostic[];
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
export interface PreferenceDiagnostic {
|
|
606
|
+
path: string;
|
|
607
|
+
scope: "global" | "project";
|
|
608
|
+
severity: "error" | "warning";
|
|
609
|
+
kind: "parse" | "validation";
|
|
610
|
+
message: string;
|
|
611
|
+
line?: number;
|
|
612
|
+
column?: number;
|
|
613
|
+
ignored?: boolean;
|
|
614
|
+
sanitized?: boolean;
|
|
599
615
|
}
|
|
600
616
|
|
|
601
617
|
export interface SkillResolution {
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
type WorkflowMode,
|
|
30
30
|
type GSDPreferences,
|
|
31
31
|
type LoadedGSDPreferences,
|
|
32
|
+
type PreferenceDiagnostic,
|
|
32
33
|
type SkillResolution,
|
|
33
34
|
type SkillDiscoveryMode,
|
|
34
35
|
formatSkillRef,
|
|
@@ -59,6 +60,7 @@ export type {
|
|
|
59
60
|
ClaudeCodeMcpConfig,
|
|
60
61
|
GSDPreferences,
|
|
61
62
|
LoadedGSDPreferences,
|
|
63
|
+
PreferenceDiagnostic,
|
|
62
64
|
SkillResolution,
|
|
63
65
|
SkillResolutionReport,
|
|
64
66
|
} from "./preferences-types.js";
|
|
@@ -173,14 +175,18 @@ export function normalizePreferencesShape(
|
|
|
173
175
|
// ─── Loading ────────────────────────────────────────────────────────────────
|
|
174
176
|
|
|
175
177
|
export function loadGlobalGSDPreferences(): LoadedGSDPreferences | null {
|
|
176
|
-
return
|
|
177
|
-
|
|
178
|
-
|
|
178
|
+
return loadFirstUsablePreferencesFile([
|
|
179
|
+
globalPreferencesPath(),
|
|
180
|
+
legacyGlobalPreferencesPathLowercase(),
|
|
181
|
+
legacyGlobalPreferencesPath(),
|
|
182
|
+
], "global");
|
|
179
183
|
}
|
|
180
184
|
|
|
181
185
|
export function loadProjectGSDPreferences(basePath?: string): LoadedGSDPreferences | null {
|
|
182
|
-
return
|
|
183
|
-
|
|
186
|
+
return loadFirstUsablePreferencesFile([
|
|
187
|
+
projectPreferencesPath(basePath),
|
|
188
|
+
legacyProjectPreferencesPathLowercase(basePath),
|
|
189
|
+
], "project");
|
|
184
190
|
}
|
|
185
191
|
|
|
186
192
|
export function loadEffectiveGSDPreferences(
|
|
@@ -189,25 +195,25 @@ export function loadEffectiveGSDPreferences(
|
|
|
189
195
|
): LoadedGSDPreferences | null {
|
|
190
196
|
const globalPreferences = loadGlobalGSDPreferences();
|
|
191
197
|
const projectPreferences = loadProjectGSDPreferences(basePath);
|
|
192
|
-
const
|
|
198
|
+
const effectiveGlobalPreferences = globalPreferences?.ignored ? null : globalPreferences;
|
|
199
|
+
const effectiveProjectPreferences = projectPreferences?.ignored ? null : projectPreferences;
|
|
200
|
+
const projectHasPlanningDepth = effectiveProjectPreferences?.preferences.planning_depth !== undefined;
|
|
193
201
|
|
|
194
|
-
if (!
|
|
202
|
+
if (!effectiveGlobalPreferences && !effectiveProjectPreferences) return null;
|
|
195
203
|
|
|
196
204
|
let result: LoadedGSDPreferences;
|
|
197
|
-
if (!
|
|
198
|
-
result =
|
|
199
|
-
} else if (!
|
|
200
|
-
result =
|
|
205
|
+
if (!effectiveGlobalPreferences) {
|
|
206
|
+
result = effectiveProjectPreferences!;
|
|
207
|
+
} else if (!effectiveProjectPreferences) {
|
|
208
|
+
result = mergePreferenceMetadata(effectiveGlobalPreferences, projectPreferences);
|
|
201
209
|
} else {
|
|
202
|
-
const
|
|
203
|
-
...(globalPreferences.warnings ?? []),
|
|
204
|
-
...(projectPreferences.warnings ?? []),
|
|
205
|
-
];
|
|
210
|
+
const metadata = mergePreferenceMetadata(effectiveGlobalPreferences, effectiveProjectPreferences);
|
|
206
211
|
result = {
|
|
207
|
-
path:
|
|
212
|
+
path: effectiveProjectPreferences.path,
|
|
208
213
|
scope: "project",
|
|
209
|
-
preferences: mergePreferences(
|
|
210
|
-
...(
|
|
214
|
+
preferences: mergePreferences(effectiveGlobalPreferences.preferences, effectiveProjectPreferences.preferences),
|
|
215
|
+
...(metadata.warnings ? { warnings: metadata.warnings } : {}),
|
|
216
|
+
...(metadata.diagnostics ? { diagnostics: metadata.diagnostics } : {}),
|
|
211
217
|
};
|
|
212
218
|
}
|
|
213
219
|
|
|
@@ -240,6 +246,43 @@ export function loadEffectiveGSDPreferences(
|
|
|
240
246
|
return result;
|
|
241
247
|
}
|
|
242
248
|
|
|
249
|
+
function mergePreferenceMetadata(
|
|
250
|
+
primary: LoadedGSDPreferences,
|
|
251
|
+
secondary: LoadedGSDPreferences | null,
|
|
252
|
+
): LoadedGSDPreferences {
|
|
253
|
+
const mergedWarnings = [
|
|
254
|
+
...(primary.warnings ?? []),
|
|
255
|
+
...(secondary?.warnings ?? []),
|
|
256
|
+
];
|
|
257
|
+
const mergedDiagnostics = [
|
|
258
|
+
...(primary.diagnostics ?? []),
|
|
259
|
+
...(secondary?.diagnostics ?? []),
|
|
260
|
+
];
|
|
261
|
+
return {
|
|
262
|
+
...primary,
|
|
263
|
+
...(mergedWarnings.length > 0 ? { warnings: mergedWarnings } : {}),
|
|
264
|
+
...(mergedDiagnostics.length > 0 ? { diagnostics: mergedDiagnostics } : {}),
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function loadFirstUsablePreferencesFile(
|
|
269
|
+
paths: string[],
|
|
270
|
+
scope: "global" | "project",
|
|
271
|
+
): LoadedGSDPreferences | null {
|
|
272
|
+
let ignoredPreferences: LoadedGSDPreferences | null = null;
|
|
273
|
+
|
|
274
|
+
for (const path of paths) {
|
|
275
|
+
const loaded = loadPreferencesFile(path, scope);
|
|
276
|
+
if (!loaded) continue;
|
|
277
|
+
if (!loaded.ignored) return mergePreferenceMetadata(loaded, ignoredPreferences);
|
|
278
|
+
ignoredPreferences = ignoredPreferences
|
|
279
|
+
? mergePreferenceMetadata(ignoredPreferences, loaded)
|
|
280
|
+
: loaded;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return ignoredPreferences;
|
|
284
|
+
}
|
|
285
|
+
|
|
243
286
|
function stripInheritedPlanningDepth(
|
|
244
287
|
loaded: LoadedGSDPreferences,
|
|
245
288
|
projectHasPlanningDepth: boolean,
|
|
@@ -260,17 +303,40 @@ function loadPreferencesFile(path: string, scope: "global" | "project"): LoadedG
|
|
|
260
303
|
if (!existsSync(path)) return null;
|
|
261
304
|
|
|
262
305
|
const raw = readFileSync(path, "utf-8");
|
|
263
|
-
const
|
|
264
|
-
if (!preferences) return null;
|
|
306
|
+
const parsed = parsePreferencesMarkdownWithDiagnostics(raw);
|
|
307
|
+
if (!parsed.preferences && parsed.diagnostics.length === 0) return null;
|
|
265
308
|
|
|
309
|
+
const ignored = parsed.diagnostics.some((diagnostic) => diagnostic.ignored === true);
|
|
310
|
+
const preferences = parsed.preferences ?? {};
|
|
266
311
|
const validation = validatePreferences(preferences);
|
|
267
312
|
const allWarnings = [...validation.warnings, ...validation.errors];
|
|
313
|
+
const diagnostics: PreferenceDiagnostic[] = [
|
|
314
|
+
...parsed.diagnostics.map((diagnostic) => ({ ...diagnostic, path, scope })),
|
|
315
|
+
...validation.errors.map((message): PreferenceDiagnostic => ({
|
|
316
|
+
path,
|
|
317
|
+
scope,
|
|
318
|
+
severity: "error",
|
|
319
|
+
kind: "validation",
|
|
320
|
+
message,
|
|
321
|
+
sanitized: true,
|
|
322
|
+
})),
|
|
323
|
+
...validation.warnings.map((message): PreferenceDiagnostic => ({
|
|
324
|
+
path,
|
|
325
|
+
scope,
|
|
326
|
+
severity: "warning",
|
|
327
|
+
kind: "validation",
|
|
328
|
+
message,
|
|
329
|
+
sanitized: true,
|
|
330
|
+
})),
|
|
331
|
+
];
|
|
268
332
|
|
|
269
333
|
return {
|
|
270
334
|
path,
|
|
271
335
|
scope,
|
|
272
336
|
preferences: validation.preferences,
|
|
337
|
+
...(ignored ? { ignored: true } : {}),
|
|
273
338
|
...(allWarnings.length > 0 ? { warnings: allWarnings } : {}),
|
|
339
|
+
...(diagnostics.length > 0 ? { diagnostics } : {}),
|
|
274
340
|
};
|
|
275
341
|
}
|
|
276
342
|
|
|
@@ -286,20 +352,44 @@ export function _resetParseWarningFlag(): void {
|
|
|
286
352
|
|
|
287
353
|
/** @internal Exported for testing only */
|
|
288
354
|
export function parsePreferencesMarkdown(content: string): GSDPreferences | null {
|
|
355
|
+
return parsePreferencesMarkdownWithDiagnostics(content).preferences;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
type PreferenceParseDiagnostic = Omit<PreferenceDiagnostic, "path" | "scope">;
|
|
359
|
+
|
|
360
|
+
interface PreferenceParseResult {
|
|
361
|
+
preferences: GSDPreferences | null;
|
|
362
|
+
diagnostics: PreferenceParseDiagnostic[];
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function parsePreferencesMarkdownWithDiagnostics(content: string): PreferenceParseResult {
|
|
289
366
|
// Use indexOf instead of [\s\S]*? regex to avoid backtracking (#468)
|
|
290
367
|
const startMarker = content.startsWith('---\r\n') ? '---\r\n' : '---\n';
|
|
291
368
|
if (content.startsWith(startMarker)) {
|
|
292
369
|
const searchStart = startMarker.length;
|
|
293
370
|
const endIdx = content.indexOf('\n---', searchStart);
|
|
294
|
-
if (endIdx === -1)
|
|
371
|
+
if (endIdx === -1) {
|
|
372
|
+
return {
|
|
373
|
+
preferences: null,
|
|
374
|
+
diagnostics: [{
|
|
375
|
+
severity: "error",
|
|
376
|
+
kind: "parse",
|
|
377
|
+
message: "preferences frontmatter is missing a closing --- delimiter",
|
|
378
|
+
ignored: true,
|
|
379
|
+
}],
|
|
380
|
+
};
|
|
381
|
+
}
|
|
295
382
|
const block = content.slice(searchStart, endIdx);
|
|
296
|
-
return
|
|
383
|
+
return parseFrontmatterBlockWithDiagnostics(block.replace(/\r/g, ''), 1);
|
|
297
384
|
}
|
|
298
385
|
|
|
299
386
|
// Fallback: heading+list format (e.g. "## Git\n- isolation: none") (#2036)
|
|
300
387
|
// GSD agents may write preferences files without frontmatter delimiters.
|
|
301
388
|
if (/^##\s+\w/m.test(content)) {
|
|
302
|
-
return
|
|
389
|
+
return {
|
|
390
|
+
preferences: parseHeadingListFormat(content),
|
|
391
|
+
diagnostics: [],
|
|
392
|
+
};
|
|
303
393
|
}
|
|
304
394
|
|
|
305
395
|
// Warn when a non-empty file exists but lacks frontmatter delimiters (#2036).
|
|
@@ -310,27 +400,82 @@ export function parsePreferencesMarkdown(content: string): GSDPreferences | null
|
|
|
310
400
|
"Wrap your preferences in --- fences. See https://github.com/open-gsd/gsd-pi/issues/2036",
|
|
311
401
|
);
|
|
312
402
|
}
|
|
313
|
-
return
|
|
403
|
+
return {
|
|
404
|
+
preferences: null,
|
|
405
|
+
diagnostics: content.trim().length > 0
|
|
406
|
+
? [{
|
|
407
|
+
severity: "error",
|
|
408
|
+
kind: "parse",
|
|
409
|
+
message: "preferences file has unrecognized format; expected YAML frontmatter delimiters (---) or markdown preference sections",
|
|
410
|
+
ignored: true,
|
|
411
|
+
}]
|
|
412
|
+
: [],
|
|
413
|
+
};
|
|
314
414
|
}
|
|
315
415
|
|
|
316
416
|
let _warnedFrontmatterParse = false;
|
|
317
|
-
function
|
|
417
|
+
function parseFrontmatterBlockWithDiagnostics(
|
|
418
|
+
frontmatter: string,
|
|
419
|
+
lineOffset: number,
|
|
420
|
+
): { preferences: GSDPreferences; diagnostics: PreferenceParseDiagnostic[] } {
|
|
318
421
|
try {
|
|
319
422
|
const parsed = parseYaml(frontmatter);
|
|
320
423
|
if (typeof parsed !== 'object' || parsed === null) {
|
|
321
|
-
return {
|
|
424
|
+
return {
|
|
425
|
+
preferences: {} as GSDPreferences,
|
|
426
|
+
diagnostics: [{
|
|
427
|
+
severity: "error",
|
|
428
|
+
kind: "validation",
|
|
429
|
+
message: "preferences frontmatter must be a YAML object",
|
|
430
|
+
ignored: true,
|
|
431
|
+
}],
|
|
432
|
+
};
|
|
322
433
|
}
|
|
323
|
-
return
|
|
434
|
+
return {
|
|
435
|
+
preferences: normalizeParsedPreferences(parsed as GSDPreferences),
|
|
436
|
+
diagnostics: [],
|
|
437
|
+
};
|
|
324
438
|
} catch (e) {
|
|
325
439
|
// Warn at most once per session to avoid flooding TUI (#3376)
|
|
326
440
|
if (!_warnedFrontmatterParse) {
|
|
327
441
|
_warnedFrontmatterParse = true;
|
|
328
442
|
logWarning("guided", `YAML parse error in preferences frontmatter (suppressing further): ${(e as Error).message}`);
|
|
329
443
|
}
|
|
330
|
-
|
|
444
|
+
const location = extractYamlErrorLocation(e, lineOffset);
|
|
445
|
+
return {
|
|
446
|
+
preferences: {} as GSDPreferences,
|
|
447
|
+
diagnostics: [{
|
|
448
|
+
severity: "error",
|
|
449
|
+
kind: "parse",
|
|
450
|
+
message: cleanYamlErrorMessage(e),
|
|
451
|
+
...(location.line !== undefined ? { line: location.line } : {}),
|
|
452
|
+
...(location.column !== undefined ? { column: location.column } : {}),
|
|
453
|
+
ignored: true,
|
|
454
|
+
}],
|
|
455
|
+
};
|
|
331
456
|
}
|
|
332
457
|
}
|
|
333
458
|
|
|
459
|
+
function cleanYamlErrorMessage(error: unknown): string {
|
|
460
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
461
|
+
const firstLine = message.split("\n")[0]?.trim() ?? "unknown YAML parse error";
|
|
462
|
+
return firstLine.replace(/\s+at line \d+, column \d+:?$/, "");
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
function extractYamlErrorLocation(
|
|
466
|
+
error: unknown,
|
|
467
|
+
lineOffset: number,
|
|
468
|
+
): { line?: number; column?: number } {
|
|
469
|
+
const linePos = (error as { linePos?: Array<{ line?: unknown; col?: unknown }> })?.linePos;
|
|
470
|
+
const first = Array.isArray(linePos) ? linePos[0] : undefined;
|
|
471
|
+
const line = typeof first?.line === "number" ? first.line + lineOffset : undefined;
|
|
472
|
+
const column = typeof first?.col === "number" ? first.col : undefined;
|
|
473
|
+
return {
|
|
474
|
+
...(line !== undefined ? { line } : {}),
|
|
475
|
+
...(column !== undefined ? { column } : {}),
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
|
|
334
479
|
function normalizeParsedPreferences(preferences: GSDPreferences): GSDPreferences {
|
|
335
480
|
const remoteQuestions = preferences.remote_questions;
|
|
336
481
|
if (remoteQuestions && typeof remoteQuestions === "object" && typeof remoteQuestions.channel_id === "number") {
|
|
@@ -722,6 +867,24 @@ export function getIsolationMode(basePath?: string): "none" | "worktree" | "bran
|
|
|
722
867
|
return "none"; // default — no isolation, work on current branch
|
|
723
868
|
}
|
|
724
869
|
|
|
870
|
+
/**
|
|
871
|
+
* Resolve the isolation mode a unit actually runs under. A session whose
|
|
872
|
+
* worktree isolation has degraded (worktree creation failed) falls back to
|
|
873
|
+
* the milestone branch in the project root, so configured "worktree" becomes
|
|
874
|
+
* effective "branch". A stranded-work recovery session likewise runs under
|
|
875
|
+
* the adopted mode (`strandedRecoveryIsolationMode`) rather than the
|
|
876
|
+
* configured one until the recovered milestone merges — adopting the
|
|
877
|
+
* milestone branch in the project root is intentional, not degraded.
|
|
878
|
+
*/
|
|
879
|
+
export function resolveEffectiveUnitIsolationMode(
|
|
880
|
+
configuredMode: ReturnType<typeof getIsolationMode>,
|
|
881
|
+
isolationDegraded: boolean,
|
|
882
|
+
strandedRecoveryIsolationMode: "worktree" | "branch" | null = null,
|
|
883
|
+
): ReturnType<typeof getIsolationMode> {
|
|
884
|
+
if (configuredMode === "worktree" && isolationDegraded) return "branch";
|
|
885
|
+
return strandedRecoveryIsolationMode ?? configuredMode;
|
|
886
|
+
}
|
|
887
|
+
|
|
725
888
|
export function resolveParallelConfig(prefs: GSDPreferences | undefined): import("./types.js").ParallelConfig {
|
|
726
889
|
return {
|
|
727
890
|
enabled: prefs?.parallel?.enabled ?? false,
|
|
@@ -37,6 +37,7 @@ Use `subagent` only when useful: reviewer, security, or tester. Apply findings b
|
|
|
37
37
|
9. If requirement status changed, call `gsd_requirement_update`; do not write `.gsd/REQUIREMENTS.md` directly.
|
|
38
38
|
10. Prepare `gsd_slice_complete` content with camelCase fields `milestoneId`, `sliceId`, `sliceTitle`, `oneLiner`, `narrative`, `verification`, and `uatContent`.
|
|
39
39
|
11. Draft concrete UAT with preconditions, steps, expected outcomes, edge cases, and UAT Type.
|
|
40
|
+
**Web apps:** when inlined Web App UAT guidance is present, declare `browser-executable` or `runtime-executable` (not `artifact-driven`) for localhost/browser/screenshot steps; include dev-server preconditions and name Playwright specs when they exist.
|
|
40
41
|
12. Review the inlined task-summary excerpts for DECISIONS.md/KNOWLEDGE.md-worthy decisions and gotchas. Read full `*-SUMMARY.md` only if needed. Capture with `capture_thought`; do not append knowledge files.
|
|
41
42
|
13. When verification passes, call `gsd_slice_complete`. The DB-backed tool is the canonical write path. Do **not** manually write `{{sliceSummaryPath}}`. Do **not** manually write `{{sliceUatPath}}`. Do not edit roadmap checkboxes.
|
|
42
43
|
14. Do not run git commands.
|
|
@@ -32,6 +32,8 @@ You execute. The inlined task plan is authoritative. Verify referenced files and
|
|
|
32
32
|
- Prior task summaries:
|
|
33
33
|
{{priorTaskLines}}
|
|
34
34
|
|
|
35
|
+
{{onDemandContext}}
|
|
36
|
+
|
|
35
37
|
## Execution Rules
|
|
36
38
|
|
|
37
39
|
1. Tersely narrate transitions, decisions, and verification outcomes between tool-call clusters.
|