gsd-pi 2.57.0-dev.f22a903 → 2.58.0-dev.778d6ac
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli.js +49 -35
- package/dist/headless-ui.d.ts +17 -0
- package/dist/headless-ui.js +97 -3
- package/dist/headless.js +67 -6
- package/dist/help-text.js +1 -0
- package/dist/onboarding.js +44 -0
- package/dist/resource-loader.js +16 -1
- package/dist/resources/agents/researcher.md +1 -1
- package/dist/resources/extensions/ask-user-questions.js +16 -3
- package/dist/resources/extensions/async-jobs/extension-manifest.json +1 -1
- package/dist/resources/extensions/bg-shell/extension-manifest.json +1 -1
- package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +14 -6
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +59 -36
- package/dist/resources/extensions/context7/extension-manifest.json +1 -1
- package/dist/resources/extensions/get-secrets-from-user.js +8 -5
- package/dist/resources/extensions/google-search/extension-manifest.json +1 -1
- package/dist/resources/extensions/google-search/index.js +2 -1
- package/dist/resources/extensions/gsd/auto/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 +196 -12
- package/dist/resources/extensions/gsd/auto.js +4 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -8
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -18
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +44 -11
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -0
- package/dist/resources/extensions/gsd/captures.js +56 -4
- package/dist/resources/extensions/gsd/db-writer.js +116 -8
- package/dist/resources/extensions/gsd/doctor-git-checks.js +28 -0
- package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +5 -4
- package/dist/resources/extensions/gsd/doctor.js +3 -1
- package/dist/resources/extensions/gsd/error-classifier.js +13 -10
- package/dist/resources/extensions/gsd/extension-manifest.json +16 -1
- package/dist/resources/extensions/gsd/forensics.js +123 -20
- package/dist/resources/extensions/gsd/git-service.js +23 -1
- package/dist/resources/extensions/gsd/gitignore.js +33 -0
- package/dist/resources/extensions/gsd/gsd-db.js +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 +17 -0
- package/dist/resources/extensions/gsd/notifications.js +16 -1
- package/dist/resources/extensions/gsd/parallel-eligibility.js +13 -2
- package/dist/resources/extensions/gsd/parallel-merge.js +78 -5
- package/dist/resources/extensions/gsd/parsers-legacy.js +20 -3
- package/dist/resources/extensions/gsd/paths.js +43 -0
- package/dist/resources/extensions/gsd/preferences-models.js +14 -1
- package/dist/resources/extensions/gsd/preferences-types.js +2 -1
- package/dist/resources/extensions/gsd/preferences.js +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/workflow-manifest.js +24 -5
- package/dist/resources/extensions/gsd/workflow-projections.js +95 -63
- package/dist/resources/extensions/gsd/workflow-reconcile.js +35 -5
- package/dist/resources/extensions/gsd/workspace-index.js +24 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +105 -1
- package/dist/resources/extensions/gsd/worktree-resolver.js +20 -3
- package/dist/resources/extensions/mcp-client/index.js +11 -7
- package/dist/resources/extensions/ollama/index.js +112 -0
- package/dist/resources/extensions/ollama/model-capabilities.js +115 -0
- package/dist/resources/extensions/ollama/ollama-client.js +168 -0
- package/dist/resources/extensions/ollama/ollama-commands.js +194 -0
- package/dist/resources/extensions/ollama/ollama-discovery.js +69 -0
- package/dist/resources/extensions/ollama/ollama-tool.js +184 -0
- package/dist/resources/extensions/ollama/types.js +2 -0
- package/dist/resources/extensions/search-the-web/extension-manifest.json +1 -1
- package/dist/resources/extensions/shared/interview-ui.js +11 -1
- package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -3
- package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
- package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
- package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
- package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
- package/dist/startup-model-validation.d.ts +39 -0
- package/dist/startup-model-validation.js +50 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +16 -16
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error/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_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 +2 -2
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- 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 +2 -2
- 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_client-reference-manifest.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_client-reference-manifest.js +1 -1
- 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_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_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_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_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_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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.js +1 -1
- 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_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_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_client-reference-manifest.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_client-reference-manifest.js +1 -1
- 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_client-reference-manifest.js +1 -1
- 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_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 +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
- 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 +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +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 +16 -16
- package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +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/{webpack-61d3afac6d0f0ce7.js → webpack-a1c1e452c6b32d04.js} +1 -1
- package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +1 -0
- package/dist/web-mode.js +2 -1
- package/package.json +2 -2
- package/packages/daemon/src/cli.ts +49 -0
- package/packages/daemon/src/daemon.test.ts +104 -1
- package/packages/daemon/src/daemon.ts +24 -1
- package/packages/daemon/src/discord-bot.ts +73 -3
- package/packages/daemon/src/event-bridge.ts +15 -9
- package/packages/daemon/src/event-formatter.ts +30 -2
- package/packages/daemon/src/index.ts +9 -0
- package/packages/daemon/src/launchd.test.ts +356 -0
- package/packages/daemon/src/launchd.ts +242 -0
- package/packages/daemon/src/message-batcher.test.ts +2 -2
- package/packages/daemon/src/message-batcher.ts +9 -3
- package/packages/daemon/src/orchestrator.test.ts +1 -0
- package/packages/daemon/src/orchestrator.ts +106 -2
- package/packages/native/dist/ast/index.js +9 -5
- package/packages/native/dist/ast/types.js +2 -1
- package/packages/native/dist/clipboard/index.js +12 -7
- package/packages/native/dist/clipboard/types.js +2 -1
- package/packages/native/dist/diff/index.js +12 -7
- package/packages/native/dist/diff/types.js +2 -1
- package/packages/native/dist/fd/index.js +6 -3
- package/packages/native/dist/fd/types.js +2 -1
- package/packages/native/dist/glob/index.js +9 -5
- package/packages/native/dist/glob/types.js +2 -1
- package/packages/native/dist/grep/index.js +9 -5
- package/packages/native/dist/grep/types.js +2 -1
- package/packages/native/dist/gsd-parser/index.js +18 -11
- package/packages/native/dist/gsd-parser/types.js +2 -1
- package/packages/native/dist/highlight/index.js +12 -7
- package/packages/native/dist/highlight/types.js +2 -1
- package/packages/native/dist/html/index.js +6 -3
- package/packages/native/dist/html/types.js +2 -1
- package/packages/native/dist/image/index.js +10 -5
- package/packages/native/dist/image/types.js +7 -4
- package/packages/native/dist/index.js +70 -17
- package/packages/native/dist/json-parse/index.js +13 -8
- package/packages/native/dist/native.js +47 -10
- package/packages/native/dist/ps/index.js +15 -9
- package/packages/native/dist/ps/types.js +2 -1
- package/packages/native/dist/stream-process/index.js +12 -7
- package/packages/native/dist/text/index.js +24 -14
- package/packages/native/dist/text/types.js +5 -2
- package/packages/native/dist/truncate/index.js +12 -7
- package/packages/native/dist/ttsr/index.js +12 -7
- package/packages/native/dist/ttsr/types.js +2 -1
- package/packages/native/dist/xxhash/index.js +9 -5
- package/packages/native/package.json +19 -19
- package/packages/native/src/__tests__/module-compat.test.mjs +91 -0
- package/packages/native/src/native.ts +9 -8
- package/packages/pi-agent-core/dist/agent-loop.js +3 -2
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/proxy.d.ts +1 -1
- package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/proxy.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +45 -0
- package/packages/pi-agent-core/src/agent-loop.ts +3 -2
- package/packages/pi-agent-core/src/proxy.ts +1 -1
- package/packages/pi-ai/dist/env-api-keys.js +1 -0
- package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
- package/packages/pi-ai/dist/index.d.ts +1 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -0
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +19 -2
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js +25 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -0
- package/packages/pi-ai/dist/types.d.ts +3 -3
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.d.ts +3 -0
- package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.js +24 -1
- package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
- package/packages/pi-ai/dist/utils/repair-tool-json.d.ts +37 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.js +75 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +73 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -0
- package/packages/pi-ai/src/env-api-keys.ts +1 -0
- package/packages/pi-ai/src/index.ts +1 -0
- package/packages/pi-ai/src/providers/anthropic-shared.test.ts +29 -0
- package/packages/pi-ai/src/providers/anthropic-shared.ts +17 -2
- package/packages/pi-ai/src/types.ts +3 -2
- package/packages/pi-ai/src/utils/json-parse.ts +28 -1
- package/packages/pi-ai/src/utils/repair-tool-json.ts +88 -0
- package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +102 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +31 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +17 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +62 -2
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +176 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/exec.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/exec.js +3 -1
- package/packages/pi-coding-agent/dist/core/exec.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts +28 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js +37 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js +63 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts +19 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js +115 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js +109 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.js +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +5 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts +44 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js +97 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js +181 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/index.js +1 -1
- package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/index.js +3 -0
- package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -0
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.js +31 -2
- package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.test.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/messages.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/messages.test.js +86 -0
- package/packages/pi-coding-agent/dist/core/messages.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +10 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +12 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +48 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +193 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +10 -3
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js +13 -4
- package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts +16 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +80 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts +2 -2
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js +5 -0
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +38 -1
- package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +236 -0
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +94 -1
- package/packages/pi-coding-agent/src/core/exec.ts +3 -1
- package/packages/pi-coding-agent/src/core/extensions/extension-manifest.test.ts +77 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-manifest.ts +62 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-sort.test.ts +134 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-sort.ts +137 -0
- package/packages/pi-coding-agent/src/core/extensions/index.ts +4 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
- package/packages/pi-coding-agent/src/core/image-overflow-recovery.test.ts +228 -0
- package/packages/pi-coding-agent/src/core/image-overflow-recovery.ts +118 -0
- package/packages/pi-coding-agent/src/core/index.ts +6 -0
- package/packages/pi-coding-agent/src/core/lsp/index.ts +3 -0
- package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -0
- package/packages/pi-coding-agent/src/core/messages.test.ts +114 -0
- package/packages/pi-coding-agent/src/core/messages.ts +29 -2
- package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
- package/packages/pi-coding-agent/src/core/resource-loader.ts +20 -1
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +255 -0
- package/packages/pi-coding-agent/src/core/retry-handler.ts +52 -1
- package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +11 -3
- package/packages/pi-coding-agent/src/core/tools/read.ts +14 -4
- package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +92 -0
- package/packages/pi-coding-agent/src/index.ts +6 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +7 -0
- package/packages/pi-coding-agent/src/modes/rpc/remote-terminal.ts +6 -0
- package/packages/pi-tui/dist/terminal.d.ts +2 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +9 -0
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +9 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/terminal.ts +14 -0
- package/packages/pi-tui/src/tui.ts +8 -0
- package/pkg/package.json +1 -1
- package/scripts/ensure-workspace-builds.cjs +45 -14
- package/src/resources/agents/researcher.md +1 -1
- package/src/resources/extensions/ask-user-questions.ts +21 -3
- package/src/resources/extensions/async-jobs/extension-manifest.json +1 -1
- package/src/resources/extensions/bg-shell/extension-manifest.json +1 -1
- package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +13 -6
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +63 -35
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +28 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -1
- package/src/resources/extensions/context7/extension-manifest.json +1 -1
- package/src/resources/extensions/get-secrets-from-user.ts +8 -5
- package/src/resources/extensions/google-search/extension-manifest.json +1 -1
- package/src/resources/extensions/google-search/index.ts +2 -1
- package/src/resources/extensions/gsd/auto/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 +190 -9
- package/src/resources/extensions/gsd/auto.ts +5 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +31 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +85 -8
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +38 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +31 -19
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +50 -11
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +75 -0
- package/src/resources/extensions/gsd/captures.ts +63 -3
- package/src/resources/extensions/gsd/db-writer.ts +140 -7
- package/src/resources/extensions/gsd/doctor-git-checks.ts +26 -0
- package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +5 -4
- package/src/resources/extensions/gsd/doctor.ts +3 -1
- package/src/resources/extensions/gsd/error-classifier.ts +14 -11
- package/src/resources/extensions/gsd/extension-manifest.json +16 -1
- package/src/resources/extensions/gsd/forensics.ts +144 -20
- package/src/resources/extensions/gsd/git-service.ts +26 -3
- package/src/resources/extensions/gsd/gitignore.ts +33 -0
- package/src/resources/extensions/gsd/gsd-db.ts +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 +17 -0
- package/src/resources/extensions/gsd/notifications.ts +16 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +15 -2
- package/src/resources/extensions/gsd/parallel-merge.ts +87 -4
- package/src/resources/extensions/gsd/parsers-legacy.ts +22 -3
- package/src/resources/extensions/gsd/paths.ts +42 -0
- package/src/resources/extensions/gsd/preferences-models.ts +14 -1
- package/src/resources/extensions/gsd/preferences-types.ts +2 -1
- package/src/resources/extensions/gsd/preferences.ts +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 +47 -0
- package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +71 -1
- package/src/resources/extensions/gsd/tests/captures.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/completion-hierarchy-guards.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +131 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +7 -12
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +78 -5
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +129 -0
- package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +96 -0
- package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +125 -12
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +164 -0
- package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +135 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +111 -1
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-false-positives.test.ts +243 -0
- package/src/resources/extensions/gsd/tests/integration/gitignore-staging-2570.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +959 -0
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +85 -2
- package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/model-router.test.ts +68 -3
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/notifications.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +159 -0
- package/src/resources/extensions/gsd/tests/parallel-eligibility-ghost.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/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/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/workflow-logger.ts +3 -1
- package/src/resources/extensions/gsd/workflow-manifest.ts +22 -5
- package/src/resources/extensions/gsd/workflow-projections.ts +97 -64
- package/src/resources/extensions/gsd/workflow-reconcile.ts +39 -10
- package/src/resources/extensions/gsd/workspace-index.ts +30 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +120 -1
- package/src/resources/extensions/gsd/worktree-resolver.ts +22 -3
- package/src/resources/extensions/mcp-client/index.ts +13 -7
- package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +55 -0
- package/src/resources/extensions/ollama/index.ts +130 -0
- package/src/resources/extensions/ollama/model-capabilities.ts +145 -0
- package/src/resources/extensions/ollama/ollama-client.ts +196 -0
- package/src/resources/extensions/ollama/ollama-commands.ts +248 -0
- package/src/resources/extensions/ollama/ollama-discovery.ts +106 -0
- package/src/resources/extensions/ollama/ollama-tool.ts +218 -0
- package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +162 -0
- package/src/resources/extensions/ollama/tests/ollama-client.test.ts +38 -0
- package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +28 -0
- package/src/resources/extensions/ollama/types.ts +130 -0
- package/src/resources/extensions/search-the-web/extension-manifest.json +1 -1
- package/src/resources/extensions/shared/interview-ui.ts +12 -1
- package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +156 -0
- package/src/resources/skills/create-gsd-extension/SKILL.md +5 -3
- package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
- package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
- package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
- package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
- package/dist/web/standalone/.next/static/chunks/6502.8b732f67a11b11b4.js +0 -9
- 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/{OS7_z6QaL6uqp8q5pjHSJ → R0D4xaIPl5kg93edN7Oo0}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{OS7_z6QaL6uqp8q5pjHSJ → R0D4xaIPl5kg93edN7Oo0}/_ssgManifest.js +0 -0
|
@@ -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
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { createHash } from "node:crypto";
|
|
9
9
|
import { execFileSync } from "node:child_process";
|
|
10
|
-
import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
10
|
+
import { cpSync, existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, renameSync, rmSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
11
11
|
import { homedir } from "node:os";
|
|
12
12
|
import { basename, dirname, join, resolve } from "node:path";
|
|
13
13
|
const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
|
|
@@ -255,9 +255,14 @@ export function validateProjectId(id) {
|
|
|
255
255
|
* If `GSD_PROJECT_ID` is set, returns it directly (validation is expected
|
|
256
256
|
* to have already happened at startup via `validateProjectId`).
|
|
257
257
|
*
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
*
|
|
258
|
+
* For repos with a remote URL, returns SHA-256 of the remote URL only —
|
|
259
|
+
* this makes the identity stable across directory moves/renames (#2750).
|
|
260
|
+
*
|
|
261
|
+
* For local-only repos (no remote), includes the git root in the hash.
|
|
262
|
+
* Local repos use a `.gsd-id` marker file for recovery after moves.
|
|
263
|
+
*
|
|
264
|
+
* Deterministic: same repo always produces the same hash regardless of
|
|
265
|
+
* which worktree the caller is inside.
|
|
261
266
|
*/
|
|
262
267
|
export function repoIdentity(basePath) {
|
|
263
268
|
const projectId = process.env.GSD_PROJECT_ID;
|
|
@@ -265,8 +270,14 @@ export function repoIdentity(basePath) {
|
|
|
265
270
|
return projectId;
|
|
266
271
|
}
|
|
267
272
|
const remoteUrl = getRemoteUrl(basePath);
|
|
273
|
+
if (remoteUrl) {
|
|
274
|
+
// Remote URL alone uniquely identifies the repo — path is redundant.
|
|
275
|
+
// This makes moves transparent for repos with remotes (#2750).
|
|
276
|
+
return createHash("sha256").update(remoteUrl).digest("hex").slice(0, 12);
|
|
277
|
+
}
|
|
278
|
+
// Local-only repo: include git root since there's no remote to anchor identity.
|
|
268
279
|
const root = resolveGitRoot(basePath);
|
|
269
|
-
const input =
|
|
280
|
+
const input = `\n${root}`;
|
|
270
281
|
return createHash("sha256").update(input).digest("hex").slice(0, 12);
|
|
271
282
|
}
|
|
272
283
|
// ─── External State Directory ───────────────────────────────────────────────
|
|
@@ -325,20 +336,149 @@ export function cleanNumberedGsdVariants(projectPath) {
|
|
|
325
336
|
}
|
|
326
337
|
return removed;
|
|
327
338
|
}
|
|
339
|
+
// ─── .gsd-id Marker ─────────────────────────────────────────────────────────
|
|
340
|
+
/**
|
|
341
|
+
* Write a `.gsd-id` marker file in the project root.
|
|
342
|
+
*
|
|
343
|
+
* This file records the identity hash used for the external state directory.
|
|
344
|
+
* For local-only repos (no remote), this marker survives directory moves and
|
|
345
|
+
* enables automatic recovery of orphaned state (#2750).
|
|
346
|
+
*
|
|
347
|
+
* The marker is gitignored by ensureGitignore(). Non-fatal: failure to write
|
|
348
|
+
* the marker must never block project setup.
|
|
349
|
+
*/
|
|
350
|
+
function writeGsdIdMarker(projectPath, identity) {
|
|
351
|
+
try {
|
|
352
|
+
const markerPath = join(projectPath, ".gsd-id");
|
|
353
|
+
// Only write if content differs to avoid unnecessary disk writes.
|
|
354
|
+
if (existsSync(markerPath)) {
|
|
355
|
+
try {
|
|
356
|
+
if (readFileSync(markerPath, "utf-8").trim() === identity)
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
catch { /* fall through and overwrite */ }
|
|
360
|
+
}
|
|
361
|
+
writeFileSync(markerPath, identity + "\n", "utf-8");
|
|
362
|
+
}
|
|
363
|
+
catch {
|
|
364
|
+
// Non-fatal — marker write failure should not block project setup
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Read the `.gsd-id` marker from the project root.
|
|
369
|
+
* Returns the identity hash, or null if the marker doesn't exist or is unreadable.
|
|
370
|
+
*/
|
|
371
|
+
function readGsdIdMarker(projectPath) {
|
|
372
|
+
try {
|
|
373
|
+
const markerPath = join(projectPath, ".gsd-id");
|
|
374
|
+
if (!existsSync(markerPath))
|
|
375
|
+
return null;
|
|
376
|
+
const content = readFileSync(markerPath, "utf-8").trim();
|
|
377
|
+
return /^[a-zA-Z0-9_-]+$/.test(content) ? content : null;
|
|
378
|
+
}
|
|
379
|
+
catch {
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Check whether an external state directory has meaningful content.
|
|
385
|
+
* Returns true if the directory contains any files or subdirectories
|
|
386
|
+
* beyond just repo-meta.json.
|
|
387
|
+
*/
|
|
388
|
+
function hasProjectState(externalPath) {
|
|
389
|
+
try {
|
|
390
|
+
if (!existsSync(externalPath))
|
|
391
|
+
return false;
|
|
392
|
+
const entries = readdirSync(externalPath);
|
|
393
|
+
return entries.some(e => e !== "repo-meta.json");
|
|
394
|
+
}
|
|
395
|
+
catch {
|
|
396
|
+
return false;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Resolve the external state directory, with recovery for relocated projects.
|
|
401
|
+
*
|
|
402
|
+
* For local-only repos where the computed identity produces an empty state dir,
|
|
403
|
+
* checks the `.gsd-id` marker for the original identity hash and recovers
|
|
404
|
+
* the old state directory if it still exists and contains data (#2750).
|
|
405
|
+
*
|
|
406
|
+
* Returns the resolved external path (may differ from the computed identity).
|
|
407
|
+
*/
|
|
408
|
+
function resolveExternalPathWithRecovery(projectPath) {
|
|
409
|
+
const computedPath = externalGsdRoot(projectPath);
|
|
410
|
+
const computedId = repoIdentity(projectPath);
|
|
411
|
+
// Check if computed path already has state — fast path, no recovery needed.
|
|
412
|
+
if (hasProjectState(computedPath)) {
|
|
413
|
+
return computedPath;
|
|
414
|
+
}
|
|
415
|
+
// Check for .gsd-id marker from a previous location.
|
|
416
|
+
const markerId = readGsdIdMarker(projectPath);
|
|
417
|
+
if (markerId && markerId !== computedId) {
|
|
418
|
+
// The marker points to a different identity — the repo was likely moved.
|
|
419
|
+
const base = process.env.GSD_STATE_DIR || gsdHome;
|
|
420
|
+
const markerPath = join(base, "projects", markerId);
|
|
421
|
+
if (hasProjectState(markerPath)) {
|
|
422
|
+
// Recover: use the old state directory and update the marker to the new identity.
|
|
423
|
+
// Move the state from the old hash dir to the new one so future lookups work
|
|
424
|
+
// without the marker.
|
|
425
|
+
try {
|
|
426
|
+
mkdirSync(computedPath, { recursive: true });
|
|
427
|
+
const entries = readdirSync(markerPath);
|
|
428
|
+
for (const entry of entries) {
|
|
429
|
+
try {
|
|
430
|
+
const src = join(markerPath, entry);
|
|
431
|
+
const dst = join(computedPath, entry);
|
|
432
|
+
// Use rename for same-filesystem (fast) or fall back to copy.
|
|
433
|
+
try {
|
|
434
|
+
renameSync(src, dst);
|
|
435
|
+
}
|
|
436
|
+
catch {
|
|
437
|
+
cpSync(src, dst, { recursive: true, force: true });
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
catch { /* continue with remaining entries */ }
|
|
441
|
+
}
|
|
442
|
+
// Clean up old directory after successful migration.
|
|
443
|
+
try {
|
|
444
|
+
rmSync(markerPath, { recursive: true, force: true });
|
|
445
|
+
}
|
|
446
|
+
catch { /* non-fatal */ }
|
|
447
|
+
}
|
|
448
|
+
catch {
|
|
449
|
+
// If migration fails, just point at the old directory.
|
|
450
|
+
return markerPath;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
return computedPath;
|
|
455
|
+
}
|
|
328
456
|
// ─── Symlink Management ─────────────────────────────────────────────────────
|
|
329
457
|
/**
|
|
330
458
|
* Ensure the `<project>/.gsd` symlink points to the external state directory.
|
|
331
459
|
*
|
|
332
460
|
* 1. Clean up any macOS numbered collision variants (`.gsd 2`, `.gsd 3`, etc.)
|
|
333
|
-
* 2.
|
|
334
|
-
* 3.
|
|
335
|
-
* 4. If `<project>/.gsd`
|
|
336
|
-
* 5. If `<project>/.gsd` is
|
|
461
|
+
* 2. Resolve external dir (with relocation recovery via `.gsd-id` marker)
|
|
462
|
+
* 3. mkdir -p the external dir
|
|
463
|
+
* 4. If `<project>/.gsd` doesn't exist → create symlink
|
|
464
|
+
* 5. If `<project>/.gsd` is already the correct symlink → no-op
|
|
465
|
+
* 6. If `<project>/.gsd` is a real directory → return as-is (migration handles later)
|
|
466
|
+
* 7. Write `.gsd-id` marker for future relocation recovery
|
|
337
467
|
*
|
|
338
468
|
* Returns the resolved external path.
|
|
339
469
|
*/
|
|
340
470
|
export function ensureGsdSymlink(projectPath) {
|
|
341
|
-
const
|
|
471
|
+
const result = ensureGsdSymlinkCore(projectPath);
|
|
472
|
+
// Write .gsd-id marker so future relocations can recover this state (#2750).
|
|
473
|
+
// Only write for the project root (not subdirectories or worktrees that
|
|
474
|
+
// delegate to a parent .gsd).
|
|
475
|
+
if (!isInsideWorktree(projectPath)) {
|
|
476
|
+
writeGsdIdMarker(projectPath, repoIdentity(projectPath));
|
|
477
|
+
}
|
|
478
|
+
return result;
|
|
479
|
+
}
|
|
480
|
+
function ensureGsdSymlinkCore(projectPath) {
|
|
481
|
+
const externalPath = resolveExternalPathWithRecovery(projectPath);
|
|
342
482
|
const localGsd = join(projectPath, ".gsd");
|
|
343
483
|
const inWorktree = isInsideWorktree(projectPath);
|
|
344
484
|
// Guard: Never create a symlink at ~/.gsd — that's the user-level GSD home,
|
|
@@ -387,11 +527,34 @@ export function ensureGsdSymlink(projectPath) {
|
|
|
387
527
|
writeRepoMeta(externalPath, getRemoteUrl(projectPath), resolveGitRoot(projectPath));
|
|
388
528
|
const replaceWithSymlink = () => {
|
|
389
529
|
rmSync(localGsd, { recursive: true, force: true });
|
|
530
|
+
// Defensive: remove any residual entry (e.g. dangling symlink) before creating.
|
|
531
|
+
try {
|
|
532
|
+
unlinkSync(localGsd);
|
|
533
|
+
}
|
|
534
|
+
catch { /* already gone */ }
|
|
390
535
|
symlinkSync(externalPath, localGsd, "junction");
|
|
391
536
|
return externalPath;
|
|
392
537
|
};
|
|
538
|
+
// Check for dangling symlinks (e.g. after relocation recovery removed the old
|
|
539
|
+
// state dir). existsSync follows symlinks, so it returns false for dangling ones.
|
|
540
|
+
// lstatSync does NOT follow, so we can detect the dangling symlink and replace it.
|
|
393
541
|
if (!existsSync(localGsd)) {
|
|
394
|
-
|
|
542
|
+
try {
|
|
543
|
+
const stat = lstatSync(localGsd);
|
|
544
|
+
if (stat.isSymbolicLink()) {
|
|
545
|
+
// Dangling symlink — replace with correct one (#2750).
|
|
546
|
+
return replaceWithSymlink();
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
catch {
|
|
550
|
+
// lstat also failed — nothing exists at this path
|
|
551
|
+
}
|
|
552
|
+
// Nothing exists yet — create symlink.
|
|
553
|
+
// Defensive: remove any residual entry to avoid EEXIST race (#2750).
|
|
554
|
+
try {
|
|
555
|
+
unlinkSync(localGsd);
|
|
556
|
+
}
|
|
557
|
+
catch { /* nothing to remove */ }
|
|
395
558
|
symlinkSync(externalPath, localGsd, "junction");
|
|
396
559
|
return externalPath;
|
|
397
560
|
}
|
|
@@ -408,6 +571,37 @@ export function ensureGsdSymlink(projectPath) {
|
|
|
408
571
|
if (inWorktree) {
|
|
409
572
|
return replaceWithSymlink();
|
|
410
573
|
}
|
|
574
|
+
// After identity hash change (e.g. upgrade from path-based to remote-only
|
|
575
|
+
// hash, or relocation recovery), migrate data from old target to new path
|
|
576
|
+
// and update the symlink (#2750).
|
|
577
|
+
if (!hasProjectState(externalPath) && hasProjectState(target)) {
|
|
578
|
+
try {
|
|
579
|
+
mkdirSync(externalPath, { recursive: true });
|
|
580
|
+
const oldEntries = readdirSync(target);
|
|
581
|
+
for (const entry of oldEntries) {
|
|
582
|
+
try {
|
|
583
|
+
const src = join(target, entry);
|
|
584
|
+
const dst = join(externalPath, entry);
|
|
585
|
+
try {
|
|
586
|
+
renameSync(src, dst);
|
|
587
|
+
}
|
|
588
|
+
catch {
|
|
589
|
+
cpSync(src, dst, { recursive: true, force: true });
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
catch { /* continue */ }
|
|
593
|
+
}
|
|
594
|
+
try {
|
|
595
|
+
rmSync(target, { recursive: true, force: true });
|
|
596
|
+
}
|
|
597
|
+
catch { /* non-fatal */ }
|
|
598
|
+
return replaceWithSymlink();
|
|
599
|
+
}
|
|
600
|
+
catch {
|
|
601
|
+
// Migration failed — preserve old symlink
|
|
602
|
+
return target;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
411
605
|
// Outside worktrees, preserve custom overrides or legacy symlinks.
|
|
412
606
|
return target;
|
|
413
607
|
}
|
|
@@ -16,6 +16,7 @@ import { getParkedReason } from "./milestone-actions.js";
|
|
|
16
16
|
import { getMilestoneSlices, isDbAvailable } from "./gsd-db.js";
|
|
17
17
|
import { buildExistingMilestonesContext } from "./guided-flow-queue.js";
|
|
18
18
|
import { loadPrompt } from "./prompt-loader.js";
|
|
19
|
+
import { isGsdGitignored } from "./gitignore.js";
|
|
19
20
|
// ─── Entry Point ──────────────────────────────────────────────────────────────
|
|
20
21
|
export async function handleRethink(_args, ctx, pi) {
|
|
21
22
|
if (isAutoActive()) {
|
|
@@ -38,9 +39,13 @@ export async function handleRethink(_args, ctx, pi) {
|
|
|
38
39
|
const queueOrder = loadQueueOrder(basePath);
|
|
39
40
|
const rethinkData = buildRethinkData(basePath, milestoneIds, state, queueOrder);
|
|
40
41
|
const existingMilestonesContext = await buildExistingMilestonesContext(basePath, milestoneIds, state);
|
|
42
|
+
const commitInstruction = isGsdGitignored(basePath)
|
|
43
|
+
? "Do not commit planning artifacts — .gsd/ is gitignored in this project."
|
|
44
|
+
: '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)';
|
|
41
45
|
const content = loadPrompt("rethink", {
|
|
42
46
|
rethinkData,
|
|
43
47
|
existingMilestonesContext,
|
|
48
|
+
commitInstruction,
|
|
44
49
|
});
|
|
45
50
|
pi.sendMessage({ customType: "gsd-rethink", content, display: false }, { triggerTurn: true });
|
|
46
51
|
}
|
|
@@ -211,12 +211,13 @@ export function parseRoadmapSlices(content) {
|
|
|
211
211
|
function parseProseSliceHeaders(content) {
|
|
212
212
|
const slices = [];
|
|
213
213
|
// Match H1-H4 headers containing S<digits> with optional "Slice" prefix, bold markers,
|
|
214
|
-
//
|
|
214
|
+
// numeric prefixes (e.g., "1.", "(1)"), bracketed IDs (e.g., "[S01]"),
|
|
215
|
+
// optional checkmark completion marker, and optional leading indentation.
|
|
215
216
|
// Separator after the ID is flexible: colon, dash, em/en dash, dot, or just whitespace.
|
|
216
|
-
const headerPattern =
|
|
217
|
+
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;
|
|
217
218
|
let match;
|
|
218
219
|
// Check for checkmark before the slice ID (e.g., "## checkmark S01: Title")
|
|
219
|
-
const prefixCheckPattern =
|
|
220
|
+
const prefixCheckPattern = /^\s*#{1,4}\s+\*{0,2}\u2713\s+/;
|
|
220
221
|
while ((match = headerPattern.exec(content)) !== null) {
|
|
221
222
|
const id = match[1];
|
|
222
223
|
let title = match[2].trim().replace(/\*{1,2}$/g, "").trim(); // strip trailing bold markers
|
|
@@ -238,7 +239,7 @@ function parseProseSliceHeaders(content) {
|
|
|
238
239
|
}
|
|
239
240
|
// Try to extract depends from prose: "Depends on: S01" or "**Depends on:** S01, S02"
|
|
240
241
|
const afterHeader = content.slice(match.index + match[0].length);
|
|
241
|
-
const nextHeader = afterHeader.search(
|
|
242
|
+
const nextHeader = afterHeader.search(/^\s*#{1,4}\s/m);
|
|
242
243
|
const section = nextHeader !== -1 ? afterHeader.slice(0, nextHeader) : afterHeader.slice(0, 500);
|
|
243
244
|
const depsMatch = section.match(/\*{0,2}Depends\s+on:?\*{0,2}\s*(.+)/i);
|
|
244
245
|
let depends = [];
|
|
@@ -6,20 +6,41 @@ import { parseSummary, loadFile, parseRequirementCounts, parseContextDependsOn,
|
|
|
6
6
|
import { resolveMilestoneFile, resolveSlicePath, resolveSliceFile, resolveTaskFile, resolveTasksDir, resolveGsdRootFile, gsdRoot, } from './paths.js';
|
|
7
7
|
import { findMilestoneIds } from './milestone-ids.js';
|
|
8
8
|
import { loadQueueOrder, sortByQueueOrder } from './queue-order.js';
|
|
9
|
-
import { isClosedStatus } from './status-guards.js';
|
|
10
9
|
import { nativeBatchParseGsdFiles } from './native-parser-bridge.js';
|
|
11
10
|
import { join, resolve } from 'path';
|
|
12
|
-
import { existsSync, readdirSync } from 'node:fs';
|
|
11
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
13
12
|
import { debugCount, debugTime } from './debug-logger.js';
|
|
14
13
|
import { extractVerdict } from './verdict-parser.js';
|
|
15
|
-
import {
|
|
14
|
+
import { logWarning, logError } from './workflow-logger.js';
|
|
15
|
+
import { isDbAvailable, getAllMilestones, getMilestone, getMilestoneSlices, getSliceTasks, getReplanHistory, getSlice, insertMilestone, insertSlice, updateTaskStatus, getPendingSliceGateCount, } from './gsd-db.js';
|
|
16
16
|
/**
|
|
17
17
|
* A "ghost" milestone directory contains only META.json (and no substantive
|
|
18
18
|
* files like CONTEXT, CONTEXT-DRAFT, ROADMAP, or SUMMARY). These appear when
|
|
19
19
|
* a milestone is created but never initialised. Treating them as active causes
|
|
20
20
|
* auto-mode to stall or falsely declare completion.
|
|
21
|
+
*
|
|
22
|
+
* However, a milestone is NOT a ghost if:
|
|
23
|
+
* - It has a DB row with a meaningful status (queued, active, etc.) — the DB
|
|
24
|
+
* knows about it even if content files haven't been created yet.
|
|
25
|
+
* - It has a worktree directory — a worktree proves the milestone was
|
|
26
|
+
* legitimately created and is expected to be populated.
|
|
27
|
+
*
|
|
28
|
+
* Fixes #2921: queued milestones with worktrees were incorrectly classified
|
|
29
|
+
* as ghosts, causing auto-mode to skip them entirely.
|
|
21
30
|
*/
|
|
22
31
|
export function isGhostMilestone(basePath, mid) {
|
|
32
|
+
// If the milestone has a DB row, it's a known milestone — not a ghost.
|
|
33
|
+
if (isDbAvailable()) {
|
|
34
|
+
const dbRow = getMilestone(mid);
|
|
35
|
+
if (dbRow)
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
// If a worktree exists for this milestone, it was legitimately created.
|
|
39
|
+
const root = gsdRoot(basePath);
|
|
40
|
+
const wtPath = join(root, 'worktrees', mid);
|
|
41
|
+
if (existsSync(wtPath))
|
|
42
|
+
return false;
|
|
43
|
+
// Fall back to content-file check: no substantive files means ghost.
|
|
23
44
|
const context = resolveMilestoneFile(basePath, mid, "CONTEXT");
|
|
24
45
|
const draft = resolveMilestoneFile(basePath, mid, "CONTEXT-DRAFT");
|
|
25
46
|
const roadmap = resolveMilestoneFile(basePath, mid, "ROADMAP");
|
|
@@ -140,10 +161,10 @@ export async function deriveState(basePath) {
|
|
|
140
161
|
// Dual-path: try DB-backed derivation first when hierarchy tables are populated
|
|
141
162
|
if (isDbAvailable()) {
|
|
142
163
|
let dbMilestones = getAllMilestones();
|
|
143
|
-
// Disk→DB reconciliation
|
|
144
|
-
// (
|
|
145
|
-
//
|
|
146
|
-
//
|
|
164
|
+
// Disk→DB reconciliation when DB is empty but disk has milestones (#2631).
|
|
165
|
+
// deriveStateFromDb() does its own reconciliation, but deriveState() skips
|
|
166
|
+
// it entirely when the DB is empty. Sync here so the DB path is used when
|
|
167
|
+
// disk milestones exist but haven't been migrated yet.
|
|
147
168
|
if (dbMilestones.length === 0) {
|
|
148
169
|
const diskIds = findMilestoneIds(basePath);
|
|
149
170
|
let synced = false;
|
|
@@ -163,7 +184,7 @@ export async function deriveState(basePath) {
|
|
|
163
184
|
_telemetry.dbDeriveCount++;
|
|
164
185
|
}
|
|
165
186
|
else {
|
|
166
|
-
// DB open but
|
|
187
|
+
// DB open but no milestones on disk either — use filesystem path
|
|
167
188
|
result = await _deriveStateImpl(basePath);
|
|
168
189
|
_telemetry.markdownDeriveCount++;
|
|
169
190
|
}
|
|
@@ -198,6 +219,12 @@ function extractContextTitle(content, fallback) {
|
|
|
198
219
|
return stripMilestonePrefix(h1.slice(2).trim()) || fallback;
|
|
199
220
|
}
|
|
200
221
|
// ─── DB-backed State Derivation ────────────────────────────────────────────
|
|
222
|
+
/**
|
|
223
|
+
* Helper: check if a DB status counts as "done" (handles K002 ambiguity).
|
|
224
|
+
*/
|
|
225
|
+
function isStatusDone(status) {
|
|
226
|
+
return status === 'complete' || status === 'done';
|
|
227
|
+
}
|
|
201
228
|
/**
|
|
202
229
|
* Derive GSD state from the milestones/slices/tasks DB tables.
|
|
203
230
|
* Flag files (PARKED, VALIDATION, CONTINUE, REPLAN, REPLAN-TRIGGER, CONTEXT-DRAFT)
|
|
@@ -226,6 +253,39 @@ export async function deriveStateFromDb(basePath) {
|
|
|
226
253
|
}
|
|
227
254
|
if (synced)
|
|
228
255
|
allMilestones = getAllMilestones();
|
|
256
|
+
// Disk→DB slice reconciliation (#2533): slices defined in ROADMAP.md but
|
|
257
|
+
// missing from the DB cause permanent "No slice eligible" blocks because
|
|
258
|
+
// the dependency resolver only sees DB rows. Parse each milestone's roadmap
|
|
259
|
+
// and insert any missing slices, checking SUMMARY files to set correct status.
|
|
260
|
+
// insertSlice uses INSERT OR IGNORE, so existing rows are never overwritten.
|
|
261
|
+
for (const mid of diskIds) {
|
|
262
|
+
if (isGhostMilestone(basePath, mid))
|
|
263
|
+
continue;
|
|
264
|
+
const roadmapPath = resolveMilestoneFile(basePath, mid, "ROADMAP");
|
|
265
|
+
if (!roadmapPath)
|
|
266
|
+
continue;
|
|
267
|
+
const dbSlices = getMilestoneSlices(mid);
|
|
268
|
+
const dbSliceIds = new Set(dbSlices.map(s => s.id));
|
|
269
|
+
let roadmapContent;
|
|
270
|
+
try {
|
|
271
|
+
roadmapContent = readFileSync(roadmapPath, "utf-8");
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
const parsed = parseRoadmap(roadmapContent);
|
|
277
|
+
for (const s of parsed.slices) {
|
|
278
|
+
if (dbSliceIds.has(s.id))
|
|
279
|
+
continue;
|
|
280
|
+
const summaryPath = resolveSliceFile(basePath, mid, s.id, "SUMMARY");
|
|
281
|
+
const sliceStatus = (s.done || summaryPath) ? "complete" : "pending";
|
|
282
|
+
insertSlice({
|
|
283
|
+
id: s.id, milestoneId: mid, title: s.title,
|
|
284
|
+
status: sliceStatus, risk: s.risk,
|
|
285
|
+
depends: s.depends, demo: s.demo,
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
229
289
|
// Reconcile: discover milestones that exist on disk but are missing from
|
|
230
290
|
// the DB. This happens when milestones were created before the DB migration
|
|
231
291
|
// or were manually added to the filesystem. Without this, disk-only
|
|
@@ -281,7 +341,7 @@ export async function deriveStateFromDb(basePath) {
|
|
|
281
341
|
parkedMilestoneIds.add(m.id);
|
|
282
342
|
continue;
|
|
283
343
|
}
|
|
284
|
-
if (
|
|
344
|
+
if (isStatusDone(m.status)) {
|
|
285
345
|
completeMilestoneIds.add(m.id);
|
|
286
346
|
continue;
|
|
287
347
|
}
|
|
@@ -293,7 +353,7 @@ export async function deriveStateFromDb(basePath) {
|
|
|
293
353
|
}
|
|
294
354
|
// Check roadmap: all slices done means milestone is complete
|
|
295
355
|
const slices = getMilestoneSlices(m.id);
|
|
296
|
-
if (slices.length > 0 && slices.every(s =>
|
|
356
|
+
if (slices.length > 0 && slices.every(s => isStatusDone(s.status))) {
|
|
297
357
|
// All slices done but no summary — still counts as complete for dep resolution
|
|
298
358
|
// if a summary file exists
|
|
299
359
|
// Note: without summary file, the milestone is in validating/completing state, not complete
|
|
@@ -312,7 +372,7 @@ export async function deriveStateFromDb(basePath) {
|
|
|
312
372
|
}
|
|
313
373
|
// Ghost milestone check: no slices in DB AND no substantive files on disk
|
|
314
374
|
const slices = getMilestoneSlices(m.id);
|
|
315
|
-
if (slices.length === 0 && !
|
|
375
|
+
if (slices.length === 0 && !isStatusDone(m.status)) {
|
|
316
376
|
// Check disk for ghost detection
|
|
317
377
|
if (isGhostMilestone(basePath, m.id))
|
|
318
378
|
continue;
|
|
@@ -333,7 +393,7 @@ export async function deriveStateFromDb(basePath) {
|
|
|
333
393
|
continue;
|
|
334
394
|
}
|
|
335
395
|
// Not complete — determine if it should be active
|
|
336
|
-
const allSlicesDone = slices.length > 0 && slices.every(s =>
|
|
396
|
+
const allSlicesDone = slices.length > 0 && slices.every(s => isStatusDone(s.status));
|
|
337
397
|
// Get title — prefer DB, fall back to context file extraction
|
|
338
398
|
let title = stripMilestonePrefix(m.title) || m.id;
|
|
339
399
|
if (title === m.id) {
|
|
@@ -432,7 +492,8 @@ export async function deriveStateFromDb(basePath) {
|
|
|
432
492
|
? `All milestones complete. ${activeReqs} active requirement${activeReqs === 1 ? '' : 's'} in REQUIREMENTS.md ${activeReqs === 1 ? 'has' : 'have'} not been mapped to a milestone.`
|
|
433
493
|
: 'All milestones complete.';
|
|
434
494
|
return {
|
|
435
|
-
activeMilestone:
|
|
495
|
+
activeMilestone: null,
|
|
496
|
+
lastCompletedMilestone: lastEntry ? { id: lastEntry.id, title: lastEntry.title } : null,
|
|
436
497
|
activeSlice: null, activeTask: null,
|
|
437
498
|
phase: 'complete',
|
|
438
499
|
recentDecisions: [], blockers: [],
|
|
@@ -470,10 +531,7 @@ export async function deriveStateFromDb(basePath) {
|
|
|
470
531
|
};
|
|
471
532
|
}
|
|
472
533
|
// ── All slices done → validating/completing ─────────────────────────
|
|
473
|
-
|
|
474
|
-
// an empty slice array causes a premature phase transition to
|
|
475
|
-
// validating-milestone. See: https://github.com/gsd-build/gsd-2/issues/2667
|
|
476
|
-
const allSlicesDone = activeMilestoneSlices.length > 0 && activeMilestoneSlices.every(s => isClosedStatus(s.status));
|
|
534
|
+
const allSlicesDone = activeMilestoneSlices.every(s => isStatusDone(s.status));
|
|
477
535
|
if (allSlicesDone) {
|
|
478
536
|
const validationFile = resolveMilestoneFile(basePath, activeMilestone.id, "VALIDATION");
|
|
479
537
|
const validationContent = validationFile ? await loadFile(validationFile) : null;
|
|
@@ -503,14 +561,14 @@ export async function deriveStateFromDb(basePath) {
|
|
|
503
561
|
}
|
|
504
562
|
// ── Find active slice (first incomplete with deps satisfied) ─────────
|
|
505
563
|
const sliceProgress = {
|
|
506
|
-
done: activeMilestoneSlices.filter(s =>
|
|
564
|
+
done: activeMilestoneSlices.filter(s => isStatusDone(s.status)).length,
|
|
507
565
|
total: activeMilestoneSlices.length,
|
|
508
566
|
};
|
|
509
|
-
const doneSliceIds = new Set(activeMilestoneSlices.filter(s =>
|
|
567
|
+
const doneSliceIds = new Set(activeMilestoneSlices.filter(s => isStatusDone(s.status)).map(s => s.id));
|
|
510
568
|
let activeSlice = null;
|
|
511
569
|
let activeSliceRow = null;
|
|
512
570
|
for (const s of activeMilestoneSlices) {
|
|
513
|
-
if (
|
|
571
|
+
if (isStatusDone(s.status))
|
|
514
572
|
continue;
|
|
515
573
|
if (s.depends.every(dep => doneSliceIds.has(dep))) {
|
|
516
574
|
activeSlice = { id: s.id, title: s.title };
|
|
@@ -550,18 +608,18 @@ export async function deriveStateFromDb(basePath) {
|
|
|
550
608
|
// causing the dispatcher to re-dispatch the same completed task forever.
|
|
551
609
|
let reconciled = false;
|
|
552
610
|
for (const t of tasks) {
|
|
553
|
-
if (
|
|
611
|
+
if (isStatusDone(t.status))
|
|
554
612
|
continue;
|
|
555
613
|
const summaryPath = resolveTaskFile(basePath, activeMilestone.id, activeSlice.id, t.id, "SUMMARY");
|
|
556
614
|
if (summaryPath && existsSync(summaryPath)) {
|
|
557
615
|
try {
|
|
558
616
|
updateTaskStatus(activeMilestone.id, activeSlice.id, t.id, "complete");
|
|
559
|
-
|
|
617
|
+
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 });
|
|
560
618
|
reconciled = true;
|
|
561
619
|
}
|
|
562
620
|
catch (e) {
|
|
563
621
|
// DB write failed — continue with stale status rather than crash
|
|
564
|
-
|
|
622
|
+
logError("reconcile", `failed to update task ${t.id}`, { tid: t.id, error: e.message });
|
|
565
623
|
}
|
|
566
624
|
}
|
|
567
625
|
}
|
|
@@ -570,10 +628,10 @@ export async function deriveStateFromDb(basePath) {
|
|
|
570
628
|
tasks = getSliceTasks(activeMilestone.id, activeSlice.id);
|
|
571
629
|
}
|
|
572
630
|
const taskProgress = {
|
|
573
|
-
done: tasks.filter(t =>
|
|
631
|
+
done: tasks.filter(t => isStatusDone(t.status)).length,
|
|
574
632
|
total: tasks.length,
|
|
575
633
|
};
|
|
576
|
-
const activeTaskRow = tasks.find(t => !
|
|
634
|
+
const activeTaskRow = tasks.find(t => !isStatusDone(t.status));
|
|
577
635
|
if (!activeTaskRow && tasks.length > 0) {
|
|
578
636
|
// All tasks done but slice not marked complete → summarizing
|
|
579
637
|
return {
|
|
@@ -628,7 +686,7 @@ export async function deriveStateFromDb(basePath) {
|
|
|
628
686
|
};
|
|
629
687
|
}
|
|
630
688
|
// ── Blocker detection: check completed tasks for blocker_discovered ──
|
|
631
|
-
const completedTasks = tasks.filter(t =>
|
|
689
|
+
const completedTasks = tasks.filter(t => isStatusDone(t.status));
|
|
632
690
|
let blockerTaskId = null;
|
|
633
691
|
for (const ct of completedTasks) {
|
|
634
692
|
if (ct.blocker_discovered) {
|
|
@@ -1187,7 +1245,7 @@ export async function _deriveStateImpl(basePath) {
|
|
|
1187
1245
|
const summaryPath = resolveTaskFile(basePath, activeMilestone.id, activeSlice.id, t.id, "SUMMARY");
|
|
1188
1246
|
if (summaryPath && existsSync(summaryPath)) {
|
|
1189
1247
|
t.done = true;
|
|
1190
|
-
|
|
1248
|
+
logWarning("reconcile", `task ${activeMilestone.id}/${activeSlice.id}/${t.id} reconciled via SUMMARY on disk (#2514)`, { mid: activeMilestone.id, sid: activeSlice.id, tid: t.id });
|
|
1191
1249
|
}
|
|
1192
1250
|
}
|
|
1193
1251
|
const taskProgress = {
|
|
@@ -87,7 +87,26 @@ export function load(url, context, nextLoad) {
|
|
|
87
87
|
emitDecoratorMetadata: true,
|
|
88
88
|
},
|
|
89
89
|
});
|
|
90
|
-
|
|
90
|
+
// Inject CJS-compatible globals (__dirname, __filename, require) so that
|
|
91
|
+
// workspace packages compiled as ESM can still use them. This avoids the
|
|
92
|
+
// need for import.meta.url behind indirect invocation patterns that fail in
|
|
93
|
+
// CJS and in dynamically-created scopes.
|
|
94
|
+
// Only inject globals that the source file doesn't already declare itself.
|
|
95
|
+
const preambleLines = [
|
|
96
|
+
'import { fileURLToPath as __preamble_fUTP } from "node:url";',
|
|
97
|
+
'import { dirname as __preamble_dn } from "node:path";',
|
|
98
|
+
'import { createRequire as __preamble_cR } from "node:module";',
|
|
99
|
+
];
|
|
100
|
+
if (!outputText.includes('const __filename') && !outputText.includes('let __filename')) {
|
|
101
|
+
preambleLines.push('const __filename = __preamble_fUTP(import.meta.url);');
|
|
102
|
+
}
|
|
103
|
+
if (!outputText.includes('const __dirname') && !outputText.includes('let __dirname')) {
|
|
104
|
+
preambleLines.push('const __dirname = __preamble_dn(__preamble_fUTP(import.meta.url));');
|
|
105
|
+
}
|
|
106
|
+
if (!outputText.includes('const require') && !outputText.includes('let require')) {
|
|
107
|
+
preambleLines.push('const require = __preamble_cR(import.meta.url);');
|
|
108
|
+
}
|
|
109
|
+
return { format: 'module', source: preambleLines.join('\n') + '\n' + outputText, shortCircuit: true };
|
|
91
110
|
}
|
|
92
111
|
return nextLoad(url, context);
|
|
93
112
|
}
|