gsd-pi 2.75.0-dev.063e5a3 → 2.75.0-dev.b6ad8c5f7
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 +186 -149
- package/dist/claude-cli-check.d.ts +10 -0
- package/dist/claude-cli-check.js +13 -3
- package/dist/headless-events.d.ts +1 -1
- package/dist/headless-events.js +5 -2
- package/dist/headless.js +5 -6
- package/dist/loader.js +0 -0
- package/dist/onboarding.d.ts +20 -1
- package/dist/onboarding.js +99 -39
- package/dist/resources/extensions/ask-user-questions.js +17 -5
- package/dist/resources/extensions/claude-code-cli/models.js +9 -0
- package/dist/resources/extensions/claude-code-cli/readiness.js +12 -2
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +76 -4
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +9 -0
- package/dist/resources/extensions/gsd/auto/loop.js +67 -4
- package/dist/resources/extensions/gsd/auto/phases.js +70 -47
- package/dist/resources/extensions/gsd/auto/resolve.js +1 -1
- package/dist/resources/extensions/gsd/auto/run-unit.js +10 -1
- package/dist/resources/extensions/gsd/auto/session.js +5 -0
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +20 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +15 -7
- package/dist/resources/extensions/gsd/auto-dispatch.js +112 -6
- package/dist/resources/extensions/gsd/auto-loop.js +1 -1
- package/dist/resources/extensions/gsd/auto-model-selection.js +11 -3
- package/dist/resources/extensions/gsd/auto-post-unit.js +10 -8
- package/dist/resources/extensions/gsd/auto-prompts.js +173 -39
- package/dist/resources/extensions/gsd/auto-recovery.js +57 -0
- package/dist/resources/extensions/gsd/auto-start.js +5 -3
- package/dist/resources/extensions/gsd/auto-verification.js +3 -3
- package/dist/resources/extensions/gsd/auto-worktree.js +55 -1
- package/dist/resources/extensions/gsd/auto.js +57 -25
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +8 -21
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +45 -23
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +29 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +22 -0
- package/dist/resources/extensions/gsd/commands/catalog.js +81 -9
- package/dist/resources/extensions/gsd/commands/handlers/core.js +64 -24
- package/dist/resources/extensions/gsd/commands/handlers/escalate.js +171 -0
- package/dist/resources/extensions/gsd/commands/handlers/onboarding.js +199 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +16 -0
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +228 -29
- package/dist/resources/extensions/gsd/commands-cmux.js +5 -2
- package/dist/resources/extensions/gsd/commands-config.js +5 -0
- package/dist/resources/extensions/gsd/commands-debug.js +388 -0
- package/dist/resources/extensions/gsd/commands-do.js +1 -0
- package/dist/resources/extensions/gsd/commands-extract-learnings.js +233 -75
- package/dist/resources/extensions/gsd/commands-handlers.js +21 -2
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +40 -12
- package/dist/resources/extensions/gsd/commands-scan.js +94 -0
- package/dist/resources/extensions/gsd/commands-workflow-templates.js +101 -2
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +74 -54
- package/dist/resources/extensions/gsd/db-writer.js +1 -0
- package/dist/resources/extensions/gsd/debug-session-store.js +238 -0
- package/dist/resources/extensions/gsd/definition-loader.js +7 -0
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -9
- package/dist/resources/extensions/gsd/doctor-environment.js +2 -1
- package/dist/resources/extensions/gsd/doctor-git-checks.js +5 -1
- package/dist/resources/extensions/gsd/doctor-proactive.js +4 -1
- package/dist/resources/extensions/gsd/doctor-providers.js +48 -20
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +22 -4
- package/dist/resources/extensions/gsd/doctor.js +7 -1
- package/dist/resources/extensions/gsd/error-classifier.js +6 -3
- package/dist/resources/extensions/gsd/escalation.js +321 -0
- package/dist/resources/extensions/gsd/forensics.js +26 -29
- package/dist/resources/extensions/gsd/git-service.js +0 -1
- package/dist/resources/extensions/gsd/graph.js +26 -2
- package/dist/resources/extensions/gsd/gsd-db.js +254 -29
- package/dist/resources/extensions/gsd/health-widget-core.js +42 -14
- package/dist/resources/extensions/gsd/health-widget.js +7 -4
- package/dist/resources/extensions/gsd/init-wizard.js +86 -45
- package/dist/resources/extensions/gsd/markdown-renderer.js +5 -5
- package/dist/resources/extensions/gsd/metrics.js +1 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +3 -1
- package/dist/resources/extensions/gsd/model-router.js +16 -6
- package/dist/resources/extensions/gsd/native-git-bridge.js +137 -5
- package/dist/resources/extensions/gsd/notification-overlay.js +7 -22
- package/dist/resources/extensions/gsd/notification-widget.js +24 -39
- package/dist/resources/extensions/gsd/notifications.js +4 -0
- package/dist/resources/extensions/gsd/onboarding-state.js +133 -0
- package/dist/resources/extensions/gsd/post-execution-checks.js +27 -11
- package/dist/resources/extensions/gsd/pre-execution-checks.js +97 -4
- package/dist/resources/extensions/gsd/preferences-models.js +1 -0
- package/dist/resources/extensions/gsd/preferences-types.js +2 -1
- package/dist/resources/extensions/gsd/preferences-validation.js +42 -8
- package/dist/resources/extensions/gsd/preferences.js +10 -10
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +4 -1
- package/dist/resources/extensions/gsd/prompts/debug-diagnose.md +25 -0
- package/dist/resources/extensions/gsd/prompts/debug-session-manager.md +80 -0
- package/dist/resources/extensions/gsd/prompts/execute-task.md +12 -0
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +12 -0
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +69 -0
- package/dist/resources/extensions/gsd/prompts/scan.md +79 -0
- package/dist/resources/extensions/gsd/prompts/workflow-oneshot.md +26 -0
- package/dist/resources/extensions/gsd/python-resolver.js +70 -0
- package/dist/resources/extensions/gsd/run-manager.js +37 -17
- package/dist/resources/extensions/gsd/setup-catalog.js +75 -0
- package/dist/resources/extensions/gsd/state.js +47 -3
- package/dist/resources/extensions/gsd/templates/PREFERENCES.md +7 -7
- package/dist/resources/extensions/gsd/tools/complete-task.js +80 -0
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +37 -12
- package/dist/resources/extensions/gsd/tools/plan-slice.js +5 -2
- package/dist/resources/extensions/gsd/tools/skip-slice.js +78 -0
- package/dist/resources/extensions/gsd/uok/flags.js +7 -7
- package/dist/resources/extensions/gsd/uok/kernel.js +8 -3
- package/dist/resources/extensions/gsd/verification-gate.js +2 -1
- package/dist/resources/extensions/gsd/workflow-dispatch.js +64 -0
- package/dist/resources/extensions/gsd/workflow-install.js +327 -0
- package/dist/resources/extensions/gsd/workflow-manifest.js +8 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +1 -6
- package/dist/resources/extensions/gsd/workflow-plugins.js +346 -0
- package/dist/resources/extensions/gsd/workflow-projections.js +17 -15
- package/dist/resources/extensions/gsd/workflow-templates/accessibility-audit.md +88 -0
- package/dist/resources/extensions/gsd/workflow-templates/api-breaking-change.md +117 -0
- package/dist/resources/extensions/gsd/workflow-templates/bugfix.md +1 -0
- package/dist/resources/extensions/gsd/workflow-templates/changelog-gen.md +82 -0
- package/dist/resources/extensions/gsd/workflow-templates/ci-bootstrap.md +144 -0
- package/dist/resources/extensions/gsd/workflow-templates/dead-code.md +81 -0
- package/dist/resources/extensions/gsd/workflow-templates/dep-upgrade.md +1 -0
- package/dist/resources/extensions/gsd/workflow-templates/docs-sync.yaml +76 -0
- package/dist/resources/extensions/gsd/workflow-templates/env-audit.yaml +88 -0
- package/dist/resources/extensions/gsd/workflow-templates/full-project.md +1 -0
- package/dist/resources/extensions/gsd/workflow-templates/hotfix.md +1 -0
- package/dist/resources/extensions/gsd/workflow-templates/issue-triage.md +84 -0
- package/dist/resources/extensions/gsd/workflow-templates/observability-setup.md +133 -0
- package/dist/resources/extensions/gsd/workflow-templates/onboarding-check.md +74 -0
- package/dist/resources/extensions/gsd/workflow-templates/performance-audit.md +125 -0
- package/dist/resources/extensions/gsd/workflow-templates/pr-review.md +67 -0
- package/dist/resources/extensions/gsd/workflow-templates/pr-triage.md +83 -0
- package/dist/resources/extensions/gsd/workflow-templates/refactor.md +1 -0
- package/dist/resources/extensions/gsd/workflow-templates/registry.json +184 -0
- package/dist/resources/extensions/gsd/workflow-templates/release.md +118 -0
- package/dist/resources/extensions/gsd/workflow-templates/rename-symbol.yaml +99 -0
- package/dist/resources/extensions/gsd/workflow-templates/security-audit.md +1 -0
- package/dist/resources/extensions/gsd/workflow-templates/small-feature.md +1 -0
- package/dist/resources/extensions/gsd/workflow-templates/spike.md +1 -0
- package/dist/resources/extensions/gsd/workflow-templates/test-backfill.yaml +73 -0
- package/dist/resources/extensions/gsd/worktree-resolver.js +42 -1
- package/dist/resources/extensions/remote-questions/commands.js +380 -0
- package/dist/resources/extensions/remote-questions/manager.js +39 -5
- package/dist/resources/extensions/remote-questions/telegram-adapter.js +79 -4
- package/dist/resources/extensions/shared/interview-ui.js +189 -1
- package/dist/resources/extensions/shared/layout-utils.js +17 -0
- package/dist/resources/extensions/shared/rtk-shared.js +47 -0
- package/dist/resources/extensions/shared/rtk.js +3 -46
- package/dist/resources/skills/create-workflow/SKILL.md +33 -6
- package/dist/rtk-shared.d.ts +10 -0
- package/dist/rtk-shared.js +47 -0
- package/dist/rtk.d.ts +2 -6
- package/dist/rtk.js +3 -48
- package/dist/shared/workspace-types.d.ts +52 -0
- package/dist/shared/workspace-types.js +1 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/update-check.d.ts +10 -0
- package/dist/update-check.js +24 -3
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
- package/dist/web/standalone/.next/required-server-files.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +2 -2
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
- package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
- package/dist/web/standalone/.next/server/chunks/7461.js +1 -0
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/2826.e59e8578e2e28639.js +9 -0
- package/dist/web/standalone/.next/static/chunks/{2008.71ee9230ad78df21.js → 3621.fc7480022c972438.js} +2 -2
- package/dist/web/standalone/.next/static/chunks/app/{page-f1e30ab6bb269149.js → page-5b113fd32bc2a1c3.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-b868033a5834586d.js → webpack-5fc74f13a25fa1bb.js} +1 -1
- package/dist/web/standalone/.next/static/css/632cd626b1731d88.css +1 -0
- package/dist/web/standalone/server.js +1 -1
- package/dist/welcome-screen.js +48 -24
- package/dist/wizard.js +2 -2
- package/dist/worktree-cli.d.ts +6 -5
- package/dist/worktree-cli.js +23 -7
- package/package.json +3 -3
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/capability-patches.js +3 -2
- package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts +68 -0
- package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/amazon-bedrock.js +68 -0
- package/packages/pi-ai/dist/models/generated/amazon-bedrock.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/anthropic.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/anthropic.js +17 -0
- package/packages/pi-ai/dist/models/generated/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/google-antigravity.js +17 -0
- package/packages/pi-ai/dist/models/generated/google-antigravity.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/groq.d.ts +0 -153
- package/packages/pi-ai/dist/models/generated/groq.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/groq.js +0 -153
- package/packages/pi-ai/dist/models/generated/groq.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/index.d.ts +136 -153
- package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/openrouter.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/openrouter.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openrouter.js +17 -0
- package/packages/pi-ai/dist/models/generated/openrouter.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.test.js +17 -0
- package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/amazon-bedrock.d.ts +22 -1
- package/packages/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/amazon-bedrock.js +40 -6
- package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/packages/pi-ai/dist/providers/amazon-bedrock.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/amazon-bedrock.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/amazon-bedrock.test.js +106 -0
- package/packages/pi-ai/dist/providers/amazon-bedrock.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js +42 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts +20 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +32 -2
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js +12 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts +11 -0
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +18 -1
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/openai-codex.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/openai-codex.js +12 -0
- package/packages/pi-ai/dist/utils/oauth/openai-codex.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/scripts/generate-models.ts +50 -0
- package/packages/pi-ai/src/models/capability-patches.ts +5 -2
- package/packages/pi-ai/src/models/generated/amazon-bedrock.ts +68 -0
- package/packages/pi-ai/src/models/generated/anthropic.ts +17 -0
- package/packages/pi-ai/src/models/generated/google-antigravity.ts +17 -0
- package/packages/pi-ai/src/models/generated/groq.ts +0 -153
- package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
- package/packages/pi-ai/src/models/generated/openrouter.ts +17 -0
- package/packages/pi-ai/src/models.generated.test.ts +17 -0
- package/packages/pi-ai/src/providers/amazon-bedrock.test.ts +164 -0
- package/packages/pi-ai/src/providers/amazon-bedrock.ts +41 -7
- package/packages/pi-ai/src/providers/anthropic-auth.test.ts +47 -1
- package/packages/pi-ai/src/providers/anthropic-shared.test.ts +15 -1
- package/packages/pi-ai/src/providers/anthropic-shared.ts +36 -3
- package/packages/pi-ai/src/providers/anthropic.ts +19 -1
- package/packages/pi-ai/src/utils/oauth/openai-codex.ts +15 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +38 -0
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +14 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +34 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +74 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +4 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +32 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +32 -0
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js +2 -2
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +17 -7
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +48 -34
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +83 -33
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +70 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +77 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -66
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +1 -75
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +192 -24
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +56 -0
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +83 -0
- package/packages/pi-coding-agent/src/core/auth-storage.ts +35 -0
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +4 -1
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +37 -1
- package/packages/pi-coding-agent/src/core/sdk.ts +41 -0
- package/packages/pi-coding-agent/src/core/skill-tool.test.ts +2 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +19 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +53 -31
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +88 -36
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +83 -0
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +2 -83
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +208 -27
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +70 -0
- package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
- package/pkg/dist/modes/interactive/theme/theme-schema.js +77 -0
- package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -0
- package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -66
- package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.js +1 -75
- package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.d.ts +1 -1
- package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js +192 -24
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- package/src/resources/extensions/ask-user-questions.ts +24 -6
- package/src/resources/extensions/claude-code-cli/models.ts +9 -0
- package/src/resources/extensions/claude-code-cli/readiness.ts +13 -2
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +94 -4
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +84 -0
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +10 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/loop.ts +109 -3
- package/src/resources/extensions/gsd/auto/phases.ts +94 -60
- package/src/resources/extensions/gsd/auto/resolve.ts +1 -1
- package/src/resources/extensions/gsd/auto/run-unit.ts +11 -1
- package/src/resources/extensions/gsd/auto/session.ts +7 -0
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +20 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +21 -4
- package/src/resources/extensions/gsd/auto-dispatch.ts +123 -5
- package/src/resources/extensions/gsd/auto-loop.ts +1 -1
- package/src/resources/extensions/gsd/auto-model-selection.ts +14 -3
- package/src/resources/extensions/gsd/auto-post-unit.ts +10 -8
- package/src/resources/extensions/gsd/auto-prompts.ts +201 -40
- package/src/resources/extensions/gsd/auto-recovery.ts +63 -1
- package/src/resources/extensions/gsd/auto-start.ts +8 -6
- package/src/resources/extensions/gsd/auto-verification.ts +3 -3
- package/src/resources/extensions/gsd/auto-worktree.ts +65 -0
- package/src/resources/extensions/gsd/auto.ts +61 -28
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +8 -21
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +46 -24
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +31 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -0
- package/src/resources/extensions/gsd/commands/catalog.ts +74 -9
- package/src/resources/extensions/gsd/commands/handlers/core.ts +69 -27
- package/src/resources/extensions/gsd/commands/handlers/escalate.ts +216 -0
- package/src/resources/extensions/gsd/commands/handlers/onboarding.ts +262 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +16 -0
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +279 -29
- package/src/resources/extensions/gsd/commands-cmux.ts +6 -2
- package/src/resources/extensions/gsd/commands-config.ts +10 -0
- package/src/resources/extensions/gsd/commands-debug.ts +484 -0
- package/src/resources/extensions/gsd/commands-do.ts +1 -0
- package/src/resources/extensions/gsd/commands-extract-learnings.ts +295 -76
- package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +49 -12
- package/src/resources/extensions/gsd/commands-scan.ts +125 -0
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +129 -2
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +85 -60
- package/src/resources/extensions/gsd/db-writer.ts +3 -0
- package/src/resources/extensions/gsd/debug-session-store.ts +377 -0
- package/src/resources/extensions/gsd/definition-loader.ts +7 -0
- package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -9
- package/src/resources/extensions/gsd/doctor-environment.ts +2 -1
- package/src/resources/extensions/gsd/doctor-git-checks.ts +5 -1
- package/src/resources/extensions/gsd/doctor-proactive.ts +4 -1
- package/src/resources/extensions/gsd/doctor-providers.ts +52 -22
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +23 -4
- package/src/resources/extensions/gsd/doctor-types.ts +1 -0
- package/src/resources/extensions/gsd/doctor.ts +7 -1
- package/src/resources/extensions/gsd/error-classifier.ts +6 -3
- package/src/resources/extensions/gsd/escalation.ts +367 -0
- package/src/resources/extensions/gsd/forensics.ts +25 -29
- package/src/resources/extensions/gsd/git-service.ts +0 -1
- package/src/resources/extensions/gsd/graph.ts +33 -3
- package/src/resources/extensions/gsd/gsd-db.ts +306 -29
- package/src/resources/extensions/gsd/health-widget-core.ts +43 -14
- package/src/resources/extensions/gsd/health-widget.ts +7 -3
- package/src/resources/extensions/gsd/init-wizard.ts +87 -54
- package/src/resources/extensions/gsd/markdown-renderer.ts +5 -5
- package/src/resources/extensions/gsd/metrics.ts +1 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +3 -1
- package/src/resources/extensions/gsd/model-router.ts +25 -6
- package/src/resources/extensions/gsd/native-git-bridge.ts +134 -6
- package/src/resources/extensions/gsd/notification-overlay.ts +9 -19
- package/src/resources/extensions/gsd/notification-widget.ts +25 -43
- package/src/resources/extensions/gsd/notifications.ts +6 -0
- package/src/resources/extensions/gsd/onboarding-state.ts +146 -0
- package/src/resources/extensions/gsd/post-execution-checks.ts +37 -14
- package/src/resources/extensions/gsd/pre-execution-checks.ts +98 -8
- package/src/resources/extensions/gsd/preferences-models.ts +1 -0
- package/src/resources/extensions/gsd/preferences-types.ts +10 -2
- package/src/resources/extensions/gsd/preferences-validation.ts +33 -7
- package/src/resources/extensions/gsd/preferences.ts +10 -10
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +4 -1
- package/src/resources/extensions/gsd/prompts/debug-diagnose.md +25 -0
- package/src/resources/extensions/gsd/prompts/debug-session-manager.md +80 -0
- package/src/resources/extensions/gsd/prompts/execute-task.md +12 -0
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +12 -0
- package/src/resources/extensions/gsd/prompts/refine-slice.md +69 -0
- package/src/resources/extensions/gsd/prompts/scan.md +79 -0
- package/src/resources/extensions/gsd/prompts/workflow-oneshot.md +26 -0
- package/src/resources/extensions/gsd/python-resolver.ts +76 -0
- package/src/resources/extensions/gsd/run-manager.ts +53 -19
- package/src/resources/extensions/gsd/setup-catalog.ts +105 -0
- package/src/resources/extensions/gsd/state.ts +50 -2
- package/src/resources/extensions/gsd/templates/PREFERENCES.md +7 -7
- package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +1 -34
- package/src/resources/extensions/gsd/tests/artifact-corruption-2630.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +45 -31
- package/src/resources/extensions/gsd/tests/auto-migrating-recovery.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/auto-prompts-fallback.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +123 -1
- package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/commands-do.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +333 -21
- package/src/resources/extensions/gsd/tests/commands-scan.test.ts +351 -0
- package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +8 -6
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +6 -8
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/debug-command-handler.test.ts +905 -0
- package/src/resources/extensions/gsd/tests/debug-command-lifecycle.integration.test.ts +1229 -0
- package/src/resources/extensions/gsd/tests/debug-session-store.test.ts +565 -0
- package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +62 -18
- package/src/resources/extensions/gsd/tests/enhanced-verification-integration.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/escalation.test.ts +818 -0
- package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +29 -12
- package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +0 -4
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -1
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +8 -2
- package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +190 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +68 -1
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +109 -11
- package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/integration/integration-proof.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/integration/test-isolation.ts +53 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +171 -1
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/milestone-status-tool.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/model-router.test.ts +51 -1
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +56 -37
- package/src/resources/extensions/gsd/tests/notification-widget.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/onboarding-handler-loader.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/onboarding-state.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/plan-milestone-boundary-map-preservation.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +4 -5
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -1
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +275 -6
- package/src/resources/extensions/gsd/tests/preferences.test.ts +69 -1
- package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +539 -0
- package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +11 -2
- package/src/resources/extensions/gsd/tests/projection-regression.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/python-resolver.test.ts +131 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/requirements.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +153 -0
- package/src/resources/extensions/gsd/tests/skip-slice-cascades-tasks.test.ts +125 -0
- package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +16 -4
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/uok-flags.test.ts +31 -1
- package/src/resources/extensions/gsd/tests/uok-kernel-path.test.ts +166 -0
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/workflow-install.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +15 -6
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/workflow-plugins.test.ts +310 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +8 -2
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +77 -2
- package/src/resources/extensions/gsd/tools/complete-task.ts +87 -0
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +42 -8
- package/src/resources/extensions/gsd/tools/plan-slice.ts +6 -1
- package/src/resources/extensions/gsd/tools/skip-slice.ts +133 -0
- package/src/resources/extensions/gsd/types.ts +62 -0
- package/src/resources/extensions/gsd/unit-runtime.ts +1 -0
- package/src/resources/extensions/gsd/uok/contracts.ts +2 -1
- package/src/resources/extensions/gsd/uok/flags.ts +7 -7
- package/src/resources/extensions/gsd/uok/kernel.ts +16 -4
- package/src/resources/extensions/gsd/verification-gate.ts +2 -1
- package/src/resources/extensions/gsd/workflow-dispatch.ts +106 -0
- package/src/resources/extensions/gsd/workflow-install.ts +423 -0
- package/src/resources/extensions/gsd/workflow-manifest.ts +8 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +1 -6
- package/src/resources/extensions/gsd/workflow-plugins.ts +403 -0
- package/src/resources/extensions/gsd/workflow-projections.ts +18 -16
- package/src/resources/extensions/gsd/workflow-templates/accessibility-audit.md +88 -0
- package/src/resources/extensions/gsd/workflow-templates/api-breaking-change.md +117 -0
- package/src/resources/extensions/gsd/workflow-templates/bugfix.md +1 -0
- package/src/resources/extensions/gsd/workflow-templates/changelog-gen.md +82 -0
- package/src/resources/extensions/gsd/workflow-templates/ci-bootstrap.md +144 -0
- package/src/resources/extensions/gsd/workflow-templates/dead-code.md +81 -0
- package/src/resources/extensions/gsd/workflow-templates/dep-upgrade.md +1 -0
- package/src/resources/extensions/gsd/workflow-templates/docs-sync.yaml +76 -0
- package/src/resources/extensions/gsd/workflow-templates/env-audit.yaml +88 -0
- package/src/resources/extensions/gsd/workflow-templates/full-project.md +1 -0
- package/src/resources/extensions/gsd/workflow-templates/hotfix.md +1 -0
- package/src/resources/extensions/gsd/workflow-templates/issue-triage.md +84 -0
- package/src/resources/extensions/gsd/workflow-templates/observability-setup.md +133 -0
- package/src/resources/extensions/gsd/workflow-templates/onboarding-check.md +74 -0
- package/src/resources/extensions/gsd/workflow-templates/performance-audit.md +125 -0
- package/src/resources/extensions/gsd/workflow-templates/pr-review.md +67 -0
- package/src/resources/extensions/gsd/workflow-templates/pr-triage.md +83 -0
- package/src/resources/extensions/gsd/workflow-templates/refactor.md +1 -0
- package/src/resources/extensions/gsd/workflow-templates/registry.json +184 -0
- package/src/resources/extensions/gsd/workflow-templates/release.md +118 -0
- package/src/resources/extensions/gsd/workflow-templates/rename-symbol.yaml +99 -0
- package/src/resources/extensions/gsd/workflow-templates/security-audit.md +1 -0
- package/src/resources/extensions/gsd/workflow-templates/small-feature.md +1 -0
- package/src/resources/extensions/gsd/workflow-templates/spike.md +1 -0
- package/src/resources/extensions/gsd/workflow-templates/test-backfill.yaml +73 -0
- package/src/resources/extensions/gsd/workflow-templates.ts +7 -0
- package/src/resources/extensions/gsd/workspace-index.ts +9 -4
- package/src/resources/extensions/gsd/worktree-resolver.ts +47 -1
- package/src/resources/extensions/remote-questions/commands.ts +480 -0
- package/src/resources/extensions/remote-questions/manager.ts +49 -4
- package/src/resources/extensions/remote-questions/telegram-adapter.ts +86 -4
- package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +246 -0
- package/src/resources/extensions/remote-questions/tests/remote-answer-normalization.test.ts +92 -0
- package/src/resources/extensions/remote-questions/tests/telegram-commands.test.ts +267 -0
- package/src/resources/extensions/shared/interview-ui.ts +195 -1
- package/src/resources/extensions/shared/layout-utils.ts +26 -0
- package/src/resources/extensions/shared/rtk-shared.ts +58 -0
- package/src/resources/extensions/shared/rtk.ts +12 -52
- package/src/resources/extensions/shared/tests/interview-preview.test.ts +177 -0
- package/src/resources/extensions/shared/tests/preview-layout.test.ts +120 -0
- package/src/resources/skills/create-workflow/SKILL.md +33 -6
- package/dist/web/standalone/.next/static/chunks/2826.dd3dc8bbd3025fa5.js +0 -9
- package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +0 -1
- package/packages/native/dist/ps/types.d.ts +0 -5
- package/packages/native/dist/ps/types.js +0 -2
- package/packages/native/src/ps/types.ts +0 -5
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/LICENSE +0 -201
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/README.md +0 -9
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-cjs/index.js +0 -762
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/build-abort-error.js +0 -19
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/constants.js +0 -1
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/get-transformed-headers.js +0 -9
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/index.js +0 -3
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http-handler.js +0 -230
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-manager.js +0 -87
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-pool.js +0 -32
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-handler.js +0 -169
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/readable.mock.js +0 -21
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/server.mock.js +0 -88
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-connection-timeout.js +0 -36
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-request-timeout.js +0 -21
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-keep-alive.js +0 -22
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-timeout.js +0 -23
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/collector.js +0 -8
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/index.js +0 -41
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/readable.mock.js +0 -21
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/timing.js +0 -4
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/write-request-body.js +0 -63
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/build-abort-error.d.ts +0 -10
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/constants.d.ts +0 -5
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/get-transformed-headers.d.ts +0 -4
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/index.d.ts +0 -3
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http-handler.d.ts +0 -46
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-manager.d.ts +0 -24
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-pool.d.ts +0 -12
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-handler.d.ts +0 -63
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/readable.mock.d.ts +0 -13
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/server.mock.d.ts +0 -12
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-connection-timeout.d.ts +0 -2
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-request-timeout.d.ts +0 -6
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-keep-alive.d.ts +0 -6
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-timeout.d.ts +0 -2
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/collector.d.ts +0 -5
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/index.d.ts +0 -6
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/readable.mock.d.ts +0 -13
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/timing.d.ts +0 -8
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/build-abort-error.d.ts +0 -10
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/constants.d.ts +0 -5
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/get-transformed-headers.d.ts +0 -4
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/index.d.ts +0 -3
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http-handler.d.ts +0 -46
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-manager.d.ts +0 -24
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-pool.d.ts +0 -12
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-handler.d.ts +0 -63
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/readable.mock.d.ts +0 -13
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/server.mock.d.ts +0 -12
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-connection-timeout.d.ts +0 -2
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-request-timeout.d.ts +0 -6
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-keep-alive.d.ts +0 -6
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-timeout.d.ts +0 -2
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/collector.d.ts +0 -5
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/index.d.ts +0 -6
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/readable.mock.d.ts +0 -13
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/timing.d.ts +0 -8
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/write-request-body.d.ts +0 -12
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/write-request-body.d.ts +0 -12
- package/packages/pi-ai/node_modules/@smithy/node-http-handler/package.json +0 -68
- package/packages/pi-ai/oauth.d.ts +0 -1
- package/packages/pi-ai/oauth.js +0 -1
- /package/dist/web/standalone/.next/static/{j7IBD35UgrL2b298GLK3V → J2z3GMC9QtSLr7gyoM38c}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{j7IBD35UgrL2b298GLK3V → J2z3GMC9QtSLr7gyoM38c}/_ssgManifest.js +0 -0
|
@@ -61,6 +61,15 @@ function validateSlices(value) {
|
|
|
61
61
|
const proofLevel = obj.proofLevel;
|
|
62
62
|
const integrationClosure = obj.integrationClosure;
|
|
63
63
|
const observabilityImpact = obj.observabilityImpact;
|
|
64
|
+
const isSketchRaw = obj.isSketch;
|
|
65
|
+
const sketchScopeRaw = obj.sketchScope;
|
|
66
|
+
// ADR-011: preserve the 3-valued semantics of isSketch (true / false / absent).
|
|
67
|
+
// Callers that omit isSketch must receive `undefined` here so `insertSlice`'s
|
|
68
|
+
// ON CONFLICT clause preserves any existing is_sketch on the row rather than
|
|
69
|
+
// silently overwriting a legitimate sketch to non-sketch.
|
|
70
|
+
const isSketch = isSketchRaw === true ? true
|
|
71
|
+
: isSketchRaw === false ? false
|
|
72
|
+
: undefined;
|
|
64
73
|
if (!isNonEmptyString(sliceId))
|
|
65
74
|
throw new Error(`slices[${index}].sliceId must be a non-empty string`);
|
|
66
75
|
if (seen.has(sliceId))
|
|
@@ -77,14 +86,22 @@ function validateSlices(value) {
|
|
|
77
86
|
throw new Error(`slices[${index}].demo must be a non-empty string`);
|
|
78
87
|
if (!isNonEmptyString(goal))
|
|
79
88
|
throw new Error(`slices[${index}].goal must be a non-empty string`);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
89
|
+
// ADR-011: sketch slices may defer the heavyweight planning fields to refine-slice.
|
|
90
|
+
if (isSketch === true) {
|
|
91
|
+
if (!isNonEmptyString(sketchScopeRaw)) {
|
|
92
|
+
throw new Error(`slices[${index}].sketchScope must be a non-empty string when isSketch is true`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
if (!isNonEmptyString(successCriteria))
|
|
97
|
+
throw new Error(`slices[${index}].successCriteria must be a non-empty string`);
|
|
98
|
+
if (!isNonEmptyString(proofLevel))
|
|
99
|
+
throw new Error(`slices[${index}].proofLevel must be a non-empty string`);
|
|
100
|
+
if (!isNonEmptyString(integrationClosure))
|
|
101
|
+
throw new Error(`slices[${index}].integrationClosure must be a non-empty string`);
|
|
102
|
+
if (!isNonEmptyString(observabilityImpact))
|
|
103
|
+
throw new Error(`slices[${index}].observabilityImpact must be a non-empty string`);
|
|
104
|
+
}
|
|
88
105
|
return {
|
|
89
106
|
sliceId,
|
|
90
107
|
title,
|
|
@@ -92,10 +109,14 @@ function validateSlices(value) {
|
|
|
92
109
|
depends,
|
|
93
110
|
demo,
|
|
94
111
|
goal,
|
|
95
|
-
successCriteria,
|
|
96
|
-
proofLevel,
|
|
97
|
-
integrationClosure,
|
|
98
|
-
observabilityImpact,
|
|
112
|
+
successCriteria: isNonEmptyString(successCriteria) ? successCriteria : "",
|
|
113
|
+
proofLevel: isNonEmptyString(proofLevel) ? proofLevel : "",
|
|
114
|
+
integrationClosure: isNonEmptyString(integrationClosure) ? integrationClosure : "",
|
|
115
|
+
observabilityImpact: isNonEmptyString(observabilityImpact) ? observabilityImpact : "",
|
|
116
|
+
isSketch,
|
|
117
|
+
// Only carry the sketch scope through if the caller explicitly provided it
|
|
118
|
+
// — preserves ON CONFLICT semantics for re-plans that omit the field.
|
|
119
|
+
sketchScope: sketchScopeRaw === undefined ? undefined : (isNonEmptyString(sketchScopeRaw) ? sketchScopeRaw : ""),
|
|
99
120
|
};
|
|
100
121
|
});
|
|
101
122
|
}
|
|
@@ -209,6 +230,10 @@ export async function handlePlanMilestone(rawParams, basePath) {
|
|
|
209
230
|
depends: slice.depends,
|
|
210
231
|
demo: slice.demo,
|
|
211
232
|
sequence: i + 1, // Preserve agent-ordered sequence (#3356)
|
|
233
|
+
// ADR-011: pass undefined through so ON CONFLICT preserves existing values
|
|
234
|
+
// when the caller omitted the fields on a re-plan.
|
|
235
|
+
isSketch: slice.isSketch,
|
|
236
|
+
sketchScope: slice.sketchScope,
|
|
212
237
|
});
|
|
213
238
|
upsertSlicePlanning(params.milestoneId, slice.sliceId, {
|
|
214
239
|
goal: slice.goal,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { clearParseCache } from "../files.js";
|
|
2
|
-
import { isClosedStatus } from "../status-guards.js";
|
|
2
|
+
import { isClosedStatus, isDeferredStatus } from "../status-guards.js";
|
|
3
3
|
import { isNonEmptyString } from "../validation.js";
|
|
4
|
-
import { transaction, getMilestone, getSlice, insertTask, upsertSlicePlanning, upsertTaskPlanning, insertGateRow, } from "../gsd-db.js";
|
|
4
|
+
import { transaction, getMilestone, getSlice, insertTask, upsertSlicePlanning, upsertTaskPlanning, insertGateRow, updateSliceStatus, } from "../gsd-db.js";
|
|
5
5
|
import { invalidateStateCache } from "../state.js";
|
|
6
6
|
import { renderPlanFromDb } from "../markdown-renderer.js";
|
|
7
7
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
@@ -114,6 +114,9 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
114
114
|
guardError = `cannot re-plan slice ${params.sliceId}: it is already complete — use gsd_slice_reopen first`;
|
|
115
115
|
return;
|
|
116
116
|
}
|
|
117
|
+
if (isDeferredStatus(parentSlice.status)) {
|
|
118
|
+
updateSliceStatus(params.milestoneId, params.sliceId, "pending");
|
|
119
|
+
}
|
|
117
120
|
upsertSlicePlanning(params.milestoneId, params.sliceId, {
|
|
118
121
|
goal: params.goal,
|
|
119
122
|
successCriteria: params.successCriteria,
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* skip-slice handler — the core operation behind gsd_skip_slice.
|
|
3
|
+
*
|
|
4
|
+
* Marks a slice as skipped and cascades the skip to every non-closed task in
|
|
5
|
+
* that slice. Without the task cascade the deep-check in
|
|
6
|
+
* executeCompleteMilestone reports pending tasks inside the skipped slice and
|
|
7
|
+
* blocks milestone completion (see #4375).
|
|
8
|
+
*
|
|
9
|
+
* This function performs DB writes only. The MCP wrapper in
|
|
10
|
+
* bootstrap/db-tools.ts handles state-cache invalidation and STATE.md rebuild.
|
|
11
|
+
*/
|
|
12
|
+
import { getSlice, getSliceTasks, isDbAvailable, transaction, updateSliceStatus, updateTaskStatus, } from "../gsd-db.js";
|
|
13
|
+
import { isClosedStatus } from "../status-guards.js";
|
|
14
|
+
/**
|
|
15
|
+
* Mark a slice as "skipped" and cascade the skip to every non-closed task in
|
|
16
|
+
* that slice. Runs as a single transaction so slice status and task statuses
|
|
17
|
+
* are always consistent.
|
|
18
|
+
*
|
|
19
|
+
* Behaviour summary:
|
|
20
|
+
* - Unknown slice → returns {@link SkipSliceResult} with `error`.
|
|
21
|
+
* - Slice already complete/done → returns `error` (cannot un-complete).
|
|
22
|
+
* - Slice already skipped → still cascades leftover non-closed tasks
|
|
23
|
+
* (heals inconsistent historical state from projects that ran older
|
|
24
|
+
* versions before the #4375 cascade fix).
|
|
25
|
+
* - Tasks in closed status (complete/done/skipped) are never downgraded.
|
|
26
|
+
*/
|
|
27
|
+
export function handleSkipSlice(params) {
|
|
28
|
+
const base = {
|
|
29
|
+
milestoneId: params.milestoneId,
|
|
30
|
+
sliceId: params.sliceId,
|
|
31
|
+
tasksSkipped: 0,
|
|
32
|
+
wasAlreadySkipped: false,
|
|
33
|
+
reason: params.reason,
|
|
34
|
+
};
|
|
35
|
+
// Fail loudly on a closed DB so a `null` from getSlice() inside the
|
|
36
|
+
// transaction unambiguously means "slice not found", never "DB unavailable".
|
|
37
|
+
// The MCP wrapper in bootstrap/db-tools.ts runs ensureDbOpen() before calling
|
|
38
|
+
// this helper; this guard protects direct callers (tests, future code).
|
|
39
|
+
if (!isDbAvailable()) {
|
|
40
|
+
throw new Error("handleSkipSlice: GSD database is not available");
|
|
41
|
+
}
|
|
42
|
+
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ────
|
|
43
|
+
let guardError = null;
|
|
44
|
+
let guardCode = null;
|
|
45
|
+
let wasAlreadySkipped = false;
|
|
46
|
+
let tasksSkipped = 0;
|
|
47
|
+
transaction(() => {
|
|
48
|
+
const slice = getSlice(params.milestoneId, params.sliceId);
|
|
49
|
+
if (!slice) {
|
|
50
|
+
guardError = `Slice ${params.sliceId} not found in milestone ${params.milestoneId}`;
|
|
51
|
+
guardCode = "slice_not_found";
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (slice.status === "complete" || slice.status === "done") {
|
|
55
|
+
guardError = `Slice ${params.sliceId} is already complete — cannot skip.`;
|
|
56
|
+
guardCode = "already_complete";
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
wasAlreadySkipped = slice.status === "skipped";
|
|
60
|
+
if (!wasAlreadySkipped) {
|
|
61
|
+
updateSliceStatus(params.milestoneId, params.sliceId, "skipped");
|
|
62
|
+
}
|
|
63
|
+
// Cascade: mark every non-closed task as skipped so milestone completion
|
|
64
|
+
// doesn't trip the deep-task guard (#4375). Closed tasks (complete/done/
|
|
65
|
+
// skipped) are left untouched — we never downgrade.
|
|
66
|
+
const tasks = getSliceTasks(params.milestoneId, params.sliceId);
|
|
67
|
+
for (const task of tasks) {
|
|
68
|
+
if (!isClosedStatus(task.status)) {
|
|
69
|
+
updateTaskStatus(params.milestoneId, params.sliceId, task.id, "skipped");
|
|
70
|
+
tasksSkipped++;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
if (guardError) {
|
|
75
|
+
return { ...base, error: guardError, errorCode: guardCode ?? undefined };
|
|
76
|
+
}
|
|
77
|
+
return { ...base, tasksSkipped, wasAlreadySkipped };
|
|
78
|
+
}
|
|
@@ -13,14 +13,14 @@ export function resolveUokFlags(prefs) {
|
|
|
13
13
|
return {
|
|
14
14
|
enabled: enabledByPreference && !legacyFallback,
|
|
15
15
|
legacyFallback,
|
|
16
|
-
gates: uok?.gates?.enabled
|
|
17
|
-
modelPolicy: uok?.model_policy?.enabled
|
|
18
|
-
executionGraph: uok?.execution_graph?.enabled
|
|
19
|
-
gitops: uok?.gitops?.enabled
|
|
20
|
-
gitopsTurnAction: uok?.gitops?.turn_action ?? "
|
|
16
|
+
gates: uok?.gates?.enabled ?? true,
|
|
17
|
+
modelPolicy: uok?.model_policy?.enabled ?? true,
|
|
18
|
+
executionGraph: uok?.execution_graph?.enabled ?? true,
|
|
19
|
+
gitops: uok?.gitops?.enabled ?? true,
|
|
20
|
+
gitopsTurnAction: uok?.gitops?.turn_action ?? "commit",
|
|
21
21
|
gitopsTurnPush: uok?.gitops?.turn_push === true,
|
|
22
|
-
auditUnified: uok?.audit_unified?.enabled
|
|
23
|
-
planV2: uok?.plan_v2?.enabled
|
|
22
|
+
auditUnified: uok?.audit_unified?.enabled ?? true,
|
|
23
|
+
planV2: uok?.plan_v2?.enabled ?? true,
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
export function loadUokFlags() {
|
|
@@ -20,10 +20,10 @@ function writeParityEvent(basePath, event) {
|
|
|
20
20
|
function resolveKernelPathLabel(flags) {
|
|
21
21
|
if (flags.legacyFallback)
|
|
22
22
|
return "legacy-fallback";
|
|
23
|
-
return flags.enabled ? "uok-
|
|
23
|
+
return flags.enabled ? "uok-kernel" : "legacy-wrapper";
|
|
24
24
|
}
|
|
25
25
|
export async function runAutoLoopWithUok(args) {
|
|
26
|
-
const { ctx, pi, s, deps, runLegacyLoop } = args;
|
|
26
|
+
const { ctx, pi, s, deps, runKernelLoop, runLegacyLoop } = args;
|
|
27
27
|
const prefs = deps.loadEffectiveGSDPreferences()?.preferences;
|
|
28
28
|
const flags = resolveUokFlags(prefs);
|
|
29
29
|
setUnifiedAuditEnabled(flags.auditUnified);
|
|
@@ -57,7 +57,12 @@ export async function runAutoLoopWithUok(args) {
|
|
|
57
57
|
}
|
|
58
58
|
: deps;
|
|
59
59
|
try {
|
|
60
|
-
|
|
60
|
+
if (flags.enabled) {
|
|
61
|
+
await runKernelLoop(ctx, pi, s, decoratedDeps);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
await runLegacyLoop(ctx, pi, s, deps);
|
|
65
|
+
}
|
|
61
66
|
writeParityEvent(s.basePath, {
|
|
62
67
|
ts: new Date().toISOString(),
|
|
63
68
|
path: resolveKernelPathLabel(flags),
|
|
@@ -7,6 +7,7 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
7
7
|
import { join, basename } from "node:path";
|
|
8
8
|
import { DEFAULT_COMMAND_TIMEOUT_MS } from "./constants.js";
|
|
9
9
|
import { rewriteCommandWithRtk } from "../shared/rtk.js";
|
|
10
|
+
import { normalizePythonCommand } from "./python-resolver.js";
|
|
10
11
|
/** Maximum bytes of stdout/stderr to retain per command (10 KB). */
|
|
11
12
|
const MAX_OUTPUT_BYTES = 10 * 1024;
|
|
12
13
|
/** Truncate a string to maxBytes, appending a marker if truncated. */
|
|
@@ -211,7 +212,7 @@ export function runVerificationGate(options) {
|
|
|
211
212
|
const checks = [];
|
|
212
213
|
for (const command of commands) {
|
|
213
214
|
const start = Date.now();
|
|
214
|
-
const rewrittenCommand = rewriteCommandWithRtk(command);
|
|
215
|
+
const rewrittenCommand = normalizePythonCommand(rewriteCommandWithRtk(command));
|
|
215
216
|
// Pass the command string as an argument to the shell explicitly
|
|
216
217
|
// to avoid Node.js DEP0190 (spawnSync with shell: true and no args).
|
|
217
218
|
const shellBin = process.platform === "win32" ? "cmd" : "sh";
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* workflow-dispatch.ts — Shared dispatchers for workflow plugins.
|
|
3
|
+
*
|
|
4
|
+
* Called by both `/gsd start <template>` (existing markdown path) and
|
|
5
|
+
* `/gsd workflow <name>` (new direct dispatch). Keeps the prompt-build
|
|
6
|
+
* logic in one place so md template behavior stays consistent.
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync } from "node:fs";
|
|
9
|
+
import { loadPrompt } from "./prompt-loader.js";
|
|
10
|
+
// ─── Oneshot dispatch ────────────────────────────────────────────────────
|
|
11
|
+
/**
|
|
12
|
+
* Strip the `<template_meta>` block from markdown content so it's not
|
|
13
|
+
* repeated in the prompt body.
|
|
14
|
+
*/
|
|
15
|
+
function stripTemplateMeta(content) {
|
|
16
|
+
return content.replace(/<template_meta>[\s\S]*?<\/template_meta>\s*/, "");
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* For a oneshot YAML plugin, extract the single-step prompt.
|
|
20
|
+
* For multi-step YAML defined as oneshot, concatenate step prompts.
|
|
21
|
+
*/
|
|
22
|
+
function extractYamlOneshotPrompt(yamlContent) {
|
|
23
|
+
// Simple: just include the raw YAML so the model can follow it.
|
|
24
|
+
// This keeps the oneshot format flexible without re-parsing.
|
|
25
|
+
return `\`\`\`yaml\n${yamlContent}\n\`\`\``;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Dispatch a oneshot workflow: load the prompt, inject the body, send.
|
|
29
|
+
* No STATE.json, no branch switch, no auto-loop.
|
|
30
|
+
*/
|
|
31
|
+
export function dispatchOneshot(plugin, pi, userArgs) {
|
|
32
|
+
const raw = readFileSync(plugin.path, "utf-8");
|
|
33
|
+
const body = plugin.format === "yaml"
|
|
34
|
+
? extractYamlOneshotPrompt(raw)
|
|
35
|
+
: stripTemplateMeta(raw);
|
|
36
|
+
const prompt = loadPrompt("workflow-oneshot", {
|
|
37
|
+
name: plugin.name,
|
|
38
|
+
displayName: plugin.meta.displayName,
|
|
39
|
+
body,
|
|
40
|
+
userArgs: userArgs || "(none)",
|
|
41
|
+
});
|
|
42
|
+
pi.sendMessage({ customType: "gsd-workflow-oneshot", content: prompt, display: false }, { triggerTurn: true });
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Build and dispatch the `workflow-start.md` prompt for a markdown-phase plugin.
|
|
46
|
+
* Returns the prompt that was sent (useful for tests).
|
|
47
|
+
*/
|
|
48
|
+
export function dispatchMarkdownPhase(opts, pi) {
|
|
49
|
+
const prompt = loadPrompt("workflow-start", {
|
|
50
|
+
templateId: opts.templateId,
|
|
51
|
+
templateName: opts.templateName,
|
|
52
|
+
templateDescription: opts.templateDescription,
|
|
53
|
+
phases: opts.phases.join(" → "),
|
|
54
|
+
complexity: opts.complexity,
|
|
55
|
+
artifactDir: opts.artifactDir || "(none)",
|
|
56
|
+
branch: opts.branch,
|
|
57
|
+
description: opts.description || "(none provided)",
|
|
58
|
+
issueRef: opts.issueRef || "(none)",
|
|
59
|
+
date: opts.date,
|
|
60
|
+
workflowContent: opts.workflowContent,
|
|
61
|
+
});
|
|
62
|
+
pi.sendMessage({ customType: "gsd-workflow-template", content: prompt, display: false }, { triggerTurn: true });
|
|
63
|
+
return prompt;
|
|
64
|
+
}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* workflow-install.ts — Fetch, validate, and install remote workflow plugins.
|
|
3
|
+
*
|
|
4
|
+
* Accepts:
|
|
5
|
+
* - Full URL (https://raw.githubusercontent.com/... or gist raw URL)
|
|
6
|
+
* - gist:abc123 → https://gist.githubusercontent.com/anonymous/abc123/raw
|
|
7
|
+
* - gh:owner/repo/path[@ref] → raw.githubusercontent.com/owner/repo/<ref>/path
|
|
8
|
+
*
|
|
9
|
+
* Installed files land in `~/.gsd/workflows/<name>.<ext>` by default, or
|
|
10
|
+
* `.gsd/workflows/<name>.<ext>` with the `--project` flag.
|
|
11
|
+
*
|
|
12
|
+
* A provenance file `~/.gsd/workflows/.installed.json` (or project equivalent)
|
|
13
|
+
* records source URL, timestamp, and sha256 so `/gsd workflow uninstall` can
|
|
14
|
+
* clean up and future `/gsd workflow update` can refresh.
|
|
15
|
+
*/
|
|
16
|
+
import { existsSync, mkdirSync, readFileSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
17
|
+
import { homedir } from "node:os";
|
|
18
|
+
import { extname, join, resolve, sep as pathSep } from "node:path";
|
|
19
|
+
import { createHash } from "node:crypto";
|
|
20
|
+
import { parse as parseYaml } from "yaml";
|
|
21
|
+
import { validateDefinition } from "./definition-loader.js";
|
|
22
|
+
// ─── Constants ───────────────────────────────────────────────────────────
|
|
23
|
+
const MAX_RESPONSE_BYTES = 256 * 1024;
|
|
24
|
+
const FETCH_TIMEOUT_MS = 15_000;
|
|
25
|
+
const PROVENANCE_FILE = ".installed.json";
|
|
26
|
+
function provenancePath(dir) {
|
|
27
|
+
return join(dir, PROVENANCE_FILE);
|
|
28
|
+
}
|
|
29
|
+
function readProvenance(dir) {
|
|
30
|
+
const path = provenancePath(dir);
|
|
31
|
+
if (!existsSync(path))
|
|
32
|
+
return {};
|
|
33
|
+
try {
|
|
34
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return {};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function writeProvenance(dir, data) {
|
|
41
|
+
mkdirSync(dir, { recursive: true });
|
|
42
|
+
writeFileSync(provenancePath(dir), JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
43
|
+
}
|
|
44
|
+
export function globalInstallDir() {
|
|
45
|
+
const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
|
|
46
|
+
return join(gsdHome, "workflows");
|
|
47
|
+
}
|
|
48
|
+
export function projectInstallDir(basePath) {
|
|
49
|
+
return join(basePath, ".gsd", "workflows");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Reject plugin names that could escape the workflows directory.
|
|
53
|
+
* Allows a-z, A-Z, 0-9, dot, underscore, hyphen — no separators, no dot-segments.
|
|
54
|
+
*/
|
|
55
|
+
function assertSafePluginName(name) {
|
|
56
|
+
if (!name || name === "." || name === "..") {
|
|
57
|
+
throw new Error(`Invalid plugin name: "${name}"`);
|
|
58
|
+
}
|
|
59
|
+
if (!/^[a-zA-Z0-9._-]+$/.test(name)) {
|
|
60
|
+
throw new Error(`Invalid plugin name "${name}". Allowed characters: letters, digits, dot, underscore, hyphen.`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Resolve `child` inside `dir` and refuse any result that escapes `dir`.
|
|
65
|
+
*/
|
|
66
|
+
function safeResolveInDir(dir, child) {
|
|
67
|
+
const resolvedDir = resolve(dir);
|
|
68
|
+
const resolvedPath = resolve(resolvedDir, child);
|
|
69
|
+
if (resolvedPath !== resolvedDir &&
|
|
70
|
+
!resolvedPath.startsWith(resolvedDir + pathSep)) {
|
|
71
|
+
throw new Error(`Refusing to operate outside ${dir}: ${child}`);
|
|
72
|
+
}
|
|
73
|
+
return resolvedPath;
|
|
74
|
+
}
|
|
75
|
+
// ─── Source URL resolution ───────────────────────────────────────────────
|
|
76
|
+
/**
|
|
77
|
+
* Turn a user-supplied source specifier into a fetchable HTTPS URL.
|
|
78
|
+
* Throws on clearly unsafe inputs (file://, unsupported schemes).
|
|
79
|
+
*/
|
|
80
|
+
export function resolveSourceUrl(source) {
|
|
81
|
+
const trimmed = source.trim();
|
|
82
|
+
// gist:<id>
|
|
83
|
+
if (trimmed.startsWith("gist:")) {
|
|
84
|
+
const id = trimmed.slice("gist:".length).trim();
|
|
85
|
+
if (!/^[a-f0-9]{6,}$/i.test(id)) {
|
|
86
|
+
throw new Error(`Invalid gist id: ${id}`);
|
|
87
|
+
}
|
|
88
|
+
return `https://gist.githubusercontent.com/anonymous/${id}/raw`;
|
|
89
|
+
}
|
|
90
|
+
// gh:owner/repo/path[@ref]
|
|
91
|
+
if (trimmed.startsWith("gh:")) {
|
|
92
|
+
const rest = trimmed.slice("gh:".length);
|
|
93
|
+
const atIdx = rest.lastIndexOf("@");
|
|
94
|
+
const pathPart = atIdx === -1 ? rest : rest.slice(0, atIdx);
|
|
95
|
+
const ref = atIdx === -1 ? "main" : rest.slice(atIdx + 1);
|
|
96
|
+
const parts = pathPart.split("/");
|
|
97
|
+
if (parts.length < 3) {
|
|
98
|
+
throw new Error(`Expected gh:<owner>/<repo>/<path>: ${trimmed}`);
|
|
99
|
+
}
|
|
100
|
+
const [owner, repo, ...filePath] = parts;
|
|
101
|
+
return `https://raw.githubusercontent.com/${owner}/${repo}/${ref}/${filePath.join("/")}`;
|
|
102
|
+
}
|
|
103
|
+
// file:// — reject
|
|
104
|
+
if (trimmed.startsWith("file:")) {
|
|
105
|
+
throw new Error("file:// sources are not supported for security reasons.");
|
|
106
|
+
}
|
|
107
|
+
// Must be https:// (or http://localhost for dev)
|
|
108
|
+
if (trimmed.startsWith("https://"))
|
|
109
|
+
return trimmed;
|
|
110
|
+
if (trimmed.startsWith("http://")) {
|
|
111
|
+
const url = new URL(trimmed);
|
|
112
|
+
if (url.hostname === "localhost" || url.hostname === "127.0.0.1") {
|
|
113
|
+
return trimmed;
|
|
114
|
+
}
|
|
115
|
+
throw new Error("http:// is only allowed for localhost. Use https://.");
|
|
116
|
+
}
|
|
117
|
+
throw new Error(`Unsupported source format: ${trimmed}\n` +
|
|
118
|
+
`Use one of: https://..., gist:<id>, gh:<owner>/<repo>/<path>[@ref]`);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Fetch the resolved URL with a timeout and a max response size.
|
|
122
|
+
* Injects a simple User-Agent so GitHub doesn't 403.
|
|
123
|
+
*/
|
|
124
|
+
export async function fetchWorkflowSource(url) {
|
|
125
|
+
const controller = new AbortController();
|
|
126
|
+
const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
127
|
+
try {
|
|
128
|
+
const res = await fetch(url, {
|
|
129
|
+
signal: controller.signal,
|
|
130
|
+
headers: { "User-Agent": "gsd-workflow-install" },
|
|
131
|
+
});
|
|
132
|
+
if (!res.ok) {
|
|
133
|
+
throw new Error(`Fetch failed (${res.status} ${res.statusText}): ${url}`);
|
|
134
|
+
}
|
|
135
|
+
// Cap size: read as a stream and bail if it exceeds MAX_RESPONSE_BYTES.
|
|
136
|
+
const buf = await res.arrayBuffer();
|
|
137
|
+
if (buf.byteLength > MAX_RESPONSE_BYTES) {
|
|
138
|
+
throw new Error(`Response too large (${buf.byteLength} bytes, max ${MAX_RESPONSE_BYTES}): ${url}`);
|
|
139
|
+
}
|
|
140
|
+
const content = new TextDecoder().decode(buf);
|
|
141
|
+
// Prefer the final response URL after redirects (e.g., gist /raw → /raw/<sha>/file.ext).
|
|
142
|
+
const finalUrl = typeof res.url === "string" && res.url ? res.url : url;
|
|
143
|
+
let pathname;
|
|
144
|
+
try {
|
|
145
|
+
pathname = new URL(finalUrl).pathname;
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
pathname = new URL(url).pathname;
|
|
149
|
+
}
|
|
150
|
+
let basename = pathname.slice(pathname.lastIndexOf("/") + 1);
|
|
151
|
+
let rawExt = extname(basename).toLowerCase();
|
|
152
|
+
let ext;
|
|
153
|
+
if (rawExt === ".yaml" || rawExt === ".yml" || rawExt === ".md") {
|
|
154
|
+
ext = rawExt;
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
// Fallback: sniff content. Gist /raw and similar URLs have no extension.
|
|
158
|
+
if (/<template_meta>[\s\S]*?<\/template_meta>/.test(content)) {
|
|
159
|
+
ext = ".md";
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
let parsed;
|
|
163
|
+
try {
|
|
164
|
+
parsed = parseYaml(content);
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
parsed = undefined;
|
|
168
|
+
}
|
|
169
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
170
|
+
ext = ".yaml";
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
throw new Error(`Cannot determine workflow type from ${url}. ` +
|
|
174
|
+
`Expected .yaml/.yml/.md URL, a markdown file with <template_meta>, ` +
|
|
175
|
+
`or a YAML document.`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// Synthesize a filename so downstream sanitizers have something to chew on.
|
|
179
|
+
if (!basename)
|
|
180
|
+
basename = "workflow";
|
|
181
|
+
basename = `${basename}${ext}`;
|
|
182
|
+
}
|
|
183
|
+
const filename = basename;
|
|
184
|
+
const sha256 = createHash("sha256").update(content).digest("hex");
|
|
185
|
+
return { url, filename, ext, content, sha256 };
|
|
186
|
+
}
|
|
187
|
+
finally {
|
|
188
|
+
clearTimeout(timer);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// ─── Validation ──────────────────────────────────────────────────────────
|
|
192
|
+
/**
|
|
193
|
+
* Validate fetched content: YAML must pass validateDefinition, markdown must
|
|
194
|
+
* have a `<template_meta>` block with at least `name`.
|
|
195
|
+
*/
|
|
196
|
+
export function validateFetchedContent(fetched) {
|
|
197
|
+
if (fetched.ext === ".yaml" || fetched.ext === ".yml") {
|
|
198
|
+
let parsed;
|
|
199
|
+
try {
|
|
200
|
+
parsed = parseYaml(fetched.content);
|
|
201
|
+
}
|
|
202
|
+
catch (err) {
|
|
203
|
+
throw new Error(`Installed YAML failed to parse: ${err instanceof Error ? err.message : String(err)}`);
|
|
204
|
+
}
|
|
205
|
+
const result = validateDefinition(parsed);
|
|
206
|
+
if (!result.valid) {
|
|
207
|
+
throw new Error(`Installed YAML failed validation:\n - ${result.errors.join("\n - ")}`);
|
|
208
|
+
}
|
|
209
|
+
// Optional: validate `mode:` if present.
|
|
210
|
+
if (parsed && typeof parsed === "object") {
|
|
211
|
+
const mode = parsed.mode;
|
|
212
|
+
if (mode !== undefined && mode !== "oneshot" && mode !== "yaml-step") {
|
|
213
|
+
throw new Error(`YAML plugins must declare mode: oneshot or yaml-step (got "${String(mode)}")`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
// Markdown: require a <template_meta> block with at least a name.
|
|
219
|
+
const metaMatch = fetched.content.match(/<template_meta>([\s\S]*?)<\/template_meta>/);
|
|
220
|
+
if (!metaMatch) {
|
|
221
|
+
throw new Error("Installed markdown must contain a <template_meta>…</template_meta> block.");
|
|
222
|
+
}
|
|
223
|
+
if (!/\bname\s*:/i.test(metaMatch[1])) {
|
|
224
|
+
throw new Error("Installed markdown <template_meta> must declare at least `name:`.");
|
|
225
|
+
}
|
|
226
|
+
// Optional: validate `mode:` if declared.
|
|
227
|
+
const modeLine = metaMatch[1].match(/\bmode\s*:\s*(\S+)/i);
|
|
228
|
+
if (modeLine) {
|
|
229
|
+
const mode = modeLine[1];
|
|
230
|
+
if (mode !== "oneshot" && mode !== "markdown-phase") {
|
|
231
|
+
throw new Error(`Markdown plugins must declare mode: oneshot or markdown-phase (got "${mode}")`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// ─── Name inference ──────────────────────────────────────────────────────
|
|
236
|
+
/**
|
|
237
|
+
* Infer a plugin name from fetched content. For YAML, prefer the top-level
|
|
238
|
+
* `name:` field. For markdown, prefer `<template_meta>.name`. Fall back to
|
|
239
|
+
* the filename stem.
|
|
240
|
+
*/
|
|
241
|
+
export function inferPluginName(fetched) {
|
|
242
|
+
if (fetched.ext === ".yaml" || fetched.ext === ".yml") {
|
|
243
|
+
try {
|
|
244
|
+
const parsed = parseYaml(fetched.content);
|
|
245
|
+
if (parsed && typeof parsed === "object") {
|
|
246
|
+
const n = parsed.name;
|
|
247
|
+
if (typeof n === "string" && n.trim())
|
|
248
|
+
return sanitizeName(n);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
// Fall through to filename.
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
const metaMatch = fetched.content.match(/<template_meta>([\s\S]*?)<\/template_meta>/);
|
|
257
|
+
if (metaMatch) {
|
|
258
|
+
const nameMatch = metaMatch[1].match(/\bname\s*:\s*(\S+)/i);
|
|
259
|
+
if (nameMatch)
|
|
260
|
+
return sanitizeName(nameMatch[1]);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
const stem = fetched.filename.replace(/\.[^.]+$/, "");
|
|
264
|
+
return sanitizeName(stem);
|
|
265
|
+
}
|
|
266
|
+
function sanitizeName(raw) {
|
|
267
|
+
return raw.trim().toLowerCase().replace(/[^a-z0-9._-]/g, "-").replace(/^-+|-+$/g, "");
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Write the fetched plugin to disk and update the provenance file.
|
|
271
|
+
* Does NOT prompt — caller is responsible for confirming with the user first.
|
|
272
|
+
*/
|
|
273
|
+
export function installPlugin(target, fetched, name) {
|
|
274
|
+
assertSafePluginName(name);
|
|
275
|
+
mkdirSync(target.dir, { recursive: true });
|
|
276
|
+
const filename = `${name}${fetched.ext}`;
|
|
277
|
+
const path = safeResolveInDir(target.dir, filename);
|
|
278
|
+
writeFileSync(path, fetched.content, "utf-8");
|
|
279
|
+
const prov = readProvenance(target.dir);
|
|
280
|
+
prov[name] = {
|
|
281
|
+
source: fetched.url,
|
|
282
|
+
installedAt: new Date().toISOString(),
|
|
283
|
+
sha256: fetched.sha256,
|
|
284
|
+
filename,
|
|
285
|
+
};
|
|
286
|
+
writeProvenance(target.dir, prov);
|
|
287
|
+
return { path, name, ext: fetched.ext, source: fetched.url };
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Remove an installed plugin and its provenance record.
|
|
291
|
+
* Checks global dir first, then project (same order as install default).
|
|
292
|
+
*/
|
|
293
|
+
export function uninstallPlugin(basePath, name) {
|
|
294
|
+
assertSafePluginName(name);
|
|
295
|
+
for (const dir of [globalInstallDir(), projectInstallDir(basePath)]) {
|
|
296
|
+
const prov = readProvenance(dir);
|
|
297
|
+
const entry = prov[name];
|
|
298
|
+
if (entry) {
|
|
299
|
+
// Re-validate the filename recorded in provenance: a malicious provenance
|
|
300
|
+
// file must not trick us into deleting outside `dir`.
|
|
301
|
+
assertSafePluginName(entry.filename.replace(/\.(yaml|yml|md)$/i, ""));
|
|
302
|
+
const path = safeResolveInDir(dir, entry.filename);
|
|
303
|
+
if (existsSync(path))
|
|
304
|
+
unlinkSync(path);
|
|
305
|
+
delete prov[name];
|
|
306
|
+
writeProvenance(dir, prov);
|
|
307
|
+
return { removed: true, path };
|
|
308
|
+
}
|
|
309
|
+
// No provenance, but file might still exist.
|
|
310
|
+
for (const ext of [".yaml", ".yml", ".md"]) {
|
|
311
|
+
const candidate = safeResolveInDir(dir, `${name}${ext}`);
|
|
312
|
+
if (existsSync(candidate) && statSync(candidate).isFile()) {
|
|
313
|
+
unlinkSync(candidate);
|
|
314
|
+
return { removed: true, path: candidate, warnedNotInProvenance: true };
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return { removed: false };
|
|
319
|
+
}
|
|
320
|
+
// ─── Preview helpers ─────────────────────────────────────────────────────
|
|
321
|
+
/**
|
|
322
|
+
* First N lines of the fetched content, for the install confirmation UI.
|
|
323
|
+
*/
|
|
324
|
+
export function previewContent(content, maxLines = 20) {
|
|
325
|
+
const lines = content.split(/\r?\n/).slice(0, maxLines);
|
|
326
|
+
return lines.join("\n");
|
|
327
|
+
}
|
|
@@ -82,6 +82,8 @@ export function snapshotState() {
|
|
|
82
82
|
observability_impact: r["observability_impact"] ?? "",
|
|
83
83
|
sequence: toNumeric(r["sequence"], 0),
|
|
84
84
|
replan_triggered_at: r["replan_triggered_at"] ?? null,
|
|
85
|
+
is_sketch: toNumeric(r["is_sketch"], 0),
|
|
86
|
+
sketch_scope: r["sketch_scope"] ?? "",
|
|
85
87
|
}));
|
|
86
88
|
const rawTasks = db.prepare("SELECT * FROM tasks ORDER BY milestone_id, slice_id, sequence, id").all();
|
|
87
89
|
const tasks = rawTasks.map((r) => ({
|
|
@@ -110,6 +112,11 @@ export function snapshotState() {
|
|
|
110
112
|
observability_impact: r["observability_impact"] ?? "",
|
|
111
113
|
full_plan_md: r["full_plan_md"] ?? "",
|
|
112
114
|
sequence: toNumeric(r["sequence"], 0),
|
|
115
|
+
blocker_source: r["blocker_source"] ?? "",
|
|
116
|
+
escalation_pending: toNumeric(r["escalation_pending"], 0),
|
|
117
|
+
escalation_awaiting_review: toNumeric(r["escalation_awaiting_review"], 0),
|
|
118
|
+
escalation_artifact_path: r["escalation_artifact_path"] ?? null,
|
|
119
|
+
escalation_override_applied_at: r["escalation_override_applied_at"] ?? null,
|
|
113
120
|
}));
|
|
114
121
|
const rawDecisions = db.prepare("SELECT * FROM decisions ORDER BY seq").all();
|
|
115
122
|
const decisions = rawDecisions.map((r) => ({
|
|
@@ -122,6 +129,7 @@ export function snapshotState() {
|
|
|
122
129
|
rationale: r["rationale"] ?? "",
|
|
123
130
|
revisable: r["revisable"] ?? "",
|
|
124
131
|
made_by: r["made_by"] ?? "agent",
|
|
132
|
+
source: r["source"] ?? "discussion",
|
|
125
133
|
superseded_by: r["superseded_by"] ?? null,
|
|
126
134
|
}));
|
|
127
135
|
const rawEvidence = db.prepare("SELECT * FROM verification_evidence ORDER BY id").all();
|