gsd-pi 2.58.0-dev.d63175c → 2.58.0-dev.e002a57
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 +1 -1
- package/dist/cli.js +60 -35
- package/dist/headless-ui.d.ts +17 -0
- package/dist/headless-ui.js +97 -3
- package/dist/headless.js +67 -6
- package/dist/help-text.js +1 -0
- package/dist/onboarding.js +44 -0
- package/dist/resource-loader.js +16 -1
- package/dist/resources/agents/researcher.md +1 -1
- package/dist/resources/extensions/ask-user-questions.js +16 -3
- package/dist/resources/extensions/async-jobs/extension-manifest.json +1 -1
- package/dist/resources/extensions/bg-shell/extension-manifest.json +1 -1
- package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +14 -6
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +59 -36
- package/dist/resources/extensions/context7/extension-manifest.json +1 -1
- package/dist/resources/extensions/get-secrets-from-user.js +8 -5
- package/dist/resources/extensions/google-search/extension-manifest.json +1 -1
- package/dist/resources/extensions/google-search/index.js +2 -1
- package/dist/resources/extensions/gsd/auto/phases.js +25 -21
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
- package/dist/resources/extensions/gsd/auto-dashboard.js +37 -20
- package/dist/resources/extensions/gsd/auto-dispatch.js +17 -2
- package/dist/resources/extensions/gsd/auto-model-selection.js +26 -3
- package/dist/resources/extensions/gsd/auto-post-unit.js +16 -4
- package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
- package/dist/resources/extensions/gsd/auto-recovery.js +13 -5
- package/dist/resources/extensions/gsd/auto-start.js +35 -22
- package/dist/resources/extensions/gsd/auto-worktree.js +199 -12
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -8
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +42 -34
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +66 -12
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -0
- package/dist/resources/extensions/gsd/captures.js +56 -4
- package/dist/resources/extensions/gsd/codebase-generator.js +279 -0
- package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
- package/dist/resources/extensions/gsd/commands-codebase.js +115 -0
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +41 -4
- package/dist/resources/extensions/gsd/complexity-classifier.js +8 -6
- package/dist/resources/extensions/gsd/db-writer.js +116 -8
- package/dist/resources/extensions/gsd/doctor-git-checks.js +76 -1
- package/dist/resources/extensions/gsd/doctor-proactive.js +34 -1
- package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +5 -4
- package/dist/resources/extensions/gsd/doctor.js +3 -1
- package/dist/resources/extensions/gsd/error-classifier.js +12 -10
- package/dist/resources/extensions/gsd/extension-manifest.json +16 -1
- package/dist/resources/extensions/gsd/forensics.js +123 -20
- package/dist/resources/extensions/gsd/git-service.js +105 -2
- package/dist/resources/extensions/gsd/gitignore.js +33 -0
- package/dist/resources/extensions/gsd/gsd-db.js +36 -9
- package/dist/resources/extensions/gsd/guided-flow.js +106 -44
- package/dist/resources/extensions/gsd/health-widget-core.js +31 -0
- package/dist/resources/extensions/gsd/health-widget.js +17 -0
- package/dist/resources/extensions/gsd/index.js +1 -1
- package/dist/resources/extensions/gsd/memory-extractor.js +7 -0
- package/dist/resources/extensions/gsd/migrate-external.js +8 -1
- package/dist/resources/extensions/gsd/milestone-validation-gates.js +45 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +18 -0
- package/dist/resources/extensions/gsd/model-router.js +35 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +39 -0
- package/dist/resources/extensions/gsd/notifications.js +16 -1
- package/dist/resources/extensions/gsd/parallel-eligibility.js +13 -2
- package/dist/resources/extensions/gsd/parallel-merge.js +78 -5
- package/dist/resources/extensions/gsd/parsers-legacy.js +20 -3
- package/dist/resources/extensions/gsd/paths.js +45 -0
- package/dist/resources/extensions/gsd/preferences-models.js +14 -1
- package/dist/resources/extensions/gsd/preferences-types.js +3 -1
- package/dist/resources/extensions/gsd/preferences.js +13 -16
- package/dist/resources/extensions/gsd/prompt-loader.js +4 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -2
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -1
- package/dist/resources/extensions/gsd/prompts/forensics.md +2 -2
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -0
- package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -0
- package/dist/resources/extensions/gsd/repo-identity.js +205 -11
- package/dist/resources/extensions/gsd/rethink.js +5 -0
- package/dist/resources/extensions/gsd/roadmap-slices.js +5 -4
- package/dist/resources/extensions/gsd/state.js +85 -27
- package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
- package/dist/resources/extensions/gsd/tools/complete-task.js +34 -71
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +12 -2
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +29 -1
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +14 -3
- package/dist/resources/extensions/gsd/triage-resolution.js +22 -7
- package/dist/resources/extensions/gsd/undo.js +2 -2
- package/dist/resources/extensions/gsd/unit-ownership.js +164 -33
- package/dist/resources/extensions/gsd/verdict-parser.js +20 -8
- package/dist/resources/extensions/gsd/watch/header-renderer.js +241 -0
- package/dist/resources/extensions/gsd/workflow-manifest.js +24 -5
- package/dist/resources/extensions/gsd/workflow-projections.js +95 -63
- package/dist/resources/extensions/gsd/workflow-reconcile.js +35 -5
- package/dist/resources/extensions/gsd/workspace-index.js +24 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +105 -1
- package/dist/resources/extensions/gsd/worktree-resolver.js +20 -3
- package/dist/resources/extensions/mcp-client/index.js +11 -7
- package/dist/resources/extensions/ollama/index.js +112 -0
- package/dist/resources/extensions/ollama/model-capabilities.js +115 -0
- package/dist/resources/extensions/ollama/ollama-client.js +168 -0
- package/dist/resources/extensions/ollama/ollama-commands.js +194 -0
- package/dist/resources/extensions/ollama/ollama-discovery.js +69 -0
- package/dist/resources/extensions/ollama/ollama-tool.js +184 -0
- package/dist/resources/extensions/ollama/types.js +2 -0
- package/dist/resources/extensions/search-the-web/extension-manifest.json +1 -1
- package/dist/resources/extensions/search-the-web/url-utils.js +17 -0
- package/dist/resources/extensions/shared/interview-ui.js +11 -1
- package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -3
- package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
- package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
- package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
- package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
- package/dist/security-overrides.d.ts +11 -0
- package/dist/security-overrides.js +41 -0
- package/dist/startup-model-validation.d.ts +39 -0
- package/dist/startup-model-validation.js +50 -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/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/required-server-files.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +2 -2
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.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_client-reference-manifest.js +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_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_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_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_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_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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.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_client-reference-manifest.js +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_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_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_client-reference-manifest.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_client-reference-manifest.js +1 -1
- 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_client-reference-manifest.js +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_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 +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
- package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +9 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-61d3afac6d0f0ce7.js → webpack-a1c1e452c6b32d04.js} +1 -1
- package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +1 -0
- package/dist/web/standalone/server.js +1 -1
- package/dist/web-mode.js +2 -1
- package/dist/welcome-screen.d.ts +1 -0
- package/dist/welcome-screen.js +32 -6
- package/package.json +2 -2
- package/packages/native/dist/ast/index.js +9 -5
- package/packages/native/dist/ast/types.js +2 -1
- package/packages/native/dist/clipboard/index.js +12 -7
- package/packages/native/dist/clipboard/types.js +2 -1
- package/packages/native/dist/diff/index.js +12 -7
- package/packages/native/dist/diff/types.js +2 -1
- package/packages/native/dist/fd/index.js +6 -3
- package/packages/native/dist/fd/types.js +2 -1
- package/packages/native/dist/glob/index.js +9 -5
- package/packages/native/dist/glob/types.js +2 -1
- package/packages/native/dist/grep/index.js +9 -5
- package/packages/native/dist/grep/types.js +2 -1
- package/packages/native/dist/gsd-parser/index.js +18 -11
- package/packages/native/dist/gsd-parser/types.js +2 -1
- package/packages/native/dist/highlight/index.js +12 -7
- package/packages/native/dist/highlight/types.js +2 -1
- package/packages/native/dist/html/index.js +6 -3
- package/packages/native/dist/html/types.js +2 -1
- package/packages/native/dist/image/index.js +10 -5
- package/packages/native/dist/image/types.js +7 -4
- package/packages/native/dist/index.js +70 -17
- package/packages/native/dist/json-parse/index.js +13 -8
- package/packages/native/dist/native.js +47 -10
- package/packages/native/dist/ps/index.js +15 -9
- package/packages/native/dist/ps/types.js +2 -1
- package/packages/native/dist/stream-process/index.js +12 -7
- package/packages/native/dist/text/index.js +24 -14
- package/packages/native/dist/text/types.js +5 -2
- package/packages/native/dist/truncate/index.js +12 -7
- package/packages/native/dist/ttsr/index.js +12 -7
- package/packages/native/dist/ttsr/types.js +2 -1
- package/packages/native/dist/xxhash/index.js +9 -5
- package/packages/native/package.json +19 -19
- package/packages/native/src/__tests__/module-compat.test.mjs +91 -0
- package/packages/native/src/native.ts +9 -8
- package/packages/pi-agent-core/dist/agent-loop.js +3 -2
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/proxy.d.ts +1 -1
- package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/proxy.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +45 -0
- package/packages/pi-agent-core/src/agent-loop.ts +3 -2
- package/packages/pi-agent-core/src/proxy.ts +1 -1
- package/packages/pi-ai/dist/env-api-keys.js +1 -0
- package/packages/pi-ai/dist/env-api-keys.js.map +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/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +19 -2
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js +25 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -0
- package/packages/pi-ai/dist/types.d.ts +3 -3
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.d.ts +3 -0
- package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.js +24 -1
- package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
- package/packages/pi-ai/dist/utils/repair-tool-json.d.ts +37 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.js +75 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +73 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -0
- package/packages/pi-ai/src/env-api-keys.ts +1 -0
- package/packages/pi-ai/src/index.ts +1 -0
- package/packages/pi-ai/src/providers/anthropic-shared.test.ts +29 -0
- package/packages/pi-ai/src/providers/anthropic-shared.ts +17 -2
- package/packages/pi-ai/src/types.ts +3 -2
- package/packages/pi-ai/src/utils/json-parse.ts +28 -1
- package/packages/pi-ai/src/utils/repair-tool-json.ts +88 -0
- package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +102 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +4 -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 +31 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +17 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +62 -2
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +176 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/exec.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/exec.js +3 -1
- package/packages/pi-coding-agent/dist/core/exec.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts +28 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js +37 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js +63 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts +19 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js +115 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js +109 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.js +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
- 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/image-overflow-recovery.d.ts +44 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js +97 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js +181 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/index.js +1 -1
- package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/index.js +3 -0
- package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -0
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.js +31 -2
- package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.test.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/messages.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/messages.test.js +86 -0
- package/packages/pi-coding-agent/dist/core/messages.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resolve-config-value.d.ts +8 -0
- package/packages/pi-coding-agent/dist/core/resolve-config-value.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resolve-config-value.js +23 -2
- package/packages/pi-coding-agent/dist/core/resolve-config-value.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +89 -2
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +10 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +12 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +48 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +193 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/settings-manager-security.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/settings-manager-security.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/settings-manager-security.test.js +83 -0
- package/packages/pi-coding-agent/dist/core/settings-manager-security.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +14 -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 +36 -3
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +10 -3
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js +13 -4
- package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts +16 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +80 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts +3 -2
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +2 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/armin.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/armin.js +9 -8
- package/packages/pi-coding-agent/dist/modes/interactive/components/armin.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +0 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bordered-loader.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.js +5 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/custom-message.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.js +4 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +8 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.js +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.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 +26 -12
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/oauth-selector.js +4 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +46 -14
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js +2 -8
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js +4 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +8 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.js +3 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- 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 +19 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- 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 +16 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- 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 +27 -4
- 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 +6 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js +5 -0
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +38 -1
- package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +236 -0
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +94 -1
- package/packages/pi-coding-agent/src/core/exec.ts +3 -1
- package/packages/pi-coding-agent/src/core/extensions/extension-manifest.test.ts +77 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-manifest.ts +62 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-sort.test.ts +134 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-sort.ts +137 -0
- package/packages/pi-coding-agent/src/core/extensions/index.ts +4 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
- package/packages/pi-coding-agent/src/core/image-overflow-recovery.test.ts +228 -0
- package/packages/pi-coding-agent/src/core/image-overflow-recovery.ts +118 -0
- package/packages/pi-coding-agent/src/core/index.ts +6 -0
- package/packages/pi-coding-agent/src/core/lsp/index.ts +3 -0
- package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -0
- package/packages/pi-coding-agent/src/core/messages.test.ts +114 -0
- package/packages/pi-coding-agent/src/core/messages.ts +29 -2
- package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
- package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +111 -1
- package/packages/pi-coding-agent/src/core/resolve-config-value.ts +26 -2
- package/packages/pi-coding-agent/src/core/resource-loader.ts +20 -1
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +255 -0
- package/packages/pi-coding-agent/src/core/retry-handler.ts +52 -1
- package/packages/pi-coding-agent/src/core/settings-manager-security.test.ts +102 -0
- package/packages/pi-coding-agent/src/core/settings-manager.ts +44 -3
- package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +11 -3
- package/packages/pi-coding-agent/src/core/tools/read.ts +14 -4
- package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +92 -0
- package/packages/pi-coding-agent/src/index.ts +11 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/armin.ts +9 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +0 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +3 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/bordered-loader.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/branch-summary-message.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/compaction-summary-message.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/config-selector.ts +7 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/countdown-timer.ts +3 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/custom-message.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/daxnuts.ts +4 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +2 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +3 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/extension-input.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/extension-selector.ts +4 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +27 -13
- package/packages/pi-coding-agent/src/modes/interactive/components/oauth-selector.ts +4 -4
- package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +45 -14
- package/packages/pi-coding-agent/src/modes/interactive/components/scoped-models-selector.ts +2 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/session-selector.ts +4 -4
- package/packages/pi-coding-agent/src/modes/interactive/components/skill-invocation-message.ts +2 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +8 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/user-message-selector.ts +3 -2
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +24 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +14 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +35 -3
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +7 -0
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +1 -1
- package/packages/pi-coding-agent/src/modes/rpc/remote-terminal.ts +6 -0
- package/packages/pi-tui/dist/terminal.d.ts +2 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +9 -0
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +9 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/terminal.ts +14 -0
- package/packages/pi-tui/src/tui.ts +8 -0
- package/pkg/dist/modes/interactive/theme/themes.js +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- package/scripts/ensure-workspace-builds.cjs +45 -14
- package/src/resources/agents/researcher.md +1 -1
- package/src/resources/extensions/ask-user-questions.ts +21 -3
- package/src/resources/extensions/async-jobs/extension-manifest.json +1 -1
- package/src/resources/extensions/bg-shell/extension-manifest.json +1 -1
- package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +13 -6
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +63 -35
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +28 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -1
- package/src/resources/extensions/context7/extension-manifest.json +1 -1
- package/src/resources/extensions/get-secrets-from-user.ts +8 -5
- package/src/resources/extensions/google-search/extension-manifest.json +1 -1
- package/src/resources/extensions/google-search/index.ts +2 -1
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/phases.ts +43 -34
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
- package/src/resources/extensions/gsd/auto-dashboard.ts +37 -19
- package/src/resources/extensions/gsd/auto-dispatch.ts +18 -2
- package/src/resources/extensions/gsd/auto-model-selection.ts +26 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
- package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +12 -5
- package/src/resources/extensions/gsd/auto-start.ts +35 -26
- package/src/resources/extensions/gsd/auto-worktree.ts +193 -9
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +31 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +85 -8
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +38 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +41 -35
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +72 -12
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +75 -0
- package/src/resources/extensions/gsd/captures.ts +63 -3
- package/src/resources/extensions/gsd/codebase-generator.ts +351 -0
- package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
- package/src/resources/extensions/gsd/commands-codebase.ts +164 -0
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +46 -4
- package/src/resources/extensions/gsd/complexity-classifier.ts +8 -6
- package/src/resources/extensions/gsd/db-writer.ts +140 -7
- package/src/resources/extensions/gsd/doctor-git-checks.ts +75 -1
- package/src/resources/extensions/gsd/doctor-proactive.ts +35 -1
- package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +5 -4
- package/src/resources/extensions/gsd/doctor-types.ts +2 -0
- package/src/resources/extensions/gsd/doctor.ts +3 -1
- package/src/resources/extensions/gsd/error-classifier.ts +13 -11
- package/src/resources/extensions/gsd/extension-manifest.json +16 -1
- package/src/resources/extensions/gsd/forensics.ts +144 -20
- package/src/resources/extensions/gsd/git-service.ts +119 -3
- package/src/resources/extensions/gsd/gitignore.ts +33 -0
- package/src/resources/extensions/gsd/gsd-db.ts +43 -7
- package/src/resources/extensions/gsd/guided-flow.ts +114 -45
- package/src/resources/extensions/gsd/health-widget-core.ts +34 -0
- package/src/resources/extensions/gsd/health-widget.ts +17 -0
- package/src/resources/extensions/gsd/index.ts +1 -0
- package/src/resources/extensions/gsd/memory-extractor.ts +8 -0
- package/src/resources/extensions/gsd/migrate-external.ts +9 -1
- package/src/resources/extensions/gsd/milestone-validation-gates.ts +56 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +19 -0
- package/src/resources/extensions/gsd/model-router.ts +35 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +41 -0
- package/src/resources/extensions/gsd/notifications.ts +16 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +15 -2
- package/src/resources/extensions/gsd/parallel-merge.ts +87 -4
- package/src/resources/extensions/gsd/parsers-legacy.ts +22 -3
- package/src/resources/extensions/gsd/paths.ts +44 -0
- package/src/resources/extensions/gsd/preferences-models.ts +14 -1
- package/src/resources/extensions/gsd/preferences-types.ts +10 -1
- package/src/resources/extensions/gsd/preferences.ts +13 -15
- package/src/resources/extensions/gsd/prompt-loader.ts +4 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -2
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/src/resources/extensions/gsd/prompts/execute-task.md +3 -1
- package/src/resources/extensions/gsd/prompts/forensics.md +2 -2
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -0
- package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
- package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -0
- package/src/resources/extensions/gsd/repo-identity.ts +186 -11
- package/src/resources/extensions/gsd/rethink.ts +6 -0
- package/src/resources/extensions/gsd/roadmap-slices.ts +5 -4
- package/src/resources/extensions/gsd/state.ts +84 -32
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +71 -1
- package/src/resources/extensions/gsd/tests/captures.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +488 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/completion-hierarchy-guards.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/complexity-classifier.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +131 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +7 -12
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +78 -5
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +129 -0
- package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +96 -0
- package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +125 -12
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +164 -0
- package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +135 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +111 -1
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +134 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-false-positives.test.ts +243 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +72 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/integration/gitignore-staging-2570.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +959 -0
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +85 -2
- package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/model-router.test.ts +68 -3
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/notifications.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +159 -0
- package/src/resources/extensions/gsd/tests/parallel-eligibility-ghost.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +297 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/prompt-loader-replacement.test.ts +178 -0
- package/src/resources/extensions/gsd/tests/prompt-tool-names.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/reconciliation-edge-cases.test.ts +162 -0
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +134 -0
- package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +233 -0
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +305 -0
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +405 -0
- package/src/resources/extensions/gsd/tests/state-derivation-parity.test.ts +257 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +1628 -0
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +174 -0
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +221 -0
- package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +289 -0
- package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +100 -17
- package/src/resources/extensions/gsd/tests/vacuum-recovery.test.ts +154 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/verdict-parser.test.ts +156 -0
- package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +82 -0
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +48 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +95 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +36 -74
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +13 -1
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +36 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +20 -2
- package/src/resources/extensions/gsd/triage-resolution.ts +23 -6
- package/src/resources/extensions/gsd/types.ts +4 -2
- package/src/resources/extensions/gsd/undo.ts +2 -2
- package/src/resources/extensions/gsd/unit-ownership.ts +206 -35
- package/src/resources/extensions/gsd/verdict-parser.ts +21 -6
- package/src/resources/extensions/gsd/watch/header-renderer.ts +275 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +3 -1
- package/src/resources/extensions/gsd/workflow-manifest.ts +22 -5
- package/src/resources/extensions/gsd/workflow-projections.ts +97 -64
- package/src/resources/extensions/gsd/workflow-reconcile.ts +39 -10
- package/src/resources/extensions/gsd/workspace-index.ts +30 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +120 -1
- package/src/resources/extensions/gsd/worktree-resolver.ts +22 -3
- package/src/resources/extensions/mcp-client/index.ts +13 -7
- package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +55 -0
- package/src/resources/extensions/ollama/index.ts +130 -0
- package/src/resources/extensions/ollama/model-capabilities.ts +145 -0
- package/src/resources/extensions/ollama/ollama-client.ts +196 -0
- package/src/resources/extensions/ollama/ollama-commands.ts +248 -0
- package/src/resources/extensions/ollama/ollama-discovery.ts +106 -0
- package/src/resources/extensions/ollama/ollama-tool.ts +218 -0
- package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +162 -0
- package/src/resources/extensions/ollama/tests/ollama-client.test.ts +38 -0
- package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +28 -0
- package/src/resources/extensions/ollama/types.ts +130 -0
- package/src/resources/extensions/search-the-web/extension-manifest.json +1 -1
- package/src/resources/extensions/search-the-web/url-utils.ts +19 -0
- package/src/resources/extensions/shared/interview-ui.ts +12 -1
- package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +156 -0
- package/src/resources/skills/create-gsd-extension/SKILL.md +5 -3
- package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
- package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
- package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
- package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
- package/dist/web/standalone/.next/static/chunks/6502.8b732f67a11b11b4.js +0 -9
- package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +0 -1
- package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +0 -79
- /package/dist/web/standalone/.next/static/{5DLsjFHdSB6_a1EDQVjr7 → nUA6d2OJrDSVq9RNb-c8b}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{5DLsjFHdSB6_a1EDQVjr7 → nUA6d2OJrDSVq9RNb-c8b}/_ssgManifest.js +0 -0
package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts
CHANGED
|
@@ -638,6 +638,140 @@ describe("auto-worktree-milestone-merge", { timeout: 300_000 }, () => {
|
|
|
638
638
|
"#1906: codeFilesChanged must be false when only .gsd/ files were merged");
|
|
639
639
|
});
|
|
640
640
|
|
|
641
|
+
test("#2912: MERGE_HEAD cleaned up after squash-merge conflict", () => {
|
|
642
|
+
const repo = freshRepo();
|
|
643
|
+
const wtPath = createAutoWorktree(repo, "M291");
|
|
644
|
+
|
|
645
|
+
// Create a file on main that will conflict with the milestone branch
|
|
646
|
+
run("git checkout main", repo);
|
|
647
|
+
writeFileSync(join(repo, "conflict.ts"), "// main version\nexport const x = 1;\n");
|
|
648
|
+
run("git add .", repo);
|
|
649
|
+
run("git commit -m 'add conflict.ts on main'", repo);
|
|
650
|
+
|
|
651
|
+
// Switch back to milestone branch and create conflicting content
|
|
652
|
+
run("git checkout milestone/M291", wtPath);
|
|
653
|
+
writeFileSync(join(wtPath, "conflict.ts"), "// milestone version\nexport const x = 2;\n");
|
|
654
|
+
run("git add .", wtPath);
|
|
655
|
+
run("git commit -m 'add conflict.ts on milestone'", wtPath);
|
|
656
|
+
|
|
657
|
+
const roadmap = makeRoadmap("M291", "Conflict milestone", [
|
|
658
|
+
{ id: "S01", title: "Conflict test" },
|
|
659
|
+
]);
|
|
660
|
+
|
|
661
|
+
// The merge should throw MergeConflictError due to conflict.ts
|
|
662
|
+
let threw = false;
|
|
663
|
+
try {
|
|
664
|
+
mergeMilestoneToMain(repo, "M291", roadmap);
|
|
665
|
+
} catch (err: unknown) {
|
|
666
|
+
threw = true;
|
|
667
|
+
// Verify it's a merge conflict error
|
|
668
|
+
assert.ok(
|
|
669
|
+
err instanceof Error && err.message.includes("conflict"),
|
|
670
|
+
"should throw a conflict-related error",
|
|
671
|
+
);
|
|
672
|
+
}
|
|
673
|
+
assert.ok(threw, "mergeMilestoneToMain must throw on code conflict");
|
|
674
|
+
|
|
675
|
+
// BUG #2912: MERGE_HEAD must NOT be left on disk after the error
|
|
676
|
+
const mergeHeadPath = join(repo, ".git", "MERGE_HEAD");
|
|
677
|
+
assert.ok(
|
|
678
|
+
!existsSync(mergeHeadPath),
|
|
679
|
+
"#2912: MERGE_HEAD must be cleaned up after merge conflict error",
|
|
680
|
+
);
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
test("#2912: stale MERGE_HEAD from native merge is cleaned after successful commit", () => {
|
|
684
|
+
const repo = freshRepo();
|
|
685
|
+
const wtPath = createAutoWorktree(repo, "M292");
|
|
686
|
+
|
|
687
|
+
addSliceToMilestone(repo, wtPath, "M292", "S01", "Feature A", [
|
|
688
|
+
{ file: "feature-a.ts", content: "export const a = true;\n", message: "add feature a" },
|
|
689
|
+
]);
|
|
690
|
+
|
|
691
|
+
const roadmap = makeRoadmap("M292", "Clean merge", [
|
|
692
|
+
{ id: "S01", title: "Feature A" },
|
|
693
|
+
]);
|
|
694
|
+
|
|
695
|
+
// Simulate what libgit2's merge implementation does: it creates MERGE_HEAD
|
|
696
|
+
// even for squash merges (unlike CLI git). We plant MERGE_HEAD before calling
|
|
697
|
+
// mergeMilestoneToMain to verify the success path cleans it up.
|
|
698
|
+
// We cannot plant it before the call because the function manages checkout
|
|
699
|
+
// internally, so instead we verify after the call.
|
|
700
|
+
mergeMilestoneToMain(repo, "M292", roadmap);
|
|
701
|
+
|
|
702
|
+
// After successful merge+commit, MERGE_HEAD must not linger
|
|
703
|
+
const mergeHeadPath = join(repo, ".git", "MERGE_HEAD");
|
|
704
|
+
assert.ok(
|
|
705
|
+
!existsSync(mergeHeadPath),
|
|
706
|
+
"#2912: MERGE_HEAD must be cleaned up after successful merge",
|
|
707
|
+
);
|
|
708
|
+
});
|
|
709
|
+
|
|
710
|
+
test("#2912: planted MERGE_HEAD is cleaned up in success path", () => {
|
|
711
|
+
// This test directly verifies the cleanup code handles a MERGE_HEAD file
|
|
712
|
+
// left by the native (libgit2) merge path. We hook into the merge by
|
|
713
|
+
// planting MERGE_HEAD right after nativeMergeSquash would create it.
|
|
714
|
+
const repo = freshRepo();
|
|
715
|
+
const wtPath = createAutoWorktree(repo, "M293");
|
|
716
|
+
|
|
717
|
+
addSliceToMilestone(repo, wtPath, "M293", "S01", "Feature B", [
|
|
718
|
+
{ file: "feature-b.ts", content: "export const b = true;\n", message: "add feature b" },
|
|
719
|
+
]);
|
|
720
|
+
|
|
721
|
+
const roadmap = makeRoadmap("M293", "Planted MERGE_HEAD", [
|
|
722
|
+
{ id: "S01", title: "Feature B" },
|
|
723
|
+
]);
|
|
724
|
+
|
|
725
|
+
// Plant a fake MERGE_HEAD in the git dir to simulate libgit2 behavior.
|
|
726
|
+
// We need to do this after the function checks out main but before it
|
|
727
|
+
// commits. Since we can't intercept mid-function, we plant it before
|
|
728
|
+
// the call. If the function cleans it up, the test passes.
|
|
729
|
+
const gitDir = join(repo, ".git");
|
|
730
|
+
const fakeHead = run("git rev-parse HEAD", repo);
|
|
731
|
+
writeFileSync(join(gitDir, "MERGE_HEAD"), fakeHead + "\n");
|
|
732
|
+
|
|
733
|
+
mergeMilestoneToMain(repo, "M293", roadmap);
|
|
734
|
+
|
|
735
|
+
// The planted MERGE_HEAD must be cleaned up
|
|
736
|
+
assert.ok(
|
|
737
|
+
!existsSync(join(gitDir, "MERGE_HEAD")),
|
|
738
|
+
"#2912: planted MERGE_HEAD must be removed by success-path cleanup",
|
|
739
|
+
);
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
test("#2912: stale SQUASH_MSG and MERGE_MSG are cleaned before squash merge", () => {
|
|
743
|
+
// Verifies that the pre-merge cleanup (step 7b) removes all three merge
|
|
744
|
+
// artifacts — not just MERGE_HEAD — so that `git merge --squash` never
|
|
745
|
+
// encounters leftover state from a prior interrupted operation.
|
|
746
|
+
const repo = freshRepo();
|
|
747
|
+
const wtPath = createAutoWorktree(repo, "M294");
|
|
748
|
+
|
|
749
|
+
addSliceToMilestone(repo, wtPath, "M294", "S01", "Feature C", [
|
|
750
|
+
{ file: "feature-c.ts", content: "export const c = true;\n", message: "add feature c" },
|
|
751
|
+
]);
|
|
752
|
+
|
|
753
|
+
const roadmap = makeRoadmap("M294", "Stale merge artifacts", [
|
|
754
|
+
{ id: "S01", title: "Feature C" },
|
|
755
|
+
]);
|
|
756
|
+
|
|
757
|
+
// Plant stale merge artifacts in the git dir to simulate a prior
|
|
758
|
+
// interrupted merge. The pre-merge cleanup must remove all of them.
|
|
759
|
+
const gitDir = join(repo, ".git");
|
|
760
|
+
writeFileSync(join(gitDir, "SQUASH_MSG"), "stale squash message\n");
|
|
761
|
+
writeFileSync(join(gitDir, "MERGE_MSG"), "stale merge message\n");
|
|
762
|
+
|
|
763
|
+
mergeMilestoneToMain(repo, "M294", roadmap);
|
|
764
|
+
|
|
765
|
+
assert.ok(
|
|
766
|
+
!existsSync(join(gitDir, "SQUASH_MSG")),
|
|
767
|
+
"#2912: stale SQUASH_MSG must be removed by pre-merge cleanup",
|
|
768
|
+
);
|
|
769
|
+
assert.ok(
|
|
770
|
+
!existsSync(join(gitDir, "MERGE_MSG")),
|
|
771
|
+
"#2912: stale MERGE_MSG must be removed by pre-merge cleanup",
|
|
772
|
+
);
|
|
773
|
+
});
|
|
774
|
+
|
|
641
775
|
test("#1906: codeFilesChanged=true when real code is merged", () => {
|
|
642
776
|
const repo = freshRepo();
|
|
643
777
|
const wtPath = createAutoWorktree(repo, "M190");
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
enterAutoWorktree,
|
|
21
21
|
getAutoWorktreeOriginalBase,
|
|
22
22
|
getActiveAutoWorktreeContext,
|
|
23
|
+
syncGsdStateToWorktree,
|
|
23
24
|
} from "../../auto-worktree.ts";
|
|
24
25
|
|
|
25
26
|
// Note: execSync is used intentionally in tests for git operations with
|
|
@@ -286,4 +287,62 @@ describe("auto-worktree lifecycle", () => {
|
|
|
286
287
|
teardownAutoWorktree(tempDir, "M004");
|
|
287
288
|
}
|
|
288
289
|
});
|
|
290
|
+
|
|
291
|
+
test("#2791: mcp.json copied into worktree via copyPlanningArtifacts", () => {
|
|
292
|
+
tempDir = createTempRepo();
|
|
293
|
+
const msDir = join(tempDir, ".gsd", "milestones", "M003");
|
|
294
|
+
mkdirSync(msDir, { recursive: true });
|
|
295
|
+
writeFileSync(join(msDir, "CONTEXT.md"), "# M003 Context\n");
|
|
296
|
+
run("git add .", tempDir);
|
|
297
|
+
run("git commit -m \"add milestone\"", tempDir);
|
|
298
|
+
|
|
299
|
+
// Create mcp.json in .gsd/ AFTER the commit (untracked, like real usage).
|
|
300
|
+
// copyPlanningArtifacts should copy it into the worktree's .gsd/.
|
|
301
|
+
writeFileSync(
|
|
302
|
+
join(tempDir, ".gsd", "mcp.json"),
|
|
303
|
+
JSON.stringify({ servers: { test: { command: "echo" } } }),
|
|
304
|
+
);
|
|
305
|
+
|
|
306
|
+
const wtPath = createAutoWorktree(tempDir, "M003");
|
|
307
|
+
|
|
308
|
+
try {
|
|
309
|
+
assert.ok(
|
|
310
|
+
existsSync(join(wtPath, ".gsd", "mcp.json")),
|
|
311
|
+
"mcp.json should be copied into worktree .gsd/ on creation",
|
|
312
|
+
);
|
|
313
|
+
} finally {
|
|
314
|
+
teardownAutoWorktree(tempDir, "M003");
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
test("#2791: mcp.json synced via syncGsdStateToWorktree (ROOT_STATE_FILES)", () => {
|
|
319
|
+
tempDir = createTempRepo();
|
|
320
|
+
const msDir = join(tempDir, ".gsd", "milestones", "M003");
|
|
321
|
+
mkdirSync(msDir, { recursive: true });
|
|
322
|
+
writeFileSync(join(msDir, "CONTEXT.md"), "# M003 Context\n");
|
|
323
|
+
run("git add .", tempDir);
|
|
324
|
+
run("git commit -m \"add milestone\"", tempDir);
|
|
325
|
+
|
|
326
|
+
// Create worktree first (no mcp.json yet)
|
|
327
|
+
const wtPath = createAutoWorktree(tempDir, "M003");
|
|
328
|
+
|
|
329
|
+
try {
|
|
330
|
+
// Now add mcp.json to the main .gsd/ after worktree was created
|
|
331
|
+
writeFileSync(
|
|
332
|
+
join(tempDir, ".gsd", "mcp.json"),
|
|
333
|
+
JSON.stringify({ servers: { test: { command: "echo" } } }),
|
|
334
|
+
);
|
|
335
|
+
|
|
336
|
+
// Sync should pick up the new mcp.json
|
|
337
|
+
const { synced } = syncGsdStateToWorktree(tempDir, wtPath);
|
|
338
|
+
|
|
339
|
+
assert.ok(synced.includes("mcp.json"), "mcp.json should be in the synced list");
|
|
340
|
+
assert.ok(
|
|
341
|
+
existsSync(join(wtPath, ".gsd", "mcp.json")),
|
|
342
|
+
"mcp.json should exist in worktree after sync",
|
|
343
|
+
);
|
|
344
|
+
} finally {
|
|
345
|
+
teardownAutoWorktree(tempDir, "M003");
|
|
346
|
+
}
|
|
347
|
+
});
|
|
289
348
|
});
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { describe, test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { mkdtempSync, mkdirSync, rmSync, writeFileSync, existsSync, readdirSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
|
|
7
|
+
import { runGSDDoctor } from "../../doctor.js";
|
|
8
|
+
import { parsePlan } from "../../parsers-legacy.js";
|
|
9
|
+
|
|
10
|
+
// ── Helpers ─────────────────────────────────────────────────────────────────
|
|
11
|
+
|
|
12
|
+
function makeBase(): { base: string; gsd: string; mDir: string } {
|
|
13
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-fp-"));
|
|
14
|
+
const gsd = join(base, ".gsd");
|
|
15
|
+
const mDir = join(gsd, "milestones", "M001");
|
|
16
|
+
mkdirSync(join(mDir, "slices"), { recursive: true });
|
|
17
|
+
return { base, gsd, mDir };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function writeRoadmap(mDir: string, content: string): void {
|
|
21
|
+
writeFileSync(join(mDir, "M001-ROADMAP.md"), content);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function writeSlice(mDir: string, sliceId: string, planContent: string): string {
|
|
25
|
+
const sDir = join(mDir, "slices", sliceId);
|
|
26
|
+
const tDir = join(sDir, "tasks");
|
|
27
|
+
mkdirSync(tDir, { recursive: true });
|
|
28
|
+
writeFileSync(join(sDir, `${sliceId}-PLAN.md`), planContent);
|
|
29
|
+
return sDir;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
describe('doctor false-positives (#3105)', async () => {
|
|
33
|
+
|
|
34
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
35
|
+
// Bug 1: Orphaned worktree directory recreated by appendDoctorHistory
|
|
36
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
37
|
+
|
|
38
|
+
test('Bug 1: orphaned worktree check ignores dirs containing only .gsd/doctor-history.jsonl', async () => {
|
|
39
|
+
// Simulate: a worktree dir that only contains .gsd/doctor-history.jsonl
|
|
40
|
+
// (created by appendDoctorHistory writing to the worktree-scoped path).
|
|
41
|
+
// The orphan check should NOT warn about this directory.
|
|
42
|
+
const { base, gsd } = makeBase();
|
|
43
|
+
writeRoadmap(join(gsd, "milestones", "M001"), `# M001: Test\n\n## Slices\n- [ ] **S01: Slice** \`risk:low\` \`depends:[]\`\n > After this: done\n`);
|
|
44
|
+
writeSlice(join(gsd, "milestones", "M001"), "S01", "# S01: Slice\n\n**Goal:** G\n**Demo:** D\n\n## Tasks\n- [ ] **T01: Task** `est:10m`\n Pending.\n");
|
|
45
|
+
|
|
46
|
+
// Create a worktree directory that only has .gsd/doctor-history.jsonl
|
|
47
|
+
const wtDir = join(gsd, "worktrees", "M042");
|
|
48
|
+
const wtGsdDir = join(wtDir, ".gsd");
|
|
49
|
+
mkdirSync(wtGsdDir, { recursive: true });
|
|
50
|
+
writeFileSync(join(wtGsdDir, "doctor-history.jsonl"), '{"ts":"2026-01-01","ok":true}\n');
|
|
51
|
+
|
|
52
|
+
const result = await runGSDDoctor(base, { fix: false });
|
|
53
|
+
|
|
54
|
+
// Should NOT produce worktree_directory_orphaned for a dir that only has doctor history
|
|
55
|
+
const orphanIssues = result.issues.filter(
|
|
56
|
+
i => i.code === "worktree_directory_orphaned" && i.unitId === "M042"
|
|
57
|
+
);
|
|
58
|
+
assert.equal(orphanIssues.length, 0,
|
|
59
|
+
"should not warn about worktree dir that only contains .gsd/doctor-history.jsonl");
|
|
60
|
+
|
|
61
|
+
rmSync(base, { recursive: true, force: true });
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
65
|
+
// Bug 2: blocker_discovered + all tasks done = unfixable deadlock
|
|
66
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
67
|
+
|
|
68
|
+
test('Bug 2: blocker_discovered with all tasks done should not warn (implicitly resolved)', async () => {
|
|
69
|
+
// Scenario: blocker was discovered and resolved within the same task.
|
|
70
|
+
// blocker_discovered: true, no REPLAN, but all tasks are done.
|
|
71
|
+
// Neither blocker_discovered_no_replan nor stale_replan_file should fire.
|
|
72
|
+
const { base, mDir } = makeBase();
|
|
73
|
+
writeRoadmap(mDir, `# M001: Blocker Test\n\n## Slices\n- [ ] **S01: Slice** \`risk:low\` \`depends:[]\`\n > After this: done\n`);
|
|
74
|
+
const sDir = writeSlice(mDir, "S01",
|
|
75
|
+
"# S01: Slice\n\n**Goal:** G\n**Demo:** D\n\n## Tasks\n- [x] **T01: Task** `est:10m`\n Done.\n");
|
|
76
|
+
writeFileSync(join(sDir, "tasks", "T01-SUMMARY.md"), `---
|
|
77
|
+
id: T01
|
|
78
|
+
parent: S01
|
|
79
|
+
milestone: M001
|
|
80
|
+
provides: []
|
|
81
|
+
requires: []
|
|
82
|
+
affects: []
|
|
83
|
+
key_files: []
|
|
84
|
+
key_decisions: []
|
|
85
|
+
patterns_established: []
|
|
86
|
+
observability_surfaces: []
|
|
87
|
+
drill_down_paths: []
|
|
88
|
+
duration: 10m
|
|
89
|
+
verification_result: passed
|
|
90
|
+
completed_at: 2026-01-01T00:00:00Z
|
|
91
|
+
blocker_discovered: true
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
# T01: Task
|
|
95
|
+
|
|
96
|
+
**Done**
|
|
97
|
+
|
|
98
|
+
## What Happened
|
|
99
|
+
Found a blocker, resolved it in-task.
|
|
100
|
+
|
|
101
|
+
## Diagnostics
|
|
102
|
+
- log
|
|
103
|
+
`);
|
|
104
|
+
|
|
105
|
+
const result = await runGSDDoctor(base, { fix: false });
|
|
106
|
+
|
|
107
|
+
// Should NOT produce blocker_discovered_no_replan when all tasks are done
|
|
108
|
+
const blockerIssues = result.issues.filter(i => i.code === "blocker_discovered_no_replan");
|
|
109
|
+
assert.equal(blockerIssues.length, 0,
|
|
110
|
+
"should not warn about blocker_discovered when all tasks are done (blocker was implicitly resolved)");
|
|
111
|
+
|
|
112
|
+
// Also should NOT produce stale_replan_file (no REPLAN exists, so this shouldn't fire anyway)
|
|
113
|
+
const staleReplanIssues = result.issues.filter(i => i.code === "stale_replan_file");
|
|
114
|
+
assert.equal(staleReplanIssues.length, 0,
|
|
115
|
+
"should not produce stale_replan_file when no REPLAN exists");
|
|
116
|
+
|
|
117
|
+
rmSync(base, { recursive: true, force: true });
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test('Bug 2: blocker_discovered with incomplete tasks should still warn', async () => {
|
|
121
|
+
// Sanity check: when there IS an incomplete task and blocker_discovered, warn as before.
|
|
122
|
+
const { base, mDir } = makeBase();
|
|
123
|
+
writeRoadmap(mDir, `# M001: Blocker Warn Test\n\n## Slices\n- [ ] **S01: Slice** \`risk:low\` \`depends:[]\`\n > After this: done\n`);
|
|
124
|
+
const sDir = writeSlice(mDir, "S01",
|
|
125
|
+
"# S01: Slice\n\n**Goal:** G\n**Demo:** D\n\n## Tasks\n- [x] **T01: Task A** `est:10m`\n Done.\n- [ ] **T02: Task B** `est:10m`\n Pending.\n");
|
|
126
|
+
writeFileSync(join(sDir, "tasks", "T01-SUMMARY.md"), `---
|
|
127
|
+
id: T01
|
|
128
|
+
parent: S01
|
|
129
|
+
milestone: M001
|
|
130
|
+
provides: []
|
|
131
|
+
requires: []
|
|
132
|
+
affects: []
|
|
133
|
+
key_files: []
|
|
134
|
+
key_decisions: []
|
|
135
|
+
patterns_established: []
|
|
136
|
+
observability_surfaces: []
|
|
137
|
+
drill_down_paths: []
|
|
138
|
+
duration: 10m
|
|
139
|
+
verification_result: passed
|
|
140
|
+
completed_at: 2026-01-01T00:00:00Z
|
|
141
|
+
blocker_discovered: true
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
# T01: Task A
|
|
145
|
+
|
|
146
|
+
**Done**
|
|
147
|
+
|
|
148
|
+
## What Happened
|
|
149
|
+
Found blocker, but T02 is still pending.
|
|
150
|
+
|
|
151
|
+
## Diagnostics
|
|
152
|
+
- log
|
|
153
|
+
`);
|
|
154
|
+
|
|
155
|
+
const result = await runGSDDoctor(base, { fix: false });
|
|
156
|
+
|
|
157
|
+
const blockerIssues = result.issues.filter(i => i.code === "blocker_discovered_no_replan");
|
|
158
|
+
assert.ok(blockerIssues.length > 0,
|
|
159
|
+
"should still warn about blocker_discovered when some tasks are not done");
|
|
160
|
+
|
|
161
|
+
rmSync(base, { recursive: true, force: true });
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
165
|
+
// Bug 3: Multi-task plan — T02+ outside ## Tasks section
|
|
166
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
167
|
+
|
|
168
|
+
test('Bug 3: parsePlan finds all tasks even when interleaved with detail sections', () => {
|
|
169
|
+
// Multi-task plan where T02 checkbox appears after T01's ## Steps heading,
|
|
170
|
+
// which ends the ## Tasks section for extractSection().
|
|
171
|
+
const planContent = `# S01: Demo Slice
|
|
172
|
+
|
|
173
|
+
**Goal:** Build the demo
|
|
174
|
+
**Demo:** Run it
|
|
175
|
+
|
|
176
|
+
## Must-Haves
|
|
177
|
+
- Feature A
|
|
178
|
+
|
|
179
|
+
## Tasks
|
|
180
|
+
- [x] **T01: First task** \`est:30m\`
|
|
181
|
+
Implement the first thing.
|
|
182
|
+
## Steps
|
|
183
|
+
1. Step one
|
|
184
|
+
2. Step two
|
|
185
|
+
## Must-Haves
|
|
186
|
+
- Requirement A
|
|
187
|
+
- [x] **T02: Second task** \`est:1h\`
|
|
188
|
+
Implement the second thing.
|
|
189
|
+
## Steps
|
|
190
|
+
1. Step one
|
|
191
|
+
2. Step two
|
|
192
|
+
`;
|
|
193
|
+
|
|
194
|
+
const plan = parsePlan(planContent);
|
|
195
|
+
const taskIds = plan.tasks.map(t => t.id);
|
|
196
|
+
|
|
197
|
+
assert.ok(taskIds.includes("T01"), "should find T01");
|
|
198
|
+
assert.ok(taskIds.includes("T02"), "should find T02 even when after T01 detail headings");
|
|
199
|
+
assert.equal(plan.tasks.length, 2, "should find exactly 2 tasks");
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test('Bug 3: task_file_not_in_plan should not fire for T02 in multi-task plan', async () => {
|
|
203
|
+
const { base, mDir } = makeBase();
|
|
204
|
+
writeRoadmap(mDir, `# M001: Multi-Task Test\n\n## Slices\n- [ ] **S01: Slice** \`risk:low\` \`depends:[]\`\n > After this: done\n`);
|
|
205
|
+
|
|
206
|
+
// Plan with interleaved headings (the problematic format)
|
|
207
|
+
const sDir = writeSlice(mDir, "S01", `# S01: Demo Slice
|
|
208
|
+
|
|
209
|
+
**Goal:** Build the demo
|
|
210
|
+
**Demo:** Run it
|
|
211
|
+
|
|
212
|
+
## Must-Haves
|
|
213
|
+
- Feature A
|
|
214
|
+
|
|
215
|
+
## Tasks
|
|
216
|
+
- [x] **T01: First task** \`est:30m\`
|
|
217
|
+
Implement the first thing.
|
|
218
|
+
## Steps
|
|
219
|
+
1. Step one
|
|
220
|
+
## Must-Haves
|
|
221
|
+
- Req A
|
|
222
|
+
- [x] **T02: Second task** \`est:1h\`
|
|
223
|
+
Implement the second thing.
|
|
224
|
+
## Steps
|
|
225
|
+
1. Step one
|
|
226
|
+
`);
|
|
227
|
+
|
|
228
|
+
// Both tasks have summaries on disk
|
|
229
|
+
writeFileSync(join(sDir, "tasks", "T01-SUMMARY.md"), "---\nstatus: done\ncompleted_at: 2026-01-01T00:00:00Z\n---\n# T01\nDone.\n");
|
|
230
|
+
writeFileSync(join(sDir, "tasks", "T02-SUMMARY.md"), "---\nstatus: done\ncompleted_at: 2026-01-01T00:00:00Z\n---\n# T02\nDone.\n");
|
|
231
|
+
|
|
232
|
+
const result = await runGSDDoctor(base, { fix: false });
|
|
233
|
+
|
|
234
|
+
// T02 should NOT be flagged as "not in plan"
|
|
235
|
+
const notInPlan = result.issues.filter(
|
|
236
|
+
i => i.code === "task_file_not_in_plan" && i.message.includes("T02")
|
|
237
|
+
);
|
|
238
|
+
assert.equal(notInPlan.length, 0,
|
|
239
|
+
"should not report T02 as 'not in plan' when it exists in the interleaved plan format");
|
|
240
|
+
|
|
241
|
+
rmSync(base, { recursive: true, force: true });
|
|
242
|
+
});
|
|
243
|
+
});
|
|
@@ -645,6 +645,78 @@ describe('doctor-git', async () => {
|
|
|
645
645
|
} else {
|
|
646
646
|
}
|
|
647
647
|
|
|
648
|
+
// ─── Test: stale_uncommitted_changes detection & auto-snapshot ──────
|
|
649
|
+
test('stale_uncommitted_changes (detected and auto-committed)', async () => {
|
|
650
|
+
const dir = createRepoWithActiveMilestone();
|
|
651
|
+
cleanups.push(dir);
|
|
652
|
+
|
|
653
|
+
// Make the last commit appear old by amending its date to 45 min ago
|
|
654
|
+
const pastDate = new Date(Date.now() - 45 * 60 * 1000).toISOString();
|
|
655
|
+
run(`git commit --amend --no-edit --date="${pastDate}"`, dir);
|
|
656
|
+
// Also set committer date so git log %ct reflects it
|
|
657
|
+
execSync(`git commit --amend --no-edit`, {
|
|
658
|
+
cwd: dir,
|
|
659
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
660
|
+
encoding: "utf-8",
|
|
661
|
+
env: { ...process.env, GIT_COMMITTER_DATE: pastDate },
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
// Modify an already-tracked file (nativeAddTracked uses git add -u,
|
|
665
|
+
// which only stages tracked files — new untracked files are not staged)
|
|
666
|
+
writeFileSync(join(dir, "README.md"), "# test\nmodified content\n");
|
|
667
|
+
|
|
668
|
+
const detect = await runGSDDoctor(dir);
|
|
669
|
+
const staleIssues = detect.issues.filter(i => i.code === "stale_uncommitted_changes");
|
|
670
|
+
assert.ok(staleIssues.length > 0, "detects stale uncommitted changes");
|
|
671
|
+
assert.ok(staleIssues[0]?.message.includes("minute"), "message mentions minutes");
|
|
672
|
+
assert.ok(staleIssues[0]?.fixable === true, "stale uncommitted changes is fixable");
|
|
673
|
+
|
|
674
|
+
// Fix should create a gsd snapshot commit
|
|
675
|
+
const fixed = await runGSDDoctor(dir, { fix: true });
|
|
676
|
+
assert.ok(
|
|
677
|
+
fixed.fixesApplied.some(f => f.includes("gsd snapshot")),
|
|
678
|
+
"fix creates a gsd snapshot commit",
|
|
679
|
+
);
|
|
680
|
+
|
|
681
|
+
// Verify the snapshot commit was created with the gsd snapshot tag
|
|
682
|
+
const log = run("git log -1 --oneline", dir);
|
|
683
|
+
assert.ok(log.includes("gsd snapshot"), "commit is tagged with gsd snapshot");
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
// ─── Test: stale_uncommitted_changes NOT flagged when recent commit ──
|
|
687
|
+
test('stale_uncommitted_changes (no false positive on recent commit)', async () => {
|
|
688
|
+
const dir = createRepoWithActiveMilestone();
|
|
689
|
+
cleanups.push(dir);
|
|
690
|
+
|
|
691
|
+
// Create uncommitted changes (but last commit is fresh — just created)
|
|
692
|
+
writeFileSync(join(dir, "fresh-dirty.txt"), "recent changes\n");
|
|
693
|
+
|
|
694
|
+
const detect = await runGSDDoctor(dir);
|
|
695
|
+
const staleIssues = detect.issues.filter(i => i.code === "stale_uncommitted_changes");
|
|
696
|
+
assert.deepStrictEqual(staleIssues.length, 0, "recent commit with dirty tree NOT flagged as stale");
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
// ─── Test: stale_uncommitted_changes NOT flagged when tree is clean ──
|
|
700
|
+
test('stale_uncommitted_changes (no false positive on clean tree)', async () => {
|
|
701
|
+
const dir = createRepoWithActiveMilestone();
|
|
702
|
+
cleanups.push(dir);
|
|
703
|
+
|
|
704
|
+
// Make the last commit appear old
|
|
705
|
+
const pastDate = new Date(Date.now() - 45 * 60 * 1000).toISOString();
|
|
706
|
+
run(`git commit --amend --no-edit --date="${pastDate}"`, dir);
|
|
707
|
+
execSync(`git commit --amend --no-edit`, {
|
|
708
|
+
cwd: dir,
|
|
709
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
710
|
+
encoding: "utf-8",
|
|
711
|
+
env: { ...process.env, GIT_COMMITTER_DATE: pastDate },
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
// No uncommitted changes — tree is clean
|
|
715
|
+
const detect = await runGSDDoctor(dir);
|
|
716
|
+
const staleIssues = detect.issues.filter(i => i.code === "stale_uncommitted_changes");
|
|
717
|
+
assert.deepStrictEqual(staleIssues.length, 0, "old commit with clean tree NOT flagged as stale");
|
|
718
|
+
});
|
|
719
|
+
|
|
648
720
|
} finally {
|
|
649
721
|
for (const dir of cleanups) {
|
|
650
722
|
try { rmSync(dir, { recursive: true, force: true }); } catch { /* ignore */ }
|
|
@@ -1455,4 +1455,72 @@ describe('git-service', async () => {
|
|
|
1455
1455
|
try { rmSync(repo, { recursive: true, force: true }); } catch {}
|
|
1456
1456
|
try { rmSync(externalGsd, { recursive: true, force: true }); } catch {}
|
|
1457
1457
|
});
|
|
1458
|
+
|
|
1459
|
+
// ─── autoCommit: absorbs preceding gsd snapshot commits ─────────────────
|
|
1460
|
+
|
|
1461
|
+
test('autoCommit: absorbs preceding gsd snapshot commits', () => {
|
|
1462
|
+
const repo = initTempRepo();
|
|
1463
|
+
|
|
1464
|
+
// Simulate 2 gsd snapshot commits
|
|
1465
|
+
createFile(repo, "file1.ts", "v1");
|
|
1466
|
+
run("git add -A", repo);
|
|
1467
|
+
run('git commit -m "gsd snapshot: uncommitted changes after 35m inactivity"', repo);
|
|
1468
|
+
|
|
1469
|
+
createFile(repo, "file2.ts", "v2");
|
|
1470
|
+
run("git add -A", repo);
|
|
1471
|
+
run('git commit -m "gsd snapshot: pre-dispatch, uncommitted changes after 40m inactivity"', repo);
|
|
1472
|
+
|
|
1473
|
+
// Verify we have 3 commits (init + 2 snapshots)
|
|
1474
|
+
const countBefore = run("git rev-list --count HEAD", repo);
|
|
1475
|
+
assert.deepStrictEqual(countBefore, "3", "precondition: 3 commits before autoCommit");
|
|
1476
|
+
|
|
1477
|
+
// Now make a real change and autoCommit
|
|
1478
|
+
createFile(repo, "feature.ts", "real work");
|
|
1479
|
+
|
|
1480
|
+
const svc = new GitServiceImpl(repo);
|
|
1481
|
+
const msg = svc.autoCommit("execute-task", "S01/T01");
|
|
1482
|
+
assert.ok(msg !== null, "autoCommit succeeds");
|
|
1483
|
+
|
|
1484
|
+
// Should be 2 commits: init + squashed real commit (snapshots absorbed)
|
|
1485
|
+
const countAfter = run("git rev-list --count HEAD", repo);
|
|
1486
|
+
assert.deepStrictEqual(countAfter, "2", "snapshot commits absorbed into real commit");
|
|
1487
|
+
|
|
1488
|
+
// All files should be present
|
|
1489
|
+
const files = run("git show --name-only HEAD", repo);
|
|
1490
|
+
assert.ok(files.includes("file1.ts"), "file1.ts from snapshot 1 preserved");
|
|
1491
|
+
assert.ok(files.includes("file2.ts"), "file2.ts from snapshot 2 preserved");
|
|
1492
|
+
assert.ok(files.includes("feature.ts"), "feature.ts from real commit preserved");
|
|
1493
|
+
|
|
1494
|
+
// No gsd snapshot commits in log
|
|
1495
|
+
const log = run("git log --oneline", repo);
|
|
1496
|
+
assert.ok(!log.includes("gsd snapshot"), "no gsd snapshot commits remain in history");
|
|
1497
|
+
|
|
1498
|
+
rmSync(repo, { recursive: true, force: true });
|
|
1499
|
+
});
|
|
1500
|
+
|
|
1501
|
+
// ─── autoCommit: does not absorb non-snapshot commits ───────────────────
|
|
1502
|
+
|
|
1503
|
+
test('autoCommit: does not absorb non-snapshot commits', () => {
|
|
1504
|
+
const repo = initTempRepo();
|
|
1505
|
+
|
|
1506
|
+
// Create a normal (non-snapshot) commit
|
|
1507
|
+
createFile(repo, "earlier.ts", "earlier work");
|
|
1508
|
+
run("git add -A", repo);
|
|
1509
|
+
run('git commit -m "feat: earlier work"', repo);
|
|
1510
|
+
|
|
1511
|
+
const countBefore = run("git rev-list --count HEAD", repo);
|
|
1512
|
+
assert.deepStrictEqual(countBefore, "2", "precondition: 2 commits before autoCommit");
|
|
1513
|
+
|
|
1514
|
+
// Make a real change and autoCommit
|
|
1515
|
+
createFile(repo, "feature.ts", "new work");
|
|
1516
|
+
|
|
1517
|
+
const svc = new GitServiceImpl(repo);
|
|
1518
|
+
svc.autoCommit("execute-task", "S01/T02");
|
|
1519
|
+
|
|
1520
|
+
// Should be 3 commits — earlier commit not absorbed
|
|
1521
|
+
const countAfter = run("git rev-list --count HEAD", repo);
|
|
1522
|
+
assert.deepStrictEqual(countAfter, "3", "non-snapshot commits NOT absorbed");
|
|
1523
|
+
|
|
1524
|
+
rmSync(repo, { recursive: true, force: true });
|
|
1525
|
+
});
|
|
1458
1526
|
});
|