@opengsd/gsd-pi 1.6.0 → 1.7.0-dev.30c4ec2f
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 +6 -10
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/gsd/auto-post-unit.js +19 -3
- package/dist/resources/extensions/gsd/auto-prompts.js +20 -0
- package/dist/resources/extensions/gsd/auto.js +12 -0
- package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +68 -2
- package/dist/resources/extensions/gsd/doctor-history.js +65 -0
- package/dist/resources/extensions/gsd/doctor-state-checks.js +509 -0
- package/dist/resources/extensions/gsd/doctor-workspace-checks.js +91 -0
- package/dist/resources/extensions/gsd/doctor.js +14 -653
- package/dist/resources/extensions/gsd/md-importer.js +7 -2
- package/dist/resources/extensions/gsd/migrate/planning-writer.js +8 -2
- package/dist/resources/extensions/gsd/migration-auto-check.js +4 -0
- package/dist/resources/extensions/gsd/reopen-reason.js +98 -0
- package/dist/resources/extensions/gsd/session-status-io.js +31 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +54 -14
- package/dist/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.js +48 -5
- package/dist/resources/extensions/gsd/tools/reopen-task.js +15 -0
- package/dist/resources/extensions/shared/gsd-browser-cli.js +22 -5
- 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 +10 -10
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/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 +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
- package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
- package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
- 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/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/server.js +1 -1
- package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
- package/integrations/hermes/pyproject.toml +1 -1
- package/package.json +6 -6
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/dist/cloud-cli.d.ts +1 -1
- package/packages/daemon/dist/cloud-cli.d.ts.map +1 -1
- package/packages/daemon/dist/cloud-cli.js +42 -2
- package/packages/daemon/dist/cloud-cli.js.map +1 -1
- package/packages/daemon/dist/cloud-config.d.ts +1 -0
- package/packages/daemon/dist/cloud-config.d.ts.map +1 -1
- package/packages/daemon/dist/cloud-config.js +26 -8
- package/packages/daemon/dist/cloud-config.js.map +1 -1
- package/packages/daemon/dist/cloud-config.test.js +19 -1
- package/packages/daemon/dist/cloud-config.test.js.map +1 -1
- package/packages/daemon/dist/device-flow.d.ts +24 -0
- package/packages/daemon/dist/device-flow.d.ts.map +1 -0
- package/packages/daemon/dist/device-flow.js +128 -0
- package/packages/daemon/dist/device-flow.js.map +1 -0
- package/packages/daemon/dist/device-flow.test.d.ts +2 -0
- package/packages/daemon/dist/device-flow.test.d.ts.map +1 -0
- package/packages/daemon/dist/device-flow.test.js +172 -0
- package/packages/daemon/dist/device-flow.test.js.map +1 -0
- package/packages/daemon/package.json +5 -5
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/gsd-cloud/README.md +48 -0
- package/packages/gsd-cloud/bin/gsd-cloud.js +28 -0
- package/packages/gsd-cloud/package.json +40 -0
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/package.json +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/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +19 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +22 -3
- package/src/resources/extensions/gsd/auto-prompts.ts +20 -0
- package/src/resources/extensions/gsd/auto.ts +12 -0
- package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +77 -1
- package/src/resources/extensions/gsd/doctor-history.ts +81 -0
- package/src/resources/extensions/gsd/doctor-state-checks.ts +527 -0
- package/src/resources/extensions/gsd/doctor-workspace-checks.ts +97 -0
- package/src/resources/extensions/gsd/doctor.ts +14 -673
- package/src/resources/extensions/gsd/md-importer.ts +7 -2
- package/src/resources/extensions/gsd/migrate/planning-writer.ts +9 -3
- package/src/resources/extensions/gsd/migration-auto-check.ts +3 -0
- package/src/resources/extensions/gsd/reopen-reason.ts +109 -0
- package/src/resources/extensions/gsd/session-status-io.ts +34 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +67 -20
- package/src/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.ts +47 -5
- package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +76 -1
- package/src/resources/extensions/gsd/tests/doctor-history-public-api.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/planning-writer.test.ts +18 -1
- package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +18 -3
- package/src/resources/extensions/gsd/tests/reopen-reason.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +177 -25
- package/src/resources/extensions/gsd/tests/worker-resume-wait.test.ts +73 -0
- package/src/resources/extensions/gsd/tools/reopen-task.ts +15 -0
- package/src/resources/extensions/shared/gsd-browser-cli.ts +35 -7
- 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/{6xYMOzxVhsQgryneJ5KRc → ue2JDvA1wboxPBPeblD5N}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{6xYMOzxVhsQgryneJ5KRc → ue2JDvA1wboxPBPeblD5N}/_ssgManifest.js +0 -0
package/README.md
CHANGED
|
@@ -28,16 +28,12 @@ See [CHANGELOG.md](./CHANGELOG.md) for release-by-release fixes and [Legacy Rele
|
|
|
28
28
|
## Latest Release Highlights
|
|
29
29
|
|
|
30
30
|
<!-- release-highlights:start -->
|
|
31
|
-
Latest release: **v1.
|
|
32
|
-
|
|
33
|
-
- **
|
|
34
|
-
- **
|
|
35
|
-
- **
|
|
36
|
-
- **
|
|
37
|
-
- **uok:** Scope audit degradation to kernel workspace.
|
|
38
|
-
- **browser-tools:** Abort pending daemon starts on close.
|
|
39
|
-
- **browser-tools:** Guard managed daemon connection lifecycle.
|
|
40
|
-
- **worktree:** Centralize changed scan.
|
|
31
|
+
Latest release: **v1.7.0**
|
|
32
|
+
|
|
33
|
+
- **cloud:** Add device-flow login to daemon + @opengsd/gsd-cloud agent (#1278).
|
|
34
|
+
- **issue:** [Bug]: Unattended `gsd headless auto` has no resumer for the parallel/slice_parallel worker pause signal → terminal exit 10 after the first unit.
|
|
35
|
+
- **issue:** Complete-slice's reopen reason never reaches the re-dispatched execute-task (follow-up to #1225).
|
|
36
|
+
- **issue:** [Feature Request]: gsd-browser daemon has no automatic teardown — orphaned Chrome process survives session/task completion.
|
|
41
37
|
|
|
42
38
|
<!-- release-highlights:end -->
|
|
43
39
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
f38cd5787a6340c5
|
|
@@ -31,7 +31,7 @@ import { normalizeWorktreePathForCompare } from "./worktree-root.js";
|
|
|
31
31
|
import { isDbAvailable, getTask, getSlice, getMilestone, getMilestoneSlices, updateTaskStatus, _getAdapter, getVerificationEvidence } from "./gsd-db.js";
|
|
32
32
|
import { getWorkflowDatabasePath, refreshWorkflowDatabaseFromDisk } from "./db-workspace.js";
|
|
33
33
|
import { renderPlanCheckboxes, renderRoadmapFromDb, roadmapRenderMarksSliceDone } from "./markdown-renderer.js";
|
|
34
|
-
import { consumeSignal } from "./session-status-io.js";
|
|
34
|
+
import { awaitWorkerResume, consumeSignal } from "./session-status-io.js";
|
|
35
35
|
import { checkPostUnitHooks, consumeHookFailure, isRetryPending, consumeRetryTrigger, consumeGateBlock, persistHookState, resolveHookArtifactPath, } from "./post-unit-hooks.js";
|
|
36
36
|
import { hasPendingCaptures, loadPendingCaptures, revertExecutorResolvedCaptures } from "./captures.js";
|
|
37
37
|
import { debugLog } from "./debug-logger.js";
|
|
@@ -1051,8 +1051,24 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
1051
1051
|
return "dispatched";
|
|
1052
1052
|
}
|
|
1053
1053
|
if (signal.signal === "pause") {
|
|
1054
|
-
|
|
1055
|
-
|
|
1054
|
+
// A worker `pause` is a *temporary* coordination request: the docs
|
|
1055
|
+
// contract (docs/user-docs/parallel-orchestration.md) is "finish current
|
|
1056
|
+
// unit, wait" followed by a matching `resume`. Only the interactive
|
|
1057
|
+
// dashboard runtime owns a resumer — unattended `gsd headless auto` does
|
|
1058
|
+
// not — so a terminal pauseAuto() here strands the worker at exit 10
|
|
1059
|
+
// (BLOCKED) after its first unit, with nothing able to lift it (#1273).
|
|
1060
|
+
// Wait for the coordinator to resume (or stop) us instead. If no resumer
|
|
1061
|
+
// lifts the pause within the window, degrade to in-process serialization
|
|
1062
|
+
// and continue the dispatch loop rather than halting the run forever.
|
|
1063
|
+
const resumeOutcome = await awaitWorkerResume(s.basePath, milestoneLock);
|
|
1064
|
+
if (resumeOutcome === "stop") {
|
|
1065
|
+
await stopAuto(ctx, pi);
|
|
1066
|
+
return "dispatched";
|
|
1067
|
+
}
|
|
1068
|
+
if (resumeOutcome === "timeout") {
|
|
1069
|
+
logWarning("parallel", `pause signal for ${milestoneLock} was not resumed (no headless resumer, #1273); continuing dispatch`);
|
|
1070
|
+
}
|
|
1071
|
+
// "resume" or "timeout": fall through and continue post-unit processing.
|
|
1056
1072
|
}
|
|
1057
1073
|
}
|
|
1058
1074
|
}
|
|
@@ -2299,6 +2299,26 @@ export async function buildExecuteTaskPrompt(mid, sid, sTitle, tid, tTitle, base
|
|
|
2299
2299
|
trackPromptContext(contextTelemetry, "runtime", runtimeContext ? "inline" : "skipped", runtimeContext, runtimeContext ? undefined : "missing");
|
|
2300
2300
|
let phaseAnchorSection = planAnchor ? formatAnchorForPrompt(planAnchor) : "";
|
|
2301
2301
|
trackPromptContext(contextTelemetry, "plan-anchor", phaseAnchorSection ? "inline" : "skipped", phaseAnchorSection, phaseAnchorSection ? undefined : "missing");
|
|
2302
|
+
// #1272: inject a pending reopen reason into this task's prompt. When a gate
|
|
2303
|
+
// (e.g. complete-slice's full-suite run) reopened the task via gsd_task_reopen
|
|
2304
|
+
// with a diagnosis, surface it here so the re-dispatched executor fixes the
|
|
2305
|
+
// regression instead of re-running the original (green) scoped verify. Claim
|
|
2306
|
+
// is one-shot (artifact deleted on read). Not feature-gated — a reopened task
|
|
2307
|
+
// must always know why. Prepended so it sits above the plan anchor.
|
|
2308
|
+
try {
|
|
2309
|
+
const { claimReopenReasonForInjection } = await import("./reopen-reason.js");
|
|
2310
|
+
const reopenClaimed = claimReopenReasonForInjection(base, mid, sid, tid);
|
|
2311
|
+
if (reopenClaimed) {
|
|
2312
|
+
const block = reopenClaimed.injectionBlock + "\n\n---\n\n";
|
|
2313
|
+
phaseAnchorSection = phaseAnchorSection
|
|
2314
|
+
? `${block}${phaseAnchorSection}`
|
|
2315
|
+
: block;
|
|
2316
|
+
trackPromptContext(contextTelemetry, "reopen-reason", "inline", reopenClaimed.injectionBlock);
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
catch (reopenErr) {
|
|
2320
|
+
logWarning("prompt", `reopen reason injection failed: ${reopenErr.message}`);
|
|
2321
|
+
}
|
|
2302
2322
|
// ADR-011 Phase 2: inject any resolved-but-unapplied escalation override
|
|
2303
2323
|
// into this task's prompt. Claim is atomic via DB UPDATE WHERE IS NULL, so
|
|
2304
2324
|
// if a parallel build already injected it, we skip. Feature-gated by
|
|
@@ -58,6 +58,7 @@ import { isInAutoWorktree } from "./auto-worktree-entry.js";
|
|
|
58
58
|
import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
|
|
59
59
|
import { checkResourcesStale } from "./auto-worktree-resource-version.js";
|
|
60
60
|
import { escapeStaleWorktree } from "./auto-worktree-runtime-cleanup.js";
|
|
61
|
+
import { teardownWarmedBrowserDaemons } from "./browser-daemon-auto-prep.js";
|
|
61
62
|
import { teardownAutoWorktree } from "./auto-worktree-teardown.js";
|
|
62
63
|
import { pruneQueueOrder } from "./queue-order.js";
|
|
63
64
|
import { startCommandPolling as _startCommandPolling, isRemoteConfigured } from "../remote-questions/manager.js";
|
|
@@ -1003,6 +1004,17 @@ export async function cleanupAfterLoopExit(ctx) {
|
|
|
1003
1004
|
/* best-effort — mirror stopAuto cleanup */
|
|
1004
1005
|
logWarning("session", `lock cleanup failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
1005
1006
|
}
|
|
1007
|
+
// Symmetric teardown for the browser-UAT warm-up preflight (#1259): stop any
|
|
1008
|
+
// gsd-browser daemon this session started so the Chrome process does not
|
|
1009
|
+
// linger after the loop exits. Re-warms on the next browser-backed run-uat.
|
|
1010
|
+
try {
|
|
1011
|
+
for (const { projectRoot, error } of teardownWarmedBrowserDaemons()) {
|
|
1012
|
+
logWarning("session", `gsd-browser daemon stop failed for ${projectRoot}: ${error}`, { file: "auto.ts" });
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
catch (err) {
|
|
1016
|
+
logWarning("session", `browser daemon teardown failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
1017
|
+
}
|
|
1006
1018
|
// A transient provider-error pause intentionally leaves the paused badge
|
|
1007
1019
|
// visible so the user still has a resumable auto-mode signal on screen.
|
|
1008
1020
|
if (!s.paused) {
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { execFileSync } from "node:child_process";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { resolveAmbientBrowserEngineResolution, resolveBrowserEngineResolution, } from "../browser-tools/engine/selection.js";
|
|
4
|
-
import { resolveGsdBrowserCliAvailability, resolveGsdBrowserDaemonStartInvocation, } from "../shared/gsd-browser-cli.js";
|
|
4
|
+
import { resolveGsdBrowserCliAvailability, resolveGsdBrowserDaemonStartInvocation, resolveGsdBrowserDaemonStopInvocation, } from "../shared/gsd-browser-cli.js";
|
|
5
5
|
import { uatTypeIncludesBrowser } from "./uat-policy.js";
|
|
6
6
|
const DEFAULT_DAEMON_START_TIMEOUT_MS = 30_000;
|
|
7
|
+
const DEFAULT_DAEMON_STOP_TIMEOUT_MS = 15_000;
|
|
8
|
+
/**
|
|
9
|
+
* Project roots whose gsd-browser daemon this process warmed via
|
|
10
|
+
* {@link prepareBrowserDaemonForUat}. Teardown only stops daemons we actually
|
|
11
|
+
* started, so non-browser auto-mode sessions never spawn a stray `daemon stop`.
|
|
12
|
+
*/
|
|
13
|
+
const warmedDaemonProjectRoots = new Set();
|
|
7
14
|
function isEnvDisabled(value) {
|
|
8
15
|
if (!value)
|
|
9
16
|
return false;
|
|
@@ -77,7 +84,66 @@ export function prepareBrowserDaemonForUat(ctx) {
|
|
|
77
84
|
if (!shouldWarmBrowserDaemonForUat(ctx))
|
|
78
85
|
return null;
|
|
79
86
|
const result = ensureBrowserDaemonStarted(ctx.projectRoot, { env: ctx.env });
|
|
80
|
-
if (result.ok)
|
|
87
|
+
if (result.ok) {
|
|
88
|
+
warmedDaemonProjectRoots.add(resolve(ctx.projectRoot));
|
|
81
89
|
return null;
|
|
90
|
+
}
|
|
82
91
|
return `Cannot dispatch browser-backed run-uat: gsd-browser daemon failed to start (${result.error}). Ensure Chrome/Chromium is installed, run \`gsd-browser daemon health\` with the project session flags from .mcp.json, or set GSD_BROWSER_PATH to a Chromium binary.`;
|
|
83
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Best-effort stop of a gsd-browser session daemon warmed for browser UAT.
|
|
95
|
+
* Mirrors {@link ensureBrowserDaemonStarted}; returns the failure detail rather
|
|
96
|
+
* than throwing so teardown can stay non-fatal.
|
|
97
|
+
*/
|
|
98
|
+
export function stopBrowserDaemon(projectRoot, options = {}) {
|
|
99
|
+
const env = options.env ?? process.env;
|
|
100
|
+
const availability = resolveGsdBrowserCliAvailability(env);
|
|
101
|
+
if (!availability.available) {
|
|
102
|
+
return { ok: false, error: availability.detail };
|
|
103
|
+
}
|
|
104
|
+
let invocation;
|
|
105
|
+
try {
|
|
106
|
+
invocation = resolveGsdBrowserDaemonStopInvocation(projectRoot, env);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
return {
|
|
110
|
+
ok: false,
|
|
111
|
+
error: error instanceof Error ? error.message : String(error),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
execFileSync(invocation.command, invocation.args, {
|
|
116
|
+
cwd: invocation.cwd,
|
|
117
|
+
env: { ...process.env, ...env, ...(invocation.env ?? {}) },
|
|
118
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
119
|
+
timeout: options.timeoutMs ?? DEFAULT_DAEMON_STOP_TIMEOUT_MS,
|
|
120
|
+
encoding: "utf-8",
|
|
121
|
+
});
|
|
122
|
+
return { ok: true };
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
return {
|
|
126
|
+
ok: false,
|
|
127
|
+
error: error instanceof Error ? error.message : String(error),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Tear down every gsd-browser daemon this process warmed for browser UAT,
|
|
133
|
+
* clearing the tracked set. Called on auto-mode loop exit so the Chrome process
|
|
134
|
+
* does not survive session/task completion (mirrors the warm-up preflight).
|
|
135
|
+
* Best-effort: returns the project roots whose stop failed for logging.
|
|
136
|
+
*/
|
|
137
|
+
export function teardownWarmedBrowserDaemons(options = {}) {
|
|
138
|
+
if (warmedDaemonProjectRoots.size === 0)
|
|
139
|
+
return [];
|
|
140
|
+
const failures = [];
|
|
141
|
+
for (const projectRoot of warmedDaemonProjectRoots) {
|
|
142
|
+
const result = stopBrowserDaemon(projectRoot, { env: options.env });
|
|
143
|
+
if (!result.ok) {
|
|
144
|
+
failures.push({ projectRoot, error: result.error });
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
warmedDaemonProjectRoots.clear();
|
|
148
|
+
return failures;
|
|
149
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { saveFile } from "./files.js";
|
|
4
|
+
import { gsdRoot } from "./paths.js";
|
|
5
|
+
function buildDoctorHistorySummary(report, errorCount, warningCount, issueDetails) {
|
|
6
|
+
const summaryParts = [];
|
|
7
|
+
if (report.ok) {
|
|
8
|
+
summaryParts.push("Clean");
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
const counts = [];
|
|
12
|
+
if (errorCount > 0)
|
|
13
|
+
counts.push(`${errorCount} error${errorCount > 1 ? "s" : ""}`);
|
|
14
|
+
if (warningCount > 0)
|
|
15
|
+
counts.push(`${warningCount} warning${warningCount > 1 ? "s" : ""}`);
|
|
16
|
+
summaryParts.push(counts.join(", "));
|
|
17
|
+
}
|
|
18
|
+
if (report.fixesApplied.length > 0) {
|
|
19
|
+
summaryParts.push(`${report.fixesApplied.length} fixed`);
|
|
20
|
+
}
|
|
21
|
+
if (issueDetails && issueDetails.length > 0) {
|
|
22
|
+
const topIssue = issueDetails.find(i => i.severity === "error") ?? issueDetails[0];
|
|
23
|
+
summaryParts.push(topIssue.message);
|
|
24
|
+
}
|
|
25
|
+
return summaryParts.join(" · ");
|
|
26
|
+
}
|
|
27
|
+
export async function appendDoctorHistory(basePath, report) {
|
|
28
|
+
try {
|
|
29
|
+
const historyPath = join(gsdRoot(basePath), "doctor-history.jsonl");
|
|
30
|
+
const errorCount = report.issues.filter(i => i.severity === "error").length;
|
|
31
|
+
const warningCount = report.issues.filter(i => i.severity === "warning").length;
|
|
32
|
+
const issueDetails = report.issues
|
|
33
|
+
.filter(i => i.severity === "error" || i.severity === "warning")
|
|
34
|
+
.slice(0, 10) // cap to keep JSONL lines bounded
|
|
35
|
+
.map(i => ({ severity: i.severity, code: i.code, message: i.message, unitId: i.unitId }));
|
|
36
|
+
const entry = JSON.stringify({
|
|
37
|
+
ts: new Date().toISOString(),
|
|
38
|
+
ok: report.ok,
|
|
39
|
+
errors: errorCount,
|
|
40
|
+
warnings: warningCount,
|
|
41
|
+
fixes: report.fixesApplied.length,
|
|
42
|
+
codes: [...new Set(report.issues.map(i => i.code))],
|
|
43
|
+
issues: issueDetails.length > 0 ? issueDetails : undefined,
|
|
44
|
+
fixDescriptions: report.fixesApplied.length > 0 ? report.fixesApplied : undefined,
|
|
45
|
+
scope: report.scope,
|
|
46
|
+
summary: buildDoctorHistorySummary(report, errorCount, warningCount, issueDetails),
|
|
47
|
+
});
|
|
48
|
+
const existing = existsSync(historyPath) ? readFileSync(historyPath, "utf-8") : "";
|
|
49
|
+
await saveFile(historyPath, existing + entry + "\n");
|
|
50
|
+
}
|
|
51
|
+
catch { /* non-fatal */ }
|
|
52
|
+
}
|
|
53
|
+
/** Read the last N doctor history entries. Returns most-recent-first. */
|
|
54
|
+
export async function readDoctorHistory(basePath, lastN = 50) {
|
|
55
|
+
try {
|
|
56
|
+
const historyPath = join(gsdRoot(basePath), "doctor-history.jsonl");
|
|
57
|
+
if (!existsSync(historyPath))
|
|
58
|
+
return [];
|
|
59
|
+
const lines = readFileSync(historyPath, "utf-8").split("\n").filter(l => l.trim());
|
|
60
|
+
return lines.slice(-lastN).reverse().map(l => JSON.parse(l));
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
}
|