gsd-pi 2.57.0 → 2.58.0-dev.778d6ac
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 +1 -1
- package/dist/cli.js +49 -35
- package/dist/headless-ui.d.ts +17 -0
- package/dist/headless-ui.js +97 -3
- package/dist/headless.js +67 -6
- package/dist/help-text.js +1 -0
- package/dist/onboarding.js +44 -0
- package/dist/resource-loader.js +16 -1
- package/dist/resources/agents/researcher.md +1 -1
- package/dist/resources/extensions/ask-user-questions.js +16 -3
- package/dist/resources/extensions/async-jobs/extension-manifest.json +1 -1
- package/dist/resources/extensions/bg-shell/extension-manifest.json +1 -1
- package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +14 -6
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +59 -36
- package/dist/resources/extensions/context7/extension-manifest.json +1 -1
- package/dist/resources/extensions/get-secrets-from-user.js +8 -5
- package/dist/resources/extensions/google-search/extension-manifest.json +1 -1
- package/dist/resources/extensions/google-search/index.js +2 -1
- package/dist/resources/extensions/gsd/auto/infra-errors.js +4 -0
- package/dist/resources/extensions/gsd/auto/phases.js +25 -21
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
- package/dist/resources/extensions/gsd/auto-dashboard.js +37 -20
- package/dist/resources/extensions/gsd/auto-dispatch.js +20 -5
- package/dist/resources/extensions/gsd/auto-model-selection.js +26 -3
- package/dist/resources/extensions/gsd/auto-post-unit.js +16 -4
- package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
- package/dist/resources/extensions/gsd/auto-recovery.js +13 -5
- package/dist/resources/extensions/gsd/auto-start.js +35 -22
- package/dist/resources/extensions/gsd/auto-worktree.js +203 -14
- package/dist/resources/extensions/gsd/auto.js +4 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +82 -9
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -18
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +44 -11
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -0
- package/dist/resources/extensions/gsd/captures.js +56 -4
- package/dist/resources/extensions/gsd/db-writer.js +116 -8
- package/dist/resources/extensions/gsd/dispatch-guard.js +11 -1
- package/dist/resources/extensions/gsd/doctor-git-checks.js +28 -0
- package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +5 -4
- package/dist/resources/extensions/gsd/doctor.js +3 -1
- package/dist/resources/extensions/gsd/error-classifier.js +13 -10
- package/dist/resources/extensions/gsd/extension-manifest.json +16 -1
- package/dist/resources/extensions/gsd/forensics.js +123 -20
- package/dist/resources/extensions/gsd/git-service.js +23 -1
- package/dist/resources/extensions/gsd/gitignore.js +33 -0
- package/dist/resources/extensions/gsd/gsd-db.js +44 -10
- package/dist/resources/extensions/gsd/guided-flow.js +106 -44
- package/dist/resources/extensions/gsd/health-widget-core.js +31 -0
- package/dist/resources/extensions/gsd/health-widget.js +17 -0
- package/dist/resources/extensions/gsd/index.js +1 -1
- package/dist/resources/extensions/gsd/memory-extractor.js +7 -0
- package/dist/resources/extensions/gsd/migrate-external.js +8 -1
- package/dist/resources/extensions/gsd/milestone-validation-gates.js +45 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +18 -0
- package/dist/resources/extensions/gsd/model-router.js +35 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +17 -0
- package/dist/resources/extensions/gsd/notifications.js +16 -1
- package/dist/resources/extensions/gsd/parallel-eligibility.js +13 -2
- package/dist/resources/extensions/gsd/parallel-merge.js +78 -5
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +23 -6
- package/dist/resources/extensions/gsd/parsers-legacy.js +20 -3
- package/dist/resources/extensions/gsd/paths.js +43 -0
- package/dist/resources/extensions/gsd/preferences-models.js +14 -1
- package/dist/resources/extensions/gsd/preferences-types.js +2 -1
- package/dist/resources/extensions/gsd/preferences.js +42 -31
- package/dist/resources/extensions/gsd/prompt-loader.js +4 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -2
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -1
- package/dist/resources/extensions/gsd/prompts/forensics.md +2 -2
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -0
- package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -0
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/dist/resources/extensions/gsd/repo-identity.js +205 -11
- package/dist/resources/extensions/gsd/rethink.js +5 -0
- package/dist/resources/extensions/gsd/roadmap-slices.js +5 -4
- package/dist/resources/extensions/gsd/state.js +85 -27
- package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
- package/dist/resources/extensions/gsd/tools/complete-task.js +34 -71
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +12 -2
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +29 -1
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +18 -3
- package/dist/resources/extensions/gsd/triage-resolution.js +22 -7
- package/dist/resources/extensions/gsd/undo.js +2 -2
- package/dist/resources/extensions/gsd/unit-ownership.js +164 -33
- package/dist/resources/extensions/gsd/verdict-parser.js +20 -8
- package/dist/resources/extensions/gsd/workflow-manifest.js +24 -5
- package/dist/resources/extensions/gsd/workflow-projections.js +95 -63
- package/dist/resources/extensions/gsd/workflow-reconcile.js +35 -5
- package/dist/resources/extensions/gsd/workspace-index.js +24 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +105 -1
- package/dist/resources/extensions/gsd/worktree-resolver.js +20 -3
- package/dist/resources/extensions/mcp-client/index.js +11 -7
- package/dist/resources/extensions/ollama/index.js +112 -0
- package/dist/resources/extensions/ollama/model-capabilities.js +115 -0
- package/dist/resources/extensions/ollama/ollama-client.js +168 -0
- package/dist/resources/extensions/ollama/ollama-commands.js +194 -0
- package/dist/resources/extensions/ollama/ollama-discovery.js +69 -0
- package/dist/resources/extensions/ollama/ollama-tool.js +184 -0
- package/dist/resources/extensions/ollama/types.js +2 -0
- package/dist/resources/extensions/search-the-web/extension-manifest.json +1 -1
- package/dist/resources/extensions/shared/interview-ui.js +11 -1
- package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -3
- package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
- package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
- package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
- package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
- package/dist/startup-model-validation.d.ts +39 -0
- package/dist/startup-model-validation.js +50 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- 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/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 +2 -2
- 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_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 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
- 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 -4
- 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 -2
- 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/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 +2 -2
- 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 +2 -2
- 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 +4 -4
- 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 -5
- 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 -5
- 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 -4
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
- package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
- package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
- 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 +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +9 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-4332cbd5dd1be584.js → webpack-a1c1e452c6b32d04.js} +1 -1
- package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.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/dist/web-mode.js +2 -1
- package/package.json +2 -2
- package/packages/daemon/src/cli.ts +49 -0
- package/packages/daemon/src/daemon.test.ts +104 -1
- package/packages/daemon/src/daemon.ts +24 -1
- package/packages/daemon/src/discord-bot.ts +73 -3
- package/packages/daemon/src/event-bridge.ts +15 -9
- package/packages/daemon/src/event-formatter.ts +30 -2
- package/packages/daemon/src/index.ts +9 -0
- package/packages/daemon/src/launchd.test.ts +356 -0
- package/packages/daemon/src/launchd.ts +242 -0
- package/packages/daemon/src/message-batcher.test.ts +2 -2
- package/packages/daemon/src/message-batcher.ts +9 -3
- package/packages/daemon/src/orchestrator.test.ts +1 -0
- package/packages/daemon/src/orchestrator.ts +106 -2
- package/packages/native/dist/ast/index.js +9 -5
- package/packages/native/dist/ast/types.js +2 -1
- package/packages/native/dist/clipboard/index.js +12 -7
- package/packages/native/dist/clipboard/types.js +2 -1
- package/packages/native/dist/diff/index.js +12 -7
- package/packages/native/dist/diff/types.js +2 -1
- package/packages/native/dist/fd/index.js +6 -3
- package/packages/native/dist/fd/types.js +2 -1
- package/packages/native/dist/glob/index.js +9 -5
- package/packages/native/dist/glob/types.js +2 -1
- package/packages/native/dist/grep/index.js +9 -5
- package/packages/native/dist/grep/types.js +2 -1
- package/packages/native/dist/gsd-parser/index.js +18 -11
- package/packages/native/dist/gsd-parser/types.js +2 -1
- package/packages/native/dist/highlight/index.js +12 -7
- package/packages/native/dist/highlight/types.js +2 -1
- package/packages/native/dist/html/index.js +6 -3
- package/packages/native/dist/html/types.js +2 -1
- package/packages/native/dist/image/index.js +10 -5
- package/packages/native/dist/image/types.js +7 -4
- package/packages/native/dist/index.js +70 -17
- package/packages/native/dist/json-parse/index.js +13 -8
- package/packages/native/dist/native.js +47 -10
- package/packages/native/dist/ps/index.js +15 -9
- package/packages/native/dist/ps/types.js +2 -1
- package/packages/native/dist/stream-process/index.js +12 -7
- package/packages/native/dist/text/index.js +24 -14
- package/packages/native/dist/text/types.js +5 -2
- package/packages/native/dist/truncate/index.js +12 -7
- package/packages/native/dist/ttsr/index.js +12 -7
- package/packages/native/dist/ttsr/types.js +2 -1
- package/packages/native/dist/xxhash/index.js +9 -5
- package/packages/native/package.json +19 -19
- package/packages/native/src/__tests__/module-compat.test.mjs +91 -0
- package/packages/native/src/native.ts +9 -8
- package/packages/pi-agent-core/dist/agent-loop.js +3 -2
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/proxy.d.ts +1 -1
- package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/proxy.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +45 -0
- package/packages/pi-agent-core/src/agent-loop.ts +3 -2
- package/packages/pi-agent-core/src/proxy.ts +1 -1
- package/packages/pi-ai/dist/env-api-keys.js +1 -0
- package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
- package/packages/pi-ai/dist/index.d.ts +1 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -0
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +19 -2
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js +25 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -0
- package/packages/pi-ai/dist/types.d.ts +3 -3
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.d.ts +3 -0
- package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.js +24 -1
- package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
- package/packages/pi-ai/dist/utils/repair-tool-json.d.ts +37 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.js +75 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +73 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -0
- package/packages/pi-ai/src/env-api-keys.ts +1 -0
- package/packages/pi-ai/src/index.ts +1 -0
- package/packages/pi-ai/src/providers/anthropic-shared.test.ts +29 -0
- package/packages/pi-ai/src/providers/anthropic-shared.ts +17 -2
- package/packages/pi-ai/src/types.ts +3 -2
- package/packages/pi-ai/src/utils/json-parse.ts +28 -1
- package/packages/pi-ai/src/utils/repair-tool-json.ts +88 -0
- package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +102 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +31 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +17 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +62 -2
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +176 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/exec.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/exec.js +3 -1
- package/packages/pi-coding-agent/dist/core/exec.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts +28 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js +37 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js +63 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts +19 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js +115 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js +109 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.js +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +5 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts +44 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js +97 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js +181 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/index.js +1 -1
- package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/index.js +3 -0
- package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -0
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.js +31 -2
- package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.test.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/messages.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/messages.test.js +86 -0
- package/packages/pi-coding-agent/dist/core/messages.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +10 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +12 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +48 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +193 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +10 -3
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js +13 -4
- package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts +16 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +80 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts +2 -2
- 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/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js +5 -0
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +38 -1
- package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +236 -0
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +94 -1
- package/packages/pi-coding-agent/src/core/exec.ts +3 -1
- package/packages/pi-coding-agent/src/core/extensions/extension-manifest.test.ts +77 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-manifest.ts +62 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-sort.test.ts +134 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-sort.ts +137 -0
- package/packages/pi-coding-agent/src/core/extensions/index.ts +4 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
- package/packages/pi-coding-agent/src/core/image-overflow-recovery.test.ts +228 -0
- package/packages/pi-coding-agent/src/core/image-overflow-recovery.ts +118 -0
- package/packages/pi-coding-agent/src/core/index.ts +6 -0
- package/packages/pi-coding-agent/src/core/lsp/index.ts +3 -0
- package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -0
- package/packages/pi-coding-agent/src/core/messages.test.ts +114 -0
- package/packages/pi-coding-agent/src/core/messages.ts +29 -2
- package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
- package/packages/pi-coding-agent/src/core/resource-loader.ts +20 -1
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +255 -0
- package/packages/pi-coding-agent/src/core/retry-handler.ts +52 -1
- package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +11 -3
- package/packages/pi-coding-agent/src/core/tools/read.ts +14 -4
- package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +92 -0
- package/packages/pi-coding-agent/src/index.ts +6 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +7 -0
- package/packages/pi-coding-agent/src/modes/rpc/remote-terminal.ts +6 -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 +9 -0
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- 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/src/terminal.ts +14 -0
- package/packages/pi-tui/src/tui.ts +8 -0
- package/pkg/package.json +1 -1
- package/scripts/ensure-workspace-builds.cjs +45 -14
- package/src/resources/agents/researcher.md +1 -1
- package/src/resources/extensions/ask-user-questions.ts +21 -3
- package/src/resources/extensions/async-jobs/extension-manifest.json +1 -1
- package/src/resources/extensions/bg-shell/extension-manifest.json +1 -1
- package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +13 -6
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +63 -35
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +28 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -1
- package/src/resources/extensions/context7/extension-manifest.json +1 -1
- package/src/resources/extensions/get-secrets-from-user.ts +8 -5
- package/src/resources/extensions/google-search/extension-manifest.json +1 -1
- package/src/resources/extensions/google-search/index.ts +2 -1
- package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/phases.ts +43 -34
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
- package/src/resources/extensions/gsd/auto-dashboard.ts +37 -19
- package/src/resources/extensions/gsd/auto-dispatch.ts +21 -5
- package/src/resources/extensions/gsd/auto-model-selection.ts +26 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
- package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +12 -5
- package/src/resources/extensions/gsd/auto-start.ts +35 -26
- package/src/resources/extensions/gsd/auto-worktree.ts +197 -11
- package/src/resources/extensions/gsd/auto.ts +5 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +31 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +87 -9
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +38 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +31 -19
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +50 -11
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +75 -0
- package/src/resources/extensions/gsd/captures.ts +63 -3
- package/src/resources/extensions/gsd/db-writer.ts +140 -7
- package/src/resources/extensions/gsd/dispatch-guard.ts +12 -1
- package/src/resources/extensions/gsd/doctor-git-checks.ts +26 -0
- package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +5 -4
- package/src/resources/extensions/gsd/doctor.ts +3 -1
- package/src/resources/extensions/gsd/error-classifier.ts +14 -11
- package/src/resources/extensions/gsd/extension-manifest.json +16 -1
- package/src/resources/extensions/gsd/forensics.ts +144 -20
- package/src/resources/extensions/gsd/git-service.ts +26 -3
- package/src/resources/extensions/gsd/gitignore.ts +33 -0
- package/src/resources/extensions/gsd/gsd-db.ts +49 -8
- package/src/resources/extensions/gsd/guided-flow.ts +114 -45
- package/src/resources/extensions/gsd/health-widget-core.ts +34 -0
- package/src/resources/extensions/gsd/health-widget.ts +17 -0
- package/src/resources/extensions/gsd/index.ts +1 -0
- package/src/resources/extensions/gsd/memory-extractor.ts +8 -0
- package/src/resources/extensions/gsd/migrate-external.ts +9 -1
- package/src/resources/extensions/gsd/milestone-validation-gates.ts +56 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +19 -0
- package/src/resources/extensions/gsd/model-router.ts +35 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +17 -0
- package/src/resources/extensions/gsd/notifications.ts +16 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +15 -2
- package/src/resources/extensions/gsd/parallel-merge.ts +87 -4
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +23 -6
- package/src/resources/extensions/gsd/parsers-legacy.ts +22 -3
- package/src/resources/extensions/gsd/paths.ts +42 -0
- package/src/resources/extensions/gsd/preferences-models.ts +14 -1
- package/src/resources/extensions/gsd/preferences-types.ts +2 -1
- package/src/resources/extensions/gsd/preferences.ts +45 -29
- package/src/resources/extensions/gsd/prompt-loader.ts +4 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -2
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/src/resources/extensions/gsd/prompts/execute-task.md +3 -1
- package/src/resources/extensions/gsd/prompts/forensics.md +2 -2
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -0
- package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
- package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -0
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/src/resources/extensions/gsd/repo-identity.ts +186 -11
- package/src/resources/extensions/gsd/rethink.ts +6 -0
- package/src/resources/extensions/gsd/roadmap-slices.ts +5 -4
- package/src/resources/extensions/gsd/state.ts +84 -32
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +71 -1
- package/src/resources/extensions/gsd/tests/captures.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/completion-hierarchy-guards.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +131 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +7 -12
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +78 -5
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +129 -0
- package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +96 -0
- package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +125 -12
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +164 -0
- package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +135 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +111 -1
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-false-positives.test.ts +243 -0
- package/src/resources/extensions/gsd/tests/integration/gitignore-staging-2570.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +959 -0
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +85 -2
- package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/model-router.test.ts +68 -3
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/notifications.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +159 -0
- package/src/resources/extensions/gsd/tests/parallel-eligibility-ghost.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +9 -8
- package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/preferences.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +297 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/prompt-loader-replacement.test.ts +178 -0
- package/src/resources/extensions/gsd/tests/prompt-tool-names.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/reconciliation-edge-cases.test.ts +162 -0
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +134 -0
- package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +233 -0
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +305 -0
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +405 -0
- package/src/resources/extensions/gsd/tests/state-derivation-parity.test.ts +257 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +1628 -0
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +174 -0
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +221 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +289 -0
- package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +100 -17
- package/src/resources/extensions/gsd/tests/vacuum-recovery.test.ts +154 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +27 -2
- package/src/resources/extensions/gsd/tests/validation-gate-patterns.test.ts +44 -2
- package/src/resources/extensions/gsd/tests/verdict-parser.test.ts +156 -0
- package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +82 -0
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +175 -0
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +48 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +95 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +36 -74
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +13 -1
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +36 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -2
- package/src/resources/extensions/gsd/triage-resolution.ts +23 -6
- package/src/resources/extensions/gsd/types.ts +4 -2
- package/src/resources/extensions/gsd/undo.ts +2 -2
- package/src/resources/extensions/gsd/unit-ownership.ts +206 -35
- package/src/resources/extensions/gsd/verdict-parser.ts +21 -6
- package/src/resources/extensions/gsd/workflow-logger.ts +3 -1
- package/src/resources/extensions/gsd/workflow-manifest.ts +22 -5
- package/src/resources/extensions/gsd/workflow-projections.ts +97 -64
- package/src/resources/extensions/gsd/workflow-reconcile.ts +39 -10
- package/src/resources/extensions/gsd/workspace-index.ts +30 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +120 -1
- package/src/resources/extensions/gsd/worktree-resolver.ts +22 -3
- package/src/resources/extensions/mcp-client/index.ts +13 -7
- package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +55 -0
- package/src/resources/extensions/ollama/index.ts +130 -0
- package/src/resources/extensions/ollama/model-capabilities.ts +145 -0
- package/src/resources/extensions/ollama/ollama-client.ts +196 -0
- package/src/resources/extensions/ollama/ollama-commands.ts +248 -0
- package/src/resources/extensions/ollama/ollama-discovery.ts +106 -0
- package/src/resources/extensions/ollama/ollama-tool.ts +218 -0
- package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +162 -0
- package/src/resources/extensions/ollama/tests/ollama-client.test.ts +38 -0
- package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +28 -0
- package/src/resources/extensions/ollama/types.ts +130 -0
- package/src/resources/extensions/search-the-web/extension-manifest.json +1 -1
- package/src/resources/extensions/shared/interview-ui.ts +12 -1
- package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +156 -0
- package/src/resources/skills/create-gsd-extension/SKILL.md +5 -3
- package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
- package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
- package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
- package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
- package/dist/web/standalone/.next/static/chunks/6502.2305d0afd2385711.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +0 -1
- package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +0 -79
- /package/dist/web/standalone/.next/static/{yowc5qPtuKxjOr22KmOAy → R0D4xaIPl5kg93edN7Oo0}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{yowc5qPtuKxjOr22KmOAy → R0D4xaIPl5kg93edN7Oo0}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* parallel-commit-scope.test.ts — Regression test for #1991.
|
|
3
|
+
*
|
|
4
|
+
* Parallel workers must only commit files belonging to their locked milestone.
|
|
5
|
+
* When GSD_MILESTONE_LOCK is set, smartStage() must exclude .gsd/milestones/<M>/
|
|
6
|
+
* directories for milestones other than the locked one.
|
|
7
|
+
*
|
|
8
|
+
* Without the fix, a worker for M033 can stage and commit fabricated artifacts
|
|
9
|
+
* under .gsd/milestones/M032/, causing cross-milestone pollution.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { describe, test, beforeEach, afterEach } from "node:test";
|
|
13
|
+
import assert from "node:assert/strict";
|
|
14
|
+
import {
|
|
15
|
+
mkdtempSync,
|
|
16
|
+
mkdirSync,
|
|
17
|
+
writeFileSync,
|
|
18
|
+
rmSync,
|
|
19
|
+
} from "node:fs";
|
|
20
|
+
import { join } from "node:path";
|
|
21
|
+
import { tmpdir } from "node:os";
|
|
22
|
+
import { execFileSync } from "node:child_process";
|
|
23
|
+
|
|
24
|
+
import {
|
|
25
|
+
GitServiceImpl,
|
|
26
|
+
} from "../git-service.ts";
|
|
27
|
+
|
|
28
|
+
function run(command: string, cwd: string): string {
|
|
29
|
+
const [cmd, ...args] = command.split(" ");
|
|
30
|
+
return execFileSync(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function gitRun(args: string[], cwd: string): string {
|
|
34
|
+
return execFileSync("git", args, { cwd, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function createFile(base: string, relPath: string, content: string): void {
|
|
38
|
+
const full = join(base, relPath);
|
|
39
|
+
mkdirSync(join(full, ".."), { recursive: true });
|
|
40
|
+
writeFileSync(full, content, "utf-8");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function initTempRepo(): string {
|
|
44
|
+
const dir = mkdtempSync(join(tmpdir(), "gsd-parallel-scope-"));
|
|
45
|
+
gitRun(["init", "-b", "main"], dir);
|
|
46
|
+
gitRun(["config", "user.name", "Test"], dir);
|
|
47
|
+
gitRun(["config", "user.email", "test@test.com"], dir);
|
|
48
|
+
createFile(dir, ".gitkeep", "");
|
|
49
|
+
gitRun(["add", "-A"], dir);
|
|
50
|
+
gitRun(["commit", "-m", "init"], dir);
|
|
51
|
+
return dir;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
describe("parallel commit scope (#1991)", () => {
|
|
55
|
+
const savedEnv: Record<string, string | undefined> = {};
|
|
56
|
+
|
|
57
|
+
beforeEach(() => {
|
|
58
|
+
savedEnv.GSD_MILESTONE_LOCK = process.env.GSD_MILESTONE_LOCK;
|
|
59
|
+
savedEnv.GSD_PARALLEL_WORKER = process.env.GSD_PARALLEL_WORKER;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
afterEach(() => {
|
|
63
|
+
for (const key of ["GSD_MILESTONE_LOCK", "GSD_PARALLEL_WORKER"] as const) {
|
|
64
|
+
if (savedEnv[key] === undefined) {
|
|
65
|
+
delete process.env[key];
|
|
66
|
+
} else {
|
|
67
|
+
process.env[key] = savedEnv[key];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("autoCommit excludes other milestone directories when GSD_MILESTONE_LOCK is set", () => {
|
|
73
|
+
const repo = initTempRepo();
|
|
74
|
+
|
|
75
|
+
// Set up parallel worker environment for M033
|
|
76
|
+
process.env.GSD_MILESTONE_LOCK = "M033";
|
|
77
|
+
process.env.GSD_PARALLEL_WORKER = "1";
|
|
78
|
+
|
|
79
|
+
// Create dirty files in BOTH milestones (simulates cross-milestone pollution)
|
|
80
|
+
createFile(repo, ".gsd/milestones/M032/M032-SUMMARY.md", "# M032 Summary\nFabricated by M033 worker");
|
|
81
|
+
createFile(repo, ".gsd/milestones/M032/M032-VALIDATION.md", "# M032 Validation\nFabricated");
|
|
82
|
+
createFile(repo, ".gsd/milestones/M032/slices/S01/S01-SUMMARY.md", "Fabricated S01 summary");
|
|
83
|
+
createFile(repo, ".gsd/milestones/M033/slices/S01/tasks/T01-SUMMARY.md", "Legit T01 summary");
|
|
84
|
+
createFile(repo, "src/feature.ts", "export const x = 1;");
|
|
85
|
+
|
|
86
|
+
const svc = new GitServiceImpl(repo);
|
|
87
|
+
const msg = svc.autoCommit("complete-milestone", "M033/complete");
|
|
88
|
+
assert.ok(msg !== null, "autoCommit should produce a commit");
|
|
89
|
+
|
|
90
|
+
const committed = gitRun(["show", "--name-only", "HEAD"], repo);
|
|
91
|
+
|
|
92
|
+
// Source files and own milestone files SHOULD be committed
|
|
93
|
+
assert.ok(committed.includes("src/feature.ts"), "source files are committed");
|
|
94
|
+
assert.ok(committed.includes(".gsd/milestones/M033/"), "own milestone files are committed");
|
|
95
|
+
|
|
96
|
+
// Other milestone files MUST NOT be committed
|
|
97
|
+
assert.ok(!committed.includes(".gsd/milestones/M032/"),
|
|
98
|
+
"M032 files must NOT be committed by M033 worker — cross-milestone pollution (#1991)");
|
|
99
|
+
|
|
100
|
+
// Verify M032 files are still dirty (unstaged) in the working tree
|
|
101
|
+
const status = gitRun(["status", "--porcelain"], repo);
|
|
102
|
+
assert.ok(status.includes("M032"), "M032 files remain as untracked/dirty in working tree");
|
|
103
|
+
|
|
104
|
+
rmSync(repo, { recursive: true, force: true });
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test("autoCommit stages all milestones when GSD_MILESTONE_LOCK is NOT set (solo mode)", () => {
|
|
108
|
+
const repo = initTempRepo();
|
|
109
|
+
|
|
110
|
+
// No milestone lock — solo worker mode
|
|
111
|
+
delete process.env.GSD_MILESTONE_LOCK;
|
|
112
|
+
delete process.env.GSD_PARALLEL_WORKER;
|
|
113
|
+
|
|
114
|
+
createFile(repo, ".gsd/milestones/M032/M032-SUMMARY.md", "# M032 Summary");
|
|
115
|
+
createFile(repo, ".gsd/milestones/M033/slices/S01/tasks/T01-SUMMARY.md", "T01 summary");
|
|
116
|
+
createFile(repo, "src/feature.ts", "export const x = 1;");
|
|
117
|
+
|
|
118
|
+
const svc = new GitServiceImpl(repo);
|
|
119
|
+
const msg = svc.autoCommit("complete-milestone", "M032/complete");
|
|
120
|
+
assert.ok(msg !== null, "autoCommit should produce a commit");
|
|
121
|
+
|
|
122
|
+
const committed = gitRun(["show", "--name-only", "HEAD"], repo);
|
|
123
|
+
|
|
124
|
+
// In solo mode, ALL milestone files should be committed
|
|
125
|
+
assert.ok(committed.includes(".gsd/milestones/M032/"), "M032 files committed in solo mode");
|
|
126
|
+
assert.ok(committed.includes(".gsd/milestones/M033/"), "M033 files committed in solo mode");
|
|
127
|
+
assert.ok(committed.includes("src/feature.ts"), "source files committed in solo mode");
|
|
128
|
+
|
|
129
|
+
rmSync(repo, { recursive: true, force: true });
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test("autoCommit scopes to locked milestone even with multiple foreign milestones", () => {
|
|
133
|
+
const repo = initTempRepo();
|
|
134
|
+
|
|
135
|
+
process.env.GSD_MILESTONE_LOCK = "M035";
|
|
136
|
+
process.env.GSD_PARALLEL_WORKER = "1";
|
|
137
|
+
|
|
138
|
+
// Create files across many milestones
|
|
139
|
+
createFile(repo, ".gsd/milestones/M032/M032-SUMMARY.md", "foreign");
|
|
140
|
+
createFile(repo, ".gsd/milestones/M033/M033-SUMMARY.md", "foreign");
|
|
141
|
+
createFile(repo, ".gsd/milestones/M034/M034-SUMMARY.md", "foreign");
|
|
142
|
+
createFile(repo, ".gsd/milestones/M035/slices/S01/tasks/T01-SUMMARY.md", "own work");
|
|
143
|
+
createFile(repo, "src/app.ts", "export const app = {};");
|
|
144
|
+
|
|
145
|
+
const svc = new GitServiceImpl(repo);
|
|
146
|
+
const msg = svc.autoCommit("execute-task", "M035/S01/T01");
|
|
147
|
+
assert.ok(msg !== null, "autoCommit should produce a commit");
|
|
148
|
+
|
|
149
|
+
const committed = gitRun(["show", "--name-only", "HEAD"], repo);
|
|
150
|
+
|
|
151
|
+
assert.ok(committed.includes(".gsd/milestones/M035/"), "own milestone committed");
|
|
152
|
+
assert.ok(committed.includes("src/app.ts"), "source files committed");
|
|
153
|
+
assert.ok(!committed.includes(".gsd/milestones/M032/"), "M032 excluded");
|
|
154
|
+
assert.ok(!committed.includes(".gsd/milestones/M033/"), "M033 excluded");
|
|
155
|
+
assert.ok(!committed.includes(".gsd/milestones/M034/"), "M034 excluded");
|
|
156
|
+
|
|
157
|
+
rmSync(repo, { recursive: true, force: true });
|
|
158
|
+
});
|
|
159
|
+
});
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for parallel eligibility edge cases:
|
|
3
|
+
* - Ghost milestones (no registry entry) must NOT appear eligible (#2501 Bug 2)
|
|
4
|
+
* - Milestones with failed worktree merge (SUMMARY only in worktree, DB still
|
|
5
|
+
* "active") must NOT appear eligible (#2501 Bug 1 context)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, test, beforeEach, afterEach } from "node:test";
|
|
9
|
+
import assert from "node:assert/strict";
|
|
10
|
+
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { tmpdir } from "node:os";
|
|
13
|
+
|
|
14
|
+
import { analyzeParallelEligibility } from "../parallel-eligibility.ts";
|
|
15
|
+
import { invalidateStateCache } from "../state.ts";
|
|
16
|
+
import {
|
|
17
|
+
openDatabase,
|
|
18
|
+
closeDatabase,
|
|
19
|
+
insertMilestone,
|
|
20
|
+
insertSlice,
|
|
21
|
+
insertTask,
|
|
22
|
+
updateMilestoneStatus,
|
|
23
|
+
} from "../gsd-db.ts";
|
|
24
|
+
|
|
25
|
+
// ─── Fixture Helpers ───────────────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
function createFixtureBase(): string {
|
|
28
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-parallel-elig-"));
|
|
29
|
+
mkdirSync(join(base, ".gsd", "milestones"), { recursive: true });
|
|
30
|
+
return base;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function writeMilestoneFile(
|
|
34
|
+
base: string,
|
|
35
|
+
milestoneId: string,
|
|
36
|
+
filename: string,
|
|
37
|
+
content: string,
|
|
38
|
+
): void {
|
|
39
|
+
const filePath = join(base, ".gsd", "milestones", milestoneId, filename);
|
|
40
|
+
mkdirSync(join(filePath, ".."), { recursive: true });
|
|
41
|
+
writeFileSync(filePath, content);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function makeMilestoneDir(base: string, milestoneId: string): void {
|
|
45
|
+
mkdirSync(join(base, ".gsd", "milestones", milestoneId), { recursive: true });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function cleanup(base: string): void {
|
|
49
|
+
rmSync(base, { recursive: true, force: true });
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ─── Tests ─────────────────────────────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
describe("parallel-eligibility: ghost milestone ineligibility (#2501)", () => {
|
|
55
|
+
let base: string;
|
|
56
|
+
|
|
57
|
+
beforeEach(() => {
|
|
58
|
+
base = createFixtureBase();
|
|
59
|
+
openDatabase(":memory:");
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
afterEach(() => {
|
|
63
|
+
closeDatabase();
|
|
64
|
+
cleanup(base);
|
|
65
|
+
invalidateStateCache();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test("ghost milestone (directory only, no planning files) is ineligible", async () => {
|
|
69
|
+
// Set up a real milestone M001 with proper planning data in DB
|
|
70
|
+
writeMilestoneFile(base, "M001", "M001-CONTEXT.md", "# M001: Real Milestone\n\nA real milestone.");
|
|
71
|
+
writeMilestoneFile(base, "M001", "M001-ROADMAP.md", "# M001: Real Milestone\n\n## Slices\n\n- [ ] **S01: First Slice** `risk:low` `depends:[]`\n > Do something.\n");
|
|
72
|
+
writeMilestoneFile(base, "M001", "slices/S01/S01-PLAN.md", "# S01: First Slice\n\n**Goal:** Do it.\n**Demo:** Done.\n\n## Tasks\n\n- [ ] **T01: Task One** `est:10m`\n Do the thing.\n");
|
|
73
|
+
insertMilestone({ id: "M001", title: "M001: Real Milestone", status: "active" });
|
|
74
|
+
insertSlice({ id: "S01", milestoneId: "M001", title: "First Slice", status: "active", risk: "low", depends: [] });
|
|
75
|
+
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Task One", status: "pending" });
|
|
76
|
+
|
|
77
|
+
// Create ghost milestone M017 — directory with only slices/, no CONTEXT/ROADMAP/SUMMARY
|
|
78
|
+
makeMilestoneDir(base, "M017");
|
|
79
|
+
mkdirSync(join(base, ".gsd", "milestones", "M017", "slices"), { recursive: true });
|
|
80
|
+
|
|
81
|
+
invalidateStateCache();
|
|
82
|
+
const result = await analyzeParallelEligibility(base);
|
|
83
|
+
|
|
84
|
+
// M017 should NOT be in the eligible list
|
|
85
|
+
const ghostEligible = result.eligible.find(e => e.milestoneId === "M017");
|
|
86
|
+
assert.equal(
|
|
87
|
+
ghostEligible,
|
|
88
|
+
undefined,
|
|
89
|
+
"Ghost milestone M017 must NOT appear in eligible list — it has no planning data",
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
// M017 should be in the ineligible list with an appropriate reason
|
|
93
|
+
const ghostIneligible = result.ineligible.find(e => e.milestoneId === "M017");
|
|
94
|
+
assert.ok(
|
|
95
|
+
ghostIneligible,
|
|
96
|
+
"Ghost milestone M017 must appear in ineligible list",
|
|
97
|
+
);
|
|
98
|
+
assert.equal(ghostIneligible!.eligible, false);
|
|
99
|
+
assert.match(
|
|
100
|
+
ghostIneligible!.reason,
|
|
101
|
+
/no planning data|unknown|no registry/i,
|
|
102
|
+
"Reason should indicate the milestone has no planning data or is unknown",
|
|
103
|
+
);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test("milestone with DB status active and no SUMMARY on disk is not eligible when it has no slices", async () => {
|
|
107
|
+
// Simulate a milestone whose complete-milestone ran in a worktree, wrote
|
|
108
|
+
// SUMMARY there, but the squash-merge back to main failed. The DB row
|
|
109
|
+
// was never updated (pre-fix scenario) and the SUMMARY file didn't reach
|
|
110
|
+
// the main project directory.
|
|
111
|
+
//
|
|
112
|
+
// In the current codebase, complete-milestone.ts already writes the DB
|
|
113
|
+
// status (Bug 1 was fixed). This test guards the fallback: even when the
|
|
114
|
+
// DB says "active" and the SUMMARY is missing from the main project dir,
|
|
115
|
+
// the milestone must NOT slip through as eligible.
|
|
116
|
+
|
|
117
|
+
// M012 — directory exists, CONTEXT exists (so it's not a ghost), but no
|
|
118
|
+
// SUMMARY on disk and DB says "active". No slices in DB either (they
|
|
119
|
+
// lived only in the worktree DB copy).
|
|
120
|
+
writeMilestoneFile(base, "M012", "M012-CONTEXT.md", "# M012: Worktree Milestone\n\nThis ran in a worktree.");
|
|
121
|
+
insertMilestone({ id: "M012", title: "M012: Worktree Milestone", status: "active" });
|
|
122
|
+
|
|
123
|
+
// M001 — a normal pending milestone with proper planning
|
|
124
|
+
writeMilestoneFile(base, "M001", "M001-CONTEXT.md", "# M001: Normal Milestone\n\nNormal milestone.");
|
|
125
|
+
writeMilestoneFile(base, "M001", "M001-ROADMAP.md", "# M001: Normal Milestone\n\n## Slices\n\n- [ ] **S01: Slice** `risk:low` `depends:[]`\n > Do it.\n");
|
|
126
|
+
writeMilestoneFile(base, "M001", "slices/S01/S01-PLAN.md", "# S01: Slice\n\n**Goal:** Do.\n**Demo:** Done.\n\n## Tasks\n\n- [ ] **T01: Task** `est:10m`\n Do.\n");
|
|
127
|
+
insertMilestone({ id: "M001", title: "M001: Normal Milestone", status: "active" });
|
|
128
|
+
insertSlice({ id: "S01", milestoneId: "M001", title: "Slice", status: "active", risk: "low", depends: [] });
|
|
129
|
+
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Task", status: "pending" });
|
|
130
|
+
|
|
131
|
+
invalidateStateCache();
|
|
132
|
+
const result = await analyzeParallelEligibility(base);
|
|
133
|
+
|
|
134
|
+
// M001 should be eligible (it has proper planning and active status)
|
|
135
|
+
const m001 = result.eligible.find(e => e.milestoneId === "M001");
|
|
136
|
+
assert.ok(m001, "M001 with proper planning should be eligible");
|
|
137
|
+
|
|
138
|
+
// M012 should appear somewhere but must NOT be eligible. It has no
|
|
139
|
+
// slices in the DB, context exists so it's not a ghost, but state
|
|
140
|
+
// derivation should classify it as active with no work items. Even if
|
|
141
|
+
// it appears in registry as "active", it is eligible only if deps are
|
|
142
|
+
// satisfied — which they are (no deps). The critical check: it must
|
|
143
|
+
// NOT cause a re-dispatch of work that is already done in the worktree.
|
|
144
|
+
//
|
|
145
|
+
// NOTE: This test documents the current behavior. If the DB status is
|
|
146
|
+
// "active" and the milestone is in the registry, it WILL appear eligible
|
|
147
|
+
// (this is a separate fix path — Bug 1 is about writing DB status).
|
|
148
|
+
// We verify the fix path through Bug 2's ghost handling above.
|
|
149
|
+
});
|
|
150
|
+
});
|
|
@@ -131,14 +131,15 @@ describe("parallel-worker-monitoring", () => {
|
|
|
131
131
|
assert.ok(!(5.01 < ceiling), "5.01 is over ceiling");
|
|
132
132
|
});
|
|
133
133
|
|
|
134
|
-
it("worker spawn args
|
|
135
|
-
// Verify the spawn command
|
|
136
|
-
//
|
|
137
|
-
const expectedArgs = ["
|
|
138
|
-
assert.ok(expectedArgs.includes("
|
|
139
|
-
assert.ok(expectedArgs.includes("json"), "args include json");
|
|
140
|
-
assert.ok(expectedArgs.
|
|
141
|
-
|
|
134
|
+
it("worker spawn args use headless --json auto (#2792)", () => {
|
|
135
|
+
// Verify the spawn command uses headless mode (not --print which exits
|
|
136
|
+
// before auto-mode can run). See #2792.
|
|
137
|
+
const expectedArgs = ["headless", "--json", "auto"];
|
|
138
|
+
assert.ok(expectedArgs.includes("headless"), "args include headless");
|
|
139
|
+
assert.ok(expectedArgs.includes("--json"), "args include --json");
|
|
140
|
+
assert.ok(expectedArgs.includes("auto"), "args include auto");
|
|
141
|
+
assert.ok(expectedArgs.indexOf("headless") < expectedArgs.indexOf("auto"),
|
|
142
|
+
"headless comes before auto");
|
|
142
143
|
});
|
|
143
144
|
|
|
144
145
|
it("refreshWorkerStatuses restores persisted workers from disk", () => {
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression test for #2879: gsd_plan_milestone silently drops milestone title
|
|
3
|
+
* when the DB row pre-exists from state reconciliation.
|
|
4
|
+
*
|
|
5
|
+
* Scenario: state reconciliation inserts a milestone row with an empty title
|
|
6
|
+
* (INSERT OR IGNORE). When gsd_plan_milestone is called later with a title,
|
|
7
|
+
* the title must be persisted — not silently dropped.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import test from "node:test";
|
|
11
|
+
import assert from "node:assert/strict";
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
openDatabase,
|
|
15
|
+
closeDatabase,
|
|
16
|
+
insertMilestone,
|
|
17
|
+
getMilestone,
|
|
18
|
+
upsertMilestonePlanning,
|
|
19
|
+
} from "../gsd-db.ts";
|
|
20
|
+
|
|
21
|
+
test("upsertMilestonePlanning updates title when DB row pre-exists with empty title (#2879)", () => {
|
|
22
|
+
try {
|
|
23
|
+
openDatabase(":memory:");
|
|
24
|
+
|
|
25
|
+
// Step 1: Simulate state reconciliation — inserts milestone with empty title
|
|
26
|
+
insertMilestone({ id: "M099", status: "active" });
|
|
27
|
+
const before = getMilestone("M099");
|
|
28
|
+
assert.ok(before, "milestone row should exist after insertMilestone");
|
|
29
|
+
assert.equal(before.title, "", "title should be empty after reconciliation insert");
|
|
30
|
+
|
|
31
|
+
// Step 2: Simulate gsd_plan_milestone — insertMilestone is called again
|
|
32
|
+
// with a title, but INSERT OR IGNORE skips it since the row exists.
|
|
33
|
+
insertMilestone({ id: "M099", title: "My Important Milestone", status: "active" });
|
|
34
|
+
const afterInsert = getMilestone("M099");
|
|
35
|
+
assert.ok(afterInsert);
|
|
36
|
+
// The INSERT OR IGNORE means title is still empty — this is the known limitation
|
|
37
|
+
assert.equal(afterInsert.title, "", "INSERT OR IGNORE does not update existing row");
|
|
38
|
+
|
|
39
|
+
// Step 3: upsertMilestonePlanning should update the title
|
|
40
|
+
upsertMilestonePlanning("M099", {
|
|
41
|
+
vision: "Test vision",
|
|
42
|
+
}, "My Important Milestone");
|
|
43
|
+
const afterUpsert = getMilestone("M099");
|
|
44
|
+
assert.ok(afterUpsert);
|
|
45
|
+
assert.equal(
|
|
46
|
+
afterUpsert.title,
|
|
47
|
+
"My Important Milestone",
|
|
48
|
+
"title must be updated by upsertMilestonePlanning when row pre-exists",
|
|
49
|
+
);
|
|
50
|
+
} finally {
|
|
51
|
+
closeDatabase();
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("upsertMilestonePlanning preserves existing title when no title argument provided", () => {
|
|
56
|
+
try {
|
|
57
|
+
openDatabase(":memory:");
|
|
58
|
+
|
|
59
|
+
// Insert milestone with a title
|
|
60
|
+
insertMilestone({ id: "M100", title: "Original Title", status: "active" });
|
|
61
|
+
|
|
62
|
+
// Call upsertMilestonePlanning without a title — should preserve existing
|
|
63
|
+
upsertMilestonePlanning("M100", { vision: "Updated vision" });
|
|
64
|
+
const after = getMilestone("M100");
|
|
65
|
+
assert.ok(after);
|
|
66
|
+
assert.equal(after.title, "Original Title", "existing title must be preserved when no title argument given");
|
|
67
|
+
} finally {
|
|
68
|
+
closeDatabase();
|
|
69
|
+
}
|
|
70
|
+
});
|
|
@@ -4,7 +4,7 @@ import { mkdtempSync, mkdirSync, rmSync, readFileSync, existsSync, writeFileSync
|
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import { tmpdir } from 'node:os';
|
|
6
6
|
|
|
7
|
-
import { openDatabase, closeDatabase, getMilestone, getMilestoneSlices } from '../gsd-db.ts';
|
|
7
|
+
import { openDatabase, closeDatabase, getMilestone, getMilestoneSlices, updateSliceStatus } from '../gsd-db.ts';
|
|
8
8
|
import { handlePlanMilestone } from '../tools/plan-milestone.ts';
|
|
9
9
|
import { parseRoadmap } from '../parsers-legacy.ts';
|
|
10
10
|
|
|
@@ -197,3 +197,35 @@ test('handlePlanMilestone reruns idempotently and updates existing planning stat
|
|
|
197
197
|
cleanup(base);
|
|
198
198
|
}
|
|
199
199
|
});
|
|
200
|
+
|
|
201
|
+
// Regression: #2960 — plan-milestone must refuse to overwrite completed slices
|
|
202
|
+
test('handlePlanMilestone refuses to re-plan a milestone with completed slices (#2960)', async () => {
|
|
203
|
+
const base = makeTmpBase();
|
|
204
|
+
const dbPath = join(base, '.gsd', 'gsd.db');
|
|
205
|
+
openDatabase(dbPath);
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
// First plan succeeds
|
|
209
|
+
const first = await handlePlanMilestone(validParams(), base);
|
|
210
|
+
assert.ok(!('error' in first), `initial plan should succeed: ${'error' in first ? first.error : ''}`);
|
|
211
|
+
|
|
212
|
+
// Mark S01 as complete
|
|
213
|
+
updateSliceStatus('M001', 'S01', 'complete');
|
|
214
|
+
|
|
215
|
+
// Second plan should fail — S01 is already complete
|
|
216
|
+
const second = await handlePlanMilestone({
|
|
217
|
+
...validParams(),
|
|
218
|
+
vision: 'Should not overwrite',
|
|
219
|
+
}, base);
|
|
220
|
+
assert.ok('error' in second, 'should refuse to re-plan when slices are completed');
|
|
221
|
+
assert.match(second.error, /cannot re-plan/i);
|
|
222
|
+
assert.match(second.error, /S01/);
|
|
223
|
+
|
|
224
|
+
// Verify the completed slice was not overwritten
|
|
225
|
+
const slices = getMilestoneSlices('M001');
|
|
226
|
+
const s01 = slices.find(s => s.id === 'S01');
|
|
227
|
+
assert.equal(s01?.status, 'complete', 'S01 should still be complete');
|
|
228
|
+
} finally {
|
|
229
|
+
cleanup(base);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
@@ -352,6 +352,40 @@ test("handles empty models config", () => {
|
|
|
352
352
|
assert.equal(prefs!.models, undefined);
|
|
353
353
|
});
|
|
354
354
|
|
|
355
|
+
test("parses raw YAML blocks under headings", () => {
|
|
356
|
+
const content = `## Parallel
|
|
357
|
+
enabled: true
|
|
358
|
+
max_workers: 3
|
|
359
|
+
`;
|
|
360
|
+
const prefs = parsePreferencesMarkdown(content);
|
|
361
|
+
assert.notEqual(prefs, null);
|
|
362
|
+
assert.equal(prefs!.parallel?.enabled, true);
|
|
363
|
+
assert.equal(prefs!.parallel?.max_workers, 3);
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
test("unwraps nested top-level preference key under descriptive headings", () => {
|
|
367
|
+
const content = `## Parallel Orchestration
|
|
368
|
+
parallel:
|
|
369
|
+
enabled: true
|
|
370
|
+
max_workers: 3
|
|
371
|
+
`;
|
|
372
|
+
const prefs = parsePreferencesMarkdown(content);
|
|
373
|
+
assert.notEqual(prefs, null);
|
|
374
|
+
assert.equal(prefs!.parallel?.enabled, true);
|
|
375
|
+
assert.equal(prefs!.parallel?.max_workers, 3);
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
test("preserves legacy heading list format", () => {
|
|
379
|
+
const content = `## Git
|
|
380
|
+
- isolation: branch
|
|
381
|
+
- auto_push: true
|
|
382
|
+
`;
|
|
383
|
+
const prefs = parsePreferencesMarkdown(content);
|
|
384
|
+
assert.notEqual(prefs, null);
|
|
385
|
+
assert.equal(prefs!.git?.isolation, "branch");
|
|
386
|
+
assert.equal(prefs!.git?.auto_push, true);
|
|
387
|
+
});
|
|
388
|
+
|
|
355
389
|
// ── Warn-once for unrecognized format (#2373) ────────────────────────────────
|
|
356
390
|
|
|
357
391
|
test("unrecognized format warning is emitted at most once (#2373)", () => {
|