@opengsd/gsd-pi 1.2.0-dev.955e4da0 → 1.2.0-dev.9ad8ae33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-style.d.ts +17 -0
- package/dist/cli-style.js +28 -0
- package/dist/cli.js +1 -1
- package/dist/headless-events.d.ts +4 -2
- package/dist/headless-events.js +14 -34
- package/dist/mcp-server.js +2 -1
- package/dist/models-resolver.d.ts +3 -13
- package/dist/models-resolver.js +3 -22
- package/dist/resource-loader.d.ts +10 -5
- package/dist/resource-loader.js +123 -20
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +5 -4
- package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
- package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
- package/dist/resources/extensions/async-jobs/index.js +65 -0
- package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
- package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
- package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
- package/dist/resources/extensions/bg-shell/overlay.js +9 -6
- package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
- package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
- package/dist/resources/extensions/bg-shell/utilities.js +3 -0
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
- package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
- package/dist/resources/extensions/browser-tools/index.js +69 -12
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +30 -4
- package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
- package/dist/resources/extensions/gsd/auto/dispatch-history.js +105 -0
- package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
- package/dist/resources/extensions/gsd/auto/loop.js +4 -1
- package/dist/resources/extensions/gsd/auto/orchestrator.js +89 -54
- package/dist/resources/extensions/gsd/auto/phases.js +49 -6
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
- package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
- package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
- package/dist/resources/extensions/gsd/auto-post-unit.js +35 -8
- package/dist/resources/extensions/gsd/auto-prompts.js +81 -19
- package/dist/resources/extensions/gsd/auto-start.js +41 -18
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +12 -20
- package/dist/resources/extensions/gsd/auto-verification.js +23 -30
- package/dist/resources/extensions/gsd/auto-worktree.js +44 -91
- package/dist/resources/extensions/gsd/auto.js +41 -14
- package/dist/resources/extensions/gsd/blocked-models.js +28 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +29 -8
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +23 -6
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +212 -48
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +303 -77
- package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
- package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
- package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
- package/dist/resources/extensions/gsd/captures.js +4 -6
- package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
- package/dist/resources/extensions/gsd/commands/context.js +16 -2
- package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
- package/dist/resources/extensions/gsd/consent-question.js +353 -0
- package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
- package/dist/resources/extensions/gsd/constants.js +0 -2
- package/dist/resources/extensions/gsd/crash-recovery.js +12 -15
- package/dist/resources/extensions/gsd/db/queries.js +26 -0
- package/dist/resources/extensions/gsd/db-writer.js +8 -17
- package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
- package/dist/resources/extensions/gsd/doctor-environment.js +2 -6
- package/dist/resources/extensions/gsd/doctor-format.js +9 -6
- package/dist/resources/extensions/gsd/doctor-git-checks.js +2 -18
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +13 -15
- package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
- package/dist/resources/extensions/gsd/error-classifier.js +9 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
- package/dist/resources/extensions/gsd/files.js +33 -19
- package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
- package/dist/resources/extensions/gsd/gsd-db.js +2 -1
- package/dist/resources/extensions/gsd/guidance.js +158 -0
- package/dist/resources/extensions/gsd/guided-flow.js +23 -5
- package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
- package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
- package/dist/resources/extensions/gsd/mcp-tool-name.js +5 -13
- package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
- package/dist/resources/extensions/gsd/migrate/safety.js +4 -1
- package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
- package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
- package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
- package/dist/resources/extensions/gsd/notification-store.js +11 -4
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +6 -4
- package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
- package/dist/resources/extensions/gsd/paths.js +27 -0
- package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
- package/dist/resources/extensions/gsd/preferences-models.js +14 -48
- package/dist/resources/extensions/gsd/projection-flush.js +7 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +3 -3
- package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +7 -5
- package/dist/resources/extensions/gsd/prompts/system.md +5 -2
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
- package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
- package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
- package/dist/resources/extensions/gsd/publication.js +87 -0
- package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
- package/dist/resources/extensions/gsd/recovery-classification.js +37 -94
- package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
- package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
- package/dist/resources/extensions/gsd/session-lock.js +1 -1
- package/dist/resources/extensions/gsd/state.js +6 -20
- package/dist/resources/extensions/gsd/stop-notice.js +57 -0
- package/dist/resources/extensions/gsd/tool-contract.js +14 -3
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
- package/dist/resources/extensions/gsd/tool-surface-readiness.js +56 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
- package/dist/resources/extensions/gsd/tools/complete-slice.js +22 -12
- package/dist/resources/extensions/gsd/tools/complete-task.js +3 -2
- package/dist/resources/extensions/gsd/tools/exec-tool.js +9 -7
- package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -8
- package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
- package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
- package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
- package/dist/resources/extensions/gsd/uat-policy.js +42 -16
- package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
- package/dist/resources/extensions/gsd/unit-context-composer.js +74 -1
- package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
- package/dist/resources/extensions/gsd/unit-registry.js +337 -0
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
- package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
- package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
- package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
- package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
- package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
- package/dist/resources/extensions/gsd/workflow-events.js +6 -18
- package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
- package/dist/resources/extensions/gsd/workflow-tool-surface.js +1 -1
- package/dist/resources/extensions/gsd/worktree-git-recovery.js +15 -9
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +3 -2
- package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
- package/dist/resources/extensions/gsd/worktree-root.js +11 -0
- package/dist/resources/extensions/gsd/worktree-session-state.js +4 -5
- package/dist/resources/extensions/gsd/worktree.js +8 -1
- package/dist/resources/extensions/search-the-web/native-search.js +5 -3
- package/dist/resources/extensions/shared/browser-contract.js +59 -0
- package/dist/resources/extensions/shared/gsd-browser-cli.js +116 -6
- package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
- package/dist/resources/shared/package-manager-detection.js +1 -1
- package/dist/resources/shared/package.json +3 -0
- package/dist/resources/skills/create-skill/SKILL.md +3 -0
- package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
- package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
- package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
- package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
- package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
- package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
- package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
- package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
- package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/update-check.d.ts +2 -0
- package/dist/update-check.js +24 -1
- package/dist/update-cmd.js +20 -3
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
- package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
- package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/dist/web/standalone/package.json +1 -1
- package/dist/worktree-cli.js +3 -6
- package/dist/worktree-status-banner.js +7 -15
- package/package.json +2 -2
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/rpc.d.ts +1 -0
- package/packages/contracts/dist/rpc.d.ts.map +1 -1
- package/packages/contracts/dist/rpc.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +4 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/cli.js +9 -1
- package/packages/mcp-server/dist/cli.js.map +1 -1
- package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
- package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
- package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
- package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +4 -0
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +26 -18
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +116 -39
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +5 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
- package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
- package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
- package/packages/pi-agent-core/dist/index.d.ts +1 -0
- package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/index.js +3 -0
- package/packages/pi-agent-core/dist/index.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/README.md +1 -0
- package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
- package/packages/pi-ai/dist/image-models.generated.js +6 -6
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/index.d.ts +2 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +2 -0
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +35 -125
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +46 -120
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +12 -7
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
- package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-shared.js +12 -3
- package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
- package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
- package/packages/pi-ai/package.json +3 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
- package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
- package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
- package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +9 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +5 -4
- package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
- package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
- package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
- package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
- package/src/resources/extensions/async-jobs/index.ts +79 -0
- package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
- package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
- package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
- package/src/resources/extensions/bg-shell/overlay.ts +9 -5
- package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
- package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
- package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
- package/src/resources/extensions/bg-shell/utilities.ts +3 -0
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
- package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
- package/src/resources/extensions/browser-tools/index.ts +71 -13
- package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
- package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
- package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +34 -4
- package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
- package/src/resources/extensions/gsd/auto/dispatch-history.ts +152 -0
- package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
- package/src/resources/extensions/gsd/auto/loop.ts +4 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +98 -56
- package/src/resources/extensions/gsd/auto/phases.ts +65 -26
- package/src/resources/extensions/gsd/auto/session.ts +3 -0
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
- package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
- package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
- package/src/resources/extensions/gsd/auto-post-unit.ts +40 -8
- package/src/resources/extensions/gsd/auto-prompts.ts +118 -35
- package/src/resources/extensions/gsd/auto-start.ts +42 -21
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +14 -21
- package/src/resources/extensions/gsd/auto-verification.ts +26 -28
- package/src/resources/extensions/gsd/auto-worktree.ts +44 -94
- package/src/resources/extensions/gsd/auto.ts +52 -16
- package/src/resources/extensions/gsd/blocked-models.ts +49 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +37 -10
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +23 -6
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +251 -47
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +352 -84
- package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
- package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
- package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
- package/src/resources/extensions/gsd/captures.ts +4 -6
- package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
- package/src/resources/extensions/gsd/commands/context.ts +16 -2
- package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
- package/src/resources/extensions/gsd/consent-question.ts +431 -0
- package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
- package/src/resources/extensions/gsd/constants.ts +0 -3
- package/src/resources/extensions/gsd/crash-recovery.ts +13 -11
- package/src/resources/extensions/gsd/db/queries.ts +37 -0
- package/src/resources/extensions/gsd/db-writer.ts +11 -19
- package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
- package/src/resources/extensions/gsd/doctor-environment.ts +2 -7
- package/src/resources/extensions/gsd/doctor-format.ts +12 -7
- package/src/resources/extensions/gsd/doctor-git-checks.ts +2 -19
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +13 -15
- package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
- package/src/resources/extensions/gsd/error-classifier.ts +11 -0
- package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
- package/src/resources/extensions/gsd/files.ts +33 -12
- package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
- package/src/resources/extensions/gsd/gsd-db.ts +4 -3
- package/src/resources/extensions/gsd/guidance.ts +217 -0
- package/src/resources/extensions/gsd/guided-flow.ts +37 -28
- package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
- package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
- package/src/resources/extensions/gsd/mcp-tool-name.ts +6 -11
- package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
- package/src/resources/extensions/gsd/migrate/safety.ts +4 -1
- package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
- package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
- package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
- package/src/resources/extensions/gsd/notification-store.ts +26 -3
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +6 -4
- package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
- package/src/resources/extensions/gsd/paths.ts +33 -0
- package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
- package/src/resources/extensions/gsd/preferences-models.ts +12 -47
- package/src/resources/extensions/gsd/projection-flush.ts +20 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +3 -3
- package/src/resources/extensions/gsd/prompts/execute-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +7 -5
- package/src/resources/extensions/gsd/prompts/system.md +5 -2
- package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
- package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
- package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
- package/src/resources/extensions/gsd/publication.ts +122 -0
- package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
- package/src/resources/extensions/gsd/recovery-classification.ts +42 -96
- package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
- package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
- package/src/resources/extensions/gsd/session-lock.ts +1 -1
- package/src/resources/extensions/gsd/state.ts +9 -21
- package/src/resources/extensions/gsd/stop-notice.ts +75 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +198 -26
- package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +236 -0
- package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
- package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
- package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +66 -1
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +8 -7
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
- package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +10 -10
- package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
- package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +273 -0
- package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
- package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
- package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/guidance.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +2 -6
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +53 -11
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +73 -58
- package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +199 -0
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +138 -0
- package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
- package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/publication.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -1
- package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +155 -0
- package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
- package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +67 -2
- package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
- package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
- package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +275 -40
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -1
- package/src/resources/extensions/gsd/tool-contract.ts +38 -3
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
- package/src/resources/extensions/gsd/tool-surface-readiness.ts +76 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
- package/src/resources/extensions/gsd/tools/complete-slice.ts +22 -12
- package/src/resources/extensions/gsd/tools/complete-task.ts +3 -2
- package/src/resources/extensions/gsd/tools/exec-tool.ts +8 -7
- package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -8
- package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
- package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
- package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
- package/src/resources/extensions/gsd/uat-policy.ts +62 -16
- package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
- package/src/resources/extensions/gsd/unit-context-composer.ts +111 -1
- package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
- package/src/resources/extensions/gsd/unit-registry.ts +412 -0
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
- package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
- package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
- package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
- package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
- package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
- package/src/resources/extensions/gsd/workflow-events.ts +12 -20
- package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
- package/src/resources/extensions/gsd/workflow-tool-surface.ts +4 -1
- package/src/resources/extensions/gsd/worktree-git-recovery.ts +15 -9
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +3 -8
- package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
- package/src/resources/extensions/gsd/worktree-root.ts +12 -0
- package/src/resources/extensions/gsd/worktree-session-state.ts +3 -5
- package/src/resources/extensions/gsd/worktree.ts +7 -1
- package/src/resources/extensions/search-the-web/native-search.ts +5 -3
- package/src/resources/extensions/shared/browser-contract.ts +66 -0
- package/src/resources/extensions/shared/gsd-browser-cli.ts +141 -6
- package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
- package/src/resources/shared/package-manager-detection.ts +1 -1
- package/src/resources/shared/package.json +3 -0
- package/src/resources/skills/create-skill/SKILL.md +3 -0
- package/src/resources/skills/create-skill/references/executable-code.md +1 -1
- package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
- package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
- package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
- package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
- package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
- package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
- package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
- package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
- package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
- package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
- package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
- package/src/resources/skills/gsd-browser/SKILL.md +0 -41
- /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → FBNo5cT_chy7YNoAQsU3o}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → FBNo5cT_chy7YNoAQsU3o}/_ssgManifest.js +0 -0
|
@@ -4,6 +4,7 @@ import { mkdtempSync, readFileSync, rmSync, existsSync } from "node:fs";
|
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
import { emitJournalEvent } from "../journal.ts";
|
|
7
|
+
import { appendEvent } from "../workflow-events.ts";
|
|
7
8
|
import { saveActivityLog } from "../activity-log.ts";
|
|
8
9
|
import { initMetrics, resetMetrics, snapshotUnitMetrics } from "../metrics.ts";
|
|
9
10
|
import { setLogBasePath, logWarning } from "../workflow-logger.ts";
|
|
@@ -38,6 +39,12 @@ test("unified audit plane bridges journal/activity/metrics/workflow logger into
|
|
|
38
39
|
eventType: "iteration-start",
|
|
39
40
|
data: { turnId: "turn-123", unitId: "M001/S01/T01" },
|
|
40
41
|
});
|
|
42
|
+
appendEvent(basePath, {
|
|
43
|
+
cmd: "complete-task",
|
|
44
|
+
params: { milestoneId: "M001", sliceId: "S01", taskId: "T01" },
|
|
45
|
+
ts: new Date().toISOString(),
|
|
46
|
+
actor: "agent",
|
|
47
|
+
});
|
|
41
48
|
|
|
42
49
|
const activityCtx = makeMockContext([
|
|
43
50
|
{ type: "message", message: { role: "assistant", content: [{ type: "text", text: "hello" }] } },
|
|
@@ -73,6 +80,7 @@ test("unified audit plane bridges journal/activity/metrics/workflow logger into
|
|
|
73
80
|
const events = readAuditEvents(basePath);
|
|
74
81
|
const types = new Set(events.map((event) => String(event.type ?? "")));
|
|
75
82
|
assert.ok(types.has("journal-iteration-start"));
|
|
83
|
+
assert.ok(types.has("workflow-event-complete_task"));
|
|
76
84
|
assert.ok(types.has("activity-log-saved"));
|
|
77
85
|
assert.ok(types.has("unit-metrics-snapshot"));
|
|
78
86
|
assert.ok(types.has("workflow-log-warn"));
|
|
@@ -24,6 +24,8 @@ test("execute-task fails closed when no host-owned checks are discovered", () =>
|
|
|
24
24
|
assert.equal(verdict.reason, "no-host-checks");
|
|
25
25
|
assert.equal(verdict.retryable, false);
|
|
26
26
|
assert.match(verdict.failureContext, /No runnable host-owned verification command/);
|
|
27
|
+
assert.match(verdict.failureContext, /\.gsd\/PREFERENCES\.md/);
|
|
28
|
+
assert.match(verdict.failureContext, /\/gsd next/);
|
|
27
29
|
});
|
|
28
30
|
|
|
29
31
|
test("execute-task passes when non-runnable task-plan prose is the verification source", () => {
|
|
@@ -15,6 +15,10 @@ function scaffoldProject(root: string, pkg: Record<string, unknown>): void {
|
|
|
15
15
|
writeFileSync(join(root, "package.json"), JSON.stringify(pkg, null, 2));
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
const LEGACY_ENGINE = { engine: "legacy", source: "probe", reason: "test" } as const;
|
|
19
|
+
const MANAGED_ENGINE = { engine: "gsd-browser", source: "probe", reason: "test" } as const;
|
|
20
|
+
const OFF_ENGINE = { engine: "off", source: "env", reason: "test" } as const;
|
|
21
|
+
|
|
18
22
|
describe("web-app-uat guidance", () => {
|
|
19
23
|
test("returns null for non-web projects", () => {
|
|
20
24
|
const root = mkdtempSync(join(tmpdir(), "gsd-web-uat-"));
|
|
@@ -36,15 +40,54 @@ describe("web-app-uat guidance", () => {
|
|
|
36
40
|
scripts: { dev: "vite" },
|
|
37
41
|
});
|
|
38
42
|
assert.equal(detectWebApp(root), true);
|
|
39
|
-
const block = buildWebAppUatGuidanceBlock(root);
|
|
43
|
+
const block = buildWebAppUatGuidanceBlock(root, LEGACY_ENGINE);
|
|
40
44
|
assert.ok(block);
|
|
41
45
|
assert.match(block!, /browser-executable/);
|
|
46
|
+
assert.match(block!, /Playwright-backed `browser_\*` tools/);
|
|
42
47
|
assert.match(block!, /Playwright scaffolding/);
|
|
43
48
|
} finally {
|
|
44
49
|
rmSync(root, { recursive: true, force: true });
|
|
45
50
|
}
|
|
46
51
|
});
|
|
47
52
|
|
|
53
|
+
test("describes the managed gsd-browser engine when it is the resolved backing", () => {
|
|
54
|
+
const root = mkdtempSync(join(tmpdir(), "gsd-web-uat-"));
|
|
55
|
+
try {
|
|
56
|
+
scaffoldProject(root, {
|
|
57
|
+
dependencies: { react: "19.0.0" },
|
|
58
|
+
scripts: { dev: "vite" },
|
|
59
|
+
});
|
|
60
|
+
const block = buildWebAppUatGuidanceBlock(root, MANAGED_ENGINE);
|
|
61
|
+
assert.ok(block);
|
|
62
|
+
assert.match(block!, /managed gsd-browser engine/);
|
|
63
|
+
assert.match(block!, /browser-executable/);
|
|
64
|
+
assert.doesNotMatch(block!, /Playwright-backed/);
|
|
65
|
+
} finally {
|
|
66
|
+
rmSync(root, { recursive: true, force: true });
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("steers to runtime-executable UAT when browser tools are off", () => {
|
|
71
|
+
const root = mkdtempSync(join(tmpdir(), "gsd-web-uat-"));
|
|
72
|
+
try {
|
|
73
|
+
scaffoldProject(root, {
|
|
74
|
+
dependencies: { react: "19.0.0" },
|
|
75
|
+
scripts: { dev: "vite" },
|
|
76
|
+
});
|
|
77
|
+
const block = buildWebAppUatGuidanceBlock(root, OFF_ENGINE);
|
|
78
|
+
assert.ok(block);
|
|
79
|
+
assert.match(block!, /browser tools are disabled/);
|
|
80
|
+
assert.doesNotMatch(block!, /- `browser-executable`/);
|
|
81
|
+
// mixed/live-runtime require browser tools per UAT_MODE_POLICIES, so the
|
|
82
|
+
// bullet must drop out too — recommending them would dead-end at dispatch.
|
|
83
|
+
assert.doesNotMatch(block!, /- `mixed`/);
|
|
84
|
+
assert.doesNotMatch(block!, /interactive `browser_\*` checks/);
|
|
85
|
+
assert.match(block!, /runtime-executable/);
|
|
86
|
+
} finally {
|
|
87
|
+
rmSync(root, { recursive: true, force: true });
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
48
91
|
test("detects existing Playwright and npm script", () => {
|
|
49
92
|
const root = mkdtempSync(join(tmpdir(), "gsd-web-uat-"));
|
|
50
93
|
try {
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
compactMilestoneEvents,
|
|
14
14
|
type WorkflowEvent,
|
|
15
15
|
} from '../workflow-events.ts';
|
|
16
|
+
import { workflowEventLogPath } from '../workflow-event-ledger.ts';
|
|
16
17
|
|
|
17
18
|
function tempDir(): string {
|
|
18
19
|
return fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-events-'));
|
|
@@ -38,6 +39,24 @@ test('workflow-events: appendEvent creates .gsd dir and event-log.jsonl', () =>
|
|
|
38
39
|
}
|
|
39
40
|
});
|
|
40
41
|
|
|
42
|
+
test('workflow-events: appendEvent from canonical worktree writes project ledger', () => {
|
|
43
|
+
const base = tempDir();
|
|
44
|
+
try {
|
|
45
|
+
const worktree = path.join(base, '.gsd-worktrees', 'M001');
|
|
46
|
+
fs.mkdirSync(worktree, { recursive: true });
|
|
47
|
+
|
|
48
|
+
appendEvent(worktree, makeEvent('complete-task', { milestoneId: 'M001', taskId: 'T01' }));
|
|
49
|
+
|
|
50
|
+
const projectLog = path.join(base, '.gsd', 'event-log.jsonl');
|
|
51
|
+
const worktreeLog = path.join(worktree, '.gsd', 'event-log.jsonl');
|
|
52
|
+
assert.ok(fs.existsSync(projectLog), 'project event ledger should exist');
|
|
53
|
+
assert.equal(fs.existsSync(worktreeLog), false, 'worktree-local event log should not be the append target');
|
|
54
|
+
assert.equal(workflowEventLogPath(worktree), projectLog);
|
|
55
|
+
} finally {
|
|
56
|
+
cleanupDir(base);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
41
60
|
test('workflow-events: appendEvent writes valid JSON line', () => {
|
|
42
61
|
const base = tempDir();
|
|
43
62
|
try {
|
|
@@ -495,8 +495,8 @@ test("workflow MCP launch config reaches mutation tools over stdio", async () =>
|
|
|
495
495
|
estimate: "10m",
|
|
496
496
|
files: ["src/resources/extensions/gsd/workflow-mcp.ts"],
|
|
497
497
|
verify: "node --test",
|
|
498
|
-
inputs: [
|
|
499
|
-
expectedOutput: ["
|
|
498
|
+
inputs: [],
|
|
499
|
+
expectedOutput: ["src/bridge-status.md"],
|
|
500
500
|
},
|
|
501
501
|
],
|
|
502
502
|
},
|
|
@@ -89,3 +89,23 @@ test("resolveConflict(pick=main) rewrites the worktree log durably", () => {
|
|
|
89
89
|
const second = reconcileWorktreeLogs(main, worktree);
|
|
90
90
|
assert.equal(second.conflicts.length, 0, "reconcile should stay clean after choosing main");
|
|
91
91
|
});
|
|
92
|
+
|
|
93
|
+
test("reconcileWorktreeLogs treats canonical worktree project-ledger appends as already durable", () => {
|
|
94
|
+
const root = mkdtempSync(join(tmpdir(), "workflow-reconcile-canonical-"));
|
|
95
|
+
const main = join(root, "main");
|
|
96
|
+
const worktree = join(main, ".gsd-worktrees", "M001");
|
|
97
|
+
mkdirSync(worktree, { recursive: true });
|
|
98
|
+
tmpDirs.push(root);
|
|
99
|
+
|
|
100
|
+
appendEvent(worktree, {
|
|
101
|
+
cmd: "complete-task",
|
|
102
|
+
params: { milestoneId: "M001", sliceId: "S01", taskId: "T01" },
|
|
103
|
+
ts: "2026-01-01T00:00:00.000Z",
|
|
104
|
+
actor: "agent",
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const result = reconcileWorktreeLogs(main, worktree);
|
|
108
|
+
|
|
109
|
+
assert.equal(result.autoMerged, 0, "project-ledger append should not replay the root log");
|
|
110
|
+
assert.equal(result.conflicts.length, 0, "missing worktree shard is not a conflict");
|
|
111
|
+
});
|
|
@@ -15,8 +15,11 @@ import {
|
|
|
15
15
|
upsertRequirement,
|
|
16
16
|
getAllMilestones,
|
|
17
17
|
} from "../gsd-db.ts";
|
|
18
|
+
import { registerAutoWorker } from "../db/auto-workers.ts";
|
|
19
|
+
import { claimMilestoneLease, getMilestoneLease } from "../db/milestone-leases.ts";
|
|
18
20
|
import { deriveState, invalidateStateCache } from "../state.ts";
|
|
19
21
|
import { autoSession } from "../auto-runtime-state.ts";
|
|
22
|
+
import { normalizeRealPath } from "../paths.ts";
|
|
20
23
|
import { markApprovalGateVerified, markDepthVerified, clearDiscussionFlowState, loadWriteGateSnapshot, setPendingGate } from "../bootstrap/write-gate.ts";
|
|
21
24
|
import {
|
|
22
25
|
executeCompleteMilestone,
|
|
@@ -94,6 +97,28 @@ function seedMilestone(milestoneId: string, title: string, status = "active"): v
|
|
|
94
97
|
).run(milestoneId, title, status, new Date().toISOString());
|
|
95
98
|
}
|
|
96
99
|
|
|
100
|
+
function validMilestonePlan(milestoneId = "M001"): Parameters<typeof executePlanMilestone>[0] {
|
|
101
|
+
return {
|
|
102
|
+
milestoneId,
|
|
103
|
+
title: "Workflow MCP planning",
|
|
104
|
+
vision: "Plan milestone over shared executors.",
|
|
105
|
+
slices: [
|
|
106
|
+
{
|
|
107
|
+
sliceId: "S01",
|
|
108
|
+
title: "Bridge planning",
|
|
109
|
+
risk: "medium",
|
|
110
|
+
depends: [],
|
|
111
|
+
demo: "Milestone plan persists through MCP.",
|
|
112
|
+
goal: "Persist roadmap state.",
|
|
113
|
+
successCriteria: "ROADMAP.md renders from DB.",
|
|
114
|
+
proofLevel: "integration",
|
|
115
|
+
integrationClosure: "Prompts and MCP call the same handler.",
|
|
116
|
+
observabilityImpact: "Executor tests cover output paths.",
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
97
122
|
function seedSlice(milestoneId: string, sliceId: string, status: string): void {
|
|
98
123
|
const db = _getAdapter();
|
|
99
124
|
if (!db) throw new Error("DB not open");
|
|
@@ -461,25 +486,7 @@ test("executePlanMilestone writes roadmap state and rendered roadmap path", asyn
|
|
|
461
486
|
try {
|
|
462
487
|
openTestDb(base);
|
|
463
488
|
|
|
464
|
-
const result = await inProjectDir(base, () => executePlanMilestone(
|
|
465
|
-
milestoneId: "M001",
|
|
466
|
-
title: "Workflow MCP planning",
|
|
467
|
-
vision: "Plan milestone over shared executors.",
|
|
468
|
-
slices: [
|
|
469
|
-
{
|
|
470
|
-
sliceId: "S01",
|
|
471
|
-
title: "Bridge planning",
|
|
472
|
-
risk: "medium",
|
|
473
|
-
depends: [],
|
|
474
|
-
demo: "Milestone plan persists through MCP.",
|
|
475
|
-
goal: "Persist roadmap state.",
|
|
476
|
-
successCriteria: "ROADMAP.md renders from DB.",
|
|
477
|
-
proofLevel: "integration",
|
|
478
|
-
integrationClosure: "Prompts and MCP call the same handler.",
|
|
479
|
-
observabilityImpact: "Executor tests cover output paths.",
|
|
480
|
-
},
|
|
481
|
-
],
|
|
482
|
-
}, base));
|
|
489
|
+
const result = await inProjectDir(base, () => executePlanMilestone(validMilestonePlan(), base));
|
|
483
490
|
|
|
484
491
|
assert.equal(result.details.operation, "plan_milestone");
|
|
485
492
|
assert.equal(result.details.milestoneId, "M001");
|
|
@@ -492,29 +499,257 @@ test("executePlanMilestone writes roadmap state and rendered roadmap path", asyn
|
|
|
492
499
|
}
|
|
493
500
|
});
|
|
494
501
|
|
|
502
|
+
test("executePlanMilestone refuses a same-milestone lease conflict", async () => {
|
|
503
|
+
const base = makeTmpBase();
|
|
504
|
+
try {
|
|
505
|
+
openTestDb(base);
|
|
506
|
+
seedMilestone("M001", "Existing holder");
|
|
507
|
+
const holder = registerAutoWorker({ projectRootRealpath: join(base, "other-project") });
|
|
508
|
+
const lease = claimMilestoneLease(holder, "M001");
|
|
509
|
+
assert.equal(lease.ok, true);
|
|
510
|
+
|
|
511
|
+
const result = await inProjectDir(base, () => executePlanMilestone(validMilestonePlan("M001"), base));
|
|
512
|
+
|
|
513
|
+
assert.equal(result.isError, true);
|
|
514
|
+
assert.equal(result.details.operation, "plan_milestone");
|
|
515
|
+
assert.equal(result.details.error, "milestone_lease_conflict");
|
|
516
|
+
assert.match(result.content[0].text, /Milestone M001 is currently leased/);
|
|
517
|
+
} finally {
|
|
518
|
+
closeDatabase();
|
|
519
|
+
cleanup(base);
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
test("executePlanMilestone releases its one-shot milestone lease after planning", async () => {
|
|
524
|
+
const base = makeTmpBase();
|
|
525
|
+
try {
|
|
526
|
+
openTestDb(base);
|
|
527
|
+
seedMilestone("M001", "Existing milestone");
|
|
528
|
+
|
|
529
|
+
const result = await inProjectDir(base, () => executePlanMilestone(validMilestonePlan("M001"), base));
|
|
530
|
+
|
|
531
|
+
assert.equal(result.isError, undefined);
|
|
532
|
+
const lease = getMilestoneLease("M001");
|
|
533
|
+
assert.ok(lease, "planning should participate in milestone lease coordination");
|
|
534
|
+
assert.equal(lease.status, "released");
|
|
535
|
+
} finally {
|
|
536
|
+
closeDatabase();
|
|
537
|
+
cleanup(base);
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
test("executePlanMilestone creates a fresh milestone without a one-shot lease", async () => {
|
|
542
|
+
const base = makeTmpBase();
|
|
543
|
+
try {
|
|
544
|
+
openTestDb(base);
|
|
545
|
+
|
|
546
|
+
const result = await inProjectDir(base, () => executePlanMilestone(validMilestonePlan("M042"), base));
|
|
547
|
+
|
|
548
|
+
assert.equal(result.isError, undefined);
|
|
549
|
+
assert.equal(result.details.operation, "plan_milestone");
|
|
550
|
+
assert.equal(result.details.milestoneId, "M042");
|
|
551
|
+
assert.equal(getMilestoneLease("M042"), null,
|
|
552
|
+
"fresh milestone creation must pass through without creating a lease row");
|
|
553
|
+
} finally {
|
|
554
|
+
closeDatabase();
|
|
555
|
+
cleanup(base);
|
|
556
|
+
}
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
test("executePlanMilestone does not create a placeholder when fresh planning validation fails", async () => {
|
|
560
|
+
const base = makeTmpBase();
|
|
561
|
+
try {
|
|
562
|
+
openTestDb(base);
|
|
563
|
+
|
|
564
|
+
// handlePlanMilestone rejects empty slice arrays during validation. Fresh
|
|
565
|
+
// milestone creation must pass through without pre-inserting a leaseable
|
|
566
|
+
// placeholder row.
|
|
567
|
+
const invalid = { ...validMilestonePlan("M042"), slices: [] };
|
|
568
|
+
const result = await inProjectDir(base, () => executePlanMilestone(invalid, base));
|
|
569
|
+
|
|
570
|
+
assert.equal(result.isError, true);
|
|
571
|
+
assert.equal(result.details.operation, "plan_milestone");
|
|
572
|
+
const milestones = getAllMilestones();
|
|
573
|
+
assert.equal(milestones.find(m => m.id === "M042"), undefined,
|
|
574
|
+
"failed fresh planning must not leave a milestone row behind");
|
|
575
|
+
assert.equal(getMilestoneLease("M042"), null,
|
|
576
|
+
"failed fresh planning must not create a lease row");
|
|
577
|
+
} finally {
|
|
578
|
+
closeDatabase();
|
|
579
|
+
cleanup(base);
|
|
580
|
+
}
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
test("executePlanMilestone does not delete a peer worker's milestone row on lease conflict", async () => {
|
|
584
|
+
const base = makeTmpBase();
|
|
585
|
+
try {
|
|
586
|
+
openTestDb(base);
|
|
587
|
+
|
|
588
|
+
// Simulate a peer worker (different project_root) that has already
|
|
589
|
+
// created the milestone row and taken its lease. The one-shot executor
|
|
590
|
+
// must observe the active lease and refuse — without removing the peer's
|
|
591
|
+
// milestone row or lease. The pre-rollback bug was that
|
|
592
|
+
// INSERT OR IGNORE's silent no-op was treated as proof of authorship and
|
|
593
|
+
// the cleanup path then deleted the peer's row.
|
|
594
|
+
const peer = registerAutoWorker({ projectRootRealpath: join(base, "peer-project") });
|
|
595
|
+
seedMilestone("M050", "Peer-owned milestone");
|
|
596
|
+
const peerLease = claimMilestoneLease(peer, "M050");
|
|
597
|
+
assert.equal(peerLease.ok, true);
|
|
598
|
+
const peerLeaseToken = peerLease.ok ? peerLease.token : -1;
|
|
599
|
+
|
|
600
|
+
const result = await inProjectDir(base, () => executePlanMilestone(validMilestonePlan("M050"), base));
|
|
601
|
+
|
|
602
|
+
assert.equal(result.isError, true);
|
|
603
|
+
assert.equal(result.details.error, "milestone_lease_conflict");
|
|
604
|
+
const peerMilestone = getAllMilestones().find(m => m.id === "M050");
|
|
605
|
+
assert.ok(peerMilestone, "peer milestone row must survive the one-shot conflict path");
|
|
606
|
+
assert.equal(peerMilestone?.title, "Peer-owned milestone",
|
|
607
|
+
"peer milestone row must not be clobbered or recreated");
|
|
608
|
+
const surviving = getMilestoneLease("M050");
|
|
609
|
+
assert.ok(surviving, "peer lease row must survive");
|
|
610
|
+
assert.equal(surviving.status, "held", "peer must still hold the lease");
|
|
611
|
+
assert.equal(surviving.worker_id, peer);
|
|
612
|
+
assert.equal(surviving.fencing_token, peerLeaseToken,
|
|
613
|
+
"peer's fencing token must not be incremented by the rejected one-shot");
|
|
614
|
+
} finally {
|
|
615
|
+
closeDatabase();
|
|
616
|
+
cleanup(base);
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
test("executePlanMilestone refuses when a foreign active worker holds the lease even while in-process auto is active", async () => {
|
|
621
|
+
const base = makeTmpBase();
|
|
622
|
+
autoSession.reset();
|
|
623
|
+
try {
|
|
624
|
+
openTestDb(base);
|
|
625
|
+
seedMilestone("M060", "Foreign-held milestone");
|
|
626
|
+
|
|
627
|
+
// In-process auto must still reject a lease held by another worker.
|
|
628
|
+
const foreign = registerAutoWorker({ projectRootRealpath: join(base, "foreign-project") });
|
|
629
|
+
const foreignLease = claimMilestoneLease(foreign, "M060");
|
|
630
|
+
assert.equal(foreignLease.ok, true);
|
|
631
|
+
const foreignToken = foreignLease.ok ? foreignLease.token : -1;
|
|
632
|
+
|
|
633
|
+
const ownAutoWorker = registerAutoWorker({ projectRootRealpath: normalizeRealPath(base) });
|
|
634
|
+
autoSession.active = true;
|
|
635
|
+
autoSession.workerId = ownAutoWorker;
|
|
636
|
+
|
|
637
|
+
const result = await inProjectDir(base, () => executePlanMilestone(validMilestonePlan("M060"), base));
|
|
638
|
+
|
|
639
|
+
assert.equal(result.isError, true);
|
|
640
|
+
assert.equal(result.details.error, "milestone_lease_conflict",
|
|
641
|
+
"in-process auto must NOT skip lease checks when the lease is held by a different active worker");
|
|
642
|
+
const surviving = getMilestoneLease("M060");
|
|
643
|
+
assert.ok(surviving);
|
|
644
|
+
assert.equal(surviving.status, "held");
|
|
645
|
+
assert.equal(surviving.worker_id, foreign);
|
|
646
|
+
assert.equal(surviving.fencing_token, foreignToken,
|
|
647
|
+
"foreign worker's fencing token must not be incremented by the rejected call");
|
|
648
|
+
} finally {
|
|
649
|
+
autoSession.reset();
|
|
650
|
+
closeDatabase();
|
|
651
|
+
cleanup(base);
|
|
652
|
+
}
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
test("executePlanMilestone proceeds without re-claiming when in-process auto holds the lease itself", async () => {
|
|
656
|
+
const base = makeTmpBase();
|
|
657
|
+
autoSession.reset();
|
|
658
|
+
try {
|
|
659
|
+
openTestDb(base);
|
|
660
|
+
seedMilestone("M070", "Auto-held milestone");
|
|
661
|
+
|
|
662
|
+
// In-process auto should not re-claim its own lease and bump its token.
|
|
663
|
+
const ownAutoWorker = registerAutoWorker({ projectRootRealpath: normalizeRealPath(base) });
|
|
664
|
+
const heldLease = claimMilestoneLease(ownAutoWorker, "M070");
|
|
665
|
+
assert.equal(heldLease.ok, true);
|
|
666
|
+
const heldToken = heldLease.ok ? heldLease.token : -1;
|
|
667
|
+
autoSession.active = true;
|
|
668
|
+
autoSession.workerId = ownAutoWorker;
|
|
669
|
+
|
|
670
|
+
const result = await inProjectDir(base, () => executePlanMilestone(validMilestonePlan("M070"), base));
|
|
671
|
+
|
|
672
|
+
assert.equal(result.isError, undefined, `auto's own plan-milestone call should succeed: ${result.content?.[0]?.text}`);
|
|
673
|
+
const surviving = getMilestoneLease("M070");
|
|
674
|
+
assert.ok(surviving);
|
|
675
|
+
assert.equal(surviving.status, "held", "auto's lease must still be held after the planning call");
|
|
676
|
+
assert.equal(surviving.worker_id, ownAutoWorker);
|
|
677
|
+
assert.equal(surviving.fencing_token, heldToken,
|
|
678
|
+
"auto's fencing token must not be incremented by an in-process plan call");
|
|
679
|
+
} finally {
|
|
680
|
+
autoSession.reset();
|
|
681
|
+
closeDatabase();
|
|
682
|
+
cleanup(base);
|
|
683
|
+
}
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
test("executePlanMilestone refuses a same-process holder when active auto does not own it", async () => {
|
|
687
|
+
const base = makeTmpBase();
|
|
688
|
+
autoSession.reset();
|
|
689
|
+
try {
|
|
690
|
+
openTestDb(base);
|
|
691
|
+
seedMilestone("M080", "Same-process holder");
|
|
692
|
+
const staleWorker = registerAutoWorker({ projectRootRealpath: normalizeRealPath(base) });
|
|
693
|
+
const heldLease = claimMilestoneLease(staleWorker, "M080");
|
|
694
|
+
assert.equal(heldLease.ok, true);
|
|
695
|
+
const heldToken = heldLease.ok ? heldLease.token : -1;
|
|
696
|
+
|
|
697
|
+
autoSession.active = true;
|
|
698
|
+
autoSession.workerId = registerAutoWorker({ projectRootRealpath: normalizeRealPath(base) });
|
|
699
|
+
|
|
700
|
+
const result = await inProjectDir(base, () => executePlanMilestone(validMilestonePlan("M080"), base));
|
|
701
|
+
|
|
702
|
+
assert.equal(result.isError, true);
|
|
703
|
+
assert.equal(result.details?.error, "milestone_lease_conflict");
|
|
704
|
+
const surviving = getMilestoneLease("M080");
|
|
705
|
+
assert.ok(surviving, "same-process holder lease must remain after conflict");
|
|
706
|
+
assert.equal(surviving.worker_id, staleWorker);
|
|
707
|
+
assert.equal(surviving.fencing_token, heldToken);
|
|
708
|
+
assert.equal(surviving.status, "held");
|
|
709
|
+
} finally {
|
|
710
|
+
autoSession.reset();
|
|
711
|
+
closeDatabase();
|
|
712
|
+
cleanup(base);
|
|
713
|
+
}
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
test("executePlanMilestone takes over a stale same-process lease via reentry instead of waiting for TTL", async () => {
|
|
717
|
+
const base = makeTmpBase();
|
|
718
|
+
autoSession.reset();
|
|
719
|
+
try {
|
|
720
|
+
openTestDb(base);
|
|
721
|
+
seedMilestone("M080", "Stale-locked milestone");
|
|
722
|
+
|
|
723
|
+
// One-shot planning should reach claimMilestoneLease so its same-process
|
|
724
|
+
// reentry clause can recover stale worker rows.
|
|
725
|
+
const staleWorker = registerAutoWorker({ projectRootRealpath: normalizeRealPath(base) });
|
|
726
|
+
const staleLease = claimMilestoneLease(staleWorker, "M080");
|
|
727
|
+
assert.equal(staleLease.ok, true);
|
|
728
|
+
const staleToken = staleLease.ok ? staleLease.token : -1;
|
|
729
|
+
|
|
730
|
+
const result = await inProjectDir(base, () => executePlanMilestone(validMilestonePlan("M080"), base));
|
|
731
|
+
|
|
732
|
+
assert.equal(result.isError, undefined,
|
|
733
|
+
`same-process reentry takeover must succeed, not return milestone_lease_conflict: ${result.content?.[0]?.text}`);
|
|
734
|
+
const after = getMilestoneLease("M080");
|
|
735
|
+
assert.ok(after, "lease row must remain after takeover + release");
|
|
736
|
+
assert.equal(after.status, "released", "the executor releases its own claim before returning");
|
|
737
|
+
assert.notEqual(after.worker_id, staleWorker,
|
|
738
|
+
"lease must be owned by the new worker after takeover");
|
|
739
|
+
assert.ok(after.fencing_token > staleToken,
|
|
740
|
+
`fencing token must monotonically advance on takeover (was ${staleToken}, now ${after.fencing_token})`);
|
|
741
|
+
} finally {
|
|
742
|
+
autoSession.reset();
|
|
743
|
+
closeDatabase();
|
|
744
|
+
cleanup(base);
|
|
745
|
+
}
|
|
746
|
+
});
|
|
747
|
+
|
|
495
748
|
test("executePlanSlice writes task planning state and rendered plan artifacts", async () => {
|
|
496
749
|
const base = makeTmpBase();
|
|
497
750
|
try {
|
|
498
751
|
openTestDb(base);
|
|
499
|
-
await inProjectDir(base, () => executePlanMilestone(
|
|
500
|
-
milestoneId: "M001",
|
|
501
|
-
title: "Workflow MCP planning",
|
|
502
|
-
vision: "Plan milestone over shared executors.",
|
|
503
|
-
slices: [
|
|
504
|
-
{
|
|
505
|
-
sliceId: "S01",
|
|
506
|
-
title: "Bridge planning",
|
|
507
|
-
risk: "medium",
|
|
508
|
-
depends: [],
|
|
509
|
-
demo: "Milestone plan persists through MCP.",
|
|
510
|
-
goal: "Persist roadmap state.",
|
|
511
|
-
successCriteria: "ROADMAP.md renders from DB.",
|
|
512
|
-
proofLevel: "integration",
|
|
513
|
-
integrationClosure: "Prompts and MCP call the same handler.",
|
|
514
|
-
observabilityImpact: "Executor tests cover output paths.",
|
|
515
|
-
},
|
|
516
|
-
],
|
|
517
|
-
}, base));
|
|
752
|
+
await inProjectDir(base, () => executePlanMilestone(validMilestonePlan(), base));
|
|
518
753
|
|
|
519
754
|
const result = await inProjectDir(base, () => executePlanSlice({
|
|
520
755
|
milestoneId: "M001",
|
|
@@ -528,8 +763,8 @@ test("executePlanSlice writes task planning state and rendered plan artifacts",
|
|
|
528
763
|
estimate: "15m",
|
|
529
764
|
files: ["src/resources/extensions/gsd/tools/workflow-tool-executors.ts"],
|
|
530
765
|
verify: "node --test",
|
|
531
|
-
inputs: [
|
|
532
|
-
expectedOutput: ["
|
|
766
|
+
inputs: [],
|
|
767
|
+
expectedOutput: ["src/bridge-status.md"],
|
|
533
768
|
},
|
|
534
769
|
],
|
|
535
770
|
}, base));
|
|
@@ -25,6 +25,7 @@ import { join } from "node:path";
|
|
|
25
25
|
import { tmpdir } from "node:os";
|
|
26
26
|
import { execSync } from "node:child_process";
|
|
27
27
|
import { describe, it, after } from "node:test";
|
|
28
|
+
import assert from "node:assert/strict";
|
|
28
29
|
|
|
29
30
|
import { createWorktree, removeWorktree, worktreePath, isInsideWorktreesDir } from "../worktree-manager.ts";
|
|
30
31
|
import { createTestContext } from "./test-helpers.ts";
|
|
@@ -86,6 +87,27 @@ describe("worktree-teardown-safety", () => {
|
|
|
86
87
|
);
|
|
87
88
|
});
|
|
88
89
|
|
|
90
|
+
it("removeWorktree survives when current working directory was deleted", () => {
|
|
91
|
+
const tempDir = createTempRepo();
|
|
92
|
+
dirs.push(tempDir);
|
|
93
|
+
|
|
94
|
+
const wt = createWorktree(tempDir, "deleted-cwd");
|
|
95
|
+
assertTrue(existsSync(wt.path), "worktree created successfully");
|
|
96
|
+
|
|
97
|
+
const safeCwd = process.cwd();
|
|
98
|
+
try {
|
|
99
|
+
process.chdir(wt.path);
|
|
100
|
+
rmSync(wt.path, { recursive: true, force: true });
|
|
101
|
+
|
|
102
|
+
assert.doesNotThrow(
|
|
103
|
+
() => removeWorktree(tempDir, "deleted-cwd"),
|
|
104
|
+
"removeWorktree should not call process.cwd() unguarded from a deleted cwd",
|
|
105
|
+
);
|
|
106
|
+
} finally {
|
|
107
|
+
process.chdir(safeCwd);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
89
111
|
it("path validation rejects paths outside .gsd/worktrees/", () => {
|
|
90
112
|
const tempDir = createTempRepo();
|
|
91
113
|
dirs.push(tempDir);
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
detectWorktreeName,
|
|
10
10
|
getCurrentBranch,
|
|
11
11
|
getMainBranch,
|
|
12
|
+
nudgeGitBranchCache,
|
|
12
13
|
getSliceBranchName,
|
|
13
14
|
parseSliceBranch,
|
|
14
15
|
resolveProjectRoot,
|
|
@@ -95,6 +96,23 @@ describe('worktree', async () => {
|
|
|
95
96
|
assert.ok(!SLICE_BRANCH_RE.test("gsd/"), "regex rejects bare gsd/");
|
|
96
97
|
assert.ok(!SLICE_BRANCH_RE.test("worktree/foo"), "regex rejects worktree/foo");
|
|
97
98
|
|
|
99
|
+
console.log("\n=== nudgeGitBranchCache deleted cwd ===");
|
|
100
|
+
{
|
|
101
|
+
const safeCwd = process.cwd();
|
|
102
|
+
const deletedCwd = mkdtempSync(join(tmpdir(), "gsd-deleted-cwd-"));
|
|
103
|
+
try {
|
|
104
|
+
process.chdir(deletedCwd);
|
|
105
|
+
rmSync(deletedCwd, { recursive: true, force: true });
|
|
106
|
+
|
|
107
|
+
assert.doesNotThrow(
|
|
108
|
+
() => nudgeGitBranchCache(safeCwd),
|
|
109
|
+
"nudgeGitBranchCache should not call process.cwd() unguarded from a deleted cwd",
|
|
110
|
+
);
|
|
111
|
+
} finally {
|
|
112
|
+
process.chdir(safeCwd);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
98
116
|
console.log("\n=== detectWorktreeName ===");
|
|
99
117
|
assert.deepStrictEqual(detectWorktreeName("/projects/myapp"), null, "no worktree in plain path");
|
|
100
118
|
assert.deepStrictEqual(detectWorktreeName("/projects/myapp/.gsd/worktrees/feature-auth"), "feature-auth", "detects worktree name");
|