gsd-pi 2.29.0-dev.953d788 → 2.29.0-dev.f08b4fe
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 +24 -17
- package/dist/extension-registry.d.ts +63 -0
- package/dist/extension-registry.js +166 -0
- package/dist/headless.js +4 -0
- package/dist/loader.js +10 -1
- package/dist/resource-loader.js +11 -1
- package/dist/resources/extensions/async-jobs/extension-manifest.json +13 -0
- package/dist/resources/extensions/bg-shell/extension-manifest.json +14 -0
- package/dist/resources/extensions/bg-shell/process-manager.ts +13 -0
- package/dist/resources/extensions/browser-tools/extension-manifest.json +37 -0
- package/dist/resources/extensions/context7/extension-manifest.json +12 -0
- package/dist/resources/extensions/google-search/extension-manifest.json +12 -0
- package/dist/resources/extensions/gsd/auto-dashboard.ts +217 -65
- package/dist/resources/extensions/gsd/auto-dispatch.ts +32 -3
- package/dist/resources/extensions/gsd/auto-post-unit.ts +45 -13
- package/dist/resources/extensions/gsd/auto-prompts.ts +40 -17
- package/dist/resources/extensions/gsd/auto-recovery.ts +18 -23
- package/dist/resources/extensions/gsd/auto-start.ts +18 -32
- package/dist/resources/extensions/gsd/auto-worktree.ts +21 -182
- package/dist/resources/extensions/gsd/auto.ts +2 -24
- package/dist/resources/extensions/gsd/captures.ts +4 -10
- package/dist/resources/extensions/gsd/commands-extensions.ts +328 -0
- package/dist/resources/extensions/gsd/commands-handlers.ts +22 -2
- package/dist/resources/extensions/gsd/commands-logs.ts +13 -14
- package/dist/resources/extensions/gsd/commands-prefs-wizard.ts +44 -14
- package/dist/resources/extensions/gsd/commands-workflow-templates.ts +544 -0
- package/dist/resources/extensions/gsd/commands.ts +108 -24
- package/dist/resources/extensions/gsd/dashboard-overlay.ts +2 -1
- package/dist/resources/extensions/gsd/detection.ts +2 -1
- package/dist/resources/extensions/gsd/doctor-checks.ts +49 -1
- package/dist/resources/extensions/gsd/doctor-types.ts +3 -1
- package/dist/resources/extensions/gsd/extension-manifest.json +18 -0
- package/dist/resources/extensions/gsd/forensics.ts +2 -2
- package/dist/resources/extensions/gsd/git-service.ts +3 -2
- package/dist/resources/extensions/gsd/gitignore.ts +9 -63
- package/dist/resources/extensions/gsd/gsd-db.ts +1 -165
- package/dist/resources/extensions/gsd/guided-flow.ts +8 -5
- package/dist/resources/extensions/gsd/index.ts +3 -3
- package/dist/resources/extensions/gsd/json-persistence.ts +16 -1
- package/dist/resources/extensions/gsd/md-importer.ts +3 -2
- package/dist/resources/extensions/gsd/mechanical-completion.ts +430 -0
- package/dist/resources/extensions/gsd/migrate/command.ts +3 -2
- package/dist/resources/extensions/gsd/migrate/writer.ts +2 -1
- package/dist/resources/extensions/gsd/migrate-external.ts +123 -0
- package/dist/resources/extensions/gsd/paths.ts +24 -2
- package/dist/resources/extensions/gsd/post-unit-hooks.ts +6 -5
- package/dist/resources/extensions/gsd/preferences-models.ts +7 -1
- package/dist/resources/extensions/gsd/preferences-validation.ts +2 -1
- package/dist/resources/extensions/gsd/preferences.ts +10 -5
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +4 -2
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +26 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -1
- package/dist/resources/extensions/gsd/prompts/workflow-start.md +28 -0
- package/dist/resources/extensions/gsd/queue-order.ts +10 -11
- package/dist/resources/extensions/gsd/repo-identity.ts +148 -0
- package/dist/resources/extensions/gsd/resource-version.ts +99 -0
- package/dist/resources/extensions/gsd/session-forensics.ts +4 -3
- package/dist/resources/extensions/gsd/session-status-io.ts +23 -41
- package/dist/resources/extensions/gsd/tests/activity-log.test.ts +2 -2
- package/dist/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +1 -1
- package/dist/resources/extensions/gsd/tests/auto-recovery.test.ts +3 -3
- package/dist/resources/extensions/gsd/tests/auto-skip-loop.test.ts +1 -1
- package/dist/resources/extensions/gsd/tests/auto-worktree.test.ts +0 -58
- package/dist/resources/extensions/gsd/tests/doctor-runtime.test.ts +3 -4
- package/dist/resources/extensions/gsd/tests/extension-selector-separator.test.ts +60 -38
- package/dist/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +5 -18
- package/dist/resources/extensions/gsd/tests/git-service.test.ts +10 -37
- package/dist/resources/extensions/gsd/tests/knowledge.test.ts +4 -4
- package/dist/resources/extensions/gsd/tests/mechanical-completion.test.ts +356 -0
- package/dist/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +1 -1
- package/dist/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +1 -0
- package/dist/resources/extensions/gsd/tests/token-profile.test.ts +14 -16
- package/dist/resources/extensions/gsd/tests/workflow-templates.test.ts +173 -0
- package/dist/resources/extensions/gsd/triage-resolution.ts +2 -1
- package/dist/resources/extensions/gsd/types.ts +2 -0
- package/dist/resources/extensions/gsd/workflow-templates/bugfix.md +87 -0
- package/dist/resources/extensions/gsd/workflow-templates/dep-upgrade.md +74 -0
- package/dist/resources/extensions/gsd/workflow-templates/full-project.md +41 -0
- package/dist/resources/extensions/gsd/workflow-templates/hotfix.md +45 -0
- package/dist/resources/extensions/gsd/workflow-templates/refactor.md +83 -0
- package/dist/resources/extensions/gsd/workflow-templates/registry.json +85 -0
- package/dist/resources/extensions/gsd/workflow-templates/security-audit.md +73 -0
- package/dist/resources/extensions/gsd/workflow-templates/small-feature.md +81 -0
- package/dist/resources/extensions/gsd/workflow-templates/spike.md +69 -0
- package/dist/resources/extensions/gsd/workflow-templates.ts +241 -0
- package/dist/resources/extensions/gsd/worktree-command.ts +1 -11
- package/dist/resources/extensions/gsd/worktree-manager.ts +3 -2
- package/dist/resources/extensions/gsd/worktree.ts +42 -5
- package/dist/resources/extensions/mac-tools/extension-manifest.json +16 -0
- package/dist/resources/extensions/mcp-client/index.ts +459 -0
- package/dist/resources/extensions/mcporter/extension-manifest.json +12 -0
- package/dist/resources/extensions/remote-questions/discord-adapter.ts +8 -19
- package/dist/resources/extensions/remote-questions/extension-manifest.json +11 -0
- package/dist/resources/extensions/remote-questions/http-client.ts +76 -0
- package/dist/resources/extensions/remote-questions/slack-adapter.ts +11 -17
- package/dist/resources/extensions/remote-questions/telegram-adapter.ts +8 -19
- package/dist/resources/extensions/search-the-web/extension-manifest.json +13 -0
- package/dist/resources/extensions/slash-commands/extension-manifest.json +11 -0
- package/dist/resources/extensions/subagent/extension-manifest.json +13 -0
- package/dist/resources/extensions/ttsr/extension-manifest.json +11 -0
- package/dist/resources/extensions/universal-config/extension-manifest.json +13 -0
- package/dist/resources/extensions/voice/extension-manifest.json +12 -0
- package/dist/resources/skills/create-gsd-extension/SKILL.md +87 -0
- package/dist/resources/skills/create-gsd-extension/references/compaction-session-control.md +77 -0
- package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +139 -0
- package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +108 -0
- package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +183 -0
- package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +490 -0
- package/dist/resources/skills/create-gsd-extension/references/events-reference.md +126 -0
- package/dist/resources/skills/create-gsd-extension/references/extension-lifecycle.md +64 -0
- package/dist/resources/skills/create-gsd-extension/references/extensionapi-reference.md +75 -0
- package/dist/resources/skills/create-gsd-extension/references/extensioncontext-reference.md +53 -0
- package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +36 -0
- package/dist/resources/skills/create-gsd-extension/references/mode-behavior.md +32 -0
- package/dist/resources/skills/create-gsd-extension/references/model-provider-management.md +89 -0
- package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +55 -0
- package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +90 -0
- package/dist/resources/skills/create-gsd-extension/references/state-management.md +70 -0
- package/dist/resources/skills/create-gsd-extension/references/system-prompt-modification.md +52 -0
- package/dist/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +51 -0
- package/dist/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +143 -0
- package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +57 -0
- package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +156 -0
- package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +74 -0
- package/dist/resources/skills/create-skill/SKILL.md +184 -0
- package/dist/resources/skills/create-skill/references/api-security.md +226 -0
- package/dist/resources/skills/create-skill/references/be-clear-and-direct.md +531 -0
- package/dist/resources/skills/create-skill/references/common-patterns.md +595 -0
- package/dist/resources/skills/create-skill/references/core-principles.md +437 -0
- package/dist/resources/skills/create-skill/references/executable-code.md +175 -0
- package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +68 -0
- package/dist/resources/skills/create-skill/references/iteration-and-testing.md +474 -0
- package/dist/resources/skills/create-skill/references/recommended-structure.md +168 -0
- package/dist/resources/skills/create-skill/references/skill-structure.md +372 -0
- package/dist/resources/skills/create-skill/references/use-xml-tags.md +466 -0
- package/dist/resources/skills/create-skill/references/using-scripts.md +113 -0
- package/dist/resources/skills/create-skill/references/using-templates.md +112 -0
- package/dist/resources/skills/create-skill/references/workflows-and-validation.md +510 -0
- package/dist/resources/skills/create-skill/templates/router-skill.md +73 -0
- package/dist/resources/skills/create-skill/templates/simple-skill.md +33 -0
- package/dist/resources/skills/create-skill/workflows/add-reference.md +96 -0
- package/dist/resources/skills/create-skill/workflows/add-script.md +93 -0
- package/dist/resources/skills/create-skill/workflows/add-template.md +74 -0
- package/dist/resources/skills/create-skill/workflows/add-workflow.md +120 -0
- package/dist/resources/skills/create-skill/workflows/audit-skill.md +148 -0
- package/dist/resources/skills/create-skill/workflows/create-new-skill.md +196 -0
- package/dist/resources/skills/create-skill/workflows/get-guidance.md +121 -0
- package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +161 -0
- package/dist/resources/skills/create-skill/workflows/verify-skill.md +204 -0
- package/dist/resources/skills/react-best-practices/SKILL.md +1 -1
- package/package.json +1 -1
- package/packages/native/dist/native.d.ts +2 -0
- package/packages/native/dist/native.js +19 -5
- package/packages/native/src/native.ts +23 -9
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +13 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/client.js +3 -0
- package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +13 -0
- package/packages/pi-coding-agent/src/core/lsp/client.ts +3 -0
- package/src/resources/extensions/async-jobs/extension-manifest.json +13 -0
- package/src/resources/extensions/bg-shell/extension-manifest.json +14 -0
- package/src/resources/extensions/bg-shell/process-manager.ts +13 -0
- package/src/resources/extensions/browser-tools/extension-manifest.json +37 -0
- package/src/resources/extensions/context7/extension-manifest.json +12 -0
- package/src/resources/extensions/google-search/extension-manifest.json +12 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +217 -65
- package/src/resources/extensions/gsd/auto-dispatch.ts +32 -3
- package/src/resources/extensions/gsd/auto-post-unit.ts +45 -13
- package/src/resources/extensions/gsd/auto-prompts.ts +40 -17
- package/src/resources/extensions/gsd/auto-recovery.ts +18 -23
- package/src/resources/extensions/gsd/auto-start.ts +18 -32
- package/src/resources/extensions/gsd/auto-worktree.ts +21 -182
- package/src/resources/extensions/gsd/auto.ts +2 -24
- package/src/resources/extensions/gsd/captures.ts +4 -10
- package/src/resources/extensions/gsd/commands-extensions.ts +328 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +22 -2
- package/src/resources/extensions/gsd/commands-logs.ts +13 -14
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +44 -14
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +544 -0
- package/src/resources/extensions/gsd/commands.ts +108 -24
- package/src/resources/extensions/gsd/dashboard-overlay.ts +2 -1
- package/src/resources/extensions/gsd/detection.ts +2 -1
- package/src/resources/extensions/gsd/doctor-checks.ts +49 -1
- package/src/resources/extensions/gsd/doctor-types.ts +3 -1
- package/src/resources/extensions/gsd/extension-manifest.json +18 -0
- package/src/resources/extensions/gsd/forensics.ts +2 -2
- package/src/resources/extensions/gsd/git-service.ts +3 -2
- package/src/resources/extensions/gsd/gitignore.ts +9 -63
- package/src/resources/extensions/gsd/gsd-db.ts +1 -165
- package/src/resources/extensions/gsd/guided-flow.ts +8 -5
- package/src/resources/extensions/gsd/index.ts +3 -3
- package/src/resources/extensions/gsd/json-persistence.ts +16 -1
- package/src/resources/extensions/gsd/md-importer.ts +3 -2
- package/src/resources/extensions/gsd/mechanical-completion.ts +430 -0
- package/src/resources/extensions/gsd/migrate/command.ts +3 -2
- package/src/resources/extensions/gsd/migrate/writer.ts +2 -1
- package/src/resources/extensions/gsd/migrate-external.ts +123 -0
- package/src/resources/extensions/gsd/paths.ts +24 -2
- package/src/resources/extensions/gsd/post-unit-hooks.ts +6 -5
- package/src/resources/extensions/gsd/preferences-models.ts +7 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +2 -1
- package/src/resources/extensions/gsd/preferences.ts +10 -5
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +4 -2
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +26 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -1
- package/src/resources/extensions/gsd/prompts/workflow-start.md +28 -0
- package/src/resources/extensions/gsd/queue-order.ts +10 -11
- package/src/resources/extensions/gsd/repo-identity.ts +148 -0
- package/src/resources/extensions/gsd/resource-version.ts +99 -0
- package/src/resources/extensions/gsd/session-forensics.ts +4 -3
- package/src/resources/extensions/gsd/session-status-io.ts +23 -41
- package/src/resources/extensions/gsd/tests/activity-log.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/auto-skip-loop.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +0 -58
- package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +3 -4
- package/src/resources/extensions/gsd/tests/extension-selector-separator.test.ts +60 -38
- package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +5 -18
- package/src/resources/extensions/gsd/tests/git-service.test.ts +10 -37
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/mechanical-completion.test.ts +356 -0
- package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +14 -16
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +173 -0
- package/src/resources/extensions/gsd/triage-resolution.ts +2 -1
- package/src/resources/extensions/gsd/types.ts +2 -0
- package/src/resources/extensions/gsd/workflow-templates/bugfix.md +87 -0
- package/src/resources/extensions/gsd/workflow-templates/dep-upgrade.md +74 -0
- package/src/resources/extensions/gsd/workflow-templates/full-project.md +41 -0
- package/src/resources/extensions/gsd/workflow-templates/hotfix.md +45 -0
- package/src/resources/extensions/gsd/workflow-templates/refactor.md +83 -0
- package/src/resources/extensions/gsd/workflow-templates/registry.json +85 -0
- package/src/resources/extensions/gsd/workflow-templates/security-audit.md +73 -0
- package/src/resources/extensions/gsd/workflow-templates/small-feature.md +81 -0
- package/src/resources/extensions/gsd/workflow-templates/spike.md +69 -0
- package/src/resources/extensions/gsd/workflow-templates.ts +241 -0
- package/src/resources/extensions/gsd/worktree-command.ts +1 -11
- package/src/resources/extensions/gsd/worktree-manager.ts +3 -2
- package/src/resources/extensions/gsd/worktree.ts +42 -5
- package/src/resources/extensions/mac-tools/extension-manifest.json +16 -0
- package/src/resources/extensions/mcp-client/index.ts +459 -0
- package/src/resources/extensions/mcporter/extension-manifest.json +12 -0
- package/src/resources/extensions/remote-questions/discord-adapter.ts +8 -19
- package/src/resources/extensions/remote-questions/extension-manifest.json +11 -0
- package/src/resources/extensions/remote-questions/http-client.ts +76 -0
- package/src/resources/extensions/remote-questions/slack-adapter.ts +11 -17
- package/src/resources/extensions/remote-questions/telegram-adapter.ts +8 -19
- package/src/resources/extensions/search-the-web/extension-manifest.json +13 -0
- package/src/resources/extensions/slash-commands/extension-manifest.json +11 -0
- package/src/resources/extensions/subagent/extension-manifest.json +13 -0
- package/src/resources/extensions/ttsr/extension-manifest.json +11 -0
- package/src/resources/extensions/universal-config/extension-manifest.json +13 -0
- package/src/resources/extensions/voice/extension-manifest.json +12 -0
- package/src/resources/skills/create-gsd-extension/SKILL.md +87 -0
- package/src/resources/skills/create-gsd-extension/references/compaction-session-control.md +77 -0
- package/src/resources/skills/create-gsd-extension/references/custom-commands.md +139 -0
- package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +108 -0
- package/src/resources/skills/create-gsd-extension/references/custom-tools.md +183 -0
- package/src/resources/skills/create-gsd-extension/references/custom-ui.md +490 -0
- package/src/resources/skills/create-gsd-extension/references/events-reference.md +126 -0
- package/src/resources/skills/create-gsd-extension/references/extension-lifecycle.md +64 -0
- package/src/resources/skills/create-gsd-extension/references/extensionapi-reference.md +75 -0
- package/src/resources/skills/create-gsd-extension/references/extensioncontext-reference.md +53 -0
- package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +36 -0
- package/src/resources/skills/create-gsd-extension/references/mode-behavior.md +32 -0
- package/src/resources/skills/create-gsd-extension/references/model-provider-management.md +89 -0
- package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +55 -0
- package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +90 -0
- package/src/resources/skills/create-gsd-extension/references/state-management.md +70 -0
- package/src/resources/skills/create-gsd-extension/references/system-prompt-modification.md +52 -0
- package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +51 -0
- package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +143 -0
- package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +57 -0
- package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +156 -0
- package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +74 -0
- package/src/resources/skills/create-skill/SKILL.md +184 -0
- package/src/resources/skills/create-skill/references/api-security.md +226 -0
- package/src/resources/skills/create-skill/references/be-clear-and-direct.md +531 -0
- package/src/resources/skills/create-skill/references/common-patterns.md +595 -0
- package/src/resources/skills/create-skill/references/core-principles.md +437 -0
- package/src/resources/skills/create-skill/references/executable-code.md +175 -0
- package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +68 -0
- package/src/resources/skills/create-skill/references/iteration-and-testing.md +474 -0
- package/src/resources/skills/create-skill/references/recommended-structure.md +168 -0
- package/src/resources/skills/create-skill/references/skill-structure.md +372 -0
- package/src/resources/skills/create-skill/references/use-xml-tags.md +466 -0
- package/src/resources/skills/create-skill/references/using-scripts.md +113 -0
- package/src/resources/skills/create-skill/references/using-templates.md +112 -0
- package/src/resources/skills/create-skill/references/workflows-and-validation.md +510 -0
- package/src/resources/skills/create-skill/templates/router-skill.md +73 -0
- package/src/resources/skills/create-skill/templates/simple-skill.md +33 -0
- package/src/resources/skills/create-skill/workflows/add-reference.md +96 -0
- package/src/resources/skills/create-skill/workflows/add-script.md +93 -0
- package/src/resources/skills/create-skill/workflows/add-template.md +74 -0
- package/src/resources/skills/create-skill/workflows/add-workflow.md +120 -0
- package/src/resources/skills/create-skill/workflows/audit-skill.md +148 -0
- package/src/resources/skills/create-skill/workflows/create-new-skill.md +196 -0
- package/src/resources/skills/create-skill/workflows/get-guidance.md +121 -0
- package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +161 -0
- package/src/resources/skills/create-skill/workflows/verify-skill.md +204 -0
- package/src/resources/skills/react-best-practices/SKILL.md +1 -1
- package/dist/resources/extensions/gsd/auto-worktree-sync.ts +0 -198
- package/dist/resources/extensions/gsd/tests/worktree-db-integration.test.ts +0 -205
- package/dist/resources/extensions/gsd/tests/worktree-db.test.ts +0 -442
- package/dist/resources/extensions/mcporter/index.ts +0 -525
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +0 -198
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +0 -205
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +0 -442
- package/src/resources/extensions/mcporter/index.ts +0 -525
|
@@ -22,7 +22,6 @@ import { loadFile, getManifestStatus, resolveAllOverrides, parsePlan, parseSumma
|
|
|
22
22
|
import { loadPrompt } from "./prompt-loader.js";
|
|
23
23
|
import { runVerificationGate, formatFailureContext, captureRuntimeErrors, runDependencyAudit } from "./verification-gate.js";
|
|
24
24
|
import { writeVerificationJSON } from "./verification-evidence.js";
|
|
25
|
-
export { inlinePriorMilestoneSummary } from "./files.js";
|
|
26
25
|
import { collectSecretsFromManifest } from "../get-secrets-from-user.js";
|
|
27
26
|
import {
|
|
28
27
|
gsdRoot, resolveMilestoneFile, resolveSliceFile, resolveSlicePath,
|
|
@@ -70,12 +69,10 @@ import { closeoutUnit } from "./auto-unit-closeout.js";
|
|
|
70
69
|
import { recoverTimedOutUnit } from "./auto-timeout-recovery.js";
|
|
71
70
|
import { selectAndApplyModel } from "./auto-model-selection.js";
|
|
72
71
|
import {
|
|
73
|
-
syncProjectRootToWorktree,
|
|
74
|
-
syncStateToProjectRoot,
|
|
75
72
|
readResourceVersion,
|
|
76
73
|
checkResourcesStale,
|
|
77
74
|
escapeStaleWorktree,
|
|
78
|
-
} from "./
|
|
75
|
+
} from "./resource-version.js";
|
|
79
76
|
import { initRoutingHistory, resetRoutingHistory, recordOutcome } from "./routing-history.js";
|
|
80
77
|
import {
|
|
81
78
|
checkPostUnitHooks,
|
|
@@ -181,7 +178,7 @@ import { runPostUnitVerification, type VerificationContext } from "./auto-verifi
|
|
|
181
178
|
import { postUnitPreVerification, postUnitPostVerification, type PostUnitContext } from "./auto-post-unit.js";
|
|
182
179
|
import { bootstrapAutoSession, type BootstrapDeps } from "./auto-start.js";
|
|
183
180
|
|
|
184
|
-
//
|
|
181
|
+
// Resource staleness, stale worktree escape → resource-version.ts
|
|
185
182
|
|
|
186
183
|
// ─── Session State ─────────────────────────────────────────────────────────
|
|
187
184
|
|
|
@@ -192,12 +189,6 @@ import {
|
|
|
192
189
|
NEW_SESSION_TIMEOUT_MS, DISPATCH_HANG_TIMEOUT_MS,
|
|
193
190
|
} from "./auto/session.js";
|
|
194
191
|
import type { CompletedUnit, CurrentUnit, UnitRouting, StartModel, PendingVerificationRetry } from "./auto/session.js";
|
|
195
|
-
export {
|
|
196
|
-
MAX_UNIT_DISPATCHES, STUB_RECOVERY_THRESHOLD, MAX_LIFETIME_DISPATCHES,
|
|
197
|
-
MAX_CONSECUTIVE_SKIPS, DISPATCH_GAP_TIMEOUT_MS, MAX_SKIP_DEPTH,
|
|
198
|
-
NEW_SESSION_TIMEOUT_MS, DISPATCH_HANG_TIMEOUT_MS,
|
|
199
|
-
} from "./auto/session.js";
|
|
200
|
-
export type { CompletedUnit, CurrentUnit, UnitRouting, StartModel } from "./auto/session.js";
|
|
201
192
|
|
|
202
193
|
// ── ENCAPSULATION INVARIANT ─────────────────────────────────────────────────
|
|
203
194
|
// ALL mutable auto-mode state lives in the AutoSession class (auto/session.ts).
|
|
@@ -268,8 +259,6 @@ export function shouldUseWorktreeIsolation(): boolean {
|
|
|
268
259
|
* Maps toolCallId → start timestamp (ms) so the idle watchdog can detect tools that have been
|
|
269
260
|
* running suspiciously long (e.g., a Bash command hung because `&` kept stdout open).
|
|
270
261
|
*/
|
|
271
|
-
// Re-export budget utilities for external consumers
|
|
272
|
-
export { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction } from "./auto-budget.js";
|
|
273
262
|
|
|
274
263
|
/** Wrapper: register SIGTERM handler and store reference. */
|
|
275
264
|
function registerSigtermHandler(currentBasePath: string): void {
|
|
@@ -282,8 +271,6 @@ function deregisterSigtermHandler(): void {
|
|
|
282
271
|
s.sigtermHandler = null;
|
|
283
272
|
}
|
|
284
273
|
|
|
285
|
-
export { type AutoDashboardData } from "./auto-dashboard.js";
|
|
286
|
-
|
|
287
274
|
export function getAutoDashboardData(): AutoDashboardData {
|
|
288
275
|
const ledger = getLedger();
|
|
289
276
|
const totals = ledger ? getProjectTotals(ledger.units) : null;
|
|
@@ -934,8 +921,6 @@ async function showStepWizard(
|
|
|
934
921
|
}
|
|
935
922
|
}
|
|
936
923
|
|
|
937
|
-
// describeNextUnit is imported from auto-dashboard.ts and re-exported
|
|
938
|
-
export { describeNextUnit } from "./auto-dashboard.js";
|
|
939
924
|
|
|
940
925
|
/** Thin wrapper: delegates to auto-dashboard.ts, passing state accessors. */
|
|
941
926
|
function updateProgressWidget(
|
|
@@ -1031,11 +1016,6 @@ async function dispatchNextUnit(
|
|
|
1031
1016
|
// Non-fatal
|
|
1032
1017
|
}
|
|
1033
1018
|
|
|
1034
|
-
// ── Sync project root artifacts into worktree ──
|
|
1035
|
-
if (s.originalBasePath && s.basePath !== s.originalBasePath && s.currentMilestoneId) {
|
|
1036
|
-
syncProjectRootToWorktree(s.originalBasePath, s.basePath, s.currentMilestoneId);
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
1019
|
const stopDeriveTimer = debugTime("derive-state");
|
|
1040
1020
|
let state = await deriveState(s.basePath);
|
|
1041
1021
|
stopDeriveTimer({
|
|
@@ -1905,5 +1885,3 @@ export async function dispatchHookUnit(
|
|
|
1905
1885
|
}
|
|
1906
1886
|
|
|
1907
1887
|
|
|
1908
|
-
// Direct phase dispatch → auto-direct-dispatch.ts
|
|
1909
|
-
export { dispatchDirectPhase } from "./auto-direct-dispatch.js";
|
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
12
|
-
import { join, resolve
|
|
12
|
+
import { join, resolve } from "node:path";
|
|
13
13
|
import { randomUUID } from "node:crypto";
|
|
14
14
|
import { gsdRoot } from "./paths.js";
|
|
15
|
+
import { resolveProjectRoot } from "./worktree.js";
|
|
15
16
|
|
|
16
17
|
// ─── Types ────────────────────────────────────────────────────────────────────
|
|
17
18
|
|
|
@@ -58,15 +59,8 @@ const VALID_CLASSIFICATIONS: readonly string[] = [
|
|
|
58
59
|
* directory that contains `.gsd/worktrees/` — that's the project root.
|
|
59
60
|
*/
|
|
60
61
|
export function resolveCapturesPath(basePath: string): string {
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
const idx = resolved.indexOf(worktreeMarker);
|
|
64
|
-
if (idx !== -1) {
|
|
65
|
-
// basePath is inside a worktree — resolve to project root
|
|
66
|
-
const projectRoot = resolved.slice(0, idx);
|
|
67
|
-
return join(projectRoot, ".gsd", CAPTURES_FILENAME);
|
|
68
|
-
}
|
|
69
|
-
return join(gsdRoot(basePath), CAPTURES_FILENAME);
|
|
62
|
+
const projectRoot = resolveProjectRoot(resolve(basePath));
|
|
63
|
+
return join(gsdRoot(projectRoot), CAPTURES_FILENAME);
|
|
70
64
|
}
|
|
71
65
|
|
|
72
66
|
// ─── File I/O ─────────────────────────────────────────────────────────────────
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GSD Extensions Command — /gsd extensions
|
|
3
|
+
*
|
|
4
|
+
* Manage the extension registry: list, enable, disable, info.
|
|
5
|
+
* Self-contained — no imports outside the extensions tree (extensions are loaded
|
|
6
|
+
* via jiti at runtime from ~/.gsd/agent/, not compiled by tsc).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { ExtensionCommandContext } from "@gsd/pi-coding-agent";
|
|
10
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, writeFileSync } from "node:fs";
|
|
11
|
+
import { dirname, join } from "node:path";
|
|
12
|
+
import { homedir } from "node:os";
|
|
13
|
+
|
|
14
|
+
// ─── Types (mirrored from extension-registry.ts) ────────────────────────────
|
|
15
|
+
|
|
16
|
+
interface ExtensionManifest {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
version: string;
|
|
20
|
+
description: string;
|
|
21
|
+
tier: "core" | "bundled" | "community";
|
|
22
|
+
requires: { platform: string };
|
|
23
|
+
provides?: {
|
|
24
|
+
tools?: string[];
|
|
25
|
+
commands?: string[];
|
|
26
|
+
hooks?: string[];
|
|
27
|
+
shortcuts?: string[];
|
|
28
|
+
};
|
|
29
|
+
dependencies?: {
|
|
30
|
+
extensions?: string[];
|
|
31
|
+
runtime?: string[];
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface ExtensionRegistryEntry {
|
|
36
|
+
id: string;
|
|
37
|
+
enabled: boolean;
|
|
38
|
+
source: "bundled" | "user" | "project";
|
|
39
|
+
disabledAt?: string;
|
|
40
|
+
disabledReason?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface ExtensionRegistry {
|
|
44
|
+
version: 1;
|
|
45
|
+
entries: Record<string, ExtensionRegistryEntry>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ─── Registry I/O ───────────────────────────────────────────────────────────
|
|
49
|
+
|
|
50
|
+
function getRegistryPath(): string {
|
|
51
|
+
return join(homedir(), ".gsd", "extensions", "registry.json");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function getAgentExtensionsDir(): string {
|
|
55
|
+
return join(homedir(), ".gsd", "agent", "extensions");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function loadRegistry(): ExtensionRegistry {
|
|
59
|
+
const filePath = getRegistryPath();
|
|
60
|
+
try {
|
|
61
|
+
if (!existsSync(filePath)) return { version: 1, entries: {} };
|
|
62
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
63
|
+
const parsed = JSON.parse(raw);
|
|
64
|
+
if (typeof parsed === "object" && parsed !== null && parsed.version === 1 && typeof parsed.entries === "object") {
|
|
65
|
+
return parsed as ExtensionRegistry;
|
|
66
|
+
}
|
|
67
|
+
return { version: 1, entries: {} };
|
|
68
|
+
} catch {
|
|
69
|
+
return { version: 1, entries: {} };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function saveRegistry(registry: ExtensionRegistry): void {
|
|
74
|
+
const filePath = getRegistryPath();
|
|
75
|
+
try {
|
|
76
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
77
|
+
const tmp = filePath + ".tmp";
|
|
78
|
+
writeFileSync(tmp, JSON.stringify(registry, null, 2), "utf-8");
|
|
79
|
+
renameSync(tmp, filePath);
|
|
80
|
+
} catch { /* non-fatal */ }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function isEnabled(registry: ExtensionRegistry, id: string): boolean {
|
|
84
|
+
const entry = registry.entries[id];
|
|
85
|
+
if (!entry) return true;
|
|
86
|
+
return entry.enabled;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function readManifest(dir: string): ExtensionManifest | null {
|
|
90
|
+
const mPath = join(dir, "extension-manifest.json");
|
|
91
|
+
if (!existsSync(mPath)) return null;
|
|
92
|
+
try {
|
|
93
|
+
const raw = JSON.parse(readFileSync(mPath, "utf-8"));
|
|
94
|
+
if (typeof raw?.id === "string" && typeof raw?.name === "string") return raw as ExtensionManifest;
|
|
95
|
+
return null;
|
|
96
|
+
} catch {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function discoverManifests(): Map<string, ExtensionManifest> {
|
|
102
|
+
const extDir = getAgentExtensionsDir();
|
|
103
|
+
const manifests = new Map<string, ExtensionManifest>();
|
|
104
|
+
if (!existsSync(extDir)) return manifests;
|
|
105
|
+
for (const entry of readdirSync(extDir, { withFileTypes: true })) {
|
|
106
|
+
if (!entry.isDirectory()) continue;
|
|
107
|
+
const m = readManifest(join(extDir, entry.name));
|
|
108
|
+
if (m) manifests.set(m.id, m);
|
|
109
|
+
}
|
|
110
|
+
return manifests;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ─── Command Handler ────────────────────────────────────────────────────────
|
|
114
|
+
|
|
115
|
+
export async function handleExtensions(args: string, ctx: ExtensionCommandContext): Promise<void> {
|
|
116
|
+
const parts = args.split(/\s+/).filter(Boolean);
|
|
117
|
+
const subCmd = parts[0] ?? "list";
|
|
118
|
+
|
|
119
|
+
if (subCmd === "list") {
|
|
120
|
+
handleList(ctx);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (subCmd === "enable") {
|
|
125
|
+
handleEnable(parts[1], ctx);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (subCmd === "disable") {
|
|
130
|
+
handleDisable(parts[1], parts.slice(2).join(" "), ctx);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (subCmd === "info") {
|
|
135
|
+
handleInfo(parts[1], ctx);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
ctx.ui.notify(
|
|
140
|
+
`Unknown: /gsd extensions ${subCmd}. Usage: /gsd extensions [list|enable|disable|info]`,
|
|
141
|
+
"warning",
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function handleList(ctx: ExtensionCommandContext): void {
|
|
146
|
+
const manifests = discoverManifests();
|
|
147
|
+
const registry = loadRegistry();
|
|
148
|
+
|
|
149
|
+
if (manifests.size === 0) {
|
|
150
|
+
ctx.ui.notify("No extension manifests found.", "warning");
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Sort: core first, then alphabetical
|
|
155
|
+
const sorted = [...manifests.values()].sort((a, b) => {
|
|
156
|
+
if (a.tier === "core" && b.tier !== "core") return -1;
|
|
157
|
+
if (b.tier === "core" && a.tier !== "core") return 1;
|
|
158
|
+
return a.id.localeCompare(b.id);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
const lines: string[] = [];
|
|
162
|
+
const hdr = padRight("Extensions", 38) + padRight("Status", 10) + padRight("Tier", 10) + padRight("Tools", 7) + "Commands";
|
|
163
|
+
lines.push(hdr);
|
|
164
|
+
lines.push("─".repeat(hdr.length));
|
|
165
|
+
|
|
166
|
+
for (const m of sorted) {
|
|
167
|
+
const enabled = isEnabled(registry, m.id);
|
|
168
|
+
const status = enabled ? "enabled" : "disabled";
|
|
169
|
+
const toolCount = m.provides?.tools?.length ?? 0;
|
|
170
|
+
const cmdCount = m.provides?.commands?.length ?? 0;
|
|
171
|
+
const label = `${m.id} (${m.name})`;
|
|
172
|
+
|
|
173
|
+
lines.push(
|
|
174
|
+
padRight(label, 38) +
|
|
175
|
+
padRight(status, 10) +
|
|
176
|
+
padRight(m.tier, 10) +
|
|
177
|
+
padRight(String(toolCount), 7) +
|
|
178
|
+
String(cmdCount),
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
if (!enabled) {
|
|
182
|
+
lines.push(` ↳ gsd extensions enable ${m.id}`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
ctx.ui.notify(lines.join("\n"), "info");
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function handleEnable(id: string | undefined, ctx: ExtensionCommandContext): void {
|
|
190
|
+
if (!id) {
|
|
191
|
+
ctx.ui.notify("Usage: /gsd extensions enable <id>", "warning");
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const manifests = discoverManifests();
|
|
196
|
+
if (!manifests.has(id)) {
|
|
197
|
+
ctx.ui.notify(`Extension "${id}" not found. Run /gsd extensions list to see available extensions.`, "warning");
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const registry = loadRegistry();
|
|
202
|
+
if (isEnabled(registry, id)) {
|
|
203
|
+
ctx.ui.notify(`Extension "${id}" is already enabled.`, "info");
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const entry = registry.entries[id];
|
|
208
|
+
if (entry) {
|
|
209
|
+
entry.enabled = true;
|
|
210
|
+
delete entry.disabledAt;
|
|
211
|
+
delete entry.disabledReason;
|
|
212
|
+
} else {
|
|
213
|
+
registry.entries[id] = { id, enabled: true, source: "bundled" };
|
|
214
|
+
}
|
|
215
|
+
saveRegistry(registry);
|
|
216
|
+
ctx.ui.notify(`Enabled "${id}". Restart GSD to activate.`, "info");
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function handleDisable(id: string | undefined, reason: string, ctx: ExtensionCommandContext): void {
|
|
220
|
+
if (!id) {
|
|
221
|
+
ctx.ui.notify("Usage: /gsd extensions disable <id>", "warning");
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const manifests = discoverManifests();
|
|
226
|
+
const manifest = manifests.get(id) ?? null;
|
|
227
|
+
|
|
228
|
+
if (!manifests.has(id)) {
|
|
229
|
+
ctx.ui.notify(`Extension "${id}" not found. Run /gsd extensions list to see available extensions.`, "warning");
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (manifest?.tier === "core") {
|
|
234
|
+
ctx.ui.notify(`Cannot disable "${id}" — it is a core extension.`, "warning");
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const registry = loadRegistry();
|
|
239
|
+
if (!isEnabled(registry, id)) {
|
|
240
|
+
ctx.ui.notify(`Extension "${id}" is already disabled.`, "info");
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const entry = registry.entries[id];
|
|
245
|
+
if (entry) {
|
|
246
|
+
entry.enabled = false;
|
|
247
|
+
entry.disabledAt = new Date().toISOString();
|
|
248
|
+
entry.disabledReason = reason || undefined;
|
|
249
|
+
} else {
|
|
250
|
+
registry.entries[id] = {
|
|
251
|
+
id,
|
|
252
|
+
enabled: false,
|
|
253
|
+
source: "bundled",
|
|
254
|
+
disabledAt: new Date().toISOString(),
|
|
255
|
+
disabledReason: reason || undefined,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
saveRegistry(registry);
|
|
259
|
+
ctx.ui.notify(`Disabled "${id}". Restart GSD to deactivate.`, "info");
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function handleInfo(id: string | undefined, ctx: ExtensionCommandContext): void {
|
|
263
|
+
if (!id) {
|
|
264
|
+
ctx.ui.notify("Usage: /gsd extensions info <id>", "warning");
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const manifests = discoverManifests();
|
|
269
|
+
const manifest = manifests.get(id);
|
|
270
|
+
if (!manifest) {
|
|
271
|
+
ctx.ui.notify(`Extension "${id}" not found.`, "warning");
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const registry = loadRegistry();
|
|
276
|
+
const enabled = isEnabled(registry, id);
|
|
277
|
+
const entry = registry.entries[id];
|
|
278
|
+
|
|
279
|
+
const lines: string[] = [
|
|
280
|
+
`${manifest.name} (${manifest.id})`,
|
|
281
|
+
"",
|
|
282
|
+
` Version: ${manifest.version}`,
|
|
283
|
+
` Description: ${manifest.description}`,
|
|
284
|
+
` Tier: ${manifest.tier}`,
|
|
285
|
+
` Status: ${enabled ? "enabled" : "disabled"}`,
|
|
286
|
+
];
|
|
287
|
+
|
|
288
|
+
if (entry?.disabledAt) {
|
|
289
|
+
lines.push(` Disabled at: ${entry.disabledAt}`);
|
|
290
|
+
}
|
|
291
|
+
if (entry?.disabledReason) {
|
|
292
|
+
lines.push(` Reason: ${entry.disabledReason}`);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (manifest.provides) {
|
|
296
|
+
lines.push("");
|
|
297
|
+
lines.push(" Provides:");
|
|
298
|
+
if (manifest.provides.tools?.length) {
|
|
299
|
+
lines.push(` Tools: ${manifest.provides.tools.join(", ")}`);
|
|
300
|
+
}
|
|
301
|
+
if (manifest.provides.commands?.length) {
|
|
302
|
+
lines.push(` Commands: ${manifest.provides.commands.join(", ")}`);
|
|
303
|
+
}
|
|
304
|
+
if (manifest.provides.hooks?.length) {
|
|
305
|
+
lines.push(` Hooks: ${manifest.provides.hooks.join(", ")}`);
|
|
306
|
+
}
|
|
307
|
+
if (manifest.provides.shortcuts?.length) {
|
|
308
|
+
lines.push(` Shortcuts: ${manifest.provides.shortcuts.join(", ")}`);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (manifest.dependencies) {
|
|
313
|
+
lines.push("");
|
|
314
|
+
lines.push(" Dependencies:");
|
|
315
|
+
if (manifest.dependencies.extensions?.length) {
|
|
316
|
+
lines.push(` Extensions: ${manifest.dependencies.extensions.join(", ")}`);
|
|
317
|
+
}
|
|
318
|
+
if (manifest.dependencies.runtime?.length) {
|
|
319
|
+
lines.push(` Runtime: ${manifest.dependencies.runtime.join(", ")}`);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
ctx.ui.notify(lines.join("\n"), "info");
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function padRight(str: string, len: number): string {
|
|
327
|
+
return str.length >= len ? str + " " : str + " ".repeat(len - str.length);
|
|
328
|
+
}
|
|
@@ -9,6 +9,7 @@ import type { ExtensionAPI, ExtensionCommandContext } from "@gsd/pi-coding-agent
|
|
|
9
9
|
import { existsSync, readFileSync, mkdirSync } from "node:fs";
|
|
10
10
|
import { join } from "node:path";
|
|
11
11
|
import { deriveState } from "./state.js";
|
|
12
|
+
import { gsdRoot } from "./paths.js";
|
|
12
13
|
import { appendCapture, hasPendingCaptures, loadPendingCaptures } from "./captures.js";
|
|
13
14
|
import { appendOverride, appendKnowledge } from "./files.js";
|
|
14
15
|
import {
|
|
@@ -19,7 +20,26 @@ import {
|
|
|
19
20
|
filterDoctorIssues,
|
|
20
21
|
} from "./doctor.js";
|
|
21
22
|
import { isAutoActive } from "./auto.js";
|
|
22
|
-
import { projectRoot
|
|
23
|
+
import { projectRoot } from "./commands.js";
|
|
24
|
+
import { loadPrompt } from "./prompt-loader.js";
|
|
25
|
+
|
|
26
|
+
export function dispatchDoctorHeal(pi: ExtensionAPI, scope: string | undefined, reportText: string, structuredIssues: string): void {
|
|
27
|
+
const workflowPath = process.env.GSD_WORKFLOW_PATH ?? join(process.env.HOME ?? "~", ".pi", "GSD-WORKFLOW.md");
|
|
28
|
+
const workflow = readFileSync(workflowPath, "utf-8");
|
|
29
|
+
const prompt = loadPrompt("doctor-heal", {
|
|
30
|
+
doctorSummary: reportText,
|
|
31
|
+
structuredIssues,
|
|
32
|
+
scopeLabel: scope ?? "active milestone / blocking scope",
|
|
33
|
+
doctorCommandSuffix: scope ? ` ${scope}` : "",
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const content = `Read the following GSD workflow protocol and execute exactly.\n\n${workflow}\n\n## Your Task\n\n${prompt}`;
|
|
37
|
+
|
|
38
|
+
pi.sendMessage(
|
|
39
|
+
{ customType: "gsd-doctor-heal", content, display: false },
|
|
40
|
+
{ triggerTurn: true },
|
|
41
|
+
);
|
|
42
|
+
}
|
|
23
43
|
|
|
24
44
|
export async function handleDoctor(args: string, ctx: ExtensionCommandContext, pi: ExtensionAPI): Promise<void> {
|
|
25
45
|
const trimmed = args.trim();
|
|
@@ -117,7 +137,7 @@ export async function handleCapture(args: string, ctx: ExtensionCommandContext):
|
|
|
117
137
|
const basePath = process.cwd();
|
|
118
138
|
|
|
119
139
|
// Ensure .gsd/ exists — capture should work even without a milestone
|
|
120
|
-
const gsdDir =
|
|
140
|
+
const gsdDir = gsdRoot(basePath);
|
|
121
141
|
if (!existsSync(gsdDir)) {
|
|
122
142
|
mkdirSync(gsdDir, { recursive: true });
|
|
123
143
|
}
|
|
@@ -14,6 +14,7 @@ import type { ExtensionCommandContext } from "@gsd/pi-coding-agent";
|
|
|
14
14
|
import { existsSync, readdirSync, readFileSync, statSync, unlinkSync } from "node:fs";
|
|
15
15
|
import { join } from "node:path";
|
|
16
16
|
import { gsdRoot } from "./paths.js";
|
|
17
|
+
import { loadJsonFileOrNull } from "./json-persistence.js";
|
|
17
18
|
|
|
18
19
|
// ─── Types ──────────────────────────────────────────────────────────────────
|
|
19
20
|
|
|
@@ -331,20 +332,18 @@ async function handleLogsList(basePath: string, ctx: ExtensionCommandContext): P
|
|
|
331
332
|
|
|
332
333
|
// Metrics summary
|
|
333
334
|
const metricsPath = join(gsdRoot(basePath), "metrics.json");
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
}
|
|
347
|
-
} catch { /* ignore */ }
|
|
335
|
+
const isMetrics = (d: unknown): d is { units: Array<Record<string, unknown>> } =>
|
|
336
|
+
d !== null && typeof d === "object" && "units" in d! && Array.isArray((d as Record<string, unknown>).units);
|
|
337
|
+
const metrics = loadJsonFileOrNull(metricsPath, isMetrics);
|
|
338
|
+
if (metrics && metrics.units.length > 0) {
|
|
339
|
+
const units = metrics.units;
|
|
340
|
+
const totalCost = units.reduce((sum: number, u) => sum + ((u.cost as number) ?? 0), 0);
|
|
341
|
+
const totalTokens = units.reduce((sum: number, u) => {
|
|
342
|
+
const t = u.tokens as Record<string, number> | undefined;
|
|
343
|
+
return sum + (t?.total ?? 0);
|
|
344
|
+
}, 0);
|
|
345
|
+
lines.push("");
|
|
346
|
+
lines.push(`Metrics: ${units.length} units tracked · $${totalCost.toFixed(2)} · ${(totalTokens / 1000).toFixed(0)}K tokens`);
|
|
348
347
|
}
|
|
349
348
|
|
|
350
349
|
lines.push("");
|
|
@@ -260,27 +260,57 @@ async function configureModels(ctx: ExtensionCommandContext, prefs: Record<strin
|
|
|
260
260
|
group.push(m);
|
|
261
261
|
}
|
|
262
262
|
const providers = Array.from(byProvider.keys()).sort((a, b) => a.localeCompare(b));
|
|
263
|
-
|
|
264
|
-
const
|
|
265
|
-
|
|
266
|
-
const group = byProvider.get(provider)!;
|
|
267
|
-
modelOptions.push(`─── ${provider} (${group.length}) ───`);
|
|
268
|
-
for (const m of group) {
|
|
269
|
-
modelOptions.push(`${m.id} · ${m.provider}`);
|
|
270
|
-
}
|
|
263
|
+
// Sort models within each provider
|
|
264
|
+
for (const group of byProvider.values()) {
|
|
265
|
+
group.sort((a, b) => a.id.localeCompare(b.id));
|
|
271
266
|
}
|
|
272
|
-
|
|
267
|
+
|
|
268
|
+
// Build provider menu with model counts
|
|
269
|
+
const providerOptions = providers.map(p => {
|
|
270
|
+
const count = byProvider.get(p)!.length;
|
|
271
|
+
return `${p} (${count} models)`;
|
|
272
|
+
});
|
|
273
|
+
providerOptions.push("(keep current)", "(clear)", "(type manually)");
|
|
273
274
|
|
|
274
275
|
for (const phase of modelPhases) {
|
|
275
276
|
const current = models[phase] ?? "";
|
|
276
|
-
const
|
|
277
|
-
|
|
277
|
+
const phaseLabel = `Model for ${phase} phase${current ? ` (current: ${current})` : ""}`;
|
|
278
|
+
|
|
279
|
+
// Step 1: pick provider
|
|
280
|
+
const providerChoice = await ctx.ui.select(`${phaseLabel} — choose provider:`, providerOptions);
|
|
281
|
+
if (!providerChoice || typeof providerChoice !== "string" || providerChoice === "(keep current)") continue;
|
|
282
|
+
|
|
283
|
+
if (providerChoice === "(clear)") {
|
|
284
|
+
delete models[phase];
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (providerChoice === "(type manually)") {
|
|
289
|
+
const input = await ctx.ui.input(
|
|
290
|
+
`${phaseLabel} — enter model ID:`,
|
|
291
|
+
current || "e.g. claude-sonnet-4-20250514",
|
|
292
|
+
);
|
|
293
|
+
if (input !== null && input !== undefined) {
|
|
294
|
+
const val = input.trim();
|
|
295
|
+
if (val) models[phase] = val;
|
|
296
|
+
}
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Step 2: pick model within provider
|
|
301
|
+
const providerName = providerChoice.replace(/ \(\d+ models?\)$/, "");
|
|
302
|
+
const group = byProvider.get(providerName);
|
|
303
|
+
if (!group) continue;
|
|
304
|
+
|
|
305
|
+
const modelOptions = group.map(m => m.id);
|
|
306
|
+
modelOptions.push("(keep current)", "(clear)");
|
|
278
307
|
|
|
279
|
-
|
|
280
|
-
|
|
308
|
+
const modelChoice = await ctx.ui.select(`${phaseLabel} — ${providerName}:`, modelOptions);
|
|
309
|
+
if (modelChoice && typeof modelChoice === "string" && modelChoice !== "(keep current)") {
|
|
310
|
+
if (modelChoice === "(clear)") {
|
|
281
311
|
delete models[phase];
|
|
282
312
|
} else {
|
|
283
|
-
models[phase] =
|
|
313
|
+
models[phase] = modelChoice;
|
|
284
314
|
}
|
|
285
315
|
}
|
|
286
316
|
}
|