gsd-pi 2.44.0-dev.d25d507 → 2.45.0-dev.1afbdaa
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/help-text.js +1 -1
- package/dist/loader.js +34 -0
- package/dist/resources/extensions/gsd/activity-log.js +7 -0
- package/dist/resources/extensions/gsd/auto/infra-errors.js +3 -0
- package/dist/resources/extensions/gsd/auto/phases.js +63 -77
- package/dist/resources/extensions/gsd/auto/run-unit.js +6 -3
- package/dist/resources/extensions/gsd/auto/session.js +0 -11
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +112 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +25 -96
- package/dist/resources/extensions/gsd/auto-prompts.js +24 -1
- package/dist/resources/extensions/gsd/auto-start.js +23 -5
- package/dist/resources/extensions/gsd/auto-timers.js +57 -3
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +4 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +14 -10
- package/dist/resources/extensions/gsd/auto.js +42 -60
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +170 -11
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +18 -0
- package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
- package/dist/resources/extensions/gsd/commands/context.js +0 -4
- package/dist/resources/extensions/gsd/commands/handlers/core.js +2 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +10 -0
- package/dist/resources/extensions/gsd/commands/handlers/parallel.js +1 -1
- package/dist/resources/extensions/gsd/commands-mcp-status.js +187 -0
- package/dist/resources/extensions/gsd/crash-recovery.js +2 -4
- package/dist/resources/extensions/gsd/dashboard-overlay.js +0 -44
- package/dist/resources/extensions/gsd/db-writer.js +40 -22
- package/dist/resources/extensions/gsd/doctor-checks.js +167 -2
- package/dist/resources/extensions/gsd/doctor.js +13 -3
- package/dist/resources/extensions/gsd/git-service.js +8 -3
- package/dist/resources/extensions/gsd/gsd-db.js +28 -4
- package/dist/resources/extensions/gsd/guided-flow.js +1 -2
- package/dist/resources/extensions/gsd/markdown-renderer.js +1 -1
- package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +5 -18
- package/dist/resources/extensions/gsd/preferences-types.js +2 -2
- package/dist/resources/extensions/gsd/preferences.js +8 -4
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +21 -10
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +10 -23
- package/dist/resources/extensions/gsd/prompts/discuss.md +2 -2
- package/dist/resources/extensions/gsd/prompts/execute-task.md +5 -15
- 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/guided-plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-research-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +5 -3
- package/dist/resources/extensions/gsd/prompts/queue.md +2 -2
- package/dist/resources/extensions/gsd/prompts/quick-task.md +2 -0
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +3 -14
- package/dist/resources/extensions/gsd/prompts/research-slice.md +3 -3
- package/dist/resources/extensions/gsd/prompts/rethink.md +83 -0
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
- package/dist/resources/extensions/gsd/provider-error-pause.js +7 -0
- package/dist/resources/extensions/gsd/repo-identity.js +45 -7
- package/dist/resources/extensions/gsd/rethink.js +115 -0
- package/dist/resources/extensions/gsd/session-lock.js +1 -3
- package/dist/resources/extensions/gsd/state.js +48 -3
- package/dist/resources/extensions/gsd/sync-lock.js +89 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +61 -11
- package/dist/resources/extensions/gsd/tools/complete-slice.js +56 -11
- package/dist/resources/extensions/gsd/tools/complete-task.js +50 -2
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +37 -1
- package/dist/resources/extensions/gsd/tools/plan-slice.js +31 -1
- package/dist/resources/extensions/gsd/tools/plan-task.js +28 -1
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +32 -2
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +86 -0
- package/dist/resources/extensions/gsd/tools/reopen-task.js +90 -0
- package/dist/resources/extensions/gsd/tools/replan-slice.js +34 -2
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +88 -0
- package/dist/resources/extensions/gsd/unit-ownership.js +85 -0
- package/dist/resources/extensions/gsd/workflow-events.js +102 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +193 -0
- package/dist/resources/extensions/gsd/workflow-manifest.js +244 -0
- package/dist/resources/extensions/gsd/workflow-migration.js +280 -0
- package/dist/resources/extensions/gsd/workflow-projections.js +373 -0
- package/dist/resources/extensions/gsd/workflow-reconcile.js +411 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +34 -3
- package/dist/resources/extensions/gsd/worktree-resolver.js +43 -0
- package/dist/resources/extensions/gsd/write-intercept.js +84 -0
- package/dist/resources/extensions/mcp-client/index.js +14 -0
- package/dist/resources/extensions/voice/index.js +11 -16
- package/dist/resources/extensions/voice/linux-ready.js +67 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +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 +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +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_client-reference-manifest.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_client-reference-manifest.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_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_client-reference-manifest.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_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_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_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_client-reference-manifest.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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/page.js +1 -1
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +14 -14
- 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/4024.11ca5c01938e5948.js +9 -0
- package/dist/web/standalone/.next/static/chunks/{3721.bf31263de6d5fa46.js → 485.243af25f0cdf50d6.js} +2 -2
- package/dist/web/standalone/.next/static/chunks/app/{page-b9367c5ae13b99c6.js → page-6654a8cca61a3d1c.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/webpack-0a4cd455ec4197d2.js +1 -0
- package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +1 -0
- package/package.json +2 -1
- package/packages/native/dist/stream-process/index.js +2 -2
- package/packages/native/src/__tests__/stream-process.test.mjs +34 -0
- package/packages/native/src/stream-process/index.ts +2 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +3 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +15 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +2 -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/lifecycle-hooks.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js +10 -5
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.js +185 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/local-model-check.d.ts +15 -0
- package/packages/pi-coding-agent/dist/core/local-model-check.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/local-model-check.js +41 -0
- package/packages/pi-coding-agent/dist/core/local-model-check.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +239 -10
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts +13 -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 +40 -3
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-commands.test.js +206 -195
- package/packages/pi-coding-agent/dist/core/package-commands.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -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 +6 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/main.js +17 -0
- package/packages/pi-coding-agent/dist/main.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js +32 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +3 -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 +8 -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/settings-selector.d.ts +2 -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 +12 -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/timestamp.d.ts +15 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js +40 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js.map +1 -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 +4 -1
- 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.d.ts +5 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +13 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.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 +17 -8
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- 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 +7 -3
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/auth-storage.ts +15 -1
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +2 -0
- package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -1
- package/packages/pi-coding-agent/src/core/lifecycle-hooks.test.ts +227 -0
- package/packages/pi-coding-agent/src/core/lifecycle-hooks.ts +11 -5
- package/packages/pi-coding-agent/src/core/local-model-check.ts +45 -0
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +297 -11
- package/packages/pi-coding-agent/src/core/model-registry.ts +51 -4
- package/packages/pi-coding-agent/src/core/package-commands.test.ts +227 -205
- package/packages/pi-coding-agent/src/core/settings-manager.ts +9 -0
- package/packages/pi-coding-agent/src/main.ts +19 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/timestamp.test.ts +38 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +10 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/timestamp.ts +48 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +3 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +18 -3
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +16 -7
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +8 -1
- package/pkg/package.json +1 -1
- package/src/resources/extensions/gsd/activity-log.ts +1 -0
- package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +0 -19
- package/src/resources/extensions/gsd/auto/phases.ts +69 -91
- package/src/resources/extensions/gsd/auto/run-unit.ts +6 -3
- package/src/resources/extensions/gsd/auto/session.ts +0 -18
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +131 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +0 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +25 -106
- package/src/resources/extensions/gsd/auto-prompts.ts +24 -1
- package/src/resources/extensions/gsd/auto-start.ts +26 -5
- package/src/resources/extensions/gsd/auto-timers.ts +64 -3
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +5 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +17 -11
- package/src/resources/extensions/gsd/auto.ts +44 -86
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +162 -11
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -0
- package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
- package/src/resources/extensions/gsd/commands/context.ts +0 -5
- package/src/resources/extensions/gsd/commands/handlers/core.ts +2 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
- package/src/resources/extensions/gsd/commands/handlers/parallel.ts +1 -1
- package/src/resources/extensions/gsd/commands-mcp-status.ts +247 -0
- package/src/resources/extensions/gsd/crash-recovery.ts +1 -5
- package/src/resources/extensions/gsd/dashboard-overlay.ts +0 -50
- package/src/resources/extensions/gsd/db-writer.ts +41 -27
- package/src/resources/extensions/gsd/doctor-checks.ts +180 -2
- package/src/resources/extensions/gsd/doctor-types.ts +7 -1
- package/src/resources/extensions/gsd/doctor.ts +13 -4
- package/src/resources/extensions/gsd/git-service.ts +6 -2
- package/src/resources/extensions/gsd/gsd-db.ts +32 -4
- package/src/resources/extensions/gsd/guided-flow.ts +1 -2
- package/src/resources/extensions/gsd/journal.ts +6 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +1 -1
- package/src/resources/extensions/gsd/parallel-merge.ts +1 -1
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +5 -21
- package/src/resources/extensions/gsd/preferences-types.ts +2 -2
- package/src/resources/extensions/gsd/preferences.ts +7 -3
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +21 -10
- package/src/resources/extensions/gsd/prompts/complete-slice.md +10 -23
- package/src/resources/extensions/gsd/prompts/discuss.md +2 -2
- package/src/resources/extensions/gsd/prompts/execute-task.md +5 -15
- 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/guided-plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-research-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +5 -3
- package/src/resources/extensions/gsd/prompts/queue.md +2 -2
- package/src/resources/extensions/gsd/prompts/quick-task.md +2 -0
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
- package/src/resources/extensions/gsd/prompts/replan-slice.md +3 -14
- package/src/resources/extensions/gsd/prompts/research-slice.md +3 -3
- package/src/resources/extensions/gsd/prompts/rethink.md +83 -0
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
- package/src/resources/extensions/gsd/provider-error-pause.ts +9 -0
- package/src/resources/extensions/gsd/repo-identity.ts +46 -7
- package/src/resources/extensions/gsd/rethink.ts +154 -0
- package/src/resources/extensions/gsd/session-lock.ts +0 -4
- package/src/resources/extensions/gsd/state.ts +49 -1
- package/src/resources/extensions/gsd/sync-lock.ts +94 -0
- package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +5 -13
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +6 -10
- package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +96 -0
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +264 -228
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +317 -250
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +2 -8
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +0 -3
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +121 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +60 -0
- package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +20 -2
- package/src/resources/extensions/gsd/tests/inherited-repo-home-dir.test.ts +121 -0
- package/src/resources/extensions/gsd/tests/integration-proof.test.ts +15 -24
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -3
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +8 -9
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +42 -3
- package/src/resources/extensions/gsd/tests/parallel-budget-atomicity.test.ts +0 -1
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +0 -7
- package/src/resources/extensions/gsd/tests/parallel-merge.test.ts +7 -8
- package/src/resources/extensions/gsd/tests/parallel-orchestration.test.ts +20 -24
- package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +0 -2
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +9 -6
- package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +171 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +7 -9
- package/src/resources/extensions/gsd/tests/projection-regression.test.ts +174 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +26 -21
- package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +176 -0
- package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +155 -0
- package/src/resources/extensions/gsd/tests/reopen-task.test.ts +165 -0
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +1 -4
- package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts +2 -3
- package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/sync-lock.test.ts +122 -0
- package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +175 -0
- package/src/resources/extensions/gsd/tests/workflow-events.test.ts +205 -0
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +275 -0
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +171 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +220 -0
- package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/write-intercept.test.ts +76 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +74 -11
- package/src/resources/extensions/gsd/tools/complete-slice.ts +68 -11
- package/src/resources/extensions/gsd/tools/complete-task.ts +63 -1
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +45 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +40 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +37 -1
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +39 -1
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +125 -0
- package/src/resources/extensions/gsd/tools/reopen-task.ts +129 -0
- package/src/resources/extensions/gsd/tools/replan-slice.ts +41 -1
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +127 -0
- package/src/resources/extensions/gsd/types.ts +8 -0
- package/src/resources/extensions/gsd/unit-ownership.ts +104 -0
- package/src/resources/extensions/gsd/workflow-events.ts +154 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +243 -0
- package/src/resources/extensions/gsd/workflow-manifest.ts +334 -0
- package/src/resources/extensions/gsd/workflow-migration.ts +345 -0
- package/src/resources/extensions/gsd/workflow-projections.ts +425 -0
- package/src/resources/extensions/gsd/workflow-reconcile.ts +503 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +41 -5
- package/src/resources/extensions/gsd/worktree-resolver.ts +44 -0
- package/src/resources/extensions/gsd/write-intercept.ts +90 -0
- package/src/resources/extensions/mcp-client/index.ts +20 -0
- package/src/resources/extensions/voice/index.ts +11 -21
- package/src/resources/extensions/voice/linux-ready.ts +87 -0
- package/src/resources/extensions/voice/tests/linux-ready.test.ts +124 -0
- package/dist/web/standalone/.next/static/chunks/4024.0de81b543b28b9fe.js +0 -9
- package/dist/web/standalone/.next/static/chunks/webpack-9014b5adb127a98a.js +0 -1
- package/dist/web/standalone/.next/static/css/8a727f372cf53002.css +0 -1
- /package/dist/web/standalone/.next/static/{tokoGmfkYfWf1_Yl_Gz7i → j-BskPs0nxxPeYY-bSrab}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{tokoGmfkYfWf1_Yl_Gz7i → j-BskPs0nxxPeYY-bSrab}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timestamp formatting for message display.
|
|
3
|
+
*
|
|
4
|
+
* Formats:
|
|
5
|
+
* - "time-date-iso": 10:34 2025-03-24 (default)
|
|
6
|
+
* - "date-time-iso": 2025-03-24 10:34
|
|
7
|
+
* - "time-date-us": 10:34 AM 03/24/2025
|
|
8
|
+
* - "date-time-us": 03/24/2025 10:34 AM
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export type TimestampFormat = "date-time-iso" | "date-time-us";
|
|
12
|
+
|
|
13
|
+
function pad2(n: number): string {
|
|
14
|
+
return n.toString().padStart(2, "0");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function isoDate(d: Date): string {
|
|
18
|
+
return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function isoTime(d: Date): string {
|
|
22
|
+
return `${pad2(d.getHours())}:${pad2(d.getMinutes())}`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function usDate(d: Date): string {
|
|
26
|
+
return `${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}-${d.getFullYear()}`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function usTime(d: Date): string {
|
|
30
|
+
const hours = d.getHours();
|
|
31
|
+
const period = hours >= 12 ? "PM" : "AM";
|
|
32
|
+
const h = hours % 12 || 12;
|
|
33
|
+
return `${h}:${pad2(d.getMinutes())} ${period}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Format a timestamp for message display using the specified format.
|
|
38
|
+
*/
|
|
39
|
+
export function formatTimestamp(timestamp: number, format: TimestampFormat = "date-time-iso"): string {
|
|
40
|
+
const d = new Date(timestamp);
|
|
41
|
+
|
|
42
|
+
switch (format) {
|
|
43
|
+
case "date-time-iso":
|
|
44
|
+
return `${isoDate(d)} ${isoTime(d)}`;
|
|
45
|
+
case "date-time-us":
|
|
46
|
+
return `${usDate(d)} ${usTime(d)}`;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -895,7 +895,9 @@ export class ToolExecutionComponent extends Container {
|
|
|
895
895
|
// Server-side Anthropic web search
|
|
896
896
|
text = theme.fg("toolTitle", theme.bold("web search"));
|
|
897
897
|
|
|
898
|
-
if (
|
|
898
|
+
if (process.env.PI_OFFLINE === "1") {
|
|
899
|
+
text += "\n\n" + theme.fg("muted", "\u{1F50C} Offline \u{2014} web search unavailable");
|
|
900
|
+
} else if (this.result) {
|
|
899
901
|
const output = this.getTextOutput().trim();
|
|
900
902
|
if (output) {
|
|
901
903
|
const lines = output.split("\n");
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
import { Container, Markdown, type MarkdownTheme, Spacer } from "@gsd/pi-tui";
|
|
1
|
+
import { Container, Markdown, type MarkdownTheme, Spacer, Text } from "@gsd/pi-tui";
|
|
2
2
|
import { getMarkdownTheme, theme } from "../theme/theme.js";
|
|
3
|
+
import { formatTimestamp, type TimestampFormat } from "./timestamp.js";
|
|
3
4
|
|
|
4
5
|
const OSC133_ZONE_START = "\x1b]133;A\x07";
|
|
5
6
|
const OSC133_ZONE_END = "\x1b]133;B\x07";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
|
-
* Component that renders a user message
|
|
9
|
+
* Component that renders a user message with a right-aligned timestamp.
|
|
9
10
|
*/
|
|
10
11
|
export class UserMessageComponent extends Container {
|
|
11
|
-
|
|
12
|
+
private timestamp: number | undefined;
|
|
13
|
+
private timestampFormat: TimestampFormat;
|
|
14
|
+
|
|
15
|
+
constructor(text: string, markdownTheme: MarkdownTheme = getMarkdownTheme(), timestamp?: number, timestampFormat: TimestampFormat = "date-time-iso") {
|
|
12
16
|
super();
|
|
17
|
+
this.timestamp = timestamp;
|
|
18
|
+
this.timestampFormat = timestampFormat;
|
|
13
19
|
this.addChild(new Spacer(1));
|
|
14
20
|
this.addChild(
|
|
15
21
|
new Markdown(text, 1, 1, markdownTheme, {
|
|
@@ -25,6 +31,15 @@ export class UserMessageComponent extends Container {
|
|
|
25
31
|
return lines;
|
|
26
32
|
}
|
|
27
33
|
|
|
34
|
+
// Insert right-aligned timestamp above the message content
|
|
35
|
+
if (this.timestamp) {
|
|
36
|
+
const timeStr = formatTimestamp(this.timestamp, this.timestampFormat);
|
|
37
|
+
const label = theme.fg("dim", timeStr);
|
|
38
|
+
const padding = Math.max(0, width - timeStr.length - 1);
|
|
39
|
+
const timestampLine = " ".repeat(padding) + label;
|
|
40
|
+
lines.splice(0, 0, timestampLine);
|
|
41
|
+
}
|
|
42
|
+
|
|
28
43
|
lines[0] = OSC133_ZONE_START + lines[0];
|
|
29
44
|
lines[lines.length - 1] = lines[lines.length - 1] + OSC133_ZONE_END;
|
|
30
45
|
return lines;
|
|
@@ -100,6 +100,7 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
|
|
|
100
100
|
undefined,
|
|
101
101
|
host.hideThinkingBlock,
|
|
102
102
|
host.getMarkdownThemeWithSettings(),
|
|
103
|
+
host.settingsManager.getTimestampFormat(),
|
|
103
104
|
);
|
|
104
105
|
host.streamingMessage = event.message;
|
|
105
106
|
host.chatContainer.addChild(host.streamingComponent);
|
|
@@ -144,13 +145,21 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
|
|
|
144
145
|
} else if (content.type === "webSearchResult") {
|
|
145
146
|
const component = host.pendingTools.get(content.toolUseId);
|
|
146
147
|
if (component) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
148
|
+
if (process.env.PI_OFFLINE === "1") {
|
|
149
|
+
component.updateResult({
|
|
150
|
+
content: [{ type: "text", text: "Web search disabled (offline mode)" }],
|
|
151
|
+
isError: false,
|
|
152
|
+
});
|
|
153
|
+
host.pendingTools.delete(content.toolUseId);
|
|
154
|
+
} else {
|
|
155
|
+
const searchContent = content.content;
|
|
156
|
+
const isError = searchContent && typeof searchContent === "object" && "type" in (searchContent as any) && (searchContent as any).type === "web_search_tool_result_error";
|
|
157
|
+
component.updateResult({
|
|
158
|
+
content: [{ type: "text", text: host.formatWebSearchResult(searchContent) }],
|
|
159
|
+
isError: !!isError,
|
|
160
|
+
});
|
|
161
|
+
host.pendingTools.delete(content.toolUseId);
|
|
162
|
+
}
|
|
154
163
|
}
|
|
155
164
|
}
|
|
156
165
|
}
|
|
@@ -2099,11 +2099,13 @@ export class InteractiveMode {
|
|
|
2099
2099
|
const userComponent = new UserMessageComponent(
|
|
2100
2100
|
skillBlock.userMessage,
|
|
2101
2101
|
this.getMarkdownThemeWithSettings(),
|
|
2102
|
+
message.timestamp,
|
|
2103
|
+
this.settingsManager.getTimestampFormat(),
|
|
2102
2104
|
);
|
|
2103
2105
|
this.chatContainer.addChild(userComponent);
|
|
2104
2106
|
}
|
|
2105
2107
|
} else {
|
|
2106
|
-
const userComponent = new UserMessageComponent(textContent, this.getMarkdownThemeWithSettings());
|
|
2108
|
+
const userComponent = new UserMessageComponent(textContent, this.getMarkdownThemeWithSettings(), message.timestamp, this.settingsManager.getTimestampFormat());
|
|
2107
2109
|
this.chatContainer.addChild(userComponent);
|
|
2108
2110
|
}
|
|
2109
2111
|
if (options?.populateHistory) {
|
|
@@ -2117,6 +2119,7 @@ export class InteractiveMode {
|
|
|
2117
2119
|
message,
|
|
2118
2120
|
this.hideThinkingBlock,
|
|
2119
2121
|
this.getMarkdownThemeWithSettings(),
|
|
2122
|
+
this.settingsManager.getTimestampFormat(),
|
|
2120
2123
|
);
|
|
2121
2124
|
this.chatContainer.addChild(assistantComponent);
|
|
2122
2125
|
break;
|
|
@@ -2795,6 +2798,7 @@ export class InteractiveMode {
|
|
|
2795
2798
|
respectGitignoreInPicker: this.settingsManager.getRespectGitignoreInPicker(),
|
|
2796
2799
|
quietStartup: this.settingsManager.getQuietStartup(),
|
|
2797
2800
|
clearOnShrink: this.settingsManager.getClearOnShrink(),
|
|
2801
|
+
timestampFormat: this.settingsManager.getTimestampFormat(),
|
|
2798
2802
|
},
|
|
2799
2803
|
{
|
|
2800
2804
|
onAutoCompactChange: (enabled) => {
|
|
@@ -2898,6 +2902,9 @@ export class InteractiveMode {
|
|
|
2898
2902
|
this.settingsManager.setRespectGitignoreInPicker(enabled);
|
|
2899
2903
|
this.autocompleteProvider?.setRespectGitignore(enabled);
|
|
2900
2904
|
},
|
|
2905
|
+
onTimestampFormatChange: (format) => {
|
|
2906
|
+
this.settingsManager.setTimestampFormat(format);
|
|
2907
|
+
},
|
|
2901
2908
|
onCancel: () => {
|
|
2902
2909
|
done();
|
|
2903
2910
|
this.ui.requestRender();
|
package/pkg/package.json
CHANGED
|
@@ -153,6 +153,7 @@ export function pruneActivityLogs(activityDir: string, retentionDays: number): v
|
|
|
153
153
|
const cutoff = Date.now() - retentionDays * 86_400_000;
|
|
154
154
|
for (const entry of entries) {
|
|
155
155
|
if (entry.seq === maxSeq) continue; // always preserve highest-seq
|
|
156
|
+
if (retentionDays === 0) { try { unlinkSync(entry.filePath); } catch { /* skip */ } continue; }
|
|
156
157
|
try {
|
|
157
158
|
const mtime = statSync(entry.filePath).mtimeMs;
|
|
158
159
|
if (Math.floor(mtime) <= cutoff) unlinkSync(entry.filePath);
|
|
@@ -18,6 +18,9 @@ export const INFRA_ERROR_CODES: ReadonlySet<string> = new Set([
|
|
|
18
18
|
"EDQUOT", // disk quota exceeded
|
|
19
19
|
"EMFILE", // too many open files (process)
|
|
20
20
|
"ENFILE", // too many open files (system)
|
|
21
|
+
"ECONNREFUSED", // connection refused (offline / local server down)
|
|
22
|
+
"ENOTFOUND", // DNS lookup failed (offline / no network)
|
|
23
|
+
"ENETUNREACH", // network unreachable (offline / no route)
|
|
21
24
|
]);
|
|
22
25
|
|
|
23
26
|
/**
|
|
@@ -80,7 +80,6 @@ export interface LoopDeps {
|
|
|
80
80
|
basePath: string,
|
|
81
81
|
unitType: string,
|
|
82
82
|
unitId: string,
|
|
83
|
-
completedUnits: number,
|
|
84
83
|
sessionFile?: string,
|
|
85
84
|
) => void;
|
|
86
85
|
handleLostSessionLock: (
|
|
@@ -179,29 +178,11 @@ export interface LoopDeps {
|
|
|
179
178
|
startedAt: number,
|
|
180
179
|
opts?: CloseoutOptions & Record<string, unknown>,
|
|
181
180
|
) => Promise<void>;
|
|
182
|
-
verifyExpectedArtifact: (
|
|
183
|
-
unitType: string,
|
|
184
|
-
unitId: string,
|
|
185
|
-
basePath: string,
|
|
186
|
-
) => boolean;
|
|
187
|
-
clearUnitRuntimeRecord: (
|
|
188
|
-
basePath: string,
|
|
189
|
-
unitType: string,
|
|
190
|
-
unitId: string,
|
|
191
|
-
) => void;
|
|
192
|
-
writeUnitRuntimeRecord: (
|
|
193
|
-
basePath: string,
|
|
194
|
-
unitType: string,
|
|
195
|
-
unitId: string,
|
|
196
|
-
startedAt: number,
|
|
197
|
-
record: Record<string, unknown>,
|
|
198
|
-
) => void;
|
|
199
181
|
recordOutcome: (unitType: string, tier: string, success: boolean) => void;
|
|
200
182
|
writeLock: (
|
|
201
183
|
lockBase: string,
|
|
202
184
|
unitType: string,
|
|
203
185
|
unitId: string,
|
|
204
|
-
completedCount: number,
|
|
205
186
|
sessionFile?: string,
|
|
206
187
|
) => void;
|
|
207
188
|
captureAvailableSkills: () => void;
|
|
@@ -24,10 +24,15 @@ import {
|
|
|
24
24
|
import { detectStuck } from "./detect-stuck.js";
|
|
25
25
|
import { runUnit } from "./run-unit.js";
|
|
26
26
|
import { debugLog } from "../debug-logger.js";
|
|
27
|
-
import { gsdRoot } from "../paths.js";
|
|
28
|
-
import { atomicWriteSync } from "../atomic-write.js";
|
|
29
27
|
import { PROJECT_FILES } from "../detection.js";
|
|
28
|
+
import { MergeConflictError } from "../git-service.js";
|
|
30
29
|
import { join } from "node:path";
|
|
30
|
+
import { existsSync, cpSync } from "node:fs";
|
|
31
|
+
import { logWarning, logError } from "../workflow-logger.js";
|
|
32
|
+
import { gsdRoot } from "../paths.js";
|
|
33
|
+
import { atomicWriteSync } from "../atomic-write.js";
|
|
34
|
+
import { verifyExpectedArtifact } from "../auto-recovery.js";
|
|
35
|
+
import { writeUnitRuntimeRecord } from "../unit-runtime.js";
|
|
31
36
|
|
|
32
37
|
// ─── generateMilestoneReport ──────────────────────────────────────────────────
|
|
33
38
|
|
|
@@ -162,8 +167,8 @@ export async function runPreDispatch(
|
|
|
162
167
|
debugLog("autoLoop", { phase: "exit", reason: "health-gate-failed" });
|
|
163
168
|
return { action: "break", reason: "health-gate-failed" };
|
|
164
169
|
}
|
|
165
|
-
} catch {
|
|
166
|
-
|
|
170
|
+
} catch (e) {
|
|
171
|
+
logWarning("engine", "Pre-dispatch health gate threw unexpectedly", { error: String(e) });
|
|
167
172
|
}
|
|
168
173
|
|
|
169
174
|
// Sync project root artifacts into worktree
|
|
@@ -233,26 +238,24 @@ export async function runPreDispatch(
|
|
|
233
238
|
loopState.stuckRecoveryAttempts = 0;
|
|
234
239
|
|
|
235
240
|
// Worktree lifecycle on milestone transition — merge current, enter next
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
s.currentMilestoneId!,
|
|
245
|
-
`[GSD] ${s.currentMilestoneId} complete`,
|
|
246
|
-
`Milestone ${s.currentMilestoneId} completed by GSD auto-mode.\n\nSee .gsd/${s.currentMilestoneId}/ for details.`,
|
|
241
|
+
try {
|
|
242
|
+
deps.resolver.mergeAndExit(s.currentMilestoneId!, ctx.ui);
|
|
243
|
+
} catch (mergeErr) {
|
|
244
|
+
if (mergeErr instanceof MergeConflictError) {
|
|
245
|
+
// Real code conflicts — stop the loop instead of retrying forever (#2330)
|
|
246
|
+
ctx.ui.notify(
|
|
247
|
+
`Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`,
|
|
248
|
+
"error",
|
|
247
249
|
);
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
} catch {
|
|
252
|
-
// Non-fatal — PR creation is best-effort
|
|
250
|
+
await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
|
|
251
|
+
return { action: "break", reason: "merge-conflict" };
|
|
253
252
|
}
|
|
253
|
+
// Non-conflict merge errors — log and continue
|
|
254
|
+
logWarning("engine", "Milestone merge failed with non-conflict error", { milestone: s.currentMilestoneId!, error: String(mergeErr) });
|
|
254
255
|
}
|
|
255
256
|
|
|
257
|
+
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
258
|
+
|
|
256
259
|
deps.invalidateAllCaches();
|
|
257
260
|
|
|
258
261
|
state = await deps.deriveState(s.basePath);
|
|
@@ -276,14 +279,20 @@ export async function runPreDispatch(
|
|
|
276
279
|
.map((m: { id: string }) => m.id);
|
|
277
280
|
deps.pruneQueueOrder(s.basePath, pendingIds);
|
|
278
281
|
|
|
279
|
-
//
|
|
280
|
-
// from the previous milestone cause the dispatch loop to skip units
|
|
281
|
-
// that haven't actually been completed in the new milestone's context.
|
|
282
|
-
s.completedUnits = [];
|
|
282
|
+
// Archive the old completed-units.json instead of wiping it (#2313).
|
|
283
283
|
try {
|
|
284
284
|
const completedKeysPath = join(gsdRoot(s.basePath), "completed-units.json");
|
|
285
|
+
if (existsSync(completedKeysPath) && s.currentMilestoneId) {
|
|
286
|
+
const archivePath = join(
|
|
287
|
+
gsdRoot(s.basePath),
|
|
288
|
+
`completed-units-${s.currentMilestoneId}.json`,
|
|
289
|
+
);
|
|
290
|
+
cpSync(completedKeysPath, archivePath);
|
|
291
|
+
}
|
|
285
292
|
atomicWriteSync(completedKeysPath, JSON.stringify([], null, 2));
|
|
286
|
-
} catch {
|
|
293
|
+
} catch (e) {
|
|
294
|
+
logWarning("engine", "Failed to archive completed-units on milestone transition", { error: String(e) });
|
|
295
|
+
}
|
|
287
296
|
|
|
288
297
|
// Rebuild STATE.md immediately so it reflects the new active milestone.
|
|
289
298
|
// This bypasses the 30-second throttle in the normal rebuild path —
|
|
@@ -291,8 +300,8 @@ export async function runPreDispatch(
|
|
|
291
300
|
// immediate write.
|
|
292
301
|
try {
|
|
293
302
|
await deps.rebuildState(s.basePath);
|
|
294
|
-
} catch {
|
|
295
|
-
|
|
303
|
+
} catch (e) {
|
|
304
|
+
logWarning("engine", "STATE.md rebuild failed after milestone transition", { error: String(e) });
|
|
296
305
|
}
|
|
297
306
|
}
|
|
298
307
|
|
|
@@ -322,25 +331,20 @@ export async function runPreDispatch(
|
|
|
322
331
|
if (incomplete.length === 0 && state.registry.length > 0) {
|
|
323
332
|
// All milestones complete — merge milestone branch before stopping
|
|
324
333
|
if (s.currentMilestoneId) {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
s.basePath,
|
|
333
|
-
s.currentMilestoneId,
|
|
334
|
-
`[GSD] ${s.currentMilestoneId} complete`,
|
|
335
|
-
`Milestone ${s.currentMilestoneId} completed by GSD auto-mode.\n\nSee .gsd/${s.currentMilestoneId}/ for details.`,
|
|
334
|
+
try {
|
|
335
|
+
deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
|
|
336
|
+
} catch (mergeErr) {
|
|
337
|
+
if (mergeErr instanceof MergeConflictError) {
|
|
338
|
+
ctx.ui.notify(
|
|
339
|
+
`Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`,
|
|
340
|
+
"error",
|
|
336
341
|
);
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
}
|
|
340
|
-
} catch {
|
|
341
|
-
// Non-fatal — PR creation is best-effort
|
|
342
|
+
await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
|
|
343
|
+
return { action: "break", reason: "merge-conflict" };
|
|
342
344
|
}
|
|
343
345
|
}
|
|
346
|
+
|
|
347
|
+
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
344
348
|
}
|
|
345
349
|
deps.sendDesktopNotification(
|
|
346
350
|
"GSD",
|
|
@@ -422,25 +426,20 @@ export async function runPreDispatch(
|
|
|
422
426
|
if (state.phase === "complete") {
|
|
423
427
|
// Milestone merge on complete (before closeout so branch state is clean)
|
|
424
428
|
if (s.currentMilestoneId) {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
s.basePath,
|
|
433
|
-
s.currentMilestoneId,
|
|
434
|
-
`[GSD] ${s.currentMilestoneId} complete`,
|
|
435
|
-
`Milestone ${s.currentMilestoneId} completed by GSD auto-mode.\n\nSee .gsd/${s.currentMilestoneId}/ for details.`,
|
|
429
|
+
try {
|
|
430
|
+
deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
|
|
431
|
+
} catch (mergeErr) {
|
|
432
|
+
if (mergeErr instanceof MergeConflictError) {
|
|
433
|
+
ctx.ui.notify(
|
|
434
|
+
`Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`,
|
|
435
|
+
"error",
|
|
436
436
|
);
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
}
|
|
440
|
-
} catch {
|
|
441
|
-
// Non-fatal — PR creation is best-effort
|
|
437
|
+
await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
|
|
438
|
+
return { action: "break", reason: "merge-conflict" };
|
|
442
439
|
}
|
|
443
440
|
}
|
|
441
|
+
|
|
442
|
+
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
444
443
|
}
|
|
445
444
|
deps.sendDesktopNotification(
|
|
446
445
|
"GSD",
|
|
@@ -539,7 +538,7 @@ export async function runDispatch(
|
|
|
539
538
|
if (loopState.stuckRecoveryAttempts === 0) {
|
|
540
539
|
// Level 1: try verifying the artifact, then cache invalidation + retry
|
|
541
540
|
loopState.stuckRecoveryAttempts++;
|
|
542
|
-
const artifactExists =
|
|
541
|
+
const artifactExists = verifyExpectedArtifact(
|
|
543
542
|
unitType,
|
|
544
543
|
unitId,
|
|
545
544
|
s.basePath,
|
|
@@ -848,7 +847,7 @@ export async function runUnitPhase(
|
|
|
848
847
|
const unitStartSeq = ic.nextSeq();
|
|
849
848
|
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: unitStartSeq, eventType: "unit-start", data: { unitType, unitId } });
|
|
850
849
|
deps.captureAvailableSkills();
|
|
851
|
-
|
|
850
|
+
writeUnitRuntimeRecord(
|
|
852
851
|
s.basePath,
|
|
853
852
|
unitType,
|
|
854
853
|
unitId,
|
|
@@ -860,6 +859,7 @@ export async function runUnitPhase(
|
|
|
860
859
|
lastProgressAt: s.currentUnit.startedAt,
|
|
861
860
|
progressCount: 0,
|
|
862
861
|
lastProgressKind: "dispatch",
|
|
862
|
+
recoveryAttempts: 0, // Reset so re-dispatched units get full recovery budget (#2322)
|
|
863
863
|
},
|
|
864
864
|
);
|
|
865
865
|
|
|
@@ -921,8 +921,8 @@ export async function runUnitPhase(
|
|
|
921
921
|
(decisionsContent?.length ?? 0) +
|
|
922
922
|
(requirementsContent?.length ?? 0) +
|
|
923
923
|
(projectContent?.length ?? 0);
|
|
924
|
-
} catch {
|
|
925
|
-
|
|
924
|
+
} catch (e) {
|
|
925
|
+
logWarning("engine", "Baseline char count measurement failed", { error: String(e) });
|
|
926
926
|
}
|
|
927
927
|
}
|
|
928
928
|
|
|
@@ -932,9 +932,7 @@ export async function runUnitPhase(
|
|
|
932
932
|
} catch (reorderErr) {
|
|
933
933
|
const msg =
|
|
934
934
|
reorderErr instanceof Error ? reorderErr.message : String(reorderErr);
|
|
935
|
-
|
|
936
|
-
`[gsd] prompt reorder failed (non-fatal): ${msg}\n`,
|
|
937
|
-
);
|
|
935
|
+
logWarning("engine", "Prompt reorder failed", { error: msg });
|
|
938
936
|
}
|
|
939
937
|
|
|
940
938
|
// Select and apply model (with tier escalation on retry — normal units only)
|
|
@@ -1001,7 +999,6 @@ export async function runUnitPhase(
|
|
|
1001
999
|
deps.lockBase(),
|
|
1002
1000
|
unitType,
|
|
1003
1001
|
unitId,
|
|
1004
|
-
s.completedUnits.length,
|
|
1005
1002
|
);
|
|
1006
1003
|
|
|
1007
1004
|
debugLog("autoLoop", {
|
|
@@ -1032,14 +1029,12 @@ export async function runUnitPhase(
|
|
|
1032
1029
|
deps.lockBase(),
|
|
1033
1030
|
unitType,
|
|
1034
1031
|
unitId,
|
|
1035
|
-
s.completedUnits.length,
|
|
1036
1032
|
sessionFile,
|
|
1037
1033
|
);
|
|
1038
1034
|
deps.writeLock(
|
|
1039
1035
|
deps.lockBase(),
|
|
1040
1036
|
unitType,
|
|
1041
1037
|
unitId,
|
|
1042
|
-
s.completedUnits.length,
|
|
1043
1038
|
sessionFile,
|
|
1044
1039
|
);
|
|
1045
1040
|
|
|
@@ -1103,8 +1098,8 @@ export async function runUnitPhase(
|
|
|
1103
1098
|
`${unitType} ${unitId} completed with 0 tool calls — hallucinated summary, will retry`,
|
|
1104
1099
|
"warning",
|
|
1105
1100
|
);
|
|
1106
|
-
//
|
|
1107
|
-
//
|
|
1101
|
+
// Fall through to next iteration where dispatch will re-derive
|
|
1102
|
+
// and re-dispatch this task.
|
|
1108
1103
|
return { action: "next", data: { unitStartedAt: s.currentUnit.startedAt } };
|
|
1109
1104
|
}
|
|
1110
1105
|
}
|
|
@@ -1121,25 +1116,8 @@ export async function runUnitPhase(
|
|
|
1121
1116
|
const skipArtifactVerification = unitType.startsWith("hook/") || unitType === "custom-step";
|
|
1122
1117
|
const artifactVerified =
|
|
1123
1118
|
skipArtifactVerification ||
|
|
1124
|
-
|
|
1119
|
+
verifyExpectedArtifact(unitType, unitId, s.basePath);
|
|
1125
1120
|
if (artifactVerified) {
|
|
1126
|
-
s.completedUnits.push({
|
|
1127
|
-
type: unitType,
|
|
1128
|
-
id: unitId,
|
|
1129
|
-
startedAt: s.currentUnit.startedAt,
|
|
1130
|
-
finishedAt: Date.now(),
|
|
1131
|
-
});
|
|
1132
|
-
if (s.completedUnits.length > 200) {
|
|
1133
|
-
s.completedUnits = s.completedUnits.slice(-200);
|
|
1134
|
-
}
|
|
1135
|
-
// Flush completed-units to disk so the record survives crashes
|
|
1136
|
-
try {
|
|
1137
|
-
const completedKeysPath = join(gsdRoot(s.basePath), "completed-units.json");
|
|
1138
|
-
const keys = s.completedUnits.map((u) => `${u.type}/${u.id}`);
|
|
1139
|
-
atomicWriteSync(completedKeysPath, JSON.stringify(keys, null, 2));
|
|
1140
|
-
} catch { /* non-fatal: disk flush failure */ }
|
|
1141
|
-
|
|
1142
|
-
deps.clearUnitRuntimeRecord(s.basePath, unitType, unitId);
|
|
1143
1121
|
s.unitDispatchCount.delete(`${unitType}/${unitId}`);
|
|
1144
1122
|
s.unitRecoveryCount.delete(`${unitType}/${unitId}`);
|
|
1145
1123
|
}
|
|
@@ -1184,8 +1162,8 @@ export async function runFinalize(
|
|
|
1184
1162
|
// Sidecar items use lightweight pre-verification opts
|
|
1185
1163
|
const preVerificationOpts: PreVerificationOpts | undefined = sidecarItem
|
|
1186
1164
|
? sidecarItem.kind === "hook"
|
|
1187
|
-
? { skipSettleDelay: true,
|
|
1188
|
-
: { skipSettleDelay: true
|
|
1165
|
+
? { skipSettleDelay: true, skipWorktreeSync: true }
|
|
1166
|
+
: { skipSettleDelay: true }
|
|
1189
1167
|
: undefined;
|
|
1190
1168
|
const preResult = await deps.postUnitPreVerification(postUnitCtx, preVerificationOpts);
|
|
1191
1169
|
if (preResult === "dispatched") {
|
|
@@ -11,6 +11,7 @@ import { NEW_SESSION_TIMEOUT_MS } from "./session.js";
|
|
|
11
11
|
import type { UnitResult } from "./types.js";
|
|
12
12
|
import { _setCurrentResolve, _setSessionSwitchInFlight } from "./resolve.js";
|
|
13
13
|
import { debugLog } from "../debug-logger.js";
|
|
14
|
+
import { logWarning, logError } from "../workflow-logger.js";
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Execute a single unit: create a new session, send the prompt, and await
|
|
@@ -85,7 +86,9 @@ export async function runUnit(
|
|
|
85
86
|
if (process.cwd() !== s.basePath) {
|
|
86
87
|
process.chdir(s.basePath);
|
|
87
88
|
}
|
|
88
|
-
} catch {
|
|
89
|
+
} catch (e) {
|
|
90
|
+
logWarning("engine", "Failed to chdir to basePath before dispatch", { basePath: s.basePath, error: String(e) });
|
|
91
|
+
}
|
|
89
92
|
|
|
90
93
|
// ── Send the prompt ──
|
|
91
94
|
debugLog("runUnit", { phase: "send-message", unitType, unitId });
|
|
@@ -115,8 +118,8 @@ export async function runUnit(
|
|
|
115
118
|
if (typeof cmdCtxAny?.clearQueue === "function") {
|
|
116
119
|
(cmdCtxAny.clearQueue as () => unknown)();
|
|
117
120
|
}
|
|
118
|
-
} catch {
|
|
119
|
-
|
|
121
|
+
} catch (e) {
|
|
122
|
+
logWarning("engine", "clearQueue failed after unit completion", { error: String(e) });
|
|
120
123
|
}
|
|
121
124
|
|
|
122
125
|
return result;
|
|
@@ -23,13 +23,6 @@ import type { BudgetAlertLevel } from "../auto-budget.js";
|
|
|
23
23
|
|
|
24
24
|
// ─── Exported Types ──────────────────────────────────────────────────────────
|
|
25
25
|
|
|
26
|
-
export interface CompletedUnit {
|
|
27
|
-
type: string;
|
|
28
|
-
id: string;
|
|
29
|
-
startedAt: number;
|
|
30
|
-
finishedAt: number;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
26
|
export interface CurrentUnit {
|
|
34
27
|
type: string;
|
|
35
28
|
id: string;
|
|
@@ -106,7 +99,6 @@ export class AutoSession {
|
|
|
106
99
|
// ── Current unit ─────────────────────────────────────────────────────────
|
|
107
100
|
currentUnit: CurrentUnit | null = null;
|
|
108
101
|
currentUnitRouting: UnitRouting | null = null;
|
|
109
|
-
completedUnits: CompletedUnit[] = [];
|
|
110
102
|
currentMilestoneId: string | null = null;
|
|
111
103
|
|
|
112
104
|
// ── Model state ──────────────────────────────────────────────────────────
|
|
@@ -160,14 +152,6 @@ export class AutoSession {
|
|
|
160
152
|
return this.originalBasePath || this.basePath;
|
|
161
153
|
}
|
|
162
154
|
|
|
163
|
-
completeCurrentUnit(): CompletedUnit | null {
|
|
164
|
-
if (!this.currentUnit) return null;
|
|
165
|
-
const done: CompletedUnit = { ...this.currentUnit, finishedAt: Date.now() };
|
|
166
|
-
this.completedUnits.push(done);
|
|
167
|
-
this.currentUnit = null;
|
|
168
|
-
return done;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
155
|
reset(): void {
|
|
172
156
|
this.clearTimers();
|
|
173
157
|
|
|
@@ -193,7 +177,6 @@ export class AutoSession {
|
|
|
193
177
|
// Unit
|
|
194
178
|
this.currentUnit = null;
|
|
195
179
|
this.currentUnitRouting = null;
|
|
196
|
-
this.completedUnits = [];
|
|
197
180
|
this.currentMilestoneId = null;
|
|
198
181
|
|
|
199
182
|
// Model
|
|
@@ -234,7 +217,6 @@ export class AutoSession {
|
|
|
234
217
|
activeRunDir: this.activeRunDir,
|
|
235
218
|
currentMilestoneId: this.currentMilestoneId,
|
|
236
219
|
currentUnit: this.currentUnit,
|
|
237
|
-
completedUnits: this.completedUnits.length,
|
|
238
220
|
unitDispatchCount: Object.fromEntries(this.unitDispatchCount),
|
|
239
221
|
};
|
|
240
222
|
}
|