gsd-pi 2.52.0 → 2.53.0-dev.a67436f
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 +55 -32
- package/dist/headless-query.js +1 -1
- package/dist/headless-ui.d.ts +2 -2
- package/dist/headless-ui.js +18 -15
- package/dist/headless.d.ts +11 -0
- package/dist/headless.js +178 -38
- package/dist/resources/extensions/get-secrets-from-user.js +7 -0
- package/dist/resources/extensions/gsd/auto/phases.js +28 -8
- package/dist/resources/extensions/gsd/auto-dispatch.js +5 -1
- package/dist/resources/extensions/gsd/auto-worktree.js +70 -14
- package/dist/resources/extensions/gsd/auto.js +22 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +4 -10
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +3 -3
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +2 -2
- package/dist/resources/extensions/gsd/git-service.js +4 -3
- package/dist/resources/extensions/gsd/guided-flow.js +4 -3
- package/dist/resources/extensions/gsd/markdown-renderer.js +5 -4
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +18 -2
- package/dist/resources/extensions/gsd/preferences-types.js +1 -1
- package/dist/resources/extensions/gsd/state.js +18 -29
- package/dist/resources/extensions/gsd/status-guards.js +12 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +4 -3
- package/dist/resources/extensions/gsd/tools/complete-slice.js +4 -3
- package/dist/resources/extensions/gsd/tools/complete-task.js +4 -3
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +4 -14
- package/dist/resources/extensions/gsd/tools/plan-slice.js +4 -14
- package/dist/resources/extensions/gsd/tools/plan-task.js +4 -14
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +6 -7
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +4 -3
- package/dist/resources/extensions/gsd/tools/reopen-task.js +5 -4
- package/dist/resources/extensions/gsd/tools/replan-slice.js +5 -6
- package/dist/resources/extensions/gsd/validation.js +21 -0
- package/dist/resources/extensions/shared/rtk.js +14 -4
- package/dist/rtk.js +3 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +20 -20
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/required-server-files.json +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 +2 -2
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +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/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 +2 -2
- 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 +2 -2
- 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 +20 -20
- package/dist/web/standalone/.next/server/chunks/2229.js +1 -1
- package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/4024.87fd909ae0110f50.js +9 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-b950e4e384cc62b3.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-024d82be84800e52.js → webpack-bca0e732db0dcec3.js} +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/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/packages/mcp-server/README.md +6 -6
- package/packages/mcp-server/package.json +14 -4
- package/packages/mcp-server/src/cli.ts +1 -1
- package/packages/mcp-server/src/index.ts +1 -1
- package/packages/mcp-server/src/mcp-server.test.ts +2 -2
- package/packages/mcp-server/src/session-manager.ts +2 -2
- package/packages/mcp-server/src/types.ts +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/rpc-client/README.md +125 -0
- package/packages/rpc-client/examples/basic-usage.ts +13 -0
- package/packages/rpc-client/package.json +17 -3
- package/packages/rpc-client/src/index.ts +10 -0
- package/packages/rpc-client/src/jsonl.ts +64 -0
- package/packages/rpc-client/src/rpc-client.test.ts +568 -0
- package/packages/rpc-client/src/rpc-client.ts +666 -0
- package/packages/rpc-client/src/rpc-types.ts +399 -0
- package/packages/rpc-client/tsconfig.examples.json +17 -0
- package/packages/rpc-client/tsconfig.json +24 -0
- package/pkg/package.json +1 -1
- package/scripts/ensure-workspace-builds.cjs +36 -8
- package/src/resources/extensions/get-secrets-from-user.ts +8 -0
- package/src/resources/extensions/gsd/auto/phases.ts +38 -7
- package/src/resources/extensions/gsd/auto-dispatch.ts +6 -1
- package/src/resources/extensions/gsd/auto-worktree.ts +73 -14
- package/src/resources/extensions/gsd/auto.ts +21 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +4 -11
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +3 -3
- package/src/resources/extensions/gsd/docs/preferences-reference.md +2 -2
- package/src/resources/extensions/gsd/git-service.ts +4 -3
- package/src/resources/extensions/gsd/guided-flow.ts +4 -3
- package/src/resources/extensions/gsd/markdown-renderer.ts +5 -4
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +23 -1
- package/src/resources/extensions/gsd/preferences-types.ts +1 -1
- package/src/resources/extensions/gsd/state.ts +18 -29
- package/src/resources/extensions/gsd/status-guards.ts +13 -0
- package/src/resources/extensions/gsd/tests/active-milestone-id-guard.test.ts +91 -0
- package/src/resources/extensions/gsd/tests/auto-stale-lock-self-kill.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +80 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/git-service.test.ts +64 -30
- package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +277 -0
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/rate-limit-model-fallback.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/session-lock-transient-read.test.ts +9 -8
- package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +125 -0
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/validation-gate-patterns.test.ts +124 -0
- package/src/resources/extensions/gsd/tests/validation.test.ts +72 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +4 -3
- package/src/resources/extensions/gsd/tools/complete-slice.ts +4 -3
- package/src/resources/extensions/gsd/tools/complete-task.ts +4 -3
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +4 -16
- package/src/resources/extensions/gsd/tools/plan-slice.ts +4 -16
- package/src/resources/extensions/gsd/tools/plan-task.ts +4 -16
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +6 -7
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +4 -3
- package/src/resources/extensions/gsd/tools/reopen-task.ts +5 -4
- package/src/resources/extensions/gsd/tools/replan-slice.ts +5 -7
- package/src/resources/extensions/gsd/validation.ts +23 -0
- package/src/resources/extensions/shared/rtk.ts +22 -4
- package/dist/web/standalone/.next/static/chunks/4024.21054f459af5cc78.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/page-fbecd1237e2d6d1f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- /package/dist/web/standalone/.next/static/{vlgS2rkXjxeKhgXhdp4lh → YO-PWFRitlHM-L-dotlmm}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{vlgS2rkXjxeKhgXhdp4lh → YO-PWFRitlHM-L-dotlmm}/_ssgManifest.js +0 -0
|
@@ -9,6 +9,7 @@ import { join } from "node:path";
|
|
|
9
9
|
import { mkdirSync } from "node:fs";
|
|
10
10
|
import { transaction, getMilestone, getMilestoneSlices, getSliceTasks, updateMilestoneStatus, } from "../gsd-db.js";
|
|
11
11
|
import { resolveMilestonePath, clearPathCache } from "../paths.js";
|
|
12
|
+
import { isClosedStatus } from "../status-guards.js";
|
|
12
13
|
import { saveFile, clearParseCache } from "../files.js";
|
|
13
14
|
import { invalidateStateCache } from "../state.js";
|
|
14
15
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
@@ -89,7 +90,7 @@ export async function handleCompleteMilestone(params, basePath) {
|
|
|
89
90
|
guardError = `milestone not found: ${params.milestoneId}`;
|
|
90
91
|
return;
|
|
91
92
|
}
|
|
92
|
-
if (milestone.status
|
|
93
|
+
if (isClosedStatus(milestone.status)) {
|
|
93
94
|
guardError = `milestone ${params.milestoneId} is already complete`;
|
|
94
95
|
return;
|
|
95
96
|
}
|
|
@@ -99,7 +100,7 @@ export async function handleCompleteMilestone(params, basePath) {
|
|
|
99
100
|
guardError = `no slices found for milestone ${params.milestoneId}`;
|
|
100
101
|
return;
|
|
101
102
|
}
|
|
102
|
-
const incompleteSlices = slices.filter(s => s.status
|
|
103
|
+
const incompleteSlices = slices.filter(s => !isClosedStatus(s.status));
|
|
103
104
|
if (incompleteSlices.length > 0) {
|
|
104
105
|
const incompleteIds = incompleteSlices.map(s => `${s.id} (status: ${s.status})`).join(", ");
|
|
105
106
|
guardError = `incomplete slices: ${incompleteIds}`;
|
|
@@ -108,7 +109,7 @@ export async function handleCompleteMilestone(params, basePath) {
|
|
|
108
109
|
// Deep check: verify all tasks in all slices are complete
|
|
109
110
|
for (const slice of slices) {
|
|
110
111
|
const tasks = getSliceTasks(params.milestoneId, slice.id);
|
|
111
|
-
const incompleteTasks = tasks.filter(t => t.status
|
|
112
|
+
const incompleteTasks = tasks.filter(t => !isClosedStatus(t.status));
|
|
112
113
|
if (incompleteTasks.length > 0) {
|
|
113
114
|
const ids = incompleteTasks.map(t => `${t.id} (status: ${t.status})`).join(", ");
|
|
114
115
|
guardError = `slice ${slice.id} has incomplete tasks: ${ids}`;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import { mkdirSync } from "node:fs";
|
|
11
|
+
import { isClosedStatus } from "../status-guards.js";
|
|
11
12
|
import { transaction, insertMilestone, insertSlice, getSlice, getSliceTasks, getMilestone, updateSliceStatus, setSliceSummaryMd, } from "../gsd-db.js";
|
|
12
13
|
import { resolveSlicePath, clearPathCache } from "../paths.js";
|
|
13
14
|
import { checkOwnership, sliceUnitKey } from "../unit-ownership.js";
|
|
@@ -179,12 +180,12 @@ export async function handleCompleteSlice(params, basePath) {
|
|
|
179
180
|
// Milestone/slice not existing is OK — insertMilestone/insertSlice below will auto-create.
|
|
180
181
|
// Only block if they exist and are closed.
|
|
181
182
|
const milestone = getMilestone(params.milestoneId);
|
|
182
|
-
if (milestone && (milestone.status
|
|
183
|
+
if (milestone && isClosedStatus(milestone.status)) {
|
|
183
184
|
guardError = `cannot complete slice in a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
|
|
184
185
|
return;
|
|
185
186
|
}
|
|
186
187
|
const slice = getSlice(params.milestoneId, params.sliceId);
|
|
187
|
-
if (slice && (slice.status
|
|
188
|
+
if (slice && isClosedStatus(slice.status)) {
|
|
188
189
|
guardError = `slice ${params.sliceId} is already complete — use gsd_slice_reopen first if you need to redo it`;
|
|
189
190
|
return;
|
|
190
191
|
}
|
|
@@ -194,7 +195,7 @@ export async function handleCompleteSlice(params, basePath) {
|
|
|
194
195
|
guardError = `no tasks found for slice ${params.sliceId} in milestone ${params.milestoneId}`;
|
|
195
196
|
return;
|
|
196
197
|
}
|
|
197
|
-
const incompleteTasks = tasks.filter(t => t.status
|
|
198
|
+
const incompleteTasks = tasks.filter(t => !isClosedStatus(t.status));
|
|
198
199
|
if (incompleteTasks.length > 0) {
|
|
199
200
|
const incompleteIds = incompleteTasks.map(t => `${t.id} (status: ${t.status})`).join(", ");
|
|
200
201
|
guardError = `incomplete tasks: ${incompleteIds}`;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import { mkdirSync } from "node:fs";
|
|
11
|
+
import { isClosedStatus } from "../status-guards.js";
|
|
11
12
|
import { transaction, insertMilestone, insertSlice, insertTask, insertVerificationEvidence, getMilestone, getSlice, getTask, updateTaskStatus, setTaskSummaryMd, deleteVerificationEvidence, } from "../gsd-db.js";
|
|
12
13
|
import { resolveSliceFile, resolveTasksDir, clearPathCache } from "../paths.js";
|
|
13
14
|
import { checkOwnership, taskUnitKey } from "../unit-ownership.js";
|
|
@@ -122,17 +123,17 @@ export async function handleCompleteTask(params, basePath) {
|
|
|
122
123
|
// Milestone/slice not existing is OK — insertMilestone/insertSlice below will auto-create.
|
|
123
124
|
// Only block if they exist and are closed.
|
|
124
125
|
const milestone = getMilestone(params.milestoneId);
|
|
125
|
-
if (milestone && (milestone.status
|
|
126
|
+
if (milestone && isClosedStatus(milestone.status)) {
|
|
126
127
|
guardError = `cannot complete task in a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
|
|
127
128
|
return;
|
|
128
129
|
}
|
|
129
130
|
const slice = getSlice(params.milestoneId, params.sliceId);
|
|
130
|
-
if (slice && (slice.status
|
|
131
|
+
if (slice && isClosedStatus(slice.status)) {
|
|
131
132
|
guardError = `cannot complete task in a closed slice: ${params.sliceId} (status: ${slice.status})`;
|
|
132
133
|
return;
|
|
133
134
|
}
|
|
134
135
|
const existingTask = getTask(params.milestoneId, params.sliceId, params.taskId);
|
|
135
|
-
if (existingTask && (existingTask.status
|
|
136
|
+
if (existingTask && isClosedStatus(existingTask.status)) {
|
|
136
137
|
guardError = `task ${params.taskId} is already complete — use gsd_task_reopen first if you need to redo it`;
|
|
137
138
|
return;
|
|
138
139
|
}
|
|
@@ -1,22 +1,12 @@
|
|
|
1
1
|
import { clearParseCache } from "../files.js";
|
|
2
|
+
import { isClosedStatus } from "../status-guards.js";
|
|
3
|
+
import { isNonEmptyString, validateStringArray } from "../validation.js";
|
|
2
4
|
import { transaction, getMilestone, insertMilestone, insertSlice, upsertMilestonePlanning, upsertSlicePlanning, } from "../gsd-db.js";
|
|
3
5
|
import { invalidateStateCache } from "../state.js";
|
|
4
6
|
import { renderRoadmapFromDb } from "../markdown-renderer.js";
|
|
5
7
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
6
8
|
import { writeManifest } from "../workflow-manifest.js";
|
|
7
9
|
import { appendEvent } from "../workflow-events.js";
|
|
8
|
-
function isNonEmptyString(value) {
|
|
9
|
-
return typeof value === "string" && value.trim().length > 0;
|
|
10
|
-
}
|
|
11
|
-
function validateStringArray(value, field) {
|
|
12
|
-
if (!Array.isArray(value)) {
|
|
13
|
-
throw new Error(`${field} must be an array`);
|
|
14
|
-
}
|
|
15
|
-
if (value.some((item) => !isNonEmptyString(item))) {
|
|
16
|
-
throw new Error(`${field} must contain only non-empty strings`);
|
|
17
|
-
}
|
|
18
|
-
return value;
|
|
19
|
-
}
|
|
20
10
|
function validateRiskEntries(value) {
|
|
21
11
|
if (!Array.isArray(value)) {
|
|
22
12
|
throw new Error("keyRisks must be an array");
|
|
@@ -152,7 +142,7 @@ export async function handlePlanMilestone(rawParams, basePath) {
|
|
|
152
142
|
try {
|
|
153
143
|
transaction(() => {
|
|
154
144
|
const existingMilestone = getMilestone(params.milestoneId);
|
|
155
|
-
if (existingMilestone && (existingMilestone.status
|
|
145
|
+
if (existingMilestone && isClosedStatus(existingMilestone.status)) {
|
|
156
146
|
guardError = `cannot re-plan milestone ${params.milestoneId}: it is already complete`;
|
|
157
147
|
return;
|
|
158
148
|
}
|
|
@@ -164,7 +154,7 @@ export async function handlePlanMilestone(rawParams, basePath) {
|
|
|
164
154
|
guardError = `depends_on references unknown milestone: ${depId}`;
|
|
165
155
|
return;
|
|
166
156
|
}
|
|
167
|
-
if (dep.status
|
|
157
|
+
if (!isClosedStatus(dep.status)) {
|
|
168
158
|
guardError = `depends_on milestone ${depId} is not yet complete (status: ${dep.status})`;
|
|
169
159
|
return;
|
|
170
160
|
}
|
|
@@ -1,22 +1,12 @@
|
|
|
1
1
|
import { clearParseCache } from "../files.js";
|
|
2
|
+
import { isClosedStatus } from "../status-guards.js";
|
|
3
|
+
import { isNonEmptyString } from "../validation.js";
|
|
2
4
|
import { transaction, getMilestone, getSlice, insertTask, upsertSlicePlanning, upsertTaskPlanning, insertGateRow, } from "../gsd-db.js";
|
|
3
5
|
import { invalidateStateCache } from "../state.js";
|
|
4
6
|
import { renderPlanFromDb } from "../markdown-renderer.js";
|
|
5
7
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
6
8
|
import { writeManifest } from "../workflow-manifest.js";
|
|
7
9
|
import { appendEvent } from "../workflow-events.js";
|
|
8
|
-
function isNonEmptyString(value) {
|
|
9
|
-
return typeof value === "string" && value.trim().length > 0;
|
|
10
|
-
}
|
|
11
|
-
function validateStringArray(value, field) {
|
|
12
|
-
if (!Array.isArray(value)) {
|
|
13
|
-
throw new Error(`${field} must be an array`);
|
|
14
|
-
}
|
|
15
|
-
if (value.some((item) => !isNonEmptyString(item))) {
|
|
16
|
-
throw new Error(`${field} must contain only non-empty strings`);
|
|
17
|
-
}
|
|
18
|
-
return value;
|
|
19
|
-
}
|
|
20
10
|
function validateTasks(value) {
|
|
21
11
|
if (!Array.isArray(value) || value.length === 0) {
|
|
22
12
|
throw new Error("tasks must be a non-empty array");
|
|
@@ -113,7 +103,7 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
113
103
|
guardError = `milestone not found: ${params.milestoneId}`;
|
|
114
104
|
return;
|
|
115
105
|
}
|
|
116
|
-
if (parentMilestone.status
|
|
106
|
+
if (isClosedStatus(parentMilestone.status)) {
|
|
117
107
|
guardError = `cannot plan slice in a closed milestone: ${params.milestoneId} (status: ${parentMilestone.status})`;
|
|
118
108
|
return;
|
|
119
109
|
}
|
|
@@ -122,7 +112,7 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
122
112
|
guardError = `missing parent slice: ${params.milestoneId}/${params.sliceId}`;
|
|
123
113
|
return;
|
|
124
114
|
}
|
|
125
|
-
if (parentSlice.status
|
|
115
|
+
if (isClosedStatus(parentSlice.status)) {
|
|
126
116
|
guardError = `cannot re-plan slice ${params.sliceId}: it is already complete — use gsd_slice_reopen first`;
|
|
127
117
|
return;
|
|
128
118
|
}
|
|
@@ -1,22 +1,12 @@
|
|
|
1
1
|
import { clearParseCache } from "../files.js";
|
|
2
|
+
import { isClosedStatus } from "../status-guards.js";
|
|
3
|
+
import { isNonEmptyString, validateStringArray } from "../validation.js";
|
|
2
4
|
import { transaction, getSlice, getTask, insertTask, upsertTaskPlanning } from "../gsd-db.js";
|
|
3
5
|
import { invalidateStateCache } from "../state.js";
|
|
4
6
|
import { renderTaskPlanFromDb } from "../markdown-renderer.js";
|
|
5
7
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
6
8
|
import { writeManifest } from "../workflow-manifest.js";
|
|
7
9
|
import { appendEvent } from "../workflow-events.js";
|
|
8
|
-
function isNonEmptyString(value) {
|
|
9
|
-
return typeof value === "string" && value.trim().length > 0;
|
|
10
|
-
}
|
|
11
|
-
function validateStringArray(value, field) {
|
|
12
|
-
if (!Array.isArray(value)) {
|
|
13
|
-
throw new Error(`${field} must be an array`);
|
|
14
|
-
}
|
|
15
|
-
if (value.some((item) => !isNonEmptyString(item))) {
|
|
16
|
-
throw new Error(`${field} must contain only non-empty strings`);
|
|
17
|
-
}
|
|
18
|
-
return value;
|
|
19
|
-
}
|
|
20
10
|
function validateParams(params) {
|
|
21
11
|
if (!isNonEmptyString(params?.milestoneId))
|
|
22
12
|
throw new Error("milestoneId is required");
|
|
@@ -61,12 +51,12 @@ export async function handlePlanTask(rawParams, basePath) {
|
|
|
61
51
|
guardError = `missing parent slice: ${params.milestoneId}/${params.sliceId}`;
|
|
62
52
|
return;
|
|
63
53
|
}
|
|
64
|
-
if (parentSlice.status
|
|
54
|
+
if (isClosedStatus(parentSlice.status)) {
|
|
65
55
|
guardError = `cannot plan task in a closed slice: ${params.sliceId} (status: ${parentSlice.status})`;
|
|
66
56
|
return;
|
|
67
57
|
}
|
|
68
58
|
const existingTask = getTask(params.milestoneId, params.sliceId, params.taskId);
|
|
69
|
-
if (existingTask && (existingTask.status
|
|
59
|
+
if (existingTask && isClosedStatus(existingTask.status)) {
|
|
70
60
|
guardError = `cannot re-plan task ${params.taskId}: it is already complete — use gsd_task_reopen first`;
|
|
71
61
|
return;
|
|
72
62
|
}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
1
2
|
import { clearParseCache } from "../files.js";
|
|
3
|
+
import { isClosedStatus } from "../status-guards.js";
|
|
4
|
+
import { isNonEmptyString } from "../validation.js";
|
|
2
5
|
import { transaction, getMilestone, getMilestoneSlices, getSlice, insertSlice, updateSliceFields, insertAssessment, deleteSlice, } from "../gsd-db.js";
|
|
3
6
|
import { invalidateStateCache } from "../state.js";
|
|
4
7
|
import { renderRoadmapFromDb, renderAssessmentFromDb } from "../markdown-renderer.js";
|
|
5
8
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
6
9
|
import { writeManifest } from "../workflow-manifest.js";
|
|
7
10
|
import { appendEvent } from "../workflow-events.js";
|
|
8
|
-
import { join } from "node:path";
|
|
9
|
-
function isNonEmptyString(value) {
|
|
10
|
-
return typeof value === "string" && value.trim().length > 0;
|
|
11
|
-
}
|
|
12
11
|
function validateParams(params) {
|
|
13
12
|
if (!isNonEmptyString(params?.milestoneId))
|
|
14
13
|
throw new Error("milestoneId is required");
|
|
@@ -76,7 +75,7 @@ export async function handleReassessRoadmap(rawParams, basePath) {
|
|
|
76
75
|
guardError = `milestone not found: ${params.milestoneId}`;
|
|
77
76
|
return;
|
|
78
77
|
}
|
|
79
|
-
if (milestone.status
|
|
78
|
+
if (isClosedStatus(milestone.status)) {
|
|
80
79
|
guardError = `cannot reassess a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
|
|
81
80
|
return;
|
|
82
81
|
}
|
|
@@ -86,7 +85,7 @@ export async function handleReassessRoadmap(rawParams, basePath) {
|
|
|
86
85
|
guardError = `completedSliceId not found: ${params.milestoneId}/${params.completedSliceId}`;
|
|
87
86
|
return;
|
|
88
87
|
}
|
|
89
|
-
if (completedSlice.status
|
|
88
|
+
if (!isClosedStatus(completedSlice.status)) {
|
|
90
89
|
guardError = `completedSliceId ${params.completedSliceId} is not complete (status: ${completedSlice.status}) — reassess can only be called after a slice finishes`;
|
|
91
90
|
return;
|
|
92
91
|
}
|
|
@@ -94,7 +93,7 @@ export async function handleReassessRoadmap(rawParams, basePath) {
|
|
|
94
93
|
const existingSlices = getMilestoneSlices(params.milestoneId);
|
|
95
94
|
const completedSliceIds = new Set();
|
|
96
95
|
for (const slice of existingSlices) {
|
|
97
|
-
if (slice.status
|
|
96
|
+
if (isClosedStatus(slice.status)) {
|
|
98
97
|
completedSliceIds.add(slice.id);
|
|
99
98
|
}
|
|
100
99
|
}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
12
12
|
import { getMilestone, getSlice, getSliceTasks, updateSliceStatus, updateTaskStatus, transaction, } from "../gsd-db.js";
|
|
13
13
|
import { invalidateStateCache } from "../state.js";
|
|
14
|
+
import { isClosedStatus } from "../status-guards.js";
|
|
14
15
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
15
16
|
import { writeManifest } from "../workflow-manifest.js";
|
|
16
17
|
import { appendEvent } from "../workflow-events.js";
|
|
@@ -31,8 +32,8 @@ export async function handleReopenSlice(params, basePath) {
|
|
|
31
32
|
guardError = `milestone not found: ${params.milestoneId}`;
|
|
32
33
|
return;
|
|
33
34
|
}
|
|
34
|
-
if (milestone.status
|
|
35
|
-
guardError = `cannot reopen slice
|
|
35
|
+
if (isClosedStatus(milestone.status)) {
|
|
36
|
+
guardError = `cannot reopen slice in a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
|
|
36
37
|
return;
|
|
37
38
|
}
|
|
38
39
|
const slice = getSlice(params.milestoneId, params.sliceId);
|
|
@@ -40,7 +41,7 @@ export async function handleReopenSlice(params, basePath) {
|
|
|
40
41
|
guardError = `slice not found: ${params.milestoneId}/${params.sliceId}`;
|
|
41
42
|
return;
|
|
42
43
|
}
|
|
43
|
-
if (slice.status
|
|
44
|
+
if (!isClosedStatus(slice.status)) {
|
|
44
45
|
guardError = `slice ${params.sliceId} is not complete (status: ${slice.status}) — nothing to reopen`;
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
11
11
|
import { getMilestone, getSlice, getTask, updateTaskStatus, transaction, } from "../gsd-db.js";
|
|
12
12
|
import { invalidateStateCache } from "../state.js";
|
|
13
|
+
import { isClosedStatus } from "../status-guards.js";
|
|
13
14
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
14
15
|
import { writeManifest } from "../workflow-manifest.js";
|
|
15
16
|
import { appendEvent } from "../workflow-events.js";
|
|
@@ -32,7 +33,7 @@ export async function handleReopenTask(params, basePath) {
|
|
|
32
33
|
guardError = `milestone not found: ${params.milestoneId}`;
|
|
33
34
|
return;
|
|
34
35
|
}
|
|
35
|
-
if (milestone.status
|
|
36
|
+
if (isClosedStatus(milestone.status)) {
|
|
36
37
|
guardError = `cannot reopen task in a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
|
|
37
38
|
return;
|
|
38
39
|
}
|
|
@@ -41,8 +42,8 @@ export async function handleReopenTask(params, basePath) {
|
|
|
41
42
|
guardError = `slice not found: ${params.milestoneId}/${params.sliceId}`;
|
|
42
43
|
return;
|
|
43
44
|
}
|
|
44
|
-
if (slice.status
|
|
45
|
-
guardError = `cannot reopen task
|
|
45
|
+
if (isClosedStatus(slice.status)) {
|
|
46
|
+
guardError = `cannot reopen task in a closed slice: ${params.sliceId} (status: ${slice.status}) — use gsd_slice_reopen first`;
|
|
46
47
|
return;
|
|
47
48
|
}
|
|
48
49
|
const task = getTask(params.milestoneId, params.sliceId, params.taskId);
|
|
@@ -50,7 +51,7 @@ export async function handleReopenTask(params, basePath) {
|
|
|
50
51
|
guardError = `task not found: ${params.milestoneId}/${params.sliceId}/${params.taskId}`;
|
|
51
52
|
return;
|
|
52
53
|
}
|
|
53
|
-
if (task.status
|
|
54
|
+
if (!isClosedStatus(task.status)) {
|
|
54
55
|
guardError = `task ${params.taskId} is not complete (status: ${task.status}) — nothing to reopen`;
|
|
55
56
|
return;
|
|
56
57
|
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { clearParseCache } from "../files.js";
|
|
2
2
|
import { transaction, getSlice, getSliceTasks, getTask, insertTask, upsertTaskPlanning, insertReplanHistory, deleteTask, } from "../gsd-db.js";
|
|
3
3
|
import { invalidateStateCache } from "../state.js";
|
|
4
|
+
import { isClosedStatus } from "../status-guards.js";
|
|
5
|
+
import { isNonEmptyString } from "../validation.js";
|
|
4
6
|
import { renderPlanFromDb, renderReplanFromDb } from "../markdown-renderer.js";
|
|
5
7
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
6
8
|
import { writeManifest } from "../workflow-manifest.js";
|
|
7
9
|
import { appendEvent } from "../workflow-events.js";
|
|
8
|
-
function isNonEmptyString(value) {
|
|
9
|
-
return typeof value === "string" && value.trim().length > 0;
|
|
10
|
-
}
|
|
11
10
|
function validateParams(params) {
|
|
12
11
|
if (!isNonEmptyString(params?.milestoneId))
|
|
13
12
|
throw new Error("milestoneId is required");
|
|
@@ -59,7 +58,7 @@ export async function handleReplanSlice(rawParams, basePath) {
|
|
|
59
58
|
guardError = `missing parent slice: ${params.milestoneId}/${params.sliceId}`;
|
|
60
59
|
return;
|
|
61
60
|
}
|
|
62
|
-
if (parentSlice.status
|
|
61
|
+
if (isClosedStatus(parentSlice.status)) {
|
|
63
62
|
guardError = `cannot replan a closed slice: ${params.sliceId} (status: ${parentSlice.status})`;
|
|
64
63
|
return;
|
|
65
64
|
}
|
|
@@ -69,7 +68,7 @@ export async function handleReplanSlice(rawParams, basePath) {
|
|
|
69
68
|
guardError = `blockerTaskId not found: ${params.milestoneId}/${params.sliceId}/${params.blockerTaskId}`;
|
|
70
69
|
return;
|
|
71
70
|
}
|
|
72
|
-
if (blockerTask.status
|
|
71
|
+
if (!isClosedStatus(blockerTask.status)) {
|
|
73
72
|
guardError = `blockerTaskId ${params.blockerTaskId} is not complete (status: ${blockerTask.status}) — the blocker task must be finished before a replan is triggered`;
|
|
74
73
|
return;
|
|
75
74
|
}
|
|
@@ -77,7 +76,7 @@ export async function handleReplanSlice(rawParams, basePath) {
|
|
|
77
76
|
const existingTasks = getSliceTasks(params.milestoneId, params.sliceId);
|
|
78
77
|
const completedTaskIds = new Set();
|
|
79
78
|
for (const task of existingTasks) {
|
|
80
|
-
if (task.status
|
|
79
|
+
if (isClosedStatus(task.status)) {
|
|
81
80
|
completedTaskIds.add(task.id);
|
|
82
81
|
}
|
|
83
82
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared input-validation primitives for GSD tool handlers.
|
|
3
|
+
*/
|
|
4
|
+
/** Type guard: value is a string with at least one non-whitespace character. */
|
|
5
|
+
export function isNonEmptyString(value) {
|
|
6
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Validate that `value` is an array of non-empty strings.
|
|
10
|
+
* Throws with a message referencing `field` on failure.
|
|
11
|
+
* Returns the validated array (narrowed to string[]).
|
|
12
|
+
*/
|
|
13
|
+
export function validateStringArray(value, field) {
|
|
14
|
+
if (!Array.isArray(value)) {
|
|
15
|
+
throw new Error(`${field} must be an array`);
|
|
16
|
+
}
|
|
17
|
+
if (value.some((item) => !isNonEmptyString(item))) {
|
|
18
|
+
throw new Error(`${field} must contain only non-empty strings`);
|
|
19
|
+
}
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
@@ -4,6 +4,7 @@ import { homedir } from "node:os";
|
|
|
4
4
|
import { delimiter, join } from "node:path";
|
|
5
5
|
const GSD_RTK_PATH_ENV = "GSD_RTK_PATH";
|
|
6
6
|
const GSD_RTK_DISABLED_ENV = "GSD_RTK_DISABLED";
|
|
7
|
+
const GSD_RTK_REWRITE_TIMEOUT_MS_ENV = "GSD_RTK_REWRITE_TIMEOUT_MS";
|
|
7
8
|
const RTK_TELEMETRY_DISABLED_ENV = "RTK_TELEMETRY_DISABLED";
|
|
8
9
|
const RTK_REWRITE_TIMEOUT_MS = 5_000;
|
|
9
10
|
function isTruthy(value) {
|
|
@@ -12,6 +13,13 @@ function isTruthy(value) {
|
|
|
12
13
|
const normalized = value.trim().toLowerCase();
|
|
13
14
|
return normalized === "1" || normalized === "true" || normalized === "yes";
|
|
14
15
|
}
|
|
16
|
+
function getRewriteTimeoutMs(env = process.env) {
|
|
17
|
+
const configured = Number.parseInt(env[GSD_RTK_REWRITE_TIMEOUT_MS_ENV] ?? "", 10);
|
|
18
|
+
if (Number.isFinite(configured) && configured > 0) {
|
|
19
|
+
return configured;
|
|
20
|
+
}
|
|
21
|
+
return RTK_REWRITE_TIMEOUT_MS;
|
|
22
|
+
}
|
|
15
23
|
export function isRtkEnabled(env = process.env) {
|
|
16
24
|
return !isTruthy(env[GSD_RTK_DISABLED_ENV]);
|
|
17
25
|
}
|
|
@@ -75,19 +83,21 @@ export function resolveRtkBinaryPath(options = {}) {
|
|
|
75
83
|
}
|
|
76
84
|
return resolveSystemRtkPath(options.pathValue ?? getPathValue(env), platform);
|
|
77
85
|
}
|
|
78
|
-
export function rewriteCommandWithRtk(command,
|
|
86
|
+
export function rewriteCommandWithRtk(command, options = {}) {
|
|
87
|
+
const env = options.env ?? process.env;
|
|
79
88
|
if (!command.trim())
|
|
80
89
|
return command;
|
|
81
90
|
if (!isRtkEnabled(env))
|
|
82
91
|
return command;
|
|
83
|
-
const binaryPath = resolveRtkBinaryPath({ env });
|
|
92
|
+
const binaryPath = options.binaryPath ?? resolveRtkBinaryPath({ env });
|
|
84
93
|
if (!binaryPath)
|
|
85
94
|
return command;
|
|
86
|
-
const
|
|
95
|
+
const run = options.spawnSyncImpl ?? spawnSync;
|
|
96
|
+
const result = run(binaryPath, ["rewrite", command], {
|
|
87
97
|
encoding: "utf-8",
|
|
88
98
|
env: buildRtkEnv(env),
|
|
89
99
|
stdio: ["ignore", "pipe", "ignore"],
|
|
90
|
-
timeout:
|
|
100
|
+
timeout: getRewriteTimeoutMs(env),
|
|
91
101
|
// .cmd/.bat wrappers (used by fake-rtk in tests) require shell:true on Windows
|
|
92
102
|
shell: /\.(cmd|bat)$/i.test(binaryPath),
|
|
93
103
|
});
|
package/dist/rtk.js
CHANGED
|
@@ -175,7 +175,9 @@ function resolveSystemRtkPath(pathValue, platform = process.platform) {
|
|
|
175
175
|
export function resolveRtkBinaryPath(options = {}) {
|
|
176
176
|
const env = options.env ?? process.env;
|
|
177
177
|
const platform = options.platform ?? process.platform;
|
|
178
|
-
|
|
178
|
+
if (options.binaryPath)
|
|
179
|
+
return options.binaryPath;
|
|
180
|
+
const explicitPath = env[GSD_RTK_PATH_ENV];
|
|
179
181
|
if (explicitPath && existsSync(explicitPath)) {
|
|
180
182
|
return explicitPath;
|
|
181
183
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
YO-PWFRitlHM-L-dotlmm
|
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"/_global-error/page": "/_global-error",
|
|
3
3
|
"/_not-found/page": "/_not-found",
|
|
4
|
-
"/api/boot/route": "/api/boot",
|
|
5
4
|
"/api/bridge-terminal/input/route": "/api/bridge-terminal/input",
|
|
5
|
+
"/api/boot/route": "/api/boot",
|
|
6
6
|
"/api/bridge-terminal/resize/route": "/api/bridge-terminal/resize",
|
|
7
7
|
"/api/bridge-terminal/stream/route": "/api/bridge-terminal/stream",
|
|
8
|
-
"/api/dev-mode/route": "/api/dev-mode",
|
|
9
8
|
"/api/cleanup/route": "/api/cleanup",
|
|
10
|
-
"/api/browse-directories/route": "/api/browse-directories",
|
|
11
9
|
"/api/export-data/route": "/api/export-data",
|
|
12
|
-
"/api/forensics/route": "/api/forensics",
|
|
13
10
|
"/api/doctor/route": "/api/doctor",
|
|
14
|
-
"/api/
|
|
11
|
+
"/api/browse-directories/route": "/api/browse-directories",
|
|
12
|
+
"/api/dev-mode/route": "/api/dev-mode",
|
|
15
13
|
"/api/captures/route": "/api/captures",
|
|
16
|
-
"/api/experimental/route": "/api/experimental",
|
|
17
|
-
"/api/inspect/route": "/api/inspect",
|
|
18
|
-
"/api/hooks/route": "/api/hooks",
|
|
19
14
|
"/api/history/route": "/api/history",
|
|
15
|
+
"/api/forensics/route": "/api/forensics",
|
|
16
|
+
"/api/git/route": "/api/git",
|
|
17
|
+
"/api/hooks/route": "/api/hooks",
|
|
18
|
+
"/api/inspect/route": "/api/inspect",
|
|
19
|
+
"/api/live-state/route": "/api/live-state",
|
|
20
20
|
"/api/knowledge/route": "/api/knowledge",
|
|
21
|
+
"/api/experimental/route": "/api/experimental",
|
|
21
22
|
"/api/preferences/route": "/api/preferences",
|
|
22
|
-
"/api/live-state/route": "/api/live-state",
|
|
23
23
|
"/api/recovery/route": "/api/recovery",
|
|
24
|
-
"/api/projects/route": "/api/projects",
|
|
25
|
-
"/api/session/browser/route": "/api/session/browser",
|
|
26
24
|
"/api/onboarding/route": "/api/onboarding",
|
|
27
|
-
"/api/
|
|
25
|
+
"/api/session/browser/route": "/api/session/browser",
|
|
26
|
+
"/api/projects/route": "/api/projects",
|
|
27
|
+
"/api/session/manage/route": "/api/session/manage",
|
|
28
28
|
"/api/session/command/route": "/api/session/command",
|
|
29
|
-
"/api/
|
|
29
|
+
"/api/skill-health/route": "/api/skill-health",
|
|
30
30
|
"/api/session/events/route": "/api/session/events",
|
|
31
|
+
"/api/settings-data/route": "/api/settings-data",
|
|
31
32
|
"/api/shutdown/route": "/api/shutdown",
|
|
32
|
-
"/api/session/manage/route": "/api/session/manage",
|
|
33
|
-
"/api/skill-health/route": "/api/skill-health",
|
|
34
33
|
"/api/steer/route": "/api/steer",
|
|
34
|
+
"/api/terminal/resize/route": "/api/terminal/resize",
|
|
35
35
|
"/api/switch-root/route": "/api/switch-root",
|
|
36
|
+
"/api/files/route": "/api/files",
|
|
36
37
|
"/api/terminal/input/route": "/api/terminal/input",
|
|
37
|
-
"/api/terminal/resize/route": "/api/terminal/resize",
|
|
38
|
-
"/api/terminal/sessions/route": "/api/terminal/sessions",
|
|
39
|
-
"/api/undo/route": "/api/undo",
|
|
40
|
-
"/api/remote-questions/route": "/api/remote-questions",
|
|
41
|
-
"/api/update/route": "/api/update",
|
|
42
38
|
"/api/visualizer/route": "/api/visualizer",
|
|
43
39
|
"/api/terminal/stream/route": "/api/terminal/stream",
|
|
40
|
+
"/api/undo/route": "/api/undo",
|
|
41
|
+
"/api/terminal/sessions/route": "/api/terminal/sessions",
|
|
42
|
+
"/api/update/route": "/api/update",
|
|
43
|
+
"/api/remote-questions/route": "/api/remote-questions",
|
|
44
44
|
"/api/terminal/upload/route": "/api/terminal/upload",
|
|
45
45
|
"/page": "/"
|
|
46
46
|
}
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
],
|
|
5
5
|
"devFiles": [],
|
|
6
6
|
"lowPriorityFiles": [
|
|
7
|
-
"static/
|
|
8
|
-
"static/
|
|
7
|
+
"static/YO-PWFRitlHM-L-dotlmm/_buildManifest.js",
|
|
8
|
+
"static/YO-PWFRitlHM-L-dotlmm/_ssgManifest.js"
|
|
9
9
|
],
|
|
10
10
|
"rootMainFiles": [
|
|
11
|
-
"static/chunks/webpack-
|
|
11
|
+
"static/chunks/webpack-bca0e732db0dcec3.js",
|
|
12
12
|
"static/chunks/4bd1b696-e5d7c65570c947b7.js",
|
|
13
13
|
"static/chunks/3794-337d1ca25ad99a89.js",
|
|
14
|
-
"static/chunks/main-app-
|
|
14
|
+
"static/chunks/main-app-fdab67f7802d7832.js"
|
|
15
15
|
],
|
|
16
16
|
"rootMainFilesTree": {},
|
|
17
17
|
"pages": {
|
|
@@ -78,8 +78,8 @@
|
|
|
78
78
|
"dynamicRoutes": {},
|
|
79
79
|
"notFoundRoutes": [],
|
|
80
80
|
"preview": {
|
|
81
|
-
"previewModeId": "
|
|
82
|
-
"previewModeSigningKey": "
|
|
83
|
-
"previewModeEncryptionKey": "
|
|
81
|
+
"previewModeId": "01331f5d86acc7be1d3ecc8d5855e334",
|
|
82
|
+
"previewModeSigningKey": "8b6653cdd01c63bde017b6a42df870bc138ec94025546cdb71ac3548cfea7fa6",
|
|
83
|
+
"previewModeEncryptionKey": "2d7b20c003d03450d2f327b36c6e5db81437c825c1417b0299956d4083d83ea7"
|
|
84
84
|
}
|
|
85
85
|
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"static/chunks/363642f4.f9053a63f1b97508.js",
|
|
7
7
|
"static/chunks/4986-c2fc8845ce785303.js",
|
|
8
8
|
"static/chunks/2008.817d0885545aaea9.js",
|
|
9
|
-
"static/chunks/4024.
|
|
9
|
+
"static/chunks/4024.87fd909ae0110f50.js"
|
|
10
10
|
]
|
|
11
11
|
},
|
|
12
12
|
"components/gsd/chat-mode.tsx -> react-markdown": {
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"transform": "lodash/{{member}}"
|
|
101
101
|
}
|
|
102
102
|
},
|
|
103
|
-
"outputFileTracingRoot": "/
|
|
103
|
+
"outputFileTracingRoot": "/__w/gsd-2/gsd-2",
|
|
104
104
|
"cacheComponents": false,
|
|
105
105
|
"cacheLife": {
|
|
106
106
|
"default": {
|
|
@@ -297,11 +297,11 @@
|
|
|
297
297
|
"node-pty"
|
|
298
298
|
],
|
|
299
299
|
"turbopack": {
|
|
300
|
-
"root": "/
|
|
300
|
+
"root": "/__w/gsd-2/gsd-2"
|
|
301
301
|
},
|
|
302
302
|
"distDirRoot": ".next"
|
|
303
303
|
},
|
|
304
|
-
"appDir": "/
|
|
304
|
+
"appDir": "/__w/gsd-2/gsd-2/web",
|
|
305
305
|
"relativeAppDir": "web",
|
|
306
306
|
"files": [
|
|
307
307
|
".next/routes-manifest.json",
|