gsd-pi 2.57.0 → 2.58.0-dev.394cb18
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 +58 -35
- package/dist/headless-ui.d.ts +17 -0
- package/dist/headless-ui.js +97 -3
- package/dist/headless.js +67 -6
- package/dist/help-text.js +1 -0
- package/dist/onboarding.js +44 -0
- package/dist/resource-loader.js +16 -1
- package/dist/resources/agents/researcher.md +1 -1
- package/dist/resources/extensions/ask-user-questions.js +16 -3
- package/dist/resources/extensions/async-jobs/extension-manifest.json +1 -1
- package/dist/resources/extensions/bg-shell/extension-manifest.json +1 -1
- package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +14 -6
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +59 -36
- package/dist/resources/extensions/context7/extension-manifest.json +1 -1
- package/dist/resources/extensions/get-secrets-from-user.js +8 -5
- package/dist/resources/extensions/google-search/extension-manifest.json +1 -1
- package/dist/resources/extensions/google-search/index.js +2 -1
- package/dist/resources/extensions/gsd/auto/infra-errors.js +4 -0
- package/dist/resources/extensions/gsd/auto/phases.js +25 -21
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
- package/dist/resources/extensions/gsd/auto-dashboard.js +37 -20
- package/dist/resources/extensions/gsd/auto-dispatch.js +20 -5
- package/dist/resources/extensions/gsd/auto-model-selection.js +26 -3
- package/dist/resources/extensions/gsd/auto-post-unit.js +16 -4
- package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
- package/dist/resources/extensions/gsd/auto-recovery.js +13 -5
- package/dist/resources/extensions/gsd/auto-start.js +35 -22
- package/dist/resources/extensions/gsd/auto-worktree.js +206 -14
- package/dist/resources/extensions/gsd/auto.js +4 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +82 -9
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +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/dispatch-guard.js +11 -1
- 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 +44 -10
- package/dist/resources/extensions/gsd/guided-flow.js +106 -44
- package/dist/resources/extensions/gsd/health-widget-core.js +31 -0
- package/dist/resources/extensions/gsd/health-widget.js +17 -0
- package/dist/resources/extensions/gsd/index.js +1 -1
- package/dist/resources/extensions/gsd/memory-extractor.js +7 -0
- package/dist/resources/extensions/gsd/migrate-external.js +8 -1
- package/dist/resources/extensions/gsd/milestone-validation-gates.js +45 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +18 -0
- package/dist/resources/extensions/gsd/model-router.js +35 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +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/parallel-orchestrator.js +23 -6
- 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 +42 -31
- package/dist/resources/extensions/gsd/prompt-loader.js +4 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -2
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -1
- package/dist/resources/extensions/gsd/prompts/forensics.md +2 -2
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -0
- package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -0
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/dist/resources/extensions/gsd/repo-identity.js +205 -11
- package/dist/resources/extensions/gsd/rethink.js +5 -0
- package/dist/resources/extensions/gsd/roadmap-slices.js +5 -4
- package/dist/resources/extensions/gsd/state.js +85 -27
- package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
- package/dist/resources/extensions/gsd/tools/complete-task.js +34 -71
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +12 -2
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +29 -1
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +18 -3
- package/dist/resources/extensions/gsd/triage-resolution.js +22 -7
- package/dist/resources/extensions/gsd/undo.js +2 -2
- package/dist/resources/extensions/gsd/unit-ownership.js +164 -33
- package/dist/resources/extensions/gsd/verdict-parser.js +20 -8
- package/dist/resources/extensions/gsd/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/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 +9 -9
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +5 -5
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
- package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
- package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +9 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-4332cbd5dd1be584.js → webpack-a1c1e452c6b32d04.js} +1 -1
- package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/dist/web-mode.js +2 -1
- package/dist/welcome-screen.d.ts +1 -0
- package/dist/welcome-screen.js +32 -6
- 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/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.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +16 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +1 -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 +27 -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.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +6 -0
- 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/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/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.ts +14 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +35 -3
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +7 -0
- 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/infra-errors.ts +3 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/phases.ts +43 -34
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
- package/src/resources/extensions/gsd/auto-dashboard.ts +37 -19
- package/src/resources/extensions/gsd/auto-dispatch.ts +21 -5
- package/src/resources/extensions/gsd/auto-model-selection.ts +26 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
- package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +12 -5
- package/src/resources/extensions/gsd/auto-start.ts +35 -26
- package/src/resources/extensions/gsd/auto-worktree.ts +200 -11
- package/src/resources/extensions/gsd/auto.ts +5 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +31 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +87 -9
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +38 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +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/dispatch-guard.ts +12 -1
- 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 +49 -8
- package/src/resources/extensions/gsd/guided-flow.ts +114 -45
- package/src/resources/extensions/gsd/health-widget-core.ts +34 -0
- package/src/resources/extensions/gsd/health-widget.ts +17 -0
- package/src/resources/extensions/gsd/index.ts +1 -0
- package/src/resources/extensions/gsd/memory-extractor.ts +8 -0
- package/src/resources/extensions/gsd/migrate-external.ts +9 -1
- package/src/resources/extensions/gsd/milestone-validation-gates.ts +56 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +19 -0
- package/src/resources/extensions/gsd/model-router.ts +35 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +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/parallel-orchestrator.ts +23 -6
- 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 +45 -29
- package/src/resources/extensions/gsd/prompt-loader.ts +4 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -2
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/src/resources/extensions/gsd/prompts/execute-task.md +3 -1
- package/src/resources/extensions/gsd/prompts/forensics.md +2 -2
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -0
- package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
- package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -0
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/src/resources/extensions/gsd/repo-identity.ts +186 -11
- package/src/resources/extensions/gsd/rethink.ts +6 -0
- package/src/resources/extensions/gsd/roadmap-slices.ts +5 -4
- package/src/resources/extensions/gsd/state.ts +84 -32
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +71 -1
- package/src/resources/extensions/gsd/tests/captures.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/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/dispatch-guard.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +129 -0
- package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +96 -0
- package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +125 -12
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +164 -0
- package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +135 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +111 -1
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +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/parallel-worker-monitoring.test.ts +9 -8
- package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/preferences.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +297 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/prompt-loader-replacement.test.ts +178 -0
- package/src/resources/extensions/gsd/tests/prompt-tool-names.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/reconciliation-edge-cases.test.ts +162 -0
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +134 -0
- package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +233 -0
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +305 -0
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +405 -0
- package/src/resources/extensions/gsd/tests/state-derivation-parity.test.ts +257 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +1628 -0
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +174 -0
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +221 -0
- package/src/resources/extensions/gsd/tests/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 +27 -2
- package/src/resources/extensions/gsd/tests/validation-gate-patterns.test.ts +44 -2
- package/src/resources/extensions/gsd/tests/verdict-parser.test.ts +156 -0
- package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +82 -0
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +175 -0
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +48 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +95 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +36 -74
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +13 -1
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +36 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -2
- package/src/resources/extensions/gsd/triage-resolution.ts +23 -6
- package/src/resources/extensions/gsd/types.ts +4 -2
- package/src/resources/extensions/gsd/undo.ts +2 -2
- package/src/resources/extensions/gsd/unit-ownership.ts +206 -35
- package/src/resources/extensions/gsd/verdict-parser.ts +21 -6
- package/src/resources/extensions/gsd/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/shared/interview-ui.ts +12 -1
- package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +156 -0
- package/src/resources/skills/create-gsd-extension/SKILL.md +5 -3
- package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
- package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
- package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
- package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
- package/dist/web/standalone/.next/static/chunks/6502.2305d0afd2385711.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +0 -1
- package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +0 -79
- /package/dist/web/standalone/.next/static/{yowc5qPtuKxjOr22KmOAy → uDm3eO1oo9lDfY2TyoO9t}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{yowc5qPtuKxjOr22KmOAy → uDm3eO1oo9lDfY2TyoO9t}/_ssgManifest.js +0 -0
|
@@ -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
|
/**
|
|
@@ -1233,6 +1262,24 @@ test("startAuto calls selfHealRuntimeRecords before autoLoop (#1727)", { skip: "
|
|
|
1233
1262
|
);
|
|
1234
1263
|
});
|
|
1235
1264
|
|
|
1265
|
+
test("startAuto guards against concurrent invocation (#2923)", () => {
|
|
1266
|
+
const src = readFileSync(
|
|
1267
|
+
resolve(import.meta.dirname, "..", "auto.ts"),
|
|
1268
|
+
"utf-8",
|
|
1269
|
+
);
|
|
1270
|
+
const fnIdx = src.indexOf("export async function startAuto");
|
|
1271
|
+
assert.ok(fnIdx > -1, "startAuto must exist in auto.ts");
|
|
1272
|
+
// The guard must appear before any other logic in the function body
|
|
1273
|
+
const fnBody = src.slice(fnIdx, fnIdx + 500);
|
|
1274
|
+
const activeGuard = fnBody.indexOf("if (s.active)");
|
|
1275
|
+
assert.ok(activeGuard > -1, "startAuto must check s.active to prevent concurrent auto-loops");
|
|
1276
|
+
const returnIdx = fnBody.indexOf("return;", activeGuard);
|
|
1277
|
+
assert.ok(
|
|
1278
|
+
returnIdx > -1 && returnIdx < activeGuard + 120,
|
|
1279
|
+
"s.active guard must early-return to prevent a second concurrent loop",
|
|
1280
|
+
);
|
|
1281
|
+
});
|
|
1282
|
+
|
|
1236
1283
|
test("agent_end handler calls resolveAgentEnd (not handleAgentEnd)", () => {
|
|
1237
1284
|
const hooksSrc = readFileSync(
|
|
1238
1285
|
resolve(import.meta.dirname, "..", "bootstrap", "register-hooks.ts"),
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test: auto-mode prompts must prohibit ask_user_questions / secure_env_collect
|
|
3
|
+
*
|
|
4
|
+
* Bug #2936: When the LLM calls ask_user_questions during auto-mode units
|
|
5
|
+
* (plan-slice, execute-task, complete-slice), the interactive tool queues a
|
|
6
|
+
* user response which causes the subsequent gsd_plan_slice / gsd_complete_task
|
|
7
|
+
* call to fail with "Skipped due to queued user message." The canonical GSD
|
|
8
|
+
* tool call is never recorded, verifyExpectedArtifact finds no artifact, and
|
|
9
|
+
* the dispatch loop re-dispatches the same unit 2-4x.
|
|
10
|
+
*
|
|
11
|
+
* Fix: Each auto-mode prompt must contain an "Autonomous execution" guard
|
|
12
|
+
* that explicitly prohibits ask_user_questions and secure_env_collect.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import test from "node:test";
|
|
16
|
+
import assert from "node:assert/strict";
|
|
17
|
+
import { readFileSync } from "node:fs";
|
|
18
|
+
import { join, dirname } from "node:path";
|
|
19
|
+
import { fileURLToPath } from "node:url";
|
|
20
|
+
|
|
21
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
22
|
+
const promptsDir = join(__dirname, "..", "prompts");
|
|
23
|
+
|
|
24
|
+
function loadPromptRaw(name: string): string {
|
|
25
|
+
return readFileSync(join(promptsDir, `${name}.md`), "utf-8");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const AUTO_MODE_PROMPTS = ["plan-slice", "execute-task", "complete-slice"];
|
|
29
|
+
|
|
30
|
+
for (const promptName of AUTO_MODE_PROMPTS) {
|
|
31
|
+
test(`${promptName} prompt prohibits ask_user_questions in auto-mode`, () => {
|
|
32
|
+
const content = loadPromptRaw(promptName);
|
|
33
|
+
|
|
34
|
+
assert.ok(
|
|
35
|
+
content.includes("ask_user_questions"),
|
|
36
|
+
`${promptName}.md must mention ask_user_questions (to prohibit it)`,
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
assert.ok(
|
|
40
|
+
content.includes("secure_env_collect"),
|
|
41
|
+
`${promptName}.md must mention secure_env_collect (to prohibit it)`,
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// The guard must clearly state this is autonomous / auto-mode
|
|
45
|
+
assert.ok(
|
|
46
|
+
content.toLowerCase().includes("auto-mode") || content.toLowerCase().includes("autonomous"),
|
|
47
|
+
`${promptName}.md must reference auto-mode or autonomous execution`,
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// The guard must indicate no human is available
|
|
51
|
+
assert.ok(
|
|
52
|
+
content.includes("no human") || content.includes("no user"),
|
|
53
|
+
`${promptName}.md must state that no human/user is available to answer`,
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
test("auto-mode prompts contain autonomous guard before final tool call reminder", () => {
|
|
59
|
+
for (const promptName of AUTO_MODE_PROMPTS) {
|
|
60
|
+
const content = loadPromptRaw(promptName);
|
|
61
|
+
|
|
62
|
+
// The guard should appear before the final "MUST call" line
|
|
63
|
+
const guardIndex = content.indexOf("ask_user_questions");
|
|
64
|
+
const mustCallIndex = content.lastIndexOf("MUST call");
|
|
65
|
+
|
|
66
|
+
assert.ok(
|
|
67
|
+
guardIndex !== -1 && mustCallIndex !== -1 && guardIndex < mustCallIndex,
|
|
68
|
+
`${promptName}.md: autonomous guard (ask_user_questions prohibition) must appear before the final MUST call reminder`,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
@@ -4,7 +4,7 @@ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
|
|
7
|
-
import { resolvePreferredModelConfig } from "../auto-model-selection.js";
|
|
7
|
+
import { resolvePreferredModelConfig, resolveModelId } from "../auto-model-selection.js";
|
|
8
8
|
|
|
9
9
|
function makeTempDir(prefix: string): string {
|
|
10
10
|
return mkdtempSync(join(tmpdir(), prefix));
|
|
@@ -137,3 +137,73 @@ test("resolvePreferredModelConfig keeps explicit phase models as the ceiling", (
|
|
|
137
137
|
rmSync(tempGsdHome, { recursive: true, force: true });
|
|
138
138
|
}
|
|
139
139
|
});
|
|
140
|
+
|
|
141
|
+
// ─── resolveModelId tests ─────────────────────────────────────────────────
|
|
142
|
+
|
|
143
|
+
test("resolveModelId: bare ID resolves to anthropic over claude-code when session is claude-code (#2905)", () => {
|
|
144
|
+
const availableModels = [
|
|
145
|
+
{ id: "claude-sonnet-4-6", provider: "anthropic" },
|
|
146
|
+
{ id: "claude-sonnet-4-6", provider: "claude-code" },
|
|
147
|
+
];
|
|
148
|
+
|
|
149
|
+
// Bug: when currentProvider is "claude-code", bare ID "claude-sonnet-4-6"
|
|
150
|
+
// resolves to claude-code/claude-sonnet-4-6 instead of anthropic/claude-sonnet-4-6
|
|
151
|
+
const result = resolveModelId("claude-sonnet-4-6", availableModels, "claude-code");
|
|
152
|
+
assert.ok(result, "should resolve a model");
|
|
153
|
+
assert.equal(result.provider, "anthropic", "bare ID must resolve to anthropic, not claude-code");
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test("resolveModelId: bare ID still prefers current provider when it is a first-class API provider", () => {
|
|
157
|
+
const availableModels = [
|
|
158
|
+
{ id: "claude-sonnet-4-6", provider: "anthropic" },
|
|
159
|
+
{ id: "claude-sonnet-4-6", provider: "bedrock" },
|
|
160
|
+
];
|
|
161
|
+
|
|
162
|
+
const result = resolveModelId("claude-sonnet-4-6", availableModels, "bedrock");
|
|
163
|
+
assert.ok(result, "should resolve a model");
|
|
164
|
+
assert.equal(result.provider, "bedrock", "bare ID should prefer current provider when it is a real API provider");
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test("resolveModelId: explicit provider/model format still resolves to claude-code when specified", () => {
|
|
168
|
+
const availableModels = [
|
|
169
|
+
{ id: "claude-sonnet-4-6", provider: "anthropic" },
|
|
170
|
+
{ id: "claude-sonnet-4-6", provider: "claude-code" },
|
|
171
|
+
];
|
|
172
|
+
|
|
173
|
+
const result = resolveModelId("claude-code/claude-sonnet-4-6", availableModels, "anthropic");
|
|
174
|
+
assert.ok(result, "should resolve a model");
|
|
175
|
+
assert.equal(result.provider, "claude-code", "explicit provider prefix must be respected");
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
test("resolveModelId: bare ID with only one provider works normally", () => {
|
|
179
|
+
const availableModels = [
|
|
180
|
+
{ id: "claude-sonnet-4-6", provider: "anthropic" },
|
|
181
|
+
];
|
|
182
|
+
|
|
183
|
+
const result = resolveModelId("claude-sonnet-4-6", availableModels, "anthropic");
|
|
184
|
+
assert.ok(result, "should resolve a model");
|
|
185
|
+
assert.equal(result.provider, "anthropic");
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
test("resolveModelId: bare ID with claude-code as only provider still resolves", () => {
|
|
189
|
+
const availableModels = [
|
|
190
|
+
{ id: "claude-sonnet-4-6", provider: "claude-code" },
|
|
191
|
+
];
|
|
192
|
+
|
|
193
|
+
// If claude-code is the ONLY provider for this model, it should still resolve
|
|
194
|
+
const result = resolveModelId("claude-sonnet-4-6", availableModels, "claude-code");
|
|
195
|
+
assert.ok(result, "should resolve even when only available via claude-code");
|
|
196
|
+
assert.equal(result.provider, "claude-code");
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test("resolveModelId: anthropic wins over claude-code regardless of list order", () => {
|
|
200
|
+
const availableModels = [
|
|
201
|
+
{ id: "claude-sonnet-4-6", provider: "claude-code" },
|
|
202
|
+
{ id: "claude-sonnet-4-6", provider: "anthropic" },
|
|
203
|
+
];
|
|
204
|
+
|
|
205
|
+
// Even when claude-code appears first in the list, anthropic should win
|
|
206
|
+
const result = resolveModelId("claude-sonnet-4-6", availableModels, "claude-code");
|
|
207
|
+
assert.ok(result, "should resolve a model");
|
|
208
|
+
assert.equal(result.provider, "anthropic", "anthropic must win over claude-code regardless of list order");
|
|
209
|
+
});
|
|
@@ -19,8 +19,11 @@ import {
|
|
|
19
19
|
appendCapture,
|
|
20
20
|
loadAllCaptures,
|
|
21
21
|
loadPendingCaptures,
|
|
22
|
+
loadActionableCaptures,
|
|
22
23
|
hasPendingCaptures,
|
|
23
24
|
markCaptureResolved,
|
|
25
|
+
markCaptureExecuted,
|
|
26
|
+
stampCaptureMilestone,
|
|
24
27
|
resolveCapturesPath,
|
|
25
28
|
parseTriageOutput,
|
|
26
29
|
} from "../captures.ts";
|
|
@@ -419,3 +422,103 @@ test("triage: parseTriageOutput preserves affectedFiles and targetSlice", () =>
|
|
|
419
422
|
assert.strictEqual(results[1].targetSlice, "S04");
|
|
420
423
|
assert.strictEqual(results[1].affectedFiles, undefined);
|
|
421
424
|
});
|
|
425
|
+
|
|
426
|
+
// ─── Stale Quick-Task Captures (#2872) ────────────────────────────────────────
|
|
427
|
+
|
|
428
|
+
test("captures: markCaptureResolved stores milestone ID when provided", (t) => {
|
|
429
|
+
const tmp = makeTempDir("cap-milestone");
|
|
430
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
431
|
+
|
|
432
|
+
const id = appendCapture(tmp, "fix dialog width");
|
|
433
|
+
markCaptureResolved(tmp, id, "quick-task", "widen the dialog", "small fix", "M003");
|
|
434
|
+
|
|
435
|
+
const all = loadAllCaptures(tmp);
|
|
436
|
+
assert.strictEqual(all.length, 1);
|
|
437
|
+
assert.strictEqual(all[0].resolvedInMilestone, "M003", "should store milestone ID");
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
test("captures: loadActionableCaptures excludes captures resolved in prior milestones", (t) => {
|
|
441
|
+
const tmp = makeTempDir("cap-stale-filter");
|
|
442
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
443
|
+
|
|
444
|
+
// Capture resolved in M003 (prior milestone)
|
|
445
|
+
const id1 = appendCapture(tmp, "dialog too narrow");
|
|
446
|
+
markCaptureResolved(tmp, id1, "quick-task", "widen it", "small fix", "M003");
|
|
447
|
+
|
|
448
|
+
// Capture resolved in M004 (current milestone)
|
|
449
|
+
const id2 = appendCapture(tmp, "button misaligned");
|
|
450
|
+
markCaptureResolved(tmp, id2, "quick-task", "fix alignment", "css fix", "M004");
|
|
451
|
+
|
|
452
|
+
// Capture resolved without milestone context (legacy)
|
|
453
|
+
const id3 = appendCapture(tmp, "typo in label");
|
|
454
|
+
markCaptureResolved(tmp, id3, "quick-task", "fix typo", "trivial");
|
|
455
|
+
|
|
456
|
+
// When loading for M004, only M004 and no-milestone captures should be returned
|
|
457
|
+
const actionable = loadActionableCaptures(tmp, "M004");
|
|
458
|
+
const ids = actionable.map(c => c.id);
|
|
459
|
+
|
|
460
|
+
assert.ok(!ids.includes(id1), "should exclude capture resolved in M003");
|
|
461
|
+
assert.ok(ids.includes(id2), "should include capture resolved in M004");
|
|
462
|
+
assert.ok(ids.includes(id3), "should include capture with no milestone (legacy)");
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
test("captures: loadActionableCaptures without milestone returns all actionable", (t) => {
|
|
466
|
+
const tmp = makeTempDir("cap-no-milestone-filter");
|
|
467
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
468
|
+
|
|
469
|
+
const id1 = appendCapture(tmp, "issue one");
|
|
470
|
+
markCaptureResolved(tmp, id1, "quick-task", "fix it", "small", "M003");
|
|
471
|
+
|
|
472
|
+
const id2 = appendCapture(tmp, "issue two");
|
|
473
|
+
markCaptureResolved(tmp, id2, "inject", "inject it", "needed", "M004");
|
|
474
|
+
|
|
475
|
+
// Without milestone filter, all actionable captures are returned (backward compat)
|
|
476
|
+
const actionable = loadActionableCaptures(tmp);
|
|
477
|
+
assert.strictEqual(actionable.length, 2, "should return all actionable without filter");
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
test("captures: loadActionableCaptures excludes already-executed captures", (t) => {
|
|
481
|
+
const tmp = makeTempDir("cap-executed-filter");
|
|
482
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
483
|
+
|
|
484
|
+
const id1 = appendCapture(tmp, "already done");
|
|
485
|
+
markCaptureResolved(tmp, id1, "quick-task", "fix it", "small", "M004");
|
|
486
|
+
markCaptureExecuted(tmp, id1);
|
|
487
|
+
|
|
488
|
+
const id2 = appendCapture(tmp, "still pending");
|
|
489
|
+
markCaptureResolved(tmp, id2, "quick-task", "fix it too", "small", "M004");
|
|
490
|
+
|
|
491
|
+
const actionable = loadActionableCaptures(tmp, "M004");
|
|
492
|
+
assert.strictEqual(actionable.length, 1, "should exclude executed capture");
|
|
493
|
+
assert.strictEqual(actionable[0].id, id2);
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
test("captures: stampCaptureMilestone adds milestone to capture missing it", (t) => {
|
|
497
|
+
const tmp = makeTempDir("cap-stamp-milestone");
|
|
498
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
499
|
+
|
|
500
|
+
const id = appendCapture(tmp, "fix alignment");
|
|
501
|
+
markCaptureResolved(tmp, id, "quick-task", "fix it", "small");
|
|
502
|
+
|
|
503
|
+
// Before stamping, no milestone
|
|
504
|
+
let all = loadAllCaptures(tmp);
|
|
505
|
+
assert.strictEqual(all[0].resolvedInMilestone, undefined, "should have no milestone initially");
|
|
506
|
+
|
|
507
|
+
stampCaptureMilestone(tmp, id, "M004");
|
|
508
|
+
|
|
509
|
+
all = loadAllCaptures(tmp);
|
|
510
|
+
assert.strictEqual(all[0].resolvedInMilestone, "M004", "should have milestone after stamping");
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
test("captures: stampCaptureMilestone is no-op if milestone already present", (t) => {
|
|
514
|
+
const tmp = makeTempDir("cap-stamp-noop");
|
|
515
|
+
t.after(() => rmSync(tmp, { recursive: true, force: true }));
|
|
516
|
+
|
|
517
|
+
const id = appendCapture(tmp, "fix alignment");
|
|
518
|
+
markCaptureResolved(tmp, id, "quick-task", "fix it", "small", "M003");
|
|
519
|
+
|
|
520
|
+
stampCaptureMilestone(tmp, id, "M004");
|
|
521
|
+
|
|
522
|
+
const all = loadAllCaptures(tmp);
|
|
523
|
+
assert.strictEqual(all[0].resolvedInMilestone, "M003", "should keep original milestone");
|
|
524
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cli-provider-rate-limit.test.ts — Verify rate-limit backoff capping
|
|
3
|
+
* for CLI-style providers (openai-codex, google-gemini-cli). (#2922)
|
|
4
|
+
*
|
|
5
|
+
* These providers use per-user quotas with shorter windows, so the
|
|
6
|
+
* default 60s backoff should be capped at 30s to avoid leaving users
|
|
7
|
+
* stuck in an apparent permanent "rate limit" state.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import test from "node:test";
|
|
11
|
+
import assert from "node:assert/strict";
|
|
12
|
+
import { readFileSync } from "node:fs";
|
|
13
|
+
import { join, dirname } from "node:path";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
|
|
16
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
const RECOVERY_PATH = join(__dirname, "..", "bootstrap", "agent-end-recovery.ts");
|
|
18
|
+
|
|
19
|
+
function getRecoverySource(): string {
|
|
20
|
+
return readFileSync(RECOVERY_PATH, "utf-8");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
test("agent-end-recovery references openai-codex for rate-limit handling (#2922)", () => {
|
|
24
|
+
const src = getRecoverySource();
|
|
25
|
+
assert.ok(
|
|
26
|
+
src.includes("openai-codex"),
|
|
27
|
+
'agent-end-recovery.ts must reference "openai-codex" for CLI provider rate-limit handling (#2922)',
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("agent-end-recovery references google-gemini-cli for rate-limit handling (#2922)", () => {
|
|
32
|
+
const src = getRecoverySource();
|
|
33
|
+
assert.ok(
|
|
34
|
+
src.includes("google-gemini-cli"),
|
|
35
|
+
'agent-end-recovery.ts must reference "google-gemini-cli" for CLI provider rate-limit handling (#2922)',
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("agent-end-recovery caps rate-limit backoff for CLI providers (#2922)", () => {
|
|
40
|
+
const src = getRecoverySource();
|
|
41
|
+
// Must have a Math.min capping pattern for CLI provider rate-limit backoff
|
|
42
|
+
const cappingRe = /Math\.min\s*\(/;
|
|
43
|
+
assert.ok(
|
|
44
|
+
cappingRe.test(src),
|
|
45
|
+
'agent-end-recovery.ts must cap rate-limit backoff with Math.min for CLI providers (#2922)',
|
|
46
|
+
);
|
|
47
|
+
});
|