gsd-pi 2.58.0 → 2.59.0-dev.3de3832
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 +60 -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/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 +17 -2
- 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 +199 -12
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -8
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +42 -34
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +66 -12
- 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/codebase-generator.js +279 -0
- package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
- package/dist/resources/extensions/gsd/commands-codebase.js +115 -0
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +41 -4
- package/dist/resources/extensions/gsd/complexity-classifier.js +8 -6
- package/dist/resources/extensions/gsd/db-writer.js +116 -8
- package/dist/resources/extensions/gsd/doctor-git-checks.js +76 -1
- package/dist/resources/extensions/gsd/doctor-proactive.js +34 -1
- 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 +12 -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 +105 -2
- package/dist/resources/extensions/gsd/gitignore.js +33 -0
- package/dist/resources/extensions/gsd/gsd-db.js +36 -9
- 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 +39 -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/parsers-legacy.js +20 -3
- package/dist/resources/extensions/gsd/paths.js +45 -0
- package/dist/resources/extensions/gsd/preferences-models.js +14 -1
- package/dist/resources/extensions/gsd/preferences-types.js +3 -1
- package/dist/resources/extensions/gsd/preferences.js +13 -16
- 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/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 +14 -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/watch/header-renderer.js +241 -0
- 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/search-the-web/url-utils.js +17 -0
- 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/security-overrides.d.ts +11 -0
- package/dist/security-overrides.js +41 -0
- 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 +15 -15
- 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 +4 -4
- 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 +15 -15
- 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-61d3afac6d0f0ce7.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/dist/welcome-screen.d.ts +1 -0
- package/dist/welcome-screen.js +32 -6
- package/package.json +2 -2
- package/packages/daemon/src/daemon.ts +1 -1
- package/packages/daemon/src/discord-bot.ts +11 -0
- package/packages/daemon/src/event-bridge.ts +15 -9
- package/packages/daemon/src/event-formatter.ts +30 -2
- 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/resolve-config-value.d.ts +8 -0
- package/packages/pi-coding-agent/dist/core/resolve-config-value.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resolve-config-value.js +23 -2
- package/packages/pi-coding-agent/dist/core/resolve-config-value.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +89 -2
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.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/settings-manager-security.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/settings-manager-security.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/settings-manager-security.test.js +83 -0
- package/packages/pi-coding-agent/dist/core/settings-manager-security.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +14 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +36 -3
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- 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 +3 -2
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +2 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/armin.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/armin.js +9 -8
- package/packages/pi-coding-agent/dist/modes/interactive/components/armin.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +0 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bordered-loader.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.js +5 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/custom-message.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.js +4 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +8 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.js +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.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 +26 -12
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/oauth-selector.js +4 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +46 -14
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js +2 -8
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js +4 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +8 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.js +3 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.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 +19 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +22 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +122 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -0
- 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 +57 -4
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.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/resolve-config-value.test.ts +111 -1
- package/packages/pi-coding-agent/src/core/resolve-config-value.ts +26 -2
- 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/settings-manager-security.test.ts +102 -0
- package/packages/pi-coding-agent/src/core/settings-manager.ts +44 -3
- 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 +11 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/armin.ts +9 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +0 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +3 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/bordered-loader.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/branch-summary-message.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/compaction-summary-message.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/config-selector.ts +7 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/countdown-timer.ts +3 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/custom-message.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/daxnuts.ts +4 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +2 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +3 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/extension-input.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/extension-selector.ts +4 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +27 -13
- package/packages/pi-coding-agent/src/modes/interactive/components/oauth-selector.ts +4 -4
- package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +45 -14
- package/packages/pi-coding-agent/src/modes/interactive/components/scoped-models-selector.ts +2 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/session-selector.ts +4 -4
- package/packages/pi-coding-agent/src/modes/interactive/components/skill-invocation-message.ts +2 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +8 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/user-message-selector.ts +3 -2
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +24 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +156 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +21 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +73 -3
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +1 -1
- 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/dist/modes/interactive/theme/themes.js +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- 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/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 +18 -2
- 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 +193 -9
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +31 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +85 -8
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +38 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +41 -35
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +72 -12
- 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/codebase-generator.ts +351 -0
- package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
- package/src/resources/extensions/gsd/commands-codebase.ts +164 -0
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +46 -4
- package/src/resources/extensions/gsd/complexity-classifier.ts +8 -6
- package/src/resources/extensions/gsd/db-writer.ts +140 -7
- package/src/resources/extensions/gsd/doctor-git-checks.ts +75 -1
- package/src/resources/extensions/gsd/doctor-proactive.ts +35 -1
- 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-types.ts +2 -0
- package/src/resources/extensions/gsd/doctor.ts +3 -1
- package/src/resources/extensions/gsd/error-classifier.ts +13 -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 +119 -3
- package/src/resources/extensions/gsd/gitignore.ts +33 -0
- package/src/resources/extensions/gsd/gsd-db.ts +43 -7
- 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 +41 -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/parsers-legacy.ts +22 -3
- package/src/resources/extensions/gsd/paths.ts +44 -0
- package/src/resources/extensions/gsd/preferences-models.ts +14 -1
- package/src/resources/extensions/gsd/preferences-types.ts +10 -1
- package/src/resources/extensions/gsd/preferences.ts +13 -15
- 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/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 +29 -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/codebase-generator.test.ts +488 -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/complexity-classifier.test.ts +4 -4
- 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/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 +134 -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/doctor-git.test.ts +72 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +68 -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/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/project-relocation-recovery.test.ts +297 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +29 -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/terminated-transient.test.ts +44 -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 +4 -1
- 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-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 +20 -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/watch/header-renderer.ts +275 -0
- 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/search-the-web/url-utils.ts +19 -0
- 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.8b732f67a11b11b4.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/{IoheXIe-5DH7ieX8AUo8U → Y_HG7cJVptjBpkVSQQiFi}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{IoheXIe-5DH7ieX8AUo8U → Y_HG7cJVptjBpkVSQQiFi}/_ssgManifest.js +0 -0
|
@@ -80,4 +80,4 @@ If a proposed order would violate constraints, explain the issue and suggest alt
|
|
|
80
80
|
- Do NOT park completed milestones — it would corrupt dependency satisfaction
|
|
81
81
|
- Park is preferred over discard when a milestone has any completed work
|
|
82
82
|
- Always persist queue order changes to `.gsd/QUEUE-ORDER.json`
|
|
83
|
-
-
|
|
83
|
+
- {{commitInstruction}}
|
|
@@ -54,6 +54,7 @@ For each capture, classify it as one of:
|
|
|
54
54
|
- Add `**Resolution:** <brief description of what will happen>`
|
|
55
55
|
- Add `**Rationale:** <why this classification>`
|
|
56
56
|
- Add `**Resolved:** <current ISO timestamp>`
|
|
57
|
+
- Add `**Milestone:** <current milestone ID>` (e.g., `**Milestone:** M003`)
|
|
57
58
|
|
|
58
59
|
4. **Summarize** what was triaged: how many captures, what classifications were assigned, and what actions are pending (e.g., "2 quick-tasks ready for execution, 1 deferred to S03").
|
|
59
60
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import { createHash } from "node:crypto";
|
|
10
10
|
import { execFileSync } from "node:child_process";
|
|
11
|
-
import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
11
|
+
import { cpSync, existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, renameSync, rmSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
12
12
|
import { homedir } from "node:os";
|
|
13
13
|
import { basename, dirname, join, resolve } from "node:path";
|
|
14
14
|
|
|
@@ -276,9 +276,14 @@ export function validateProjectId(id: string): boolean {
|
|
|
276
276
|
* If `GSD_PROJECT_ID` is set, returns it directly (validation is expected
|
|
277
277
|
* to have already happened at startup via `validateProjectId`).
|
|
278
278
|
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
279
|
+
* For repos with a remote URL, returns SHA-256 of the remote URL only —
|
|
280
|
+
* this makes the identity stable across directory moves/renames (#2750).
|
|
281
|
+
*
|
|
282
|
+
* For local-only repos (no remote), includes the git root in the hash.
|
|
283
|
+
* Local repos use a `.gsd-id` marker file for recovery after moves.
|
|
284
|
+
*
|
|
285
|
+
* Deterministic: same repo always produces the same hash regardless of
|
|
286
|
+
* which worktree the caller is inside.
|
|
282
287
|
*/
|
|
283
288
|
export function repoIdentity(basePath: string): string {
|
|
284
289
|
const projectId = process.env.GSD_PROJECT_ID;
|
|
@@ -286,8 +291,14 @@ export function repoIdentity(basePath: string): string {
|
|
|
286
291
|
return projectId;
|
|
287
292
|
}
|
|
288
293
|
const remoteUrl = getRemoteUrl(basePath);
|
|
294
|
+
if (remoteUrl) {
|
|
295
|
+
// Remote URL alone uniquely identifies the repo — path is redundant.
|
|
296
|
+
// This makes moves transparent for repos with remotes (#2750).
|
|
297
|
+
return createHash("sha256").update(remoteUrl).digest("hex").slice(0, 12);
|
|
298
|
+
}
|
|
299
|
+
// Local-only repo: include git root since there's no remote to anchor identity.
|
|
289
300
|
const root = resolveGitRoot(basePath);
|
|
290
|
-
const input =
|
|
301
|
+
const input = `\n${root}`;
|
|
291
302
|
return createHash("sha256").update(input).digest("hex").slice(0, 12);
|
|
292
303
|
}
|
|
293
304
|
|
|
@@ -351,21 +362,148 @@ export function cleanNumberedGsdVariants(projectPath: string): string[] {
|
|
|
351
362
|
return removed;
|
|
352
363
|
}
|
|
353
364
|
|
|
365
|
+
// ─── .gsd-id Marker ─────────────────────────────────────────────────────────
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Write a `.gsd-id` marker file in the project root.
|
|
369
|
+
*
|
|
370
|
+
* This file records the identity hash used for the external state directory.
|
|
371
|
+
* For local-only repos (no remote), this marker survives directory moves and
|
|
372
|
+
* enables automatic recovery of orphaned state (#2750).
|
|
373
|
+
*
|
|
374
|
+
* The marker is gitignored by ensureGitignore(). Non-fatal: failure to write
|
|
375
|
+
* the marker must never block project setup.
|
|
376
|
+
*/
|
|
377
|
+
function writeGsdIdMarker(projectPath: string, identity: string): void {
|
|
378
|
+
try {
|
|
379
|
+
const markerPath = join(projectPath, ".gsd-id");
|
|
380
|
+
// Only write if content differs to avoid unnecessary disk writes.
|
|
381
|
+
if (existsSync(markerPath)) {
|
|
382
|
+
try {
|
|
383
|
+
if (readFileSync(markerPath, "utf-8").trim() === identity) return;
|
|
384
|
+
} catch { /* fall through and overwrite */ }
|
|
385
|
+
}
|
|
386
|
+
writeFileSync(markerPath, identity + "\n", "utf-8");
|
|
387
|
+
} catch {
|
|
388
|
+
// Non-fatal — marker write failure should not block project setup
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Read the `.gsd-id` marker from the project root.
|
|
394
|
+
* Returns the identity hash, or null if the marker doesn't exist or is unreadable.
|
|
395
|
+
*/
|
|
396
|
+
function readGsdIdMarker(projectPath: string): string | null {
|
|
397
|
+
try {
|
|
398
|
+
const markerPath = join(projectPath, ".gsd-id");
|
|
399
|
+
if (!existsSync(markerPath)) return null;
|
|
400
|
+
const content = readFileSync(markerPath, "utf-8").trim();
|
|
401
|
+
return /^[a-zA-Z0-9_-]+$/.test(content) ? content : null;
|
|
402
|
+
} catch {
|
|
403
|
+
return null;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Check whether an external state directory has meaningful content.
|
|
409
|
+
* Returns true if the directory contains any files or subdirectories
|
|
410
|
+
* beyond just repo-meta.json.
|
|
411
|
+
*/
|
|
412
|
+
function hasProjectState(externalPath: string): boolean {
|
|
413
|
+
try {
|
|
414
|
+
if (!existsSync(externalPath)) return false;
|
|
415
|
+
const entries = readdirSync(externalPath);
|
|
416
|
+
return entries.some(e => e !== "repo-meta.json");
|
|
417
|
+
} catch {
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Resolve the external state directory, with recovery for relocated projects.
|
|
424
|
+
*
|
|
425
|
+
* For local-only repos where the computed identity produces an empty state dir,
|
|
426
|
+
* checks the `.gsd-id` marker for the original identity hash and recovers
|
|
427
|
+
* the old state directory if it still exists and contains data (#2750).
|
|
428
|
+
*
|
|
429
|
+
* Returns the resolved external path (may differ from the computed identity).
|
|
430
|
+
*/
|
|
431
|
+
function resolveExternalPathWithRecovery(projectPath: string): string {
|
|
432
|
+
const computedPath = externalGsdRoot(projectPath);
|
|
433
|
+
const computedId = repoIdentity(projectPath);
|
|
434
|
+
|
|
435
|
+
// Check if computed path already has state — fast path, no recovery needed.
|
|
436
|
+
if (hasProjectState(computedPath)) {
|
|
437
|
+
return computedPath;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Check for .gsd-id marker from a previous location.
|
|
441
|
+
const markerId = readGsdIdMarker(projectPath);
|
|
442
|
+
if (markerId && markerId !== computedId) {
|
|
443
|
+
// The marker points to a different identity — the repo was likely moved.
|
|
444
|
+
const base = process.env.GSD_STATE_DIR || gsdHome;
|
|
445
|
+
const markerPath = join(base, "projects", markerId);
|
|
446
|
+
if (hasProjectState(markerPath)) {
|
|
447
|
+
// Recover: use the old state directory and update the marker to the new identity.
|
|
448
|
+
// Move the state from the old hash dir to the new one so future lookups work
|
|
449
|
+
// without the marker.
|
|
450
|
+
try {
|
|
451
|
+
mkdirSync(computedPath, { recursive: true });
|
|
452
|
+
const entries = readdirSync(markerPath);
|
|
453
|
+
for (const entry of entries) {
|
|
454
|
+
try {
|
|
455
|
+
const src = join(markerPath, entry);
|
|
456
|
+
const dst = join(computedPath, entry);
|
|
457
|
+
// Use rename for same-filesystem (fast) or fall back to copy.
|
|
458
|
+
try {
|
|
459
|
+
renameSync(src, dst);
|
|
460
|
+
} catch {
|
|
461
|
+
cpSync(src, dst, { recursive: true, force: true });
|
|
462
|
+
}
|
|
463
|
+
} catch { /* continue with remaining entries */ }
|
|
464
|
+
}
|
|
465
|
+
// Clean up old directory after successful migration.
|
|
466
|
+
try { rmSync(markerPath, { recursive: true, force: true }); } catch { /* non-fatal */ }
|
|
467
|
+
} catch {
|
|
468
|
+
// If migration fails, just point at the old directory.
|
|
469
|
+
return markerPath;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
return computedPath;
|
|
475
|
+
}
|
|
476
|
+
|
|
354
477
|
// ─── Symlink Management ─────────────────────────────────────────────────────
|
|
355
478
|
|
|
356
479
|
/**
|
|
357
480
|
* Ensure the `<project>/.gsd` symlink points to the external state directory.
|
|
358
481
|
*
|
|
359
482
|
* 1. Clean up any macOS numbered collision variants (`.gsd 2`, `.gsd 3`, etc.)
|
|
360
|
-
* 2.
|
|
361
|
-
* 3.
|
|
362
|
-
* 4. If `<project>/.gsd`
|
|
363
|
-
* 5. If `<project>/.gsd` is
|
|
483
|
+
* 2. Resolve external dir (with relocation recovery via `.gsd-id` marker)
|
|
484
|
+
* 3. mkdir -p the external dir
|
|
485
|
+
* 4. If `<project>/.gsd` doesn't exist → create symlink
|
|
486
|
+
* 5. If `<project>/.gsd` is already the correct symlink → no-op
|
|
487
|
+
* 6. If `<project>/.gsd` is a real directory → return as-is (migration handles later)
|
|
488
|
+
* 7. Write `.gsd-id` marker for future relocation recovery
|
|
364
489
|
*
|
|
365
490
|
* Returns the resolved external path.
|
|
366
491
|
*/
|
|
367
492
|
export function ensureGsdSymlink(projectPath: string): string {
|
|
368
|
-
const
|
|
493
|
+
const result = ensureGsdSymlinkCore(projectPath);
|
|
494
|
+
|
|
495
|
+
// Write .gsd-id marker so future relocations can recover this state (#2750).
|
|
496
|
+
// Only write for the project root (not subdirectories or worktrees that
|
|
497
|
+
// delegate to a parent .gsd).
|
|
498
|
+
if (!isInsideWorktree(projectPath)) {
|
|
499
|
+
writeGsdIdMarker(projectPath, repoIdentity(projectPath));
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
return result;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
function ensureGsdSymlinkCore(projectPath: string): string {
|
|
506
|
+
const externalPath = resolveExternalPathWithRecovery(projectPath);
|
|
369
507
|
const localGsd = join(projectPath, ".gsd");
|
|
370
508
|
const inWorktree = isInsideWorktree(projectPath);
|
|
371
509
|
|
|
@@ -418,12 +556,28 @@ export function ensureGsdSymlink(projectPath: string): string {
|
|
|
418
556
|
|
|
419
557
|
const replaceWithSymlink = (): string => {
|
|
420
558
|
rmSync(localGsd, { recursive: true, force: true });
|
|
559
|
+
// Defensive: remove any residual entry (e.g. dangling symlink) before creating.
|
|
560
|
+
try { unlinkSync(localGsd); } catch { /* already gone */ }
|
|
421
561
|
symlinkSync(externalPath, localGsd, "junction");
|
|
422
562
|
return externalPath;
|
|
423
563
|
};
|
|
424
564
|
|
|
565
|
+
// Check for dangling symlinks (e.g. after relocation recovery removed the old
|
|
566
|
+
// state dir). existsSync follows symlinks, so it returns false for dangling ones.
|
|
567
|
+
// lstatSync does NOT follow, so we can detect the dangling symlink and replace it.
|
|
425
568
|
if (!existsSync(localGsd)) {
|
|
426
|
-
|
|
569
|
+
try {
|
|
570
|
+
const stat = lstatSync(localGsd);
|
|
571
|
+
if (stat.isSymbolicLink()) {
|
|
572
|
+
// Dangling symlink — replace with correct one (#2750).
|
|
573
|
+
return replaceWithSymlink();
|
|
574
|
+
}
|
|
575
|
+
} catch {
|
|
576
|
+
// lstat also failed — nothing exists at this path
|
|
577
|
+
}
|
|
578
|
+
// Nothing exists yet — create symlink.
|
|
579
|
+
// Defensive: remove any residual entry to avoid EEXIST race (#2750).
|
|
580
|
+
try { unlinkSync(localGsd); } catch { /* nothing to remove */ }
|
|
427
581
|
symlinkSync(externalPath, localGsd, "junction");
|
|
428
582
|
return externalPath;
|
|
429
583
|
}
|
|
@@ -442,6 +596,27 @@ export function ensureGsdSymlink(projectPath: string): string {
|
|
|
442
596
|
if (inWorktree) {
|
|
443
597
|
return replaceWithSymlink();
|
|
444
598
|
}
|
|
599
|
+
// After identity hash change (e.g. upgrade from path-based to remote-only
|
|
600
|
+
// hash, or relocation recovery), migrate data from old target to new path
|
|
601
|
+
// and update the symlink (#2750).
|
|
602
|
+
if (!hasProjectState(externalPath) && hasProjectState(target)) {
|
|
603
|
+
try {
|
|
604
|
+
mkdirSync(externalPath, { recursive: true });
|
|
605
|
+
const oldEntries = readdirSync(target);
|
|
606
|
+
for (const entry of oldEntries) {
|
|
607
|
+
try {
|
|
608
|
+
const src = join(target, entry);
|
|
609
|
+
const dst = join(externalPath, entry);
|
|
610
|
+
try { renameSync(src, dst); } catch { cpSync(src, dst, { recursive: true, force: true }); }
|
|
611
|
+
} catch { /* continue */ }
|
|
612
|
+
}
|
|
613
|
+
try { rmSync(target, { recursive: true, force: true }); } catch { /* non-fatal */ }
|
|
614
|
+
return replaceWithSymlink();
|
|
615
|
+
} catch {
|
|
616
|
+
// Migration failed — preserve old symlink
|
|
617
|
+
return target;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
445
620
|
// Outside worktrees, preserve custom overrides or legacy symlinks.
|
|
446
621
|
return target;
|
|
447
622
|
}
|
|
@@ -19,6 +19,7 @@ import { isParked, getParkedReason } from "./milestone-actions.js";
|
|
|
19
19
|
import { getMilestoneSlices, isDbAvailable } from "./gsd-db.js";
|
|
20
20
|
import { buildExistingMilestonesContext } from "./guided-flow-queue.js";
|
|
21
21
|
import { loadPrompt } from "./prompt-loader.js";
|
|
22
|
+
import { isGsdGitignored } from "./gitignore.js";
|
|
22
23
|
|
|
23
24
|
// ─── Entry Point ──────────────────────────────────────────────────────────────
|
|
24
25
|
|
|
@@ -53,9 +54,14 @@ export async function handleRethink(
|
|
|
53
54
|
const rethinkData = buildRethinkData(basePath, milestoneIds, state, queueOrder);
|
|
54
55
|
const existingMilestonesContext = await buildExistingMilestonesContext(basePath, milestoneIds, state);
|
|
55
56
|
|
|
57
|
+
const commitInstruction = isGsdGitignored(basePath)
|
|
58
|
+
? "Do not commit planning artifacts — .gsd/ is gitignored in this project."
|
|
59
|
+
: 'After changes, run `git add .gsd/ && git commit -m "docs(gsd): rethink milestone plan"` to persist (rethink runs interactively outside auto-mode, so no system auto-commit)';
|
|
60
|
+
|
|
56
61
|
const content = loadPrompt("rethink", {
|
|
57
62
|
rethinkData,
|
|
58
63
|
existingMilestonesContext,
|
|
64
|
+
commitInstruction,
|
|
59
65
|
});
|
|
60
66
|
|
|
61
67
|
pi.sendMessage(
|
|
@@ -219,13 +219,14 @@ export function parseRoadmapSlices(content: string): RoadmapSliceEntry[] {
|
|
|
219
219
|
function parseProseSliceHeaders(content: string): RoadmapSliceEntry[] {
|
|
220
220
|
const slices: RoadmapSliceEntry[] = [];
|
|
221
221
|
// Match H1-H4 headers containing S<digits> with optional "Slice" prefix, bold markers,
|
|
222
|
-
//
|
|
222
|
+
// numeric prefixes (e.g., "1.", "(1)"), bracketed IDs (e.g., "[S01]"),
|
|
223
|
+
// optional checkmark completion marker, and optional leading indentation.
|
|
223
224
|
// Separator after the ID is flexible: colon, dash, em/en dash, dot, or just whitespace.
|
|
224
|
-
const headerPattern =
|
|
225
|
+
const headerPattern = /^\s*#{1,4}\s+\*{0,2}(?:\u2713\s+)?(?:\d+[.)]\s+)?(?:\(\d+\)\s+)?(?:Slice\s+)?\[?(S\d+)\]?\*{0,2}[:\s.\u2014\u2013-]*\s*(.+)/gm;
|
|
225
226
|
let match: RegExpExecArray | null;
|
|
226
227
|
|
|
227
228
|
// Check for checkmark before the slice ID (e.g., "## checkmark S01: Title")
|
|
228
|
-
const prefixCheckPattern =
|
|
229
|
+
const prefixCheckPattern = /^\s*#{1,4}\s+\*{0,2}\u2713\s+/;
|
|
229
230
|
|
|
230
231
|
while ((match = headerPattern.exec(content)) !== null) {
|
|
231
232
|
const id = match[1]!;
|
|
@@ -251,7 +252,7 @@ function parseProseSliceHeaders(content: string): RoadmapSliceEntry[] {
|
|
|
251
252
|
|
|
252
253
|
// Try to extract depends from prose: "Depends on: S01" or "**Depends on:** S01, S02"
|
|
253
254
|
const afterHeader = content.slice(match.index + match[0].length);
|
|
254
|
-
const nextHeader = afterHeader.search(
|
|
255
|
+
const nextHeader = afterHeader.search(/^\s*#{1,4}\s/m);
|
|
255
256
|
const section = nextHeader !== -1 ? afterHeader.slice(0, nextHeader) : afterHeader.slice(0, 500);
|
|
256
257
|
|
|
257
258
|
const depsMatch = section.match(/\*{0,2}Depends\s+on:?\*{0,2}\s*(.+)/i);
|
|
@@ -36,22 +36,24 @@ import {
|
|
|
36
36
|
|
|
37
37
|
import { findMilestoneIds } from './milestone-ids.js';
|
|
38
38
|
import { loadQueueOrder, sortByQueueOrder } from './queue-order.js';
|
|
39
|
-
import { isClosedStatus } from './status-guards.js';
|
|
40
39
|
import { nativeBatchParseGsdFiles, type BatchParsedFile } from './native-parser-bridge.js';
|
|
41
40
|
|
|
42
41
|
import { join, resolve } from 'path';
|
|
43
|
-
import { existsSync, readdirSync } from 'node:fs';
|
|
42
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
44
43
|
import { debugCount, debugTime } from './debug-logger.js';
|
|
45
44
|
import { extractVerdict } from './verdict-parser.js';
|
|
45
|
+
import { logWarning, logError } from './workflow-logger.js';
|
|
46
46
|
|
|
47
47
|
import {
|
|
48
48
|
isDbAvailable,
|
|
49
49
|
getAllMilestones,
|
|
50
|
+
getMilestone,
|
|
50
51
|
getMilestoneSlices,
|
|
51
52
|
getSliceTasks,
|
|
52
53
|
getReplanHistory,
|
|
53
54
|
getSlice,
|
|
54
55
|
insertMilestone,
|
|
56
|
+
insertSlice,
|
|
55
57
|
updateTaskStatus,
|
|
56
58
|
getPendingSliceGateCount,
|
|
57
59
|
type MilestoneRow,
|
|
@@ -64,8 +66,29 @@ import {
|
|
|
64
66
|
* files like CONTEXT, CONTEXT-DRAFT, ROADMAP, or SUMMARY). These appear when
|
|
65
67
|
* a milestone is created but never initialised. Treating them as active causes
|
|
66
68
|
* auto-mode to stall or falsely declare completion.
|
|
69
|
+
*
|
|
70
|
+
* However, a milestone is NOT a ghost if:
|
|
71
|
+
* - It has a DB row with a meaningful status (queued, active, etc.) — the DB
|
|
72
|
+
* knows about it even if content files haven't been created yet.
|
|
73
|
+
* - It has a worktree directory — a worktree proves the milestone was
|
|
74
|
+
* legitimately created and is expected to be populated.
|
|
75
|
+
*
|
|
76
|
+
* Fixes #2921: queued milestones with worktrees were incorrectly classified
|
|
77
|
+
* as ghosts, causing auto-mode to skip them entirely.
|
|
67
78
|
*/
|
|
68
79
|
export function isGhostMilestone(basePath: string, mid: string): boolean {
|
|
80
|
+
// If the milestone has a DB row, it's a known milestone — not a ghost.
|
|
81
|
+
if (isDbAvailable()) {
|
|
82
|
+
const dbRow = getMilestone(mid);
|
|
83
|
+
if (dbRow) return false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// If a worktree exists for this milestone, it was legitimately created.
|
|
87
|
+
const root = gsdRoot(basePath);
|
|
88
|
+
const wtPath = join(root, 'worktrees', mid);
|
|
89
|
+
if (existsSync(wtPath)) return false;
|
|
90
|
+
|
|
91
|
+
// Fall back to content-file check: no substantive files means ghost.
|
|
69
92
|
const context = resolveMilestoneFile(basePath, mid, "CONTEXT");
|
|
70
93
|
const draft = resolveMilestoneFile(basePath, mid, "CONTEXT-DRAFT");
|
|
71
94
|
const roadmap = resolveMilestoneFile(basePath, mid, "ROADMAP");
|
|
@@ -209,10 +232,10 @@ export async function deriveState(basePath: string): Promise<GSDState> {
|
|
|
209
232
|
if (isDbAvailable()) {
|
|
210
233
|
let dbMilestones = getAllMilestones();
|
|
211
234
|
|
|
212
|
-
// Disk→DB reconciliation
|
|
213
|
-
// (
|
|
214
|
-
//
|
|
215
|
-
//
|
|
235
|
+
// Disk→DB reconciliation when DB is empty but disk has milestones (#2631).
|
|
236
|
+
// deriveStateFromDb() does its own reconciliation, but deriveState() skips
|
|
237
|
+
// it entirely when the DB is empty. Sync here so the DB path is used when
|
|
238
|
+
// disk milestones exist but haven't been migrated yet.
|
|
216
239
|
if (dbMilestones.length === 0) {
|
|
217
240
|
const diskIds = findMilestoneIds(basePath);
|
|
218
241
|
let synced = false;
|
|
@@ -231,7 +254,7 @@ export async function deriveState(basePath: string): Promise<GSDState> {
|
|
|
231
254
|
stopDbTimer({ phase: result.phase, milestone: result.activeMilestone?.id });
|
|
232
255
|
_telemetry.dbDeriveCount++;
|
|
233
256
|
} else {
|
|
234
|
-
// DB open but
|
|
257
|
+
// DB open but no milestones on disk either — use filesystem path
|
|
235
258
|
result = await _deriveStateImpl(basePath);
|
|
236
259
|
_telemetry.markdownDeriveCount++;
|
|
237
260
|
}
|
|
@@ -268,6 +291,13 @@ function extractContextTitle(content: string | null, fallback: string): string {
|
|
|
268
291
|
|
|
269
292
|
// ─── DB-backed State Derivation ────────────────────────────────────────────
|
|
270
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Helper: check if a DB status counts as "done" (handles K002 ambiguity).
|
|
296
|
+
*/
|
|
297
|
+
function isStatusDone(status: string): boolean {
|
|
298
|
+
return status === 'complete' || status === 'done';
|
|
299
|
+
}
|
|
300
|
+
|
|
271
301
|
/**
|
|
272
302
|
* Derive GSD state from the milestones/slices/tasks DB tables.
|
|
273
303
|
* Flag files (PARKED, VALIDATION, CONTINUE, REPLAN, REPLAN-TRIGGER, CONTEXT-DRAFT)
|
|
@@ -298,6 +328,36 @@ export async function deriveStateFromDb(basePath: string): Promise<GSDState> {
|
|
|
298
328
|
}
|
|
299
329
|
if (synced) allMilestones = getAllMilestones();
|
|
300
330
|
|
|
331
|
+
// Disk→DB slice reconciliation (#2533): slices defined in ROADMAP.md but
|
|
332
|
+
// missing from the DB cause permanent "No slice eligible" blocks because
|
|
333
|
+
// the dependency resolver only sees DB rows. Parse each milestone's roadmap
|
|
334
|
+
// and insert any missing slices, checking SUMMARY files to set correct status.
|
|
335
|
+
// insertSlice uses INSERT OR IGNORE, so existing rows are never overwritten.
|
|
336
|
+
for (const mid of diskIds) {
|
|
337
|
+
if (isGhostMilestone(basePath, mid)) continue;
|
|
338
|
+
const roadmapPath = resolveMilestoneFile(basePath, mid, "ROADMAP");
|
|
339
|
+
if (!roadmapPath) continue;
|
|
340
|
+
|
|
341
|
+
const dbSlices = getMilestoneSlices(mid);
|
|
342
|
+
const dbSliceIds = new Set(dbSlices.map(s => s.id));
|
|
343
|
+
|
|
344
|
+
let roadmapContent: string;
|
|
345
|
+
try { roadmapContent = readFileSync(roadmapPath, "utf-8"); }
|
|
346
|
+
catch { continue; }
|
|
347
|
+
|
|
348
|
+
const parsed = parseRoadmap(roadmapContent);
|
|
349
|
+
for (const s of parsed.slices) {
|
|
350
|
+
if (dbSliceIds.has(s.id)) continue;
|
|
351
|
+
const summaryPath = resolveSliceFile(basePath, mid, s.id, "SUMMARY");
|
|
352
|
+
const sliceStatus = (s.done || summaryPath) ? "complete" : "pending";
|
|
353
|
+
insertSlice({
|
|
354
|
+
id: s.id, milestoneId: mid, title: s.title,
|
|
355
|
+
status: sliceStatus, risk: s.risk,
|
|
356
|
+
depends: s.depends, demo: s.demo,
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
301
361
|
// Reconcile: discover milestones that exist on disk but are missing from
|
|
302
362
|
// the DB. This happens when milestones were created before the DB migration
|
|
303
363
|
// or were manually added to the filesystem. Without this, disk-only
|
|
@@ -357,7 +417,7 @@ export async function deriveStateFromDb(basePath: string): Promise<GSDState> {
|
|
|
357
417
|
continue;
|
|
358
418
|
}
|
|
359
419
|
|
|
360
|
-
if (
|
|
420
|
+
if (isStatusDone(m.status)) {
|
|
361
421
|
completeMilestoneIds.add(m.id);
|
|
362
422
|
continue;
|
|
363
423
|
}
|
|
@@ -371,7 +431,7 @@ export async function deriveStateFromDb(basePath: string): Promise<GSDState> {
|
|
|
371
431
|
|
|
372
432
|
// Check roadmap: all slices done means milestone is complete
|
|
373
433
|
const slices = getMilestoneSlices(m.id);
|
|
374
|
-
if (slices.length > 0 && slices.every(s =>
|
|
434
|
+
if (slices.length > 0 && slices.every(s => isStatusDone(s.status))) {
|
|
375
435
|
// All slices done but no summary — still counts as complete for dep resolution
|
|
376
436
|
// if a summary file exists
|
|
377
437
|
// Note: without summary file, the milestone is in validating/completing state, not complete
|
|
@@ -393,7 +453,7 @@ export async function deriveStateFromDb(basePath: string): Promise<GSDState> {
|
|
|
393
453
|
|
|
394
454
|
// Ghost milestone check: no slices in DB AND no substantive files on disk
|
|
395
455
|
const slices = getMilestoneSlices(m.id);
|
|
396
|
-
if (slices.length === 0 && !
|
|
456
|
+
if (slices.length === 0 && !isStatusDone(m.status)) {
|
|
397
457
|
// Check disk for ghost detection
|
|
398
458
|
if (isGhostMilestone(basePath, m.id)) continue;
|
|
399
459
|
}
|
|
@@ -416,7 +476,7 @@ export async function deriveStateFromDb(basePath: string): Promise<GSDState> {
|
|
|
416
476
|
}
|
|
417
477
|
|
|
418
478
|
// Not complete — determine if it should be active
|
|
419
|
-
const allSlicesDone = slices.length > 0 && slices.every(s =>
|
|
479
|
+
const allSlicesDone = slices.length > 0 && slices.every(s => isStatusDone(s.status));
|
|
420
480
|
|
|
421
481
|
// Get title — prefer DB, fall back to context file extraction
|
|
422
482
|
let title = stripMilestonePrefix(m.title) || m.id;
|
|
@@ -526,7 +586,8 @@ export async function deriveStateFromDb(basePath: string): Promise<GSDState> {
|
|
|
526
586
|
? `All milestones complete. ${activeReqs} active requirement${activeReqs === 1 ? '' : 's'} in REQUIREMENTS.md ${activeReqs === 1 ? 'has' : 'have'} not been mapped to a milestone.`
|
|
527
587
|
: 'All milestones complete.';
|
|
528
588
|
return {
|
|
529
|
-
activeMilestone:
|
|
589
|
+
activeMilestone: null,
|
|
590
|
+
lastCompletedMilestone: lastEntry ? { id: lastEntry.id, title: lastEntry.title } : null,
|
|
530
591
|
activeSlice: null, activeTask: null,
|
|
531
592
|
phase: 'complete',
|
|
532
593
|
recentDecisions: [], blockers: [],
|
|
@@ -568,10 +629,7 @@ export async function deriveStateFromDb(basePath: string): Promise<GSDState> {
|
|
|
568
629
|
}
|
|
569
630
|
|
|
570
631
|
// ── All slices done → validating/completing ─────────────────────────
|
|
571
|
-
|
|
572
|
-
// an empty slice array causes a premature phase transition to
|
|
573
|
-
// validating-milestone. See: https://github.com/gsd-build/gsd-2/issues/2667
|
|
574
|
-
const allSlicesDone = activeMilestoneSlices.length > 0 && activeMilestoneSlices.every(s => isClosedStatus(s.status));
|
|
632
|
+
const allSlicesDone = activeMilestoneSlices.every(s => isStatusDone(s.status));
|
|
575
633
|
if (allSlicesDone) {
|
|
576
634
|
const validationFile = resolveMilestoneFile(basePath, activeMilestone.id, "VALIDATION");
|
|
577
635
|
const validationContent = validationFile ? await loadFile(validationFile) : null;
|
|
@@ -604,19 +662,19 @@ export async function deriveStateFromDb(basePath: string): Promise<GSDState> {
|
|
|
604
662
|
|
|
605
663
|
// ── Find active slice (first incomplete with deps satisfied) ─────────
|
|
606
664
|
const sliceProgress = {
|
|
607
|
-
done: activeMilestoneSlices.filter(s =>
|
|
665
|
+
done: activeMilestoneSlices.filter(s => isStatusDone(s.status)).length,
|
|
608
666
|
total: activeMilestoneSlices.length,
|
|
609
667
|
};
|
|
610
668
|
|
|
611
669
|
const doneSliceIds = new Set(
|
|
612
|
-
activeMilestoneSlices.filter(s =>
|
|
670
|
+
activeMilestoneSlices.filter(s => isStatusDone(s.status)).map(s => s.id)
|
|
613
671
|
);
|
|
614
672
|
|
|
615
673
|
let activeSlice: ActiveRef | null = null;
|
|
616
674
|
let activeSliceRow: SliceRow | null = null;
|
|
617
675
|
|
|
618
676
|
for (const s of activeMilestoneSlices) {
|
|
619
|
-
if (
|
|
677
|
+
if (isStatusDone(s.status)) continue;
|
|
620
678
|
if (s.depends.every(dep => doneSliceIds.has(dep))) {
|
|
621
679
|
activeSlice = { id: s.id, title: s.title };
|
|
622
680
|
activeSliceRow = s;
|
|
@@ -659,20 +717,16 @@ export async function deriveStateFromDb(basePath: string): Promise<GSDState> {
|
|
|
659
717
|
// causing the dispatcher to re-dispatch the same completed task forever.
|
|
660
718
|
let reconciled = false;
|
|
661
719
|
for (const t of tasks) {
|
|
662
|
-
if (
|
|
720
|
+
if (isStatusDone(t.status)) continue;
|
|
663
721
|
const summaryPath = resolveTaskFile(basePath, activeMilestone.id, activeSlice.id, t.id, "SUMMARY");
|
|
664
722
|
if (summaryPath && existsSync(summaryPath)) {
|
|
665
723
|
try {
|
|
666
724
|
updateTaskStatus(activeMilestone.id, activeSlice.id, t.id, "complete");
|
|
667
|
-
|
|
668
|
-
`gsd-reconcile: task ${activeMilestone.id}/${activeSlice.id}/${t.id} had SUMMARY on disk but DB status was "${t.status}" — updated to "complete" (#2514)\n`,
|
|
669
|
-
);
|
|
725
|
+
logWarning("reconcile", `task ${activeMilestone.id}/${activeSlice.id}/${t.id} status reconciled from "${t.status}" to "complete" (#2514)`, { mid: activeMilestone.id, sid: activeSlice.id, tid: t.id });
|
|
670
726
|
reconciled = true;
|
|
671
727
|
} catch (e) {
|
|
672
728
|
// DB write failed — continue with stale status rather than crash
|
|
673
|
-
|
|
674
|
-
`gsd-reconcile: failed to update task ${t.id}: ${(e as Error).message}\n`,
|
|
675
|
-
);
|
|
729
|
+
logError("reconcile", `failed to update task ${t.id}`, { tid: t.id, error: (e as Error).message });
|
|
676
730
|
}
|
|
677
731
|
}
|
|
678
732
|
}
|
|
@@ -682,11 +736,11 @@ export async function deriveStateFromDb(basePath: string): Promise<GSDState> {
|
|
|
682
736
|
}
|
|
683
737
|
|
|
684
738
|
const taskProgress = {
|
|
685
|
-
done: tasks.filter(t =>
|
|
739
|
+
done: tasks.filter(t => isStatusDone(t.status)).length,
|
|
686
740
|
total: tasks.length,
|
|
687
741
|
};
|
|
688
742
|
|
|
689
|
-
const activeTaskRow = tasks.find(t => !
|
|
743
|
+
const activeTaskRow = tasks.find(t => !isStatusDone(t.status));
|
|
690
744
|
|
|
691
745
|
if (!activeTaskRow && tasks.length > 0) {
|
|
692
746
|
// All tasks done but slice not marked complete → summarizing
|
|
@@ -747,7 +801,7 @@ export async function deriveStateFromDb(basePath: string): Promise<GSDState> {
|
|
|
747
801
|
}
|
|
748
802
|
|
|
749
803
|
// ── Blocker detection: check completed tasks for blocker_discovered ──
|
|
750
|
-
const completedTasks = tasks.filter(t =>
|
|
804
|
+
const completedTasks = tasks.filter(t => isStatusDone(t.status));
|
|
751
805
|
let blockerTaskId: string | null = null;
|
|
752
806
|
for (const ct of completedTasks) {
|
|
753
807
|
if (ct.blocker_discovered) {
|
|
@@ -1327,9 +1381,7 @@ export async function _deriveStateImpl(basePath: string): Promise<GSDState> {
|
|
|
1327
1381
|
const summaryPath = resolveTaskFile(basePath, activeMilestone.id, activeSlice.id, t.id, "SUMMARY");
|
|
1328
1382
|
if (summaryPath && existsSync(summaryPath)) {
|
|
1329
1383
|
t.done = true;
|
|
1330
|
-
|
|
1331
|
-
`gsd-reconcile: task ${activeMilestone.id}/${activeSlice.id}/${t.id} has SUMMARY on disk but plan shows incomplete — marking done (#2514)\n`,
|
|
1332
|
-
);
|
|
1384
|
+
logWarning("reconcile", `task ${activeMilestone.id}/${activeSlice.id}/${t.id} reconciled via SUMMARY on disk (#2514)`, { mid: activeMilestone.id, sid: activeSlice.id, tid: t.id });
|
|
1333
1385
|
}
|
|
1334
1386
|
}
|
|
1335
1387
|
|
|
@@ -317,6 +317,35 @@ test("auto/resolve.ts one-shot pattern: _currentResolve is nulled before calling
|
|
|
317
317
|
);
|
|
318
318
|
});
|
|
319
319
|
|
|
320
|
+
test("auto/phases.ts: selectAndApplyModel called exactly once and before updateProgressWidget (#2907)", () => {
|
|
321
|
+
const src = readFileSync(
|
|
322
|
+
resolve(import.meta.dirname, "..", "auto", "phases.ts"),
|
|
323
|
+
"utf-8",
|
|
324
|
+
);
|
|
325
|
+
// Extract the runUnitPhase function body
|
|
326
|
+
const fnStart = src.indexOf("export async function runUnitPhase");
|
|
327
|
+
assert.ok(fnStart > 0, "runUnitPhase should exist in phases.ts");
|
|
328
|
+
const fnBody = src.slice(fnStart, fnStart + 8000);
|
|
329
|
+
|
|
330
|
+
// selectAndApplyModel must appear exactly once
|
|
331
|
+
const allOccurrences = [...fnBody.matchAll(/selectAndApplyModel\(/g)];
|
|
332
|
+
assert.equal(
|
|
333
|
+
allOccurrences.length,
|
|
334
|
+
1,
|
|
335
|
+
`selectAndApplyModel should be called exactly once in runUnitPhase, found ${allOccurrences.length} calls`,
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
// selectAndApplyModel must appear BEFORE updateProgressWidget
|
|
339
|
+
const modelIdx = fnBody.indexOf("selectAndApplyModel(");
|
|
340
|
+
const widgetIdx = fnBody.indexOf("updateProgressWidget(");
|
|
341
|
+
assert.ok(modelIdx > 0, "selectAndApplyModel should exist in runUnitPhase");
|
|
342
|
+
assert.ok(widgetIdx > 0, "updateProgressWidget should exist in runUnitPhase");
|
|
343
|
+
assert.ok(
|
|
344
|
+
modelIdx < widgetIdx,
|
|
345
|
+
"selectAndApplyModel must be called BEFORE updateProgressWidget (#2899/#2907)",
|
|
346
|
+
);
|
|
347
|
+
});
|
|
348
|
+
|
|
320
349
|
// ─── autoLoop tests (T02) ─────────────────────────────────────────────────
|
|
321
350
|
|
|
322
351
|
/**
|