@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
package/README.md
CHANGED
|
@@ -28,16 +28,16 @@ See [CHANGELOG.md](./CHANGELOG.md) for release-by-release fixes and [Legacy Rele
|
|
|
28
28
|
## Latest Release Highlights
|
|
29
29
|
|
|
30
30
|
<!-- release-highlights:start -->
|
|
31
|
-
Latest release: **v1.
|
|
32
|
-
|
|
33
|
-
- **
|
|
34
|
-
- **
|
|
35
|
-
- **
|
|
36
|
-
- **
|
|
37
|
-
- **
|
|
38
|
-
- **
|
|
39
|
-
- **
|
|
40
|
-
- **
|
|
31
|
+
Latest release: **v1.5.0**
|
|
32
|
+
|
|
33
|
+
- **hermes:** Add /gsd new-milestone command for chat-driven milestone creation (#1162).
|
|
34
|
+
- **gsd:** Make CODEBASE.md workspace-aware in parent mode.
|
|
35
|
+
- **gsd:** Doctor probe + validation for parent-workspace repos.
|
|
36
|
+
- **gsd:** Surface per-repo git health in /gsd status + document limits.
|
|
37
|
+
- **gsd:** Wire repository assignment into slice/task planning.
|
|
38
|
+
- **gsd:** Add parent-workspace discovery UX + document nested-only layout.
|
|
39
|
+
- **provider:** Add Cursor Agent provider.
|
|
40
|
+
- **gsd:** Make workspace.mode parent behavioral (mode contract).
|
|
41
41
|
|
|
42
42
|
<!-- release-highlights:end -->
|
|
43
43
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
dc6f7673892b74e1
|
|
@@ -209,7 +209,7 @@ export default function AskUserQuestions(pi) {
|
|
|
209
209
|
"For single-select: each question must have 2-3 options. Put the recommended option first with '(Recommended)' suffix. Do not include an 'Other' or 'None of the above' option - the client adds one automatically.",
|
|
210
210
|
"For multi-select: set allowMultiple: true. The user can pick any number of options. No 'None of the above' is added.",
|
|
211
211
|
"When options involve code patterns, config choices, or architecture decisions, add a 'preview' field with markdown content (code blocks, lists, headers, etc.). The preview renders in a side-by-side panel when the option is highlighted.",
|
|
212
|
-
"Preview content is rendered in a fixed-height panel (max ~20 lines visible). Keep previews concise — show the most relevant snippet, not exhaustive examples. Longer content
|
|
212
|
+
"Preview content is rendered in a fixed-height panel (max ~20 lines visible). Keep previews concise — show the most relevant snippet, not exhaustive examples. Longer content stays fully accessible: the user scrolls it with PgUp/PgDn, with '▲/▼ N more' indicators marking hidden rows.",
|
|
213
213
|
],
|
|
214
214
|
parameters: AskUserQuestionsParams,
|
|
215
215
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
// Project/App: gsd-pi
|
|
2
2
|
// File Purpose: Auto-loop closeout, milestone report, and merge helpers.
|
|
3
3
|
import { importExtensionModule } from "@gsd/pi-coding-agent";
|
|
4
|
+
import { execFileSync } from "node:child_process";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
6
|
+
import { join, basename } from "node:path";
|
|
7
|
+
import { readFileSync } from "node:fs";
|
|
4
8
|
import { MergeConflictError } from "../git-service.js";
|
|
5
9
|
import { findUnmergedCompletedMilestones } from "../unmerged-milestone-guard.js";
|
|
6
10
|
import { getIsolationMode } from "../preferences.js";
|
|
7
11
|
import { isDbAvailable, getMilestone } from "../gsd-db.js";
|
|
8
12
|
import { refreshWorkflowDatabaseFromDisk } from "../db-workspace.js";
|
|
9
13
|
import { isClosedStatus } from "../status-guards.js";
|
|
14
|
+
import { PLANNING_ARTIFACT_SUFFIXES } from "../paths.js";
|
|
10
15
|
import { logWarning, logError } from "../workflow-logger.js";
|
|
11
16
|
import { debugLog } from "../debug-logger.js";
|
|
12
17
|
import { _resolveReportBasePath } from "./phase-helpers.js";
|
|
@@ -51,7 +56,15 @@ export async function restorePreflightStashOrStop(ic, preflight, milestoneId) {
|
|
|
51
56
|
*/
|
|
52
57
|
export async function _runMilestoneMergeWithStashRestore(ic, milestoneId, options = {}) {
|
|
53
58
|
const { ctx, pi, s, deps } = ic;
|
|
54
|
-
|
|
59
|
+
// Resolve the project root once, before the merge can flip session path
|
|
60
|
+
// pointers (worktree teardown mutates s.basePath / s.scope). The guarded
|
|
61
|
+
// merge's preflight/postflight stash restore, the pre-merge ignored-markdown
|
|
62
|
+
// snapshot, the dirty-projection check, and the rebuild must all target this
|
|
63
|
+
// same tree; otherwise `.gsd` markdown restored on one tree can be silently
|
|
64
|
+
// overwritten by a rebuild on another. canonicalProjectRoot is the
|
|
65
|
+
// authoritative `.gsd`/DB writer path (see AutoSession.canonicalProjectRoot).
|
|
66
|
+
const projectRoot = s.originalBasePath || s.canonicalProjectRoot || s.basePath;
|
|
67
|
+
const ignoredProjectionSnapshot = snapshotIgnoredGsdMarkdownProjections(projectRoot);
|
|
55
68
|
const mergeResult = deps.lifecycle.exitMilestone(milestoneId, {
|
|
56
69
|
merge: true,
|
|
57
70
|
guardedMerge: {
|
|
@@ -61,11 +74,11 @@ export async function _runMilestoneMergeWithStashRestore(ic, milestoneId, option
|
|
|
61
74
|
},
|
|
62
75
|
}, ctx.ui);
|
|
63
76
|
if (mergeResult.ok) {
|
|
64
|
-
await markMilestoneMergedAndRebuild(s);
|
|
77
|
+
await markMilestoneMergedAndRebuild(s, projectRoot, ignoredProjectionSnapshot);
|
|
65
78
|
return null;
|
|
66
79
|
}
|
|
67
80
|
if (mergeResult.reason === "postflight-stash-restore-failed") {
|
|
68
|
-
await markMilestoneMergedAndRebuild(s);
|
|
81
|
+
await markMilestoneMergedAndRebuild(s, projectRoot, ignoredProjectionSnapshot);
|
|
69
82
|
}
|
|
70
83
|
if (mergeResult.reason === "preflight-dirty-overlap" || mergeResult.reason === "preflight-unmerged-conflicts") {
|
|
71
84
|
const reason = mergeResult.reason === "preflight-unmerged-conflicts"
|
|
@@ -122,10 +135,13 @@ export async function _runMilestoneMergeWithStashRestore(ic, milestoneId, option
|
|
|
122
135
|
}
|
|
123
136
|
return null;
|
|
124
137
|
}
|
|
125
|
-
async function markMilestoneMergedAndRebuild(s) {
|
|
138
|
+
async function markMilestoneMergedAndRebuild(s, rebuildBasePath, ignoredProjectionSnapshot) {
|
|
126
139
|
s.milestoneMergedInPhases = true;
|
|
140
|
+
if (hasDirtyGsdMarkdownProjections(rebuildBasePath, ignoredProjectionSnapshot)) {
|
|
141
|
+
logWarning("engine", "skipping markdown projection rebuild after milestone merge because restored .gsd edits are dirty");
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
127
144
|
try {
|
|
128
|
-
const rebuildBasePath = s.originalBasePath || s.canonicalProjectRoot || s.basePath;
|
|
129
145
|
const { rebuildMarkdownProjectionsFromDb } = await import("../commands-maintenance.js");
|
|
130
146
|
await rebuildMarkdownProjectionsFromDb(rebuildBasePath);
|
|
131
147
|
}
|
|
@@ -133,6 +149,82 @@ async function markMilestoneMergedAndRebuild(s) {
|
|
|
133
149
|
logWarning("engine", `markdown projection rebuild after milestone merge failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
134
150
|
}
|
|
135
151
|
}
|
|
152
|
+
function hasDirtyGsdMarkdownProjections(basePath, ignoredProjectionSnapshot) {
|
|
153
|
+
try {
|
|
154
|
+
const output = execFileSync("git", ["status", "--porcelain", "-z", "--untracked-files=all", "--", ".gsd"], { cwd: basePath, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
155
|
+
const entries = output.split("\0").filter(Boolean);
|
|
156
|
+
for (let i = 0; i < entries.length; i++) {
|
|
157
|
+
const entry = entries[i];
|
|
158
|
+
if (entry.length <= 3)
|
|
159
|
+
continue;
|
|
160
|
+
const status = entry.slice(0, 2);
|
|
161
|
+
const path = entry.slice(3);
|
|
162
|
+
if (isGeneratedGsdMarkdownProjection(path))
|
|
163
|
+
return true;
|
|
164
|
+
if ((status === "R " || status === "C ") && i + 1 < entries.length) {
|
|
165
|
+
const dest = entries[++i];
|
|
166
|
+
if (isGeneratedGsdMarkdownProjection(dest))
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
void err;
|
|
173
|
+
// Fall through to ignored-file snapshot comparison below.
|
|
174
|
+
}
|
|
175
|
+
return ignoredGsdMarkdownProjectionSnapshotChanged(basePath, ignoredProjectionSnapshot);
|
|
176
|
+
}
|
|
177
|
+
function isGeneratedGsdMarkdownProjection(path) {
|
|
178
|
+
const normalized = path.replace(/\\/g, "/");
|
|
179
|
+
if (normalized === ".gsd/DECISIONS.md")
|
|
180
|
+
return true;
|
|
181
|
+
if (!normalized.startsWith(".gsd/milestones/") && !normalized.startsWith(".gsd/phases/")) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
return isGeneratedPlanningArtifactFileName(basename(normalized));
|
|
185
|
+
}
|
|
186
|
+
function isGeneratedPlanningArtifactFileName(fileName) {
|
|
187
|
+
if (!fileName.endsWith(".md"))
|
|
188
|
+
return false;
|
|
189
|
+
const stem = fileName.slice(0, -".md".length).toUpperCase();
|
|
190
|
+
for (const suffix of PLANNING_ARTIFACT_SUFFIXES) {
|
|
191
|
+
if (!stem.endsWith(`-${suffix}`))
|
|
192
|
+
continue;
|
|
193
|
+
const idPrefix = stem.slice(0, -suffix.length - 1);
|
|
194
|
+
return /^(?:[MST]\d+|\d{2,})(?:-[A-Z0-9]+)*$/.test(idPrefix);
|
|
195
|
+
}
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
function snapshotIgnoredGsdMarkdownProjections(basePath) {
|
|
199
|
+
try {
|
|
200
|
+
const output = execFileSync("git", ["ls-files", "--others", "--ignored", "--exclude-standard", "-z", "--", ".gsd"], { cwd: basePath, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
201
|
+
const snapshot = new Map();
|
|
202
|
+
for (const path of output.split("\0")) {
|
|
203
|
+
if (!isGeneratedGsdMarkdownProjection(path))
|
|
204
|
+
continue;
|
|
205
|
+
snapshot.set(path, hashFile(join(basePath, path)));
|
|
206
|
+
}
|
|
207
|
+
return snapshot;
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function hashFile(path) {
|
|
214
|
+
return createHash("sha256").update(readFileSync(path)).digest("hex");
|
|
215
|
+
}
|
|
216
|
+
function ignoredGsdMarkdownProjectionSnapshotChanged(basePath, before) {
|
|
217
|
+
if (!before)
|
|
218
|
+
return true;
|
|
219
|
+
const after = snapshotIgnoredGsdMarkdownProjections(basePath);
|
|
220
|
+
if (!after || after.size !== before.size)
|
|
221
|
+
return true;
|
|
222
|
+
for (const [path, hash] of before) {
|
|
223
|
+
if (after.get(path) !== hash)
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
136
228
|
export async function _runMilestoneMergeOnceWithStashRestore(ic, milestoneId, options = {}) {
|
|
137
229
|
if (ic.s.milestoneMergedInPhases) {
|
|
138
230
|
debugLog("autoLoop", {
|
|
@@ -21,7 +21,8 @@ import { createWorktreeSafetyModule } from "../worktree-safety.js";
|
|
|
21
21
|
import { repairAutoWorktreeSafetyFailure } from "../auto-worktree-repair.js";
|
|
22
22
|
import { resolveManifest } from "../unit-context-manifest.js";
|
|
23
23
|
import { preDispatchHealthGate, recordHealthSnapshot, } from "../doctor-proactive.js";
|
|
24
|
-
import {
|
|
24
|
+
import { autoWorktreeBranch } from "../auto-worktree-branch-lifecycle.js";
|
|
25
|
+
import { checkResourcesStale } from "../auto-worktree-resource-version.js";
|
|
25
26
|
import { getSessionLockStatus } from "../session-lock.js";
|
|
26
27
|
import { resolveUokFlags } from "../uok/flags.js";
|
|
27
28
|
import { emitJournalEvent as _emitJournalEvent } from "../journal.js";
|
|
@@ -31,7 +32,7 @@ import { getPriorSliceCompletionBlocker } from "../dispatch-guard.js";
|
|
|
31
32
|
import { GitServiceImpl } from "../git-service.js";
|
|
32
33
|
import { WorktreeStateProjection } from "../worktree-state-projection.js";
|
|
33
34
|
import { WorktreeLifecycle } from "../worktree-lifecycle.js";
|
|
34
|
-
import {
|
|
35
|
+
import { createDefaultMilestoneMergeTransaction } from "../milestone-merge-transaction.js";
|
|
35
36
|
import { createWorkspace, scopeMilestone } from "../workspace.js";
|
|
36
37
|
import { supportsStructuredQuestions } from "../workflow-mcp.js";
|
|
37
38
|
import { getRegisteredToolSnapshot, getToolBaselineSnapshot } from "../auto-model-selection.js";
|
|
@@ -560,7 +561,7 @@ export class AutoOrchestrator {
|
|
|
560
561
|
return new GitServiceImpl(basePath, gitConfig);
|
|
561
562
|
},
|
|
562
563
|
worktreeProjection: new WorktreeStateProjection(),
|
|
563
|
-
mergeMilestone:
|
|
564
|
+
mergeMilestone: createDefaultMilestoneMergeTransaction(),
|
|
564
565
|
});
|
|
565
566
|
}
|
|
566
567
|
rebuildScope(rawPath, milestoneId) {
|
|
@@ -345,7 +345,8 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
345
345
|
if (stop)
|
|
346
346
|
return stop;
|
|
347
347
|
}
|
|
348
|
-
// PR creation (auto_pr) is handled
|
|
348
|
+
// PR creation (auto_pr) is handled by the publication handoff in
|
|
349
|
+
// the milestone merge transaction (#2302).
|
|
349
350
|
deps.invalidateAllCaches();
|
|
350
351
|
state = await deps.deriveState(s.canonicalProjectRoot);
|
|
351
352
|
mid = state.activeMilestone?.id;
|
|
@@ -430,7 +431,8 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
430
431
|
const stop = await _runMilestoneMergeOnceWithStashRestore(ic, s.currentMilestoneId);
|
|
431
432
|
if (stop)
|
|
432
433
|
return stop;
|
|
433
|
-
// PR creation (auto_pr) is handled
|
|
434
|
+
// PR creation (auto_pr) is handled by the publication handoff in
|
|
435
|
+
// the milestone merge transaction (#2302).
|
|
434
436
|
}
|
|
435
437
|
const unmappedActive = countUnmappedActiveRequirements();
|
|
436
438
|
const completionStopReason = formatCompletePhaseNextAction(unmappedActive);
|
|
@@ -506,7 +508,8 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
506
508
|
const stop = await _runMilestoneMergeOnceWithStashRestore(ic, s.currentMilestoneId);
|
|
507
509
|
if (stop)
|
|
508
510
|
return stop;
|
|
509
|
-
// PR creation (auto_pr) is handled
|
|
511
|
+
// PR creation (auto_pr) is handled by the publication handoff in
|
|
512
|
+
// the milestone merge transaction (#2302).
|
|
510
513
|
}
|
|
511
514
|
deps.sendDesktopNotification("GSD", `Milestone ${mid} complete!`, "success", "milestone", basename(s.originalBasePath || s.basePath));
|
|
512
515
|
deps.logCmuxEvent(prefs, `Milestone ${mid} complete.`, "success");
|
|
@@ -17,7 +17,7 @@ import { isDbAvailable, getTask } from "../gsd-db.js";
|
|
|
17
17
|
import { parseUnitId } from "../unit-id.js";
|
|
18
18
|
import { createCheckpoint, cleanupCheckpoint, rollbackToCheckpoint } from "../safety/git-checkpoint.js";
|
|
19
19
|
import { resolveSafetyHarnessConfig } from "../safety/safety-harness.js";
|
|
20
|
-
import {
|
|
20
|
+
import { getUnitWorkflowDispatchReadinessErrorForModel } from "../tool-contract.js";
|
|
21
21
|
import { prepareWorkflowMcpForProject } from "../workflow-mcp-auto-prep.js";
|
|
22
22
|
import { applyThinkingLevelForModel, floorThinkingLevelForUnit, } from "../auto-model-selection.js";
|
|
23
23
|
import { isSuspiciousGhostCompletion } from "../auto-unit-closeout.js";
|
|
@@ -246,17 +246,13 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
246
246
|
s.currentDispatchedModelId = s.currentUnitModel
|
|
247
247
|
? `${s.currentUnitModel.provider ?? ""}/${s.currentUnitModel.id ?? ""}`
|
|
248
248
|
: null;
|
|
249
|
-
const compatibilityError =
|
|
250
|
-
|
|
249
|
+
const compatibilityError = getUnitWorkflowDispatchReadinessErrorForModel({
|
|
250
|
+
model: s.currentUnitModel,
|
|
251
|
+
fallbackModel: ctx.model,
|
|
252
|
+
getProviderAuthMode: (provider) => ctx.modelRegistry.getProviderAuthMode(provider),
|
|
251
253
|
projectRoot: s.basePath,
|
|
252
254
|
surface: "auto-mode",
|
|
253
255
|
unitType,
|
|
254
|
-
authMode: s.currentUnitModel?.provider
|
|
255
|
-
? ctx.modelRegistry.getProviderAuthMode(s.currentUnitModel.provider)
|
|
256
|
-
: ctx.model?.provider
|
|
257
|
-
? ctx.modelRegistry.getProviderAuthMode(ctx.model.provider)
|
|
258
|
-
: undefined,
|
|
259
|
-
baseUrl: s.currentUnitModel?.baseUrl ?? ctx.model?.baseUrl,
|
|
260
256
|
activeTools: typeof pi.getActiveTools === "function" ? pi.getActiveTools() : [],
|
|
261
257
|
});
|
|
262
258
|
const workflowMcpPrepModel = s.currentUnitModel;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { gsdRoot, resolveDir, resolveFile, resolveMilestonePath, resolveMilestoneFile, resolveSliceFile, relMilestoneFile, relSliceFile, buildTaskFileName, resolveSlicePath, resolveTasksDir, dirIsMetaOnlyLegacyMilestone, } from "./paths.js";
|
|
9
9
|
import { milestoneIdToPhaseNum } from "./layout-policy.js";
|
|
10
10
|
import { parseUnitId } from "./unit-id.js";
|
|
11
|
-
import { dirname, join, relative } from "node:path";
|
|
11
|
+
import { basename, dirname, join, relative } from "node:path";
|
|
12
12
|
import { existsSync } from "node:fs";
|
|
13
13
|
function resolveMilestoneArtifactPath(base, mid, suffix) {
|
|
14
14
|
const existing = resolveProjectedMilestoneFile(base, mid, suffix) ?? resolveProjectMilestoneFile(base, mid, suffix);
|
|
@@ -193,8 +193,17 @@ export function resolveExpectedArtifactPath(unitType, unitId, base) {
|
|
|
193
193
|
?? resolveSlicePath(base, mid, sid);
|
|
194
194
|
if (!slicePath || !tid)
|
|
195
195
|
return null;
|
|
196
|
-
|
|
197
|
-
|
|
196
|
+
// Legacy layout: slice dirs live under slices/<SID>/ and task summaries
|
|
197
|
+
// live in a tasks/ subdir. Flat-phase layout: slicePath IS the phase dir
|
|
198
|
+
// and task summaries live beside the plan files at the phase root. A
|
|
199
|
+
// tasks/ subdir may still exist in flat-phase for auxiliary task-scoped
|
|
200
|
+
// artifacts (e.g. T01-VERIFY.json gate outputs) — its mere existence must
|
|
201
|
+
// NOT redirect summary resolution into tasks/ (#1208).
|
|
202
|
+
const isLegacySlice = basename(dirname(slicePath)) === "slices";
|
|
203
|
+
const summaryDir = isLegacySlice
|
|
204
|
+
? (resolveTasksDir(base, mid, sid) ?? slicePath)
|
|
205
|
+
: slicePath;
|
|
206
|
+
return join(summaryDir, buildTaskFileName(tid, "SUMMARY"));
|
|
198
207
|
}
|
|
199
208
|
case "complete-slice": {
|
|
200
209
|
return resolveSliceArtifactPath(base, mid, sid, "SUMMARY");
|
|
@@ -7,10 +7,10 @@ import { loadFile } from "./files.js";
|
|
|
7
7
|
import { isDbAvailable, getClosedSliceIds } from "./gsd-db.js";
|
|
8
8
|
import { resolveSliceFile, relSliceFile, } from "./paths.js";
|
|
9
9
|
import { buildResearchSlicePrompt, buildResearchMilestonePrompt, buildPlanSlicePrompt, buildPlanMilestonePrompt, buildExecuteTaskPrompt, buildCompleteSlicePrompt, buildCompleteMilestonePrompt, buildValidateMilestonePrompt, buildReassessRoadmapPrompt, buildRunUatPrompt, buildReplanSlicePrompt, } from "./auto-prompts.js";
|
|
10
|
-
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
10
|
+
import { loadEffectiveGSDPreferences, renderLanguageDirectiveForPrompt } from "./preferences.js";
|
|
11
11
|
import { pauseAuto } from "./auto.js";
|
|
12
12
|
import { resolveCanonicalMilestoneRoot } from "./worktree-manager.js";
|
|
13
|
-
import {
|
|
13
|
+
import { getUnitWorkflowDispatchReadinessErrorForModel } from "./tool-contract.js";
|
|
14
14
|
export function parseDirectDispatchPhase(raw) {
|
|
15
15
|
const tokens = raw.trim().split(/\s+/).filter(Boolean);
|
|
16
16
|
if (tokens.length === 0)
|
|
@@ -213,13 +213,12 @@ export async function dispatchDirectPhase(ctx, pi, phase, base, opts = {}) {
|
|
|
213
213
|
ctx.ui.notify(`Unknown phase "${phase}". Valid phases: research, plan, execute, complete, validate, reassess, uat, replan.`, "warning");
|
|
214
214
|
return;
|
|
215
215
|
}
|
|
216
|
-
const compatibilityError =
|
|
217
|
-
|
|
216
|
+
const compatibilityError = getUnitWorkflowDispatchReadinessErrorForModel({
|
|
217
|
+
model: ctx.model,
|
|
218
|
+
getProviderAuthMode: (provider) => ctx.modelRegistry.getProviderAuthMode(provider),
|
|
218
219
|
projectRoot,
|
|
219
220
|
surface: "direct phase dispatch",
|
|
220
221
|
unitType,
|
|
221
|
-
authMode: ctx.model?.provider ? ctx.modelRegistry.getProviderAuthMode(ctx.model.provider) : undefined,
|
|
222
|
-
baseUrl: ctx.model?.baseUrl,
|
|
223
222
|
activeTools: typeof pi.getActiveTools === "function" ? pi.getActiveTools() : [],
|
|
224
223
|
});
|
|
225
224
|
if (compatibilityError) {
|
|
@@ -232,5 +231,10 @@ export async function dispatchDirectPhase(ctx, pi, phase, base, opts = {}) {
|
|
|
232
231
|
ctx.ui.notify("Session creation cancelled.", "warning");
|
|
233
232
|
return;
|
|
234
233
|
}
|
|
235
|
-
|
|
234
|
+
// Inject the configured response language into the dispatched prompt content
|
|
235
|
+
// — the new session's system prompt does not carry the preferences block, so
|
|
236
|
+
// the language setting would otherwise never reach the unit (#1210).
|
|
237
|
+
const languageDirective = renderLanguageDirectiveForPrompt(loadEffectiveGSDPreferences(dispatchBase)?.preferences);
|
|
238
|
+
const dispatchContent = languageDirective ? `${languageDirective}\n\n${prompt}` : prompt;
|
|
239
|
+
pi.sendMessage({ customType: "gsd-dispatch", content: dispatchContent, display: false }, { triggerTurn: true });
|
|
236
240
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Project/App: gsd-pi
|
|
2
2
|
// File Purpose: Declarative auto-mode dispatch rules and dispatch resolver.
|
|
3
|
+
import { renderLanguageDirectiveForPrompt } from "./preferences.js";
|
|
3
4
|
import { loadFile, extractUatType, loadActiveOverrides } from "./files.js";
|
|
4
5
|
import { getUatBrowserToolSupportError } from "./uat-policy.js";
|
|
5
6
|
import { isDbAvailable, getMilestoneSlices, getMilestoneSliceSummaries, getClosedSliceIds, getPendingGatesForTurn, markPendingGatesOmittedForTurn, getMilestone, insertArtifact, insertAssessment, setSliceSketchFlag, transaction, getAssessment, getSliceRunUatAssessment, } from "./gsd-db.js";
|
|
@@ -1500,6 +1501,19 @@ export const DISPATCH_RULES = [
|
|
|
1500
1501
|
},
|
|
1501
1502
|
];
|
|
1502
1503
|
import { getRegistry } from "./rule-registry.js";
|
|
1504
|
+
/**
|
|
1505
|
+
* Prepend the configured response-language directive to a dispatched unit
|
|
1506
|
+
* prompt so auto-execution units respond in the language set in PREFERENCES.md
|
|
1507
|
+
* (#1210). No-op for non-dispatch actions or when no language is configured.
|
|
1508
|
+
*/
|
|
1509
|
+
function applyLanguageDirectiveToDispatch(action, prefs) {
|
|
1510
|
+
if (action.action !== "dispatch" || !action.prompt)
|
|
1511
|
+
return action;
|
|
1512
|
+
const directive = renderLanguageDirectiveForPrompt(prefs);
|
|
1513
|
+
if (!directive)
|
|
1514
|
+
return action;
|
|
1515
|
+
return { ...action, prompt: `${directive}\n\n${action.prompt}` };
|
|
1516
|
+
}
|
|
1503
1517
|
// ─── Resolver ─────────────────────────────────────────────────────────────
|
|
1504
1518
|
/**
|
|
1505
1519
|
* Evaluate dispatch rules in order. Returns the first matching action,
|
|
@@ -1551,7 +1565,7 @@ export async function resolveDispatch(ctx) {
|
|
|
1551
1565
|
level: "error",
|
|
1552
1566
|
};
|
|
1553
1567
|
}
|
|
1554
|
-
return action;
|
|
1568
|
+
return applyLanguageDirectiveToDispatch(action, ctx.prefs);
|
|
1555
1569
|
}
|
|
1556
1570
|
catch (err) {
|
|
1557
1571
|
// Registry not initialized — fall back to inline loop
|
|
@@ -1572,7 +1586,7 @@ export async function resolveDispatch(ctx) {
|
|
|
1572
1586
|
matchedRule: rule.name,
|
|
1573
1587
|
};
|
|
1574
1588
|
}
|
|
1575
|
-
return action;
|
|
1589
|
+
return applyLanguageDirectiveToDispatch(action, ctx.prefs);
|
|
1576
1590
|
}
|
|
1577
1591
|
}
|
|
1578
1592
|
// No rule matched — unhandled phase.
|
|
@@ -149,12 +149,56 @@ export function refreshRecoveryDbForArtifact(unitType, unitId, basePath) {
|
|
|
149
149
|
};
|
|
150
150
|
}
|
|
151
151
|
if (!isClosedStatus(task.status)) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
152
|
+
// The artifact was already confirmed on disk by verifyExpectedArtifact
|
|
153
|
+
// upstream (Gate 1 accepts a checked disk checkbox as proof of completion),
|
|
154
|
+
// but the DB task row is still open. A bare refreshWorkflowDatabaseFromDisk
|
|
155
|
+
// never promotes the disk checkbox into task status (the checkbox is
|
|
156
|
+
// rendered *from* the DB, never *into* it), so this divergence can never
|
|
157
|
+
// self-heal. Promote the task to align the DB with disk instead of failing
|
|
158
|
+
// shut — otherwise the lowest-pending derivation re-picks the same task
|
|
159
|
+
// forever and execute-task hard-stops with "state did not advance" (#1204).
|
|
160
|
+
// Mirrors the promotion pattern used by the context-exhaustion and
|
|
161
|
+
// reactive-execute-blocker recovery paths.
|
|
162
|
+
const ts = new Date().toISOString();
|
|
163
|
+
// Only the DB promotion is load-bearing: if it throws, nothing advanced
|
|
164
|
+
// and failing shut is correct. The plan checkbox rewrite and cache clears
|
|
165
|
+
// are best-effort follow-ups — a throw there must NOT abort recovery, or
|
|
166
|
+
// the DB is left complete without ever emitting the stuck-artifact-recovery
|
|
167
|
+
// event (#1221), stranding worktree reconciliation.
|
|
168
|
+
try {
|
|
169
|
+
updateTaskStatus(mid, sid, tid, "complete", ts);
|
|
170
|
+
}
|
|
171
|
+
catch (e) {
|
|
172
|
+
return {
|
|
173
|
+
ok: false,
|
|
174
|
+
fatal: true,
|
|
175
|
+
reason: "execute-task-artifact-db-promote-failed",
|
|
176
|
+
message: `Stuck recovery found execute-task ${unitId} artifacts, but promoting the DB task status from '${task.status}' failed: ${getErrorMessage(e)}`,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
const artifactBase = resolveArtifactVerificationBase(unitId, basePath);
|
|
181
|
+
const planPath = resolveExpectedArtifactPath("plan-slice", `${mid}/${sid}`, artifactBase);
|
|
182
|
+
if (planPath && existsSync(planPath)) {
|
|
183
|
+
const planContent = readFileSync(planPath, "utf-8");
|
|
184
|
+
const updatedPlan = planContent.replace(new RegExp(`^(\\s*-\\s+)\\[ \\]\\s+\\*\\*${tid}:`, "m"), `$1[x] **${tid}:`);
|
|
185
|
+
if (updatedPlan !== planContent) {
|
|
186
|
+
atomicWriteSync(planPath, updatedPlan);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
clearPathCache();
|
|
190
|
+
clearParseCache();
|
|
191
|
+
}
|
|
192
|
+
catch (e) {
|
|
193
|
+
logWarning("recovery", `stuck-artifact plan checkbox sync failed after DB promotion of ${unitId}: ${getErrorMessage(e)}`);
|
|
194
|
+
}
|
|
195
|
+
// Append event so worktree reconciliation can replay this recovery completion.
|
|
196
|
+
try {
|
|
197
|
+
appendEvent(basePath, { cmd: "complete-task", params: { milestoneId: mid, sliceId: sid, taskId: tid }, ts, actor: "system", trigger_reason: "stuck-artifact-recovery" });
|
|
198
|
+
}
|
|
199
|
+
catch (e) {
|
|
200
|
+
logWarning("recovery", `appendEvent failed for stuck-artifact task promotion: ${getErrorMessage(e)}`);
|
|
201
|
+
}
|
|
158
202
|
}
|
|
159
203
|
return { ok: true };
|
|
160
204
|
}
|
|
@@ -27,9 +27,10 @@ import { ensureGitignore, untrackRuntimeFiles } from "./gitignore.js";
|
|
|
27
27
|
import { nativeIsRepo, nativeInit, nativeAddAll, nativeCommit, nativeGetCurrentBranch, nativeDetectMainBranch, nativeBranchList, nativeBranchExists, nativeBranchListMerged, nativeBranchDelete, nativeWorktreeRemove, nativeCommitCountBetween, nativeHasChanges, } from "./native-git-bridge.js";
|
|
28
28
|
import { GitServiceImpl } from "./git-service.js";
|
|
29
29
|
import { captureIntegrationBranch, detectWorktreeName, setActiveMilestoneId, } from "./worktree.js";
|
|
30
|
-
import { getAutoWorktreePath } from "./auto-worktree.js";
|
|
30
|
+
import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
|
|
31
31
|
import { checkoutBranchWithStashGuard } from "./worktree-git-recovery.js";
|
|
32
|
-
import {
|
|
32
|
+
import { cleanStaleRuntimeUnits } from "./auto-worktree-runtime-cleanup.js";
|
|
33
|
+
import { readResourceVersion } from "./auto-worktree-resource-version.js";
|
|
33
34
|
import { worktreePath as getWorktreeDir, isInsideWorktreesDir } from "./worktree-manager.js";
|
|
34
35
|
import { emitWorktreeOrphaned } from "./worktree-telemetry.js";
|
|
35
36
|
import { queryJournal } from "./journal.js";
|
|
@@ -1409,7 +1410,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
1409
1410
|
}
|
|
1410
1411
|
// Snapshot installed skills
|
|
1411
1412
|
if (resolveSkillDiscoveryMode(base) !== "off") {
|
|
1412
|
-
snapshotSkills();
|
|
1413
|
+
snapshotSkills({ cwd: s.basePath });
|
|
1413
1414
|
}
|
|
1414
1415
|
setAutoActiveStatus(ctx, s.stepMode ? "next" : "auto");
|
|
1415
1416
|
ctx.ui.setWidget("gsd-health", undefined);
|