@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 CHANGED
@@ -2049,10 +2049,10 @@ var AISpecBuilder = class {
2049
2049
  return;
2050
2050
  }
2051
2051
  const fsp7 = await import("node:fs/promises");
2052
- const path6 = await import("node:path");
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(path6.dirname(sessionPath), { recursive: true });
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 path6 = [];
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
- path6.unshift(current);
5091
+ path7.unshift(current);
5092
5092
  current = prev.get(current) ?? null;
5093
5093
  }
5094
- return path6;
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 join6 } from "node:path";
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: (path6) => readFile6(path6, "utf8"),
5863
- write: async (path6, content) => {
5864
- await writeFile(path6, content, "utf8");
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 : join6(info.cwd, 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 : join6(info.cwd, 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);
@@ -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.26",
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.26",
31
- "@wrongstack/kanban": "1.0.26",
32
- "@wrongstack/primitives": "1.0.26",
33
- "@wrongstack/requirement-intake": "1.0.26"
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",