gsd-pi 2.80.0-dev.2848d9009 → 2.80.0-dev.42bd34838
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/gsd/auto/loop.js +32 -1
- package/dist/resources/extensions/gsd/auto/phases.js +29 -15
- package/dist/resources/extensions/gsd/auto/resolve.js +17 -0
- package/dist/resources/extensions/gsd/auto/run-unit.js +13 -1
- package/dist/resources/extensions/gsd/auto-prompts.js +13 -1
- package/dist/resources/extensions/gsd/auto-recovery.js +43 -1
- package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
- package/dist/resources/extensions/gsd/auto.js +68 -4
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +21 -2
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +27 -20
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +21 -0
- package/dist/resources/extensions/gsd/context-budget.js +37 -2
- package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +39 -0
- package/dist/resources/extensions/gsd/db-base-schema.js +4 -2
- package/dist/resources/extensions/gsd/db-migration-steps.js +6 -0
- package/dist/resources/extensions/gsd/git-service.js +36 -4
- package/dist/resources/extensions/gsd/gsd-db.js +46 -13
- package/dist/resources/extensions/gsd/guided-flow.js +52 -10
- package/dist/resources/extensions/gsd/memory-store.js +69 -12
- package/dist/resources/extensions/gsd/migrate/command.js +40 -1
- package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
- package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +14 -13
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/dist/resources/extensions/gsd/quick.js +34 -2
- package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
- package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
- package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
- package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
- package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
- package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
- package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
- package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
- package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
- package/dist/resources/extensions/gsd/worktree-resolver.js +33 -17
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/server.js +1 -1
- package/package.json +3 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +22 -17
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
- package/packages/mcp-server/src/workflow-tools.ts +30 -16
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +8 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +3 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +3 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +7 -0
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +20 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +25 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +13 -5
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +53 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +10 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +8 -0
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +3 -1
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
- package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
- package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
- package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +2 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +3 -0
- package/packages/pi-coding-agent/src/core/extensions/types.ts +7 -0
- package/packages/pi-coding-agent/src/core/settings-manager.ts +39 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +4 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +56 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +22 -7
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +3 -0
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +14 -0
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +18 -8
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/tui.ts +20 -8
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/src/resources/extensions/gsd/auto/loop.ts +50 -8
- package/src/resources/extensions/gsd/auto/phases.ts +35 -20
- package/src/resources/extensions/gsd/auto/resolve.ts +23 -1
- package/src/resources/extensions/gsd/auto/run-unit.ts +18 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +17 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +54 -0
- package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
- package/src/resources/extensions/gsd/auto.ts +80 -3
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +21 -1
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +27 -19
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -0
- package/src/resources/extensions/gsd/context-budget.ts +44 -2
- package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +41 -0
- package/src/resources/extensions/gsd/db-base-schema.ts +4 -2
- package/src/resources/extensions/gsd/db-migration-steps.ts +8 -0
- package/src/resources/extensions/gsd/git-service.ts +46 -8
- package/src/resources/extensions/gsd/gsd-db.ts +50 -13
- package/src/resources/extensions/gsd/guided-flow.ts +71 -10
- package/src/resources/extensions/gsd/memory-store.ts +77 -12
- package/src/resources/extensions/gsd/migrate/command.ts +47 -1
- package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
- package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
- package/src/resources/extensions/gsd/preferences-types.ts +1 -1
- package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +14 -13
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/src/resources/extensions/gsd/quick.ts +37 -2
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +56 -13
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +14 -1
- package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
- package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
- package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
- package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +234 -0
- package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
- package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/status-db-open.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
- package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +63 -1
- package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
- package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
- package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
- package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
- package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
- package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
- package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
- package/src/resources/extensions/gsd/worktree-resolver.ts +36 -15
- /package/dist/web/standalone/.next/static/{vaQ47E8aNlbbNEDoeME6G → tht0ltP8EIjsohPOA_WZf}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{vaQ47E8aNlbbNEDoeME6G → tht0ltP8EIjsohPOA_WZf}/_ssgManifest.js +0 -0
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
* Quick tasks live in `.gsd/quick/` and are tracked in STATE.md's
|
|
9
9
|
* "Quick Tasks Completed" table.
|
|
10
10
|
*/
|
|
11
|
-
import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
12
|
-
import { join } from "node:path";
|
|
11
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
|
12
|
+
import { isAbsolute, join, relative } from "node:path";
|
|
13
13
|
import { loadPrompt } from "./prompt-loader.js";
|
|
14
14
|
import { gsdRoot } from "./paths.js";
|
|
15
15
|
import { GitServiceImpl, runGit } from "./git-service.js";
|
|
@@ -64,6 +64,37 @@ function ensureQuickDir(basePath, taskNum, slug) {
|
|
|
64
64
|
mkdirSync(taskDir, { recursive: true });
|
|
65
65
|
return taskDir;
|
|
66
66
|
}
|
|
67
|
+
function isPathInside(parent, child) {
|
|
68
|
+
const rel = relative(parent, child);
|
|
69
|
+
return rel === "" || (!!rel && !rel.startsWith("..") && !isAbsolute(rel));
|
|
70
|
+
}
|
|
71
|
+
function isExternalGsdRoot(basePath, root) {
|
|
72
|
+
try {
|
|
73
|
+
return !isPathInside(realpathSync(basePath), realpathSync(root));
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return !isPathInside(basePath, root);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export function buildQuickCommitInstruction(basePath, root) {
|
|
80
|
+
const externalState = isExternalGsdRoot(basePath, root);
|
|
81
|
+
if (externalState) {
|
|
82
|
+
return [
|
|
83
|
+
"Commit repo changes atomically, but do not stage or commit `.gsd/quick/...`:",
|
|
84
|
+
" - `.gsd/` resolves outside this git repository, so Git cannot stage quick-task summary files from the project repo.",
|
|
85
|
+
" - Write the quick summary file directly at the requested path; that file is persisted by GSD external state.",
|
|
86
|
+
" - Stage and commit only implementation/test/docs files that live inside the repository.",
|
|
87
|
+
" - If the task only writes quick-task research/summary files and no repository files changed, do not run `git commit`; report that there was nothing in the project repo to commit.",
|
|
88
|
+
].join("\n");
|
|
89
|
+
}
|
|
90
|
+
return [
|
|
91
|
+
"Commit your changes atomically:",
|
|
92
|
+
" - Use conventional commit messages (feat:, fix:, refactor:, etc.)",
|
|
93
|
+
" - Stage only relevant files — never commit secrets or runtime files.",
|
|
94
|
+
" - Commit logical units separately if the task involves distinct changes.",
|
|
95
|
+
" - Quick tasks run outside the auto-mode lifecycle — there is no system auto-commit, so commit directly here.",
|
|
96
|
+
].join("\n");
|
|
97
|
+
}
|
|
67
98
|
function quickReturnStatePath(basePath) {
|
|
68
99
|
return join(gsdRoot(basePath), "runtime", "quick-return.json");
|
|
69
100
|
}
|
|
@@ -198,6 +229,7 @@ export async function handleQuick(args, ctx, pi) {
|
|
|
198
229
|
taskDir: taskDirRel,
|
|
199
230
|
branch: actualBranch,
|
|
200
231
|
summaryPath,
|
|
232
|
+
commitInstruction: buildQuickCommitInstruction(basePath, root),
|
|
201
233
|
date,
|
|
202
234
|
taskNum: String(taskNum),
|
|
203
235
|
slug,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Shared Context Mode tool result helpers.
|
|
3
|
+
export function contextModeDisabledResult(operation) {
|
|
4
|
+
return {
|
|
5
|
+
content: [
|
|
6
|
+
{
|
|
7
|
+
type: "text",
|
|
8
|
+
text: `${operation} is disabled by \`context_mode.enabled: false\` in preferences. ` +
|
|
9
|
+
"Remove that override or set it to true to re-enable Context Mode tools.",
|
|
10
|
+
},
|
|
11
|
+
],
|
|
12
|
+
details: { operation, error: "context_mode_disabled" },
|
|
13
|
+
isError: true,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
// Scans .gsd/exec/*.meta.json and returns a ranked summary so agents can
|
|
4
4
|
// re-discover past runs without re-executing. Read-only; no DB writes.
|
|
5
5
|
import { searchExecHistory } from "../exec-history.js";
|
|
6
|
+
import { isContextModeEnabled } from "../preferences-types.js";
|
|
7
|
+
import { contextModeDisabledResult } from "./context-mode-tool-result.js";
|
|
6
8
|
export function executeExecSearch(params, opts) {
|
|
9
|
+
if (!isContextModeEnabled(opts.preferences)) {
|
|
10
|
+
return contextModeDisabledResult("gsd_exec_search");
|
|
11
|
+
}
|
|
7
12
|
const searchOpts = {
|
|
8
13
|
query: typeof params.query === "string" ? params.query : undefined,
|
|
9
14
|
runtime: params.runtime,
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// for MCP return.
|
|
6
6
|
import { EXEC_DEFAULTS, runExecSandbox, } from "../exec-sandbox.js";
|
|
7
7
|
import { isContextModeEnabled } from "../preferences-types.js";
|
|
8
|
+
import { contextModeDisabledResult } from "./context-mode-tool-result.js";
|
|
8
9
|
export function buildExecOptions(baseDir, cfg, extras) {
|
|
9
10
|
const allowlist = Array.isArray(cfg?.exec_env_allowlist) ? cfg.exec_env_allowlist : EXEC_DEFAULTS.envAllowlist;
|
|
10
11
|
const stdoutCap = clampNumber(cfg?.exec_stdout_cap_bytes, EXEC_DEFAULTS.stdoutCapBytes, 4_096, 16_777_216);
|
|
@@ -33,19 +34,6 @@ function clampNumber(value, fallback, min, max) {
|
|
|
33
34
|
function isEnabled(prefs) {
|
|
34
35
|
return isContextModeEnabled(prefs);
|
|
35
36
|
}
|
|
36
|
-
function disabledResult() {
|
|
37
|
-
return {
|
|
38
|
-
content: [
|
|
39
|
-
{
|
|
40
|
-
type: "text",
|
|
41
|
-
text: "gsd_exec is disabled by `context_mode.enabled: false` in preferences. Remove that " +
|
|
42
|
-
"override (or set it to true) to re-enable sandboxed tool-output execution.",
|
|
43
|
-
},
|
|
44
|
-
],
|
|
45
|
-
details: { operation: "gsd_exec", error: "context_mode_disabled" },
|
|
46
|
-
isError: true,
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
37
|
function paramError(message) {
|
|
50
38
|
return {
|
|
51
39
|
content: [{ type: "text", text: `Error: ${message}` }],
|
|
@@ -55,7 +43,7 @@ function paramError(message) {
|
|
|
55
43
|
}
|
|
56
44
|
export async function executeGsdExec(params, deps) {
|
|
57
45
|
if (!isEnabled(deps.preferences))
|
|
58
|
-
return
|
|
46
|
+
return contextModeDisabledResult("gsd_exec");
|
|
59
47
|
const runtime = params.runtime;
|
|
60
48
|
if (runtime !== "bash" && runtime !== "node" && runtime !== "python") {
|
|
61
49
|
return paramError(`invalid runtime "${String(runtime)}" — must be bash | node | python`);
|
|
@@ -67,7 +55,7 @@ export async function executeGsdExec(params, deps) {
|
|
|
67
55
|
if (Buffer.byteLength(script, "utf8") > 200_000) {
|
|
68
56
|
return paramError("script exceeds the 200 KB length limit");
|
|
69
57
|
}
|
|
70
|
-
const opts = buildExecOptions(deps.baseDir, deps.preferences?.context_mode, { now: deps.now, generateId: deps.generateId });
|
|
58
|
+
const opts = buildExecOptions(deps.baseDir, deps.preferences?.context_mode, { env: deps.env, now: deps.now, generateId: deps.generateId });
|
|
71
59
|
const run = deps.run ?? runExecSandbox;
|
|
72
60
|
try {
|
|
73
61
|
const result = await run({
|
|
@@ -8,6 +8,7 @@ import { renderAllProjections } from "../workflow-projections.js";
|
|
|
8
8
|
import { writeManifest } from "../workflow-manifest.js";
|
|
9
9
|
import { appendEvent } from "../workflow-events.js";
|
|
10
10
|
import { logWarning } from "../workflow-logger.js";
|
|
11
|
+
import { validatePlanningPathScope } from "../planning-path-scope.js";
|
|
11
12
|
function validateTasks(value) {
|
|
12
13
|
if (!Array.isArray(value) || value.length === 0) {
|
|
13
14
|
throw new Error("tasks must be a non-empty array");
|
|
@@ -91,6 +92,14 @@ export async function handlePlanSlice(rawParams, basePath) {
|
|
|
91
92
|
catch (err) {
|
|
92
93
|
return { error: `validation failed: ${err.message}` };
|
|
93
94
|
}
|
|
95
|
+
const pathScopeError = validatePlanningPathScope(basePath, params.tasks.flatMap((task, index) => [
|
|
96
|
+
{ field: `tasks[${index}].files`, values: task.files },
|
|
97
|
+
{ field: `tasks[${index}].inputs`, values: task.inputs },
|
|
98
|
+
{ field: `tasks[${index}].expectedOutput`, values: task.expectedOutput },
|
|
99
|
+
]));
|
|
100
|
+
if (pathScopeError) {
|
|
101
|
+
return { error: `validation failed: ${pathScopeError}` };
|
|
102
|
+
}
|
|
94
103
|
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
|
|
95
104
|
// Guards must be inside the transaction so the state they check cannot
|
|
96
105
|
// change between the read and the write (#2723).
|
|
@@ -8,6 +8,7 @@ import { renderAllProjections } from "../workflow-projections.js";
|
|
|
8
8
|
import { writeManifest } from "../workflow-manifest.js";
|
|
9
9
|
import { appendEvent } from "../workflow-events.js";
|
|
10
10
|
import { logWarning } from "../workflow-logger.js";
|
|
11
|
+
import { validatePlanningPathScope } from "../planning-path-scope.js";
|
|
11
12
|
function validateParams(params) {
|
|
12
13
|
if (!isNonEmptyString(params?.milestoneId))
|
|
13
14
|
throw new Error("milestoneId is required");
|
|
@@ -41,6 +42,14 @@ export async function handlePlanTask(rawParams, basePath) {
|
|
|
41
42
|
catch (err) {
|
|
42
43
|
return { error: `validation failed: ${err.message}` };
|
|
43
44
|
}
|
|
45
|
+
const pathScopeError = validatePlanningPathScope(basePath, [
|
|
46
|
+
{ field: "files", values: params.files },
|
|
47
|
+
{ field: "inputs", values: params.inputs },
|
|
48
|
+
{ field: "expectedOutput", values: params.expectedOutput },
|
|
49
|
+
]);
|
|
50
|
+
if (pathScopeError) {
|
|
51
|
+
return { error: `validation failed: ${pathScopeError}` };
|
|
52
|
+
}
|
|
44
53
|
// ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
|
|
45
54
|
// Guards must be inside the transaction so the state they check cannot
|
|
46
55
|
// change between the read and the write (#2723).
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
// agents can re-orient after compaction or session resume without
|
|
3
3
|
// re-deriving project memory state.
|
|
4
4
|
import { readCompactionSnapshot } from "../compaction-snapshot.js";
|
|
5
|
+
import { isContextModeEnabled } from "../preferences-types.js";
|
|
6
|
+
import { contextModeDisabledResult } from "./context-mode-tool-result.js";
|
|
5
7
|
export function executeResume(_params, opts) {
|
|
8
|
+
if (!isContextModeEnabled(opts.preferences)) {
|
|
9
|
+
return contextModeDisabledResult("gsd_resume");
|
|
10
|
+
}
|
|
6
11
|
const snapshot = readCompactionSnapshot(opts.baseDir);
|
|
7
12
|
if (snapshot == null) {
|
|
8
13
|
return {
|
|
@@ -680,7 +680,7 @@ export async function executeMilestoneStatus(params, basePath = process.cwd()) {
|
|
|
680
680
|
};
|
|
681
681
|
return {
|
|
682
682
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
683
|
-
details: { operation: "milestone_status",
|
|
683
|
+
details: { operation: "milestone_status", ...result },
|
|
684
684
|
};
|
|
685
685
|
});
|
|
686
686
|
}
|
|
@@ -80,7 +80,15 @@ const CONTEXT_MODE_LANE_LABELS = {
|
|
|
80
80
|
orchestration: "orchestration",
|
|
81
81
|
docs: "documentation",
|
|
82
82
|
};
|
|
83
|
-
const
|
|
83
|
+
const CONTEXT_MODE_GUIDANCE_BY_LANE = {
|
|
84
|
+
interview: "Use `gsd_resume` to restore prior discussion, `gsd_exec` for noisy discovery, and `gsd_exec_search` before repeating scans.",
|
|
85
|
+
research: "Use `gsd_exec` for noisy research scans, `gsd_exec_search` before reruns, and `gsd_resume` to restore prior findings.",
|
|
86
|
+
planning: "Use `gsd_resume` for planning continuity, `gsd_exec` for noisy checks, and `gsd_exec_search` before rerunning diagnostics.",
|
|
87
|
+
execution: "Use `gsd_exec` for builds, tests, and diagnostics, `gsd_exec_search` before reruns, and `gsd_resume` after compaction or resume.",
|
|
88
|
+
verification: "Use `gsd_exec` for verification commands, `gsd_exec_search` to reuse prior evidence, and `gsd_resume` after compaction or resume.",
|
|
89
|
+
orchestration: "Use `gsd_resume` before resuming orchestration, `gsd_exec_search` to reuse prior runs, and `gsd_exec` for noisy coordination checks.",
|
|
90
|
+
docs: "Use `gsd_resume` for prior context, `gsd_exec_search` for saved evidence, and `gsd_exec` for noisy doc validation commands.",
|
|
91
|
+
};
|
|
84
92
|
/**
|
|
85
93
|
* Render the Context Mode instruction lane for a unit type. Unknown unit
|
|
86
94
|
* types, disabled config, and explicit `contextMode: "none"` all omit the
|
|
@@ -93,14 +101,15 @@ export function composeContextModeInstructions(unitType, opts) {
|
|
|
93
101
|
if (!manifest || manifest.contextMode === "none")
|
|
94
102
|
return "";
|
|
95
103
|
const lane = CONTEXT_MODE_LANE_LABELS[manifest.contextMode];
|
|
104
|
+
const guidance = CONTEXT_MODE_GUIDANCE_BY_LANE[manifest.contextMode];
|
|
96
105
|
if (opts.renderMode === "nested") {
|
|
97
|
-
return `Context Mode (${lane} lane): ${
|
|
106
|
+
return `Context Mode (${lane} lane): ${guidance}`;
|
|
98
107
|
}
|
|
99
108
|
return [
|
|
100
109
|
"## Context Mode",
|
|
101
110
|
"",
|
|
102
111
|
`Lane: **${lane} lane**.`,
|
|
103
|
-
|
|
112
|
+
guidance,
|
|
104
113
|
].join("\n");
|
|
105
114
|
}
|
|
106
115
|
const SECTION_SEPARATOR = "\n\n---\n\n";
|
|
@@ -4,6 +4,8 @@ import { atomicWriteSync } from "./atomic-write.js";
|
|
|
4
4
|
import { gsdRoot, relSliceFile, relTaskFile, resolveSliceFile, resolveTaskFile, } from "./paths.js";
|
|
5
5
|
import { loadFile, parseTaskPlanMustHaves, countMustHavesMentionedInSummary } from "./files.js";
|
|
6
6
|
import { parseUnitId } from "./unit-id.js";
|
|
7
|
+
import { getTask, isDbAvailable, refreshOpenDatabaseFromDisk } from "./gsd-db.js";
|
|
8
|
+
import { isClosedStatus } from "./status-guards.js";
|
|
7
9
|
// Per-record advisory lock — prevents read-modify-write races between
|
|
8
10
|
// concurrent writers updating disjoint fields of the same runtime record.
|
|
9
11
|
// Within a single Node process this is moot (writeUnitRuntimeRecord is sync),
|
|
@@ -67,6 +69,17 @@ function withRecordLock(recordPath, fn) {
|
|
|
67
69
|
catch { /* best-effort */ }
|
|
68
70
|
}
|
|
69
71
|
}
|
|
72
|
+
export const IN_FLIGHT_RUNTIME_PHASES = new Set([
|
|
73
|
+
"dispatched",
|
|
74
|
+
"wrapup-warning-sent",
|
|
75
|
+
"timeout",
|
|
76
|
+
"finalize-timeout",
|
|
77
|
+
"crashed",
|
|
78
|
+
"paused",
|
|
79
|
+
]);
|
|
80
|
+
export function isInFlightRuntimePhase(phase) {
|
|
81
|
+
return IN_FLIGHT_RUNTIME_PHASES.has(phase);
|
|
82
|
+
}
|
|
70
83
|
function runtimeDir(basePath) {
|
|
71
84
|
return join(gsdRoot(basePath), "runtime", "units");
|
|
72
85
|
}
|
|
@@ -154,6 +167,12 @@ export async function inspectExecuteTaskDurability(basePath, unitId) {
|
|
|
154
167
|
const escapedTid = tid.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
155
168
|
const taskChecked = !!planContent && new RegExp(`^- \\[[xX]\\] \\*\\*${escapedTid}:`, "m").test(planContent);
|
|
156
169
|
const nextActionAdvanced = !new RegExp(`Execute ${tid}\\b`).test(stateContent);
|
|
170
|
+
let dbComplete = false;
|
|
171
|
+
if (isDbAvailable()) {
|
|
172
|
+
refreshOpenDatabaseFromDisk();
|
|
173
|
+
const task = getTask(mid, sid, tid);
|
|
174
|
+
dbComplete = !!task && isClosedStatus(task.status);
|
|
175
|
+
}
|
|
157
176
|
// Must-have coverage: load task plan and count mentions in summary
|
|
158
177
|
let mustHaveCount = 0;
|
|
159
178
|
let mustHavesMentionedInSummary = 0;
|
|
@@ -177,11 +196,14 @@ export async function inspectExecuteTaskDurability(basePath, unitId) {
|
|
|
177
196
|
summaryExists,
|
|
178
197
|
taskChecked,
|
|
179
198
|
nextActionAdvanced,
|
|
199
|
+
dbComplete,
|
|
180
200
|
mustHaveCount,
|
|
181
201
|
mustHavesMentionedInSummary,
|
|
182
202
|
};
|
|
183
203
|
}
|
|
184
204
|
export function formatExecuteTaskRecoveryStatus(status) {
|
|
205
|
+
if (status.dbComplete)
|
|
206
|
+
return "DB task status is closed";
|
|
185
207
|
const missing = [];
|
|
186
208
|
if (!status.summaryExists)
|
|
187
209
|
missing.push(`summary missing (${status.summaryPath})`);
|
|
@@ -22,7 +22,7 @@ import { emitWorktreeCreated, emitWorktreeMerged } from "./worktree-telemetry.js
|
|
|
22
22
|
import { getCollapseCadence, getMilestoneResquash, resquashMilestoneOnMain } from "./slice-cadence.js";
|
|
23
23
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
24
24
|
import { resolveWorktreeProjectRoot, normalizeWorktreePathForCompare } from "./worktree-root.js";
|
|
25
|
-
import { claimMilestoneLease, releaseMilestoneLease } from "./db/milestone-leases.js";
|
|
25
|
+
import { claimMilestoneLease, refreshMilestoneLease, releaseMilestoneLease } from "./db/milestone-leases.js";
|
|
26
26
|
// ─── Path Comparison Helper ────────────────────────────────────────────────
|
|
27
27
|
/**
|
|
28
28
|
* Compare two paths for physical identity, tolerating trailing slashes,
|
|
@@ -119,24 +119,40 @@ export class WorktreeResolver {
|
|
|
119
119
|
// milestone (re-entry within the same session).
|
|
120
120
|
if (this.s.workerId) {
|
|
121
121
|
if (this.s.currentMilestoneId === milestoneId && this.s.milestoneLeaseToken !== null) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
122
|
+
const refreshed = refreshMilestoneLease(this.s.workerId, milestoneId, this.s.milestoneLeaseToken);
|
|
123
|
+
if (refreshed) {
|
|
124
|
+
debugLog("WorktreeResolver", {
|
|
125
|
+
action: "enterMilestone",
|
|
126
|
+
milestoneId,
|
|
127
|
+
leaseRefreshed: true,
|
|
128
|
+
fencingToken: this.s.milestoneLeaseToken,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
debugLog("WorktreeResolver", {
|
|
133
|
+
action: "enterMilestone",
|
|
134
|
+
milestoneId,
|
|
135
|
+
staleLeaseToken: this.s.milestoneLeaseToken,
|
|
136
|
+
});
|
|
138
137
|
this.s.milestoneLeaseToken = null;
|
|
139
138
|
}
|
|
139
|
+
}
|
|
140
|
+
// If we held a different milestone, release it first so other
|
|
141
|
+
// workers don't have to wait for TTL.
|
|
142
|
+
if (this.s.currentMilestoneId && this.s.currentMilestoneId !== milestoneId && this.s.milestoneLeaseToken !== null) {
|
|
143
|
+
try {
|
|
144
|
+
releaseMilestoneLease(this.s.workerId, this.s.currentMilestoneId, this.s.milestoneLeaseToken);
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
debugLog("WorktreeResolver", {
|
|
148
|
+
action: "enterMilestone",
|
|
149
|
+
milestoneId,
|
|
150
|
+
releasePriorLeaseError: err instanceof Error ? err.message : String(err),
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
this.s.milestoneLeaseToken = null;
|
|
154
|
+
}
|
|
155
|
+
if (this.s.milestoneLeaseToken === null) {
|
|
140
156
|
try {
|
|
141
157
|
const claim = claimMilestoneLease(this.s.workerId, milestoneId);
|
|
142
158
|
if (claim.ok) {
|