@wrongstack/sdd 1.0.26 → 1.0.27
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/dist/index.js +55 -14
- package/dist/sdd-supervisor.d.ts +2 -0
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -2049,10 +2049,10 @@ var AISpecBuilder = class {
|
|
|
2049
2049
|
return;
|
|
2050
2050
|
}
|
|
2051
2051
|
const fsp7 = await import("node:fs/promises");
|
|
2052
|
-
const
|
|
2052
|
+
const path7 = await import("node:path");
|
|
2053
2053
|
const { atomicWrite: atomicWrite4 } = await import("@wrongstack/core/utils");
|
|
2054
2054
|
const sessionPath = expectDefined2(this.sessionPath);
|
|
2055
|
-
await fsp7.mkdir(
|
|
2055
|
+
await fsp7.mkdir(path7.dirname(sessionPath), { recursive: true });
|
|
2056
2056
|
await atomicWrite4(sessionPath, JSON.stringify(snapshot, null, 2));
|
|
2057
2057
|
} catch (error) {
|
|
2058
2058
|
console.warn(
|
|
@@ -5083,15 +5083,15 @@ function computeCriticalPath(graph, _topoOrder, blockedByMap) {
|
|
|
5083
5083
|
maxId = id;
|
|
5084
5084
|
}
|
|
5085
5085
|
}
|
|
5086
|
-
const
|
|
5086
|
+
const path7 = [];
|
|
5087
5087
|
let current = maxId;
|
|
5088
5088
|
const visited = /* @__PURE__ */ new Set();
|
|
5089
5089
|
while (current && !visited.has(current)) {
|
|
5090
5090
|
visited.add(current);
|
|
5091
|
-
|
|
5091
|
+
path7.unshift(current);
|
|
5092
5092
|
current = prev.get(current) ?? null;
|
|
5093
5093
|
}
|
|
5094
|
-
return
|
|
5094
|
+
return path7;
|
|
5095
5095
|
}
|
|
5096
5096
|
function computeParallelGroups(graph, blockedByMap) {
|
|
5097
5097
|
const groups = [];
|
|
@@ -5312,6 +5312,14 @@ var SpecVersioning = class {
|
|
|
5312
5312
|
};
|
|
5313
5313
|
|
|
5314
5314
|
// src/auto-executor.ts
|
|
5315
|
+
function asDependentFirstGraph(graph) {
|
|
5316
|
+
return {
|
|
5317
|
+
...graph,
|
|
5318
|
+
edges: graph.edges.map(
|
|
5319
|
+
(edge) => edge.type === "depends_on" ? { ...edge, from: edge.to, to: edge.from } : edge
|
|
5320
|
+
)
|
|
5321
|
+
};
|
|
5322
|
+
}
|
|
5315
5323
|
var AutoExecutor = class {
|
|
5316
5324
|
opts;
|
|
5317
5325
|
stopped = false;
|
|
@@ -5328,7 +5336,7 @@ var AutoExecutor = class {
|
|
|
5328
5336
|
this.stopped = false;
|
|
5329
5337
|
this.retryMap.clear();
|
|
5330
5338
|
const startTime = Date.now();
|
|
5331
|
-
const critical = analyzeCriticalPath(graph);
|
|
5339
|
+
const critical = analyzeCriticalPath(asDependentFirstGraph(graph));
|
|
5332
5340
|
let completed = 0;
|
|
5333
5341
|
let failed = 0;
|
|
5334
5342
|
const skipped = 0;
|
|
@@ -5501,6 +5509,7 @@ var SddSupervisor = class {
|
|
|
5501
5509
|
const canSplit = Boolean(this.opts.generateSubtasks);
|
|
5502
5510
|
const decision = await this.opts.brain.decide({
|
|
5503
5511
|
id: `sdd-supervisor-${task.id}-${attempts}`,
|
|
5512
|
+
sessionId: this.opts.sessionId,
|
|
5504
5513
|
source: "system",
|
|
5505
5514
|
question: `SDD task "${task.title}" exhausted its retries. How should the run proceed?`,
|
|
5506
5515
|
context: `Error: ${error}
|
|
@@ -5539,6 +5548,28 @@ Supervisor rescues already used: ${attempts}`,
|
|
|
5539
5548
|
|
|
5540
5549
|
// src/verify-task.ts
|
|
5541
5550
|
import { spawn } from "node:child_process";
|
|
5551
|
+
import { accessSync } from "node:fs";
|
|
5552
|
+
import * as path6 from "node:path";
|
|
5553
|
+
import { buildWin32CmdShimInvocation } from "@wrongstack/core/utils";
|
|
5554
|
+
function win32BatchTarget(executable) {
|
|
5555
|
+
if (/\.(?:cmd|bat)$/i.test(executable)) return executable;
|
|
5556
|
+
if (/[\\/]/.test(executable) || path6.extname(executable)) return void 0;
|
|
5557
|
+
const exts = (process.env["PATHEXT"] ?? ".COM;.EXE;.BAT;.CMD").toLowerCase().split(";");
|
|
5558
|
+
for (const dir of (process.env["PATH"] ?? "").split(path6.delimiter)) {
|
|
5559
|
+
if (!dir) continue;
|
|
5560
|
+
for (const ext of exts) {
|
|
5561
|
+
if (!ext) continue;
|
|
5562
|
+
const full = path6.join(dir, `${executable}${ext}`);
|
|
5563
|
+
try {
|
|
5564
|
+
accessSync(full);
|
|
5565
|
+
} catch {
|
|
5566
|
+
continue;
|
|
5567
|
+
}
|
|
5568
|
+
return ext === ".cmd" || ext === ".bat" ? full : void 0;
|
|
5569
|
+
}
|
|
5570
|
+
}
|
|
5571
|
+
return void 0;
|
|
5572
|
+
}
|
|
5542
5573
|
function tokenizeCommand(command) {
|
|
5543
5574
|
const trimmed = command.trim();
|
|
5544
5575
|
if (!trimmed) return void 0;
|
|
@@ -5675,12 +5706,22 @@ function makeCommandVerifier(options = {}) {
|
|
|
5675
5706
|
return { ok: false, reason: `verification command is malformed: ${rawCommand}` };
|
|
5676
5707
|
}
|
|
5677
5708
|
const [executable, ...args] = argv;
|
|
5709
|
+
const batch = process.platform === "win32" ? win32BatchTarget(executable) : void 0;
|
|
5710
|
+
let shim;
|
|
5711
|
+
if (batch) {
|
|
5712
|
+
try {
|
|
5713
|
+
shim = buildWin32CmdShimInvocation(batch, args);
|
|
5714
|
+
} catch (err) {
|
|
5715
|
+
return { ok: false, reason: `verification command refused: ${String(err)}` };
|
|
5716
|
+
}
|
|
5717
|
+
}
|
|
5678
5718
|
return await new Promise((resolve3) => {
|
|
5679
|
-
const child = spawn(executable, args, {
|
|
5719
|
+
const child = spawn(shim?.command ?? executable, shim?.args ?? args, {
|
|
5680
5720
|
cwd: info.cwd,
|
|
5681
5721
|
shell: false,
|
|
5682
5722
|
windowsHide: true,
|
|
5683
|
-
stdio: "ignore"
|
|
5723
|
+
stdio: "ignore",
|
|
5724
|
+
...shim ? { windowsVerbatimArguments: shim.windowsVerbatimArguments } : {}
|
|
5684
5725
|
});
|
|
5685
5726
|
let timedOut = false;
|
|
5686
5727
|
const timer = setTimeout(() => {
|
|
@@ -5856,12 +5897,12 @@ async function decomposeNonAtomicTasks(opts) {
|
|
|
5856
5897
|
|
|
5857
5898
|
// src/conflict-resolver.ts
|
|
5858
5899
|
import { readFile as readFile6, writeFile } from "node:fs/promises";
|
|
5859
|
-
import { isAbsolute as isAbsolute3, join as
|
|
5900
|
+
import { isAbsolute as isAbsolute3, join as join7 } from "node:path";
|
|
5860
5901
|
import { readBundledInstructionText as readBundledInstructionText2, renderInstructionTemplate as renderInstructionTemplate2 } from "@wrongstack/core/utils";
|
|
5861
5902
|
var defaultFileIO = {
|
|
5862
|
-
read: (
|
|
5863
|
-
write: async (
|
|
5864
|
-
await writeFile(
|
|
5903
|
+
read: (path7) => readFile6(path7, "utf8"),
|
|
5904
|
+
write: async (path7, content) => {
|
|
5905
|
+
await writeFile(path7, content, "utf8");
|
|
5865
5906
|
}
|
|
5866
5907
|
};
|
|
5867
5908
|
var START = "<<<<<<<";
|
|
@@ -5905,7 +5946,7 @@ function makePreferSideConflictResolver(side, io = defaultFileIO) {
|
|
|
5905
5946
|
return async function conflictResolver(info) {
|
|
5906
5947
|
if (info.conflictFiles.length === 0) return false;
|
|
5907
5948
|
for (const rel of info.conflictFiles) {
|
|
5908
|
-
const abs = isAbsolute3(rel) ? rel :
|
|
5949
|
+
const abs = isAbsolute3(rel) ? rel : join7(info.cwd, rel);
|
|
5909
5950
|
let content;
|
|
5910
5951
|
try {
|
|
5911
5952
|
content = await io.read(abs);
|
|
@@ -5939,7 +5980,7 @@ function makeLlmConflictResolver(opts) {
|
|
|
5939
5980
|
return async function conflictResolver(info) {
|
|
5940
5981
|
if (info.conflictFiles.length === 0) return false;
|
|
5941
5982
|
for (const rel of info.conflictFiles) {
|
|
5942
|
-
const abs = isAbsolute3(rel) ? rel :
|
|
5983
|
+
const abs = isAbsolute3(rel) ? rel : join7(info.cwd, rel);
|
|
5943
5984
|
let content;
|
|
5944
5985
|
try {
|
|
5945
5986
|
content = await io.read(abs);
|
package/dist/sdd-supervisor.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ import type { SddSubtaskSpec, SddSupervisorVerdict } from './sdd-parallel-run.js
|
|
|
4
4
|
export interface SddSupervisorOptions {
|
|
5
5
|
/** Decision authority (policy/LLM/human). Reuse the session's TOKENS.BrainArbiter. */
|
|
6
6
|
brain: BrainArbiter;
|
|
7
|
+
/** Session that started this run, retained when another tab becomes foreground. */
|
|
8
|
+
sessionId?: string | undefined;
|
|
7
9
|
/**
|
|
8
10
|
* Models to rotate through on a `reassign` verdict (e.g. the run's fallback
|
|
9
11
|
* chain). Omit to drop the reassign option entirely.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/sdd",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.27",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack Spec-Driven Development engine — standalone package extracted from @wrongstack/core. Task graph generation, tracking, execution, lifecycle management, and AI-driven spec building for SDD workflows.",
|
|
6
6
|
"repository": {
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"!dist/**/*.map"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@wrongstack/core": "1.0.
|
|
31
|
-
"@wrongstack/kanban": "1.0.
|
|
32
|
-
"@wrongstack/primitives": "1.0.
|
|
33
|
-
"@wrongstack/requirement-intake": "1.0.
|
|
30
|
+
"@wrongstack/core": "1.0.27",
|
|
31
|
+
"@wrongstack/kanban": "1.0.27",
|
|
32
|
+
"@wrongstack/primitives": "1.0.27",
|
|
33
|
+
"@wrongstack/requirement-intake": "1.0.27"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/node": "^26.5.1",
|