@opengsd/gsd-pi 1.8.1 → 1.9.0-dev.5c1a3ff2
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 +10 -8
- package/dist/cli.js +5 -1
- package/dist/headless-events.d.ts +2 -1
- package/dist/headless-events.js +11 -3
- package/dist/headless-milestone-readiness.d.ts +29 -0
- package/dist/headless-milestone-readiness.js +161 -0
- package/dist/headless.js +25 -2
- package/dist/print-mode-exit.d.ts +12 -0
- package/dist/print-mode-exit.js +14 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +18 -49
- package/dist/resources/extensions/browser-tools/capture.js +2 -77
- package/dist/resources/extensions/browser-tools/screenshot-constraints.js +83 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +17 -2
- package/dist/resources/extensions/claude-code-cli/turn-assembler.js +30 -2
- package/dist/resources/extensions/gsd/artifact-verification.js +3 -4
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +16 -10
- package/dist/resources/extensions/gsd/auto-dispatch.js +74 -19
- package/dist/resources/extensions/gsd/auto-post-unit.js +4 -0
- package/dist/resources/extensions/gsd/auto-prompts.js +125 -18
- package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
- package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +4 -0
- package/dist/resources/extensions/gsd/auto-worktree-teardown.js +1 -1
- package/dist/resources/extensions/gsd/auto.js +5 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -4
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +31 -5
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +10 -3
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +88 -50
- package/dist/resources/extensions/gsd/command-feedback.js +16 -12
- package/dist/resources/extensions/gsd/compat/compat-marker.js +19 -2
- package/dist/resources/extensions/gsd/constants.js +12 -13
- package/dist/resources/extensions/gsd/context-masker.js +97 -21
- package/dist/resources/extensions/gsd/db/command-queue.js +7 -2
- package/dist/resources/extensions/gsd/db/engine.js +51 -16
- package/dist/resources/extensions/gsd/db/writers/cascades.js +5 -1
- package/dist/resources/extensions/gsd/db/writers/status.js +13 -3
- package/dist/resources/extensions/gsd/db-base-schema.js +28 -0
- package/dist/resources/extensions/gsd/db-migration-steps.js +30 -0
- package/dist/resources/extensions/gsd/db-schema-metadata.js +4 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +26 -4
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +3 -6
- package/dist/resources/extensions/gsd/flat-phase-migration.js +156 -21
- package/dist/resources/extensions/gsd/git-service.js +19 -7
- package/dist/resources/extensions/gsd/gsd-db.js +187 -45
- package/dist/resources/extensions/gsd/guided-flow.js +38 -13
- package/dist/resources/extensions/gsd/markdown-renderer.js +17 -13
- package/dist/resources/extensions/gsd/md-importer.js +107 -20
- package/dist/resources/extensions/gsd/migrate/command.js +19 -162
- package/dist/resources/extensions/gsd/migrate/execution.js +98 -0
- package/dist/resources/extensions/gsd/migrate/plan.js +49 -0
- package/dist/resources/extensions/gsd/migrate/planning-writer.js +12 -17
- package/dist/resources/extensions/gsd/migrate/presentation.js +64 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +2 -0
- package/dist/resources/extensions/gsd/model-router.js +11 -0
- package/dist/resources/extensions/gsd/parallel-eligibility.js +5 -4
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +28 -43
- package/dist/resources/extensions/gsd/paths.js +55 -11
- package/dist/resources/extensions/gsd/phase-anchor.js +7 -2
- package/dist/resources/extensions/gsd/planning-subagent-policy.js +37 -0
- package/dist/resources/extensions/gsd/planning-subagent-registry.js +25 -0
- package/dist/resources/extensions/gsd/post-execution-checks.js +4 -4
- package/dist/resources/extensions/gsd/preferences-types.js +5 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +48 -1
- package/dist/resources/extensions/gsd/preferences.js +17 -0
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/provider-payload-policy.js +16 -5
- package/dist/resources/extensions/gsd/safety/destructive-guard.js +1 -1
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +26 -1
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +30 -5
- package/dist/resources/extensions/gsd/skill-activation.js +17 -3
- package/dist/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.js +27 -13
- package/dist/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.js +13 -3
- package/dist/resources/extensions/gsd/stop-notice.js +15 -1
- package/dist/resources/extensions/gsd/sync-lock.js +13 -7
- package/dist/resources/extensions/gsd/templates/PREFERENCES.md +5 -0
- package/dist/resources/extensions/gsd/tools/complete-task.js +94 -6
- package/dist/resources/extensions/gsd/tools/plan-task.js +13 -15
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +18 -15
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +14 -5
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +15 -5
- package/dist/resources/extensions/gsd/tools/reopen-task.js +16 -10
- package/dist/resources/extensions/gsd/tools/replan-task.js +128 -0
- package/dist/resources/extensions/gsd/tools/rework-brief.js +74 -0
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +81 -0
- package/dist/resources/extensions/gsd/unit-context-composer.js +28 -5
- package/dist/resources/extensions/gsd/unit-registry.js +4 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +19 -3
- package/dist/resources/extensions/gsd/workflow-projections.js +2 -3
- package/dist/resources/extensions/gsd/workspace.js +2 -1
- package/dist/resources/extensions/gsd/worktree-state-projection.js +6 -0
- package/dist/resources/extensions/mac-tools/index.js +31 -9
- 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 +8 -8
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +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.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +5 -5
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
- package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
- package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +3 -3
- 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/app/_not-found/page-a6fb1847f67f167c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
- package/dist/web/standalone/.next/static/css/3b1ceb7abfb9a230.css +1 -0
- package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/package.json +0 -1
- package/dist/web/standalone/server.js +1 -1
- package/dist/web-mode.js +31 -3
- package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
- package/integrations/hermes/pyproject.toml +1 -1
- package/package.json +12 -10
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/workflow.d.ts +14 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +16 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/dist/cloud-config.d.ts +1 -1
- package/packages/daemon/dist/cloud-config.d.ts.map +1 -1
- package/packages/daemon/dist/cloud-config.js +5 -1
- package/packages/daemon/dist/cloud-config.js.map +1 -1
- package/packages/daemon/dist/cloud-config.test.js +51 -1
- package/packages/daemon/dist/cloud-config.test.js.map +1 -1
- package/packages/daemon/dist/local-tool-executor.d.ts.map +1 -1
- package/packages/daemon/dist/local-tool-executor.js +2 -0
- package/packages/daemon/dist/local-tool-executor.js.map +1 -1
- package/packages/daemon/package.json +6 -6
- package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.js +36 -4
- package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
- package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/sdk.js +1 -0
- package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/gsd-cloud/dist/cli.d.ts +5 -0
- package/packages/gsd-cloud/dist/cli.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cli.js +160 -0
- package/packages/gsd-cloud/dist/cli.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.d.ts +19 -0
- package/packages/gsd-cloud/dist/cloud-config.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.js +231 -0
- package/packages/gsd-cloud/dist/cloud-config.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/cloud-config.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.test.js +118 -0
- package/packages/gsd-cloud/dist/cloud-config.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js +37 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.d.ts +35 -0
- package/packages/gsd-cloud/dist/cloud-runtime.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.js +258 -0
- package/packages/gsd-cloud/dist/cloud-runtime.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.js +88 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-token.d.ts +3 -0
- package/packages/gsd-cloud/dist/cloud-token.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-token.js +37 -0
- package/packages/gsd-cloud/dist/cloud-token.js.map +1 -0
- package/packages/gsd-cloud/dist/config.d.ts +17 -0
- package/packages/gsd-cloud/dist/config.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/config.js +146 -0
- package/packages/gsd-cloud/dist/config.js.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.d.ts +24 -0
- package/packages/gsd-cloud/dist/device-flow.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.js +128 -0
- package/packages/gsd-cloud/dist/device-flow.js.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/device-flow.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.test.js +155 -0
- package/packages/gsd-cloud/dist/device-flow.test.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.d.ts +6 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.js +15 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.d.ts +6 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.js +15 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/executor.d.ts +28 -0
- package/packages/gsd-cloud/dist/executors/executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/executor.js +11 -0
- package/packages/gsd-cloud/dist/executors/executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts +34 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js +179 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js +44 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/index.d.ts +17 -0
- package/packages/gsd-cloud/dist/executors/index.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/index.js +29 -0
- package/packages/gsd-cloud/dist/executors/index.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts +36 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js +176 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js +34 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js.map +1 -0
- package/packages/gsd-cloud/dist/index.d.ts +7 -0
- package/packages/gsd-cloud/dist/index.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/index.js +8 -0
- package/packages/gsd-cloud/dist/index.js.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.d.ts +16 -0
- package/packages/gsd-cloud/dist/inject-gateway.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.js +29 -0
- package/packages/gsd-cloud/dist/inject-gateway.js.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.js +41 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.js.map +1 -0
- package/packages/gsd-cloud/dist/logger.d.ts +25 -0
- package/packages/gsd-cloud/dist/logger.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/logger.js +72 -0
- package/packages/gsd-cloud/dist/logger.js.map +1 -0
- package/packages/gsd-cloud/dist/types.d.ts +51 -0
- package/packages/gsd-cloud/dist/types.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/types.js +9 -0
- package/packages/gsd-cloud/dist/types.js.map +1 -0
- package/packages/gsd-cloud/package.json +3 -3
- package/packages/mcp-server/README.md +15 -2
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +5 -5
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +4 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +64 -2
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +5 -1
- 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/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +119 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +107 -0
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/amazon-bedrock.js +1 -0
- package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +25 -1
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.js +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +11 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +8 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +18 -49
- package/src/resources/extensions/browser-tools/capture.ts +2 -86
- package/src/resources/extensions/browser-tools/screenshot-constraints.ts +94 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +18 -1
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -0
- package/src/resources/extensions/claude-code-cli/turn-assembler.ts +30 -2
- package/src/resources/extensions/gsd/artifact-verification.ts +3 -8
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +16 -9
- package/src/resources/extensions/gsd/auto-dispatch.ts +86 -19
- package/src/resources/extensions/gsd/auto-post-unit.ts +4 -0
- package/src/resources/extensions/gsd/auto-prompts.ts +142 -16
- package/src/resources/extensions/gsd/auto-recovery.ts +10 -8
- package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +4 -0
- package/src/resources/extensions/gsd/auto-worktree-teardown.ts +1 -1
- package/src/resources/extensions/gsd/auto.ts +5 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +92 -4
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +39 -10
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +11 -3
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +87 -53
- package/src/resources/extensions/gsd/command-feedback.ts +19 -12
- package/src/resources/extensions/gsd/compat/compat-marker.ts +21 -4
- package/src/resources/extensions/gsd/constants.ts +14 -13
- package/src/resources/extensions/gsd/context-masker.ts +98 -2
- package/src/resources/extensions/gsd/db/command-queue.ts +7 -1
- package/src/resources/extensions/gsd/db/engine.ts +53 -17
- package/src/resources/extensions/gsd/db/writers/cascades.ts +5 -1
- package/src/resources/extensions/gsd/db/writers/status.ts +25 -8
- package/src/resources/extensions/gsd/db-base-schema.ts +30 -0
- package/src/resources/extensions/gsd/db-migration-steps.ts +32 -0
- package/src/resources/extensions/gsd/db-schema-metadata.ts +4 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +26 -4
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +3 -5
- package/src/resources/extensions/gsd/flat-phase-migration.ts +160 -19
- package/src/resources/extensions/gsd/git-service.ts +19 -6
- package/src/resources/extensions/gsd/gsd-db.ts +255 -52
- package/src/resources/extensions/gsd/guided-flow.ts +48 -12
- package/src/resources/extensions/gsd/markdown-renderer.ts +25 -21
- package/src/resources/extensions/gsd/md-importer.ts +114 -16
- package/src/resources/extensions/gsd/migrate/command.ts +21 -227
- package/src/resources/extensions/gsd/migrate/execution.ts +136 -0
- package/src/resources/extensions/gsd/migrate/plan.ts +101 -0
- package/src/resources/extensions/gsd/migrate/planning-writer.ts +12 -20
- package/src/resources/extensions/gsd/migrate/presentation.ts +83 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +2 -0
- package/src/resources/extensions/gsd/model-router.ts +12 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +5 -4
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +37 -40
- package/src/resources/extensions/gsd/paths.ts +62 -11
- package/src/resources/extensions/gsd/phase-anchor.ts +8 -2
- package/src/resources/extensions/gsd/planning-subagent-policy.ts +58 -0
- package/src/resources/extensions/gsd/planning-subagent-registry.ts +31 -0
- package/src/resources/extensions/gsd/post-execution-checks.ts +4 -4
- package/src/resources/extensions/gsd/preferences-types.ts +16 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +62 -0
- package/src/resources/extensions/gsd/preferences.ts +25 -0
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/provider-payload-policy.ts +18 -4
- package/src/resources/extensions/gsd/safety/destructive-guard.ts +1 -1
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +28 -1
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +31 -5
- package/src/resources/extensions/gsd/skill-activation.ts +17 -3
- package/src/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.ts +30 -13
- package/src/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.ts +16 -3
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +2 -2
- package/src/resources/extensions/gsd/stop-notice.ts +18 -1
- package/src/resources/extensions/gsd/sync-lock.ts +14 -6
- package/src/resources/extensions/gsd/templates/PREFERENCES.md +5 -0
- package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/before-provider-context-management.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +96 -1
- package/src/resources/extensions/gsd/tests/command-feedback.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/compat-marker.test.ts +104 -0
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +362 -1
- package/src/resources/extensions/gsd/tests/context-masker.test.ts +204 -8
- package/src/resources/extensions/gsd/tests/db-engine-migrate-guards.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/db-tools-alias-suppression.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +81 -0
- package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/external-edit-scoped-import.test.ts +262 -0
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +202 -0
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/import-slice-milestone-completion-preserve.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/integration/paths.test.ts +22 -4
- package/src/resources/extensions/gsd/tests/integration-branch-meta-location.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +5 -5
- package/src/resources/extensions/gsd/tests/migrate-plan.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/migrate-presentation.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/migrate-safety-audit.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/milestone-leases.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
- package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/parallel-eligibility-file-overlap.test.ts +146 -0
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +7 -5
- package/src/resources/extensions/gsd/tests/phase-anchor.test.ts +32 -4
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +26 -23
- package/src/resources/extensions/gsd/tests/planning-writer.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +84 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/replan-task-handler.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/rework-brief.test.ts +197 -0
- package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +33 -7
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -16
- package/src/resources/extensions/gsd/tests/skip-slice-cascades-tasks.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/stop-notice.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/sync-lock.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +13 -7
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +93 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/workflow-migration-gates.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +52 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +140 -5
- package/src/resources/extensions/gsd/tools/plan-task.ts +14 -16
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +18 -17
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +24 -5
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +25 -5
- package/src/resources/extensions/gsd/tools/reopen-task.ts +23 -9
- package/src/resources/extensions/gsd/tools/replan-task.ts +160 -0
- package/src/resources/extensions/gsd/tools/rework-brief.ts +91 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +92 -0
- package/src/resources/extensions/gsd/types.ts +11 -0
- package/src/resources/extensions/gsd/unit-context-composer.ts +34 -8
- package/src/resources/extensions/gsd/unit-registry.ts +4 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +20 -3
- package/src/resources/extensions/gsd/workflow-projections.ts +2 -3
- package/src/resources/extensions/gsd/workspace.ts +2 -1
- package/src/resources/extensions/gsd/worktree-state-projection.ts +12 -0
- package/src/resources/extensions/mac-tools/index.ts +52 -9
- package/src/resources/extensions/mac-tools/tests/mac-screenshot-payload.test.cjs +70 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
- package/dist/web/standalone/.next/static/css/18c2fdf261bfc1b7.css +0 -1
- /package/dist/web/standalone/.next/static/{UaXRrOYxBpG9QBINKhZkg → 6YWV7VAPg-jqjfPswrKZb}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{UaXRrOYxBpG9QBINKhZkg → 6YWV7VAPg-jqjfPswrKZb}/_ssgManifest.js +0 -0
|
@@ -6,58 +6,14 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { Frame, Page } from "playwright";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// can still be loaded on platforms where sharp is unavailable (e.g. bunx on
|
|
12
|
-
// Raspberry Pi). constrainScreenshot falls back to returning the raw buffer
|
|
13
|
-
// when sharp is not installed, which means screenshots won't be resized but
|
|
14
|
-
// the tool remains functional.
|
|
15
|
-
let _sharp: typeof import("sharp") | null | undefined;
|
|
16
|
-
async function getSharp(): Promise<typeof import("sharp") | null> {
|
|
17
|
-
if (_sharp !== undefined) return _sharp;
|
|
18
|
-
try {
|
|
19
|
-
_sharp = (await import("sharp")).default;
|
|
20
|
-
} catch {
|
|
21
|
-
_sharp = null;
|
|
22
|
-
}
|
|
23
|
-
return _sharp;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Test-only seam: override the cached sharp module. Pass `null` to simulate
|
|
28
|
-
* an environment where the sharp native dep is unavailable; pass `undefined`
|
|
29
|
-
* to clear the cache and let the next getSharp() call re-import. See
|
|
30
|
-
* tests/capture-sharp-optional.test.cjs.
|
|
31
|
-
*/
|
|
32
|
-
export function __setSharpForTesting(
|
|
33
|
-
value: typeof import("sharp") | null | undefined,
|
|
34
|
-
): void {
|
|
35
|
-
_sharp = value;
|
|
36
|
-
}
|
|
9
|
+
import { constrainScreenshot } from "./screenshot-constraints.js";
|
|
10
|
+
export { constrainScreenshot, __setSharpForTesting } from "./screenshot-constraints.js";
|
|
37
11
|
import type { CompactPageState, CompactSelectorState } from "./state.js";
|
|
38
12
|
import { formatCompactStateSummary } from "./utils.js";
|
|
39
13
|
|
|
40
|
-
// Anthropic vision: 1568px is the recommended optimal width. Height is capped
|
|
41
|
-
// generously at 8000px so tall full-page screenshots remain readable rather
|
|
42
|
-
// than being squished into a square constraint.
|
|
43
|
-
//
|
|
44
14
|
// Override via environment variables:
|
|
45
|
-
// SCREENSHOT_MAX_WIDTH=0 → uncap width (use raw resolution)
|
|
46
|
-
// SCREENSHOT_MAX_HEIGHT=0 → uncap height
|
|
47
15
|
// SCREENSHOT_FORMAT=png → lossless PNG for all viewport/fullpage screenshots
|
|
48
16
|
// SCREENSHOT_QUALITY=100 → max JPEG quality (1-100, default 80)
|
|
49
|
-
const MAX_SCREENSHOT_WIDTH = parseScreenshotDimension(process.env.SCREENSHOT_MAX_WIDTH, 1568);
|
|
50
|
-
const MAX_SCREENSHOT_HEIGHT = parseScreenshotDimension(process.env.SCREENSHOT_MAX_HEIGHT, 8000);
|
|
51
|
-
|
|
52
|
-
/** Parse a dimension env var: positive int = that value, 0 = Infinity (uncapped), absent/invalid = default. */
|
|
53
|
-
function parseScreenshotDimension(value: string | undefined, fallback: number): number {
|
|
54
|
-
if (value === undefined || value === "") return fallback;
|
|
55
|
-
const n = parseInt(value, 10);
|
|
56
|
-
if (isNaN(n) || n < 0) return fallback;
|
|
57
|
-
if (n === 0) return Infinity;
|
|
58
|
-
return n;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
17
|
/** Return the user-configured screenshot format override, or null for default behavior. */
|
|
62
18
|
export function getScreenshotFormatOverride(): "png" | "jpeg" | null {
|
|
63
19
|
const fmt = process.env.SCREENSHOT_FORMAT?.toLowerCase();
|
|
@@ -176,46 +132,6 @@ export async function postActionSummary(p: Page, target?: Page | Frame): Promise
|
|
|
176
132
|
}
|
|
177
133
|
}
|
|
178
134
|
|
|
179
|
-
// ---------------------------------------------------------------------------
|
|
180
|
-
// Screenshot helpers
|
|
181
|
-
// ---------------------------------------------------------------------------
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Constrain screenshot dimensions for the Anthropic vision API.
|
|
185
|
-
* Width is capped at 1568px (optimal) and height at 8000px, each
|
|
186
|
-
* independently, using `fit: "inside"` so aspect ratio is preserved.
|
|
187
|
-
* Small images are never upscaled.
|
|
188
|
-
*
|
|
189
|
-
* `page` parameter is retained for ToolDeps signature stability (D008)
|
|
190
|
-
* but is no longer used — all processing is server-side via sharp.
|
|
191
|
-
*/
|
|
192
|
-
export async function constrainScreenshot(
|
|
193
|
-
_page: Page,
|
|
194
|
-
buffer: Buffer,
|
|
195
|
-
mimeType: string,
|
|
196
|
-
quality: number,
|
|
197
|
-
): Promise<Buffer> {
|
|
198
|
-
const sharp = await getSharp();
|
|
199
|
-
if (!sharp) return buffer;
|
|
200
|
-
|
|
201
|
-
const meta = await sharp(buffer).metadata();
|
|
202
|
-
const width = meta.width;
|
|
203
|
-
const height = meta.height;
|
|
204
|
-
|
|
205
|
-
if (width === undefined || height === undefined) return buffer;
|
|
206
|
-
if (width <= MAX_SCREENSHOT_WIDTH && height <= MAX_SCREENSHOT_HEIGHT) return buffer;
|
|
207
|
-
|
|
208
|
-
const resizer = sharp(buffer).resize(MAX_SCREENSHOT_WIDTH, MAX_SCREENSHOT_HEIGHT, {
|
|
209
|
-
fit: "inside",
|
|
210
|
-
withoutEnlargement: true,
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
if (mimeType === "image/png") {
|
|
214
|
-
return Buffer.from(await resizer.png().toBuffer());
|
|
215
|
-
}
|
|
216
|
-
return Buffer.from(await resizer.jpeg({ quality }).toBuffer());
|
|
217
|
-
}
|
|
218
|
-
|
|
219
135
|
/** Capture a JPEG screenshot for error debugging. Returns base64 or null. */
|
|
220
136
|
export async function captureErrorScreenshot(p: Page | null): Promise<{ data: string; mimeType: string } | null> {
|
|
221
137
|
if (!p) return null;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { Page } from "playwright";
|
|
2
|
+
|
|
3
|
+
// sharp is an optional native dependency. Load it lazily so that screenshot
|
|
4
|
+
// emitters still work on platforms where sharp is unavailable (e.g. bunx on
|
|
5
|
+
// Raspberry Pi). constrainScreenshot falls back to returning the raw buffer
|
|
6
|
+
// when sharp is not installed.
|
|
7
|
+
let _sharp: typeof import("sharp") | null | undefined;
|
|
8
|
+
async function getSharp(): Promise<typeof import("sharp") | null> {
|
|
9
|
+
if (_sharp !== undefined) return _sharp;
|
|
10
|
+
try {
|
|
11
|
+
_sharp = (await import("sharp")).default;
|
|
12
|
+
} catch {
|
|
13
|
+
_sharp = null;
|
|
14
|
+
}
|
|
15
|
+
return _sharp;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Test-only seam: override the cached sharp module. Pass `null` to simulate
|
|
20
|
+
* an environment where the sharp native dep is unavailable; pass `undefined`
|
|
21
|
+
* to clear the cache and let the next getSharp() call re-import. See
|
|
22
|
+
* tests/capture-sharp-optional.test.cjs.
|
|
23
|
+
*/
|
|
24
|
+
export function __setSharpForTesting(
|
|
25
|
+
value: typeof import("sharp") | null | undefined,
|
|
26
|
+
): void {
|
|
27
|
+
_sharp = value;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Anthropic vision: 1568px is the recommended optimal width. Height is capped
|
|
31
|
+
// generously at 8000px so tall full-page screenshots remain readable rather
|
|
32
|
+
// than being squished into a square constraint.
|
|
33
|
+
//
|
|
34
|
+
// Override via environment variables:
|
|
35
|
+
// SCREENSHOT_MAX_WIDTH=0 -> uncap width (use raw resolution)
|
|
36
|
+
// SCREENSHOT_MAX_HEIGHT=0 -> uncap height
|
|
37
|
+
export const MAX_SCREENSHOT_WIDTH = parseScreenshotDimension(process.env.SCREENSHOT_MAX_WIDTH, 1568);
|
|
38
|
+
export const MAX_SCREENSHOT_HEIGHT = parseScreenshotDimension(process.env.SCREENSHOT_MAX_HEIGHT, 8000);
|
|
39
|
+
|
|
40
|
+
/** Parse a dimension env var: positive int = that value, 0 = Infinity (uncapped), absent/invalid = default. */
|
|
41
|
+
function parseScreenshotDimension(value: string | undefined, fallback: number): number {
|
|
42
|
+
if (value === undefined || value === "") return fallback;
|
|
43
|
+
const n = parseInt(value, 10);
|
|
44
|
+
if (isNaN(n) || n < 0) return fallback;
|
|
45
|
+
if (n === 0) return Infinity;
|
|
46
|
+
return n;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export async function getScreenshotBufferDimensions(
|
|
50
|
+
buffer: Buffer,
|
|
51
|
+
): Promise<{ width: number; height: number } | null> {
|
|
52
|
+
const sharp = await getSharp();
|
|
53
|
+
if (!sharp) return null;
|
|
54
|
+
|
|
55
|
+
const meta = await sharp(buffer).metadata();
|
|
56
|
+
if (meta.width === undefined || meta.height === undefined) return null;
|
|
57
|
+
return { width: meta.width, height: meta.height };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Constrain screenshot dimensions for the Anthropic vision API.
|
|
62
|
+
* Width is capped at 1568px (optimal) and height at 8000px, each
|
|
63
|
+
* independently, using `fit: "inside"` so aspect ratio is preserved.
|
|
64
|
+
* Small images are never upscaled.
|
|
65
|
+
*
|
|
66
|
+
* `page` parameter is retained for ToolDeps signature stability (D008)
|
|
67
|
+
* but is no longer used — all processing is server-side via sharp.
|
|
68
|
+
*/
|
|
69
|
+
export async function constrainScreenshot(
|
|
70
|
+
_page: Page | null,
|
|
71
|
+
buffer: Buffer,
|
|
72
|
+
mimeType: string,
|
|
73
|
+
quality: number,
|
|
74
|
+
): Promise<Buffer> {
|
|
75
|
+
const sharp = await getSharp();
|
|
76
|
+
if (!sharp) return buffer;
|
|
77
|
+
|
|
78
|
+
const dimensions = await getScreenshotBufferDimensions(buffer);
|
|
79
|
+
const width = dimensions?.width;
|
|
80
|
+
const height = dimensions?.height;
|
|
81
|
+
|
|
82
|
+
if (width === undefined || height === undefined) return buffer;
|
|
83
|
+
if (width <= MAX_SCREENSHOT_WIDTH && height <= MAX_SCREENSHOT_HEIGHT) return buffer;
|
|
84
|
+
|
|
85
|
+
const resizer = sharp(buffer).resize(MAX_SCREENSHOT_WIDTH, MAX_SCREENSHOT_HEIGHT, {
|
|
86
|
+
fit: "inside",
|
|
87
|
+
withoutEnlargement: true,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
if (mimeType === "image/png") {
|
|
91
|
+
return Buffer.from(await resizer.png().toBuffer());
|
|
92
|
+
}
|
|
93
|
+
return Buffer.from(await resizer.jpeg({ quality }).toBuffer());
|
|
94
|
+
}
|
|
@@ -22,6 +22,7 @@ import type {
|
|
|
22
22
|
import type { ExtensionUIContext } from "@gsd/pi-coding-agent";
|
|
23
23
|
import { EventStream } from "@gsd/pi-ai";
|
|
24
24
|
import { execSync } from "node:child_process";
|
|
25
|
+
import { createHash } from "node:crypto";
|
|
25
26
|
import { existsSync, readFileSync } from "node:fs";
|
|
26
27
|
import { homedir } from "node:os";
|
|
27
28
|
import { createRequire } from "node:module";
|
|
@@ -583,6 +584,7 @@ function inferMimeTypeFromDataUri(value: string): string | null {
|
|
|
583
584
|
/** Collect all base64 image blocks from user messages in the context for inclusion in the SDK prompt. */
|
|
584
585
|
export function extractImageBlocksFromContext(context: Context): SDKInputImageBlock[] {
|
|
585
586
|
const imageBlocks: SDKInputImageBlock[] = [];
|
|
587
|
+
const seenImageKeys = new Set<string>();
|
|
586
588
|
|
|
587
589
|
for (const msg of context.messages) {
|
|
588
590
|
if (msg.role !== "user" || !Array.isArray(msg.content)) continue;
|
|
@@ -597,12 +599,17 @@ export function extractImageBlocksFromContext(context: Context): SDKInputImageBl
|
|
|
597
599
|
: inferMimeTypeFromDataUri(block.data);
|
|
598
600
|
if (!mimeType) continue;
|
|
599
601
|
|
|
602
|
+
const data = stripDataUriPrefix(block.data);
|
|
603
|
+
const imageKey = `${mimeType}\0${createHash("sha1").update(data).digest("hex")}`;
|
|
604
|
+
if (seenImageKeys.has(imageKey)) continue;
|
|
605
|
+
seenImageKeys.add(imageKey);
|
|
606
|
+
|
|
600
607
|
imageBlocks.push({
|
|
601
608
|
type: "image",
|
|
602
609
|
source: {
|
|
603
610
|
type: "base64",
|
|
604
611
|
media_type: mimeType,
|
|
605
|
-
data
|
|
612
|
+
data,
|
|
606
613
|
},
|
|
607
614
|
});
|
|
608
615
|
}
|
|
@@ -2252,6 +2259,7 @@ export function streamViaClaudeCode(
|
|
|
2252
2259
|
interface SdkAttemptMessageState {
|
|
2253
2260
|
builder: PartialMessageBuilder | null;
|
|
2254
2261
|
intermediateToolBlocks: AssistantMessage["content"];
|
|
2262
|
+
intermediateTextBlocks: AssistantMessage["content"];
|
|
2255
2263
|
toolResultsById: Map<string, ExternalToolResultPayload>;
|
|
2256
2264
|
toolCompletionTargetsById: Map<string, { partial: AssistantMessage; contentIndex: number }>;
|
|
2257
2265
|
emittedExternalToolResultIds: Set<string>;
|
|
@@ -2261,6 +2269,7 @@ function createSdkAttemptMessageState(): SdkAttemptMessageState {
|
|
|
2261
2269
|
return {
|
|
2262
2270
|
builder: null,
|
|
2263
2271
|
intermediateToolBlocks: [],
|
|
2272
|
+
intermediateTextBlocks: [],
|
|
2264
2273
|
toolResultsById: new Map<string, ExternalToolResultPayload>(),
|
|
2265
2274
|
toolCompletionTargetsById: new Map<string, { partial: AssistantMessage; contentIndex: number }>(),
|
|
2266
2275
|
emittedExternalToolResultIds: new Set<string>(),
|
|
@@ -2402,6 +2411,7 @@ async function pumpSdkMessages(
|
|
|
2402
2411
|
let {
|
|
2403
2412
|
builder,
|
|
2404
2413
|
intermediateToolBlocks,
|
|
2414
|
+
intermediateTextBlocks,
|
|
2405
2415
|
toolResultsById,
|
|
2406
2416
|
toolCompletionTargetsById,
|
|
2407
2417
|
emittedExternalToolResultIds,
|
|
@@ -2542,8 +2552,14 @@ async function pumpSdkMessages(
|
|
|
2542
2552
|
for (const [contentIndex, block] of builder.message.content.entries()) {
|
|
2543
2553
|
if (block.type === "text" && block.text) {
|
|
2544
2554
|
lastTextContent = block.text;
|
|
2555
|
+
// Accumulate completed prose in order — a multi-question
|
|
2556
|
+
// turn commits [prose][elicitation] segments across several
|
|
2557
|
+
// synthetic-user boundaries, and overwriting a single
|
|
2558
|
+
// scalar would drop every explanation but the last.
|
|
2559
|
+
intermediateTextBlocks.push({ type: "text", text: block.text });
|
|
2545
2560
|
} else if (block.type === "thinking" && block.thinking) {
|
|
2546
2561
|
lastThinkingContent = block.thinking;
|
|
2562
|
+
intermediateTextBlocks.push({ type: "thinking", thinking: block.thinking });
|
|
2547
2563
|
} else if (block.type === "toolCall" || block.type === "serverToolUse") {
|
|
2548
2564
|
// Collect tool blocks for externalToolExecution rendering
|
|
2549
2565
|
intermediateToolBlocks.push(block);
|
|
@@ -2641,6 +2657,7 @@ async function pumpSdkMessages(
|
|
|
2641
2657
|
const result = msg as SDKResultMessage;
|
|
2642
2658
|
const finalContent = buildFinalAssistantContent({
|
|
2643
2659
|
intermediateToolBlocks,
|
|
2660
|
+
intermediateTextBlocks,
|
|
2644
2661
|
pendingContent: builder?.message.content,
|
|
2645
2662
|
toolResultsById,
|
|
2646
2663
|
lastThinkingContent,
|
|
@@ -363,6 +363,53 @@ describe("stream-adapter — image prompt forwarding (#4183)", () => {
|
|
|
363
363
|
]);
|
|
364
364
|
});
|
|
365
365
|
|
|
366
|
+
test("extractImageBlocksFromContext deduplicates byte-identical image parts", () => {
|
|
367
|
+
const context: Context = {
|
|
368
|
+
messages: [
|
|
369
|
+
{
|
|
370
|
+
role: "user",
|
|
371
|
+
content: [
|
|
372
|
+
{
|
|
373
|
+
type: "image",
|
|
374
|
+
data: "data:image/png;base64,abc123",
|
|
375
|
+
mimeType: "image/png",
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
type: "image",
|
|
379
|
+
data: "abc123",
|
|
380
|
+
mimeType: "image/png",
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
type: "image",
|
|
384
|
+
data: "def456",
|
|
385
|
+
mimeType: "image/png",
|
|
386
|
+
},
|
|
387
|
+
],
|
|
388
|
+
} as Message,
|
|
389
|
+
],
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
const imageBlocks = extractImageBlocksFromContext(context);
|
|
393
|
+
assert.deepEqual(imageBlocks, [
|
|
394
|
+
{
|
|
395
|
+
type: "image",
|
|
396
|
+
source: {
|
|
397
|
+
type: "base64",
|
|
398
|
+
media_type: "image/png",
|
|
399
|
+
data: "abc123",
|
|
400
|
+
},
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
type: "image",
|
|
404
|
+
source: {
|
|
405
|
+
type: "base64",
|
|
406
|
+
media_type: "image/png",
|
|
407
|
+
data: "def456",
|
|
408
|
+
},
|
|
409
|
+
},
|
|
410
|
+
]);
|
|
411
|
+
});
|
|
412
|
+
|
|
366
413
|
test("buildSdkQueryPrompt returns plain string when no images exist in context", () => {
|
|
367
414
|
const context: Context = {
|
|
368
415
|
messages: [{ role: "user", content: "hello" } as Message],
|
|
@@ -1365,6 +1412,67 @@ describe("stream-adapter — Claude Code external tool results", () => {
|
|
|
1365
1412
|
});
|
|
1366
1413
|
assert.deepEqual(finalContent[1], { type: "text", text: "Read complete." });
|
|
1367
1414
|
});
|
|
1415
|
+
|
|
1416
|
+
test("buildFinalAssistantContent keeps every prose segment across successive elicitation boundaries (#1284)", () => {
|
|
1417
|
+
// A multi-question /gsd discuss turn: [prose A][Q1][prose B][Q2][prose C].
|
|
1418
|
+
// Prose A and B are committed at synthetic-user boundaries (intermediate),
|
|
1419
|
+
// prose C is still in the builder (pending) when `result` arrives.
|
|
1420
|
+
const finalContent = buildFinalAssistantContent({
|
|
1421
|
+
intermediateToolBlocks: [
|
|
1422
|
+
{ type: "toolCall", id: "q1", name: "ask_user_questions", arguments: {} } as any,
|
|
1423
|
+
{ type: "toolCall", id: "q2", name: "ask_user_questions", arguments: {} } as any,
|
|
1424
|
+
],
|
|
1425
|
+
intermediateTextBlocks: [
|
|
1426
|
+
{ type: "text", text: "prose A" },
|
|
1427
|
+
{ type: "text", text: "prose B" },
|
|
1428
|
+
],
|
|
1429
|
+
pendingContent: [{ type: "text", text: "prose C" }],
|
|
1430
|
+
toolResultsById: new Map(),
|
|
1431
|
+
});
|
|
1432
|
+
|
|
1433
|
+
const textBlocks = finalContent.filter((b) => b.type === "text").map((b) => (b as any).text);
|
|
1434
|
+
assert.deepEqual(textBlocks, ["prose A", "prose B", "prose C"]);
|
|
1435
|
+
});
|
|
1436
|
+
|
|
1437
|
+
test("buildFinalAssistantContent does not duplicate the last prose when the turn ends on an elicitation (#1284)", () => {
|
|
1438
|
+
// [prose A][Q1][prose B][Q2] — builder was reset at the final boundary, so
|
|
1439
|
+
// pendingContent is empty and lastTextContent still holds "prose B".
|
|
1440
|
+
const finalContent = buildFinalAssistantContent({
|
|
1441
|
+
intermediateToolBlocks: [
|
|
1442
|
+
{ type: "toolCall", id: "q1", name: "ask_user_questions", arguments: {} } as any,
|
|
1443
|
+
{ type: "toolCall", id: "q2", name: "ask_user_questions", arguments: {} } as any,
|
|
1444
|
+
],
|
|
1445
|
+
intermediateTextBlocks: [
|
|
1446
|
+
{ type: "text", text: "prose A" },
|
|
1447
|
+
{ type: "text", text: "prose B" },
|
|
1448
|
+
],
|
|
1449
|
+
toolResultsById: new Map(),
|
|
1450
|
+
lastTextContent: "prose B",
|
|
1451
|
+
});
|
|
1452
|
+
|
|
1453
|
+
const textBlocks = finalContent.filter((b) => b.type === "text").map((b) => (b as any).text);
|
|
1454
|
+
assert.deepEqual(textBlocks, ["prose A", "prose B"]);
|
|
1455
|
+
});
|
|
1456
|
+
|
|
1457
|
+
test("buildFinalAssistantContent emits scalar fallback prose/thinking not captured in the accumulator", () => {
|
|
1458
|
+
// A non-streaming `assistant` SDK message sets lastText/lastThinkingContent
|
|
1459
|
+
// only (never pushed to intermediateTextBlocks). With pendingContent empty
|
|
1460
|
+
// and intermediate blocks present, the fallback must still be emitted.
|
|
1461
|
+
const finalContent = buildFinalAssistantContent({
|
|
1462
|
+
intermediateToolBlocks: [
|
|
1463
|
+
{ type: "toolCall", id: "q1", name: "ask_user_questions", arguments: {} } as any,
|
|
1464
|
+
],
|
|
1465
|
+
intermediateTextBlocks: [{ type: "text", text: "prose A" }],
|
|
1466
|
+
toolResultsById: new Map(),
|
|
1467
|
+
lastThinkingContent: "final thinking",
|
|
1468
|
+
lastTextContent: "final prose",
|
|
1469
|
+
});
|
|
1470
|
+
|
|
1471
|
+
const textBlocks = finalContent.filter((b) => b.type === "text").map((b) => (b as any).text);
|
|
1472
|
+
const thinkingBlocks = finalContent.filter((b) => b.type === "thinking").map((b) => (b as any).thinking);
|
|
1473
|
+
assert.deepEqual(textBlocks, ["prose A", "final prose"]);
|
|
1474
|
+
assert.deepEqual(thinkingBlocks, ["final thinking"]);
|
|
1475
|
+
});
|
|
1368
1476
|
});
|
|
1369
1477
|
|
|
1370
1478
|
describe("claude-code-cli — Claude Fable 5 Opus-tier support", () => {
|
|
@@ -244,6 +244,7 @@ export function shouldSuppressDuplicateToolUnavailableBlock(
|
|
|
244
244
|
*/
|
|
245
245
|
export function buildFinalAssistantContent(params: {
|
|
246
246
|
intermediateToolBlocks: AssistantMessage["content"];
|
|
247
|
+
intermediateTextBlocks?: AssistantMessage["content"];
|
|
247
248
|
pendingContent?: AssistantMessage["content"];
|
|
248
249
|
toolResultsById: ReadonlyMap<string, ExternalToolResultPayload>;
|
|
249
250
|
lastThinkingContent?: string;
|
|
@@ -259,6 +260,15 @@ export function buildFinalAssistantContent(params: {
|
|
|
259
260
|
const finalContent: AssistantMessage["content"] = mergedToolBlocks.filter(
|
|
260
261
|
(block) => !shouldSuppressDuplicateToolUnavailableBlock(block, mergedToolBlocks),
|
|
261
262
|
);
|
|
263
|
+
// Emit prose/thinking captured at earlier turn-boundaries (each successive
|
|
264
|
+
// `ask_user_questions` elicitation completes a turn) before the final
|
|
265
|
+
// segment. Capturing these in an ordered accumulator — symmetric with
|
|
266
|
+
// `intermediateToolBlocks` — is what keeps intermediate explanations from
|
|
267
|
+
// being collapsed to a single overwritten scalar and silently dropped.
|
|
268
|
+
const intermediateTextBlocks = params.intermediateTextBlocks ?? [];
|
|
269
|
+
for (const block of intermediateTextBlocks) {
|
|
270
|
+
finalContent.push(block);
|
|
271
|
+
}
|
|
262
272
|
if (params.pendingContent && params.pendingContent.length > 0) {
|
|
263
273
|
for (const block of params.pendingContent) {
|
|
264
274
|
if (block.type === "text" || block.type === "thinking") {
|
|
@@ -266,11 +276,29 @@ export function buildFinalAssistantContent(params: {
|
|
|
266
276
|
}
|
|
267
277
|
}
|
|
268
278
|
} else {
|
|
279
|
+
// No builder content survived to this turn boundary, so fall back to the
|
|
280
|
+
// last scalar thinking/text captured off the stream. When the turn ends
|
|
281
|
+
// on an elicitation these scalars just mirror the final intermediate
|
|
282
|
+
// block (they are overwritten at each synthetic-user boundary), so only
|
|
283
|
+
// emit them when they carry content not already accumulated — otherwise
|
|
284
|
+
// a non-streaming `assistant` message's prose/thinking is silently lost.
|
|
285
|
+
const lastBlockOfType = (type: "text" | "thinking") => {
|
|
286
|
+
for (let i = intermediateTextBlocks.length - 1; i >= 0; i--) {
|
|
287
|
+
if (intermediateTextBlocks[i].type === type) return intermediateTextBlocks[i];
|
|
288
|
+
}
|
|
289
|
+
return undefined;
|
|
290
|
+
};
|
|
269
291
|
if (params.lastThinkingContent) {
|
|
270
|
-
|
|
292
|
+
const lastThinking = lastBlockOfType("thinking") as { thinking?: string } | undefined;
|
|
293
|
+
if (lastThinking?.thinking !== params.lastThinkingContent) {
|
|
294
|
+
finalContent.push({ type: "thinking", thinking: params.lastThinkingContent });
|
|
295
|
+
}
|
|
271
296
|
}
|
|
272
297
|
if (params.lastTextContent) {
|
|
273
|
-
|
|
298
|
+
const lastText = lastBlockOfType("text") as { text?: string } | undefined;
|
|
299
|
+
if (lastText?.text !== params.lastTextContent) {
|
|
300
|
+
finalContent.push({ type: "text", text: params.lastTextContent });
|
|
301
|
+
}
|
|
274
302
|
}
|
|
275
303
|
}
|
|
276
304
|
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
resolveSliceFile,
|
|
23
23
|
resolveTasksDir,
|
|
24
24
|
resolveTaskFiles,
|
|
25
|
+
resolveTaskFile,
|
|
25
26
|
relSliceFile,
|
|
26
27
|
resolveMilestoneFile,
|
|
27
28
|
clearPathCache,
|
|
@@ -223,15 +224,9 @@ export function verifyExpectedArtifact(
|
|
|
223
224
|
const batchIds = batchPart.slice(plusIdx + 1).split(",").filter(Boolean);
|
|
224
225
|
if (batchIds.length === 0) return false;
|
|
225
226
|
|
|
226
|
-
const tDir = resolveTasksDir(base, mid, sid) ?? slicePath;
|
|
227
|
-
const existingSummaries = new Set(
|
|
228
|
-
resolveTaskFiles(tDir, "SUMMARY").map((f) =>
|
|
229
|
-
f.replace(/-SUMMARY\.md$/i, "").toUpperCase(),
|
|
230
|
-
),
|
|
231
|
-
);
|
|
232
|
-
|
|
233
227
|
for (const tid of batchIds) {
|
|
234
|
-
|
|
228
|
+
const summaryPath = resolveTaskFile(base, mid, sid, tid, "SUMMARY");
|
|
229
|
+
if (!summaryPath || !existsSync(summaryPath)) return false;
|
|
235
230
|
}
|
|
236
231
|
return true;
|
|
237
232
|
}
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
resolveSliceFile,
|
|
16
16
|
relMilestoneFile,
|
|
17
17
|
relSliceFile,
|
|
18
|
+
buildFlatTaskFileName,
|
|
18
19
|
buildTaskFileName,
|
|
19
20
|
resolveSlicePath,
|
|
20
21
|
resolveTasksDir,
|
|
@@ -103,12 +104,15 @@ function resolveProjectMilestonePath(base: string, mid: string): string | null {
|
|
|
103
104
|
const milestonesDir = join(gsdRoot(base), "milestones");
|
|
104
105
|
const dir = resolveDir(milestonesDir, mid);
|
|
105
106
|
if (!dir) return null;
|
|
106
|
-
// git-service.ts
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
107
|
+
// Historically git-service.ts wrote integration-branch metadata into
|
|
108
|
+
// milestones/<MID>/<MID>-META.json, which could create that dir in flat-phase
|
|
109
|
+
// projects and poison layout detection. As of ADR-045 that META lives flat at
|
|
110
|
+
// .gsd/<MID>-META.json and no longer poisons detection. A dir that holds ONLY
|
|
111
|
+
// *-META.json files (a pre-migration on-disk tree) must still not be treated
|
|
112
|
+
// as a real legacy milestone dir — otherwise this early-return resolves
|
|
113
|
+
// CONTEXT/ROADMAP/SUMMARY to the legacy path (milestones/<MID>/<MID>-<SUFFIX>.md)
|
|
114
|
+
// before the flat-phase fallback can run, trapping the unit in a
|
|
115
|
+
// finalize-retry loop (#852 follow-up).
|
|
112
116
|
//
|
|
113
117
|
// We use dirIsMetaOnlyLegacyMilestone rather than !dirIsContentBearingLegacyMilestone
|
|
114
118
|
// so that an EMPTY dir (a new milestone before any content is written) is NOT
|
|
@@ -232,7 +236,10 @@ export function resolveExpectedArtifactPath(
|
|
|
232
236
|
const summaryDir = isLegacySlice
|
|
233
237
|
? (resolveTasksDir(base, mid, sid!) ?? slicePath)
|
|
234
238
|
: slicePath;
|
|
235
|
-
|
|
239
|
+
const fileName = isLegacySlice
|
|
240
|
+
? buildTaskFileName(tid, "SUMMARY")
|
|
241
|
+
: buildFlatTaskFileName(sid!, tid, "SUMMARY");
|
|
242
|
+
return join(summaryDir, fileName);
|
|
236
243
|
}
|
|
237
244
|
case "complete-slice": {
|
|
238
245
|
return resolveSliceArtifactPath(base, mid, sid!, "SUMMARY");
|
|
@@ -297,9 +304,9 @@ export function diagnoseExpectedArtifact(
|
|
|
297
304
|
}
|
|
298
305
|
return `${relSliceFile(base, mid, sid!, "RESEARCH")} (slice research)`;
|
|
299
306
|
case "plan-slice":
|
|
300
|
-
return `${relSliceFile(base, mid, sid!, "PLAN")}
|
|
307
|
+
return `${relSliceFile(base, mid, sid!, "PLAN")} with embedded task plans`;
|
|
301
308
|
case "refine-slice":
|
|
302
|
-
return `${relSliceFile(base, mid, sid!, "PLAN")}
|
|
309
|
+
return `${relSliceFile(base, mid, sid!, "PLAN")} with embedded refined task plans`;
|
|
303
310
|
case "execute-task": {
|
|
304
311
|
return `Task ${tid} marked [x] in ${relSliceFile(base, mid, sid!, "PLAN")} + summary written`;
|
|
305
312
|
}
|