gsd-pi 2.80.0-dev.c5f2443b3 → 2.80.0-dev.d4fc28e6b
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 +4 -2
- package/dist/cli.js +0 -19
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +2 -2
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +29 -0
- package/dist/resources/extensions/github-sync/templates.js +39 -8
- package/dist/resources/extensions/gsd/auto/loop.js +119 -18
- package/dist/resources/extensions/gsd/auto/phases.js +212 -135
- package/dist/resources/extensions/gsd/auto/resolve.js +29 -0
- package/dist/resources/extensions/gsd/auto/run-unit.js +41 -45
- package/dist/resources/extensions/gsd/auto/session.js +8 -0
- package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
- package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
- package/dist/resources/extensions/gsd/auto-dashboard.js +51 -15
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
- package/dist/resources/extensions/gsd/auto-dispatch.js +26 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +27 -14
- package/dist/resources/extensions/gsd/auto-prompts.js +214 -17
- package/dist/resources/extensions/gsd/auto-recovery.js +197 -9
- package/dist/resources/extensions/gsd/auto-start.js +199 -9
- package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +111 -1
- package/dist/resources/extensions/gsd/auto.js +95 -27
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +103 -3
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +49 -36
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +15 -5
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +33 -20
- package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +7 -1
- package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +9 -3
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +8 -2
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +330 -55
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +129 -1
- package/dist/resources/extensions/gsd/clean-root-preflight.js +65 -9
- package/dist/resources/extensions/gsd/commands/dispatcher.js +5 -0
- package/dist/resources/extensions/gsd/commands-extract-learnings.js +17 -12
- package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
- package/dist/resources/extensions/gsd/context-budget.js +37 -2
- package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +22 -2
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +92 -0
- package/dist/resources/extensions/gsd/db-base-schema.js +18 -2
- package/dist/resources/extensions/gsd/db-migration-steps.js +22 -0
- package/dist/resources/extensions/gsd/detection.js +106 -0
- package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
- package/dist/resources/extensions/gsd/git-service.js +36 -4
- package/dist/resources/extensions/gsd/graph.js +9 -3
- package/dist/resources/extensions/gsd/gsd-db.js +146 -13
- package/dist/resources/extensions/gsd/guided-flow.js +129 -44
- package/dist/resources/extensions/gsd/memory-store.js +69 -12
- package/dist/resources/extensions/gsd/migrate/command.js +40 -1
- package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
- package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
- package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
- package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
- package/dist/resources/extensions/gsd/pr-evidence.js +57 -16
- package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/dist/resources/extensions/gsd/quick.js +34 -2
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
- package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
- package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
- package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
- package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
- package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
- package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
- package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
- package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
- package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
- package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
- package/dist/resources/extensions/gsd/working-output-messages.js +64 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
- package/dist/resources/extensions/gsd/worktree-resolver.js +68 -21
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
- 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/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- 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 +1 -1
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
- package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
- 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 +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/{8336.6f6f30e410419aff.js → 8336.631939fb583761fa.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-d82dbee6356c1733.js → webpack-0481f1221120a7c6.js} +1 -1
- package/dist/welcome-screen.d.ts +2 -0
- package/dist/welcome-screen.js +9 -7
- package/package.json +12 -8
- package/packages/contracts/package.json +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +22 -17
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
- package/packages/mcp-server/src/workflow-tools.ts +30 -16
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +4 -1
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +5 -0
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +2 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/dist/index.d.ts +1 -0
- package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/index.js +2 -0
- package/packages/pi-agent-core/dist/index.js.map +1 -1
- package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
- package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
- package/packages/pi-agent-core/dist/token-audit.js +221 -0
- package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
- package/packages/pi-agent-core/dist/types.d.ts +9 -0
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
- package/packages/pi-agent-core/src/agent-loop.ts +4 -1
- package/packages/pi-agent-core/src/agent.ts +8 -0
- package/packages/pi-agent-core/src/index.ts +2 -0
- package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
- package/packages/pi-agent-core/src/token-audit.ts +287 -0
- package/packages/pi-agent-core/src/types.ts +14 -0
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/models/fake-model.d.ts +12 -0
- package/packages/pi-ai/dist/models/fake-model.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/fake-model.js +27 -0
- package/packages/pi-ai/dist/models/fake-model.js.map +1 -0
- package/packages/pi-ai/dist/models/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/index.js +8 -0
- package/packages/pi-ai/dist/models/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/fake.d.ts +42 -0
- package/packages/pi-ai/dist/providers/fake.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/fake.js +319 -0
- package/packages/pi-ai/dist/providers/fake.js.map +1 -0
- package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/register-builtins.js +24 -0
- package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
- package/packages/pi-ai/src/models/fake-model.ts +30 -0
- package/packages/pi-ai/src/models/index.ts +9 -0
- package/packages/pi-ai/src/providers/fake.ts +376 -0
- package/packages/pi-ai/src/providers/register-builtins.ts +23 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +18 -0
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -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 +44 -7
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +76 -0
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -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 +8 -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 +5 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +20 -7
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +102 -3
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +39 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +5 -0
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +74 -2
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +24 -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 +33 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
- package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +54 -15
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +26 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +112 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +51 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -0
- 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.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +10 -9
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +11 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +7 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +17 -0
- 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 +109 -17
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.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 +69 -2
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +93 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +3 -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 +26 -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 +20 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js +79 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +13 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +18 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +36 -27
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts +11 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js +18 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +48 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +10 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
- package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +25 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +48 -7
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +89 -0
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
- package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
- package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
- package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +113 -3
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +24 -6
- package/packages/pi-coding-agent/src/core/extensions/types.ts +42 -1
- package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +4 -0
- package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
- package/packages/pi-coding-agent/src/core/sdk.ts +85 -3
- package/packages/pi-coding-agent/src/core/settings-manager.ts +51 -1
- package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
- package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
- package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +78 -15
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +59 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +160 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +10 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +10 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +122 -17
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +99 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +92 -3
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +28 -0
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.test.ts +95 -0
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +24 -1
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +13 -0
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +32 -2
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +36 -27
- package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +65 -0
- package/packages/pi-coding-agent/src/modes/interactive/tui-mode.ts +29 -0
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +14 -0
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/style.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/style.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/style.test.js +63 -0
- package/packages/pi-tui/dist/__tests__/style.test.js.map +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js +24 -3
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/index.d.ts +1 -0
- package/packages/pi-tui/dist/index.d.ts.map +1 -1
- package/packages/pi-tui/dist/index.js +2 -0
- package/packages/pi-tui/dist/index.js.map +1 -1
- package/packages/pi-tui/dist/style.d.ts +41 -0
- package/packages/pi-tui/dist/style.d.ts.map +1 -0
- package/packages/pi-tui/dist/style.js +158 -0
- package/packages/pi-tui/dist/style.js.map +1 -0
- package/packages/pi-tui/dist/tui.d.ts +0 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +21 -16
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/__tests__/style.test.ts +76 -0
- package/packages/pi-tui/src/__tests__/tui.test.ts +29 -3
- package/packages/pi-tui/src/index.ts +9 -0
- package/packages/pi-tui/src/style.ts +225 -0
- package/packages/pi-tui/src/tui.ts +23 -16
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
- package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme-schema.js +13 -0
- package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
- package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.js +18 -1
- package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js +36 -27
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- package/src/resources/GSD-WORKFLOW.md +2 -2
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +30 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +26 -0
- package/src/resources/extensions/github-sync/templates.ts +38 -8
- package/src/resources/extensions/github-sync/tests/inline-code.test.ts +66 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -2
- package/src/resources/extensions/gsd/auto/loop.ts +151 -26
- package/src/resources/extensions/gsd/auto/phases.ts +289 -196
- package/src/resources/extensions/gsd/auto/resolve.ts +42 -1
- package/src/resources/extensions/gsd/auto/run-unit.ts +52 -44
- package/src/resources/extensions/gsd/auto/session.ts +8 -0
- package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
- package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
- package/src/resources/extensions/gsd/auto-dashboard.ts +57 -8
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
- package/src/resources/extensions/gsd/auto-dispatch.ts +33 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +28 -14
- package/src/resources/extensions/gsd/auto-prompts.ts +228 -16
- package/src/resources/extensions/gsd/auto-recovery.ts +207 -7
- package/src/resources/extensions/gsd/auto-start.ts +237 -15
- package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +123 -0
- package/src/resources/extensions/gsd/auto.ts +110 -22
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +119 -2
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +50 -36
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +16 -5
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +34 -19
- package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +8 -1
- package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +10 -3
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +9 -2
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +386 -55
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +135 -1
- package/src/resources/extensions/gsd/clean-root-preflight.ts +72 -9
- package/src/resources/extensions/gsd/commands/dispatcher.ts +6 -0
- package/src/resources/extensions/gsd/commands-extract-learnings.ts +17 -12
- package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
- package/src/resources/extensions/gsd/context-budget.ts +44 -2
- package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +24 -1
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +107 -0
- package/src/resources/extensions/gsd/db-base-schema.ts +19 -2
- package/src/resources/extensions/gsd/db-migration-steps.ts +25 -0
- package/src/resources/extensions/gsd/detection.ts +128 -0
- package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
- package/src/resources/extensions/gsd/git-service.ts +46 -8
- package/src/resources/extensions/gsd/graph.ts +12 -5
- package/src/resources/extensions/gsd/gsd-db.ts +168 -13
- package/src/resources/extensions/gsd/guided-flow.ts +150 -51
- package/src/resources/extensions/gsd/memory-store.ts +77 -12
- package/src/resources/extensions/gsd/migrate/command.ts +47 -1
- package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
- package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
- package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
- package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
- package/src/resources/extensions/gsd/pr-evidence.ts +63 -5
- package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
- package/src/resources/extensions/gsd/preferences-types.ts +1 -1
- package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
- package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/src/resources/extensions/gsd/quick.ts +37 -2
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +516 -15
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +56 -13
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +184 -2
- package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +168 -6
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +97 -2
- package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
- package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +117 -7
- package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +40 -2
- package/src/resources/extensions/gsd/tests/db-migration-steps.integration.test.ts +428 -0
- package/src/resources/extensions/gsd/tests/db-schema-metadata.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
- package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
- package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-basic.md +52 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-empty-optionals.md +42 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +55 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +60 -0
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +239 -1
- package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
- package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
- package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/pr-evidence-equivalence.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/pr-evidence-hardening.test.ts +165 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
- package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
- package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +38 -17
- package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
- package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +166 -0
- package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +101 -2
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/status-db-open.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
- package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +80 -1
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -4
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
- package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/working-output-messages.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +37 -6
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
- package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
- package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +167 -4
- package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +179 -0
- package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
- package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
- package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
- package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
- package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
- package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
- package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
- package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
- package/src/resources/extensions/gsd/working-output-messages.ts +120 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
- package/src/resources/extensions/gsd/worktree-resolver.ts +85 -19
- package/packages/contracts/tsconfig.tsbuildinfo +0 -1
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +0 -97
- /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → cWaxzf-sdbSSbbwYu8q7a}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → cWaxzf-sdbSSbbwYu8q7a}/_ssgManifest.js +0 -0
|
@@ -14,6 +14,27 @@ const CATEGORY_PRIORITY = {
|
|
|
14
14
|
environment: 4,
|
|
15
15
|
preference: 5,
|
|
16
16
|
};
|
|
17
|
+
// ─── Scoring Helpers ─────────────────────────────────────────────────────────
|
|
18
|
+
/**
|
|
19
|
+
* Time-decay factor for memory relevance scoring.
|
|
20
|
+
* Returns 1.0 for never-hit or recently-hit memories, decaying linearly to
|
|
21
|
+
* 0.7 for memories not accessed in 90+ days. Floor at 0.7 keeps old-but-valid
|
|
22
|
+
* knowledge from being fully suppressed.
|
|
23
|
+
*
|
|
24
|
+
* Defensive parsing: invalid timestamp strings (NaN from Date.parse) are
|
|
25
|
+
* treated as "no decay" rather than propagating NaN into score arithmetic.
|
|
26
|
+
* Future timestamps (clock skew, manual DB edits) clamp to daysAgo=0 so the
|
|
27
|
+
* factor stays in the documented [0.7, 1.0] contract.
|
|
28
|
+
*/
|
|
29
|
+
export function memoryDecayFactor(lastHitAt) {
|
|
30
|
+
if (!lastHitAt)
|
|
31
|
+
return 1.0;
|
|
32
|
+
const ts = Date.parse(lastHitAt);
|
|
33
|
+
if (!Number.isFinite(ts))
|
|
34
|
+
return 1.0;
|
|
35
|
+
const daysAgo = Math.max(0, (Date.now() - ts) / 86_400_000);
|
|
36
|
+
return Math.max(0.7, 1.0 - 0.3 * Math.min(1.0, daysAgo / 90));
|
|
37
|
+
}
|
|
17
38
|
// ─── Row Mapping ────────────────────────────────────────────────────────────
|
|
18
39
|
function rowToMemory(row) {
|
|
19
40
|
return {
|
|
@@ -31,6 +52,7 @@ function rowToMemory(row) {
|
|
|
31
52
|
scope: row['scope'] ?? 'project',
|
|
32
53
|
tags: parseTags(row['tags']),
|
|
33
54
|
structured_fields: parseStructuredFields(row['structured_fields']),
|
|
55
|
+
last_hit_at: row['last_hit_at'] ?? null,
|
|
34
56
|
};
|
|
35
57
|
}
|
|
36
58
|
function parseStructuredFields(raw) {
|
|
@@ -114,15 +136,37 @@ export function queryMemoriesRanked(opts) {
|
|
|
114
136
|
? semanticSearch(adapter, opts.queryVector, activeClause, 50)
|
|
115
137
|
: [];
|
|
116
138
|
if (keywordHits.length === 0 && semanticHits.length === 0 && !trimmedQuery) {
|
|
117
|
-
// No query at all —
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
139
|
+
// No query at all — return top-k by decay-aware ranked score.
|
|
140
|
+
//
|
|
141
|
+
// Build the candidate pool from a direct SQL query that honors the
|
|
142
|
+
// request's activeClause (i.e. include_superseded). Using
|
|
143
|
+
// getActiveMemoriesRanked here would silently drop superseded rows even
|
|
144
|
+
// when the caller explicitly opted in, and would slice by raw score
|
|
145
|
+
// before decay/filters had a chance to reorder.
|
|
146
|
+
const candidatePool = Math.min(Math.max(k * 5, 50), 500);
|
|
147
|
+
const rows = adapter
|
|
148
|
+
.prepare(`SELECT * FROM memories ${activeClause}
|
|
149
|
+
ORDER BY (confidence * (1.0 + hit_count * 0.1)) DESC
|
|
150
|
+
LIMIT :limit`)
|
|
151
|
+
.all({ ':limit': candidatePool });
|
|
152
|
+
const ranked = [];
|
|
153
|
+
for (const row of rows) {
|
|
154
|
+
const memory = rowToMemory(row);
|
|
155
|
+
if (!passesFilters(memory, opts))
|
|
156
|
+
continue;
|
|
157
|
+
const decay = memoryDecayFactor(memory.last_hit_at);
|
|
158
|
+
const score = memory.confidence * (1 + memory.hit_count * 0.1) * decay;
|
|
159
|
+
ranked.push({
|
|
160
|
+
memory,
|
|
161
|
+
score,
|
|
162
|
+
keywordRank: null,
|
|
163
|
+
semanticRank: null,
|
|
164
|
+
confidenceBoost: score,
|
|
165
|
+
reason: 'ranked',
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
ranked.sort((a, b) => b.score - a.score);
|
|
169
|
+
return ranked.slice(0, k);
|
|
126
170
|
}
|
|
127
171
|
// 3) Reciprocal rank fusion — each hit contributes 1/(rrfK + rank).
|
|
128
172
|
const fused = new Map();
|
|
@@ -155,7 +199,7 @@ export function queryMemoriesRanked(opts) {
|
|
|
155
199
|
for (const entry of fused.values()) {
|
|
156
200
|
if (!passesFilters(entry.memory, opts))
|
|
157
201
|
continue;
|
|
158
|
-
const boost = entry.memory.confidence * (1 + entry.memory.hit_count * 0.1);
|
|
202
|
+
const boost = entry.memory.confidence * (1 + entry.memory.hit_count * 0.1) * memoryDecayFactor(entry.memory.last_hit_at);
|
|
159
203
|
const reason = entry.kwRank != null && entry.semRank != null
|
|
160
204
|
? 'both'
|
|
161
205
|
: entry.kwRank != null
|
|
@@ -194,6 +238,7 @@ function passesFilters(memory, filters) {
|
|
|
194
238
|
}
|
|
195
239
|
return true;
|
|
196
240
|
}
|
|
241
|
+
let ftsWarningEmitted = false;
|
|
197
242
|
function keywordSearch(adapter, rawQuery, activeClause, limit) {
|
|
198
243
|
const ftsAvailable = isFtsAvailable(adapter);
|
|
199
244
|
if (ftsAvailable) {
|
|
@@ -215,14 +260,26 @@ function keywordSearch(adapter, rawQuery, activeClause, limit) {
|
|
|
215
260
|
// fall through to LIKE
|
|
216
261
|
}
|
|
217
262
|
}
|
|
218
|
-
// LIKE fallback — scans
|
|
263
|
+
// LIKE fallback — scans a capped candidate pool.
|
|
264
|
+
if (!ftsWarningEmitted) {
|
|
265
|
+
ftsWarningEmitted = true;
|
|
266
|
+
logWarning('memory-store', 'FTS5 unavailable — using LIKE fallback scan (consider enabling FTS5)');
|
|
267
|
+
}
|
|
219
268
|
const terms = rawQuery
|
|
220
269
|
.toLowerCase()
|
|
221
270
|
.split(/[^a-z0-9_]+/)
|
|
222
271
|
.filter((t) => t.length >= 2);
|
|
223
272
|
if (terms.length === 0)
|
|
224
273
|
return [];
|
|
225
|
-
const
|
|
274
|
+
const preScanCap = Math.min(limit * 20, 2000);
|
|
275
|
+
// ORDER BY confidence-weighted hit_count DESC so the cap keeps the most
|
|
276
|
+
// valuable candidates instead of the oldest-by-rowid (which would silently
|
|
277
|
+
// exclude recently-stored memories on tables larger than preScanCap).
|
|
278
|
+
const rows = adapter
|
|
279
|
+
.prepare(`SELECT * FROM memories ${activeClause}
|
|
280
|
+
ORDER BY (confidence * (1.0 + hit_count * 0.1)) DESC
|
|
281
|
+
LIMIT :preScanCap`)
|
|
282
|
+
.all({ ':preScanCap': preScanCap });
|
|
226
283
|
const scored = [];
|
|
227
284
|
for (const row of rows) {
|
|
228
285
|
const memory = rowToMemory(row);
|
|
@@ -15,6 +15,43 @@ import { fileURLToPath } from "node:url";
|
|
|
15
15
|
import { showNextAction } from "../../shared/tui.js";
|
|
16
16
|
import { validatePlanningDirectory, parsePlanningDirectory, transformToGSD, generatePreview, writeGSDDirectory, } from "./index.js";
|
|
17
17
|
import { homedir } from "node:os";
|
|
18
|
+
import { ensureDbOpen } from "../bootstrap/dynamic-tools.js";
|
|
19
|
+
import { clearEngineHierarchy, transaction } from "../gsd-db.js";
|
|
20
|
+
import { migrateFromMarkdown } from "../md-importer.js";
|
|
21
|
+
import { invalidateStateCache } from "../state.js";
|
|
22
|
+
function assertMigrationImportMatchesPreview(imported, preview) {
|
|
23
|
+
const mismatches = [];
|
|
24
|
+
if (imported.hierarchy.milestones !== preview.milestoneCount) {
|
|
25
|
+
mismatches.push(`milestones ${imported.hierarchy.milestones}/${preview.milestoneCount}`);
|
|
26
|
+
}
|
|
27
|
+
if (imported.hierarchy.slices !== preview.totalSlices) {
|
|
28
|
+
mismatches.push(`slices ${imported.hierarchy.slices}/${preview.totalSlices}`);
|
|
29
|
+
}
|
|
30
|
+
if (imported.hierarchy.tasks !== preview.totalTasks) {
|
|
31
|
+
mismatches.push(`tasks ${imported.hierarchy.tasks}/${preview.totalTasks}`);
|
|
32
|
+
}
|
|
33
|
+
if (imported.requirements !== preview.requirements.total) {
|
|
34
|
+
mismatches.push(`requirements ${imported.requirements}/${preview.requirements.total}`);
|
|
35
|
+
}
|
|
36
|
+
if (mismatches.length > 0) {
|
|
37
|
+
throw new Error(`migration DB import verification failed: ${mismatches.join(", ")}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export async function importWrittenMigrationToDb(basePath, preview) {
|
|
41
|
+
const opened = await ensureDbOpen(basePath);
|
|
42
|
+
if (!opened) {
|
|
43
|
+
throw new Error(`failed to open or create the GSD database at ${basePath}`);
|
|
44
|
+
}
|
|
45
|
+
const counts = transaction(() => {
|
|
46
|
+
clearEngineHierarchy();
|
|
47
|
+
const imported = migrateFromMarkdown(basePath);
|
|
48
|
+
if (preview)
|
|
49
|
+
assertMigrationImportMatchesPreview(imported, preview);
|
|
50
|
+
return imported;
|
|
51
|
+
});
|
|
52
|
+
invalidateStateCache();
|
|
53
|
+
return counts;
|
|
54
|
+
}
|
|
18
55
|
/** Format preview stats for embedding in the review prompt. */
|
|
19
56
|
function formatPreviewStats(preview) {
|
|
20
57
|
const lines = [
|
|
@@ -126,12 +163,14 @@ export async function handleMigrate(args, ctx, pi) {
|
|
|
126
163
|
ctx.ui.notify("Writing .gsd directory…", "info");
|
|
127
164
|
const result = await writeGSDDirectory(project, process.cwd());
|
|
128
165
|
const gsdPath = gsdRoot(process.cwd());
|
|
129
|
-
|
|
166
|
+
const imported = await importWrittenMigrationToDb(process.cwd(), preview);
|
|
167
|
+
ctx.ui.notify(`✓ Migration complete — ${result.paths.length} file(s) written to .gsd/ and ${imported.hierarchy.milestones}M/${imported.hierarchy.slices}S/${imported.hierarchy.tasks}T imported to the database`, "info");
|
|
130
168
|
// ── Post-write review offer ────────────────────────────────────────────────
|
|
131
169
|
const reviewChoice = await showNextAction(ctx, {
|
|
132
170
|
title: "Migration written",
|
|
133
171
|
summary: [
|
|
134
172
|
`${result.paths.length} files written to .gsd/`,
|
|
173
|
+
`${imported.hierarchy.milestones} milestone(s), ${imported.hierarchy.slices} slice(s), and ${imported.hierarchy.tasks} task(s) imported to gsd.db`,
|
|
135
174
|
"",
|
|
136
175
|
"The agent can now review the migrated output against GSD-2 standards —",
|
|
137
176
|
"checking structure, content quality, deriveState() round-trip, and",
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { ensureDbOpen } from "./bootstrap/dynamic-tools.js";
|
|
3
|
+
import { clearEngineHierarchy, getAllMilestones, getMilestoneSlices, getSliceTasks, isDbAvailable, transaction, } from "./gsd-db.js";
|
|
4
|
+
import { migrateHierarchyToDb } from "./md-importer.js";
|
|
5
|
+
import { parsePlan, parseRoadmap } from "./parsers-legacy.js";
|
|
6
|
+
import { milestonesDir, resolveMilestoneFile, resolveSliceFile, } from "./paths.js";
|
|
7
|
+
import { invalidateStateCache } from "./state.js";
|
|
8
|
+
function zeroCounts() {
|
|
9
|
+
return { milestones: 0, slices: 0, tasks: 0 };
|
|
10
|
+
}
|
|
11
|
+
function sameCounts(a, b) {
|
|
12
|
+
return a.milestones === b.milestones && a.slices === b.slices && a.tasks === b.tasks;
|
|
13
|
+
}
|
|
14
|
+
export function countMarkdownHierarchy(basePath) {
|
|
15
|
+
const root = milestonesDir(basePath);
|
|
16
|
+
if (!existsSync(root))
|
|
17
|
+
return zeroCounts();
|
|
18
|
+
const counts = zeroCounts();
|
|
19
|
+
for (const entry of readdirSync(root, { withFileTypes: true })) {
|
|
20
|
+
if (!entry.isDirectory() || !/^M\d+/.test(entry.name))
|
|
21
|
+
continue;
|
|
22
|
+
counts.milestones++;
|
|
23
|
+
const roadmapPath = resolveMilestoneFile(basePath, entry.name, "ROADMAP");
|
|
24
|
+
if (!roadmapPath || !existsSync(roadmapPath))
|
|
25
|
+
continue;
|
|
26
|
+
const roadmap = parseRoadmap(readFileSync(roadmapPath, "utf-8"));
|
|
27
|
+
counts.slices += roadmap.slices.length;
|
|
28
|
+
for (const slice of roadmap.slices) {
|
|
29
|
+
const planPath = resolveSliceFile(basePath, entry.name, slice.id, "PLAN");
|
|
30
|
+
if (!planPath || !existsSync(planPath))
|
|
31
|
+
continue;
|
|
32
|
+
const plan = parsePlan(readFileSync(planPath, "utf-8"));
|
|
33
|
+
counts.tasks += plan.tasks.length;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return counts;
|
|
37
|
+
}
|
|
38
|
+
export function countDbHierarchy() {
|
|
39
|
+
if (!isDbAvailable())
|
|
40
|
+
return zeroCounts();
|
|
41
|
+
const counts = zeroCounts();
|
|
42
|
+
const milestones = getAllMilestones();
|
|
43
|
+
counts.milestones = milestones.length;
|
|
44
|
+
for (const milestone of milestones) {
|
|
45
|
+
const slices = getMilestoneSlices(milestone.id);
|
|
46
|
+
counts.slices += slices.length;
|
|
47
|
+
for (const slice of slices) {
|
|
48
|
+
counts.tasks += getSliceTasks(milestone.id, slice.id).length;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return counts;
|
|
52
|
+
}
|
|
53
|
+
export async function autoImportMarkdownHierarchyIfDbMismatch(basePath) {
|
|
54
|
+
const markdown = countMarkdownHierarchy(basePath);
|
|
55
|
+
if (sameCounts(markdown, zeroCounts())) {
|
|
56
|
+
return {
|
|
57
|
+
action: "none",
|
|
58
|
+
reason: "no-markdown",
|
|
59
|
+
markdown,
|
|
60
|
+
beforeDb: zeroCounts(),
|
|
61
|
+
afterDb: zeroCounts(),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const opened = await ensureDbOpen(basePath);
|
|
65
|
+
if (!opened || !isDbAvailable()) {
|
|
66
|
+
throw new Error(`failed to open or create the GSD database at ${basePath}`);
|
|
67
|
+
}
|
|
68
|
+
const beforeDb = countDbHierarchy();
|
|
69
|
+
if (sameCounts(markdown, beforeDb)) {
|
|
70
|
+
return { action: "none", reason: "in-sync", markdown, beforeDb, afterDb: beforeDb };
|
|
71
|
+
}
|
|
72
|
+
const reason = sameCounts(beforeDb, zeroCounts()) ? "db-empty" : "count-mismatch";
|
|
73
|
+
const imported = transaction(() => {
|
|
74
|
+
clearEngineHierarchy();
|
|
75
|
+
return migrateHierarchyToDb(basePath);
|
|
76
|
+
});
|
|
77
|
+
invalidateStateCache();
|
|
78
|
+
const afterDb = {
|
|
79
|
+
milestones: imported.milestones,
|
|
80
|
+
slices: imported.slices,
|
|
81
|
+
tasks: imported.tasks,
|
|
82
|
+
};
|
|
83
|
+
if (!sameCounts(markdown, afterDb)) {
|
|
84
|
+
throw new Error(`migration auto-import verification failed: markdown ${markdown.milestones}M/${markdown.slices}S/${markdown.tasks}T, db ${afterDb.milestones}M/${afterDb.slices}S/${afterDb.tasks}T`);
|
|
85
|
+
}
|
|
86
|
+
return { action: "imported", reason, markdown, beforeDb, afterDb };
|
|
87
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// Both READ and WRITE operations are native — push operations remain as
|
|
6
6
|
// execSync calls because git2 credential handling is too complex.
|
|
7
7
|
import { execFileSync } from "node:child_process";
|
|
8
|
-
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
8
|
+
import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import { GSDError, GSD_GIT_ERROR } from "./errors.js";
|
|
11
11
|
import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
|
|
@@ -1007,6 +1007,24 @@ export function nativeRmForce(basePath, paths) {
|
|
|
1007
1007
|
gitFileExec(basePath, ["rm", "--force", "--", path], true);
|
|
1008
1008
|
}
|
|
1009
1009
|
}
|
|
1010
|
+
function runGitWorktreeAdd(basePath, wtPath, branch, createBranch, startPoint) {
|
|
1011
|
+
if (createBranch) {
|
|
1012
|
+
const branchRef = gitExec(basePath, ["show-ref", "--verify", `refs/heads/${branch}`], true);
|
|
1013
|
+
if (branchRef) {
|
|
1014
|
+
gitExec(basePath, ["worktree", "add", wtPath, branch]);
|
|
1015
|
+
return;
|
|
1016
|
+
}
|
|
1017
|
+
gitExec(basePath, ["worktree", "add", "-b", branch, wtPath, startPoint ?? "HEAD"]);
|
|
1018
|
+
}
|
|
1019
|
+
else {
|
|
1020
|
+
gitExec(basePath, ["worktree", "add", wtPath, branch]);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
export function assertWorktreeMaterialized(wtPath) {
|
|
1024
|
+
if (existsSync(join(wtPath, ".git")))
|
|
1025
|
+
return;
|
|
1026
|
+
throw new GSDError(GSD_GIT_ERROR, `git worktree add did not materialize a valid worktree at ${wtPath}: missing .git file`);
|
|
1027
|
+
}
|
|
1010
1028
|
/**
|
|
1011
1029
|
* Add a new git worktree.
|
|
1012
1030
|
* Native: libgit2 worktree API.
|
|
@@ -1016,14 +1034,20 @@ export function nativeWorktreeAdd(basePath, wtPath, branch, createBranch, startP
|
|
|
1016
1034
|
const native = loadNative();
|
|
1017
1035
|
if (native) {
|
|
1018
1036
|
native.gitWorktreeAdd(basePath, wtPath, branch, createBranch, startPoint);
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1037
|
+
try {
|
|
1038
|
+
assertWorktreeMaterialized(wtPath);
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
1041
|
+
catch {
|
|
1042
|
+
rmSync(wtPath, { recursive: true, force: true });
|
|
1043
|
+
gitExec(basePath, ["worktree", "prune"], true);
|
|
1044
|
+
runGitWorktreeAdd(basePath, wtPath, branch, createBranch, startPoint);
|
|
1045
|
+
assertWorktreeMaterialized(wtPath);
|
|
1046
|
+
return;
|
|
1047
|
+
}
|
|
1026
1048
|
}
|
|
1049
|
+
runGitWorktreeAdd(basePath, wtPath, branch, createBranch, startPoint);
|
|
1050
|
+
assertWorktreeMaterialized(wtPath);
|
|
1027
1051
|
}
|
|
1028
1052
|
/**
|
|
1029
1053
|
* Remove a git worktree.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// GSD-2 + src/resources/extensions/gsd/orphan-stash-audit.ts
|
|
2
|
+
// Startup sweep for orphaned gsd-preflight-stash entries left behind by
|
|
3
|
+
// interrupted milestone merges (#5538-followup).
|
|
4
|
+
import { execFileSync } from "node:child_process";
|
|
5
|
+
import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
|
|
6
|
+
/**
|
|
7
|
+
* Recognize the "already restored" failure mode of `git stash apply`.
|
|
8
|
+
*
|
|
9
|
+
* When a preflight stash captured untracked files via `--include-untracked`
|
|
10
|
+
* and those files are now present in the working tree (e.g. a prior audit
|
|
11
|
+
* run already applied this stash), `git stash apply` aborts with
|
|
12
|
+
* `<path> already exists, no checkout` and exits non-zero. That is the
|
|
13
|
+
* idempotent steady state for this audit, not a recovery failure — treat
|
|
14
|
+
* it as a no-op so repeated GSD startups stop spamming the user with
|
|
15
|
+
* warnings about stashes that have already been restored (#5538-followup
|
|
16
|
+
* peer-review feedback).
|
|
17
|
+
*/
|
|
18
|
+
function _isAlreadyRestoredApplyError(err) {
|
|
19
|
+
if (!err || typeof err !== "object")
|
|
20
|
+
return false;
|
|
21
|
+
const stderr = err.stderr;
|
|
22
|
+
const stderrText = typeof stderr === "string" ? stderr : stderr instanceof Uint8Array ? Buffer.from(stderr).toString("utf-8") : "";
|
|
23
|
+
if (stderrText && /already exists, no checkout/i.test(stderrText))
|
|
24
|
+
return true;
|
|
25
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
26
|
+
return /already exists, no checkout/i.test(message);
|
|
27
|
+
}
|
|
28
|
+
export { _isAlreadyRestoredApplyError };
|
|
29
|
+
/**
|
|
30
|
+
* Audit `git stash list` for orphaned `gsd-preflight-stash:M00x:*` entries.
|
|
31
|
+
*
|
|
32
|
+
* The matching merge code in `phases.ts` previously skipped the postflight
|
|
33
|
+
* pop whenever `mergeAndExit` threw, leaking the user's pre-merge working
|
|
34
|
+
* tree into the stash list. For every preflight-stash entry whose milestone
|
|
35
|
+
* is now complete (per the supplied callback), `git stash apply` is invoked —
|
|
36
|
+
* NOT `pop`. The stash entry stays in the list so the user retains a backup
|
|
37
|
+
* if the apply produces unexpected merge results. Idempotent across repeated
|
|
38
|
+
* startup runs.
|
|
39
|
+
*
|
|
40
|
+
* Failures are best-effort: a list error (no repo, git unavailable) returns
|
|
41
|
+
* an empty result. An apply error becomes a warning the user sees alongside
|
|
42
|
+
* the existing orphan-branch audit messages — startup continues.
|
|
43
|
+
*/
|
|
44
|
+
export function auditOrphanedPreflightStashes(basePath, isMilestoneComplete) {
|
|
45
|
+
const result = { applied: [], warnings: [] };
|
|
46
|
+
let listOutput;
|
|
47
|
+
try {
|
|
48
|
+
listOutput = execFileSync("git", ["stash", "list", "--format=%gd%x00%s"], {
|
|
49
|
+
cwd: basePath,
|
|
50
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
51
|
+
encoding: "utf-8",
|
|
52
|
+
env: GIT_NO_PROMPT_ENV,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
const MARKER_RE = /\bgsd-preflight-stash:([A-Za-z0-9_-]+):/;
|
|
59
|
+
for (const line of listOutput.split("\n")) {
|
|
60
|
+
const sep = line.indexOf("\x00");
|
|
61
|
+
if (sep < 0)
|
|
62
|
+
continue;
|
|
63
|
+
const ref = line.slice(0, sep);
|
|
64
|
+
const subject = line.slice(sep + 1);
|
|
65
|
+
if (!ref || !subject)
|
|
66
|
+
continue;
|
|
67
|
+
const match = MARKER_RE.exec(subject);
|
|
68
|
+
if (!match)
|
|
69
|
+
continue;
|
|
70
|
+
const milestoneId = match[1];
|
|
71
|
+
let complete = false;
|
|
72
|
+
try {
|
|
73
|
+
complete = isMilestoneComplete(milestoneId);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
result.warnings.push(`Could not determine completion status for ${milestoneId} during preflight-stash audit: ${err instanceof Error ? err.message : String(err)}.`);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (!complete)
|
|
80
|
+
continue;
|
|
81
|
+
try {
|
|
82
|
+
execFileSync("git", ["stash", "apply", "--quiet", ref], {
|
|
83
|
+
cwd: basePath,
|
|
84
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
85
|
+
encoding: "utf-8",
|
|
86
|
+
env: GIT_NO_PROMPT_ENV,
|
|
87
|
+
});
|
|
88
|
+
result.applied.push({ milestoneId, stashRef: ref });
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
// Idempotent steady state: stash was already applied in a prior audit
|
|
92
|
+
// run; the files exist and `git stash apply` refuses to overwrite.
|
|
93
|
+
// Skip silently so repeat runs are no-ops.
|
|
94
|
+
if (_isAlreadyRestoredApplyError(err))
|
|
95
|
+
continue;
|
|
96
|
+
result.warnings.push(`Could not apply orphaned preflight stash ${ref} (milestone ${milestoneId}): ${err instanceof Error ? err.message : String(err)}. ` +
|
|
97
|
+
`Run \`git stash apply ${ref}\` manually to restore your pre-merge changes.`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
@@ -12,7 +12,7 @@ import { join, dirname } from "node:path";
|
|
|
12
12
|
import { fileURLToPath } from "node:url";
|
|
13
13
|
import { gsdRoot } from "./paths.js";
|
|
14
14
|
import { createWorktree, worktreePath } from "./worktree-manager.js";
|
|
15
|
-
import { autoWorktreeBranch, runWorktreePostCreateHook, syncGsdStateToWorktree } from "./auto-worktree.js";
|
|
15
|
+
import { autoWorktreeBranch, fastForwardReusedMilestoneBranchIfSafe, runWorktreePostCreateHook, syncGsdStateToWorktree } from "./auto-worktree.js";
|
|
16
16
|
import { nativeBranchExists } from "./native-git-bridge.js";
|
|
17
17
|
import { readIntegrationBranch } from "./git-service.js";
|
|
18
18
|
import { resolveParallelConfig } from "./preferences.js";
|
|
@@ -368,7 +368,7 @@ export async function startParallel(basePath, milestoneIds, prefs) {
|
|
|
368
368
|
// Create the worktree (without chdir — coordinator stays in project root)
|
|
369
369
|
let wtPath;
|
|
370
370
|
try {
|
|
371
|
-
wtPath =
|
|
371
|
+
wtPath = _createMilestoneWorktree(basePath, mid);
|
|
372
372
|
}
|
|
373
373
|
catch (e) {
|
|
374
374
|
logWarning("parallel", `createMilestoneWorktree fallback for ${mid}: ${e.message}`);
|
|
@@ -421,12 +421,22 @@ export async function startParallel(basePath, milestoneIds, prefs) {
|
|
|
421
421
|
/**
|
|
422
422
|
* Create a git worktree for a milestone without changing the coordinator's cwd.
|
|
423
423
|
* Uses milestone/<MID> branch naming (same as auto-worktree.ts).
|
|
424
|
+
*
|
|
425
|
+
* Exported with the `_` prefix purely for tests — production callers stay on
|
|
426
|
+
* the closure-private name `createMilestoneWorktree` below.
|
|
424
427
|
*/
|
|
425
|
-
function
|
|
428
|
+
export function _createMilestoneWorktree(basePath, milestoneId) {
|
|
426
429
|
const branch = autoWorktreeBranch(milestoneId);
|
|
427
430
|
const branchExists = nativeBranchExists(basePath, branch);
|
|
428
431
|
let info;
|
|
429
432
|
if (branchExists) {
|
|
433
|
+
// #5549 post-merge audit (R3): match the fast-forward behavior added to
|
|
434
|
+
// `createAutoWorktree` in commit 8996cb68e. When a worker reuses an
|
|
435
|
+
// existing milestone branch, fast-forward it onto the integration branch
|
|
436
|
+
// when safe so per-worker worktrees don't fork from a stale base after a
|
|
437
|
+
// sibling milestone has merged. Same `nativeIsAncestor` + worktree-list
|
|
438
|
+
// safety guards apply.
|
|
439
|
+
fastForwardReusedMilestoneBranchIfSafe(basePath, milestoneId, branch);
|
|
430
440
|
info = createWorktree(basePath, milestoneId, { branch, reuseExistingBranch: true });
|
|
431
441
|
}
|
|
432
442
|
else {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { isAbsolute, relative, resolve } from "node:path";
|
|
2
|
+
import { normalizePlannedFileReference } from "./files.js";
|
|
3
|
+
function isInsideBase(basePath, candidate) {
|
|
4
|
+
const base = resolve(basePath);
|
|
5
|
+
const abs = resolve(candidate);
|
|
6
|
+
const rel = relative(base, abs);
|
|
7
|
+
return rel === "" || (!!rel && !rel.startsWith("..") && !isAbsolute(rel));
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Planning IO fields are execution contracts. Absolute paths are only safe when
|
|
11
|
+
* they stay inside the active working directory; in worktree mode, an absolute
|
|
12
|
+
* path to the original checkout makes executors edit the wrong tree.
|
|
13
|
+
*/
|
|
14
|
+
export function validatePlanningPathScope(basePath, fields) {
|
|
15
|
+
for (const { field, values } of fields) {
|
|
16
|
+
for (const raw of values) {
|
|
17
|
+
const candidate = normalizePlannedFileReference(raw);
|
|
18
|
+
if (!isAbsolute(candidate))
|
|
19
|
+
continue;
|
|
20
|
+
if (isInsideBase(basePath, candidate))
|
|
21
|
+
continue;
|
|
22
|
+
return `${field} contains absolute path outside working directory: ${candidate}. Use a path relative to ${basePath}.`;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
@@ -8,8 +8,53 @@ const CHANGE_TYPE_LABELS = {
|
|
|
8
8
|
docs: "Documentation only",
|
|
9
9
|
chore: "Build, CI, or tooling changes",
|
|
10
10
|
};
|
|
11
|
+
// Per-item cap for user-supplied content. 2 KB gives slice titles plus
|
|
12
|
+
// descriptions room while still bounding malicious DoS-via-PR-body input.
|
|
13
|
+
const USER_CONTENT_CAP_BYTES = 2048;
|
|
14
|
+
const TRUNCATION_SUFFIX = " … [truncated]";
|
|
15
|
+
// Strips HTML comments, fake commit trailers (Co-Authored-By, Signed-off-by —
|
|
16
|
+
// case-insensitive on the trailer name), and caps total length. Designed to
|
|
17
|
+
// be a no-op for well-formed input; golden fixtures must remain byte-stable.
|
|
18
|
+
// Trailer lines are removed (not rejected) so that a single bad line in an
|
|
19
|
+
// otherwise legitimate description does not block the entire PR.
|
|
20
|
+
function sanitizeUserContent(s) {
|
|
21
|
+
if (!s)
|
|
22
|
+
return s;
|
|
23
|
+
// Strip HTML comments greedily across newlines.
|
|
24
|
+
let out = s.replace(/<!--[\s\S]*?-->/g, "");
|
|
25
|
+
// Drop lines that look like commit trailers we do not want forged.
|
|
26
|
+
out = out
|
|
27
|
+
.split("\n")
|
|
28
|
+
.filter((line) => !/^\s*(co-authored-by|signed-off-by)\s*:/i.test(line))
|
|
29
|
+
.join("\n");
|
|
30
|
+
if (Buffer.byteLength(out, "utf8") > USER_CONTENT_CAP_BYTES) {
|
|
31
|
+
const budget = USER_CONTENT_CAP_BYTES - Buffer.byteLength(TRUNCATION_SUFFIX, "utf8");
|
|
32
|
+
// Truncate by code units to stay safely under the byte budget for ASCII;
|
|
33
|
+
// for multibyte content we conservatively walk back until under budget.
|
|
34
|
+
let sliced = out.slice(0, Math.max(0, budget));
|
|
35
|
+
while (Buffer.byteLength(sliced, "utf8") > budget && sliced.length > 0) {
|
|
36
|
+
sliced = sliced.slice(0, -1);
|
|
37
|
+
}
|
|
38
|
+
out = sliced + TRUNCATION_SUFFIX;
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
// Strips HTML comments and fake trailers without applying the length cap.
|
|
43
|
+
// Used for short fields like linkedIssue where truncation would be confusing.
|
|
44
|
+
function sanitizeIssueRef(s) {
|
|
45
|
+
if (!s)
|
|
46
|
+
return s;
|
|
47
|
+
let out = s.replace(/<!--[\s\S]*?-->/g, "");
|
|
48
|
+
out = out
|
|
49
|
+
.split("\n")
|
|
50
|
+
.filter((line) => !/^\s*(co-authored-by|signed-off-by)\s*:/i.test(line))
|
|
51
|
+
.join("\n");
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
11
54
|
function normalizeList(values) {
|
|
12
|
-
return (values ?? [])
|
|
55
|
+
return (values ?? [])
|
|
56
|
+
.map((value) => sanitizeUserContent(value).trim())
|
|
57
|
+
.filter(Boolean);
|
|
13
58
|
}
|
|
14
59
|
function changeTypeChecklist(selected) {
|
|
15
60
|
return Object.keys(CHANGE_TYPE_LABELS).map((type) => {
|
|
@@ -28,13 +73,17 @@ export function buildPrEvidence(input) {
|
|
|
28
73
|
const subjectTitle = input.milestoneTitle?.trim() || subjectId;
|
|
29
74
|
const changeType = input.changeType ?? "feat";
|
|
30
75
|
const summaries = normalizeList(input.summaries);
|
|
76
|
+
const blockers = normalizeList(input.blockers);
|
|
31
77
|
const roadmapItems = normalizeList(input.roadmapItems);
|
|
32
78
|
const metrics = normalizeList(input.metrics);
|
|
33
79
|
const testsRun = normalizeList(input.testsRun);
|
|
34
80
|
const rollbackNotes = normalizeList(input.rollbackNotes);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const
|
|
81
|
+
// linkedIssue is sanitized but not length-capped: legitimate issue refs
|
|
82
|
+
// are short by nature, and truncating "Closes #123" would be unhelpful.
|
|
83
|
+
const linkedIssueRaw = input.linkedIssue ? sanitizeIssueRef(input.linkedIssue).trim() : "";
|
|
84
|
+
const linkedIssue = linkedIssueRaw || "Not specified. Add an issue link before marking this PR ready if CONTRIBUTING.md requires one.";
|
|
85
|
+
const why = (input.why ? sanitizeUserContent(input.why).trim() : "") || `${capitalize(subjectKind)} work is complete and ready for review.`;
|
|
86
|
+
const how = (input.how ? sanitizeUserContent(input.how).trim() : "") || "Generated from GSD evidence and local workflow artifacts.";
|
|
38
87
|
const title = `${changeType}: ${subjectTitle}`;
|
|
39
88
|
const sections = [
|
|
40
89
|
"## TL;DR",
|
|
@@ -46,19 +95,11 @@ export function buildPrEvidence(input) {
|
|
|
46
95
|
"## What",
|
|
47
96
|
"",
|
|
48
97
|
summaries.length > 0 ? summaries.join("\n\n") : `${capitalize(subjectKind)} ${subjectId} completed.`,
|
|
49
|
-
"",
|
|
50
|
-
"## Why",
|
|
51
|
-
"",
|
|
52
|
-
why,
|
|
53
|
-
"",
|
|
54
|
-
"## How",
|
|
55
|
-
"",
|
|
56
|
-
how,
|
|
57
|
-
"",
|
|
58
|
-
"## Linked Issue",
|
|
59
|
-
"",
|
|
60
|
-
linkedIssue,
|
|
61
98
|
];
|
|
99
|
+
if (blockers.length > 0) {
|
|
100
|
+
sections.push("", "## Blockers", "", blockers.map((blocker) => `- ${blocker}`).join("\n"));
|
|
101
|
+
}
|
|
102
|
+
sections.push("", "## Why", "", why, "", "## How", "", how, "", "## Linked Issue", "", linkedIssue);
|
|
62
103
|
if (roadmapItems.length > 0) {
|
|
63
104
|
sections.push("", "## Roadmap", "", roadmapItems.join("\n"));
|
|
64
105
|
}
|
|
@@ -328,6 +328,8 @@ function shouldValidateInputAsPath(raw) {
|
|
|
328
328
|
const trimmed = raw.trim();
|
|
329
329
|
if (!trimmed)
|
|
330
330
|
return false;
|
|
331
|
+
if (isRuntimeOnlyInput(trimmed))
|
|
332
|
+
return false;
|
|
331
333
|
const candidate = extractPathFromAnnotation(trimmed);
|
|
332
334
|
if (!candidate)
|
|
333
335
|
return false;
|
|
@@ -349,6 +351,9 @@ function shouldValidateInputAsPath(raw) {
|
|
|
349
351
|
/[\\/]/.test(candidate) ||
|
|
350
352
|
/[*?[\]{}]/.test(candidate));
|
|
351
353
|
}
|
|
354
|
+
function isRuntimeOnlyInput(raw) {
|
|
355
|
+
return /\(\s*runtime\s*\)/i.test(raw);
|
|
356
|
+
}
|
|
352
357
|
function containsGlobPattern(candidate) {
|
|
353
358
|
return ["*", "?", "[", "]", "{", "}"].some((char) => candidate.includes(char));
|
|
354
359
|
}
|
|
@@ -386,6 +391,15 @@ function getExpectedOutputsUpTo(tasks, taskIndex) {
|
|
|
386
391
|
*/
|
|
387
392
|
export function checkFilePathConsistency(tasks, basePath) {
|
|
388
393
|
const results = [];
|
|
394
|
+
// Build a set of all files created by any task at any position (normalized).
|
|
395
|
+
// Used to suppress consistency errors for files that will be caught with a
|
|
396
|
+
// more precise message by checkTaskOrdering (sequence violation).
|
|
397
|
+
const allTaskOutputs = new Set();
|
|
398
|
+
for (const t of tasks) {
|
|
399
|
+
for (const f of t.expected_output) {
|
|
400
|
+
allTaskOutputs.add(normalizeFilePath(f));
|
|
401
|
+
}
|
|
402
|
+
}
|
|
389
403
|
for (let i = 0; i < tasks.length; i++) {
|
|
390
404
|
const task = tasks[i];
|
|
391
405
|
const priorOutputs = getExpectedOutputsUpTo(tasks, i);
|
|
@@ -416,6 +430,12 @@ export function checkFilePathConsistency(tasks, basePath) {
|
|
|
416
430
|
anyOutputUnderDirectory(normalizedFile, ownOutputs);
|
|
417
431
|
}
|
|
418
432
|
if (!existsOnDisk && !inPriorOutputs && !inOwnOutputs && !directorySatisfied) {
|
|
433
|
+
// If a later task claims to create this file, the ordering check will
|
|
434
|
+
// fire a more precise "sequence violation" error for the same file.
|
|
435
|
+
// Suppress the consistency error here to avoid duplicate noise.
|
|
436
|
+
if (allTaskOutputs.has(normalizedFile) && !ownOutputs.has(normalizedFile)) {
|
|
437
|
+
continue;
|
|
438
|
+
}
|
|
419
439
|
results.push({
|
|
420
440
|
category: "file",
|
|
421
441
|
target: file,
|
|
@@ -461,6 +481,8 @@ export function checkTaskOrdering(tasks, basePath) {
|
|
|
461
481
|
const task = tasks[i];
|
|
462
482
|
const filesToCheck = [...task.inputs];
|
|
463
483
|
for (const file of filesToCheck) {
|
|
484
|
+
if (isRuntimeOnlyInput(file))
|
|
485
|
+
continue;
|
|
464
486
|
if (!shouldValidateInputAsPath(file))
|
|
465
487
|
continue;
|
|
466
488
|
const normalizedFile = normalizeFilePath(file);
|