gsd-pi 2.75.0 → 2.76.0-dev.4100bd590
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 +208 -151
- 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/agents/researcher.md +1 -1
- 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 +34 -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 +118 -53
- 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 +37 -8
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +8 -2
- package/dist/resources/extensions/gsd/auto-dispatch.js +120 -14
- package/dist/resources/extensions/gsd/auto-loop.js +1 -1
- package/dist/resources/extensions/gsd/auto-model-selection.js +54 -18
- package/dist/resources/extensions/gsd/auto-post-unit.js +10 -8
- package/dist/resources/extensions/gsd/auto-prompts.js +190 -46
- 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 +36 -3
- package/dist/resources/extensions/gsd/auto-worktree.js +71 -2
- package/dist/resources/extensions/gsd/auto.js +57 -25
- package/dist/resources/extensions/gsd/blocked-models.js +68 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +84 -21
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +45 -23
- package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +131 -0
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +29 -0
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +12 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +22 -0
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +84 -10
- 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 +159 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +21 -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 +200 -77
- package/dist/resources/extensions/gsd/commands-handlers.js +21 -2
- package/dist/resources/extensions/gsd/commands-memory.js +462 -0
- 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 +89 -16
- 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 +50 -32
- package/dist/resources/extensions/gsd/doctor-proactive.js +4 -1
- package/dist/resources/extensions/gsd/doctor-providers.js +96 -22
- 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/ecosystem/gsd-extension-api.js +1 -0
- package/dist/resources/extensions/gsd/error-classifier.js +27 -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 +517 -32
- 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/hook-emitter.js +108 -0
- 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/memory-backfill.js +126 -0
- package/dist/resources/extensions/gsd/memory-embeddings.js +219 -0
- package/dist/resources/extensions/gsd/memory-extractor.js +78 -27
- package/dist/resources/extensions/gsd/memory-ingest.js +218 -0
- package/dist/resources/extensions/gsd/memory-relations.js +189 -0
- package/dist/resources/extensions/gsd/memory-source-store.js +113 -0
- package/dist/resources/extensions/gsd/memory-store.js +318 -6
- 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 +105 -8
- 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/add-tests.md +1 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +4 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/debug-diagnose.md +27 -0
- package/dist/resources/extensions/gsd/prompts/debug-session-manager.md +80 -0
- package/dist/resources/extensions/gsd/prompts/execute-task.md +16 -3
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +12 -0
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -0
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +69 -0
- package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -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 +90 -7
- 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/memory-tools.js +331 -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/tools/workflow-tool-executors.js +14 -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 +7 -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/search-the-web/command-search-provider.js +5 -1
- package/dist/resources/extensions/search-the-web/native-search.js +46 -3
- 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/api-design/SKILL.md +190 -0
- package/dist/resources/skills/create-mcp-server/SKILL.md +121 -0
- package/dist/resources/skills/create-workflow/SKILL.md +33 -6
- package/dist/resources/skills/decompose-into-slices/SKILL.md +139 -0
- package/dist/resources/skills/dependency-upgrade/SKILL.md +158 -0
- package/dist/resources/skills/design-an-interface/SKILL.md +102 -0
- package/dist/resources/skills/forensics/SKILL.md +153 -0
- package/dist/resources/skills/grill-me/SKILL.md +93 -0
- package/dist/resources/skills/handoff/SKILL.md +121 -0
- package/dist/resources/skills/observability/SKILL.md +174 -0
- package/dist/resources/skills/security-review/SKILL.md +181 -0
- package/dist/resources/skills/spike-wrap-up/SKILL.md +138 -0
- package/dist/resources/skills/tdd/SKILL.md +112 -0
- package/dist/resources/skills/verify-before-complete/SKILL.md +97 -0
- package/dist/resources/skills/write-docs/SKILL.md +81 -0
- package/dist/resources/skills/write-milestone-brief/SKILL.md +135 -0
- 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 +16 -16
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
- package/dist/web/standalone/.next/required-server-files.json +4 -4
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +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.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/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/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.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/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +5 -5
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +16 -16
- package/dist/web/standalone/.next/server/chunks/63.js +3 -3
- package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
- 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/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +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/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-5b113fd32bc2a1c3.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-b868033a5834586d.js → webpack-5fc74f13a25fa1bb.js} +1 -1
- package/dist/web/standalone/.next/static/css/632cd626b1731d88.css +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/dist/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/daemon/package.json +2 -2
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +12 -10
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/session-manager.d.ts.map +1 -1
- package/packages/mcp-server/dist/session-manager.js +8 -1
- package/packages/mcp-server/dist/session-manager.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +2 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +306 -71
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/mcp-server.test.ts +40 -4
- package/packages/mcp-server/src/server.ts +12 -10
- package/packages/mcp-server/src/session-manager.ts +10 -3
- package/packages/mcp-server/src/workflow-tools.test.ts +346 -1
- package/packages/mcp-server/src/workflow-tools.ts +359 -75
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +12 -0
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +30 -0
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-agent-core/src/agent-loop.ts +14 -0
- package/packages/pi-agent-core/src/types.ts +34 -0
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/index.d.ts +1 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -0
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/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-bearer-auth.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +13 -0
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -0
- 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 +23 -2
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/api-family.d.ts +27 -0
- package/packages/pi-ai/dist/providers/api-family.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/api-family.js +47 -0
- package/packages/pi-ai/dist/providers/api-family.js.map +1 -0
- package/packages/pi-ai/dist/providers/api-family.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/api-family.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/api-family.test.js +101 -0
- package/packages/pi-ai/dist/providers/api-family.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js +12 -2
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +164 -14
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.js +15 -3
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +67 -0
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js +16 -3
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +67 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +289 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +1 -0
- 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 +2 -2
- package/packages/pi-ai/scripts/generate-models.ts +50 -0
- package/packages/pi-ai/src/index.ts +1 -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-bearer-auth.test.ts +26 -0
- 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 +25 -2
- package/packages/pi-ai/src/providers/api-family.test.ts +129 -0
- package/packages/pi-ai/src/providers/api-family.ts +57 -0
- package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +200 -23
- package/packages/pi-ai/src/utils/oauth/github-copilot.ts +12 -2
- package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +84 -0
- package/packages/pi-ai/src/utils/oauth/google-antigravity.ts +15 -5
- package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +84 -0
- package/packages/pi-ai/src/utils/oauth/google-gemini-cli.ts +16 -5
- package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +363 -0
- 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/cli/args.d.ts +6 -0
- package/packages/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/cli/args.js +14 -4
- package/packages/pi-coding-agent/dist/cli/args.js.map +1 -1
- package/packages/pi-coding-agent/dist/cli/args.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/cli/args.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/cli/args.test.js +38 -0
- package/packages/pi-coding-agent/dist/cli/args.test.js.map +1 -0
- 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/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +25 -2
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- 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/extensions/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +4 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +34 -2
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +233 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +200 -3
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts +53 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.js +337 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +234 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/index.js +1 -0
- package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js +40 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js.map +1 -0
- 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/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +4 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +39 -1
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +55 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.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/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/main.js +3 -0
- package/packages/pi-coding-agent/dist/main.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/package.json +1 -1
- package/packages/pi-coding-agent/src/cli/args.test.ts +44 -0
- package/packages/pi-coding-agent/src/cli/args.ts +21 -6
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +56 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +27 -2
- 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/extensions/index.ts +16 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +353 -1
- package/packages/pi-coding-agent/src/core/extensions/types.ts +253 -2
- package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +269 -0
- package/packages/pi-coding-agent/src/core/hooks-runner.ts +460 -0
- package/packages/pi-coding-agent/src/core/index.ts +10 -0
- package/packages/pi-coding-agent/src/core/model-registry-auth-header.test.ts +44 -0
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +37 -1
- package/packages/pi-coding-agent/src/core/retry-handler.ts +4 -1
- package/packages/pi-coding-agent/src/core/sdk.ts +58 -1
- package/packages/pi-coding-agent/src/core/settings-manager.ts +57 -0
- package/packages/pi-coding-agent/src/core/skill-tool.test.ts +2 -2
- package/packages/pi-coding-agent/src/index.ts +16 -0
- package/packages/pi-coding-agent/src/main.ts +4 -0
- 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/package.json +1 -1
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/package.json +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/pkg/package.json +1 -1
- package/src/resources/agents/researcher.md +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 +36 -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 +2 -9
- package/src/resources/extensions/gsd/auto/loop.ts +109 -3
- package/src/resources/extensions/gsd/auto/phases.ts +146 -66
- 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 +46 -5
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +15 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +141 -9
- package/src/resources/extensions/gsd/auto-loop.ts +1 -1
- package/src/resources/extensions/gsd/auto-model-selection.ts +72 -18
- package/src/resources/extensions/gsd/auto-post-unit.ts +10 -8
- package/src/resources/extensions/gsd/auto-prompts.ts +232 -47
- 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 +36 -3
- package/src/resources/extensions/gsd/auto-worktree.ts +81 -1
- package/src/resources/extensions/gsd/auto.ts +61 -28
- package/src/resources/extensions/gsd/blocked-models.ts +98 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +105 -21
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +46 -24
- package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +163 -0
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +31 -0
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +15 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -0
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +89 -10
- 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 +196 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +21 -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 +262 -78
- package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
- package/src/resources/extensions/gsd/commands-memory.ts +551 -0
- 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 +91 -17
- 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 +51 -30
- package/src/resources/extensions/gsd/doctor-proactive.ts +4 -1
- package/src/resources/extensions/gsd/doctor-providers.ts +109 -26
- 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/ecosystem/gsd-extension-api.ts +2 -0
- package/src/resources/extensions/gsd/error-classifier.ts +32 -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 +617 -32
- 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/hook-emitter.ts +188 -0
- 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/memory-backfill.ts +140 -0
- package/src/resources/extensions/gsd/memory-embeddings.ts +235 -0
- package/src/resources/extensions/gsd/memory-extractor.ts +100 -34
- package/src/resources/extensions/gsd/memory-ingest.ts +286 -0
- package/src/resources/extensions/gsd/memory-relations.ts +240 -0
- package/src/resources/extensions/gsd/memory-source-store.ts +138 -0
- package/src/resources/extensions/gsd/memory-store.ts +377 -7
- 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 +106 -12
- 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/add-tests.md +1 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +4 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/debug-diagnose.md +27 -0
- package/src/resources/extensions/gsd/prompts/debug-session-manager.md +80 -0
- package/src/resources/extensions/gsd/prompts/execute-task.md +16 -3
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +12 -0
- package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -0
- package/src/resources/extensions/gsd/prompts/refine-slice.md +69 -0
- package/src/resources/extensions/gsd/prompts/research-slice.md +1 -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 +95 -6
- 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-dashboard.test.ts +49 -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 +95 -1
- 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/blocked-models.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/commands-do.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +335 -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/derive-state-db.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +8 -4
- 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 +175 -17
- package/src/resources/extensions/gsd/tests/enhanced-verification-integration.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +306 -1
- 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 +145 -8
- package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +62 -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-symlink-cwd.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +117 -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/interactive-routing-bypass.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +206 -1
- package/src/resources/extensions/gsd/tests/load-memory-block.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-embeddings.test.ts +213 -0
- package/src/resources/extensions/gsd/tests/memory-ingest.test.ts +153 -0
- package/src/resources/extensions/gsd/tests/memory-maintenance.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/memory-relations.test.ts +175 -0
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/memory-tools.test.ts +295 -0
- 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-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 +341 -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 +159 -8
- 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/prompts-no-gitignored-test-refs.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +88 -4
- 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/stash-queued-context-files.test.ts +54 -0
- 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/validate-milestone.test.ts +9 -3
- 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/workflow-tool-executors.test.ts +97 -0
- 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/memory-tools.ts +410 -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/tools/workflow-tool-executors.ts +14 -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-logger.ts +4 -1
- 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 +7 -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/search-the-web/command-search-provider.ts +5 -1
- package/src/resources/extensions/search-the-web/native-search.ts +50 -4
- 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/api-design/SKILL.md +190 -0
- package/src/resources/skills/create-mcp-server/SKILL.md +121 -0
- package/src/resources/skills/create-workflow/SKILL.md +33 -6
- package/src/resources/skills/decompose-into-slices/SKILL.md +139 -0
- package/src/resources/skills/dependency-upgrade/SKILL.md +158 -0
- package/src/resources/skills/design-an-interface/SKILL.md +102 -0
- package/src/resources/skills/forensics/SKILL.md +153 -0
- package/src/resources/skills/grill-me/SKILL.md +93 -0
- package/src/resources/skills/handoff/SKILL.md +121 -0
- package/src/resources/skills/observability/SKILL.md +174 -0
- package/src/resources/skills/security-review/SKILL.md +181 -0
- package/src/resources/skills/spike-wrap-up/SKILL.md +138 -0
- package/src/resources/skills/tdd/SKILL.md +112 -0
- package/src/resources/skills/verify-before-complete/SKILL.md +97 -0
- package/src/resources/skills/write-docs/SKILL.md +81 -0
- package/src/resources/skills/write-milestone-brief/SKILL.md +135 -0
- package/dist/web/standalone/.next/static/chunks/2826.dd3dc8bbd3025fa5.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/page-7115e62689b5fd84.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- package/dist/web/standalone/.next/static/css/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/{prkokVQFxWtUVIku57_0z → YnUwu2WWaT0_hyTLUF4nq}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{prkokVQFxWtUVIku57_0z → YnUwu2WWaT0_hyTLUF4nq}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,1229 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { existsSync, mkdtempSync, mkdirSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
|
|
7
|
+
import { handleGSDCommand } from "../commands/dispatcher.ts";
|
|
8
|
+
import { handleDebug } from "../commands-debug.ts";
|
|
9
|
+
import {
|
|
10
|
+
createDebugSession,
|
|
11
|
+
debugSessionArtifactPath,
|
|
12
|
+
debugSessionsDir,
|
|
13
|
+
loadDebugSession,
|
|
14
|
+
updateDebugSession,
|
|
15
|
+
} from "../debug-session-store.ts";
|
|
16
|
+
|
|
17
|
+
interface DispatchCall {
|
|
18
|
+
payload: any;
|
|
19
|
+
options: any;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function createMockPiWithDispatch() {
|
|
23
|
+
const calls: DispatchCall[] = [];
|
|
24
|
+
return {
|
|
25
|
+
calls,
|
|
26
|
+
pi: {
|
|
27
|
+
sendMessage(payload: any, options: any) {
|
|
28
|
+
calls.push({ payload, options });
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface MockCtx {
|
|
35
|
+
notifications: Array<{ message: string; level: string }>;
|
|
36
|
+
ui: {
|
|
37
|
+
notify: (message: string, level: string) => void;
|
|
38
|
+
custom: () => Promise<void>;
|
|
39
|
+
};
|
|
40
|
+
shutdown: () => Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function makeBase(): string {
|
|
44
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-debug-lifecycle-int-"));
|
|
45
|
+
mkdirSync(join(base, ".gsd"), { recursive: true });
|
|
46
|
+
return base;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function createMockCtx(): MockCtx {
|
|
50
|
+
const notifications: Array<{ message: string; level: string }> = [];
|
|
51
|
+
return {
|
|
52
|
+
notifications,
|
|
53
|
+
ui: {
|
|
54
|
+
notify(message: string, level: string) {
|
|
55
|
+
notifications.push({ message, level });
|
|
56
|
+
},
|
|
57
|
+
custom: async () => {},
|
|
58
|
+
},
|
|
59
|
+
shutdown: async () => {},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function lastNotification(ctx: MockCtx): { message: string; level: string } {
|
|
64
|
+
assert.ok(ctx.notifications.length > 0, "expected at least one UI notification");
|
|
65
|
+
return ctx.notifications.at(-1)!;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
test("/gsd debug lifecycle integration covers start/list/status/continue across multiple sessions", async () => {
|
|
69
|
+
const base = makeBase();
|
|
70
|
+
const saved = process.cwd();
|
|
71
|
+
process.chdir(base);
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
const ctx = createMockCtx();
|
|
75
|
+
|
|
76
|
+
await handleGSDCommand("debug API returns 500 on checkout", ctx as any, {} as any);
|
|
77
|
+
const firstStarted = lastNotification(ctx);
|
|
78
|
+
assert.equal(firstStarted.level, "info");
|
|
79
|
+
assert.match(firstStarted.message, /Debug session started: api-returns-500-on-checkout/);
|
|
80
|
+
|
|
81
|
+
await handleGSDCommand("debug API returns 500 on checkout", ctx as any, {} as any);
|
|
82
|
+
const secondStarted = lastNotification(ctx);
|
|
83
|
+
assert.equal(secondStarted.level, "info");
|
|
84
|
+
assert.match(secondStarted.message, /Debug session started: api-returns-500-on-checkout-2/);
|
|
85
|
+
|
|
86
|
+
await handleGSDCommand("debug Checkout retries spin forever", ctx as any, {} as any);
|
|
87
|
+
const thirdStarted = lastNotification(ctx);
|
|
88
|
+
assert.equal(thirdStarted.level, "info");
|
|
89
|
+
assert.match(thirdStarted.message, /Debug session started: checkout-retries-spin-forever/);
|
|
90
|
+
|
|
91
|
+
const sessionsDir = debugSessionsDir(base);
|
|
92
|
+
const artifacts = readdirSync(sessionsDir).filter(name => name.endsWith(".json")).sort();
|
|
93
|
+
assert.deepEqual(artifacts, [
|
|
94
|
+
"api-returns-500-on-checkout-2.json",
|
|
95
|
+
"api-returns-500-on-checkout.json",
|
|
96
|
+
"checkout-retries-spin-forever.json",
|
|
97
|
+
]);
|
|
98
|
+
|
|
99
|
+
await handleGSDCommand("debug list", ctx as any, {} as any);
|
|
100
|
+
const listed = lastNotification(ctx);
|
|
101
|
+
assert.equal(listed.level, "info");
|
|
102
|
+
assert.match(listed.message, /Debug sessions:/);
|
|
103
|
+
assert.match(listed.message, /api-returns-500-on-checkout/);
|
|
104
|
+
assert.match(listed.message, /api-returns-500-on-checkout-2/);
|
|
105
|
+
assert.match(listed.message, /checkout-retries-spin-forever/);
|
|
106
|
+
assert.match(listed.message, /mode=debug status=active phase=queued/);
|
|
107
|
+
|
|
108
|
+
await handleGSDCommand("debug status api-returns-500-on-checkout", ctx as any, {} as any);
|
|
109
|
+
const statusBeforeContinue = lastNotification(ctx);
|
|
110
|
+
assert.equal(statusBeforeContinue.level, "info");
|
|
111
|
+
assert.match(statusBeforeContinue.message, /^Debug session status: api-returns-500-on-checkout/m);
|
|
112
|
+
assert.match(statusBeforeContinue.message, /^mode=debug$/m);
|
|
113
|
+
assert.match(statusBeforeContinue.message, /^status=active$/m);
|
|
114
|
+
assert.match(statusBeforeContinue.message, /^phase=queued$/m);
|
|
115
|
+
assert.match(statusBeforeContinue.message, /^updated=\d{4}-\d{2}-\d{2}T/m);
|
|
116
|
+
|
|
117
|
+
await handleGSDCommand("debug continue api-returns-500-on-checkout-2", ctx as any, {} as any);
|
|
118
|
+
const resumed = lastNotification(ctx);
|
|
119
|
+
assert.equal(resumed.level, "info");
|
|
120
|
+
assert.match(resumed.message, /Resumed debug session: api-returns-500-on-checkout-2/);
|
|
121
|
+
assert.match(resumed.message, /status=active/);
|
|
122
|
+
assert.match(resumed.message, /phase=continued/);
|
|
123
|
+
|
|
124
|
+
await handleGSDCommand("debug status api-returns-500-on-checkout-2", ctx as any, {} as any);
|
|
125
|
+
const statusAfterContinue = lastNotification(ctx);
|
|
126
|
+
assert.equal(statusAfterContinue.level, "info");
|
|
127
|
+
assert.match(statusAfterContinue.message, /^phase=continued$/m);
|
|
128
|
+
assert.match(statusAfterContinue.message, /^updated=\d{4}-\d{2}-\d{2}T/m);
|
|
129
|
+
} finally {
|
|
130
|
+
process.chdir(saved);
|
|
131
|
+
rmSync(base, { recursive: true, force: true });
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test("/gsd debug lifecycle integration handles invalid slugs and malformed artifacts with actionable diagnostics", async () => {
|
|
136
|
+
const base = makeBase();
|
|
137
|
+
const saved = process.cwd();
|
|
138
|
+
process.chdir(base);
|
|
139
|
+
|
|
140
|
+
try {
|
|
141
|
+
const ctx = createMockCtx();
|
|
142
|
+
|
|
143
|
+
await handleGSDCommand("debug Sync bug in checkout", ctx as any, {} as any);
|
|
144
|
+
const started = lastNotification(ctx);
|
|
145
|
+
assert.equal(started.level, "info");
|
|
146
|
+
assert.match(started.message, /Debug session started: sync-bug-in-checkout/);
|
|
147
|
+
|
|
148
|
+
await handleGSDCommand("debug status no-such-session", ctx as any, {} as any);
|
|
149
|
+
const missingStatus = lastNotification(ctx);
|
|
150
|
+
assert.equal(missingStatus.level, "warning");
|
|
151
|
+
assert.match(missingStatus.message, /Unknown debug session slug 'no-such-session'/);
|
|
152
|
+
assert.match(missingStatus.message, /Run \/gsd debug list/);
|
|
153
|
+
|
|
154
|
+
await handleGSDCommand("debug continue no-such-session", ctx as any, {} as any);
|
|
155
|
+
const missingContinue = lastNotification(ctx);
|
|
156
|
+
assert.equal(missingContinue.level, "warning");
|
|
157
|
+
assert.match(missingContinue.message, /Unknown debug session slug 'no-such-session'/);
|
|
158
|
+
|
|
159
|
+
const brokenArtifactPath = debugSessionArtifactPath(base, "broken-session");
|
|
160
|
+
writeFileSync(brokenArtifactPath, "{ definitely-not-valid-json", "utf-8");
|
|
161
|
+
|
|
162
|
+
await handleGSDCommand("debug status broken-session", ctx as any, {} as any);
|
|
163
|
+
const corruptedStatus = lastNotification(ctx);
|
|
164
|
+
assert.equal(corruptedStatus.level, "warning");
|
|
165
|
+
assert.match(corruptedStatus.message, /Unable to load debug session 'broken-session'/);
|
|
166
|
+
assert.match(corruptedStatus.message, /Try \/gsd debug --diagnose broken-session/);
|
|
167
|
+
|
|
168
|
+
await handleGSDCommand("debug list", ctx as any, {} as any);
|
|
169
|
+
const listed = lastNotification(ctx);
|
|
170
|
+
assert.equal(listed.level, "info");
|
|
171
|
+
assert.match(listed.message, /Malformed artifacts: 1/);
|
|
172
|
+
assert.match(listed.message, /broken-session\.json/);
|
|
173
|
+
assert.match(listed.message, /Run \/gsd debug --diagnose for remediation guidance/);
|
|
174
|
+
|
|
175
|
+
await handleGSDCommand("debug --diagnose", ctx as any, {} as any);
|
|
176
|
+
const diagnosed = lastNotification(ctx);
|
|
177
|
+
assert.equal(diagnosed.level, "warning");
|
|
178
|
+
assert.match(diagnosed.message, /Debug session diagnostics:/);
|
|
179
|
+
assert.match(diagnosed.message, /malformedArtifacts=1/);
|
|
180
|
+
assert.match(diagnosed.message, /Remediation: repair\/remove malformed JSON artifacts under \.gsd\/debug\/sessions\//);
|
|
181
|
+
} finally {
|
|
182
|
+
process.chdir(saved);
|
|
183
|
+
rmSync(base, { recursive: true, force: true });
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test("/gsd debug lifecycle integration keeps session artifacts isolated from debug logs and preserves slug determinism", async () => {
|
|
188
|
+
const base = makeBase();
|
|
189
|
+
const saved = process.cwd();
|
|
190
|
+
process.chdir(base);
|
|
191
|
+
|
|
192
|
+
try {
|
|
193
|
+
const ctx = createMockCtx();
|
|
194
|
+
|
|
195
|
+
const debugDir = join(base, ".gsd", "debug");
|
|
196
|
+
mkdirSync(debugDir, { recursive: true });
|
|
197
|
+
writeFileSync(join(debugDir, "payment-timeout.log"), "log seed\n", "utf-8");
|
|
198
|
+
|
|
199
|
+
await handleGSDCommand("debug Payment timeout", ctx as any, {} as any);
|
|
200
|
+
const firstStarted = lastNotification(ctx);
|
|
201
|
+
assert.equal(firstStarted.level, "info");
|
|
202
|
+
assert.match(firstStarted.message, /Debug session started: payment-timeout/);
|
|
203
|
+
|
|
204
|
+
// Existing .log files must not reserve slug suffixes for session artifacts.
|
|
205
|
+
await handleGSDCommand("debug Payment timeout", ctx as any, {} as any);
|
|
206
|
+
const secondStarted = lastNotification(ctx);
|
|
207
|
+
assert.equal(secondStarted.level, "info");
|
|
208
|
+
assert.match(secondStarted.message, /Debug session started: payment-timeout-2/);
|
|
209
|
+
|
|
210
|
+
assert.equal(existsSync(join(base, ".gsd", "debug", "payment-timeout.json")), false);
|
|
211
|
+
assert.equal(existsSync(join(base, ".gsd", "debug", "sessions", "payment-timeout.json")), true);
|
|
212
|
+
assert.equal(existsSync(join(base, ".gsd", "debug", "sessions", "payment-timeout-2.json")), true);
|
|
213
|
+
|
|
214
|
+
await handleGSDCommand("logs debug", ctx as any, {} as any);
|
|
215
|
+
const logsListed = lastNotification(ctx);
|
|
216
|
+
assert.equal(logsListed.level, "info");
|
|
217
|
+
assert.match(logsListed.message, /Debug Logs \(\.gsd\/debug\/\):/);
|
|
218
|
+
assert.match(logsListed.message, /payment-timeout\.log/);
|
|
219
|
+
assert.doesNotMatch(logsListed.message, /payment-timeout\.json/);
|
|
220
|
+
|
|
221
|
+
await handleGSDCommand("debug list", ctx as any, {} as any);
|
|
222
|
+
const sessionsListed = lastNotification(ctx);
|
|
223
|
+
assert.equal(sessionsListed.level, "info");
|
|
224
|
+
assert.match(sessionsListed.message, /payment-timeout/);
|
|
225
|
+
assert.match(sessionsListed.message, /payment-timeout-2/);
|
|
226
|
+
assert.match(sessionsListed.message, /mode=debug status=active phase=queued/);
|
|
227
|
+
} finally {
|
|
228
|
+
process.chdir(saved);
|
|
229
|
+
rmSync(base, { recursive: true, force: true });
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
test("/gsd debug --diagnose <issue> dispatches find_root_cause_only goal and records mode=diagnose session", async () => {
|
|
234
|
+
const base = makeBase();
|
|
235
|
+
const saved = process.cwd();
|
|
236
|
+
process.chdir(base);
|
|
237
|
+
|
|
238
|
+
try {
|
|
239
|
+
const ctx = createMockCtx();
|
|
240
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
241
|
+
|
|
242
|
+
await handleDebug("--diagnose auth token rotation breaks sessions", ctx as any, pi as any);
|
|
243
|
+
|
|
244
|
+
const n = lastNotification(ctx);
|
|
245
|
+
assert.equal(n.level, "info");
|
|
246
|
+
assert.match(n.message, /Diagnose session started:/);
|
|
247
|
+
assert.match(n.message, /mode=diagnose/);
|
|
248
|
+
assert.match(n.message, /dispatchMode=find_root_cause_only/);
|
|
249
|
+
|
|
250
|
+
assert.equal(calls.length, 1, "should dispatch exactly one message");
|
|
251
|
+
const call = calls[0];
|
|
252
|
+
assert.equal(call.payload.customType, "gsd-debug-diagnose");
|
|
253
|
+
assert.match(call.payload.content, /find_root_cause_only/);
|
|
254
|
+
assert.match(call.payload.content, /auth token rotation breaks sessions/i);
|
|
255
|
+
assert.equal(call.options.triggerTurn, true);
|
|
256
|
+
} finally {
|
|
257
|
+
process.chdir(saved);
|
|
258
|
+
rmSync(base, { recursive: true, force: true });
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
test("/gsd debug continue <slug> dispatches find_and_fix goal scoped to target slug", async () => {
|
|
263
|
+
const base = makeBase();
|
|
264
|
+
const saved = process.cwd();
|
|
265
|
+
process.chdir(base);
|
|
266
|
+
|
|
267
|
+
try {
|
|
268
|
+
const ctx = createMockCtx();
|
|
269
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
270
|
+
|
|
271
|
+
// Start two sessions so we can verify continue targets only the right one.
|
|
272
|
+
await handleDebug("Race condition in payment handler", ctx as any, {} as any);
|
|
273
|
+
await handleDebug("Stale cache on checkout", ctx as any, {} as any);
|
|
274
|
+
|
|
275
|
+
calls.length = 0; // reset — only created without pi dispatch above
|
|
276
|
+
|
|
277
|
+
await handleDebug("continue race-condition-in-payment-handler", ctx as any, pi as any);
|
|
278
|
+
|
|
279
|
+
const n = lastNotification(ctx);
|
|
280
|
+
assert.equal(n.level, "info");
|
|
281
|
+
assert.match(n.message, /Resumed debug session: race-condition-in-payment-handler/);
|
|
282
|
+
assert.match(n.message, /phase=continued/);
|
|
283
|
+
assert.match(n.message, /dispatchMode=find_and_fix/);
|
|
284
|
+
|
|
285
|
+
assert.equal(calls.length, 1, "should dispatch exactly one message");
|
|
286
|
+
const call = calls[0];
|
|
287
|
+
assert.equal(call.payload.customType, "gsd-debug-continue");
|
|
288
|
+
assert.match(call.payload.content, /find_and_fix/);
|
|
289
|
+
// Content must reference the target slug, not the other session.
|
|
290
|
+
assert.match(call.payload.content, /race-condition-in-payment-handler/);
|
|
291
|
+
assert.doesNotMatch(call.payload.content, /stale-cache-on-checkout/);
|
|
292
|
+
assert.equal(call.options.triggerTurn, true);
|
|
293
|
+
} finally {
|
|
294
|
+
process.chdir(saved);
|
|
295
|
+
rmSync(base, { recursive: true, force: true });
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
test("/gsd debug --diagnose (zero-arg) with no pi still reports malformed artifact counts without dispatch", async () => {
|
|
300
|
+
const base = makeBase();
|
|
301
|
+
const saved = process.cwd();
|
|
302
|
+
process.chdir(base);
|
|
303
|
+
|
|
304
|
+
try {
|
|
305
|
+
const ctx = createMockCtx();
|
|
306
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
307
|
+
|
|
308
|
+
// Inject two broken artifacts.
|
|
309
|
+
const sessionsDir = debugSessionsDir(base);
|
|
310
|
+
mkdirSync(sessionsDir, { recursive: true });
|
|
311
|
+
writeFileSync(join(sessionsDir, "broken-a.json"), "{bad json", "utf-8");
|
|
312
|
+
writeFileSync(join(sessionsDir, "broken-b.json"), "null", "utf-8");
|
|
313
|
+
|
|
314
|
+
// Zero-arg --diagnose via dispatcher (no pi) — dispatch should NOT fire.
|
|
315
|
+
await handleGSDCommand("debug --diagnose", ctx as any, {} as any);
|
|
316
|
+
|
|
317
|
+
const n = lastNotification(ctx);
|
|
318
|
+
assert.equal(n.level, "warning");
|
|
319
|
+
assert.match(n.message, /Debug session diagnostics:/);
|
|
320
|
+
assert.match(n.message, /malformedArtifacts=2/);
|
|
321
|
+
assert.match(n.message, /Remediation:/);
|
|
322
|
+
|
|
323
|
+
// Now confirm no dispatch occurred even with pi present (zero-arg diagnose is advisory only).
|
|
324
|
+
await handleDebug("--diagnose", ctx as any, pi as any);
|
|
325
|
+
assert.equal(calls.length, 0, "zero-arg --diagnose must not dispatch even with pi present");
|
|
326
|
+
} finally {
|
|
327
|
+
process.chdir(saved);
|
|
328
|
+
rmSync(base, { recursive: true, force: true });
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
test("/gsd debug negative: continue unknown slug emits warning, continue resolved session emits warning", async () => {
|
|
333
|
+
const base = makeBase();
|
|
334
|
+
const saved = process.cwd();
|
|
335
|
+
process.chdir(base);
|
|
336
|
+
|
|
337
|
+
try {
|
|
338
|
+
const ctx = createMockCtx();
|
|
339
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
340
|
+
|
|
341
|
+
// Continue on non-existent slug.
|
|
342
|
+
await handleDebug("continue totally-nonexistent-slug", ctx as any, pi as any);
|
|
343
|
+
const notFound = lastNotification(ctx);
|
|
344
|
+
assert.equal(notFound.level, "warning");
|
|
345
|
+
assert.match(notFound.message, /Unknown debug session slug 'totally-nonexistent-slug'/);
|
|
346
|
+
assert.equal(calls.length, 0, "no dispatch for unknown slug");
|
|
347
|
+
|
|
348
|
+
// Start and manually check that invalid 2-token status (missing slug) emits error, not usage.
|
|
349
|
+
await handleDebug("status", ctx as any, {} as any);
|
|
350
|
+
const noSlug = lastNotification(ctx);
|
|
351
|
+
assert.equal(noSlug.level, "warning");
|
|
352
|
+
assert.match(noSlug.message, /Missing slug/);
|
|
353
|
+
} finally {
|
|
354
|
+
process.chdir(saved);
|
|
355
|
+
rmSync(base, { recursive: true, force: true });
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
test("/gsd debug negative: multiple sessions with similar slugs — status and continue target exact match only", async () => {
|
|
360
|
+
const base = makeBase();
|
|
361
|
+
const saved = process.cwd();
|
|
362
|
+
process.chdir(base);
|
|
363
|
+
|
|
364
|
+
try {
|
|
365
|
+
const ctx = createMockCtx();
|
|
366
|
+
|
|
367
|
+
await handleGSDCommand("debug Login token expires", ctx as any, {} as any);
|
|
368
|
+
await handleGSDCommand("debug Login token expires too fast", ctx as any, {} as any);
|
|
369
|
+
|
|
370
|
+
// list to confirm two distinct slugs exist.
|
|
371
|
+
await handleGSDCommand("debug list", ctx as any, {} as any);
|
|
372
|
+
const listed = lastNotification(ctx);
|
|
373
|
+
assert.match(listed.message, /login-token-expires\b/);
|
|
374
|
+
assert.match(listed.message, /login-token-expires-too-fast\b/);
|
|
375
|
+
|
|
376
|
+
// status on base slug must not accidentally describe the suffixed one.
|
|
377
|
+
await handleGSDCommand("debug status login-token-expires", ctx as any, {} as any);
|
|
378
|
+
const baseStatus = lastNotification(ctx);
|
|
379
|
+
assert.match(baseStatus.message, /^Debug session status: login-token-expires$/m);
|
|
380
|
+
assert.doesNotMatch(baseStatus.message, /login-token-expires-too-fast/);
|
|
381
|
+
|
|
382
|
+
// status on suffixed slug must describe that one.
|
|
383
|
+
await handleGSDCommand("debug status login-token-expires-too-fast", ctx as any, {} as any);
|
|
384
|
+
const suffixedStatus = lastNotification(ctx);
|
|
385
|
+
assert.match(suffixedStatus.message, /^Debug session status: login-token-expires-too-fast$/m);
|
|
386
|
+
} finally {
|
|
387
|
+
process.chdir(saved);
|
|
388
|
+
rmSync(base, { recursive: true, force: true });
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
// ── S03 tests: checkpoint/TDD gate dispatch and backward compat ──────────────
|
|
393
|
+
|
|
394
|
+
test("/gsd debug S03: checkpoint resume dispatches enriched payload via debug-session-manager template", async () => {
|
|
395
|
+
const base = makeBase();
|
|
396
|
+
const saved = process.cwd();
|
|
397
|
+
process.chdir(base);
|
|
398
|
+
|
|
399
|
+
try {
|
|
400
|
+
const ctx = createMockCtx();
|
|
401
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
402
|
+
|
|
403
|
+
const created = createDebugSession(base, { issue: "Login fails after deploy" });
|
|
404
|
+
const slug = created.session.slug;
|
|
405
|
+
|
|
406
|
+
updateDebugSession(base, slug, {
|
|
407
|
+
checkpoint: {
|
|
408
|
+
type: "human-verify",
|
|
409
|
+
summary: "Verify fix on staging",
|
|
410
|
+
awaitingResponse: true,
|
|
411
|
+
},
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
await handleDebug(`continue ${slug}`, ctx as any, pi as any);
|
|
415
|
+
|
|
416
|
+
const n = lastNotification(ctx);
|
|
417
|
+
assert.equal(n.level, "info");
|
|
418
|
+
assert.match(n.message, new RegExp(`Resumed debug session: ${slug}`));
|
|
419
|
+
assert.match(n.message, /phase=continued/);
|
|
420
|
+
assert.match(n.message, /dispatchMode=checkpointType=human-verify/);
|
|
421
|
+
|
|
422
|
+
assert.equal(calls.length, 1, "should dispatch exactly one message");
|
|
423
|
+
const call = calls[0];
|
|
424
|
+
assert.equal(call.payload.customType, "gsd-debug-continue");
|
|
425
|
+
// debug-session-manager template marker (absent from debug-diagnose)
|
|
426
|
+
assert.match(call.payload.content, /Structured Return Protocol/);
|
|
427
|
+
// Checkpoint context embedded
|
|
428
|
+
assert.match(call.payload.content, /## Active Checkpoint/);
|
|
429
|
+
assert.match(call.payload.content, /type: human-verify/);
|
|
430
|
+
assert.match(call.payload.content, /summary: Verify fix on staging/);
|
|
431
|
+
assert.match(call.payload.content, /awaitingResponse: true/);
|
|
432
|
+
assert.equal(call.options.triggerTurn, true);
|
|
433
|
+
} finally {
|
|
434
|
+
process.chdir(saved);
|
|
435
|
+
rmSync(base, { recursive: true, force: true });
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
test("/gsd debug S03: TDD gate pending dispatches find_root_cause_only with TDD instructions", async () => {
|
|
440
|
+
const base = makeBase();
|
|
441
|
+
const saved = process.cwd();
|
|
442
|
+
process.chdir(base);
|
|
443
|
+
|
|
444
|
+
try {
|
|
445
|
+
const ctx = createMockCtx();
|
|
446
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
447
|
+
|
|
448
|
+
const created = createDebugSession(base, { issue: "Auth refresh races on mobile" });
|
|
449
|
+
const slug = created.session.slug;
|
|
450
|
+
|
|
451
|
+
updateDebugSession(base, slug, {
|
|
452
|
+
tddGate: { enabled: true, phase: "pending" },
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
await handleDebug(`continue ${slug}`, ctx as any, pi as any);
|
|
456
|
+
|
|
457
|
+
const n = lastNotification(ctx);
|
|
458
|
+
assert.equal(n.level, "info");
|
|
459
|
+
assert.match(n.message, new RegExp(`Resumed debug session: ${slug}`));
|
|
460
|
+
assert.match(n.message, /dispatchMode=tddPhase=pending/);
|
|
461
|
+
|
|
462
|
+
assert.equal(calls.length, 1, "should dispatch exactly one message");
|
|
463
|
+
const call = calls[0];
|
|
464
|
+
assert.equal(call.payload.customType, "gsd-debug-continue");
|
|
465
|
+
// Active goal must be find_root_cause_only (not find_and_fix)
|
|
466
|
+
assert.match(call.payload.content, /## Goal\s+`find_root_cause_only`/);
|
|
467
|
+
assert.doesNotMatch(call.payload.content, /## Goal\s+`find_and_fix`/);
|
|
468
|
+
// TDD gate section present
|
|
469
|
+
assert.match(call.payload.content, /## TDD Gate/);
|
|
470
|
+
assert.match(call.payload.content, /phase: pending/);
|
|
471
|
+
assert.match(call.payload.content, /TDD mode is active/);
|
|
472
|
+
// debug-session-manager template marker
|
|
473
|
+
assert.match(call.payload.content, /Structured Return Protocol/);
|
|
474
|
+
assert.equal(call.options.triggerTurn, true);
|
|
475
|
+
} finally {
|
|
476
|
+
process.chdir(saved);
|
|
477
|
+
rmSync(base, { recursive: true, force: true });
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
test("/gsd debug S03: TDD gate red dispatches find_and_fix and advances phase to green", async () => {
|
|
482
|
+
const base = makeBase();
|
|
483
|
+
const saved = process.cwd();
|
|
484
|
+
process.chdir(base);
|
|
485
|
+
|
|
486
|
+
try {
|
|
487
|
+
const ctx = createMockCtx();
|
|
488
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
489
|
+
|
|
490
|
+
const created = createDebugSession(base, { issue: "Auth token expiry not handled" });
|
|
491
|
+
const slug = created.session.slug;
|
|
492
|
+
|
|
493
|
+
updateDebugSession(base, slug, {
|
|
494
|
+
tddGate: {
|
|
495
|
+
enabled: true,
|
|
496
|
+
phase: "red",
|
|
497
|
+
testFile: "auth.test.ts",
|
|
498
|
+
testName: "rejects expired token",
|
|
499
|
+
},
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
await handleDebug(`continue ${slug}`, ctx as any, pi as any);
|
|
503
|
+
|
|
504
|
+
const n = lastNotification(ctx);
|
|
505
|
+
assert.equal(n.level, "info");
|
|
506
|
+
assert.match(n.message, new RegExp(`Resumed debug session: ${slug}`));
|
|
507
|
+
assert.match(n.message, /dispatchMode=tddPhase=red/);
|
|
508
|
+
|
|
509
|
+
assert.equal(calls.length, 1, "should dispatch exactly one message");
|
|
510
|
+
const call = calls[0];
|
|
511
|
+
assert.equal(call.payload.customType, "gsd-debug-continue");
|
|
512
|
+
assert.match(call.payload.content, /## Goal\s+`find_and_fix`/);
|
|
513
|
+
assert.match(call.payload.content, /## TDD Gate/);
|
|
514
|
+
assert.match(call.payload.content, /phase: red/);
|
|
515
|
+
assert.match(call.payload.content, /testFile: auth\.test\.ts/);
|
|
516
|
+
assert.match(call.payload.content, /testName: rejects expired token/);
|
|
517
|
+
assert.equal(call.options.triggerTurn, true);
|
|
518
|
+
|
|
519
|
+
// Reload artifact from disk and verify tddGate.phase advanced to green
|
|
520
|
+
const reloaded = loadDebugSession(base, slug);
|
|
521
|
+
assert.ok(reloaded, "session should still exist after continue");
|
|
522
|
+
assert.equal(reloaded!.session.tddGate?.phase, "green", "tddGate.phase must advance red→green");
|
|
523
|
+
assert.equal(reloaded!.session.phase, "continued");
|
|
524
|
+
} finally {
|
|
525
|
+
process.chdir(saved);
|
|
526
|
+
rmSync(base, { recursive: true, force: true });
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
test("/gsd debug S03: backward compat — legacy session without checkpoint/TDD uses debug-diagnose template", async () => {
|
|
531
|
+
const base = makeBase();
|
|
532
|
+
const saved = process.cwd();
|
|
533
|
+
process.chdir(base);
|
|
534
|
+
|
|
535
|
+
try {
|
|
536
|
+
const ctx = createMockCtx();
|
|
537
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
538
|
+
|
|
539
|
+
// S02-era session — no checkpoint, no tddGate fields set
|
|
540
|
+
const created = createDebugSession(base, { issue: "Payment retries hang indefinitely" });
|
|
541
|
+
const slug = created.session.slug;
|
|
542
|
+
|
|
543
|
+
await handleDebug(`continue ${slug}`, ctx as any, pi as any);
|
|
544
|
+
|
|
545
|
+
const n = lastNotification(ctx);
|
|
546
|
+
assert.equal(n.level, "info");
|
|
547
|
+
assert.match(n.message, new RegExp(`Resumed debug session: ${slug}`));
|
|
548
|
+
assert.match(n.message, /phase=continued/);
|
|
549
|
+
assert.match(n.message, /dispatchMode=find_and_fix/);
|
|
550
|
+
|
|
551
|
+
assert.equal(calls.length, 1, "should dispatch exactly one message");
|
|
552
|
+
const call = calls[0];
|
|
553
|
+
assert.equal(call.payload.customType, "gsd-debug-continue");
|
|
554
|
+
// debug-diagnose template: no Structured Return Protocol, no checkpoint/TDD sections
|
|
555
|
+
assert.doesNotMatch(call.payload.content, /Structured Return Protocol/);
|
|
556
|
+
assert.doesNotMatch(call.payload.content, /## Active Checkpoint/);
|
|
557
|
+
assert.doesNotMatch(call.payload.content, /## TDD Gate/);
|
|
558
|
+
assert.match(call.payload.content, /find_and_fix/);
|
|
559
|
+
assert.equal(call.options.triggerTurn, true);
|
|
560
|
+
} finally {
|
|
561
|
+
process.chdir(saved);
|
|
562
|
+
rmSync(base, { recursive: true, force: true });
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
test("/gsd debug S03: round-trip — checkpoint with userResponse dispatches response and session transitions to continued", async () => {
|
|
567
|
+
const base = makeBase();
|
|
568
|
+
const saved = process.cwd();
|
|
569
|
+
process.chdir(base);
|
|
570
|
+
|
|
571
|
+
try {
|
|
572
|
+
const ctx = createMockCtx();
|
|
573
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
574
|
+
|
|
575
|
+
const created = createDebugSession(base, { issue: "Cache invalidation race on deploy" });
|
|
576
|
+
const slug = created.session.slug;
|
|
577
|
+
|
|
578
|
+
// Simulate agent setting checkpoint, then user providing a response
|
|
579
|
+
updateDebugSession(base, slug, {
|
|
580
|
+
checkpoint: {
|
|
581
|
+
type: "human-verify",
|
|
582
|
+
summary: "Check whether stale keys appear after deploy",
|
|
583
|
+
awaitingResponse: true,
|
|
584
|
+
userResponse: "Confirmed on staging",
|
|
585
|
+
},
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
await handleDebug(`continue ${slug}`, ctx as any, pi as any);
|
|
589
|
+
|
|
590
|
+
const n = lastNotification(ctx);
|
|
591
|
+
assert.equal(n.level, "info");
|
|
592
|
+
assert.match(n.message, new RegExp(`Resumed debug session: ${slug}`));
|
|
593
|
+
assert.match(n.message, /phase=continued/);
|
|
594
|
+
|
|
595
|
+
assert.equal(calls.length, 1, "should dispatch exactly one message");
|
|
596
|
+
const call = calls[0];
|
|
597
|
+
assert.equal(call.payload.customType, "gsd-debug-continue");
|
|
598
|
+
// userResponse embedded in DATA_START/DATA_END security wrapper
|
|
599
|
+
assert.match(call.payload.content, /DATA_START/);
|
|
600
|
+
assert.match(call.payload.content, /Confirmed on staging/);
|
|
601
|
+
assert.match(call.payload.content, /DATA_END/);
|
|
602
|
+
assert.equal(call.options.triggerTurn, true);
|
|
603
|
+
|
|
604
|
+
// Verify session state persisted to disk after continue
|
|
605
|
+
const reloaded = loadDebugSession(base, slug);
|
|
606
|
+
assert.ok(reloaded, "session should still exist");
|
|
607
|
+
assert.equal(reloaded!.session.phase, "continued");
|
|
608
|
+
assert.equal(reloaded!.session.status, "active");
|
|
609
|
+
} finally {
|
|
610
|
+
process.chdir(saved);
|
|
611
|
+
rmSync(base, { recursive: true, force: true });
|
|
612
|
+
}
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
// ── S04 tests: specialist review dispatch and disk-reload verification ────────
|
|
616
|
+
|
|
617
|
+
test("/gsd debug S04: specialist review round-trip through continue dispatch", async () => {
|
|
618
|
+
const base = makeBase();
|
|
619
|
+
const saved = process.cwd();
|
|
620
|
+
process.chdir(base);
|
|
621
|
+
|
|
622
|
+
try {
|
|
623
|
+
const ctx = createMockCtx();
|
|
624
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
625
|
+
|
|
626
|
+
const created = createDebugSession(base, { issue: "Unsafe type assertion in auth flow" });
|
|
627
|
+
const slug = created.session.slug;
|
|
628
|
+
|
|
629
|
+
// Need checkpoint to trigger debug-session-manager template (which includes specialistContext)
|
|
630
|
+
updateDebugSession(base, slug, {
|
|
631
|
+
checkpoint: {
|
|
632
|
+
type: "human-verify",
|
|
633
|
+
summary: "Verify type guard is safe on all auth paths",
|
|
634
|
+
awaitingResponse: true,
|
|
635
|
+
},
|
|
636
|
+
specialistReview: {
|
|
637
|
+
hint: "typescript",
|
|
638
|
+
skill: "typescript-expert",
|
|
639
|
+
verdict: "SUGGEST_CHANGE (use type guard)",
|
|
640
|
+
detail: "The current implementation uses unsafe type assertion",
|
|
641
|
+
reviewedAt: 1700000000000,
|
|
642
|
+
},
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
await handleDebug(`continue ${slug}`, ctx as any, pi as any);
|
|
646
|
+
|
|
647
|
+
const n = lastNotification(ctx);
|
|
648
|
+
assert.equal(n.level, "info");
|
|
649
|
+
assert.match(n.message, new RegExp(`Resumed debug session: ${slug}`));
|
|
650
|
+
assert.match(n.message, /phase=continued/);
|
|
651
|
+
// Notification must carry specialistHint label
|
|
652
|
+
assert.match(n.message, /specialistHint=typescript/);
|
|
653
|
+
|
|
654
|
+
assert.equal(calls.length, 1, "should dispatch exactly one message");
|
|
655
|
+
const call = calls[0];
|
|
656
|
+
assert.equal(call.payload.customType, "gsd-debug-continue");
|
|
657
|
+
// debug-session-manager template marker confirms correct template was used
|
|
658
|
+
assert.match(call.payload.content, /Structured Return Protocol/);
|
|
659
|
+
// Specialist context embedded in payload
|
|
660
|
+
assert.match(call.payload.content, /Prior Specialist Review/);
|
|
661
|
+
assert.match(call.payload.content, /hint: typescript/);
|
|
662
|
+
assert.match(call.payload.content, /SUGGEST_CHANGE \(use type guard\)/);
|
|
663
|
+
assert.match(call.payload.content, /The current implementation uses unsafe type assertion/);
|
|
664
|
+
assert.equal(call.options.triggerTurn, true);
|
|
665
|
+
} finally {
|
|
666
|
+
process.chdir(saved);
|
|
667
|
+
rmSync(base, { recursive: true, force: true });
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
test("/gsd debug S04: backward compat — session without specialistReview continues normally", async () => {
|
|
672
|
+
const base = makeBase();
|
|
673
|
+
const saved = process.cwd();
|
|
674
|
+
process.chdir(base);
|
|
675
|
+
|
|
676
|
+
try {
|
|
677
|
+
const ctx = createMockCtx();
|
|
678
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
679
|
+
|
|
680
|
+
// Checkpoint-only session — triggers debug-session-manager but has NO specialistReview
|
|
681
|
+
const created = createDebugSession(base, { issue: "Memory leak in event bus" });
|
|
682
|
+
const slug = created.session.slug;
|
|
683
|
+
|
|
684
|
+
updateDebugSession(base, slug, {
|
|
685
|
+
checkpoint: {
|
|
686
|
+
type: "human-verify",
|
|
687
|
+
summary: "Confirm leak disappears after fix",
|
|
688
|
+
awaitingResponse: true,
|
|
689
|
+
},
|
|
690
|
+
});
|
|
691
|
+
|
|
692
|
+
await handleDebug(`continue ${slug}`, ctx as any, pi as any);
|
|
693
|
+
|
|
694
|
+
const n = lastNotification(ctx);
|
|
695
|
+
assert.equal(n.level, "info");
|
|
696
|
+
assert.match(n.message, new RegExp(`Resumed debug session: ${slug}`));
|
|
697
|
+
assert.match(n.message, /phase=continued/);
|
|
698
|
+
// No specialistHint label in notification
|
|
699
|
+
assert.doesNotMatch(n.message, /specialistHint=/);
|
|
700
|
+
|
|
701
|
+
assert.equal(calls.length, 1, "should dispatch exactly one message");
|
|
702
|
+
const call = calls[0];
|
|
703
|
+
assert.equal(call.payload.customType, "gsd-debug-continue");
|
|
704
|
+
// debug-session-manager template is still used (checkpoint triggers it)
|
|
705
|
+
assert.match(call.payload.content, /Structured Return Protocol/);
|
|
706
|
+
// No specialist context section in payload (template's own Specialist Dispatch docs don't count)
|
|
707
|
+
assert.doesNotMatch(call.payload.content, /Prior Specialist Review/);
|
|
708
|
+
assert.equal(call.options.triggerTurn, true);
|
|
709
|
+
} finally {
|
|
710
|
+
process.chdir(saved);
|
|
711
|
+
rmSync(base, { recursive: true, force: true });
|
|
712
|
+
}
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
test("/gsd debug S04: specialist review persists through continue with disk reload", async () => {
|
|
716
|
+
const base = makeBase();
|
|
717
|
+
const saved = process.cwd();
|
|
718
|
+
process.chdir(base);
|
|
719
|
+
|
|
720
|
+
try {
|
|
721
|
+
const ctx = createMockCtx();
|
|
722
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
723
|
+
|
|
724
|
+
const created = createDebugSession(base, { issue: "Race condition in payment finalizer" });
|
|
725
|
+
const slug = created.session.slug;
|
|
726
|
+
|
|
727
|
+
// Checkpoint + specialistReview — continue updates status/phase/lastError but must preserve specialistReview
|
|
728
|
+
updateDebugSession(base, slug, {
|
|
729
|
+
checkpoint: {
|
|
730
|
+
type: "root-cause-found",
|
|
731
|
+
summary: "Race between finalizer and GC hook confirmed",
|
|
732
|
+
awaitingResponse: true,
|
|
733
|
+
},
|
|
734
|
+
specialistReview: {
|
|
735
|
+
hint: "typescript",
|
|
736
|
+
skill: "typescript-expert",
|
|
737
|
+
verdict: "LOOKS_GOOD",
|
|
738
|
+
detail: "WeakRef pattern correctly avoids the GC race",
|
|
739
|
+
reviewedAt: 1700000001000,
|
|
740
|
+
},
|
|
741
|
+
});
|
|
742
|
+
|
|
743
|
+
await handleDebug(`continue ${slug}`, ctx as any, pi as any);
|
|
744
|
+
|
|
745
|
+
assert.equal(calls.length, 1, "should dispatch exactly one message");
|
|
746
|
+
|
|
747
|
+
// Reload the artifact from disk and verify specialistReview survived the handler's updateDebugSession call
|
|
748
|
+
const reloaded = loadDebugSession(base, slug);
|
|
749
|
+
assert.ok(reloaded, "session must still exist on disk after continue");
|
|
750
|
+
assert.equal(reloaded!.session.phase, "continued", "phase must be updated to continued");
|
|
751
|
+
assert.equal(reloaded!.session.status, "active", "status must be active");
|
|
752
|
+
assert.ok(reloaded!.session.specialistReview != null, "specialistReview must be preserved (not wiped by continue)");
|
|
753
|
+
assert.equal(reloaded!.session.specialistReview!.hint, "typescript");
|
|
754
|
+
assert.equal(reloaded!.session.specialistReview!.verdict, "LOOKS_GOOD");
|
|
755
|
+
assert.equal(reloaded!.session.specialistReview!.skill, "typescript-expert");
|
|
756
|
+
} finally {
|
|
757
|
+
process.chdir(saved);
|
|
758
|
+
rmSync(base, { recursive: true, force: true });
|
|
759
|
+
}
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
// ── S05 tests: full lifecycle end-to-end parity ──────────────────────────────
|
|
763
|
+
|
|
764
|
+
test("/gsd debug S05: full happy-path lifecycle — start → list → status → continue → resolve → continue-blocked", async () => {
|
|
765
|
+
const base = makeBase();
|
|
766
|
+
const saved = process.cwd();
|
|
767
|
+
process.chdir(base);
|
|
768
|
+
|
|
769
|
+
try {
|
|
770
|
+
const ctx = createMockCtx();
|
|
771
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
772
|
+
|
|
773
|
+
// 1. Start session
|
|
774
|
+
await handleGSDCommand("debug Widget fails on mobile", ctx as any, {} as any);
|
|
775
|
+
const started = lastNotification(ctx);
|
|
776
|
+
assert.equal(started.level, "info");
|
|
777
|
+
assert.match(started.message, /Debug session started: widget-fails-on-mobile/);
|
|
778
|
+
const slug = "widget-fails-on-mobile";
|
|
779
|
+
|
|
780
|
+
// 2. List shows the new session
|
|
781
|
+
await handleGSDCommand("debug list", ctx as any, {} as any);
|
|
782
|
+
const listed = lastNotification(ctx);
|
|
783
|
+
assert.equal(listed.level, "info");
|
|
784
|
+
assert.match(listed.message, /Debug sessions:/);
|
|
785
|
+
assert.match(listed.message, /widget-fails-on-mobile/);
|
|
786
|
+
assert.match(listed.message, /mode=debug status=active phase=queued/);
|
|
787
|
+
|
|
788
|
+
// 3. Status shows expected fields
|
|
789
|
+
await handleGSDCommand(`debug status ${slug}`, ctx as any, {} as any);
|
|
790
|
+
const status = lastNotification(ctx);
|
|
791
|
+
assert.equal(status.level, "info");
|
|
792
|
+
assert.match(status.message, new RegExp(`^Debug session status: ${slug}`, "m"));
|
|
793
|
+
assert.match(status.message, /^mode=debug$/m);
|
|
794
|
+
assert.match(status.message, /^status=active$/m);
|
|
795
|
+
assert.match(status.message, /^phase=queued$/m);
|
|
796
|
+
|
|
797
|
+
// 4. Continue dispatches find_and_fix goal via debug-diagnose template (no checkpoint/TDD)
|
|
798
|
+
await handleDebug(`continue ${slug}`, ctx as any, pi as any);
|
|
799
|
+
const resumed = lastNotification(ctx);
|
|
800
|
+
assert.equal(resumed.level, "info");
|
|
801
|
+
assert.match(resumed.message, new RegExp(`Resumed debug session: ${slug}`));
|
|
802
|
+
assert.match(resumed.message, /dispatchMode=find_and_fix/);
|
|
803
|
+
|
|
804
|
+
assert.equal(calls.length, 1, "should dispatch exactly one message on continue");
|
|
805
|
+
const call = calls[0];
|
|
806
|
+
assert.equal(call.payload.customType, "gsd-debug-continue");
|
|
807
|
+
assert.match(call.payload.content, /find_and_fix/);
|
|
808
|
+
assert.equal(call.options.triggerTurn, true);
|
|
809
|
+
|
|
810
|
+
// 5. Mark session resolved; clear calls
|
|
811
|
+
updateDebugSession(base, slug, { status: "resolved" });
|
|
812
|
+
calls.length = 0;
|
|
813
|
+
|
|
814
|
+
// 6. Continue on resolved session emits warning and does not dispatch
|
|
815
|
+
await handleDebug(`continue ${slug}`, ctx as any, pi as any);
|
|
816
|
+
const blockedWarning = lastNotification(ctx);
|
|
817
|
+
assert.equal(blockedWarning.level, "warning");
|
|
818
|
+
assert.match(blockedWarning.message, new RegExp(`Session '${slug}' is resolved`));
|
|
819
|
+
assert.equal(calls.length, 0, "no dispatch for resolved session");
|
|
820
|
+
} finally {
|
|
821
|
+
process.chdir(saved);
|
|
822
|
+
rmSync(base, { recursive: true, force: true });
|
|
823
|
+
}
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
test("/gsd debug S05: diagnose-only full lifecycle — start → status(mode=diagnose) → continue uses debug-diagnose template", async () => {
|
|
827
|
+
const base = makeBase();
|
|
828
|
+
const saved = process.cwd();
|
|
829
|
+
process.chdir(base);
|
|
830
|
+
|
|
831
|
+
try {
|
|
832
|
+
const ctx = createMockCtx();
|
|
833
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
834
|
+
|
|
835
|
+
// 1. Start diagnose session via --diagnose <issue>
|
|
836
|
+
await handleDebug("--diagnose Memory leak in worker pool", ctx as any, pi as any);
|
|
837
|
+
const started = lastNotification(ctx);
|
|
838
|
+
assert.equal(started.level, "info");
|
|
839
|
+
assert.match(started.message, /Diagnose session started:/);
|
|
840
|
+
assert.match(started.message, /mode=diagnose/);
|
|
841
|
+
assert.match(started.message, /dispatchMode=find_root_cause_only/);
|
|
842
|
+
|
|
843
|
+
assert.equal(calls.length, 1, "should dispatch exactly one message on diagnose-start");
|
|
844
|
+
const diagnoseCall = calls[0];
|
|
845
|
+
assert.equal(diagnoseCall.payload.customType, "gsd-debug-diagnose");
|
|
846
|
+
assert.match(diagnoseCall.payload.content, /find_root_cause_only/);
|
|
847
|
+
assert.match(diagnoseCall.payload.content, /Memory leak in worker pool/i);
|
|
848
|
+
assert.equal(diagnoseCall.options.triggerTurn, true);
|
|
849
|
+
|
|
850
|
+
const slug = "memory-leak-in-worker-pool";
|
|
851
|
+
|
|
852
|
+
// 2. Status shows mode=diagnose
|
|
853
|
+
await handleGSDCommand(`debug status ${slug}`, ctx as any, {} as any);
|
|
854
|
+
const status = lastNotification(ctx);
|
|
855
|
+
assert.equal(status.level, "info");
|
|
856
|
+
assert.match(status.message, /^mode=diagnose$/m);
|
|
857
|
+
assert.match(status.message, /^status=active$/m);
|
|
858
|
+
|
|
859
|
+
// 3. Continue with no checkpoint/TDD uses debug-diagnose template (no Structured Return Protocol)
|
|
860
|
+
calls.length = 0;
|
|
861
|
+
await handleDebug(`continue ${slug}`, ctx as any, pi as any);
|
|
862
|
+
const resumed = lastNotification(ctx);
|
|
863
|
+
assert.equal(resumed.level, "info");
|
|
864
|
+
assert.match(resumed.message, new RegExp(`Resumed debug session: ${slug}`));
|
|
865
|
+
assert.match(resumed.message, /dispatchMode=find_and_fix/);
|
|
866
|
+
|
|
867
|
+
assert.equal(calls.length, 1, "should dispatch exactly one message on continue");
|
|
868
|
+
const continueCall = calls[0];
|
|
869
|
+
assert.equal(continueCall.payload.customType, "gsd-debug-continue");
|
|
870
|
+
// debug-diagnose template: no Structured Return Protocol (that marker is debug-session-manager only)
|
|
871
|
+
assert.doesNotMatch(continueCall.payload.content, /Structured Return Protocol/);
|
|
872
|
+
assert.match(continueCall.payload.content, /find_and_fix/);
|
|
873
|
+
assert.equal(continueCall.options.triggerTurn, true);
|
|
874
|
+
} finally {
|
|
875
|
+
process.chdir(saved);
|
|
876
|
+
rmSync(base, { recursive: true, force: true });
|
|
877
|
+
}
|
|
878
|
+
});
|
|
879
|
+
|
|
880
|
+
test("/gsd debug S05: TDD full cycle — pending → red → green with disk-reload verification at each phase", async () => {
|
|
881
|
+
const base = makeBase();
|
|
882
|
+
const saved = process.cwd();
|
|
883
|
+
process.chdir(base);
|
|
884
|
+
|
|
885
|
+
try {
|
|
886
|
+
const ctx = createMockCtx();
|
|
887
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
888
|
+
|
|
889
|
+
// Create session and set tddGate to pending
|
|
890
|
+
const created = createDebugSession(base, { issue: "Widget state resets on re-render" });
|
|
891
|
+
const slug = created.session.slug;
|
|
892
|
+
|
|
893
|
+
updateDebugSession(base, slug, {
|
|
894
|
+
tddGate: { enabled: true, phase: "pending" },
|
|
895
|
+
});
|
|
896
|
+
|
|
897
|
+
// Continue with pending: goal = find_root_cause_only, tddGate.phase stays pending
|
|
898
|
+
await handleDebug(`continue ${slug}`, ctx as any, pi as any);
|
|
899
|
+
const pendingNotif = lastNotification(ctx);
|
|
900
|
+
assert.match(pendingNotif.message, /dispatchMode=tddPhase=pending/);
|
|
901
|
+
|
|
902
|
+
assert.equal(calls.length, 1);
|
|
903
|
+
const pendingCall = calls[0];
|
|
904
|
+
assert.match(pendingCall.payload.content, /## Goal\s+`find_root_cause_only`/);
|
|
905
|
+
assert.match(pendingCall.payload.content, /phase: pending/);
|
|
906
|
+
assert.match(pendingCall.payload.content, /Structured Return Protocol/);
|
|
907
|
+
|
|
908
|
+
// Disk-reload: tddGate.phase must remain pending (pending does not advance)
|
|
909
|
+
const afterPending = loadDebugSession(base, slug);
|
|
910
|
+
assert.ok(afterPending, "session must exist after pending continue");
|
|
911
|
+
assert.equal(afterPending!.session.tddGate?.phase, "pending", "pending phase must not advance on disk");
|
|
912
|
+
assert.equal(afterPending!.session.phase, "continued");
|
|
913
|
+
|
|
914
|
+
// Advance to red with test metadata
|
|
915
|
+
updateDebugSession(base, slug, {
|
|
916
|
+
tddGate: { enabled: true, phase: "red", testFile: "widget.test.ts", testName: "resets on re-render" },
|
|
917
|
+
});
|
|
918
|
+
calls.length = 0;
|
|
919
|
+
|
|
920
|
+
// Continue with red: goal = find_and_fix, phase advances to green on disk
|
|
921
|
+
await handleDebug(`continue ${slug}`, ctx as any, pi as any);
|
|
922
|
+
const redNotif = lastNotification(ctx);
|
|
923
|
+
assert.match(redNotif.message, /dispatchMode=tddPhase=red/);
|
|
924
|
+
|
|
925
|
+
assert.equal(calls.length, 1);
|
|
926
|
+
const redCall = calls[0];
|
|
927
|
+
assert.match(redCall.payload.content, /## Goal\s+`find_and_fix`/);
|
|
928
|
+
assert.match(redCall.payload.content, /phase: red/);
|
|
929
|
+
assert.match(redCall.payload.content, /testFile: widget\.test\.ts/);
|
|
930
|
+
assert.match(redCall.payload.content, /testName: resets on re-render/);
|
|
931
|
+
|
|
932
|
+
// Disk-reload: tddGate.phase must advance to green
|
|
933
|
+
const afterRed = loadDebugSession(base, slug);
|
|
934
|
+
assert.ok(afterRed, "session must exist after red continue");
|
|
935
|
+
assert.equal(afterRed!.session.tddGate?.phase, "green", "tddGate.phase must advance red→green on disk");
|
|
936
|
+
assert.equal(afterRed!.session.phase, "continued");
|
|
937
|
+
|
|
938
|
+
calls.length = 0;
|
|
939
|
+
|
|
940
|
+
// Continue with green: goal = find_and_fix, notification shows tddPhase=green
|
|
941
|
+
await handleDebug(`continue ${slug}`, ctx as any, pi as any);
|
|
942
|
+
const greenNotif = lastNotification(ctx);
|
|
943
|
+
assert.match(greenNotif.message, /dispatchMode=tddPhase=green/);
|
|
944
|
+
|
|
945
|
+
assert.equal(calls.length, 1);
|
|
946
|
+
const greenCall = calls[0];
|
|
947
|
+
assert.match(greenCall.payload.content, /## Goal\s+`find_and_fix`/);
|
|
948
|
+
assert.match(greenCall.payload.content, /phase: green/);
|
|
949
|
+
} finally {
|
|
950
|
+
process.chdir(saved);
|
|
951
|
+
rmSync(base, { recursive: true, force: true });
|
|
952
|
+
}
|
|
953
|
+
});
|
|
954
|
+
|
|
955
|
+
test("/gsd debug S05: combined checkpoint + specialist review + TDD gate — all three sections present in dispatch payload", async () => {
|
|
956
|
+
const base = makeBase();
|
|
957
|
+
const saved = process.cwd();
|
|
958
|
+
process.chdir(base);
|
|
959
|
+
|
|
960
|
+
try {
|
|
961
|
+
const ctx = createMockCtx();
|
|
962
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
963
|
+
|
|
964
|
+
const created = createDebugSession(base, { issue: "Widget render loop detected" });
|
|
965
|
+
const slug = created.session.slug;
|
|
966
|
+
|
|
967
|
+
// Set all three enrichment fields simultaneously
|
|
968
|
+
updateDebugSession(base, slug, {
|
|
969
|
+
checkpoint: {
|
|
970
|
+
type: "root-cause-found",
|
|
971
|
+
summary: "Confirmed infinite re-render due to unstable reference",
|
|
972
|
+
awaitingResponse: true,
|
|
973
|
+
},
|
|
974
|
+
specialistReview: {
|
|
975
|
+
hint: "typescript",
|
|
976
|
+
skill: "typescript-expert",
|
|
977
|
+
verdict: "SUGGEST_CHANGE",
|
|
978
|
+
detail: "Use useMemo to stabilize the reference",
|
|
979
|
+
reviewedAt: 1700000002000,
|
|
980
|
+
},
|
|
981
|
+
tddGate: {
|
|
982
|
+
enabled: true,
|
|
983
|
+
phase: "red",
|
|
984
|
+
testFile: "widget.test.ts",
|
|
985
|
+
testName: "does not loop on stable props",
|
|
986
|
+
},
|
|
987
|
+
});
|
|
988
|
+
|
|
989
|
+
await handleDebug(`continue ${slug}`, ctx as any, pi as any);
|
|
990
|
+
|
|
991
|
+
const n = lastNotification(ctx);
|
|
992
|
+
assert.equal(n.level, "info");
|
|
993
|
+
assert.match(n.message, new RegExp(`Resumed debug session: ${slug}`));
|
|
994
|
+
assert.match(n.message, /phase=continued/);
|
|
995
|
+
// Notification must carry both tddPhase and specialistHint labels
|
|
996
|
+
assert.match(n.message, /specialistHint=typescript/);
|
|
997
|
+
assert.match(n.message, /tddPhase=red/);
|
|
998
|
+
|
|
999
|
+
assert.equal(calls.length, 1, "should dispatch exactly one message");
|
|
1000
|
+
const call = calls[0];
|
|
1001
|
+
assert.equal(call.payload.customType, "gsd-debug-continue");
|
|
1002
|
+
// debug-session-manager template marker
|
|
1003
|
+
assert.match(call.payload.content, /Structured Return Protocol/);
|
|
1004
|
+
// Active Checkpoint section
|
|
1005
|
+
assert.match(call.payload.content, /## Active Checkpoint/);
|
|
1006
|
+
assert.match(call.payload.content, /type: root-cause-found/);
|
|
1007
|
+
// Prior Specialist Review section (heading, not content values)
|
|
1008
|
+
assert.match(call.payload.content, /Prior Specialist Review/);
|
|
1009
|
+
assert.match(call.payload.content, /hint: typescript/);
|
|
1010
|
+
// TDD Gate section
|
|
1011
|
+
assert.match(call.payload.content, /## TDD Gate/);
|
|
1012
|
+
assert.match(call.payload.content, /phase: red/);
|
|
1013
|
+
assert.match(call.payload.content, /testFile: widget\.test\.ts/);
|
|
1014
|
+
assert.equal(call.options.triggerTurn, true);
|
|
1015
|
+
|
|
1016
|
+
// Disk-reload: tddGate.phase must advance red→green
|
|
1017
|
+
const reloaded = loadDebugSession(base, slug);
|
|
1018
|
+
assert.ok(reloaded, "session must exist after combined continue");
|
|
1019
|
+
assert.equal(reloaded!.session.tddGate?.phase, "green", "tddGate.phase must advance red→green on disk");
|
|
1020
|
+
assert.equal(reloaded!.session.phase, "continued");
|
|
1021
|
+
// specialistReview must be preserved
|
|
1022
|
+
assert.ok(reloaded!.session.specialistReview != null, "specialistReview must be preserved after continue");
|
|
1023
|
+
assert.equal(reloaded!.session.specialistReview!.hint, "typescript");
|
|
1024
|
+
} finally {
|
|
1025
|
+
process.chdir(saved);
|
|
1026
|
+
rmSync(base, { recursive: true, force: true });
|
|
1027
|
+
}
|
|
1028
|
+
});
|
|
1029
|
+
|
|
1030
|
+
test("/gsd debug S05: multi-session concurrent lifecycle — 3 sessions continue independently and list shows all as continued", async () => {
|
|
1031
|
+
const base = makeBase();
|
|
1032
|
+
const saved = process.cwd();
|
|
1033
|
+
process.chdir(base);
|
|
1034
|
+
|
|
1035
|
+
try {
|
|
1036
|
+
const ctx = createMockCtx();
|
|
1037
|
+
|
|
1038
|
+
// Start 3 sessions via handleGSDCommand
|
|
1039
|
+
await handleGSDCommand("debug Auth token expires silently", ctx as any, {} as any);
|
|
1040
|
+
assert.match(lastNotification(ctx).message, /Debug session started: auth-token-expires-silently/);
|
|
1041
|
+
|
|
1042
|
+
await handleGSDCommand("debug Cache misses on cold start", ctx as any, {} as any);
|
|
1043
|
+
assert.match(lastNotification(ctx).message, /Debug session started: cache-misses-on-cold-start/);
|
|
1044
|
+
|
|
1045
|
+
await handleGSDCommand("debug Payment webhook drops under load", ctx as any, {} as any);
|
|
1046
|
+
assert.match(lastNotification(ctx).message, /Debug session started: payment-webhook-drops-under-load/);
|
|
1047
|
+
|
|
1048
|
+
// Continue each session separately with its own dispatch mock
|
|
1049
|
+
const { calls: calls1, pi: pi1 } = createMockPiWithDispatch();
|
|
1050
|
+
await handleDebug("continue auth-token-expires-silently", ctx as any, pi1 as any);
|
|
1051
|
+
assert.equal(calls1.length, 1, "session 1 should dispatch exactly one message");
|
|
1052
|
+
// Content must reference session 1's slug, not the others
|
|
1053
|
+
assert.match(calls1[0].payload.content, /auth-token-expires-silently/);
|
|
1054
|
+
assert.doesNotMatch(calls1[0].payload.content, /cache-misses-on-cold-start/);
|
|
1055
|
+
assert.doesNotMatch(calls1[0].payload.content, /payment-webhook-drops-under-load/);
|
|
1056
|
+
|
|
1057
|
+
const { calls: calls2, pi: pi2 } = createMockPiWithDispatch();
|
|
1058
|
+
await handleDebug("continue cache-misses-on-cold-start", ctx as any, pi2 as any);
|
|
1059
|
+
assert.equal(calls2.length, 1, "session 2 should dispatch exactly one message");
|
|
1060
|
+
assert.match(calls2[0].payload.content, /cache-misses-on-cold-start/);
|
|
1061
|
+
assert.doesNotMatch(calls2[0].payload.content, /auth-token-expires-silently/);
|
|
1062
|
+
|
|
1063
|
+
const { calls: calls3, pi: pi3 } = createMockPiWithDispatch();
|
|
1064
|
+
await handleDebug("continue payment-webhook-drops-under-load", ctx as any, pi3 as any);
|
|
1065
|
+
assert.equal(calls3.length, 1, "session 3 should dispatch exactly one message");
|
|
1066
|
+
assert.match(calls3[0].payload.content, /payment-webhook-drops-under-load/);
|
|
1067
|
+
assert.doesNotMatch(calls3[0].payload.content, /auth-token-expires-silently/);
|
|
1068
|
+
|
|
1069
|
+
// debug list must show all 3 as phase=continued
|
|
1070
|
+
await handleGSDCommand("debug list", ctx as any, {} as any);
|
|
1071
|
+
const listed = lastNotification(ctx);
|
|
1072
|
+
assert.equal(listed.level, "info");
|
|
1073
|
+
assert.match(listed.message, /auth-token-expires-silently/);
|
|
1074
|
+
assert.match(listed.message, /cache-misses-on-cold-start/);
|
|
1075
|
+
assert.match(listed.message, /payment-webhook-drops-under-load/);
|
|
1076
|
+
assert.match(listed.message, /phase=continued/);
|
|
1077
|
+
} finally {
|
|
1078
|
+
process.chdir(saved);
|
|
1079
|
+
rmSync(base, { recursive: true, force: true });
|
|
1080
|
+
}
|
|
1081
|
+
});
|
|
1082
|
+
|
|
1083
|
+
test("/gsd debug S05: resolved session blocks continue via dispatcher route — warning emitted, zero dispatches", async () => {
|
|
1084
|
+
const base = makeBase();
|
|
1085
|
+
const saved = process.cwd();
|
|
1086
|
+
process.chdir(base);
|
|
1087
|
+
|
|
1088
|
+
try {
|
|
1089
|
+
const ctx = createMockCtx();
|
|
1090
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
1091
|
+
|
|
1092
|
+
// Start session via handleGSDCommand (dispatcher route)
|
|
1093
|
+
await handleGSDCommand("debug Stale lock file blocks deploy", ctx as any, {} as any);
|
|
1094
|
+
const started = lastNotification(ctx);
|
|
1095
|
+
assert.equal(started.level, "info");
|
|
1096
|
+
assert.match(started.message, /Debug session started: stale-lock-file-blocks-deploy/);
|
|
1097
|
+
const slug = "stale-lock-file-blocks-deploy";
|
|
1098
|
+
|
|
1099
|
+
// Mark as resolved via store API
|
|
1100
|
+
updateDebugSession(base, slug, { status: "resolved" });
|
|
1101
|
+
|
|
1102
|
+
// Attempt continue via dispatcher route (handleGSDCommand, not handleDebug directly)
|
|
1103
|
+
await handleGSDCommand(`debug continue ${slug}`, ctx as any, pi as any);
|
|
1104
|
+
|
|
1105
|
+
const warned = lastNotification(ctx);
|
|
1106
|
+
assert.equal(warned.level, "warning");
|
|
1107
|
+
assert.match(warned.message, new RegExp(`Session '${slug}' is resolved`));
|
|
1108
|
+
// Zero dispatch calls — guard must fire before sendMessage
|
|
1109
|
+
assert.equal(calls.length, 0, "no dispatch for resolved session via dispatcher route");
|
|
1110
|
+
} finally {
|
|
1111
|
+
process.chdir(saved);
|
|
1112
|
+
rmSync(base, { recursive: true, force: true });
|
|
1113
|
+
}
|
|
1114
|
+
});
|
|
1115
|
+
|
|
1116
|
+
test("/gsd debug S05: TDD gate green-phase continue dispatches find_and_fix with green context and 'test is now passing' text", async () => {
|
|
1117
|
+
const base = makeBase();
|
|
1118
|
+
const saved = process.cwd();
|
|
1119
|
+
process.chdir(base);
|
|
1120
|
+
|
|
1121
|
+
try {
|
|
1122
|
+
const ctx = createMockCtx();
|
|
1123
|
+
const { calls, pi } = createMockPiWithDispatch();
|
|
1124
|
+
|
|
1125
|
+
const created = createDebugSession(base, { issue: "Button click handler fires twice" });
|
|
1126
|
+
const slug = created.session.slug;
|
|
1127
|
+
|
|
1128
|
+
// Set tddGate directly to green (simulating that red phase was already completed)
|
|
1129
|
+
updateDebugSession(base, slug, {
|
|
1130
|
+
tddGate: {
|
|
1131
|
+
enabled: true,
|
|
1132
|
+
phase: "green",
|
|
1133
|
+
testFile: "button.test.ts",
|
|
1134
|
+
testName: "fires handler once per click",
|
|
1135
|
+
},
|
|
1136
|
+
});
|
|
1137
|
+
|
|
1138
|
+
await handleDebug(`continue ${slug}`, ctx as any, pi as any);
|
|
1139
|
+
|
|
1140
|
+
const n = lastNotification(ctx);
|
|
1141
|
+
assert.equal(n.level, "info");
|
|
1142
|
+
assert.match(n.message, new RegExp(`Resumed debug session: ${slug}`));
|
|
1143
|
+
assert.match(n.message, /phase=continued/);
|
|
1144
|
+
assert.match(n.message, /dispatchMode=tddPhase=green/);
|
|
1145
|
+
|
|
1146
|
+
assert.equal(calls.length, 1, "should dispatch exactly one message");
|
|
1147
|
+
const call = calls[0];
|
|
1148
|
+
assert.equal(call.payload.customType, "gsd-debug-continue");
|
|
1149
|
+
// find_and_fix goal for green phase
|
|
1150
|
+
assert.match(call.payload.content, /## Goal\s+`find_and_fix`/);
|
|
1151
|
+
// TDD Gate section with green phase
|
|
1152
|
+
assert.match(call.payload.content, /## TDD Gate/);
|
|
1153
|
+
assert.match(call.payload.content, /phase: green/);
|
|
1154
|
+
// "The test is now passing" text emitted by the handler for green phase
|
|
1155
|
+
assert.match(call.payload.content, /The test is now passing/);
|
|
1156
|
+
// test metadata present
|
|
1157
|
+
assert.match(call.payload.content, /testFile: button\.test\.ts/);
|
|
1158
|
+
assert.match(call.payload.content, /testName: fires handler once per click/);
|
|
1159
|
+
assert.equal(call.options.triggerTurn, true);
|
|
1160
|
+
|
|
1161
|
+
// Disk-reload: session persisted correctly
|
|
1162
|
+
const reloaded = loadDebugSession(base, slug);
|
|
1163
|
+
assert.ok(reloaded, "session must exist after green continue");
|
|
1164
|
+
assert.equal(reloaded!.session.phase, "continued");
|
|
1165
|
+
assert.equal(reloaded!.session.tddGate?.phase, "green", "green phase must remain green (no further advance)");
|
|
1166
|
+
} finally {
|
|
1167
|
+
process.chdir(saved);
|
|
1168
|
+
rmSync(base, { recursive: true, force: true });
|
|
1169
|
+
}
|
|
1170
|
+
});
|
|
1171
|
+
|
|
1172
|
+
test("/gsd debug S05: dispatch failure resilience — sendMessage throws, session remains resumable and retry succeeds", async () => {
|
|
1173
|
+
const base = makeBase();
|
|
1174
|
+
const saved = process.cwd();
|
|
1175
|
+
process.chdir(base);
|
|
1176
|
+
|
|
1177
|
+
try {
|
|
1178
|
+
const ctx = createMockCtx();
|
|
1179
|
+
|
|
1180
|
+
// Create session with checkpoint to engage debug-session-manager template
|
|
1181
|
+
const created = createDebugSession(base, { issue: "Payment processor timeout on retry" });
|
|
1182
|
+
const slug = created.session.slug;
|
|
1183
|
+
|
|
1184
|
+
updateDebugSession(base, slug, {
|
|
1185
|
+
checkpoint: {
|
|
1186
|
+
type: "human-verify",
|
|
1187
|
+
summary: "Confirm retry logic terminates",
|
|
1188
|
+
awaitingResponse: true,
|
|
1189
|
+
},
|
|
1190
|
+
});
|
|
1191
|
+
|
|
1192
|
+
// Mock pi whose sendMessage always throws
|
|
1193
|
+
const throwingPi = {
|
|
1194
|
+
sendMessage(_payload: any, _options: any) {
|
|
1195
|
+
throw new Error("Network error: sendMessage failed");
|
|
1196
|
+
},
|
|
1197
|
+
};
|
|
1198
|
+
|
|
1199
|
+
await handleDebug(`continue ${slug}`, ctx as any, throwingPi as any);
|
|
1200
|
+
|
|
1201
|
+
// Warning notification about dispatch failure (emitted after the session-update info notification)
|
|
1202
|
+
const failNotif = lastNotification(ctx);
|
|
1203
|
+
assert.equal(failNotif.level, "warning");
|
|
1204
|
+
assert.match(failNotif.message, /Continue dispatch failed/);
|
|
1205
|
+
assert.match(failNotif.message, new RegExp(slug));
|
|
1206
|
+
|
|
1207
|
+
// Session must be persisted with phase=continued (state is updated before dispatch attempt)
|
|
1208
|
+
const reloaded = loadDebugSession(base, slug);
|
|
1209
|
+
assert.ok(reloaded, "session must still exist on disk after dispatch failure");
|
|
1210
|
+
assert.equal(reloaded!.session.phase, "continued", "phase must be continued despite failed dispatch");
|
|
1211
|
+
assert.equal(reloaded!.session.status, "active");
|
|
1212
|
+
|
|
1213
|
+
// Retry with a working mock pi succeeds
|
|
1214
|
+
const { calls: retryCalls, pi: workingPi } = createMockPiWithDispatch();
|
|
1215
|
+
await handleDebug(`continue ${slug}`, ctx as any, workingPi as any);
|
|
1216
|
+
|
|
1217
|
+
const retryNotif = lastNotification(ctx);
|
|
1218
|
+
assert.equal(retryNotif.level, "info");
|
|
1219
|
+
assert.match(retryNotif.message, new RegExp(`Resumed debug session: ${slug}`));
|
|
1220
|
+
|
|
1221
|
+
assert.equal(retryCalls.length, 1, "retry should dispatch exactly one message");
|
|
1222
|
+
const retryCall = retryCalls[0];
|
|
1223
|
+
assert.equal(retryCall.payload.customType, "gsd-debug-continue");
|
|
1224
|
+
assert.equal(retryCall.options.triggerTurn, true);
|
|
1225
|
+
} finally {
|
|
1226
|
+
process.chdir(saved);
|
|
1227
|
+
rmSync(base, { recursive: true, force: true });
|
|
1228
|
+
}
|
|
1229
|
+
});
|