gsd-pi 2.59.0 → 2.60.0-dev.2580e65
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/dist/resources/extensions/ask-user-questions.js +7 -4
- package/dist/resources/extensions/gsd/auto/phases.js +62 -1
- package/dist/resources/extensions/gsd/auto-dashboard.js +21 -8
- package/dist/resources/extensions/gsd/auto-dispatch.js +6 -3
- package/dist/resources/extensions/gsd/auto-model-selection.js +57 -3
- package/dist/resources/extensions/gsd/auto-post-unit.js +43 -3
- package/dist/resources/extensions/gsd/auto-prompts.js +49 -20
- package/dist/resources/extensions/gsd/auto-recovery.js +37 -18
- package/dist/resources/extensions/gsd/auto-start.js +9 -5
- package/dist/resources/extensions/gsd/auto-timers.js +11 -5
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +5 -3
- package/dist/resources/extensions/gsd/auto-verification.js +3 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +120 -55
- package/dist/resources/extensions/gsd/auto.js +39 -17
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +6 -3
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +72 -2
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +4 -10
- package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +2 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +58 -5
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +11 -10
- package/dist/resources/extensions/gsd/captures.js +54 -1
- package/dist/resources/extensions/gsd/commands/catalog.js +2 -0
- package/dist/resources/extensions/gsd/commands-codebase.js +48 -21
- package/dist/resources/extensions/gsd/commands-inspect.js +2 -1
- package/dist/resources/extensions/gsd/commands-maintenance.js +32 -19
- package/dist/resources/extensions/gsd/complexity-classifier.js +9 -5
- package/dist/resources/extensions/gsd/context-masker.js +68 -0
- package/dist/resources/extensions/gsd/custom-verification.js +3 -2
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +7 -0
- package/dist/resources/extensions/gsd/gsd-db.js +35 -15
- package/dist/resources/extensions/gsd/guided-flow.js +19 -9
- package/dist/resources/extensions/gsd/init-wizard.js +12 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +11 -9
- package/dist/resources/extensions/gsd/md-importer.js +5 -4
- package/dist/resources/extensions/gsd/milestone-actions.js +3 -2
- package/dist/resources/extensions/gsd/milestone-ids.js +2 -1
- package/dist/resources/extensions/gsd/model-router.js +199 -45
- package/dist/resources/extensions/gsd/parallel-merge.js +5 -3
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +26 -14
- package/dist/resources/extensions/gsd/phase-anchor.js +56 -0
- package/dist/resources/extensions/gsd/preferences-types.js +2 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +91 -0
- package/dist/resources/extensions/gsd/preferences.js +15 -3
- package/dist/resources/extensions/gsd/prompt-loader.js +3 -2
- package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/dist/resources/extensions/gsd/prompts/rethink.md +7 -0
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +6 -1
- package/dist/resources/extensions/gsd/rethink.js +5 -2
- package/dist/resources/extensions/gsd/rule-registry.js +7 -6
- package/dist/resources/extensions/gsd/safe-fs.js +6 -8
- package/dist/resources/extensions/gsd/state.js +1 -1
- package/dist/resources/extensions/gsd/status-guards.js +4 -3
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
- package/dist/resources/extensions/gsd/tools/complete-slice.js +3 -2
- package/dist/resources/extensions/gsd/tools/complete-task.js +3 -2
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +3 -2
- package/dist/resources/extensions/gsd/tools/plan-slice.js +3 -2
- package/dist/resources/extensions/gsd/tools/plan-task.js +2 -1
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +4 -4
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -1
- package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -1
- package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -1
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +2 -1
- package/dist/resources/extensions/gsd/triage-resolution.js +135 -1
- package/dist/resources/extensions/gsd/triage-ui.js +12 -3
- package/dist/resources/extensions/gsd/workflow-events.js +2 -1
- package/dist/resources/extensions/gsd/workflow-logger.js +37 -4
- package/dist/resources/extensions/gsd/workflow-migration.js +14 -12
- package/dist/resources/extensions/gsd/workflow-projections.js +2 -2
- package/dist/resources/extensions/gsd/workflow-reconcile.js +2 -2
- package/dist/resources/extensions/gsd/worktree-manager.js +26 -14
- package/dist/resources/extensions/shared/interview-ui.js +3 -1
- package/dist/resources/skills/btw/SKILL.md +42 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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 +3 -3
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- 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 +4 -4
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- 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 +17 -17
- package/dist/web/standalone/.next/server/chunks/2229.js +1 -1
- package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/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/package.json +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 +5 -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 +2 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +16 -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 +26 -0
- 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/lsp/config.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/config.js +6 -1
- package/packages/pi-coding-agent/dist/core/lsp/config.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/defaults.json +2 -2
- package/packages/pi-coding-agent/dist/core/lsp/lsp-legacy-alias.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/lsp/lsp-legacy-alias.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/lsp-legacy-alias.test.js +47 -0
- package/packages/pi-coding-agent/dist/core/lsp/lsp-legacy-alias.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +6 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +122 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +30 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +1 -7
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +6 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +19 -0
- package/packages/pi-coding-agent/src/core/extensions/types.ts +26 -0
- package/packages/pi-coding-agent/src/core/lsp/config.ts +7 -1
- package/packages/pi-coding-agent/src/core/lsp/defaults.json +2 -2
- package/packages/pi-coding-agent/src/core/lsp/lsp-legacy-alias.test.ts +70 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +156 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +7 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +38 -0
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +1 -8
- package/pkg/package.json +1 -1
- package/src/resources/extensions/ask-user-questions.ts +7 -3
- package/src/resources/extensions/gsd/auto/phases.ts +70 -1
- package/src/resources/extensions/gsd/auto-dashboard.ts +22 -8
- package/src/resources/extensions/gsd/auto-dispatch.ts +7 -3
- package/src/resources/extensions/gsd/auto-model-selection.ts +77 -6
- package/src/resources/extensions/gsd/auto-post-unit.ts +52 -5
- package/src/resources/extensions/gsd/auto-prompts.ts +54 -20
- package/src/resources/extensions/gsd/auto-recovery.ts +38 -18
- package/src/resources/extensions/gsd/auto-start.ts +10 -9
- package/src/resources/extensions/gsd/auto-timers.ts +12 -5
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +6 -2
- package/src/resources/extensions/gsd/auto-verification.ts +3 -6
- package/src/resources/extensions/gsd/auto-worktree.ts +121 -55
- package/src/resources/extensions/gsd/auto.ts +40 -17
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +4 -3
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +80 -2
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +4 -16
- package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +2 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +61 -4
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +11 -10
- package/src/resources/extensions/gsd/captures.ts +71 -2
- package/src/resources/extensions/gsd/commands/catalog.ts +2 -0
- package/src/resources/extensions/gsd/commands-codebase.ts +52 -20
- package/src/resources/extensions/gsd/commands-inspect.ts +2 -1
- package/src/resources/extensions/gsd/commands-maintenance.ts +28 -19
- package/src/resources/extensions/gsd/complexity-classifier.ts +10 -5
- package/src/resources/extensions/gsd/context-masker.ts +74 -0
- package/src/resources/extensions/gsd/custom-verification.ts +3 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +7 -0
- package/src/resources/extensions/gsd/gsd-db.ts +14 -16
- package/src/resources/extensions/gsd/guided-flow.ts +9 -8
- package/src/resources/extensions/gsd/init-wizard.ts +12 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +11 -17
- package/src/resources/extensions/gsd/md-importer.ts +5 -4
- package/src/resources/extensions/gsd/milestone-actions.ts +3 -2
- package/src/resources/extensions/gsd/milestone-ids.ts +2 -1
- package/src/resources/extensions/gsd/model-router.ts +245 -56
- package/src/resources/extensions/gsd/parallel-merge.ts +5 -3
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +18 -14
- package/src/resources/extensions/gsd/phase-anchor.ts +71 -0
- package/src/resources/extensions/gsd/preferences-types.ts +22 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +83 -0
- package/src/resources/extensions/gsd/preferences.ts +16 -3
- package/src/resources/extensions/gsd/prompt-loader.ts +3 -2
- package/src/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/src/resources/extensions/gsd/prompts/rethink.md +7 -0
- package/src/resources/extensions/gsd/prompts/triage-captures.md +6 -1
- package/src/resources/extensions/gsd/rethink.ts +5 -2
- package/src/resources/extensions/gsd/rule-registry.ts +7 -6
- package/src/resources/extensions/gsd/safe-fs.ts +6 -5
- package/src/resources/extensions/gsd/state.ts +1 -1
- package/src/resources/extensions/gsd/status-guards.ts +4 -3
- package/src/resources/extensions/gsd/tests/capability-router.test.ts +347 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/complexity-classifier.test.ts +27 -2
- package/src/resources/extensions/gsd/tests/context-masker.test.ts +122 -0
- package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +1188 -0
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +841 -0
- package/src/resources/extensions/gsd/tests/model-router.test.ts +488 -2
- package/src/resources/extensions/gsd/tests/phase-anchor.test.ts +83 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/remote-questions.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +284 -0
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/stop-backtrack.test.ts +216 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/workflow-logger-audit.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +6 -6
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -6
- package/src/resources/extensions/gsd/tools/complete-slice.ts +3 -6
- package/src/resources/extensions/gsd/tools/complete-task.ts +3 -6
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +3 -6
- package/src/resources/extensions/gsd/tools/plan-slice.ts +3 -6
- package/src/resources/extensions/gsd/tools/plan-task.ts +2 -3
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +4 -6
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -3
- package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -3
- package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -3
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +2 -3
- package/src/resources/extensions/gsd/triage-resolution.ts +151 -1
- package/src/resources/extensions/gsd/triage-ui.ts +12 -3
- package/src/resources/extensions/gsd/types.ts +1 -0
- package/src/resources/extensions/gsd/workflow-events.ts +2 -1
- package/src/resources/extensions/gsd/workflow-logger.ts +52 -5
- package/src/resources/extensions/gsd/workflow-migration.ts +14 -12
- package/src/resources/extensions/gsd/workflow-projections.ts +2 -2
- package/src/resources/extensions/gsd/workflow-reconcile.ts +2 -2
- package/src/resources/extensions/gsd/worktree-manager.ts +16 -14
- package/src/resources/extensions/shared/interview-ui.ts +3 -1
- package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +144 -0
- package/src/resources/skills/btw/SKILL.md +42 -0
- package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- /package/dist/web/standalone/.next/static/{DGvT_c5Vb7Wu3X-fEOVUU → ogyMN7M-3bGGuRY08L5HR}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{DGvT_c5Vb7Wu3X-fEOVUU → ogyMN7M-3bGGuRY08L5HR}/_ssgManifest.js +0 -0
|
@@ -7,6 +7,7 @@ import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
|
7
7
|
import { join } from "node:path";
|
|
8
8
|
import { _getAdapter, transaction } from "./gsd-db.js";
|
|
9
9
|
import { parseRoadmap, parsePlan } from "./parsers-legacy.js";
|
|
10
|
+
import { logWarning } from "./workflow-logger.js";
|
|
10
11
|
|
|
11
12
|
// ─── needsAutoMigration ───────────────────────────────────────────────────
|
|
12
13
|
|
|
@@ -23,8 +24,8 @@ export function needsAutoMigration(basePath: string): boolean {
|
|
|
23
24
|
try {
|
|
24
25
|
const row = db.prepare("SELECT COUNT(*) as cnt FROM milestones").get();
|
|
25
26
|
if (row && (row["cnt"] as number) > 0) return false;
|
|
26
|
-
} catch {
|
|
27
|
-
|
|
27
|
+
} catch (e) {
|
|
28
|
+
logWarning("migration", `DB probe failed: ${(e as Error).message}`);
|
|
28
29
|
return false;
|
|
29
30
|
}
|
|
30
31
|
|
|
@@ -71,7 +72,7 @@ export function migrateFromMarkdown(basePath: string): void {
|
|
|
71
72
|
.filter(e => e.isDirectory())
|
|
72
73
|
.map(e => e.name);
|
|
73
74
|
} catch {
|
|
74
|
-
|
|
75
|
+
logWarning("migration", "failed to read milestones directory");
|
|
75
76
|
return;
|
|
76
77
|
}
|
|
77
78
|
|
|
@@ -141,7 +142,7 @@ export function migrateFromMarkdown(basePath: string): void {
|
|
|
141
142
|
risk: s.risk || "low",
|
|
142
143
|
}));
|
|
143
144
|
} catch (err) {
|
|
144
|
-
|
|
145
|
+
logWarning("migration", `failed to parse ROADMAP.md for ${mId}: ${(err as Error).message}`);
|
|
145
146
|
// Still add milestone with ID as title
|
|
146
147
|
milestoneInserts.push({ id: mId, title: mId, status: milestoneStatus });
|
|
147
148
|
}
|
|
@@ -191,7 +192,7 @@ export function migrateFromMarkdown(basePath: string): void {
|
|
|
191
192
|
});
|
|
192
193
|
}
|
|
193
194
|
} catch (err) {
|
|
194
|
-
|
|
195
|
+
logWarning("migration", `failed to parse ${slice.id}-PLAN.md for ${mId}: ${(err as Error).message}`);
|
|
195
196
|
}
|
|
196
197
|
}
|
|
197
198
|
}
|
|
@@ -206,8 +207,8 @@ export function migrateFromMarkdown(basePath: string): void {
|
|
|
206
207
|
process.stderr.write(`workflow-migration: orphaned summary file ${summaryFile} in ${mId} (slice not found in ROADMAP.md), skipping\n`);
|
|
207
208
|
}
|
|
208
209
|
}
|
|
209
|
-
} catch {
|
|
210
|
-
|
|
210
|
+
} catch (e) {
|
|
211
|
+
logWarning("migration", `Orphaned summary check failed for ${mId}: ${(e as Error).message}`);
|
|
211
212
|
}
|
|
212
213
|
}
|
|
213
214
|
|
|
@@ -308,17 +309,18 @@ export function validateMigration(basePath: string): { discrepancies: string[] }
|
|
|
308
309
|
const planContent = readFileSync(planPath, "utf-8");
|
|
309
310
|
const plan = parsePlan(planContent);
|
|
310
311
|
mdTaskCount += plan.tasks.length;
|
|
311
|
-
} catch {
|
|
312
|
-
|
|
312
|
+
} catch (e) {
|
|
313
|
+
logWarning("migration", `Failed to read plan ${slice.id}-PLAN.md: ${(e as Error).message}`);
|
|
313
314
|
}
|
|
314
315
|
}
|
|
315
316
|
}
|
|
316
|
-
} catch {
|
|
317
|
-
|
|
317
|
+
} catch (e) {
|
|
318
|
+
logWarning("migration", `Failed to read roadmap for ${mId}: ${(e as Error).message}`);
|
|
318
319
|
}
|
|
319
320
|
}
|
|
320
321
|
}
|
|
321
|
-
} catch {
|
|
322
|
+
} catch (e) {
|
|
323
|
+
logWarning("migration", `Validation failed to read markdown: ${(e as Error).message}`);
|
|
322
324
|
return { discrepancies: ["Failed to read markdown for validation"] };
|
|
323
325
|
}
|
|
324
326
|
|
|
@@ -423,7 +423,7 @@ export function regenerateIfMissing(
|
|
|
423
423
|
renderSummaryProjection(basePath, milestoneId, sliceId, task.id);
|
|
424
424
|
regenerated++;
|
|
425
425
|
} catch (err) {
|
|
426
|
-
|
|
426
|
+
logWarning("projection", `regenerateIfMissing SUMMARY failed for ${task.id}: ${(err as Error).message}`);
|
|
427
427
|
}
|
|
428
428
|
}
|
|
429
429
|
}
|
|
@@ -452,7 +452,7 @@ export function regenerateIfMissing(
|
|
|
452
452
|
}
|
|
453
453
|
return true;
|
|
454
454
|
} catch (err) {
|
|
455
|
-
|
|
455
|
+
logWarning("projection", `regenerateIfMissing ${fileType} failed: ${(err as Error).message}`);
|
|
456
456
|
return false;
|
|
457
457
|
}
|
|
458
458
|
}
|
|
@@ -455,8 +455,8 @@ function parseEventBlock(block: string): WorkflowEvent[] {
|
|
|
455
455
|
if (paramsMatch) {
|
|
456
456
|
try {
|
|
457
457
|
params = JSON.parse(paramsMatch[1]!) as Record<string, unknown>;
|
|
458
|
-
} catch {
|
|
459
|
-
|
|
458
|
+
} catch (e) {
|
|
459
|
+
logWarning("reconcile", `tool call params parse failed: ${(e as Error).message}`);
|
|
460
460
|
}
|
|
461
461
|
i++; // consume params line
|
|
462
462
|
}
|
|
@@ -95,8 +95,8 @@ export function resolveGitDir(basePath: string): string {
|
|
|
95
95
|
if (content.startsWith("gitdir: ")) {
|
|
96
96
|
return resolve(basePath, content.slice(8));
|
|
97
97
|
}
|
|
98
|
-
} catch {
|
|
99
|
-
|
|
98
|
+
} catch (e) {
|
|
99
|
+
logWarning("worktree", `.git file read failed: ${(e as Error).message}`);
|
|
100
100
|
}
|
|
101
101
|
return join(basePath, ".git");
|
|
102
102
|
}
|
|
@@ -308,8 +308,9 @@ export function findNestedGitDirs(rootPath: string): string[] {
|
|
|
308
308
|
let entries: string[];
|
|
309
309
|
try {
|
|
310
310
|
entries = readdirSync(dir);
|
|
311
|
-
} catch {
|
|
312
|
-
|
|
311
|
+
} catch (e) {
|
|
312
|
+
logWarning("worktree", `readdirSync failed: ${(e as Error).message}`);
|
|
313
|
+
return;
|
|
313
314
|
}
|
|
314
315
|
|
|
315
316
|
for (const entry of entries) {
|
|
@@ -321,7 +322,8 @@ export function findNestedGitDirs(rootPath: string): string[] {
|
|
|
321
322
|
let stat;
|
|
322
323
|
try {
|
|
323
324
|
stat = lstatSync(fullPath);
|
|
324
|
-
} catch {
|
|
325
|
+
} catch (e) {
|
|
326
|
+
logWarning("worktree", `lstatSync failed for ${fullPath}: ${(e as Error).message}`);
|
|
325
327
|
continue;
|
|
326
328
|
}
|
|
327
329
|
if (!stat.isDirectory()) continue;
|
|
@@ -337,8 +339,8 @@ export function findNestedGitDirs(rootPath: string): string[] {
|
|
|
337
339
|
// Don't recurse into the nested repo — we found what we need
|
|
338
340
|
continue;
|
|
339
341
|
}
|
|
340
|
-
} catch {
|
|
341
|
-
|
|
342
|
+
} catch (e) {
|
|
343
|
+
logWarning("worktree", `existsSync/.git check failed for ${fullPath}: ${(e as Error).message}`);
|
|
342
344
|
}
|
|
343
345
|
|
|
344
346
|
walk(fullPath, depth + 1);
|
|
@@ -374,7 +376,7 @@ export function removeWorktree(
|
|
|
374
376
|
if (entry?.path) {
|
|
375
377
|
wtPath = entry.path;
|
|
376
378
|
}
|
|
377
|
-
} catch {
|
|
379
|
+
} catch (e) { logWarning("worktree", `nativeWorktreeList parse failed: ${(e as Error).message}`); }
|
|
378
380
|
|
|
379
381
|
const resolvedWtPath = existsSync(wtPath) ? realpathSync(wtPath) : wtPath;
|
|
380
382
|
|
|
@@ -388,7 +390,7 @@ export function removeWorktree(
|
|
|
388
390
|
if (!existsSync(wtPath)) {
|
|
389
391
|
nativeWorktreePrune(basePath);
|
|
390
392
|
if (deleteBranch) {
|
|
391
|
-
try { nativeBranchDelete(basePath, branch, true); } catch {
|
|
393
|
+
try { nativeBranchDelete(basePath, branch, true); } catch (e) { logWarning("worktree", `nativeBranchDelete failed: ${(e as Error).message}`); }
|
|
392
394
|
}
|
|
393
395
|
return;
|
|
394
396
|
}
|
|
@@ -422,8 +424,8 @@ export function removeWorktree(
|
|
|
422
424
|
logWarning("reconcile", `Submodule changes detected — stash failed, changes may be lost during force removal`, { worktree: name, path: resolvedWtPath });
|
|
423
425
|
}
|
|
424
426
|
}
|
|
425
|
-
} catch {
|
|
426
|
-
|
|
427
|
+
} catch (e) {
|
|
428
|
+
logWarning("worktree", `submodule status check failed: ${(e as Error).message}`);
|
|
427
429
|
}
|
|
428
430
|
}
|
|
429
431
|
|
|
@@ -454,11 +456,11 @@ export function removeWorktree(
|
|
|
454
456
|
// Remove worktree: try non-force first when submodules have changes,
|
|
455
457
|
// falling back to force only after submodule state has been preserved.
|
|
456
458
|
const useForce = hasSubmoduleChanges ? false : force;
|
|
457
|
-
try { nativeWorktreeRemove(basePath, resolvedWtPath, useForce); } catch {
|
|
459
|
+
try { nativeWorktreeRemove(basePath, resolvedWtPath, useForce); } catch (e) { logWarning("worktree", `nativeWorktreeRemove failed: ${(e as Error).message}`); }
|
|
458
460
|
|
|
459
461
|
// If the directory is still there (e.g. locked), try harder with force
|
|
460
462
|
if (existsSync(resolvedWtPath)) {
|
|
461
|
-
try { nativeWorktreeRemove(basePath, resolvedWtPath, true); } catch {
|
|
463
|
+
try { nativeWorktreeRemove(basePath, resolvedWtPath, true); } catch (e) { logWarning("worktree", `nativeWorktreeRemove (force) failed: ${(e as Error).message}`); }
|
|
462
464
|
}
|
|
463
465
|
|
|
464
466
|
// (#2821) If the worktree directory STILL exists after both native removal
|
|
@@ -488,7 +490,7 @@ export function removeWorktree(
|
|
|
488
490
|
nativeWorktreePrune(basePath);
|
|
489
491
|
|
|
490
492
|
if (deleteBranch) {
|
|
491
|
-
try { nativeBranchDelete(basePath, branch, true); } catch {
|
|
493
|
+
try { nativeBranchDelete(basePath, branch, true); } catch (e) { logWarning("worktree", `final branch delete failed: ${(e as Error).message}`); }
|
|
492
494
|
}
|
|
493
495
|
}
|
|
494
496
|
|
|
@@ -298,7 +298,9 @@ export async function showInterviewRound(
|
|
|
298
298
|
// Auto-open the notes field when "None of the above" is selected
|
|
299
299
|
// so the user can immediately provide a free-text explanation
|
|
300
300
|
// instead of being trapped in a re-asking loop (bug #2715).
|
|
301
|
-
if
|
|
301
|
+
// Only auto-open if the user hasn't already provided notes —
|
|
302
|
+
// otherwise Enter from notes mode loops back here endlessly.
|
|
303
|
+
if (!isMultiSelect(currentIdx) && states[currentIdx].cursorIndex === noneOrDoneIdx(currentIdx) && !states[currentIdx].notes) {
|
|
302
304
|
states[currentIdx].notesVisible = true;
|
|
303
305
|
focusNotes = true;
|
|
304
306
|
loadStateToEditor();
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// GSD2 — Regression test for interview-ui "None of the above" notes loop
|
|
2
|
+
// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Regression test for bug #3502:
|
|
6
|
+
*
|
|
7
|
+
* Selecting "None of the above" opens the notes field, but pressing Enter
|
|
8
|
+
* after typing a note called goNextOrSubmit() which saw the cursor still
|
|
9
|
+
* on the "None of the above" slot and re-opened notes — trapping the user
|
|
10
|
+
* in an infinite loop.
|
|
11
|
+
*
|
|
12
|
+
* The fix adds a `!states[currentIdx].notes` guard so auto-open only fires
|
|
13
|
+
* when notes are still empty.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { describe, it } from "node:test";
|
|
17
|
+
import assert from "node:assert/strict";
|
|
18
|
+
import { showInterviewRound, type Question, type RoundResult } from "../interview-ui.js";
|
|
19
|
+
|
|
20
|
+
// Raw terminal sequences that matchesKey() recognises
|
|
21
|
+
const ENTER = "\r";
|
|
22
|
+
const DOWN = "\x1b[B";
|
|
23
|
+
const TAB = "\t";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Drive showInterviewRound with a scripted sequence of key inputs.
|
|
27
|
+
* We mock ctx.ui.custom() to capture the widget, feed it inputs, and
|
|
28
|
+
* resolve when done() is called.
|
|
29
|
+
*/
|
|
30
|
+
function runWithInputs(
|
|
31
|
+
questions: Question[],
|
|
32
|
+
inputs: string[],
|
|
33
|
+
): Promise<RoundResult> {
|
|
34
|
+
return new Promise((resolve, reject) => {
|
|
35
|
+
const timeout = setTimeout(() => reject(new Error("Timed out — likely stuck in infinite loop")), 3000);
|
|
36
|
+
|
|
37
|
+
const mockCtx = {
|
|
38
|
+
ui: {
|
|
39
|
+
custom: (factory: any) => {
|
|
40
|
+
const mockTui = {
|
|
41
|
+
requestRender: () => {},
|
|
42
|
+
};
|
|
43
|
+
const mockTheme = {
|
|
44
|
+
// Minimal theme stubs — render output is not asserted
|
|
45
|
+
fg: (_c: string, t: string) => t,
|
|
46
|
+
bold: (t: string) => t,
|
|
47
|
+
dim: (t: string) => t,
|
|
48
|
+
italic: (t: string) => t,
|
|
49
|
+
strikethrough: (t: string) => t,
|
|
50
|
+
accent: (t: string) => t,
|
|
51
|
+
success: (t: string) => t,
|
|
52
|
+
warning: (t: string) => t,
|
|
53
|
+
error: (t: string) => t,
|
|
54
|
+
info: (t: string) => t,
|
|
55
|
+
muted: (t: string) => t,
|
|
56
|
+
dimmed: (t: string) => t,
|
|
57
|
+
};
|
|
58
|
+
const mockKb = {};
|
|
59
|
+
|
|
60
|
+
const widget = factory(mockTui, mockTheme, mockKb, (result: RoundResult) => {
|
|
61
|
+
clearTimeout(timeout);
|
|
62
|
+
resolve(result);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Feed each input sequentially
|
|
66
|
+
for (const input of inputs) {
|
|
67
|
+
widget.handleInput(input);
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
showInterviewRound(questions, {}, mockCtx as any).catch(reject);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
describe("interview-ui notes loop regression (#3502)", () => {
|
|
78
|
+
const questions: Question[] = [
|
|
79
|
+
{
|
|
80
|
+
id: "q1",
|
|
81
|
+
header: "Project Type",
|
|
82
|
+
question: "What type of project?",
|
|
83
|
+
options: [
|
|
84
|
+
{ label: "Web App", description: "Frontend or full-stack" },
|
|
85
|
+
{ label: "CLI Tool", description: "Command-line utility" },
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
it("does not loop when Enter is pressed after typing a note on 'None of the above'", async () => {
|
|
91
|
+
// With 2 options, "None of the above" is index 2 (0-based)
|
|
92
|
+
// Cursor starts at 0, so press Down twice to reach it
|
|
93
|
+
const result = await runWithInputs(questions, [
|
|
94
|
+
DOWN, // cursor → index 1 (CLI Tool)
|
|
95
|
+
DOWN, // cursor → index 2 (None of the above)
|
|
96
|
+
ENTER, // commit → auto-opens notes field
|
|
97
|
+
"u", "n", "s", "u", "r", "e", // type "unsure"
|
|
98
|
+
ENTER, // should advance to review, NOT reopen notes
|
|
99
|
+
ENTER, // submit from review screen
|
|
100
|
+
]);
|
|
101
|
+
|
|
102
|
+
// If we get here, the loop did not occur (timeout would have fired)
|
|
103
|
+
assert.ok(result, "should return a result");
|
|
104
|
+
assert.equal(result.endInterview, false);
|
|
105
|
+
|
|
106
|
+
const answer = result.answers.q1;
|
|
107
|
+
assert.ok(answer, "answer for q1 should exist");
|
|
108
|
+
assert.equal(answer.notes, "unsure", "notes should contain typed text");
|
|
109
|
+
assert.equal(answer.selected, "None of the above");
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("still auto-opens notes when selecting 'None of the above' with no prior notes", async () => {
|
|
113
|
+
// Press Down twice to "None of the above", Enter to select
|
|
114
|
+
// Then immediately Enter again (empty notes) — this should re-open notes
|
|
115
|
+
// because the guard only skips when notes are non-empty.
|
|
116
|
+
// Type something on second open, then Enter to proceed.
|
|
117
|
+
const result = await runWithInputs(questions, [
|
|
118
|
+
DOWN, // cursor → 1
|
|
119
|
+
DOWN, // cursor → 2 (None of the above)
|
|
120
|
+
ENTER, // commit → auto-opens notes
|
|
121
|
+
ENTER, // empty notes → goNextOrSubmit → should re-open notes (empty guard)
|
|
122
|
+
"o", "k", // type "ok"
|
|
123
|
+
ENTER, // now notes = "ok" → should advance to review
|
|
124
|
+
ENTER, // submit
|
|
125
|
+
]);
|
|
126
|
+
|
|
127
|
+
assert.ok(result, "should return a result");
|
|
128
|
+
const answer = result.answers.q1;
|
|
129
|
+
assert.ok(answer, "answer for q1 should exist");
|
|
130
|
+
assert.equal(answer.notes, "ok");
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("normal option selection is unaffected", async () => {
|
|
134
|
+
const result = await runWithInputs(questions, [
|
|
135
|
+
ENTER, // select first option (Web App) and advance to review
|
|
136
|
+
ENTER, // submit from review screen
|
|
137
|
+
]);
|
|
138
|
+
|
|
139
|
+
assert.ok(result, "should return a result");
|
|
140
|
+
const answer = result.answers.q1;
|
|
141
|
+
assert.ok(answer, "answer for q1 should exist");
|
|
142
|
+
assert.equal(answer.selected, "Web App");
|
|
143
|
+
});
|
|
144
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: btw
|
|
3
|
+
description: Ask a quick side question about your current work without derailing the main task. Answers from existing conversation context only — no tool calls, no file reads, single concise response. Use when you need a fast answer from what is already in this session.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<objective>
|
|
7
|
+
Answer a quick side question using only what is already present in the current conversation context. Do not read files, run commands, search, or use any tools. Give a single, concise response and return focus to the main work.
|
|
8
|
+
</objective>
|
|
9
|
+
|
|
10
|
+
<behavior>
|
|
11
|
+
**This is a side question, not a task.**
|
|
12
|
+
|
|
13
|
+
- Answer only from information already in the conversation (files read, decisions made, code seen, context established)
|
|
14
|
+
- Do NOT use any tools — no Read, no Bash, no Grep, no Search
|
|
15
|
+
- If the answer requires reading something new, say so briefly and suggest the user ask as a normal prompt instead
|
|
16
|
+
- Keep the response short and direct — one to a few sentences unless the question genuinely needs more
|
|
17
|
+
- Do not summarize the main work, ask follow-up questions, or offer to do anything else
|
|
18
|
+
- After answering, stop — do not prompt for next steps
|
|
19
|
+
</behavior>
|
|
20
|
+
|
|
21
|
+
<quick_start>
|
|
22
|
+
Parse the argument after `/btw` as the question. Answer it directly from context.
|
|
23
|
+
|
|
24
|
+
If no argument is provided, ask: "What did you want to know?"
|
|
25
|
+
|
|
26
|
+
If the question cannot be answered from current context (requires reading a file, running a command, or information not yet in the session), respond with:
|
|
27
|
+
"I'd need to [read X / run Y / look up Z] to answer that — ask it as a normal prompt when you're ready."
|
|
28
|
+
</quick_start>
|
|
29
|
+
|
|
30
|
+
<examples>
|
|
31
|
+
**Good uses of /btw:**
|
|
32
|
+
- `/btw what was the name of that config file again?` → answers from files already read in session
|
|
33
|
+
- `/btw which branch are we on?` → answers from git context already established
|
|
34
|
+
- `/btw did we already handle the null case in that function?` → answers from code already reviewed
|
|
35
|
+
- `/btw what model does this use?` → answers from code or config already in context
|
|
36
|
+
|
|
37
|
+
**Not a good fit for /btw (suggest normal prompt):**
|
|
38
|
+
- Questions requiring reading a file not yet seen
|
|
39
|
+
- Questions requiring running a command
|
|
40
|
+
- Questions needing a multi-step answer or follow-up
|
|
41
|
+
- Starting a new task or changing direction
|
|
42
|
+
</examples>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[8974],{5214:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"workAsyncStorage",{enumerable:!0,get:function(){return r.workAsyncStorageInstance}});let r=n(17828)},15726:(e,t,n)=>{Promise.resolve().then(n.bind(n,66919))},17828:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"workAsyncStorageInstance",{enumerable:!0,get:function(){return r}});let r=(0,n(64054).createAsyncLocalStorage)()},21957:(e,t,n)=>{"use strict";function r({moduleIds:e}){return null}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"PreloadChunks",{enumerable:!0,get:function(){return r}}),n(95155),n(47650),n(5214),n(2451),n(53887)},37206:(e,t,n)=>{"use strict";n.d(t,{default:()=>u.a});var r=n(75707),u=n.n(r)},41112:(e,t,n)=>{"use strict";function r({reason:e,children:t}){return t}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"BailoutToCSR",{enumerable:!0,get:function(){return r}}),n(1980)},64054:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n={bindSnapshot:function(){return s},createAsyncLocalStorage:function(){return a},createSnapshot:function(){return i}};for(var r in n)Object.defineProperty(t,r,{enumerable:!0,get:n[r]});let u=Object.defineProperty(Error("Invariant: AsyncLocalStorage accessed in runtime where it is not available"),"__NEXT_ERROR_CODE",{value:"E504",enumerable:!1,configurable:!0});class l{disable(){throw u}getStore(){}run(){throw u}exit(){throw u}enterWith(){throw u}static bind(e){return e}}let o="u">typeof globalThis&&globalThis.AsyncLocalStorage;function a(){return o?new o:new l}function s(e){return o?o.bind(e):l.bind(e)}function i(){return o?o.snapshot():function(e,...t){return e(...t)}}},66919:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r=n(95155);let u=(0,n(37206).default)(()=>Promise.all([n.e(1838),n.e(6079),n.e(4986),n.e(2008),n.e(6502)]).then(n.bind(n,46502)).then(e=>e.GSDAppShell),{loadableGenerated:{webpack:()=>[46502]},ssr:!1,loading:()=>(0,r.jsx)("div",{className:"flex h-screen items-center justify-center bg-background text-sm text-muted-foreground",children:"Loading workspace…"})});function l(){return(0,r.jsx)(u,{})}},68635:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return s}});let r=n(95155),u=n(12115),l=n(41112);function o(e){return{default:e&&"default"in e?e.default:e}}n(21957);let a={loader:()=>Promise.resolve(o(()=>null)),loading:null,ssr:!0},s=function(e){let t={...a,...e},n=(0,u.lazy)(()=>t.loader().then(o)),s=t.loading;function i(e){let o=s?(0,r.jsx)(s,{isLoading:!0,pastDelay:!0,error:null}):null,a=!t.ssr||!!t.loading,i=a?u.Suspense:u.Fragment,c=t.ssr?(0,r.jsxs)(r.Fragment,{children:[null,(0,r.jsx)(n,{...e})]}):(0,r.jsx)(l.BailoutToCSR,{reason:"next/dynamic",children:(0,r.jsx)(n,{...e})});return(0,r.jsx)(i,{...a?{fallback:o}:{},children:c})}return i.displayName="LoadableComponent",i}},75707:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return u}});let r=n(73623)._(n(68635));function u(e,t){let n={};"function"==typeof e&&(n.loader=e);let u={...n,...t};return(0,r.default)({...u,modules:u.loadableGenerated?.modules})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)}},e=>{e.O(0,[8441,3794,7358],()=>e(e.s=15726)),_N_E=e.O()}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7358],{2852:(e,s,n)=>{Promise.resolve().then(n.t.bind(n,27123,23)),Promise.resolve().then(n.t.bind(n,61304,23)),Promise.resolve().then(n.t.bind(n,78616,23)),Promise.resolve().then(n.t.bind(n,64777,23)),Promise.resolve().then(n.t.bind(n,57121,23)),Promise.resolve().then(n.t.bind(n,74581,23)),Promise.resolve().then(n.t.bind(n,90484,23)),Promise.resolve().then(n.bind(n,86869))},19393:()=>{}},e=>{var s=s=>e(e.s=s);e.O(0,[8441,3794],()=>(s(83861),s(2852))),_N_E=e.O()}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9337],{52560:(e,s,_)=>{Promise.resolve().then(_.t.bind(_,27123,23))}},e=>{e.O(0,[8441,3794,7358],()=>e(e.s=52560)),_N_E=e.O()}]);
|
|
File without changes
|
|
File without changes
|