gsd-pi 2.38.0-dev.eeb3520 → 2.39.0-dev.20aba06
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 +15 -11
- package/dist/app-paths.js +1 -1
- package/dist/cli.js +9 -0
- package/dist/extension-discovery.d.ts +5 -3
- package/dist/extension-discovery.js +14 -9
- package/dist/extension-registry.js +2 -2
- package/dist/remote-questions-config.js +2 -2
- package/dist/resource-loader.js +100 -3
- package/dist/resources/extensions/async-jobs/index.js +10 -0
- package/dist/resources/extensions/browser-tools/index.js +3 -1
- package/dist/resources/extensions/browser-tools/package.json +3 -1
- package/dist/resources/extensions/browser-tools/tools/verify.js +97 -0
- package/dist/resources/extensions/cmux/index.js +55 -1
- package/dist/resources/extensions/context7/package.json +1 -1
- package/dist/resources/extensions/get-secrets-from-user.js +5 -24
- package/dist/resources/extensions/github-sync/cli.js +284 -0
- package/dist/resources/extensions/github-sync/index.js +73 -0
- package/dist/resources/extensions/github-sync/mapping.js +67 -0
- package/dist/resources/extensions/github-sync/sync.js +424 -0
- package/dist/resources/extensions/github-sync/templates.js +118 -0
- package/dist/resources/extensions/github-sync/types.js +7 -0
- package/dist/resources/extensions/google-search/package.json +3 -1
- package/dist/resources/extensions/gsd/auto/session.js +6 -23
- package/dist/resources/extensions/gsd/auto-dashboard.js +7 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +8 -9
- package/dist/resources/extensions/gsd/auto-loop.js +923 -787
- package/dist/resources/extensions/gsd/auto-post-unit.js +107 -70
- package/dist/resources/extensions/gsd/auto-prompts.js +205 -51
- package/dist/resources/extensions/gsd/auto-start.js +19 -3
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +13 -5
- package/dist/resources/extensions/gsd/auto-worktree.js +3 -3
- package/dist/resources/extensions/gsd/auto.js +149 -100
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +126 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +233 -0
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +59 -0
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +38 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +156 -0
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +46 -0
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +300 -0
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +38 -0
- package/dist/resources/extensions/gsd/captures.js +9 -1
- package/dist/resources/extensions/gsd/commands/catalog.js +278 -0
- package/dist/resources/extensions/gsd/commands/context.js +84 -0
- package/dist/resources/extensions/gsd/commands/dispatcher.js +21 -0
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +72 -0
- package/dist/resources/extensions/gsd/commands/handlers/core.js +246 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +166 -0
- package/dist/resources/extensions/gsd/commands/handlers/parallel.js +94 -0
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +102 -0
- package/dist/resources/extensions/gsd/commands/index.js +11 -0
- package/dist/resources/extensions/gsd/commands-extensions.js +3 -2
- package/dist/resources/extensions/gsd/commands-handlers.js +17 -4
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
- package/dist/resources/extensions/gsd/commands.js +8 -1169
- package/dist/resources/extensions/gsd/context-budget.js +2 -10
- package/dist/resources/extensions/gsd/dashboard-overlay.js +9 -0
- package/dist/resources/extensions/gsd/detection.js +1 -2
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +0 -2
- package/dist/resources/extensions/gsd/doctor-checks.js +82 -0
- package/dist/resources/extensions/gsd/doctor-environment.js +78 -0
- package/dist/resources/extensions/gsd/doctor-format.js +15 -0
- package/dist/resources/extensions/gsd/doctor-proactive.js +80 -10
- package/dist/resources/extensions/gsd/doctor-providers.js +30 -11
- package/dist/resources/extensions/gsd/doctor.js +234 -12
- package/dist/resources/extensions/gsd/env-utils.js +29 -0
- package/dist/resources/extensions/gsd/exit-command.js +2 -1
- package/dist/resources/extensions/gsd/export-html.js +46 -0
- package/dist/resources/extensions/gsd/export.js +1 -1
- package/dist/resources/extensions/gsd/files.js +48 -9
- package/dist/resources/extensions/gsd/forensics.js +1 -1
- package/dist/resources/extensions/gsd/git-service.js +30 -12
- package/dist/resources/extensions/gsd/gitignore.js +16 -3
- package/dist/resources/extensions/gsd/guided-flow.js +149 -38
- package/dist/resources/extensions/gsd/health-widget-core.js +32 -70
- package/dist/resources/extensions/gsd/health-widget.js +4 -87
- package/dist/resources/extensions/gsd/index.js +4 -1111
- package/dist/resources/extensions/gsd/migrate/parsers.js +1 -1
- package/dist/resources/extensions/gsd/migrate-external.js +18 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +37 -0
- package/dist/resources/extensions/gsd/package.json +1 -1
- package/dist/resources/extensions/gsd/paths.js +3 -0
- package/dist/resources/extensions/gsd/preferences-models.js +0 -12
- package/dist/resources/extensions/gsd/preferences-types.js +1 -1
- package/dist/resources/extensions/gsd/preferences-validation.js +59 -11
- package/dist/resources/extensions/gsd/preferences.js +22 -11
- package/dist/resources/extensions/gsd/progress-score.js +20 -1
- package/dist/resources/extensions/gsd/prompt-loader.js +6 -2
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss.md +11 -14
- package/dist/resources/extensions/gsd/prompts/execute-task.md +5 -3
- package/dist/resources/extensions/gsd/prompts/forensics.md +121 -46
- package/dist/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +11 -12
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +8 -10
- package/dist/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-research-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/queue.md +4 -8
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +11 -8
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +28 -11
- package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -2
- package/dist/resources/extensions/gsd/repo-identity.js +21 -4
- package/dist/resources/extensions/gsd/resource-version.js +2 -1
- package/dist/resources/extensions/gsd/roadmap-mutations.js +24 -0
- package/dist/resources/extensions/gsd/state.js +42 -23
- package/dist/resources/extensions/gsd/templates/runtime.md +21 -0
- package/dist/resources/extensions/gsd/templates/task-plan.md +3 -0
- package/dist/resources/extensions/gsd/visualizer-data.js +27 -2
- package/dist/resources/extensions/gsd/visualizer-views.js +52 -0
- package/dist/resources/extensions/gsd/worktree.js +35 -16
- package/dist/resources/extensions/mcp-client/index.js +14 -1
- package/dist/resources/extensions/remote-questions/status.js +4 -1
- package/dist/resources/extensions/remote-questions/store.js +4 -1
- package/dist/resources/extensions/search-the-web/provider.js +2 -1
- package/dist/resources/extensions/shared/frontmatter.js +1 -1
- package/dist/resources/extensions/subagent/index.js +12 -3
- package/dist/resources/extensions/subagent/isolation.js +2 -1
- package/dist/resources/extensions/ttsr/rule-loader.js +2 -1
- package/dist/resources/extensions/universal-config/package.json +1 -1
- package/dist/welcome-screen.d.ts +13 -0
- package/dist/welcome-screen.js +97 -0
- package/package.json +1 -1
- package/packages/pi-ai/dist/utils/oauth/anthropic.js +2 -2
- package/packages/pi-ai/dist/utils/oauth/anthropic.js.map +1 -1
- package/packages/pi-ai/src/utils/oauth/anthropic.ts +2 -2
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -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 +107 -24
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +205 -7
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.js +8 -4
- package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skill-tool.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/skill-tool.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js +70 -0
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/skills.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +8 -2
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts +17 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +244 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.d.ts +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js +58 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts +12 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +54 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.d.ts +6 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.js +63 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +38 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +1 -1
- 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 +15 -457
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +122 -23
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +223 -7
- package/packages/pi-coding-agent/src/core/package-manager.ts +8 -4
- package/packages/pi-coding-agent/src/core/skill-tool.test.ts +89 -0
- package/packages/pi-coding-agent/src/core/skills.ts +11 -2
- package/packages/pi-coding-agent/src/index.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +302 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/extension-ui-controller.ts +59 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +68 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/model-controller.ts +71 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +37 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +18 -510
- package/pkg/package.json +1 -1
- package/src/resources/extensions/async-jobs/index.ts +11 -0
- package/src/resources/extensions/browser-tools/index.ts +3 -0
- package/src/resources/extensions/browser-tools/tools/verify.ts +117 -0
- package/src/resources/extensions/cmux/index.ts +57 -1
- package/src/resources/extensions/get-secrets-from-user.ts +5 -24
- package/src/resources/extensions/github-sync/cli.ts +364 -0
- package/src/resources/extensions/github-sync/index.ts +93 -0
- package/src/resources/extensions/github-sync/mapping.ts +81 -0
- package/src/resources/extensions/github-sync/sync.ts +556 -0
- package/src/resources/extensions/github-sync/templates.ts +183 -0
- package/src/resources/extensions/github-sync/tests/cli.test.ts +20 -0
- package/src/resources/extensions/github-sync/tests/commit-linking.test.ts +39 -0
- package/src/resources/extensions/github-sync/tests/mapping.test.ts +104 -0
- package/src/resources/extensions/github-sync/tests/templates.test.ts +110 -0
- package/src/resources/extensions/github-sync/types.ts +47 -0
- package/src/resources/extensions/gsd/auto/session.ts +7 -25
- package/src/resources/extensions/gsd/auto-dashboard.ts +10 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +7 -9
- package/src/resources/extensions/gsd/auto-loop.ts +1285 -1138
- package/src/resources/extensions/gsd/auto-post-unit.ts +90 -46
- package/src/resources/extensions/gsd/auto-prompts.ts +250 -53
- package/src/resources/extensions/gsd/auto-start.ts +24 -3
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +15 -4
- package/src/resources/extensions/gsd/auto-worktree.ts +3 -3
- package/src/resources/extensions/gsd/auto.ts +152 -111
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +142 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +238 -0
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +90 -0
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +46 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +167 -0
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +55 -0
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +340 -0
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +51 -0
- package/src/resources/extensions/gsd/captures.ts +10 -1
- package/src/resources/extensions/gsd/commands/catalog.ts +301 -0
- package/src/resources/extensions/gsd/commands/context.ts +101 -0
- package/src/resources/extensions/gsd/commands/dispatcher.ts +32 -0
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +74 -0
- package/src/resources/extensions/gsd/commands/handlers/core.ts +274 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +169 -0
- package/src/resources/extensions/gsd/commands/handlers/parallel.ts +118 -0
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +109 -0
- package/src/resources/extensions/gsd/commands/index.ts +14 -0
- package/src/resources/extensions/gsd/commands-extensions.ts +4 -2
- package/src/resources/extensions/gsd/commands-handlers.ts +18 -3
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
- package/src/resources/extensions/gsd/commands.ts +10 -1307
- package/src/resources/extensions/gsd/context-budget.ts +2 -12
- package/src/resources/extensions/gsd/dashboard-overlay.ts +10 -0
- package/src/resources/extensions/gsd/detection.ts +2 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +0 -2
- package/src/resources/extensions/gsd/doctor-checks.ts +75 -0
- package/src/resources/extensions/gsd/doctor-environment.ts +82 -1
- package/src/resources/extensions/gsd/doctor-format.ts +20 -0
- package/src/resources/extensions/gsd/doctor-proactive.ts +106 -10
- package/src/resources/extensions/gsd/doctor-providers.ts +30 -9
- package/src/resources/extensions/gsd/doctor-types.ts +16 -1
- package/src/resources/extensions/gsd/doctor.ts +243 -14
- package/src/resources/extensions/gsd/env-utils.ts +31 -0
- package/src/resources/extensions/gsd/exit-command.ts +2 -2
- package/src/resources/extensions/gsd/export-html.ts +51 -0
- package/src/resources/extensions/gsd/export.ts +1 -1
- package/src/resources/extensions/gsd/files.ts +51 -11
- package/src/resources/extensions/gsd/forensics.ts +1 -1
- package/src/resources/extensions/gsd/git-service.ts +44 -10
- package/src/resources/extensions/gsd/gitignore.ts +17 -3
- package/src/resources/extensions/gsd/guided-flow.ts +177 -44
- package/src/resources/extensions/gsd/health-widget-core.ts +28 -80
- package/src/resources/extensions/gsd/health-widget.ts +4 -89
- package/src/resources/extensions/gsd/index.ts +12 -1307
- package/src/resources/extensions/gsd/migrate/parsers.ts +1 -1
- package/src/resources/extensions/gsd/migrate-external.ts +18 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +37 -0
- package/src/resources/extensions/gsd/paths.ts +4 -0
- package/src/resources/extensions/gsd/preferences-models.ts +0 -12
- package/src/resources/extensions/gsd/preferences-types.ts +4 -4
- package/src/resources/extensions/gsd/preferences-validation.ts +51 -11
- package/src/resources/extensions/gsd/preferences.ts +25 -11
- package/src/resources/extensions/gsd/progress-score.ts +23 -0
- package/src/resources/extensions/gsd/prompt-loader.ts +7 -2
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss.md +11 -14
- package/src/resources/extensions/gsd/prompts/execute-task.md +5 -3
- package/src/resources/extensions/gsd/prompts/forensics.md +121 -46
- package/src/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +11 -12
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +8 -10
- package/src/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-research-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/queue.md +4 -8
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +11 -8
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +28 -11
- package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -2
- package/src/resources/extensions/gsd/repo-identity.ts +23 -4
- package/src/resources/extensions/gsd/resource-version.ts +3 -1
- package/src/resources/extensions/gsd/roadmap-mutations.ts +29 -0
- package/src/resources/extensions/gsd/state.ts +39 -21
- package/src/resources/extensions/gsd/templates/runtime.md +21 -0
- package/src/resources/extensions/gsd/templates/task-plan.md +3 -0
- package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +21 -18
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +135 -77
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/cmux.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +43 -0
- package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +266 -0
- package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +86 -3
- package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +16 -54
- package/src/resources/extensions/gsd/tests/parsers.test.ts +131 -14
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +2 -7
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +16 -16
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +21 -1
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +16 -4
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +10 -10
- package/src/resources/extensions/gsd/tests/worktree.test.ts +47 -0
- package/src/resources/extensions/gsd/types.ts +18 -1
- package/src/resources/extensions/gsd/verification-evidence.ts +16 -0
- package/src/resources/extensions/gsd/visualizer-data.ts +52 -2
- package/src/resources/extensions/gsd/visualizer-views.ts +58 -0
- package/src/resources/extensions/gsd/worktree.ts +35 -15
- package/src/resources/extensions/mcp-client/index.ts +17 -1
- package/src/resources/extensions/remote-questions/status.ts +5 -1
- package/src/resources/extensions/remote-questions/store.ts +5 -1
- package/src/resources/extensions/search-the-web/provider.ts +2 -1
- package/src/resources/extensions/shared/frontmatter.ts +1 -1
- package/src/resources/extensions/subagent/index.ts +12 -3
- package/src/resources/extensions/subagent/isolation.ts +3 -1
- package/src/resources/extensions/ttsr/rule-loader.ts +3 -1
- package/dist/resources/extensions/gsd/prompt-compressor.js +0 -393
- package/dist/resources/extensions/gsd/semantic-chunker.js +0 -254
- package/dist/resources/extensions/gsd/summary-distiller.js +0 -212
- package/src/resources/extensions/gsd/prompt-compressor.ts +0 -508
- package/src/resources/extensions/gsd/semantic-chunker.ts +0 -336
- package/src/resources/extensions/gsd/summary-distiller.ts +0 -258
- package/src/resources/extensions/gsd/tests/context-compression.test.ts +0 -193
- package/src/resources/extensions/gsd/tests/prompt-compressor.test.ts +0 -529
- package/src/resources/extensions/gsd/tests/semantic-chunker.test.ts +0 -426
- package/src/resources/extensions/gsd/tests/summary-distiller.test.ts +0 -323
- package/src/resources/extensions/gsd/tests/token-optimization-benchmark.test.ts +0 -1272
- package/src/resources/extensions/gsd/tests/token-optimization-prefs.test.ts +0 -164
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
* @see D001 (module location), D002 (200K fallback), D003 (section-boundary truncation)
|
|
9
9
|
*/
|
|
10
10
|
import { getCharsPerToken } from "./token-counter.js";
|
|
11
|
-
import { compressToTarget } from "./prompt-compressor.js";
|
|
12
11
|
// ─── Budget ratio constants ──────────────────────────────────────────────────
|
|
13
12
|
// Percentages of total context window allocated to each budget category.
|
|
14
13
|
// These are applied after tokens→chars conversion.
|
|
@@ -132,20 +131,13 @@ export function resolveExecutorContextWindow(registry, preferences, sessionConte
|
|
|
132
131
|
return DEFAULT_CONTEXT_WINDOW;
|
|
133
132
|
}
|
|
134
133
|
/**
|
|
135
|
-
*
|
|
136
|
-
* Returns the content within budget with maximum information preservation.
|
|
134
|
+
* Reduce content to fit within budget using section-boundary truncation.
|
|
137
135
|
*/
|
|
138
136
|
export function reduceToFit(content, budgetChars) {
|
|
139
137
|
if (!content || content.length <= budgetChars) {
|
|
140
138
|
return { content, droppedSections: 0 };
|
|
141
139
|
}
|
|
142
|
-
|
|
143
|
-
const compressed = compressToTarget(content, budgetChars);
|
|
144
|
-
if (compressed.compressedChars <= budgetChars) {
|
|
145
|
-
return { content: compressed.content, droppedSections: 0 };
|
|
146
|
-
}
|
|
147
|
-
// Step 2: Truncate the compressed content at section boundaries
|
|
148
|
-
return truncateAtSectionBoundary(compressed.content, budgetChars);
|
|
140
|
+
return truncateAtSectionBoundary(content, budgetChars);
|
|
149
141
|
}
|
|
150
142
|
// ─── Internal helpers ────────────────────────────────────────────────────────
|
|
151
143
|
/**
|
|
@@ -282,6 +282,15 @@ export class GSDDashboardOverlay {
|
|
|
282
282
|
: progressScore.level === "yellow" ? th.fg("warning", "●")
|
|
283
283
|
: th.fg("error", "●");
|
|
284
284
|
lines.push(row(`${progressIcon} ${th.fg("text", progressScore.summary)}`));
|
|
285
|
+
// Show signal details when degraded — real-time visibility into what doctor found
|
|
286
|
+
if (progressScore.level !== "green" && progressScore.signals.length > 0) {
|
|
287
|
+
for (const signal of progressScore.signals) {
|
|
288
|
+
const prefix = signal.kind === "positive" ? th.fg("success", " ✓")
|
|
289
|
+
: signal.kind === "negative" ? th.fg("error", " ✗")
|
|
290
|
+
: th.fg("dim", " ·");
|
|
291
|
+
lines.push(row(`${prefix} ${th.fg("dim", signal.label)}`));
|
|
292
|
+
}
|
|
293
|
+
}
|
|
285
294
|
}
|
|
286
295
|
lines.push(blank());
|
|
287
296
|
if (this.dashData.currentUnit) {
|
|
@@ -9,6 +9,7 @@ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import { homedir } from "node:os";
|
|
11
11
|
import { gsdRoot } from "./paths.js";
|
|
12
|
+
const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
|
|
12
13
|
// ─── Project File Markers ───────────────────────────────────────────────────────
|
|
13
14
|
const PROJECT_FILES = [
|
|
14
15
|
"package.json",
|
|
@@ -309,7 +310,6 @@ function detectVerificationCommands(basePath, detectedFiles, packageManager) {
|
|
|
309
310
|
* Check if global GSD setup exists (has ~/.gsd/ with preferences).
|
|
310
311
|
*/
|
|
311
312
|
export function hasGlobalSetup() {
|
|
312
|
-
const gsdHome = join(homedir(), ".gsd");
|
|
313
313
|
return (existsSync(join(gsdHome, "preferences.md")) ||
|
|
314
314
|
existsSync(join(gsdHome, "PREFERENCES.md")));
|
|
315
315
|
}
|
|
@@ -318,7 +318,6 @@ export function hasGlobalSetup() {
|
|
|
318
318
|
* Returns true if ~/.gsd/ doesn't exist or has no preferences or auth.
|
|
319
319
|
*/
|
|
320
320
|
export function isFirstEverLaunch() {
|
|
321
|
-
const gsdHome = join(homedir(), ".gsd");
|
|
322
321
|
if (!existsSync(gsdHome))
|
|
323
322
|
return true;
|
|
324
323
|
// If we have preferences, not first launch
|
|
@@ -194,8 +194,6 @@ Setting `prefer_skills: []` does **not** disable skill discovery — it just mea
|
|
|
194
194
|
|
|
195
195
|
- `search_provider`: `"brave"`, `"tavily"`, `"ollama"`, `"native"`, or `"auto"` — selects the search backend for research phases. `"native"` forces Anthropic's built-in web search only; provider values force that backend and disable native search; `"auto"` uses the default heuristic. Default: `"auto"`.
|
|
196
196
|
|
|
197
|
-
- `compression_strategy`: `"truncate"` or `"compress"` — controls how context that exceeds the budget is reduced. `"truncate"` (default) drops sections from the end. `"compress"` applies heuristic compression before truncating, preserving more content at the cost of some fidelity. Default: `"truncate"`.
|
|
198
|
-
|
|
199
197
|
- `context_selection`: `"full"` or `"smart"` — controls how files are inlined into context. `"full"` inlines entire files; `"smart"` uses semantic chunking to include only the most relevant sections. Default is derived from `token_profile`.
|
|
200
198
|
|
|
201
199
|
- `parallel`: configures parallel orchestration for running multiple slices concurrently. Keys:
|
|
@@ -618,6 +618,88 @@ export async function checkRuntimeHealth(basePath, issues, fixesApplied, shouldF
|
|
|
618
618
|
catch {
|
|
619
619
|
// Non-fatal — external state check failed
|
|
620
620
|
}
|
|
621
|
+
// ── Metrics ledger integrity ───────────────────────────────────────────
|
|
622
|
+
try {
|
|
623
|
+
const metricsPath = join(root, "metrics.json");
|
|
624
|
+
if (existsSync(metricsPath)) {
|
|
625
|
+
try {
|
|
626
|
+
const raw = readFileSync(metricsPath, "utf-8");
|
|
627
|
+
const ledger = JSON.parse(raw);
|
|
628
|
+
if (ledger.version !== 1 || !Array.isArray(ledger.units)) {
|
|
629
|
+
issues.push({
|
|
630
|
+
severity: "warning",
|
|
631
|
+
code: "metrics_ledger_corrupt",
|
|
632
|
+
scope: "project",
|
|
633
|
+
unitId: "project",
|
|
634
|
+
message: "metrics.json has an unexpected structure (version !== 1 or units is not an array) — metrics data may be unreliable",
|
|
635
|
+
file: ".gsd/metrics.json",
|
|
636
|
+
fixable: false,
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
catch {
|
|
641
|
+
issues.push({
|
|
642
|
+
severity: "warning",
|
|
643
|
+
code: "metrics_ledger_corrupt",
|
|
644
|
+
scope: "project",
|
|
645
|
+
unitId: "project",
|
|
646
|
+
message: "metrics.json is not valid JSON — metrics data may be corrupt",
|
|
647
|
+
file: ".gsd/metrics.json",
|
|
648
|
+
fixable: false,
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
catch {
|
|
654
|
+
// Non-fatal — metrics check failed
|
|
655
|
+
}
|
|
656
|
+
// ── Large planning file detection ──────────────────────────────────────
|
|
657
|
+
// Files over 100KB can cause LLM context pressure. Report the worst offenders.
|
|
658
|
+
try {
|
|
659
|
+
const MAX_FILE_BYTES = 100 * 1024; // 100KB
|
|
660
|
+
const milestonesPath = milestonesDir(basePath);
|
|
661
|
+
if (existsSync(milestonesPath)) {
|
|
662
|
+
const largeFiles = [];
|
|
663
|
+
function scanForLargeFiles(dir, depth = 0) {
|
|
664
|
+
if (depth > 6)
|
|
665
|
+
return;
|
|
666
|
+
try {
|
|
667
|
+
for (const entry of readdirSync(dir)) {
|
|
668
|
+
const full = join(dir, entry);
|
|
669
|
+
try {
|
|
670
|
+
const s = statSync(full);
|
|
671
|
+
if (s.isDirectory()) {
|
|
672
|
+
scanForLargeFiles(full, depth + 1);
|
|
673
|
+
continue;
|
|
674
|
+
}
|
|
675
|
+
if (entry.endsWith(".md") && s.size > MAX_FILE_BYTES) {
|
|
676
|
+
largeFiles.push({ path: full.replace(basePath + "/", ""), sizeKB: Math.round(s.size / 1024) });
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
catch { /* skip entry */ }
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
catch { /* skip dir */ }
|
|
683
|
+
}
|
|
684
|
+
scanForLargeFiles(milestonesPath);
|
|
685
|
+
if (largeFiles.length > 0) {
|
|
686
|
+
largeFiles.sort((a, b) => b.sizeKB - a.sizeKB);
|
|
687
|
+
const worst = largeFiles[0];
|
|
688
|
+
issues.push({
|
|
689
|
+
severity: "warning",
|
|
690
|
+
code: "large_planning_file",
|
|
691
|
+
scope: "project",
|
|
692
|
+
unitId: "project",
|
|
693
|
+
message: `${largeFiles.length} planning file(s) exceed 100KB — largest: ${worst.path} (${worst.sizeKB}KB). Large files cause LLM context pressure.`,
|
|
694
|
+
file: worst.path,
|
|
695
|
+
fixable: false,
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
catch {
|
|
701
|
+
// Non-fatal — large file scan failed
|
|
702
|
+
}
|
|
621
703
|
}
|
|
622
704
|
/**
|
|
623
705
|
* Build STATE.md markdown content from derived state.
|
|
@@ -355,6 +355,63 @@ function checkGitRemote(basePath) {
|
|
|
355
355
|
}
|
|
356
356
|
return { name: "git_remote", status: "ok", message: "Git remote reachable" };
|
|
357
357
|
}
|
|
358
|
+
/**
|
|
359
|
+
* Check if the project build passes (opt-in slow check, use --build flag).
|
|
360
|
+
* Runs npm run build and reports failure as env_build.
|
|
361
|
+
*/
|
|
362
|
+
function checkBuildHealth(basePath) {
|
|
363
|
+
const pkgPath = join(basePath, "package.json");
|
|
364
|
+
if (!existsSync(pkgPath))
|
|
365
|
+
return null;
|
|
366
|
+
try {
|
|
367
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
368
|
+
const buildScript = pkg.scripts?.build;
|
|
369
|
+
if (!buildScript)
|
|
370
|
+
return null;
|
|
371
|
+
const result = tryExec("npm run build 2>&1", basePath);
|
|
372
|
+
if (result === null) {
|
|
373
|
+
return {
|
|
374
|
+
name: "build",
|
|
375
|
+
status: "error",
|
|
376
|
+
message: "Build failed — npm run build exited non-zero",
|
|
377
|
+
detail: "Fix build errors before dispatching work",
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
return { name: "build", status: "ok", message: "Build passes" };
|
|
381
|
+
}
|
|
382
|
+
catch {
|
|
383
|
+
return null;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Check if tests pass (opt-in slow check, use --test flag).
|
|
388
|
+
* Runs npm test and reports failures as env_test.
|
|
389
|
+
*/
|
|
390
|
+
function checkTestHealth(basePath) {
|
|
391
|
+
const pkgPath = join(basePath, "package.json");
|
|
392
|
+
if (!existsSync(pkgPath))
|
|
393
|
+
return null;
|
|
394
|
+
try {
|
|
395
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
396
|
+
const testScript = pkg.scripts?.test;
|
|
397
|
+
// Skip if no test script or the default placeholder
|
|
398
|
+
if (!testScript || testScript.includes("no test specified"))
|
|
399
|
+
return null;
|
|
400
|
+
const result = tryExec("npm test 2>&1", basePath);
|
|
401
|
+
if (result === null) {
|
|
402
|
+
return {
|
|
403
|
+
name: "test",
|
|
404
|
+
status: "warning",
|
|
405
|
+
message: "Tests failing — npm test exited non-zero",
|
|
406
|
+
detail: "Fix failing tests before shipping",
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
return { name: "test", status: "ok", message: "Tests pass" };
|
|
410
|
+
}
|
|
411
|
+
catch {
|
|
412
|
+
return null;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
358
415
|
// ── Public API ─────────────────────────────────────────────────────────────
|
|
359
416
|
/**
|
|
360
417
|
* Run all environment health checks. Returns structured results for
|
|
@@ -394,6 +451,24 @@ export function runFullEnvironmentChecks(basePath) {
|
|
|
394
451
|
results.push(remoteCheck);
|
|
395
452
|
return results;
|
|
396
453
|
}
|
|
454
|
+
/**
|
|
455
|
+
* Run slow opt-in checks (build and/or test).
|
|
456
|
+
* These are never run on the pre-dispatch gate — only on explicit /gsd doctor --build/--test.
|
|
457
|
+
*/
|
|
458
|
+
export function runSlowEnvironmentChecks(basePath, options) {
|
|
459
|
+
const results = [];
|
|
460
|
+
if (options?.includeBuild) {
|
|
461
|
+
const buildCheck = checkBuildHealth(basePath);
|
|
462
|
+
if (buildCheck)
|
|
463
|
+
results.push(buildCheck);
|
|
464
|
+
}
|
|
465
|
+
if (options?.includeTests) {
|
|
466
|
+
const testCheck = checkTestHealth(basePath);
|
|
467
|
+
if (testCheck)
|
|
468
|
+
results.push(testCheck);
|
|
469
|
+
}
|
|
470
|
+
return results;
|
|
471
|
+
}
|
|
397
472
|
/**
|
|
398
473
|
* Convert environment check results to DoctorIssue format for the doctor pipeline.
|
|
399
474
|
*/
|
|
@@ -417,6 +492,9 @@ export async function checkEnvironmentHealth(basePath, issues, options) {
|
|
|
417
492
|
const results = options?.includeRemote
|
|
418
493
|
? runFullEnvironmentChecks(basePath)
|
|
419
494
|
: runEnvironmentChecks(basePath);
|
|
495
|
+
if (options?.includeBuild || options?.includeTests) {
|
|
496
|
+
results.push(...runSlowEnvironmentChecks(basePath, options));
|
|
497
|
+
}
|
|
420
498
|
issues.push(...environmentResultsToDoctorIssues(results));
|
|
421
499
|
}
|
|
422
500
|
/**
|
|
@@ -69,3 +69,18 @@ export function formatDoctorIssuesForPrompt(issues) {
|
|
|
69
69
|
return `- [${prefix}] ${issue.unitId} | ${issue.code} | ${issue.message}${issue.file ? ` | file: ${issue.file}` : ""} | fixable: ${issue.fixable ? "yes" : "no"}`;
|
|
70
70
|
}).join("\n");
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Serialize a doctor report to JSON — suitable for CI/tooling integration.
|
|
74
|
+
* Usage: /gsd doctor --json
|
|
75
|
+
*/
|
|
76
|
+
export function formatDoctorReportJson(report) {
|
|
77
|
+
return JSON.stringify({
|
|
78
|
+
ok: report.ok,
|
|
79
|
+
basePath: report.basePath,
|
|
80
|
+
generatedAt: new Date().toISOString(),
|
|
81
|
+
summary: summarizeDoctorIssues(report.issues),
|
|
82
|
+
issues: report.issues,
|
|
83
|
+
fixesApplied: report.fixesApplied,
|
|
84
|
+
...(report.timing ? { timing: report.timing } : {}),
|
|
85
|
+
}, null, 2);
|
|
86
|
+
}
|
|
@@ -28,11 +28,23 @@ let healthHistory = [];
|
|
|
28
28
|
let consecutiveErrorUnits = 0;
|
|
29
29
|
/** Unit index counter for health tracking. */
|
|
30
30
|
let healthUnitIndex = 0;
|
|
31
|
+
/** Previous progress level for state transition detection. */
|
|
32
|
+
let previousProgressLevel = "green";
|
|
33
|
+
/** Callback for state transition notifications. Set by auto-mode. */
|
|
34
|
+
let onLevelChange = null;
|
|
35
|
+
/**
|
|
36
|
+
* Register a callback for progress level transitions (green→yellow, yellow→red, etc.).
|
|
37
|
+
* Called once when auto-mode starts. Pass null to unregister.
|
|
38
|
+
*/
|
|
39
|
+
export function setLevelChangeCallback(cb) {
|
|
40
|
+
onLevelChange = cb;
|
|
41
|
+
previousProgressLevel = "green";
|
|
42
|
+
}
|
|
31
43
|
/**
|
|
32
44
|
* Record a health snapshot after a doctor run.
|
|
33
|
-
* Called from the post-unit hook in auto.ts.
|
|
45
|
+
* Called from the post-unit hook in auto-post-unit.ts.
|
|
34
46
|
*/
|
|
35
|
-
export function recordHealthSnapshot(errors, warnings, fixesApplied) {
|
|
47
|
+
export function recordHealthSnapshot(errors, warnings, fixesApplied, issues, fixes, scope) {
|
|
36
48
|
healthUnitIndex++;
|
|
37
49
|
healthHistory.push({
|
|
38
50
|
timestamp: Date.now(),
|
|
@@ -40,6 +52,9 @@ export function recordHealthSnapshot(errors, warnings, fixesApplied) {
|
|
|
40
52
|
warnings,
|
|
41
53
|
fixesApplied,
|
|
42
54
|
unitIndex: healthUnitIndex,
|
|
55
|
+
issues: issues ?? [],
|
|
56
|
+
fixes: fixes ?? [],
|
|
57
|
+
scope,
|
|
43
58
|
});
|
|
44
59
|
// Keep only the last 50 snapshots to bound memory
|
|
45
60
|
if (healthHistory.length > 50) {
|
|
@@ -51,6 +66,18 @@ export function recordHealthSnapshot(errors, warnings, fixesApplied) {
|
|
|
51
66
|
else {
|
|
52
67
|
consecutiveErrorUnits = 0;
|
|
53
68
|
}
|
|
69
|
+
// Detect progress level transitions and notify
|
|
70
|
+
if (onLevelChange) {
|
|
71
|
+
const newLevel = consecutiveErrorUnits >= 3 ? "red"
|
|
72
|
+
: consecutiveErrorUnits >= 1 || getHealthTrend() === "degrading" ? "yellow"
|
|
73
|
+
: "green";
|
|
74
|
+
if (newLevel !== previousProgressLevel) {
|
|
75
|
+
const topIssue = (issues ?? []).find(i => i.severity === "error") ?? (issues ?? [])[0];
|
|
76
|
+
const detail = topIssue ? `: ${topIssue.message}` : "";
|
|
77
|
+
onLevelChange(previousProgressLevel, newLevel, `Health ${previousProgressLevel} → ${newLevel}${detail}`);
|
|
78
|
+
previousProgressLevel = newLevel;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
54
81
|
}
|
|
55
82
|
/**
|
|
56
83
|
* Get the current health trend.
|
|
@@ -84,6 +111,27 @@ export function getConsecutiveErrorUnits() {
|
|
|
84
111
|
export function getHealthHistory() {
|
|
85
112
|
return healthHistory;
|
|
86
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Get the latest health issues from the most recent snapshot.
|
|
116
|
+
* Returns issues from the last snapshot that had any, for real-time visibility.
|
|
117
|
+
*/
|
|
118
|
+
export function getLatestHealthIssues() {
|
|
119
|
+
for (let i = healthHistory.length - 1; i >= 0; i--) {
|
|
120
|
+
if (healthHistory[i].issues.length > 0)
|
|
121
|
+
return healthHistory[i].issues;
|
|
122
|
+
}
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get the latest fixes applied from the most recent snapshot.
|
|
127
|
+
*/
|
|
128
|
+
export function getLatestHealthFixes() {
|
|
129
|
+
for (let i = healthHistory.length - 1; i >= 0; i--) {
|
|
130
|
+
if (healthHistory[i].fixes.length > 0)
|
|
131
|
+
return healthHistory[i].fixes;
|
|
132
|
+
}
|
|
133
|
+
return [];
|
|
134
|
+
}
|
|
87
135
|
/**
|
|
88
136
|
* Reset health tracking state. Called on auto-mode start/stop.
|
|
89
137
|
*/
|
|
@@ -91,6 +139,7 @@ export function resetHealthTracking() {
|
|
|
91
139
|
healthHistory = [];
|
|
92
140
|
consecutiveErrorUnits = 0;
|
|
93
141
|
healthUnitIndex = 0;
|
|
142
|
+
previousProgressLevel = "green";
|
|
94
143
|
}
|
|
95
144
|
/**
|
|
96
145
|
* Lightweight pre-dispatch health check. Runs fast checks that should
|
|
@@ -234,23 +283,44 @@ export function resetEscalation() {
|
|
|
234
283
|
}
|
|
235
284
|
/**
|
|
236
285
|
* Format a health summary for display in the auto-mode dashboard.
|
|
286
|
+
* Human-readable with full words, not abbreviations.
|
|
237
287
|
*/
|
|
238
288
|
export function formatHealthSummary() {
|
|
239
289
|
if (healthHistory.length === 0)
|
|
240
290
|
return "No health data yet.";
|
|
241
291
|
const latest = healthHistory[healthHistory.length - 1];
|
|
242
292
|
const trend = getHealthTrend();
|
|
243
|
-
const
|
|
293
|
+
const trendLabel = trend === "improving" ? "improving"
|
|
294
|
+
: trend === "degrading" ? "degrading"
|
|
295
|
+
: trend === "stable" ? "stable"
|
|
296
|
+
: "unknown";
|
|
244
297
|
const totalFixes = healthHistory.reduce((sum, s) => sum + s.fixesApplied, 0);
|
|
245
|
-
const parts = [
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
298
|
+
const parts = [];
|
|
299
|
+
// Error/warning summary
|
|
300
|
+
if (latest.errors === 0 && latest.warnings === 0) {
|
|
301
|
+
parts.push("No issues");
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
const counts = [];
|
|
305
|
+
if (latest.errors > 0)
|
|
306
|
+
counts.push(`${latest.errors} error${latest.errors > 1 ? "s" : ""}`);
|
|
307
|
+
if (latest.warnings > 0)
|
|
308
|
+
counts.push(`${latest.warnings} warning${latest.warnings > 1 ? "s" : ""}`);
|
|
309
|
+
parts.push(counts.join(", "));
|
|
310
|
+
}
|
|
311
|
+
parts.push(`trend ${trendLabel}`);
|
|
312
|
+
if (totalFixes > 0) {
|
|
313
|
+
parts.push(`${totalFixes} fix${totalFixes > 1 ? "es" : ""} applied`);
|
|
314
|
+
}
|
|
250
315
|
if (consecutiveErrorUnits > 0) {
|
|
251
|
-
parts.push(
|
|
316
|
+
parts.push(`${consecutiveErrorUnits} of ${ESCALATION_THRESHOLD} consecutive errors before escalation`);
|
|
317
|
+
}
|
|
318
|
+
// Include top issue from latest snapshot
|
|
319
|
+
if (latest.issues.length > 0) {
|
|
320
|
+
const topIssue = latest.issues.find(i => i.severity === "error") ?? latest.issues[0];
|
|
321
|
+
parts.push(`latest: ${topIssue.message}`);
|
|
252
322
|
}
|
|
253
|
-
return parts.join("
|
|
323
|
+
return parts.join(" · ");
|
|
254
324
|
}
|
|
255
325
|
/**
|
|
256
326
|
* Reset all proactive healing state. Called on auto-mode start/stop.
|
|
@@ -28,10 +28,12 @@ function modelToProviderId(model) {
|
|
|
28
28
|
const prefix = model.split("/")[0].toLowerCase();
|
|
29
29
|
// Map known prefixes to registry IDs
|
|
30
30
|
const prefixMap = {
|
|
31
|
+
"anthropic-vertex": "anthropic-vertex",
|
|
31
32
|
openrouter: "openrouter",
|
|
32
33
|
groq: "groq",
|
|
33
34
|
mistral: "mistral",
|
|
34
35
|
google: "google",
|
|
36
|
+
"google-vertex": "google-vertex",
|
|
35
37
|
anthropic: "anthropic",
|
|
36
38
|
openai: "openai",
|
|
37
39
|
"github-copilot": "github-copilot",
|
|
@@ -67,11 +69,19 @@ function collectConfiguredModelProviders() {
|
|
|
67
69
|
}
|
|
68
70
|
const modelEntries = typeof models === "object" ? Object.values(models) : [];
|
|
69
71
|
for (const entry of modelEntries) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
if (typeof entry === "string") {
|
|
73
|
+
const pid = modelToProviderId(entry);
|
|
74
|
+
if (pid)
|
|
75
|
+
providers.add(pid);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (typeof entry === "object" && entry !== null && "model" in entry) {
|
|
79
|
+
const configuredProvider = "provider" in entry ? entry.provider : undefined;
|
|
80
|
+
if (typeof configuredProvider === "string" && configuredProvider.trim().length > 0) {
|
|
81
|
+
providers.add(configuredProvider);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const modelId = String(entry.model);
|
|
75
85
|
const pid = modelToProviderId(modelId);
|
|
76
86
|
if (pid)
|
|
77
87
|
providers.add(pid);
|
|
@@ -88,6 +98,9 @@ function collectConfiguredModelProviders() {
|
|
|
88
98
|
}
|
|
89
99
|
function resolveKey(providerId) {
|
|
90
100
|
const info = PROVIDER_REGISTRY.find(p => p.id === providerId);
|
|
101
|
+
if (providerId === "anthropic-vertex" && process.env.ANTHROPIC_VERTEX_PROJECT_ID) {
|
|
102
|
+
return { found: true, source: "env", backedOff: false };
|
|
103
|
+
}
|
|
91
104
|
// Check auth.json
|
|
92
105
|
const authPath = getAuthPath();
|
|
93
106
|
if (existsSync(authPath)) {
|
|
@@ -138,7 +151,9 @@ function checkLlmProviders() {
|
|
|
138
151
|
const results = [];
|
|
139
152
|
for (const providerId of required) {
|
|
140
153
|
const info = PROVIDER_REGISTRY.find(p => p.id === providerId);
|
|
141
|
-
const label =
|
|
154
|
+
const label = providerId === "anthropic-vertex"
|
|
155
|
+
? "Anthropic Vertex"
|
|
156
|
+
: info?.label ?? providerId;
|
|
142
157
|
const lookup = resolveKey(providerId);
|
|
143
158
|
if (!lookup.found) {
|
|
144
159
|
// Check if a cross-provider can serve this provider's models
|
|
@@ -157,16 +172,20 @@ function checkLlmProviders() {
|
|
|
157
172
|
});
|
|
158
173
|
continue;
|
|
159
174
|
}
|
|
160
|
-
const envVar =
|
|
175
|
+
const envVar = providerId === "anthropic-vertex"
|
|
176
|
+
? "ANTHROPIC_VERTEX_PROJECT_ID"
|
|
177
|
+
: info?.envVar ?? `${providerId.toUpperCase()}_API_KEY`;
|
|
161
178
|
results.push({
|
|
162
179
|
name: providerId,
|
|
163
180
|
label,
|
|
164
181
|
category: "llm",
|
|
165
182
|
status: "error",
|
|
166
|
-
message: `${label} —
|
|
167
|
-
detail:
|
|
168
|
-
?
|
|
169
|
-
:
|
|
183
|
+
message: `${label} — not configured`,
|
|
184
|
+
detail: providerId === "anthropic-vertex"
|
|
185
|
+
? "Set ANTHROPIC_VERTEX_PROJECT_ID and authenticate with Google ADC"
|
|
186
|
+
: info?.hasOAuth
|
|
187
|
+
? `Run /gsd keys to authenticate`
|
|
188
|
+
: `Set ${envVar} or run /gsd keys`,
|
|
170
189
|
required: true,
|
|
171
190
|
});
|
|
172
191
|
}
|