@opengsd/gsd-pi 1.4.0-dev.c18009cd → 1.5.0-dev.4fb2d460
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/README.md +10 -10
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/ask-user-questions.js +1 -1
- package/dist/resources/extensions/gsd/auto/closeout.js +97 -5
- package/dist/resources/extensions/gsd/auto/orchestrator.js +4 -3
- package/dist/resources/extensions/gsd/auto/pre-dispatch.js +6 -3
- package/dist/resources/extensions/gsd/auto/unit-phase.js +5 -9
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +12 -3
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -7
- package/dist/resources/extensions/gsd/auto-dispatch.js +16 -2
- package/dist/resources/extensions/gsd/auto-recovery.js +50 -6
- package/dist/resources/extensions/gsd/auto-start.js +4 -3
- package/dist/resources/extensions/gsd/auto-worktree-branch-lifecycle.js +189 -0
- package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +133 -0
- package/dist/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.js +35 -0
- package/dist/resources/extensions/gsd/auto-worktree-creation.js +130 -0
- package/dist/resources/extensions/gsd/auto-worktree-entry.js +118 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-already-merged.js +98 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-branch-head.js +52 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-cleanup.js +87 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-code-changes.js +46 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-db-ready.js +68 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-integration-branch.js +51 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-message.js +106 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-pre-teardown.js +64 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-stash.js +168 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge.js +302 -0
- package/dist/resources/extensions/gsd/auto-worktree-milestone-shelter.js +119 -0
- package/dist/resources/extensions/gsd/auto-worktree-path-resolution.js +5 -0
- package/dist/resources/extensions/gsd/auto-worktree-path-utils.js +5 -0
- package/dist/resources/extensions/gsd/auto-worktree-resource-version.js +41 -0
- package/dist/resources/extensions/gsd/auto-worktree-runtime-cleanup.js +99 -0
- package/dist/resources/extensions/gsd/auto-worktree-session-registry.js +57 -0
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +249 -0
- package/dist/resources/extensions/gsd/auto-worktree-teardown.js +120 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +20 -2073
- package/dist/resources/extensions/gsd/auto.js +9 -3
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +20 -2
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +185 -27
- package/dist/resources/extensions/gsd/codebase-generator.js +7 -1
- package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
- package/dist/resources/extensions/gsd/commands-workflow-templates.js +3 -3
- package/dist/resources/extensions/gsd/db/queries.js +9 -9
- package/dist/resources/extensions/gsd/db/writers/cascades.js +20 -2
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +93 -11
- package/dist/resources/extensions/gsd/flat-phase-migration.js +32 -3
- package/dist/resources/extensions/gsd/forensics.js +1 -1
- package/dist/resources/extensions/gsd/git-conflict-resolve.js +2 -2
- package/dist/resources/extensions/gsd/git-service.js +45 -0
- package/dist/resources/extensions/gsd/gsd-db.js +23 -11
- package/dist/resources/extensions/gsd/guided-flow.js +22 -17
- package/dist/resources/extensions/gsd/markdown-renderer.js +15 -3
- package/dist/resources/extensions/gsd/md-importer.js +89 -23
- package/dist/resources/extensions/gsd/migration-auto-check.js +30 -3
- package/dist/resources/extensions/gsd/milestone-merge-transaction.js +11 -0
- package/dist/resources/extensions/gsd/milestone-settlement.js +1 -1
- package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -1
- package/dist/resources/extensions/gsd/paths.js +17 -3
- package/dist/resources/extensions/gsd/preferences-skills.js +10 -16
- package/dist/resources/extensions/gsd/preferences-types.js +1 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +82 -0
- package/dist/resources/extensions/gsd/preferences.js +20 -0
- package/dist/resources/extensions/gsd/prompts/system.md +6 -6
- package/dist/resources/extensions/gsd/quick.js +12 -3
- package/dist/resources/extensions/gsd/skill-discovery.js +36 -23
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +2 -1
- package/dist/resources/extensions/gsd/state/derive/from-db.js +88 -153
- package/dist/resources/extensions/gsd/tool-contract.js +14 -0
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +5 -0
- package/dist/resources/extensions/gsd/tools/reopen-task.js +13 -5
- package/dist/resources/extensions/gsd/unit-registry.js +12 -2
- package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +1 -1
- package/dist/resources/extensions/gsd/validation-block-guard.js +2 -1
- package/dist/resources/extensions/gsd/workspace-git-preflight.js +2 -2
- package/dist/resources/extensions/gsd/worktree-command.js +1 -1
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +14 -9
- package/dist/resources/extensions/gsd/worktree-reentry.js +2 -1
- package/dist/resources/extensions/shared/interview-ui.js +62 -9
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- 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/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 +8 -8
- package/dist/web/standalone/.next/server/middleware-build-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/node_modules/@gsd/native/package.json +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/integrations/hermes/open_gsd_hermes/gsd_client.py +24 -35
- package/integrations/hermes/tests/test_gsd_client_timeout.py +4 -4
- package/package.json +6 -6
- 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/export-html/template.js +53 -4
- package/packages/gsd-agent-core/package.json +5 -5
- 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 +3 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +14 -9
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/index.d.ts +1 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -0
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.js +7 -3
- package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
- package/packages/pi-ai/dist/tool-result-content.d.ts +3 -0
- package/packages/pi-ai/dist/tool-result-content.d.ts.map +1 -0
- package/packages/pi-ai/dist/tool-result-content.js +62 -0
- package/packages/pi-ai/dist/tool-result-content.js.map +1 -0
- package/packages/pi-ai/dist/types.d.ts +8 -20
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.js +74 -53
- package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +30 -2
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skill-directories.d.ts +66 -0
- package/packages/pi-coding-agent/dist/core/skill-directories.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/skill-directories.js +138 -0
- package/packages/pi-coding-agent/dist/core/skill-directories.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/skills.d.ts +4 -1
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +4 -1
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -0
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/dist/core/export-html/template.js +53 -4
- package/pkg/package.json +1 -1
- package/src/resources/extensions/ask-user-questions.ts +1 -1
- package/src/resources/extensions/gsd/auto/closeout.ts +114 -7
- package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -3
- package/src/resources/extensions/gsd/auto/pre-dispatch.ts +6 -3
- package/src/resources/extensions/gsd/auto/unit-phase.ts +5 -9
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +12 -3
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +13 -7
- package/src/resources/extensions/gsd/auto-dispatch.ts +18 -2
- package/src/resources/extensions/gsd/auto-recovery.ts +50 -6
- package/src/resources/extensions/gsd/auto-start.ts +5 -3
- package/src/resources/extensions/gsd/auto-worktree-branch-lifecycle.ts +237 -0
- package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +166 -0
- package/src/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.ts +37 -0
- package/src/resources/extensions/gsd/auto-worktree-creation.ts +171 -0
- package/src/resources/extensions/gsd/auto-worktree-entry.ts +154 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-already-merged.ts +161 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-branch-head.ts +83 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-cleanup.ts +132 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-code-changes.ts +71 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-db-ready.ts +112 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-integration-branch.ts +99 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-message.ts +166 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-pre-teardown.ts +93 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-stash.ts +213 -0
- package/src/resources/extensions/gsd/auto-worktree-merge.ts +391 -0
- package/src/resources/extensions/gsd/auto-worktree-milestone-shelter.ts +159 -0
- package/src/resources/extensions/gsd/auto-worktree-path-resolution.ts +6 -0
- package/src/resources/extensions/gsd/auto-worktree-path-utils.ts +10 -0
- package/src/resources/extensions/gsd/auto-worktree-resource-version.ts +44 -0
- package/src/resources/extensions/gsd/auto-worktree-runtime-cleanup.ts +119 -0
- package/src/resources/extensions/gsd/auto-worktree-session-registry.ts +71 -0
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +370 -0
- package/src/resources/extensions/gsd/auto-worktree-teardown.ts +161 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +69 -2429
- package/src/resources/extensions/gsd/auto.ts +11 -17
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +20 -2
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +218 -27
- package/src/resources/extensions/gsd/codebase-generator.ts +7 -1
- package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +3 -3
- package/src/resources/extensions/gsd/db/queries.ts +9 -9
- package/src/resources/extensions/gsd/db/writers/cascades.ts +23 -1
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +109 -10
- package/src/resources/extensions/gsd/flat-phase-migration.ts +34 -3
- package/src/resources/extensions/gsd/forensics.ts +1 -1
- package/src/resources/extensions/gsd/git-conflict-resolve.ts +2 -2
- package/src/resources/extensions/gsd/git-service.ts +53 -0
- package/src/resources/extensions/gsd/gsd-db.ts +33 -11
- package/src/resources/extensions/gsd/guided-flow.ts +26 -18
- package/src/resources/extensions/gsd/markdown-renderer.ts +15 -3
- package/src/resources/extensions/gsd/md-importer.ts +93 -22
- package/src/resources/extensions/gsd/migration-auto-check.ts +32 -3
- package/src/resources/extensions/gsd/milestone-merge-transaction.ts +15 -0
- package/src/resources/extensions/gsd/milestone-settlement.ts +1 -1
- package/src/resources/extensions/gsd/parallel-merge.ts +1 -1
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -1
- package/src/resources/extensions/gsd/paths.ts +21 -3
- package/src/resources/extensions/gsd/preferences-skills.ts +10 -16
- package/src/resources/extensions/gsd/preferences-types.ts +30 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +69 -0
- package/src/resources/extensions/gsd/preferences.ts +20 -0
- package/src/resources/extensions/gsd/prompts/system.md +6 -6
- package/src/resources/extensions/gsd/quick.ts +11 -3
- package/src/resources/extensions/gsd/skill-discovery.ts +47 -23
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +3 -1
- package/src/resources/extensions/gsd/state/derive/from-db.ts +201 -157
- package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +169 -1
- package/src/resources/extensions/gsd/tests/auto-loop-no-copy-artifacts.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +57 -0
- package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-already-merged.test.ts +177 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-branch-head.test.ts +118 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-cleanup.test.ts +115 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-code-changes.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-db-ready.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-integration-branch.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-message.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-pre-teardown.test.ts +84 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-stash.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-shelter.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +6 -6
- package/src/resources/extensions/gsd/tests/auto-worktree-resource-version.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +174 -0
- package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +71 -1
- package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +25 -1
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/import-completion-lost-update.test.ts +196 -0
- package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +4 -6
- package/src/resources/extensions/gsd/tests/integration/auto-stash-merge.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +7 -8
- package/src/resources/extensions/gsd/tests/integration/feature-branch-lifecycle-integration.test.ts +2 -5
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/integration/merge-cwd-restore.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/merge-preserve-worktree-on-preteardown-error.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/merge-strategy-regular.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +5 -7
- package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts +2 -4
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +16 -15
- package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +91 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +439 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/parallel-worker-lock-contention.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +1 -4
- package/src/resources/extensions/gsd/tests/preferences.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +3 -5
- package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/system-flat-phase-layout.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/teardown-cleanup-parity.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/teardown-failure-clears-registry.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +196 -0
- package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/unit-registry.test.ts +26 -1
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +1 -3
- package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +1 -1
- package/src/resources/extensions/gsd/tool-contract.ts +29 -0
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +5 -0
- package/src/resources/extensions/gsd/tools/reopen-task.ts +13 -5
- package/src/resources/extensions/gsd/unit-registry.ts +16 -2
- package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +1 -1
- package/src/resources/extensions/gsd/validation-block-guard.ts +2 -1
- package/src/resources/extensions/gsd/workspace-git-preflight.ts +2 -2
- package/src/resources/extensions/gsd/worktree-command.ts +1 -1
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +19 -15
- package/src/resources/extensions/gsd/worktree-reentry.ts +2 -1
- package/src/resources/extensions/shared/interview-ui.ts +58 -11
- package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +32 -0
- /package/dist/web/standalone/.next/static/{L2UMqXELiDH3oz-7yguXp → gXoWec4UNqcR0tkuHwYCr}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{L2UMqXELiDH3oz-7yguXp → gXoWec4UNqcR0tkuHwYCr}/_ssgManifest.js +0 -0
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
import { importExtensionModule, type ExtensionAPI, type ExtensionContext } from "@gsd/pi-coding-agent";
|
|
5
5
|
|
|
6
|
+
import { execFileSync } from "node:child_process";
|
|
7
|
+
import { createHash } from "node:crypto";
|
|
6
8
|
import { join, basename } from "node:path";
|
|
7
|
-
import { existsSync, cpSync } from "node:fs";
|
|
9
|
+
import { existsSync, cpSync, readFileSync } from "node:fs";
|
|
8
10
|
import type { AutoSession } from "./session.js";
|
|
9
11
|
import type { LoopDeps } from "./loop-deps.js";
|
|
10
12
|
import type { GSDState } from "../types.js";
|
|
@@ -16,7 +18,7 @@ import { getIsolationMode } from "../preferences.js";
|
|
|
16
18
|
import { isDbAvailable, getMilestone } from "../gsd-db.js";
|
|
17
19
|
import { refreshWorkflowDatabaseFromDisk } from "../db-workspace.js";
|
|
18
20
|
import { isClosedStatus } from "../status-guards.js";
|
|
19
|
-
import { gsdRoot } from "../paths.js";
|
|
21
|
+
import { gsdRoot, PLANNING_ARTIFACT_SUFFIXES } from "../paths.js";
|
|
20
22
|
import { atomicWriteSync } from "../atomic-write.js";
|
|
21
23
|
import { logWarning, logError } from "../workflow-logger.js";
|
|
22
24
|
import { debugLog } from "../debug-logger.js";
|
|
@@ -98,7 +100,15 @@ export async function _runMilestoneMergeWithStashRestore(
|
|
|
98
100
|
): Promise<{ action: "break"; reason: string } | null> {
|
|
99
101
|
const { ctx, pi, s, deps } = ic;
|
|
100
102
|
|
|
101
|
-
|
|
103
|
+
// Resolve the project root once, before the merge can flip session path
|
|
104
|
+
// pointers (worktree teardown mutates s.basePath / s.scope). The guarded
|
|
105
|
+
// merge's preflight/postflight stash restore, the pre-merge ignored-markdown
|
|
106
|
+
// snapshot, the dirty-projection check, and the rebuild must all target this
|
|
107
|
+
// same tree; otherwise `.gsd` markdown restored on one tree can be silently
|
|
108
|
+
// overwritten by a rebuild on another. canonicalProjectRoot is the
|
|
109
|
+
// authoritative `.gsd`/DB writer path (see AutoSession.canonicalProjectRoot).
|
|
110
|
+
const projectRoot = s.originalBasePath || s.canonicalProjectRoot || s.basePath;
|
|
111
|
+
const ignoredProjectionSnapshot = snapshotIgnoredGsdMarkdownProjections(projectRoot);
|
|
102
112
|
const mergeResult = deps.lifecycle.exitMilestone(
|
|
103
113
|
milestoneId,
|
|
104
114
|
{
|
|
@@ -113,12 +123,12 @@ export async function _runMilestoneMergeWithStashRestore(
|
|
|
113
123
|
);
|
|
114
124
|
|
|
115
125
|
if (mergeResult.ok) {
|
|
116
|
-
await markMilestoneMergedAndRebuild(s);
|
|
126
|
+
await markMilestoneMergedAndRebuild(s, projectRoot, ignoredProjectionSnapshot);
|
|
117
127
|
return null;
|
|
118
128
|
}
|
|
119
129
|
|
|
120
130
|
if (mergeResult.reason === "postflight-stash-restore-failed") {
|
|
121
|
-
await markMilestoneMergedAndRebuild(s);
|
|
131
|
+
await markMilestoneMergedAndRebuild(s, projectRoot, ignoredProjectionSnapshot);
|
|
122
132
|
}
|
|
123
133
|
|
|
124
134
|
if (mergeResult.reason === "preflight-dirty-overlap" || mergeResult.reason === "preflight-unmerged-conflicts") {
|
|
@@ -180,10 +190,23 @@ export async function _runMilestoneMergeWithStashRestore(
|
|
|
180
190
|
return null;
|
|
181
191
|
}
|
|
182
192
|
|
|
183
|
-
|
|
193
|
+
type GsdMarkdownSnapshot = Map<string, string>;
|
|
194
|
+
|
|
195
|
+
async function markMilestoneMergedAndRebuild(
|
|
196
|
+
s: AutoSession,
|
|
197
|
+
rebuildBasePath: string,
|
|
198
|
+
ignoredProjectionSnapshot: GsdMarkdownSnapshot | null,
|
|
199
|
+
): Promise<void> {
|
|
184
200
|
s.milestoneMergedInPhases = true;
|
|
201
|
+
if (hasDirtyGsdMarkdownProjections(rebuildBasePath, ignoredProjectionSnapshot)) {
|
|
202
|
+
logWarning(
|
|
203
|
+
"engine",
|
|
204
|
+
"skipping markdown projection rebuild after milestone merge because restored .gsd edits are dirty",
|
|
205
|
+
);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
|
|
185
209
|
try {
|
|
186
|
-
const rebuildBasePath = s.originalBasePath || s.canonicalProjectRoot || s.basePath;
|
|
187
210
|
const { rebuildMarkdownProjectionsFromDb } = await import("../commands-maintenance.js");
|
|
188
211
|
await rebuildMarkdownProjectionsFromDb(rebuildBasePath);
|
|
189
212
|
} catch (err) {
|
|
@@ -194,6 +217,90 @@ async function markMilestoneMergedAndRebuild(s: AutoSession): Promise<void> {
|
|
|
194
217
|
}
|
|
195
218
|
}
|
|
196
219
|
|
|
220
|
+
function hasDirtyGsdMarkdownProjections(
|
|
221
|
+
basePath: string,
|
|
222
|
+
ignoredProjectionSnapshot: GsdMarkdownSnapshot | null,
|
|
223
|
+
): boolean {
|
|
224
|
+
try {
|
|
225
|
+
const output = execFileSync(
|
|
226
|
+
"git",
|
|
227
|
+
["status", "--porcelain", "-z", "--untracked-files=all", "--", ".gsd"],
|
|
228
|
+
{ cwd: basePath, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] },
|
|
229
|
+
);
|
|
230
|
+
const entries = output.split("\0").filter(Boolean);
|
|
231
|
+
for (let i = 0; i < entries.length; i++) {
|
|
232
|
+
const entry = entries[i];
|
|
233
|
+
if (entry.length <= 3) continue;
|
|
234
|
+
const status = entry.slice(0, 2);
|
|
235
|
+
const path = entry.slice(3);
|
|
236
|
+
if (isGeneratedGsdMarkdownProjection(path)) return true;
|
|
237
|
+
if ((status === "R " || status === "C ") && i + 1 < entries.length) {
|
|
238
|
+
const dest = entries[++i];
|
|
239
|
+
if (isGeneratedGsdMarkdownProjection(dest)) return true;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
} catch (err) {
|
|
243
|
+
void err;
|
|
244
|
+
// Fall through to ignored-file snapshot comparison below.
|
|
245
|
+
}
|
|
246
|
+
return ignoredGsdMarkdownProjectionSnapshotChanged(basePath, ignoredProjectionSnapshot);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function isGeneratedGsdMarkdownProjection(path: string): boolean {
|
|
250
|
+
const normalized = path.replace(/\\/g, "/");
|
|
251
|
+
if (normalized === ".gsd/DECISIONS.md") return true;
|
|
252
|
+
if (!normalized.startsWith(".gsd/milestones/") && !normalized.startsWith(".gsd/phases/")) {
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
return isGeneratedPlanningArtifactFileName(basename(normalized));
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function isGeneratedPlanningArtifactFileName(fileName: string): boolean {
|
|
259
|
+
if (!fileName.endsWith(".md")) return false;
|
|
260
|
+
const stem = fileName.slice(0, -".md".length).toUpperCase();
|
|
261
|
+
for (const suffix of PLANNING_ARTIFACT_SUFFIXES) {
|
|
262
|
+
if (!stem.endsWith(`-${suffix}`)) continue;
|
|
263
|
+
const idPrefix = stem.slice(0, -suffix.length - 1);
|
|
264
|
+
return /^(?:[MST]\d+|\d{2,})(?:-[A-Z0-9]+)*$/.test(idPrefix);
|
|
265
|
+
}
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function snapshotIgnoredGsdMarkdownProjections(basePath: string): GsdMarkdownSnapshot | null {
|
|
270
|
+
try {
|
|
271
|
+
const output = execFileSync(
|
|
272
|
+
"git",
|
|
273
|
+
["ls-files", "--others", "--ignored", "--exclude-standard", "-z", "--", ".gsd"],
|
|
274
|
+
{ cwd: basePath, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] },
|
|
275
|
+
);
|
|
276
|
+
const snapshot: GsdMarkdownSnapshot = new Map();
|
|
277
|
+
for (const path of output.split("\0")) {
|
|
278
|
+
if (!isGeneratedGsdMarkdownProjection(path)) continue;
|
|
279
|
+
snapshot.set(path, hashFile(join(basePath, path)));
|
|
280
|
+
}
|
|
281
|
+
return snapshot;
|
|
282
|
+
} catch {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function hashFile(path: string): string {
|
|
288
|
+
return createHash("sha256").update(readFileSync(path)).digest("hex");
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function ignoredGsdMarkdownProjectionSnapshotChanged(
|
|
292
|
+
basePath: string,
|
|
293
|
+
before: GsdMarkdownSnapshot | null,
|
|
294
|
+
): boolean {
|
|
295
|
+
if (!before) return true;
|
|
296
|
+
const after = snapshotIgnoredGsdMarkdownProjections(basePath);
|
|
297
|
+
if (!after || after.size !== before.size) return true;
|
|
298
|
+
for (const [path, hash] of before) {
|
|
299
|
+
if (after.get(path) !== hash) return true;
|
|
300
|
+
}
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
|
|
197
304
|
export async function _runMilestoneMergeOnceWithStashRestore(
|
|
198
305
|
ic: IterationContext,
|
|
199
306
|
milestoneId: string,
|
|
@@ -34,7 +34,8 @@ import {
|
|
|
34
34
|
preDispatchHealthGate,
|
|
35
35
|
recordHealthSnapshot,
|
|
36
36
|
} from "../doctor-proactive.js";
|
|
37
|
-
import {
|
|
37
|
+
import { autoWorktreeBranch } from "../auto-worktree-branch-lifecycle.js";
|
|
38
|
+
import { checkResourcesStale } from "../auto-worktree-resource-version.js";
|
|
38
39
|
import { getSessionLockStatus } from "../session-lock.js";
|
|
39
40
|
import { resolveUokFlags } from "../uok/flags.js";
|
|
40
41
|
import { emitJournalEvent as _emitJournalEvent } from "../journal.js";
|
|
@@ -49,7 +50,7 @@ import { getPriorSliceCompletionBlocker } from "../dispatch-guard.js";
|
|
|
49
50
|
import { GitServiceImpl } from "../git-service.js";
|
|
50
51
|
import { WorktreeStateProjection } from "../worktree-state-projection.js";
|
|
51
52
|
import { WorktreeLifecycle } from "../worktree-lifecycle.js";
|
|
52
|
-
import {
|
|
53
|
+
import { createDefaultMilestoneMergeTransaction } from "../milestone-merge-transaction.js";
|
|
53
54
|
import { createWorkspace, scopeMilestone } from "../workspace.js";
|
|
54
55
|
import { supportsStructuredQuestions } from "../workflow-mcp.js";
|
|
55
56
|
import { getRegisteredToolSnapshot, getToolBaselineSnapshot } from "../auto-model-selection.js";
|
|
@@ -731,7 +732,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
731
732
|
return new GitServiceImpl(basePath, gitConfig);
|
|
732
733
|
},
|
|
733
734
|
worktreeProjection: new WorktreeStateProjection(),
|
|
734
|
-
mergeMilestone:
|
|
735
|
+
mergeMilestone: createDefaultMilestoneMergeTransaction(),
|
|
735
736
|
});
|
|
736
737
|
}
|
|
737
738
|
|
|
@@ -440,7 +440,8 @@ export async function runPreDispatch(
|
|
|
440
440
|
if (stop) return stop;
|
|
441
441
|
}
|
|
442
442
|
|
|
443
|
-
// PR creation (auto_pr) is handled
|
|
443
|
+
// PR creation (auto_pr) is handled by the publication handoff in
|
|
444
|
+
// the milestone merge transaction (#2302).
|
|
444
445
|
|
|
445
446
|
deps.invalidateAllCaches();
|
|
446
447
|
|
|
@@ -551,7 +552,8 @@ export async function runPreDispatch(
|
|
|
551
552
|
// #2909 / #5538-followup: preflight stash + always-on postflight pop.
|
|
552
553
|
const stop = await _runMilestoneMergeOnceWithStashRestore(ic, s.currentMilestoneId);
|
|
553
554
|
if (stop) return stop;
|
|
554
|
-
// PR creation (auto_pr) is handled
|
|
555
|
+
// PR creation (auto_pr) is handled by the publication handoff in
|
|
556
|
+
// the milestone merge transaction (#2302).
|
|
555
557
|
}
|
|
556
558
|
const unmappedActive = countUnmappedActiveRequirements();
|
|
557
559
|
const completionStopReason = formatCompletePhaseNextAction(unmappedActive);
|
|
@@ -654,7 +656,8 @@ export async function runPreDispatch(
|
|
|
654
656
|
// #2909 / #5538-followup: preflight stash + always-on postflight pop.
|
|
655
657
|
const stop = await _runMilestoneMergeOnceWithStashRestore(ic, s.currentMilestoneId);
|
|
656
658
|
if (stop) return stop;
|
|
657
|
-
// PR creation (auto_pr) is handled
|
|
659
|
+
// PR creation (auto_pr) is handled by the publication handoff in
|
|
660
|
+
// the milestone merge transaction (#2302).
|
|
658
661
|
}
|
|
659
662
|
deps.sendDesktopNotification(
|
|
660
663
|
"GSD",
|
|
@@ -29,7 +29,7 @@ import type { MinimalModelRegistry } from "../context-budget.js";
|
|
|
29
29
|
import { parseUnitId } from "../unit-id.js";
|
|
30
30
|
import { createCheckpoint, cleanupCheckpoint, rollbackToCheckpoint } from "../safety/git-checkpoint.js";
|
|
31
31
|
import { resolveSafetyHarnessConfig } from "../safety/safety-harness.js";
|
|
32
|
-
import {
|
|
32
|
+
import { getUnitWorkflowDispatchReadinessErrorForModel } from "../tool-contract.js";
|
|
33
33
|
import { prepareWorkflowMcpForProject } from "../workflow-mcp-auto-prep.js";
|
|
34
34
|
import {
|
|
35
35
|
applyThinkingLevelForModel,
|
|
@@ -343,17 +343,13 @@ export async function runUnitPhase(
|
|
|
343
343
|
? `${(s.currentUnitModel as any).provider ?? ""}/${(s.currentUnitModel as any).id ?? ""}`
|
|
344
344
|
: null;
|
|
345
345
|
|
|
346
|
-
const compatibilityError =
|
|
347
|
-
|
|
346
|
+
const compatibilityError = getUnitWorkflowDispatchReadinessErrorForModel({
|
|
347
|
+
model: s.currentUnitModel as any,
|
|
348
|
+
fallbackModel: ctx.model,
|
|
349
|
+
getProviderAuthMode: (provider) => ctx.modelRegistry.getProviderAuthMode(provider),
|
|
348
350
|
projectRoot: s.basePath,
|
|
349
351
|
surface: "auto-mode",
|
|
350
352
|
unitType,
|
|
351
|
-
authMode: s.currentUnitModel?.provider
|
|
352
|
-
? ctx.modelRegistry.getProviderAuthMode(s.currentUnitModel.provider)
|
|
353
|
-
: ctx.model?.provider
|
|
354
|
-
? ctx.modelRegistry.getProviderAuthMode(ctx.model.provider)
|
|
355
|
-
: undefined,
|
|
356
|
-
baseUrl: (s.currentUnitModel as any)?.baseUrl ?? ctx.model?.baseUrl,
|
|
357
353
|
activeTools: typeof pi.getActiveTools === "function" ? pi.getActiveTools() : [],
|
|
358
354
|
});
|
|
359
355
|
const workflowMcpPrepModel = s.currentUnitModel;
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
} from "./paths.js";
|
|
23
23
|
import { milestoneIdToPhaseNum } from "./layout-policy.js";
|
|
24
24
|
import { parseUnitId } from "./unit-id.js";
|
|
25
|
-
import { dirname, join, relative } from "node:path";
|
|
25
|
+
import { basename, dirname, join, relative } from "node:path";
|
|
26
26
|
import { existsSync } from "node:fs";
|
|
27
27
|
|
|
28
28
|
function resolveMilestoneArtifactPath(
|
|
@@ -221,8 +221,17 @@ export function resolveExpectedArtifactPath(
|
|
|
221
221
|
?? resolveProjectSlicePath(base, mid, sid!)
|
|
222
222
|
?? resolveSlicePath(base, mid, sid!);
|
|
223
223
|
if (!slicePath || !tid) return null;
|
|
224
|
-
|
|
225
|
-
|
|
224
|
+
// Legacy layout: slice dirs live under slices/<SID>/ and task summaries
|
|
225
|
+
// live in a tasks/ subdir. Flat-phase layout: slicePath IS the phase dir
|
|
226
|
+
// and task summaries live beside the plan files at the phase root. A
|
|
227
|
+
// tasks/ subdir may still exist in flat-phase for auxiliary task-scoped
|
|
228
|
+
// artifacts (e.g. T01-VERIFY.json gate outputs) — its mere existence must
|
|
229
|
+
// NOT redirect summary resolution into tasks/ (#1208).
|
|
230
|
+
const isLegacySlice = basename(dirname(slicePath)) === "slices";
|
|
231
|
+
const summaryDir = isLegacySlice
|
|
232
|
+
? (resolveTasksDir(base, mid, sid!) ?? slicePath)
|
|
233
|
+
: slicePath;
|
|
234
|
+
return join(summaryDir, buildTaskFileName(tid, "SUMMARY"));
|
|
226
235
|
}
|
|
227
236
|
case "complete-slice": {
|
|
228
237
|
return resolveSliceArtifactPath(base, mid, sid!, "SUMMARY");
|
|
@@ -27,11 +27,11 @@ import {
|
|
|
27
27
|
buildRunUatPrompt,
|
|
28
28
|
buildReplanSlicePrompt,
|
|
29
29
|
} from "./auto-prompts.js";
|
|
30
|
-
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
30
|
+
import { loadEffectiveGSDPreferences, renderLanguageDirectiveForPrompt } from "./preferences.js";
|
|
31
31
|
import type { MinimalModelRegistry } from "./context-budget.js";
|
|
32
32
|
import { pauseAuto } from "./auto.js";
|
|
33
33
|
import { resolveCanonicalMilestoneRoot } from "./worktree-manager.js";
|
|
34
|
-
import {
|
|
34
|
+
import { getUnitWorkflowDispatchReadinessErrorForModel } from "./tool-contract.js";
|
|
35
35
|
|
|
36
36
|
export function parseDirectDispatchPhase(raw: string): { phase: string; milestoneId?: string } {
|
|
37
37
|
const tokens = raw.trim().split(/\s+/).filter(Boolean);
|
|
@@ -266,13 +266,12 @@ export async function dispatchDirectPhase(
|
|
|
266
266
|
return;
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
-
const compatibilityError =
|
|
270
|
-
|
|
269
|
+
const compatibilityError = getUnitWorkflowDispatchReadinessErrorForModel({
|
|
270
|
+
model: ctx.model,
|
|
271
|
+
getProviderAuthMode: (provider) => ctx.modelRegistry.getProviderAuthMode(provider),
|
|
271
272
|
projectRoot,
|
|
272
273
|
surface: "direct phase dispatch",
|
|
273
274
|
unitType,
|
|
274
|
-
authMode: ctx.model?.provider ? ctx.modelRegistry.getProviderAuthMode(ctx.model.provider) : undefined,
|
|
275
|
-
baseUrl: ctx.model?.baseUrl,
|
|
276
275
|
activeTools: typeof pi.getActiveTools === "function" ? pi.getActiveTools() : [],
|
|
277
276
|
});
|
|
278
277
|
if (compatibilityError) {
|
|
@@ -287,8 +286,15 @@ export async function dispatchDirectPhase(
|
|
|
287
286
|
ctx.ui.notify("Session creation cancelled.", "warning");
|
|
288
287
|
return;
|
|
289
288
|
}
|
|
289
|
+
// Inject the configured response language into the dispatched prompt content
|
|
290
|
+
// — the new session's system prompt does not carry the preferences block, so
|
|
291
|
+
// the language setting would otherwise never reach the unit (#1210).
|
|
292
|
+
const languageDirective = renderLanguageDirectiveForPrompt(
|
|
293
|
+
loadEffectiveGSDPreferences(dispatchBase)?.preferences,
|
|
294
|
+
);
|
|
295
|
+
const dispatchContent = languageDirective ? `${languageDirective}\n\n${prompt}` : prompt;
|
|
290
296
|
pi.sendMessage(
|
|
291
|
-
{ customType: "gsd-dispatch", content:
|
|
297
|
+
{ customType: "gsd-dispatch", content: dispatchContent, display: false },
|
|
292
298
|
{ triggerTurn: true },
|
|
293
299
|
);
|
|
294
300
|
}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import type { GSDState, TaskIO } from "./types.js";
|
|
16
16
|
import type { GSDPreferences } from "./preferences.js";
|
|
17
|
+
import { renderLanguageDirectiveForPrompt } from "./preferences.js";
|
|
17
18
|
import type { MinimalModelRegistry } from "./context-budget.js";
|
|
18
19
|
import { loadFile, extractUatType, loadActiveOverrides } from "./files.js";
|
|
19
20
|
import { getUatBrowserToolSupportError, type UatType } from "./uat-policy.js";
|
|
@@ -1834,6 +1835,21 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
1834
1835
|
|
|
1835
1836
|
import { getRegistry } from "./rule-registry.js";
|
|
1836
1837
|
|
|
1838
|
+
/**
|
|
1839
|
+
* Prepend the configured response-language directive to a dispatched unit
|
|
1840
|
+
* prompt so auto-execution units respond in the language set in PREFERENCES.md
|
|
1841
|
+
* (#1210). No-op for non-dispatch actions or when no language is configured.
|
|
1842
|
+
*/
|
|
1843
|
+
function applyLanguageDirectiveToDispatch(
|
|
1844
|
+
action: DispatchAction,
|
|
1845
|
+
prefs: GSDPreferences | undefined,
|
|
1846
|
+
): DispatchAction {
|
|
1847
|
+
if (action.action !== "dispatch" || !action.prompt) return action;
|
|
1848
|
+
const directive = renderLanguageDirectiveForPrompt(prefs);
|
|
1849
|
+
if (!directive) return action;
|
|
1850
|
+
return { ...action, prompt: `${directive}\n\n${action.prompt}` };
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1837
1853
|
// ─── Resolver ─────────────────────────────────────────────────────────────
|
|
1838
1854
|
|
|
1839
1855
|
/**
|
|
@@ -1896,7 +1912,7 @@ export async function resolveDispatch(
|
|
|
1896
1912
|
level: "error",
|
|
1897
1913
|
};
|
|
1898
1914
|
}
|
|
1899
|
-
return action;
|
|
1915
|
+
return applyLanguageDirectiveToDispatch(action, ctx.prefs);
|
|
1900
1916
|
} catch (err) {
|
|
1901
1917
|
// Registry not initialized — fall back to inline loop
|
|
1902
1918
|
logWarning("dispatch", `registry dispatch failed, falling back to inline rules: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -1918,7 +1934,7 @@ export async function resolveDispatch(
|
|
|
1918
1934
|
matchedRule: rule.name,
|
|
1919
1935
|
};
|
|
1920
1936
|
}
|
|
1921
|
-
return action;
|
|
1937
|
+
return applyLanguageDirectiveToDispatch(action, ctx.prefs);
|
|
1922
1938
|
}
|
|
1923
1939
|
}
|
|
1924
1940
|
|
|
@@ -234,12 +234,56 @@ export function refreshRecoveryDbForArtifact(
|
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
if (!isClosedStatus(task.status)) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
237
|
+
// The artifact was already confirmed on disk by verifyExpectedArtifact
|
|
238
|
+
// upstream (Gate 1 accepts a checked disk checkbox as proof of completion),
|
|
239
|
+
// but the DB task row is still open. A bare refreshWorkflowDatabaseFromDisk
|
|
240
|
+
// never promotes the disk checkbox into task status (the checkbox is
|
|
241
|
+
// rendered *from* the DB, never *into* it), so this divergence can never
|
|
242
|
+
// self-heal. Promote the task to align the DB with disk instead of failing
|
|
243
|
+
// shut — otherwise the lowest-pending derivation re-picks the same task
|
|
244
|
+
// forever and execute-task hard-stops with "state did not advance" (#1204).
|
|
245
|
+
// Mirrors the promotion pattern used by the context-exhaustion and
|
|
246
|
+
// reactive-execute-blocker recovery paths.
|
|
247
|
+
const ts = new Date().toISOString();
|
|
248
|
+
// Only the DB promotion is load-bearing: if it throws, nothing advanced
|
|
249
|
+
// and failing shut is correct. The plan checkbox rewrite and cache clears
|
|
250
|
+
// are best-effort follow-ups — a throw there must NOT abort recovery, or
|
|
251
|
+
// the DB is left complete without ever emitting the stuck-artifact-recovery
|
|
252
|
+
// event (#1221), stranding worktree reconciliation.
|
|
253
|
+
try {
|
|
254
|
+
updateTaskStatus(mid, sid, tid, "complete", ts);
|
|
255
|
+
} catch (e) {
|
|
256
|
+
return {
|
|
257
|
+
ok: false,
|
|
258
|
+
fatal: true,
|
|
259
|
+
reason: "execute-task-artifact-db-promote-failed",
|
|
260
|
+
message: `Stuck recovery found execute-task ${unitId} artifacts, but promoting the DB task status from '${task.status}' failed: ${getErrorMessage(e)}`,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
try {
|
|
264
|
+
const artifactBase = resolveArtifactVerificationBase(unitId, basePath);
|
|
265
|
+
const planPath = resolveExpectedArtifactPath("plan-slice", `${mid}/${sid}`, artifactBase);
|
|
266
|
+
if (planPath && existsSync(planPath)) {
|
|
267
|
+
const planContent = readFileSync(planPath, "utf-8");
|
|
268
|
+
const updatedPlan = planContent.replace(
|
|
269
|
+
new RegExp(`^(\\s*-\\s+)\\[ \\]\\s+\\*\\*${tid}:`, "m"),
|
|
270
|
+
`$1[x] **${tid}:`,
|
|
271
|
+
);
|
|
272
|
+
if (updatedPlan !== planContent) {
|
|
273
|
+
atomicWriteSync(planPath, updatedPlan);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
clearPathCache();
|
|
277
|
+
clearParseCache();
|
|
278
|
+
} catch (e) {
|
|
279
|
+
logWarning("recovery", `stuck-artifact plan checkbox sync failed after DB promotion of ${unitId}: ${getErrorMessage(e)}`);
|
|
280
|
+
}
|
|
281
|
+
// Append event so worktree reconciliation can replay this recovery completion.
|
|
282
|
+
try {
|
|
283
|
+
appendEvent(basePath, { cmd: "complete-task", params: { milestoneId: mid, sliceId: sid, taskId: tid }, ts, actor: "system", trigger_reason: "stuck-artifact-recovery" });
|
|
284
|
+
} catch (e) {
|
|
285
|
+
logWarning("recovery", `appendEvent failed for stuck-artifact task promotion: ${getErrorMessage(e)}`);
|
|
286
|
+
}
|
|
243
287
|
}
|
|
244
288
|
|
|
245
289
|
return { ok: true };
|
|
@@ -63,9 +63,11 @@ import {
|
|
|
63
63
|
detectWorktreeName,
|
|
64
64
|
setActiveMilestoneId,
|
|
65
65
|
} from "./worktree.js";
|
|
66
|
-
import {
|
|
66
|
+
import { isInAutoWorktree } from "./auto-worktree-entry.js";
|
|
67
|
+
import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
|
|
67
68
|
import { checkoutBranchWithStashGuard } from "./worktree-git-recovery.js";
|
|
68
|
-
import {
|
|
69
|
+
import { cleanStaleRuntimeUnits } from "./auto-worktree-runtime-cleanup.js";
|
|
70
|
+
import { readResourceVersion } from "./auto-worktree-resource-version.js";
|
|
69
71
|
import { worktreePath as getWorktreeDir, isInsideWorktreesDir } from "./worktree-manager.js";
|
|
70
72
|
import { emitWorktreeOrphaned } from "./worktree-telemetry.js";
|
|
71
73
|
import { queryJournal } from "./journal.js";
|
|
@@ -1813,7 +1815,7 @@ export async function bootstrapAutoSession(
|
|
|
1813
1815
|
|
|
1814
1816
|
// Snapshot installed skills
|
|
1815
1817
|
if (resolveSkillDiscoveryMode(base) !== "off") {
|
|
1816
|
-
snapshotSkills();
|
|
1818
|
+
snapshotSkills({ cwd: s.basePath });
|
|
1817
1819
|
}
|
|
1818
1820
|
|
|
1819
1821
|
setAutoActiveStatus(ctx, s.stepMode ? "next" : "auto");
|