gsd-pi 2.82.0-dev.ed17d078d → 3.0.0
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 +6 -5
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +10 -1
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +1 -1
- package/dist/resources/extensions/cmux/index.js +5 -0
- package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
- package/dist/resources/extensions/gsd/auto/loop.js +19 -6
- package/dist/resources/extensions/gsd/auto/orchestrator.js +11 -0
- package/dist/resources/extensions/gsd/auto/phases.js +81 -31
- package/dist/resources/extensions/gsd/auto/session.js +4 -0
- package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
- package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +20 -19
- package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +246 -133
- package/dist/resources/extensions/gsd/auto-prompts.js +2 -2
- package/dist/resources/extensions/gsd/auto-recovery.js +71 -14
- package/dist/resources/extensions/gsd/auto-start.js +87 -14
- package/dist/resources/extensions/gsd/auto-verification.js +45 -26
- package/dist/resources/extensions/gsd/auto-worktree.js +176 -10
- package/dist/resources/extensions/gsd/auto.js +57 -33
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +31 -7
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +10 -9
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +4 -2
- package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +17 -3
- package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
- package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +38 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
- package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +7 -2
- package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
- package/dist/resources/extensions/gsd/crash-recovery.js +43 -5
- package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
- package/dist/resources/extensions/gsd/dispatch-guard.js +2 -2
- package/dist/resources/extensions/gsd/doctor-git-checks.js +46 -1
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
- package/dist/resources/extensions/gsd/doctor.js +2 -28
- package/dist/resources/extensions/gsd/export-html.js +27 -425
- package/dist/resources/extensions/gsd/forensics.js +3 -3
- package/dist/resources/extensions/gsd/git-service.js +45 -3
- package/dist/resources/extensions/gsd/gsd-db.js +21 -6
- package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
- package/dist/resources/extensions/gsd/guided-flow.js +101 -116
- package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +10 -8
- package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
- package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
- package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
- package/dist/resources/extensions/gsd/native-git-bridge.js +48 -12
- package/dist/resources/extensions/gsd/paths.js +4 -0
- package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
- package/dist/resources/extensions/gsd/post-execution-checks.js +73 -2
- package/dist/resources/extensions/gsd/pre-execution-checks.js +28 -1
- package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
- package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
- package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
- package/dist/resources/extensions/gsd/state.js +3 -3
- package/dist/resources/extensions/gsd/status-guards.js +11 -0
- package/dist/resources/extensions/gsd/templates/plan.md +9 -5
- package/dist/resources/extensions/gsd/templates/task-plan.md +10 -2
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -8
- package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
- package/dist/resources/extensions/gsd/tools/plan-slice.js +87 -14
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +32 -10
- package/dist/resources/extensions/gsd/validation.js +23 -1
- package/dist/resources/extensions/gsd/verification-gate.js +68 -7
- package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
- package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +54 -10
- package/dist/resources/extensions/gsd/worktree-manager.js +1 -1
- package/dist/resources/extensions/shared/html-shell.js +388 -0
- package/dist/resources/extensions/subagent/index.js +448 -78
- package/dist/resources/extensions/subagent/launch.js +77 -0
- package/dist/resources/extensions/subagent/run-store.js +148 -0
- package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
- package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
- package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/dist/resources/extensions/visual-brief/index.js +5 -0
- package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
- package/dist/resources/extensions/visual-brief/prompts.js +140 -0
- 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 +11 -11
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +5 -5
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +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/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
- 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 +4 -5
- 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 +2 -5
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +5 -8
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -8
- 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 +4 -5
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
- package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
- package/dist/web/standalone/.next/server/chunks/63.js +3 -3
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +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/2973.33f26573894b6153.js +2 -0
- package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
- package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-f2a7482d42a5614b.js → page-2f24283c162b6ab3.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/layout-b23b3f6858dc6dc8.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/page-200592a7f3baf579.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
- package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +4 -4
- package/packages/contracts/dist/rpc.test.js +7 -0
- package/packages/contracts/dist/rpc.test.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +21 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +24 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/src/rpc.test.ts +8 -0
- package/packages/contracts/src/workflow.ts +24 -0
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/README.md +13 -4
- package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +80 -0
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
- package/packages/mcp-server/src/workflow-tools.ts +168 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/native/tsconfig.json +2 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
- package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +5 -6
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
- package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
- package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
- package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
- package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
- package/packages/pi-ai/src/providers/simple-options.ts +5 -6
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +71 -97
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
- package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +75 -102
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
- package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
- package/packages/pi-tui/dist/terminal.d.ts +2 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +12 -0
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
- package/packages/pi-tui/src/terminal.ts +11 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/package.json +1 -1
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +10 -1
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +1 -1
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +9 -0
- package/src/resources/extensions/cmux/index.ts +6 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +14 -6
- package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
- package/src/resources/extensions/gsd/auto/loop.ts +22 -6
- package/src/resources/extensions/gsd/auto/orchestrator.ts +11 -0
- package/src/resources/extensions/gsd/auto/phases.ts +90 -38
- package/src/resources/extensions/gsd/auto/session.ts +4 -0
- package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
- package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +72 -1
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +21 -19
- package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +279 -144
- package/src/resources/extensions/gsd/auto-prompts.ts +2 -2
- package/src/resources/extensions/gsd/auto-recovery.ts +74 -11
- package/src/resources/extensions/gsd/auto-start.ts +94 -12
- package/src/resources/extensions/gsd/auto-verification.ts +58 -36
- package/src/resources/extensions/gsd/auto-worktree.ts +193 -10
- package/src/resources/extensions/gsd/auto.ts +59 -31
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +42 -7
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +10 -9
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +4 -2
- package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +20 -4
- package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
- package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +41 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
- package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +8 -3
- package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
- package/src/resources/extensions/gsd/crash-recovery.ts +44 -4
- package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
- package/src/resources/extensions/gsd/dispatch-guard.ts +2 -2
- package/src/resources/extensions/gsd/doctor-git-checks.ts +45 -1
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
- package/src/resources/extensions/gsd/doctor-types.ts +1 -0
- package/src/resources/extensions/gsd/doctor.ts +2 -27
- package/src/resources/extensions/gsd/export-html.ts +27 -427
- package/src/resources/extensions/gsd/forensics.ts +3 -3
- package/src/resources/extensions/gsd/git-service.ts +51 -4
- package/src/resources/extensions/gsd/gsd-db.ts +21 -6
- package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
- package/src/resources/extensions/gsd/guided-flow.ts +134 -133
- package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +10 -8
- package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
- package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
- package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
- package/src/resources/extensions/gsd/native-git-bridge.ts +54 -12
- package/src/resources/extensions/gsd/paths.ts +5 -0
- package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
- package/src/resources/extensions/gsd/post-execution-checks.ts +87 -2
- package/src/resources/extensions/gsd/pre-execution-checks.ts +32 -1
- package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/src/resources/extensions/gsd/prompts/queue.md +4 -4
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
- package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
- package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
- package/src/resources/extensions/gsd/state.ts +3 -3
- package/src/resources/extensions/gsd/status-guards.ts +13 -0
- package/src/resources/extensions/gsd/templates/plan.md +9 -5
- package/src/resources/extensions/gsd/templates/task-plan.md +10 -2
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +80 -1
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +151 -12
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
- package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +18 -6
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +91 -6
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
- package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +11 -2
- package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +5 -9
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +86 -2
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +59 -2
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
- package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +112 -1
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +63 -2
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
- package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +251 -2
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +86 -0
- package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
- package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
- package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +53 -2
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +13 -1
- package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +103 -7
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +110 -1
- package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +19 -1
- package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +54 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +8 -10
- package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -8
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
- package/src/resources/extensions/gsd/tools/plan-slice.ts +97 -12
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
- package/src/resources/extensions/gsd/types.ts +1 -1
- package/src/resources/extensions/gsd/unit-context-manifest.ts +47 -11
- package/src/resources/extensions/gsd/validation.ts +23 -1
- package/src/resources/extensions/gsd/verification-gate.ts +78 -6
- package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
- package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +61 -10
- package/src/resources/extensions/gsd/worktree-manager.ts +1 -1
- package/src/resources/extensions/shared/html-shell.ts +412 -0
- package/src/resources/extensions/subagent/index.ts +567 -103
- package/src/resources/extensions/subagent/launch.ts +131 -0
- package/src/resources/extensions/subagent/run-store.ts +218 -0
- package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
- package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
- package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
- package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
- package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/src/resources/extensions/visual-brief/index.ts +8 -0
- package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
- package/src/resources/extensions/visual-brief/prompts.ts +183 -0
- package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
- package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
- package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
- package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-752f1e2ebdaa3e45.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
- package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
- package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
- package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
- /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → qoMxZh-xuwuvpFW0x0k01}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → qoMxZh-xuwuvpFW0x0k01}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// GSD-2 + Subagent launch contract and child process safety helpers.
|
|
2
|
+
|
|
3
|
+
import * as fs from "node:fs";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import { SessionManager } from "@gsd/pi-coding-agent";
|
|
6
|
+
import type { AgentConfig } from "./agents.js";
|
|
7
|
+
|
|
8
|
+
export const SUBAGENT_CHILD_ENV_VAR = "GSD_SUBAGENT_CHILD";
|
|
9
|
+
export const SUBAGENT_CHILD_ENV_VALUE = "1";
|
|
10
|
+
|
|
11
|
+
export type SubagentContextMode = "fresh" | "fork";
|
|
12
|
+
|
|
13
|
+
export type SubagentSessionArgs =
|
|
14
|
+
| { mode: "fresh" }
|
|
15
|
+
| { mode: "fork"; sessionFile: string; sessionDir?: string };
|
|
16
|
+
|
|
17
|
+
export interface SubagentParentSessionManager {
|
|
18
|
+
getSessionFile(): string | undefined;
|
|
19
|
+
getLeafId(): string | null;
|
|
20
|
+
getSessionDir(): string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface SubagentLaunchInput {
|
|
24
|
+
agent: AgentConfig;
|
|
25
|
+
task: string;
|
|
26
|
+
tmpPromptPath: string | null;
|
|
27
|
+
modelOverride?: string;
|
|
28
|
+
contextMode?: SubagentContextMode;
|
|
29
|
+
parentSessionManager?: SubagentParentSessionManager;
|
|
30
|
+
session?: SubagentSessionArgs;
|
|
31
|
+
cwd?: string;
|
|
32
|
+
defaultCwd: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface SubagentLaunchPlan {
|
|
36
|
+
args: string[];
|
|
37
|
+
env: NodeJS.ProcessEnv;
|
|
38
|
+
cwd: string;
|
|
39
|
+
session: SubagentSessionArgs;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function isSubagentChildProcess(env: NodeJS.ProcessEnv = process.env): boolean {
|
|
43
|
+
return env[SUBAGENT_CHILD_ENV_VAR] === SUBAGENT_CHILD_ENV_VALUE;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function buildSubagentProcessEnv(env: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv {
|
|
47
|
+
return {
|
|
48
|
+
...env,
|
|
49
|
+
[SUBAGENT_CHILD_ENV_VAR]: SUBAGENT_CHILD_ENV_VALUE,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function buildShellEnvAssignments(env: NodeJS.ProcessEnv = process.env): string[] {
|
|
54
|
+
const value = env[SUBAGENT_CHILD_ENV_VAR];
|
|
55
|
+
return value ? [`${SUBAGENT_CHILD_ENV_VAR}=${JSON.stringify(value)}`] : [];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function buildSubagentProcessArgs(
|
|
59
|
+
agent: AgentConfig,
|
|
60
|
+
task: string,
|
|
61
|
+
tmpPromptPath: string | null,
|
|
62
|
+
modelOverride?: string,
|
|
63
|
+
session: SubagentSessionArgs = { mode: "fresh" },
|
|
64
|
+
): string[] {
|
|
65
|
+
const args: string[] = ["--mode", "json", "-p"];
|
|
66
|
+
if (session.mode === "fork") {
|
|
67
|
+
args.push("--session", session.sessionFile);
|
|
68
|
+
if (session.sessionDir) args.push("--session-dir", session.sessionDir);
|
|
69
|
+
} else {
|
|
70
|
+
args.push("--no-session");
|
|
71
|
+
}
|
|
72
|
+
const effectiveModel = modelOverride ?? agent.model;
|
|
73
|
+
if (effectiveModel) args.push("--model", effectiveModel);
|
|
74
|
+
if (agent.tools && agent.tools.length > 0) args.push("--tools", agent.tools.join(","));
|
|
75
|
+
if (tmpPromptPath) args.push("--append-system-prompt", tmpPromptPath);
|
|
76
|
+
args.push(`Task: ${task}`);
|
|
77
|
+
return args;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function resolveSubagentSessionArgs(
|
|
81
|
+
contextMode: SubagentContextMode = "fresh",
|
|
82
|
+
parentSessionManager?: SubagentParentSessionManager,
|
|
83
|
+
): SubagentSessionArgs {
|
|
84
|
+
if (contextMode === "fresh") return { mode: "fresh" };
|
|
85
|
+
|
|
86
|
+
if (!parentSessionManager) {
|
|
87
|
+
throw new Error("Forked subagent context requires a parent session manager.");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const parentSessionFile = parentSessionManager.getSessionFile();
|
|
91
|
+
if (!parentSessionFile) {
|
|
92
|
+
throw new Error("Forked subagent context requires a persisted parent session file; current session is in-memory.");
|
|
93
|
+
}
|
|
94
|
+
if (!fs.existsSync(parentSessionFile)) {
|
|
95
|
+
throw new Error(`Forked subagent context could not read parent session file: ${parentSessionFile}`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const leafId = parentSessionManager.getLeafId();
|
|
99
|
+
if (!leafId) {
|
|
100
|
+
throw new Error("Forked subagent context requires a parent session leaf to branch from.");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const sessionDir = parentSessionManager.getSessionDir?.();
|
|
104
|
+
const parentSession = SessionManager.open(parentSessionFile, sessionDir);
|
|
105
|
+
const childSessionFile = parentSession.createBranchedSession(leafId);
|
|
106
|
+
if (!childSessionFile) {
|
|
107
|
+
throw new Error("Forked subagent context could not create a branched child session.");
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
mode: "fork",
|
|
112
|
+
sessionFile: childSessionFile,
|
|
113
|
+
...(sessionDir ? { sessionDir: path.resolve(sessionDir) } : {}),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function createSubagentLaunchPlan(input: SubagentLaunchInput): SubagentLaunchPlan {
|
|
118
|
+
const session = input.session ?? resolveSubagentSessionArgs(input.contextMode ?? "fresh", input.parentSessionManager);
|
|
119
|
+
return {
|
|
120
|
+
args: buildSubagentProcessArgs(
|
|
121
|
+
input.agent,
|
|
122
|
+
input.task,
|
|
123
|
+
input.tmpPromptPath,
|
|
124
|
+
input.modelOverride,
|
|
125
|
+
session,
|
|
126
|
+
),
|
|
127
|
+
env: buildSubagentProcessEnv(),
|
|
128
|
+
cwd: input.cwd ?? input.defaultCwd,
|
|
129
|
+
session,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
// GSD-2 + Durable subagent run status, tracking names, and result artifact store.
|
|
2
|
+
|
|
3
|
+
import * as fs from "node:fs";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import { randomInt } from "node:crypto";
|
|
6
|
+
import { getAgentDir } from "@gsd/pi-coding-agent";
|
|
7
|
+
|
|
8
|
+
export type SubagentRunMode = "single" | "parallel" | "chain";
|
|
9
|
+
export type SubagentRunStatus = "queued" | "running" | "succeeded" | "failed" | "interrupted";
|
|
10
|
+
|
|
11
|
+
export interface SubagentChildArtifact {
|
|
12
|
+
index: number;
|
|
13
|
+
agent: string;
|
|
14
|
+
trackingName?: string;
|
|
15
|
+
task: string;
|
|
16
|
+
status: SubagentRunStatus;
|
|
17
|
+
exitCode?: number;
|
|
18
|
+
cwd?: string;
|
|
19
|
+
sessionFile?: string;
|
|
20
|
+
startedAt?: string;
|
|
21
|
+
completedAt?: string;
|
|
22
|
+
output?: string;
|
|
23
|
+
stderr?: string;
|
|
24
|
+
errorMessage?: string;
|
|
25
|
+
stopReason?: string;
|
|
26
|
+
model?: string;
|
|
27
|
+
usage?: {
|
|
28
|
+
input: number;
|
|
29
|
+
output: number;
|
|
30
|
+
cacheRead: number;
|
|
31
|
+
cacheWrite: number;
|
|
32
|
+
cost: number;
|
|
33
|
+
contextTokens: number;
|
|
34
|
+
turns: number;
|
|
35
|
+
};
|
|
36
|
+
merge?: {
|
|
37
|
+
success: boolean;
|
|
38
|
+
appliedPatches: string[];
|
|
39
|
+
failedPatches: string[];
|
|
40
|
+
error?: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface SubagentRunRecord {
|
|
45
|
+
schemaVersion: 1;
|
|
46
|
+
runId: string;
|
|
47
|
+
mode: SubagentRunMode;
|
|
48
|
+
contextMode: "fresh" | "fork";
|
|
49
|
+
status: SubagentRunStatus;
|
|
50
|
+
cwd: string;
|
|
51
|
+
startedAt: string;
|
|
52
|
+
updatedAt: string;
|
|
53
|
+
completedAt?: string;
|
|
54
|
+
children: SubagentChildArtifact[];
|
|
55
|
+
failure?: {
|
|
56
|
+
type: "child-failed" | "merge-failed" | "interrupted" | "launch-failed";
|
|
57
|
+
message: string;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function defaultSubagentRunStoreDir(): string {
|
|
62
|
+
return path.join(getAgentDir(), "subagent-runs");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const TRACKING_ADJECTIVES = [
|
|
66
|
+
"amber",
|
|
67
|
+
"bright",
|
|
68
|
+
"calm",
|
|
69
|
+
"clear",
|
|
70
|
+
"crisp",
|
|
71
|
+
"daring",
|
|
72
|
+
"keen",
|
|
73
|
+
"lucky",
|
|
74
|
+
"quiet",
|
|
75
|
+
"steady",
|
|
76
|
+
"swift",
|
|
77
|
+
"vivid",
|
|
78
|
+
] as const;
|
|
79
|
+
|
|
80
|
+
const TRACKING_NOUNS = [
|
|
81
|
+
"anchor",
|
|
82
|
+
"atlas",
|
|
83
|
+
"beacon",
|
|
84
|
+
"canvas",
|
|
85
|
+
"compass",
|
|
86
|
+
"forge",
|
|
87
|
+
"harbor",
|
|
88
|
+
"lantern",
|
|
89
|
+
"ledger",
|
|
90
|
+
"mesa",
|
|
91
|
+
"quartz",
|
|
92
|
+
"ridge",
|
|
93
|
+
"signal",
|
|
94
|
+
"summit",
|
|
95
|
+
"vector",
|
|
96
|
+
"vista",
|
|
97
|
+
] as const;
|
|
98
|
+
|
|
99
|
+
export function createSubagentTrackingName(existingNames: ReadonlySet<string> = new Set()): string {
|
|
100
|
+
const maxCombinations = TRACKING_ADJECTIVES.length * TRACKING_NOUNS.length;
|
|
101
|
+
for (let attempt = 0; attempt < maxCombinations * 2; attempt++) {
|
|
102
|
+
const adjective = TRACKING_ADJECTIVES[randomInt(TRACKING_ADJECTIVES.length)];
|
|
103
|
+
const noun = TRACKING_NOUNS[randomInt(TRACKING_NOUNS.length)];
|
|
104
|
+
const name = `${adjective}-${noun}`;
|
|
105
|
+
if (!existingNames.has(name)) return name;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
let suffix = existingNames.size + 1;
|
|
109
|
+
while (existingNames.has(`agent-${suffix}`)) suffix++;
|
|
110
|
+
return `agent-${suffix}`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export class SubagentRunStore {
|
|
114
|
+
private readonly baseDir: string;
|
|
115
|
+
|
|
116
|
+
constructor(baseDir: string = defaultSubagentRunStoreDir()) {
|
|
117
|
+
this.baseDir = baseDir;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
getBaseDir(): string {
|
|
121
|
+
return this.baseDir;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
create(record: SubagentRunRecord): SubagentRunRecord {
|
|
125
|
+
this.write(record);
|
|
126
|
+
return record;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
get(runId: string): SubagentRunRecord | null {
|
|
130
|
+
const filePath = this.pathFor(runId);
|
|
131
|
+
if (!fs.existsSync(filePath)) return null;
|
|
132
|
+
try {
|
|
133
|
+
const parsed = JSON.parse(fs.readFileSync(filePath, "utf-8")) as Partial<SubagentRunRecord>;
|
|
134
|
+
if (
|
|
135
|
+
!parsed ||
|
|
136
|
+
typeof parsed !== "object" ||
|
|
137
|
+
typeof parsed.runId !== "string" ||
|
|
138
|
+
typeof parsed.updatedAt !== "string" ||
|
|
139
|
+
!Array.isArray(parsed.children)
|
|
140
|
+
) {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
return parsed as SubagentRunRecord;
|
|
144
|
+
} catch {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
update(runId: string, updater: (record: SubagentRunRecord) => SubagentRunRecord): SubagentRunRecord {
|
|
150
|
+
const current = this.get(runId);
|
|
151
|
+
if (!current) throw new Error(`Subagent run not found: ${runId}`);
|
|
152
|
+
const next = updater({
|
|
153
|
+
...current,
|
|
154
|
+
children: current.children.map((child) => ({ ...child })),
|
|
155
|
+
});
|
|
156
|
+
next.updatedAt = new Date().toISOString();
|
|
157
|
+
this.write(next);
|
|
158
|
+
return next;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
list(): SubagentRunRecord[] {
|
|
162
|
+
if (!fs.existsSync(this.baseDir)) return [];
|
|
163
|
+
return fs.readdirSync(this.baseDir)
|
|
164
|
+
.filter((name) => name.endsWith(".json"))
|
|
165
|
+
.map((name) => this.get(path.basename(name, ".json")))
|
|
166
|
+
.filter((record): record is SubagentRunRecord => record !== null)
|
|
167
|
+
.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private pathFor(runId: string): string {
|
|
171
|
+
const safeRunId = runId.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
172
|
+
return path.join(this.baseDir, `${safeRunId}.json`);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private write(record: SubagentRunRecord): void {
|
|
176
|
+
fs.mkdirSync(this.baseDir, { recursive: true });
|
|
177
|
+
const filePath = this.pathFor(record.runId);
|
|
178
|
+
const tmpPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
179
|
+
fs.writeFileSync(tmpPath, `${JSON.stringify(record, null, 2)}\n`, "utf-8");
|
|
180
|
+
fs.renameSync(tmpPath, filePath);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export function createInitialRunRecord(input: {
|
|
185
|
+
runId: string;
|
|
186
|
+
mode: SubagentRunMode;
|
|
187
|
+
contextMode: "fresh" | "fork";
|
|
188
|
+
cwd: string;
|
|
189
|
+
children: Array<{ agent: string; trackingName?: string; task: string; cwd?: string }>;
|
|
190
|
+
now?: string;
|
|
191
|
+
}): SubagentRunRecord {
|
|
192
|
+
const now = input.now ?? new Date().toISOString();
|
|
193
|
+
return {
|
|
194
|
+
schemaVersion: 1,
|
|
195
|
+
runId: input.runId,
|
|
196
|
+
mode: input.mode,
|
|
197
|
+
contextMode: input.contextMode,
|
|
198
|
+
status: "running",
|
|
199
|
+
cwd: input.cwd,
|
|
200
|
+
startedAt: now,
|
|
201
|
+
updatedAt: now,
|
|
202
|
+
children: input.children.map((child, index) => ({
|
|
203
|
+
index,
|
|
204
|
+
agent: child.agent,
|
|
205
|
+
trackingName: child.trackingName,
|
|
206
|
+
task: child.task,
|
|
207
|
+
cwd: child.cwd,
|
|
208
|
+
status: "queued",
|
|
209
|
+
})),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export function deriveRunStatus(children: readonly SubagentChildArtifact[]): SubagentRunStatus {
|
|
214
|
+
if (children.some((child) => child.status === "interrupted")) return "interrupted";
|
|
215
|
+
if (children.some((child) => child.status === "failed")) return "failed";
|
|
216
|
+
if (children.length > 0 && children.every((child) => child.status === "succeeded")) return "succeeded";
|
|
217
|
+
return "running";
|
|
218
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// GSD-2 + Subagent launch module regression tests.
|
|
2
|
+
|
|
3
|
+
import assert from "node:assert/strict";
|
|
4
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { describe, it, afterEach } from "node:test";
|
|
8
|
+
|
|
9
|
+
import { SessionManager } from "@gsd/pi-coding-agent";
|
|
10
|
+
import subagentExtension from "../index.js";
|
|
11
|
+
import type { AgentConfig } from "../agents.js";
|
|
12
|
+
import {
|
|
13
|
+
SUBAGENT_CHILD_ENV_VAR,
|
|
14
|
+
SUBAGENT_CHILD_ENV_VALUE,
|
|
15
|
+
buildSubagentProcessEnv,
|
|
16
|
+
createSubagentLaunchPlan,
|
|
17
|
+
isSubagentChildProcess,
|
|
18
|
+
resolveSubagentSessionArgs,
|
|
19
|
+
} from "../launch.js";
|
|
20
|
+
|
|
21
|
+
function makeAgent(overrides: Partial<AgentConfig> = {}): AgentConfig {
|
|
22
|
+
return {
|
|
23
|
+
name: "test-agent",
|
|
24
|
+
description: "A test agent",
|
|
25
|
+
systemPrompt: "",
|
|
26
|
+
source: "project",
|
|
27
|
+
filePath: "test-agent.md",
|
|
28
|
+
tools: ["read", "write"],
|
|
29
|
+
...overrides,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function makeAssistantMessage() {
|
|
34
|
+
return {
|
|
35
|
+
role: "assistant",
|
|
36
|
+
content: [{ type: "text", text: "ok" }],
|
|
37
|
+
usage: {
|
|
38
|
+
input: 1,
|
|
39
|
+
output: 1,
|
|
40
|
+
cacheRead: 0,
|
|
41
|
+
cacheWrite: 0,
|
|
42
|
+
total: 2,
|
|
43
|
+
cost: { total: 0 },
|
|
44
|
+
},
|
|
45
|
+
} as any;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
describe("subagent launch module", () => {
|
|
49
|
+
let dir: string | undefined;
|
|
50
|
+
|
|
51
|
+
afterEach(() => {
|
|
52
|
+
if (dir) rmSync(dir, { recursive: true, force: true });
|
|
53
|
+
dir = undefined;
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("builds fresh child process args with child environment", () => {
|
|
57
|
+
const agent = makeAgent({ model: "local-model" });
|
|
58
|
+
const plan = createSubagentLaunchPlan({
|
|
59
|
+
agent,
|
|
60
|
+
task: "inspect the API",
|
|
61
|
+
tmpPromptPath: "/tmp/prompt.md",
|
|
62
|
+
defaultCwd: "/repo",
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
assert.ok(plan.args.includes("--no-session"));
|
|
66
|
+
assert.equal(plan.args.includes("--session"), false);
|
|
67
|
+
assert.equal(plan.env[SUBAGENT_CHILD_ENV_VAR], SUBAGENT_CHILD_ENV_VALUE);
|
|
68
|
+
assert.equal(plan.cwd, "/repo");
|
|
69
|
+
assert.deepEqual(plan.session, { mode: "fresh" });
|
|
70
|
+
assert.deepEqual(plan.args.slice(plan.args.indexOf("--tools"), plan.args.indexOf("--tools") + 2), ["--tools", "read,write"]);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("creates a real branched session for forked context", () => {
|
|
74
|
+
dir = mkdtempSync(join(tmpdir(), "gsd-subagent-launch-"));
|
|
75
|
+
const manager = SessionManager.create(dir, dir);
|
|
76
|
+
manager.appendMessage({ role: "user", content: [{ type: "text", text: "hello" }] } as any);
|
|
77
|
+
manager.appendMessage(makeAssistantMessage());
|
|
78
|
+
|
|
79
|
+
const session = resolveSubagentSessionArgs("fork", manager);
|
|
80
|
+
|
|
81
|
+
assert.equal(session.mode, "fork");
|
|
82
|
+
assert.ok(session.sessionFile);
|
|
83
|
+
assert.notEqual(session.sessionFile, manager.getSessionFile());
|
|
84
|
+
assert.equal(session.sessionDir, dir);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("fails forked context loudly without a persisted parent session", () => {
|
|
88
|
+
const manager = SessionManager.inMemory("/repo");
|
|
89
|
+
assert.throws(
|
|
90
|
+
() => resolveSubagentSessionArgs("fork", manager),
|
|
91
|
+
/persisted parent session file/,
|
|
92
|
+
);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("marks child env and suppresses recursive tool registration", () => {
|
|
96
|
+
const env = buildSubagentProcessEnv({});
|
|
97
|
+
assert.equal(isSubagentChildProcess(env), true);
|
|
98
|
+
|
|
99
|
+
const previous = process.env[SUBAGENT_CHILD_ENV_VAR];
|
|
100
|
+
process.env[SUBAGENT_CHILD_ENV_VAR] = SUBAGENT_CHILD_ENV_VALUE;
|
|
101
|
+
const calls: string[] = [];
|
|
102
|
+
try {
|
|
103
|
+
subagentExtension({
|
|
104
|
+
on: () => calls.push("on"),
|
|
105
|
+
registerCommand: () => calls.push("command"),
|
|
106
|
+
registerTool: () => calls.push("tool"),
|
|
107
|
+
} as any);
|
|
108
|
+
} finally {
|
|
109
|
+
if (previous === undefined) delete process.env[SUBAGENT_CHILD_ENV_VAR];
|
|
110
|
+
else process.env[SUBAGENT_CHILD_ENV_VAR] = previous;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
assert.deepEqual(calls, []);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// GSD-2 + Subagent durable run-store tests.
|
|
2
|
+
|
|
3
|
+
import assert from "node:assert/strict";
|
|
4
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { afterEach, describe, it } from "node:test";
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
SubagentRunStore,
|
|
11
|
+
createInitialRunRecord,
|
|
12
|
+
createSubagentTrackingName,
|
|
13
|
+
deriveRunStatus,
|
|
14
|
+
} from "../run-store.js";
|
|
15
|
+
|
|
16
|
+
describe("SubagentRunStore", () => {
|
|
17
|
+
let dir: string | undefined;
|
|
18
|
+
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
if (dir) rmSync(dir, { recursive: true, force: true });
|
|
21
|
+
dir = undefined;
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("persists launch and successful completion evidence", () => {
|
|
25
|
+
dir = mkdtempSync(join(tmpdir(), "gsd-subagent-runs-"));
|
|
26
|
+
const store = new SubagentRunStore(dir);
|
|
27
|
+
store.create(createInitialRunRecord({
|
|
28
|
+
runId: "run-1",
|
|
29
|
+
mode: "single",
|
|
30
|
+
contextMode: "fresh",
|
|
31
|
+
cwd: "/repo",
|
|
32
|
+
children: [{ agent: "scout", trackingName: "clear-beacon", task: "inspect" }],
|
|
33
|
+
now: "2026-01-01T00:00:00.000Z",
|
|
34
|
+
}));
|
|
35
|
+
|
|
36
|
+
store.update("run-1", (record) => ({
|
|
37
|
+
...record,
|
|
38
|
+
status: "succeeded",
|
|
39
|
+
completedAt: "2026-01-01T00:00:01.000Z",
|
|
40
|
+
children: [{
|
|
41
|
+
...record.children[0],
|
|
42
|
+
status: "succeeded",
|
|
43
|
+
exitCode: 0,
|
|
44
|
+
output: "done",
|
|
45
|
+
}],
|
|
46
|
+
}));
|
|
47
|
+
|
|
48
|
+
const loaded = store.get("run-1");
|
|
49
|
+
assert.equal(loaded?.status, "succeeded");
|
|
50
|
+
assert.equal(loaded?.children[0]?.trackingName, "clear-beacon");
|
|
51
|
+
assert.equal(loaded?.children[0]?.output, "done");
|
|
52
|
+
assert.equal(store.list()[0]?.runId, "run-1");
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("generates unique tracking names for child agents", () => {
|
|
56
|
+
const names = new Set<string>();
|
|
57
|
+
for (let i = 0; i < 24; i++) {
|
|
58
|
+
const name = createSubagentTrackingName(names);
|
|
59
|
+
assert.match(name, /^[a-z]+-[a-z]+$|^agent-\d+$/);
|
|
60
|
+
assert.equal(names.has(name), false);
|
|
61
|
+
names.add(name);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("persists failed and interrupted child evidence", () => {
|
|
66
|
+
dir = mkdtempSync(join(tmpdir(), "gsd-subagent-runs-"));
|
|
67
|
+
const store = new SubagentRunStore(dir);
|
|
68
|
+
store.create(createInitialRunRecord({
|
|
69
|
+
runId: "run-2",
|
|
70
|
+
mode: "parallel",
|
|
71
|
+
contextMode: "fork",
|
|
72
|
+
cwd: "/repo",
|
|
73
|
+
children: [
|
|
74
|
+
{ agent: "tester", task: "verify" },
|
|
75
|
+
{ agent: "reviewer", task: "review" },
|
|
76
|
+
],
|
|
77
|
+
}));
|
|
78
|
+
|
|
79
|
+
store.update("run-2", (record) => ({
|
|
80
|
+
...record,
|
|
81
|
+
status: "interrupted",
|
|
82
|
+
children: [
|
|
83
|
+
{
|
|
84
|
+
...record.children[0],
|
|
85
|
+
status: "failed",
|
|
86
|
+
exitCode: 1,
|
|
87
|
+
errorMessage: "verification failed",
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
...record.children[1],
|
|
91
|
+
status: "interrupted",
|
|
92
|
+
exitCode: 1,
|
|
93
|
+
stopReason: "aborted",
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
failure: { type: "interrupted", message: "run aborted" },
|
|
97
|
+
}));
|
|
98
|
+
|
|
99
|
+
const loaded = store.get("run-2");
|
|
100
|
+
assert.equal(loaded?.status, "interrupted");
|
|
101
|
+
assert.equal(loaded?.children[0]?.errorMessage, "verification failed");
|
|
102
|
+
assert.equal(loaded?.children[1]?.stopReason, "aborted");
|
|
103
|
+
assert.equal(loaded?.failure?.type, "interrupted");
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("derives failed and interrupted status from child artifacts", () => {
|
|
107
|
+
assert.equal(deriveRunStatus([{ index: 0, agent: "a", task: "t", status: "failed" }]), "failed");
|
|
108
|
+
assert.equal(deriveRunStatus([{ index: 0, agent: "a", task: "t", status: "interrupted" }]), "interrupted");
|
|
109
|
+
assert.equal(deriveRunStatus([{ index: 0, agent: "a", task: "t", status: "succeeded" }]), "succeeded");
|
|
110
|
+
});
|
|
111
|
+
});
|
|
@@ -109,6 +109,7 @@ const MAX_BUFFER_BYTES = 512 * 1024;
|
|
|
109
109
|
* Prevents CPU spinning when deltas arrive faster than regex evaluation (#468).
|
|
110
110
|
*/
|
|
111
111
|
const JS_FALLBACK_CHECK_INTERVAL_MS = 50;
|
|
112
|
+
const JS_FALLBACK_THROTTLE_MIN_BUFFER_BYTES = 4 * 1024;
|
|
112
113
|
|
|
113
114
|
const DEFAULT_SCOPE: TtsrScope = {
|
|
114
115
|
allowText: true,
|
|
@@ -383,7 +384,10 @@ export class TtsrManager {
|
|
|
383
384
|
// streams — regex on a growing buffer is O(rules × buffer_size) (#468).
|
|
384
385
|
const now = Date.now();
|
|
385
386
|
const lastCheck = this.#lastJsCheckAt.get(bufferKey) ?? 0;
|
|
386
|
-
if (
|
|
387
|
+
if (
|
|
388
|
+
nextBuffer.length >= JS_FALLBACK_THROTTLE_MIN_BUFFER_BYTES &&
|
|
389
|
+
now - lastCheck < JS_FALLBACK_CHECK_INTERVAL_MS
|
|
390
|
+
) {
|
|
387
391
|
stopTimer({ bufferSize: nextBuffer.length, throttled: true });
|
|
388
392
|
return [];
|
|
389
393
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// GSD-2 + Visual Brief artifact policy
|
|
2
|
+
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { getAgentDir } from "@gsd/pi-coding-agent";
|
|
5
|
+
|
|
6
|
+
export interface VisualBriefArtifactPolicy {
|
|
7
|
+
outputDir: string;
|
|
8
|
+
filenameStyle: string;
|
|
9
|
+
fileShape: string;
|
|
10
|
+
openers: readonly string[];
|
|
11
|
+
failureBehavior: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function getVisualBriefOutputDir(agentDir: string = getAgentDir()): string {
|
|
15
|
+
return join(agentDir, "diagrams");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function createVisualBriefArtifactPolicy(outputDir: string): VisualBriefArtifactPolicy {
|
|
19
|
+
return {
|
|
20
|
+
outputDir,
|
|
21
|
+
filenameStyle: "Use a descriptive kebab-case filename ending in .html.",
|
|
22
|
+
fileShape: "Produce one self-contained responsive HTML file with embedded CSS and minimal JavaScript.",
|
|
23
|
+
openers: [
|
|
24
|
+
"macOS: open",
|
|
25
|
+
"Linux: xdg-open",
|
|
26
|
+
"Windows: cmd /c start",
|
|
27
|
+
],
|
|
28
|
+
failureBehavior: "If opening fails, report the absolute file path.",
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function formatArtifactPolicy(policy: VisualBriefArtifactPolicy): string {
|
|
33
|
+
return [
|
|
34
|
+
`- Create the output directory if it does not exist: ${policy.outputDir}`,
|
|
35
|
+
`- ${policy.filenameStyle}`,
|
|
36
|
+
`- ${policy.fileShape}`,
|
|
37
|
+
"- Open the result in a browser when the local platform has an opener available.",
|
|
38
|
+
...policy.openers.map((opener) => ` - ${opener}`),
|
|
39
|
+
`- ${policy.failureBehavior}`,
|
|
40
|
+
].join("\n");
|
|
41
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// GSD-2 + Visual Brief bundled extension marker
|
|
2
|
+
|
|
3
|
+
import type { ExtensionAPI } from "@gsd/pi-coding-agent";
|
|
4
|
+
|
|
5
|
+
export default function visualBrief(_pi: ExtensionAPI) {
|
|
6
|
+
// Visual Brief is invoked through /gsd brief. This module keeps the bundled
|
|
7
|
+
// extension discoverable without adding a second top-level slash command.
|
|
8
|
+
}
|