gsd-pi 2.82.0-dev.3a3c6509d → 2.82.0-dev.57fd453e4
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 +1 -1
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/gsd/auto/loop.js +14 -1
- package/dist/resources/extensions/gsd/auto/session.js +4 -0
- package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +12 -5
- package/dist/resources/extensions/gsd/auto.js +14 -7
- package/dist/resources/extensions/gsd/markdown-renderer.js +10 -8
- package/dist/resources/extensions/gsd/paths.js +4 -0
- package/dist/resources/extensions/gsd/templates/plan.md +1 -0
- package/dist/resources/extensions/gsd/templates/task-plan.md +6 -0
- package/dist/resources/extensions/gsd/tools/plan-slice.js +3 -5
- package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
- 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 +9 -9
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +3 -3
- 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 +9 -9
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
- package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-9a4db269f9ed63ad.js → webpack-855d616060cb6e59.js} +1 -1
- package/package.json +1 -1
- package/src/resources/extensions/gsd/auto/loop.ts +14 -1
- package/src/resources/extensions/gsd/auto/session.ts +4 -0
- package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +13 -5
- package/src/resources/extensions/gsd/auto.ts +13 -7
- package/src/resources/extensions/gsd/markdown-renderer.ts +10 -8
- package/src/resources/extensions/gsd/paths.ts +5 -0
- package/src/resources/extensions/gsd/templates/plan.md +1 -0
- package/src/resources/extensions/gsd/templates/task-plan.md +6 -0
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +6 -5
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +26 -1
- package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
- package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +3 -4
- package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
- package/dist/web/standalone/.next/static/chunks/8359.7eb3bb8f8ecf4c01.js +0 -10
- package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
- /package/dist/web/standalone/.next/static/{O6femb9LLl3nlgsDaYwS- → ky6ieNHfZXB_oHPklwTJb}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{O6femb9LLl3nlgsDaYwS- → ky6ieNHfZXB_oHPklwTJb}/_ssgManifest.js +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
// GSD-2
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Tests for step-mode completion messages in auto-post-unit.
|
|
2
3
|
|
|
3
4
|
import test from "node:test";
|
|
4
5
|
import assert from "node:assert/strict";
|
|
@@ -31,7 +32,7 @@ test("buildStepCompleteMessage: milestone complete surfaces review guidance", ()
|
|
|
31
32
|
assert.doesNotMatch(msg, /Next:/);
|
|
32
33
|
});
|
|
33
34
|
|
|
34
|
-
test("buildStepCompleteMessage: mid-flight step includes next unit label and /
|
|
35
|
+
test("buildStepCompleteMessage: mid-flight step includes next unit label and /gsd next hint", () => {
|
|
35
36
|
const state = makeState({
|
|
36
37
|
phase: "executing",
|
|
37
38
|
activeSlice: { id: "S01", title: "Core" },
|
|
@@ -40,7 +41,7 @@ test("buildStepCompleteMessage: mid-flight step includes next unit label and /cl
|
|
|
40
41
|
const msg = buildStepCompleteMessage(state);
|
|
41
42
|
assert.match(msg, /Next: Execute T03: Wire notify/);
|
|
42
43
|
assert.match(msg, /\/clear/);
|
|
43
|
-
assert.match(msg, /\/gsd to continue/);
|
|
44
|
+
assert.match(msg, /\/gsd next to continue one step/);
|
|
44
45
|
});
|
|
45
46
|
|
|
46
47
|
test("buildStepCompleteMessage: unknown phase falls back to generic continue label", () => {
|
|
@@ -51,9 +52,9 @@ test("buildStepCompleteMessage: unknown phase falls back to generic continue lab
|
|
|
51
52
|
assert.match(msg, /\/clear/);
|
|
52
53
|
});
|
|
53
54
|
|
|
54
|
-
test("STEP_COMPLETE_FALLBACK_MESSAGE: used when deriveState throws, still points users at /clear + /gsd", () => {
|
|
55
|
+
test("STEP_COMPLETE_FALLBACK_MESSAGE: used when deriveState throws, still points users at /clear + /gsd next", () => {
|
|
55
56
|
assert.match(STEP_COMPLETE_FALLBACK_MESSAGE, /\/clear/);
|
|
56
|
-
assert.match(STEP_COMPLETE_FALLBACK_MESSAGE, /\/gsd/);
|
|
57
|
+
assert.match(STEP_COMPLETE_FALLBACK_MESSAGE, /\/gsd next/);
|
|
57
58
|
});
|
|
58
59
|
|
|
59
60
|
test("shouldReturnStepWizardAfterUnit: terminal milestone completion continues to merge-back path", () => {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* gsdRoot() must return the canonical project .gsd directory when basePath
|
|
5
5
|
* is inside a .gsd/worktrees/<name>/ structure. Worktree-local .gsd folders
|
|
6
|
-
* are
|
|
6
|
+
* are projection roots; runtime/control state stays DB-authoritative at the
|
|
7
7
|
* project .gsd.
|
|
8
8
|
*
|
|
9
9
|
* The bug: when a git worktree lives at /project/.gsd/worktrees/M008/,
|
|
@@ -21,7 +21,7 @@ import { mkdtempSync, realpathSync } from "node:fs";
|
|
|
21
21
|
import { tmpdir } from "node:os";
|
|
22
22
|
import { spawnSync } from "node:child_process";
|
|
23
23
|
|
|
24
|
-
import { gsdRoot, resolveGsdPathContract, _clearGsdRootCache } from "../paths.ts";
|
|
24
|
+
import { gsdProjectionRoot, gsdRoot, resolveGsdPathContract, _clearGsdRootCache } from "../paths.ts";
|
|
25
25
|
|
|
26
26
|
describe("gsdRoot() worktree detection (#2594)", () => {
|
|
27
27
|
let projectRoot: string;
|
|
@@ -76,6 +76,7 @@ describe("gsdRoot() worktree detection (#2594)", () => {
|
|
|
76
76
|
`Expected canonical project .gsd (${projectGsd}), got ${result}.`,
|
|
77
77
|
);
|
|
78
78
|
assert.equal(resolveGsdPathContract(worktreeBase).worktreeGsd, worktreeGsd);
|
|
79
|
+
assert.equal(gsdProjectionRoot(worktreeBase), worktreeGsd);
|
|
79
80
|
});
|
|
80
81
|
|
|
81
82
|
test("returns project .gsd when worktree .gsd does not exist yet", () => {
|
|
@@ -89,6 +90,7 @@ describe("gsdRoot() worktree detection (#2594)", () => {
|
|
|
89
90
|
projectGsd,
|
|
90
91
|
`Expected canonical project .gsd (${projectGsd}), got ${result}.`,
|
|
91
92
|
);
|
|
93
|
+
assert.equal(gsdProjectionRoot(worktreeBase), join(worktreeBase, ".gsd"));
|
|
92
94
|
});
|
|
93
95
|
|
|
94
96
|
test("returns project .gsd when basePath is a real git worktree inside .gsd/worktrees/", () => {
|
|
@@ -116,6 +118,7 @@ describe("gsdRoot() worktree detection (#2594)", () => {
|
|
|
116
118
|
projectGsd,
|
|
117
119
|
`Expected canonical project .gsd (${projectGsd}), got ${gsdResult}`,
|
|
118
120
|
);
|
|
121
|
+
assert.equal(gsdProjectionRoot(worktreeBase), join(worktreeBase, ".gsd"));
|
|
119
122
|
|
|
120
123
|
// Cleanup worktree
|
|
121
124
|
spawnSync("git", ["worktree", "remove", "--force", worktreeBase], {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import test from 'node:test';
|
|
4
4
|
import assert from 'node:assert/strict';
|
|
5
|
-
import { mkdtempSync, mkdirSync, rmSync, readFileSync, existsSync, writeFileSync } from 'node:fs';
|
|
5
|
+
import { mkdtempSync, mkdirSync, rmSync, readFileSync, existsSync, writeFileSync, realpathSync } from 'node:fs';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
7
|
import { tmpdir } from 'node:os';
|
|
8
8
|
|
|
@@ -105,6 +105,31 @@ test('handlePlanSlice writes slice/task planning state and renders plan artifact
|
|
|
105
105
|
}
|
|
106
106
|
});
|
|
107
107
|
|
|
108
|
+
test('handlePlanSlice renders plan artifacts under worktree-local .gsd while using project DB', async () => {
|
|
109
|
+
const base = makeTmpBase();
|
|
110
|
+
const worktree = join(base, '.gsd', 'worktrees', 'M001');
|
|
111
|
+
mkdirSync(join(worktree, '.gsd'), { recursive: true });
|
|
112
|
+
mkdirSync(join(worktree, 'src', 'resources', 'extensions', 'gsd', 'tools'), { recursive: true });
|
|
113
|
+
writeFileSync(join(worktree, 'src', 'resources', 'extensions', 'gsd', 'tools', 'plan-milestone.ts'), '// fixture\n', 'utf-8');
|
|
114
|
+
writeFileSync(join(worktree, 'src', 'resources', 'extensions', 'gsd', 'tools', 'plan-task.ts'), '// fixture\n', 'utf-8');
|
|
115
|
+
openDatabase(join(base, '.gsd', 'gsd.db'));
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
seedParentSlice();
|
|
119
|
+
|
|
120
|
+
const result = await handlePlanSlice(validParams(), worktree);
|
|
121
|
+
assert.ok(!('error' in result), `unexpected error: ${'error' in result ? result.error : ''}`);
|
|
122
|
+
|
|
123
|
+
const worktreePlan = join(worktree, '.gsd', 'milestones', 'M001', 'slices', 'S02', 'S02-PLAN.md');
|
|
124
|
+
const projectPlan = join(base, '.gsd', 'milestones', 'M001', 'slices', 'S02', 'S02-PLAN.md');
|
|
125
|
+
assert.ok(existsSync(worktreePlan), 'slice plan should be rendered to worktree-local .gsd');
|
|
126
|
+
assert.ok(!existsSync(projectPlan), 'slice plan should not be rendered to project .gsd');
|
|
127
|
+
assert.equal(result.planPath, realpathSync(worktreePlan));
|
|
128
|
+
} finally {
|
|
129
|
+
cleanup(base);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
108
133
|
test('handlePlanSlice advances DB-derived state out of planning immediately', async () => {
|
|
109
134
|
const base = makeTmpBase();
|
|
110
135
|
openDatabase(join(base, '.gsd', 'gsd.db'));
|
|
@@ -8,8 +8,32 @@ import assert from "node:assert/strict";
|
|
|
8
8
|
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import { tmpdir } from "node:os";
|
|
11
|
+
import { createRequire } from "node:module";
|
|
11
12
|
import { AutoSession } from "../auto/session.ts";
|
|
12
13
|
import { postUnitPreVerification } from "../auto-post-unit.ts";
|
|
14
|
+
import {
|
|
15
|
+
_getAdapter,
|
|
16
|
+
closeDatabase,
|
|
17
|
+
getTask,
|
|
18
|
+
insertMilestone,
|
|
19
|
+
insertSlice,
|
|
20
|
+
insertTask,
|
|
21
|
+
openDatabase,
|
|
22
|
+
} from "../gsd-db.ts";
|
|
23
|
+
|
|
24
|
+
const _require = createRequire(import.meta.url);
|
|
25
|
+
|
|
26
|
+
function openRawSqliteForTest(dbPath: string): { exec(sql: string): void; close(): void } {
|
|
27
|
+
try {
|
|
28
|
+
const mod = _require("node:sqlite") as { DatabaseSync: new (path: string) => { exec(sql: string): void; close(): void } };
|
|
29
|
+
return new mod.DatabaseSync(dbPath);
|
|
30
|
+
} catch {
|
|
31
|
+
type SqliteCtor = new (path: string) => { exec(sql: string): void; close(): void };
|
|
32
|
+
const mod = _require("better-sqlite3") as SqliteCtor | { default: SqliteCtor };
|
|
33
|
+
const DatabaseCtor: SqliteCtor = typeof mod === "function" ? mod : mod.default;
|
|
34
|
+
return new DatabaseCtor(dbPath);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
13
37
|
|
|
14
38
|
test("postUnitPreVerification rebuilds STATE.md after a completed unit", async () => {
|
|
15
39
|
const base = mkdtempSync(join(tmpdir(), "gsd-post-unit-state-"));
|
|
@@ -47,3 +71,63 @@ test("postUnitPreVerification rebuilds STATE.md after a completed unit", async (
|
|
|
47
71
|
rmSync(base, { recursive: true, force: true });
|
|
48
72
|
}
|
|
49
73
|
});
|
|
74
|
+
|
|
75
|
+
test("postUnitPreVerification refreshes DB before checking execute-task completion", async () => {
|
|
76
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-post-unit-db-refresh-"));
|
|
77
|
+
try {
|
|
78
|
+
const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
|
|
79
|
+
const tasksDir = join(sliceDir, "tasks");
|
|
80
|
+
mkdirSync(tasksDir, { recursive: true });
|
|
81
|
+
writeFileSync(
|
|
82
|
+
join(base, ".gsd", "milestones", "M001", "M001-ROADMAP.md"),
|
|
83
|
+
"# Roadmap\n\n## Slices\n\n- [ ] **S01: Slice** `risk:low` `depends:[]`\n",
|
|
84
|
+
);
|
|
85
|
+
writeFileSync(
|
|
86
|
+
join(sliceDir, "S01-PLAN.md"),
|
|
87
|
+
"# S01: Slice\n\n## Tasks\n\n- [ ] **T01: Do work** `est:30m`\n",
|
|
88
|
+
);
|
|
89
|
+
writeFileSync(
|
|
90
|
+
join(tasksDir, "T01-SUMMARY.md"),
|
|
91
|
+
"---\nid: T01\nparent: S01\nmilestone: M001\n---\n# T01\nDone.\n",
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
const dbPath = join(base, ".gsd", "gsd.db");
|
|
95
|
+
openDatabase(dbPath);
|
|
96
|
+
insertMilestone({ id: "M001", title: "Milestone", status: "active" });
|
|
97
|
+
insertSlice({ id: "S01", milestoneId: "M001", title: "Slice", status: "pending" });
|
|
98
|
+
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Do work", status: "pending" });
|
|
99
|
+
const adapterBefore = _getAdapter();
|
|
100
|
+
|
|
101
|
+
const externalDb = openRawSqliteForTest(dbPath);
|
|
102
|
+
try {
|
|
103
|
+
externalDb.exec("UPDATE tasks SET status = 'complete', completed_at = '2026-05-14T00:00:00.000Z' WHERE milestone_id = 'M001' AND slice_id = 'S01' AND id = 'T01'");
|
|
104
|
+
} finally {
|
|
105
|
+
externalDb.close();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const s = new AutoSession();
|
|
109
|
+
s.basePath = base;
|
|
110
|
+
s.originalBasePath = base;
|
|
111
|
+
s.currentMilestoneId = "M001";
|
|
112
|
+
s.currentUnit = { type: "execute-task", id: "M001/S01/T01", startedAt: Date.now() };
|
|
113
|
+
|
|
114
|
+
const result = await postUnitPreVerification({
|
|
115
|
+
s,
|
|
116
|
+
ctx: { ui: { notify() {} } } as any,
|
|
117
|
+
pi: {} as any,
|
|
118
|
+
buildSnapshotOpts: () => ({}),
|
|
119
|
+
lockBase: () => base,
|
|
120
|
+
stopAuto: async () => {},
|
|
121
|
+
pauseAuto: async () => {},
|
|
122
|
+
updateProgressWidget: () => {},
|
|
123
|
+
}, { skipSettleDelay: true, skipWorktreeSync: true });
|
|
124
|
+
|
|
125
|
+
assert.equal(result, "continue");
|
|
126
|
+
assert.notEqual(_getAdapter(), adapterBefore, "post-unit flow must reopen the DB before deriving state");
|
|
127
|
+
assert.equal(getTask("M001", "S01", "T01")?.status, "complete");
|
|
128
|
+
assert.equal(s.pendingVerificationRetry, null);
|
|
129
|
+
} finally {
|
|
130
|
+
closeDatabase();
|
|
131
|
+
rmSync(base, { recursive: true, force: true });
|
|
132
|
+
}
|
|
133
|
+
});
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Validates planning and task template quality-gate content.
|
|
3
|
+
|
|
1
4
|
import { readFileSync } from "node:fs";
|
|
2
5
|
import { join, dirname } from "node:path";
|
|
3
6
|
import { fileURLToPath } from "node:url";
|
|
@@ -27,11 +30,14 @@ console.log("\n=== Level 1: Templates contain quality gate headings ===");
|
|
|
27
30
|
const plan = loadTemplate("plan");
|
|
28
31
|
assertTrue(plan.includes("## Threat Surface"), "plan.md contains ## Threat Surface");
|
|
29
32
|
assertTrue(plan.includes("## Requirement Impact"), "plan.md contains ## Requirement Impact");
|
|
33
|
+
assertTrue(plan.includes("node --test"), "plan.md instructs using node --test for verification");
|
|
30
34
|
|
|
31
35
|
const taskPlan = loadTemplate("task-plan");
|
|
32
36
|
assertTrue(taskPlan.includes("## Failure Modes"), "task-plan.md contains ## Failure Modes");
|
|
33
37
|
assertTrue(taskPlan.includes("## Load Profile"), "task-plan.md contains ## Load Profile");
|
|
34
38
|
assertTrue(taskPlan.includes("## Negative Tests"), "task-plan.md contains ## Negative Tests");
|
|
39
|
+
assertTrue(taskPlan.includes("node --test"), "task-plan.md instructs using node --test for verification");
|
|
40
|
+
assertTrue(taskPlan.includes("node -e"), "task-plan.md mentions inline node -e as disallowed guidance");
|
|
35
41
|
|
|
36
42
|
const sliceSummary = loadTemplate("slice-summary");
|
|
37
43
|
assertTrue(sliceSummary.includes("## Operational Readiness"), "slice-summary.md contains ## Operational Readiness");
|
|
@@ -165,6 +165,13 @@ test("decideFinalizeResult maps break results to stop decisions", () => {
|
|
|
165
165
|
);
|
|
166
166
|
});
|
|
167
167
|
|
|
168
|
+
test("decideFinalizeResult maps step-wizard breaks to completed step exits", () => {
|
|
169
|
+
assert.deepEqual(
|
|
170
|
+
decideFinalizeResult({ action: "break", reason: "step-wizard" }),
|
|
171
|
+
{ action: "complete-and-break" },
|
|
172
|
+
);
|
|
173
|
+
});
|
|
174
|
+
|
|
168
175
|
test("decideFinalizeResult maps continue and next results", () => {
|
|
169
176
|
assert.deepEqual(
|
|
170
177
|
decideFinalizeResult({ action: "continue" }),
|
|
@@ -27,7 +27,7 @@ import { logWarning } from "../workflow-logger.js";
|
|
|
27
27
|
import { validatePlanningPathScope } from "../planning-path-scope.js";
|
|
28
28
|
import { checkFilePathConsistency, checkTaskOrdering } from "../pre-execution-checks.js";
|
|
29
29
|
import type { TaskRow } from "../db-task-slice-rows.js";
|
|
30
|
-
import { buildTaskFileName,
|
|
30
|
+
import { buildTaskFileName, gsdProjectionRoot } from "../paths.js";
|
|
31
31
|
|
|
32
32
|
export interface PlanSliceTaskInput {
|
|
33
33
|
taskId: string;
|
|
@@ -314,12 +314,11 @@ export async function handlePlanSlice(
|
|
|
314
314
|
}
|
|
315
315
|
|
|
316
316
|
try {
|
|
317
|
-
const tasksDir =
|
|
317
|
+
const tasksDir = join(gsdProjectionRoot(basePath), "milestones", params.milestoneId, "slices", params.sliceId, "tasks");
|
|
318
318
|
for (const taskId of omittedTaskIds) {
|
|
319
|
-
if (!tasksDir) continue;
|
|
320
319
|
const taskPlanPath = join(tasksDir, buildTaskFileName(taskId, "PLAN"));
|
|
321
320
|
if (existsSync(taskPlanPath)) rmSync(taskPlanPath, { force: true });
|
|
322
|
-
const artifactPath = relative(
|
|
321
|
+
const artifactPath = relative(gsdProjectionRoot(basePath), taskPlanPath).replace(/\\/g, "/");
|
|
323
322
|
deleteArtifactByPath(artifactPath);
|
|
324
323
|
}
|
|
325
324
|
|
|
@@ -109,6 +109,7 @@ const MAX_BUFFER_BYTES = 512 * 1024;
|
|
|
109
109
|
* Prevents CPU spinning when deltas arrive faster than regex evaluation (#468).
|
|
110
110
|
*/
|
|
111
111
|
const JS_FALLBACK_CHECK_INTERVAL_MS = 50;
|
|
112
|
+
const JS_FALLBACK_THROTTLE_MIN_BUFFER_BYTES = 4 * 1024;
|
|
112
113
|
|
|
113
114
|
const DEFAULT_SCOPE: TtsrScope = {
|
|
114
115
|
allowText: true,
|
|
@@ -383,7 +384,10 @@ export class TtsrManager {
|
|
|
383
384
|
// streams — regex on a growing buffer is O(rules × buffer_size) (#468).
|
|
384
385
|
const now = Date.now();
|
|
385
386
|
const lastCheck = this.#lastJsCheckAt.get(bufferKey) ?? 0;
|
|
386
|
-
if (
|
|
387
|
+
if (
|
|
388
|
+
nextBuffer.length >= JS_FALLBACK_THROTTLE_MIN_BUFFER_BYTES &&
|
|
389
|
+
now - lastCheck < JS_FALLBACK_CHECK_INTERVAL_MS
|
|
390
|
+
) {
|
|
387
391
|
stopTimer({ bufferSize: nextBuffer.length, throttled: true });
|
|
388
392
|
return [];
|
|
389
393
|
}
|