@wrongstack/core 0.7.4 → 0.7.6

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
@@ -5,7 +5,7 @@ import { readFile, readdir, stat, mkdir } from 'fs/promises';
5
5
  import * as path6 from 'path';
6
6
  import { join, extname, relative } from 'path';
7
7
  import * as fs2 from 'fs';
8
- import * as os4 from 'os';
8
+ import * as os5 from 'os';
9
9
  import { execFile, spawn } from 'child_process';
10
10
  import { promisify } from 'util';
11
11
  import { EventEmitter } from 'events';
@@ -93,7 +93,7 @@ async function renameWithRetry(from, to) {
93
93
  if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {
94
94
  throw err;
95
95
  }
96
- await new Promise((resolve5) => setTimeout(resolve5, delays[i]));
96
+ await new Promise((resolve6) => setTimeout(resolve6, delays[i]));
97
97
  }
98
98
  }
99
99
  throw lastErr;
@@ -1048,7 +1048,9 @@ var DefaultSecretVault = class {
1048
1048
  try {
1049
1049
  const buf = fs2.readFileSync(this.keyFile);
1050
1050
  if (buf.length !== KEY_BYTES) {
1051
- throw new Error(`SecretVault: key file ${this.keyFile} has wrong size`);
1051
+ throw new Error(
1052
+ `SecretVault: key file ${this.keyFile} is ${buf.length} bytes (expected ${KEY_BYTES}). Remove it manually to generate a new key.`
1053
+ );
1052
1054
  }
1053
1055
  this.key = buf;
1054
1056
  return this.key;
@@ -1063,7 +1065,9 @@ var DefaultSecretVault = class {
1063
1065
  if (err.code !== "EEXIST") throw err;
1064
1066
  const buf = fs2.readFileSync(this.keyFile);
1065
1067
  if (buf.length !== KEY_BYTES) {
1066
- throw new Error(`SecretVault: key file ${this.keyFile} has wrong size`);
1068
+ throw new Error(
1069
+ `SecretVault: key file ${this.keyFile} is ${buf.length} bytes (expected ${KEY_BYTES}). Remove it manually to generate a new key.`
1070
+ );
1067
1071
  }
1068
1072
  this.key = buf;
1069
1073
  return this.key;
@@ -1124,10 +1128,7 @@ async function rewriteConfigEncrypted(configPath, vault, patch) {
1124
1128
  const encrypted = encryptConfigSecrets(merged, vault);
1125
1129
  await fsp2.mkdir(path6.dirname(configPath), { recursive: true });
1126
1130
  await atomicWrite(configPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
1127
- try {
1128
- await fsp2.chmod(configPath, 384);
1129
- } catch {
1130
- }
1131
+ await restrictFilePermissions(configPath);
1131
1132
  }
1132
1133
  async function migratePlaintextSecrets(configPath, vault) {
1133
1134
  let raw;
@@ -1146,12 +1147,26 @@ async function migratePlaintextSecrets(configPath, vault) {
1146
1147
  const migrated = walkCount(parsed, vault, counter);
1147
1148
  if (counter.n === 0) return { migrated: 0, file: configPath };
1148
1149
  await atomicWrite(configPath, JSON.stringify(migrated, null, 2), { mode: 384 });
1149
- try {
1150
- await fsp2.chmod(configPath, 384);
1151
- } catch {
1152
- }
1150
+ await restrictFilePermissions(configPath);
1153
1151
  return { migrated: counter.n, file: configPath };
1154
1152
  }
1153
+ async function restrictFilePermissions(filePath) {
1154
+ if (process.platform === "win32") {
1155
+ try {
1156
+ const { execFile: execFile2 } = await import('child_process');
1157
+ const { promisify: promisify2 } = await import('util');
1158
+ const execFileAsync = promisify2(execFile2);
1159
+ await execFileAsync("icacls", [filePath, "/inheritance:r", "/grant:r", `${process.env.USERNAME}:(F)`]);
1160
+ } catch {
1161
+ console.warn(`[secret-vault] Could not restrict permissions on ${filePath} \u2014 config file may be readable by other users on this system.`);
1162
+ }
1163
+ } else {
1164
+ try {
1165
+ await fsp2.chmod(filePath, 384);
1166
+ } catch {
1167
+ }
1168
+ }
1169
+ }
1155
1170
  function walkCount(node, vault, counter) {
1156
1171
  if (node === null || node === void 0) return node;
1157
1172
  if (typeof node !== "object") return node;
@@ -2654,7 +2669,7 @@ var InMemoryAgentBridge = class {
2654
2669
  );
2655
2670
  }
2656
2671
  this.inflightGuards.add(correlationId);
2657
- return new Promise((resolve5, reject) => {
2672
+ return new Promise((resolve6, reject) => {
2658
2673
  const timer = setTimeout(() => {
2659
2674
  this.inflightGuards.delete(correlationId);
2660
2675
  this.pendingRequests.delete(correlationId);
@@ -2666,7 +2681,7 @@ var InMemoryAgentBridge = class {
2666
2681
  return;
2667
2682
  }
2668
2683
  this.pendingRequests.set(correlationId, {
2669
- resolve: resolve5,
2684
+ resolve: resolve6,
2670
2685
  reject,
2671
2686
  timer
2672
2687
  });
@@ -3802,7 +3817,7 @@ function projectHash(absRoot) {
3802
3817
  return createHash("sha256").update(path6.resolve(absRoot)).digest("hex").slice(0, 12);
3803
3818
  }
3804
3819
  function resolveWstackPaths(opts) {
3805
- const home = opts.userHome ?? os4.homedir();
3820
+ const home = opts.userHome ?? os5.homedir();
3806
3821
  const globalRoot = opts.globalRoot ?? path6.join(home, ".wrongstack");
3807
3822
  const hash = projectHash(opts.projectRoot);
3808
3823
  const projectDir = path6.join(globalRoot, "projects", hash);
@@ -3825,7 +3840,12 @@ function resolveWstackPaths(opts) {
3825
3840
  projectLocalConfig: path6.join(projectDir, "config.local.json"),
3826
3841
  inProjectAgentsFile: path6.join(opts.projectRoot, ".wrongstack", "AGENTS.md"),
3827
3842
  inProjectSkills: path6.join(opts.projectRoot, ".wrongstack", "skills"),
3828
- projectHash: hash
3843
+ projectHash: hash,
3844
+ projectGoal: path6.join(projectDir, "goal.json"),
3845
+ projectSpecs: path6.join(projectDir, "specs"),
3846
+ projectTaskGraphs: path6.join(projectDir, "task-graphs"),
3847
+ projectSddSession: path6.join(projectDir, "sdd-session.json"),
3848
+ projectPlan: path6.join(projectDir, "plan.json")
3829
3849
  };
3830
3850
  }
3831
3851
 
@@ -4921,7 +4941,7 @@ function walk3(node, vault, transform) {
4921
4941
  if (Array.isArray(node)) {
4922
4942
  return node.map((item) => walk3(item, vault, transform));
4923
4943
  }
4924
- const out = {};
4944
+ const out = /* @__PURE__ */ Object.create(null);
4925
4945
  for (const [k, v] of Object.entries(node)) {
4926
4946
  if (typeof v === "string" && isSecretField2(k)) {
4927
4947
  out[k] = transform(v, k);
@@ -5219,7 +5239,7 @@ var RecoveryLock = class {
5219
5239
  constructor(opts) {
5220
5240
  this.file = path6.join(opts.dir, LOCK_FILE);
5221
5241
  this.pid = opts.pid ?? process.pid;
5222
- this.hostname = opts.hostname ?? os4.hostname();
5242
+ this.hostname = opts.hostname ?? os5.hostname();
5223
5243
  this.maxAgeMs = opts.maxAgeMs ?? DEFAULT_MAX_AGE_MS;
5224
5244
  this.sessionStore = opts.sessionStore;
5225
5245
  this.probe = opts.isPidAlive ?? defaultIsPidAlive;
@@ -6496,8 +6516,8 @@ async function streamProviderToResponse(provider, req, signal, ctx, events) {
6496
6516
  try {
6497
6517
  await Promise.race([
6498
6518
  Promise.resolve(iter.return?.()),
6499
- new Promise((resolve5) => {
6500
- drainTimer = setTimeout(resolve5, 500);
6519
+ new Promise((resolve6) => {
6520
+ drainTimer = setTimeout(resolve6, 500);
6501
6521
  })
6502
6522
  ]);
6503
6523
  } finally {
@@ -6558,7 +6578,7 @@ async function runProviderWithRetry(opts) {
6558
6578
  description
6559
6579
  });
6560
6580
  }
6561
- await new Promise((resolve5, reject) => {
6581
+ await new Promise((resolve6, reject) => {
6562
6582
  let settled = false;
6563
6583
  const onAbort = () => {
6564
6584
  if (settled) return;
@@ -6571,7 +6591,7 @@ async function runProviderWithRetry(opts) {
6571
6591
  settled = true;
6572
6592
  clearTimeout(t2);
6573
6593
  signal.removeEventListener("abort", onAbort);
6574
- resolve5();
6594
+ resolve6();
6575
6595
  }, delay);
6576
6596
  if (signal.aborted) {
6577
6597
  onAbort();
@@ -7500,7 +7520,8 @@ var AutonomousRunner = class {
7500
7520
  init_atomic_write();
7501
7521
  var MAX_JOURNAL_ENTRIES = 500;
7502
7522
  function goalFilePath(projectRoot) {
7503
- return path6.join(projectRoot, ".wrongstack", "goal.json");
7523
+ const hash = createHash("sha256").update(path6.resolve(projectRoot)).digest("hex").slice(0, 12);
7524
+ return path6.join(os5.homedir(), ".wrongstack", "projects", hash, "goal.json");
7504
7525
  }
7505
7526
  async function loadGoal(filePath) {
7506
7527
  let raw;
@@ -8172,7 +8193,7 @@ ${recentJournal}` : "No prior iterations.",
8172
8193
  }
8173
8194
  };
8174
8195
  function sleep(ms) {
8175
- return new Promise((resolve5) => setTimeout(resolve5, ms));
8196
+ return new Promise((resolve6) => setTimeout(resolve6, ms));
8176
8197
  }
8177
8198
 
8178
8199
  // src/coordination/subagent-budget.ts
@@ -8309,12 +8330,12 @@ var SubagentBudget = class _SubagentBudget {
8309
8330
  if (!bus || !bus.hasListenerFor("budget.threshold_reached")) {
8310
8331
  return Promise.resolve("stop");
8311
8332
  }
8312
- return new Promise((resolve5) => {
8333
+ return new Promise((resolve6) => {
8313
8334
  let resolved = false;
8314
8335
  const respond = (d) => {
8315
8336
  if (resolved) return;
8316
8337
  resolved = true;
8317
- resolve5(d);
8338
+ resolve6(d);
8318
8339
  };
8319
8340
  const fallback = setTimeout(
8320
8341
  () => respond("stop"),
@@ -11312,7 +11333,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
11312
11333
  taskIds.map((id) => {
11313
11334
  const cached = this.completedResults.find((r) => r.taskId === id);
11314
11335
  if (cached) return cached;
11315
- return new Promise((resolve5, reject) => {
11336
+ return new Promise((resolve6, reject) => {
11316
11337
  const timeout = setTimeout(() => {
11317
11338
  this.off("task.completed", handler);
11318
11339
  reject(new Error(`awaitTasks timed out waiting for task "${id}"`));
@@ -11321,7 +11342,7 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
11321
11342
  if (result.taskId === id) {
11322
11343
  clearTimeout(timeout);
11323
11344
  this.off("task.completed", handler);
11324
- resolve5(result);
11345
+ resolve6(result);
11325
11346
  }
11326
11347
  };
11327
11348
  this.on("task.completed", handler);
@@ -11722,7 +11743,7 @@ function providerErrorToSubagentError(err, message, cause) {
11722
11743
 
11723
11744
  // src/execution/parallel-eternal-engine.ts
11724
11745
  function sleep2(ms) {
11725
- return new Promise((resolve5) => setTimeout(resolve5, ms));
11746
+ return new Promise((resolve6) => setTimeout(resolve6, ms));
11726
11747
  }
11727
11748
  var GOAL_COMPLETE_MARKER2 = /^\s*\[goal[_\s-]?complete\]\s*$/im;
11728
11749
  var ParallelEternalEngine = class {
@@ -13307,11 +13328,11 @@ var Director = class {
13307
13328
  if (cached) return cached;
13308
13329
  const existing = this.taskWaiters.get(id);
13309
13330
  if (existing) return existing.promise;
13310
- let resolve5;
13331
+ let resolve6;
13311
13332
  const promise = new Promise((res) => {
13312
- resolve5 = res;
13333
+ resolve6 = res;
13313
13334
  });
13314
- this.taskWaiters.set(id, { promise, resolve: resolve5 });
13335
+ this.taskWaiters.set(id, { promise, resolve: resolve6 });
13315
13336
  return promise;
13316
13337
  })
13317
13338
  );
@@ -13627,7 +13648,7 @@ function createDelegateTool(opts) {
13627
13648
  subagentId
13628
13649
  });
13629
13650
  const dir = director;
13630
- const result = await new Promise((resolve5) => {
13651
+ const result = await new Promise((resolve6) => {
13631
13652
  let settled = false;
13632
13653
  let timer;
13633
13654
  const finish = (value) => {
@@ -13636,7 +13657,7 @@ function createDelegateTool(opts) {
13636
13657
  if (timer) clearTimeout(timer);
13637
13658
  offTool();
13638
13659
  offIter();
13639
- resolve5(value);
13660
+ resolve6(value);
13640
13661
  };
13641
13662
  const arm = () => {
13642
13663
  if (timer) clearTimeout(timer);
@@ -16354,6 +16375,276 @@ function createAutoExecutor(opts) {
16354
16375
  });
16355
16376
  }
16356
16377
 
16378
+ // src/sdd/sdd-task-decomposer.ts
16379
+ var SddTaskDecomposer = class {
16380
+ constructor(tracker, graph, opts = {}) {
16381
+ this.tracker = tracker;
16382
+ this.graph = graph;
16383
+ this.slots = Math.min(16, Math.max(1, opts.parallelSlots ?? 4));
16384
+ }
16385
+ tracker;
16386
+ graph;
16387
+ slots;
16388
+ wave = 0;
16389
+ // -------------------------------------------------------------------
16390
+ // Public API
16391
+ // -------------------------------------------------------------------
16392
+ /**
16393
+ * Return the next batch of runnable tasks.
16394
+ * Returns `allDone: true` when every node is completed.
16395
+ * Returns `deadlocked: true` when no batch can be produced because
16396
+ * all remaining tasks are blocked by failed nodes.
16397
+ */
16398
+ nextBatch() {
16399
+ if (this.isDone()) {
16400
+ return { tasks: [], wave: this.wave, allDone: true, deadlocked: false };
16401
+ }
16402
+ const pending = this.pendingReadyNodes();
16403
+ if (pending.length === 0) {
16404
+ const hasBlockedTasks = this.hasAnyBlockedTasks();
16405
+ return { tasks: [], wave: this.wave, allDone: false, deadlocked: hasBlockedTasks };
16406
+ }
16407
+ const batch = pending.slice(0, this.slots);
16408
+ return { tasks: batch, wave: this.wave, allDone: false, deadlocked: false };
16409
+ }
16410
+ /**
16411
+ * Advance the wave counter after a batch completes.
16412
+ * Call this once per `nextBatch()` result that was fan-out.
16413
+ */
16414
+ acknowledgeBatch(_completedTaskIds) {
16415
+ this.wave++;
16416
+ }
16417
+ /**
16418
+ * True when every node in the graph is completed.
16419
+ * Use this to exit the fan-out loop after `isDone() || deadlocked`.
16420
+ */
16421
+ isDone() {
16422
+ const progress = this.tracker.getProgress();
16423
+ return progress.total > 0 && progress.completed === progress.total;
16424
+ }
16425
+ /**
16426
+ * Total waves produced so far.
16427
+ */
16428
+ getWaveCount() {
16429
+ return this.wave;
16430
+ }
16431
+ // -------------------------------------------------------------------
16432
+ // Internal helpers
16433
+ // -------------------------------------------------------------------
16434
+ /**
16435
+ * Return pending nodes whose blockers are all completed.
16436
+ * Sorted by priority (critical first), then by creation time.
16437
+ */
16438
+ pendingReadyNodes() {
16439
+ const allPending = this.tracker.getAllNodes({ status: ["pending"] });
16440
+ const ready = [];
16441
+ for (const node of allPending) {
16442
+ if (this.tracker.canStart(node.id)) {
16443
+ ready.push(node);
16444
+ }
16445
+ }
16446
+ const priorityRank = {
16447
+ critical: 0,
16448
+ high: 1,
16449
+ medium: 2,
16450
+ low: 3
16451
+ };
16452
+ ready.sort((a, b) => {
16453
+ const pr = priorityRank[a.priority] - priorityRank[b.priority];
16454
+ if (pr !== 0) return pr;
16455
+ return a.createdAt - b.createdAt;
16456
+ });
16457
+ return ready;
16458
+ }
16459
+ /** True when at least one non-completed, non-failed task is blocked. */
16460
+ hasAnyBlockedTasks() {
16461
+ const nodes = this.tracker.getAllNodes({
16462
+ status: ["pending", "in_progress", "blocked"]
16463
+ });
16464
+ return nodes.some((n) => n.status === "blocked");
16465
+ }
16466
+ };
16467
+ var SddParallelRun = class {
16468
+ constructor(opts) {
16469
+ this.opts = opts;
16470
+ this.slots = Math.min(16, Math.max(1, opts.parallelSlots ?? 4));
16471
+ this.timeoutMs = opts.taskTimeoutMs ?? 3e5;
16472
+ this.decomposer = new SddTaskDecomposer(opts.tracker, opts.graph, { parallelSlots: this.slots });
16473
+ }
16474
+ opts;
16475
+ slots;
16476
+ timeoutMs;
16477
+ decomposer;
16478
+ coordinator = null;
16479
+ stopRequested = false;
16480
+ // -------------------------------------------------------------------
16481
+ // Public API
16482
+ // -------------------------------------------------------------------
16483
+ /** Trigger stop — causes run() to abort after the current wave. */
16484
+ stop() {
16485
+ this.stopRequested = true;
16486
+ this.coordinator?.stopAll();
16487
+ }
16488
+ /** Execute all waves until completion or deadlock. Returns final summary. */
16489
+ async run() {
16490
+ this.stopRequested = false;
16491
+ const startTime = Date.now();
16492
+ let totalCompleted = 0;
16493
+ let totalFailed = 0;
16494
+ let totalWaves = 0;
16495
+ this.buildCoordinator();
16496
+ while (!this.stopRequested && !this.decomposer.isDone()) {
16497
+ const batch = this.decomposer.nextBatch();
16498
+ if (batch.deadlocked) {
16499
+ break;
16500
+ }
16501
+ if (batch.tasks.length === 0 && batch.allDone) {
16502
+ break;
16503
+ }
16504
+ const waveResult = await this.executeWave(batch);
16505
+ totalWaves++;
16506
+ totalCompleted += waveResult.successCount;
16507
+ totalFailed += waveResult.failCount;
16508
+ this.decomposer.acknowledgeBatch(batch.tasks.map((t2) => t2.id));
16509
+ this.opts.onWave?.(waveResult);
16510
+ const progress = this.buildProgress();
16511
+ this.opts.onProgress?.(progress);
16512
+ if (this.stopRequested) break;
16513
+ }
16514
+ const finalProgress = this.opts.tracker.getProgress();
16515
+ return {
16516
+ totalWaves,
16517
+ totalCompleted,
16518
+ totalFailed,
16519
+ totalDurationMs: Date.now() - startTime,
16520
+ deadlocked: !this.decomposer.isDone() && this.stopRequested === false,
16521
+ stopRequested: this.stopRequested,
16522
+ finalProgress
16523
+ };
16524
+ }
16525
+ // -------------------------------------------------------------------
16526
+ // Internal
16527
+ // -------------------------------------------------------------------
16528
+ buildCoordinator() {
16529
+ const config = {
16530
+ coordinatorId: `sdd-parallel-${randomUUID().slice(0, 8)}`,
16531
+ maxConcurrent: this.slots,
16532
+ doneCondition: { type: "all_tasks_done" }
16533
+ };
16534
+ this.coordinator = new DefaultMultiAgentCoordinator(config);
16535
+ const runner = makeAgentSubagentRunner({ factory: this.opts.subagentFactory ?? this.defaultFactory() });
16536
+ this.coordinator.setRunner?.(runner);
16537
+ }
16538
+ defaultFactory() {
16539
+ return async (config) => ({
16540
+ agent: this.opts.agent,
16541
+ events: this.opts.agent.events
16542
+ });
16543
+ }
16544
+ async executeWave(batch) {
16545
+ const wave = batch.wave;
16546
+ const tasks = batch.tasks;
16547
+ const waveStart = Date.now();
16548
+ for (const task of tasks) {
16549
+ this.opts.tracker.updateNodeStatus(task.id, "in_progress");
16550
+ }
16551
+ const progress = computeTaskProgress(this.opts.graph);
16552
+ const taskIds = tasks.map(() => randomUUID());
16553
+ const subagentIds = tasks.map((_, i) => `sdd-wave${wave}-${i}`);
16554
+ const directivePreamble = [
16555
+ "\u2550\u2550\u2550 SDD PARALLEL EXECUTION \u2550\u2550\u2550",
16556
+ "",
16557
+ `Wave ${wave + 1} of ~${Math.ceil(progress.total / this.slots)}`,
16558
+ `Graph: ${this.opts.graph.title}`,
16559
+ `Parallel slots: ${tasks.length}`,
16560
+ "",
16561
+ "\u2500\u2500 EXECUTION PROTOCOL \u2500\u2500",
16562
+ "\u2022 Execute the assigned SDD task end-to-end using multiple tool calls.",
16563
+ "\u2022 Mark the task [done] in the tracker when complete.",
16564
+ "\u2022 Do not ask for confirmation.",
16565
+ "\u2022 Keep output concise \u2014 summarize changes, do not transcribe files."
16566
+ ].join("\n");
16567
+ const spawns = subagentIds.map(
16568
+ (subagentId) => this.coordinator.spawn({
16569
+ id: subagentId,
16570
+ name: subagentId,
16571
+ role: "executor",
16572
+ timeoutMs: this.timeoutMs
16573
+ })
16574
+ );
16575
+ const spawnResults = await Promise.all(spawns);
16576
+ if (!spawnResults.every((r) => r.subagentId)) {
16577
+ throw new Error("One or more subagent spawns failed");
16578
+ }
16579
+ const assignPromises = tasks.map((task, i) => {
16580
+ const spec = {
16581
+ id: taskIds[i],
16582
+ description: [
16583
+ directivePreamble,
16584
+ "",
16585
+ `\u2500\u2500 TASK ${i + 1}/${tasks.length} \u2500\u2500`,
16586
+ `[${task.priority.toUpperCase()}] ${task.title}`,
16587
+ "",
16588
+ task.description
16589
+ ].join("\n"),
16590
+ subagentId: subagentIds[i],
16591
+ timeoutMs: this.timeoutMs
16592
+ };
16593
+ return this.coordinator.assign(spec);
16594
+ });
16595
+ await Promise.all(assignPromises);
16596
+ let results;
16597
+ try {
16598
+ results = await this.coordinator.awaitTasks(taskIds);
16599
+ } catch (err) {
16600
+ results = taskIds.map((id) => ({
16601
+ subagentId: "",
16602
+ taskId: id,
16603
+ status: "failed",
16604
+ error: { kind: "unknown", message: String(err), retryable: false },
16605
+ iterations: 0,
16606
+ toolCalls: 0,
16607
+ durationMs: 0
16608
+ }));
16609
+ }
16610
+ const successCount = results.filter((r) => r.status === "success").length;
16611
+ const failCount = results.length - successCount;
16612
+ for (let i = 0; i < results.length; i++) {
16613
+ const result = results[i];
16614
+ const taskId = taskIds[i];
16615
+ if (result.status === "success") {
16616
+ this.opts.tracker.updateNodeStatus(taskId, "completed");
16617
+ } else {
16618
+ const errMsg = result.error?.kind ? `${result.error.kind}: ${result.error.message}` : result.error?.message ?? "unknown error";
16619
+ this.opts.tracker.updateNodeStatus(taskId, "failed", errMsg);
16620
+ }
16621
+ }
16622
+ return {
16623
+ wave,
16624
+ batch,
16625
+ results,
16626
+ successCount,
16627
+ failCount,
16628
+ durationMs: Date.now() - waveStart,
16629
+ stopRequested: this.stopRequested
16630
+ };
16631
+ }
16632
+ buildProgress() {
16633
+ const gp = this.opts.tracker.getProgress();
16634
+ return {
16635
+ wave: this.decomposer.getWaveCount(),
16636
+ total: gp.total,
16637
+ completed: gp.completed,
16638
+ inProgress: gp.inProgress,
16639
+ failed: gp.failed,
16640
+ blocked: gp.blocked,
16641
+ pending: gp.pending,
16642
+ percent: gp.percentComplete,
16643
+ deadlocked: false
16644
+ };
16645
+ }
16646
+ };
16647
+
16357
16648
  // src/observability/metrics.ts
16358
16649
  var RESERVOIR_SIZE = 1024;
16359
16650
  function labelKey(labels) {
@@ -16513,9 +16804,9 @@ var DefaultHealthRegistry = class {
16513
16804
  }
16514
16805
  async runOne(check) {
16515
16806
  let timer = null;
16516
- const timeout = new Promise((resolve5) => {
16807
+ const timeout = new Promise((resolve6) => {
16517
16808
  timer = setTimeout(
16518
- () => resolve5({ status: "unhealthy", detail: `timeout after ${this.timeoutMs}ms` }),
16809
+ () => resolve6({ status: "unhealthy", detail: `timeout after ${this.timeoutMs}ms` }),
16519
16810
  this.timeoutMs
16520
16811
  );
16521
16812
  });
@@ -16754,14 +17045,14 @@ async function startMetricsServer(opts) {
16754
17045
  const { createServer } = await import('http');
16755
17046
  server = createServer(listener);
16756
17047
  }
16757
- await new Promise((resolve5, reject) => {
17048
+ await new Promise((resolve6, reject) => {
16758
17049
  const onError = (err) => {
16759
17050
  server.off("listening", onListening);
16760
17051
  reject(err);
16761
17052
  };
16762
17053
  const onListening = () => {
16763
17054
  server.off("error", onError);
16764
- resolve5();
17055
+ resolve6();
16765
17056
  };
16766
17057
  server.once("error", onError);
16767
17058
  server.once("listening", onListening);
@@ -16773,8 +17064,8 @@ async function startMetricsServer(opts) {
16773
17064
  return {
16774
17065
  port: boundPort,
16775
17066
  url: `${protocol}://${host}:${boundPort}${path26}`,
16776
- close: () => new Promise((resolve5, reject) => {
16777
- server.close((err) => err ? reject(err) : resolve5());
17067
+ close: () => new Promise((resolve6, reject) => {
17068
+ server.close((err) => err ? reject(err) : resolve6());
16778
17069
  })
16779
17070
  };
16780
17071
  }
@@ -17438,7 +17729,7 @@ async function downloadGitHubTarball(parsed) {
17438
17729
  `Tarball too large (${(Number.parseInt(contentLength, 10) / 1024 / 1024).toFixed(1)}MB). Max: ${MAX_TARBALL_SIZE / 1024 / 1024}MB`
17439
17730
  );
17440
17731
  }
17441
- const tempDir = await fsp2.mkdtemp(path6.join(os4.tmpdir(), "wskill-"));
17732
+ const tempDir = await fsp2.mkdtemp(path6.join(os5.tmpdir(), "wskill-"));
17442
17733
  try {
17443
17734
  if (!response.body) {
17444
17735
  throw new Error("Empty response body from GitHub API");
@@ -19169,7 +19460,7 @@ var SecurityScannerOrchestrator = class {
19169
19460
  const delay = Math.round(policy.delayMs(attempt));
19170
19461
  const status = isProviderErr ? err.status : 0;
19171
19462
  console.warn(`[SecurityScanner] retry ${attempt + 1} after ${delay}ms (status=${status}) \u2014 ${errAsErr.message}`);
19172
- await new Promise((resolve5) => setTimeout(resolve5, delay));
19463
+ await new Promise((resolve6) => setTimeout(resolve6, delay));
19173
19464
  return this.completeWithRetry(provider, request, abortController, attempt + 1);
19174
19465
  }
19175
19466
  }
@@ -20556,12 +20847,12 @@ function makeContinueToNextIterationTool() {
20556
20847
  // src/core/iteration-limit.ts
20557
20848
  function requestLimitExtension(opts) {
20558
20849
  const { events, currentIterations, currentLimit, autoExtend, timeoutMs = 3e4 } = opts;
20559
- return new Promise((resolve5) => {
20850
+ return new Promise((resolve6) => {
20560
20851
  let resolved = false;
20561
20852
  const timerFired = () => {
20562
20853
  if (!resolved) {
20563
20854
  resolved = true;
20564
- resolve5(0);
20855
+ resolve6(0);
20565
20856
  }
20566
20857
  };
20567
20858
  const timer = setTimeout(timerFired, timeoutMs);
@@ -20570,14 +20861,14 @@ function requestLimitExtension(opts) {
20570
20861
  if (!resolved) {
20571
20862
  resolved = true;
20572
20863
  clearTimeout(timer);
20573
- resolve5(0);
20864
+ resolve6(0);
20574
20865
  }
20575
20866
  };
20576
20867
  const grant = (extra) => {
20577
20868
  if (!resolved) {
20578
20869
  resolved = true;
20579
20870
  clearTimeout(timer);
20580
- resolve5(Math.max(0, extra));
20871
+ resolve6(Math.max(0, extra));
20581
20872
  }
20582
20873
  };
20583
20874
  events.emit("iteration.limit_reached", {
@@ -20591,7 +20882,7 @@ function requestLimitExtension(opts) {
20591
20882
  if (!resolved) {
20592
20883
  resolved = true;
20593
20884
  clearTimeout(timer);
20594
- resolve5(100);
20885
+ resolve6(100);
20595
20886
  }
20596
20887
  });
20597
20888
  }
@@ -21137,13 +21428,13 @@ var Agent = class {
21137
21428
  await this.extensions.runAfterToolExecution(this.ctx, outputs);
21138
21429
  }
21139
21430
  waitForConfirm(info) {
21140
- return new Promise((resolve5) => {
21431
+ return new Promise((resolve6) => {
21141
21432
  this.events.emit("tool.confirm_needed", {
21142
21433
  tool: info.tool,
21143
21434
  input: info.input,
21144
21435
  toolUseId: info.toolUseId,
21145
21436
  suggestedPattern: info.suggestedPattern,
21146
- resolve: resolve5
21437
+ resolve: resolve6
21147
21438
  });
21148
21439
  });
21149
21440
  }
@@ -21791,7 +22082,7 @@ summarize it, and let the tool result hold only the summary.`);
21791
22082
  const cached = this.envCacheByRoot.get(ctx.projectRoot);
21792
22083
  if (cached) return cached;
21793
22084
  const today = this.opts.todayIso ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
21794
- const platform2 = `${os4.platform()} ${os4.release()}`;
22085
+ const platform2 = `${os5.platform()} ${os5.release()}`;
21795
22086
  const shell = process.env.SHELL ?? process.env.ComSpec ?? "unknown";
21796
22087
  const node = process.version;
21797
22088
  const isGit = await this.dirExists(path6.join(ctx.projectRoot, ".git"));
@@ -21860,12 +22151,12 @@ ${mem}`);
21860
22151
  }
21861
22152
  }
21862
22153
  async gitStatus(root) {
21863
- return new Promise((resolve5) => {
22154
+ return new Promise((resolve6) => {
21864
22155
  let settled = false;
21865
22156
  const finish = (s) => {
21866
22157
  if (settled) return;
21867
22158
  settled = true;
21868
- resolve5(s);
22159
+ resolve6(s);
21869
22160
  };
21870
22161
  let proc;
21871
22162
  const timer = setTimeout(() => {
@@ -22617,6 +22908,6 @@ function wrapApiForCapabilityCheck(plugin, api, log, enforce = false) {
22617
22908
  });
22618
22909
  }
22619
22910
 
22620
- export { AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, AUDIT_LOG_AGENT, Agent, AgentError, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutonomousRunner, BUG_HUNTER_AGENT, BudgetExceededError, CONTEXT_WINDOW_MODES, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FleetBus, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, FsError, GitignoreUpdater, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, MAX_JOURNAL_ENTRIES, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, ScopedEventBus, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolError, ToolExecutor, ToolRegistry, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, appendJournal, applyRosterBudget, asBlocks, asText, atomicWrite, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, braveSearchServer, buildChildEnv, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, color, compileGlob, compileUserRegex, composeDirectorPrompt, composeSubagentPrompt, computeTaskProgress, context7Server, contextManagerTool, createAutoExecutor, createContextManagerTool, createDefaultPipelines, createDelegateTool, createMcpControlTool, createMessage, createSecuritySlashCommand, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, dispatchAgent, downloadGitHubTarball, emptyGoal, emptyPlan, encryptConfigSecrets, ensureDir, estimateRequestTokens, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, extractRunEnv, filesystemServer, findCriticalPath, formatContextWindowModeList, formatGoal, formatPlan, formatPlanTemplates, formatTodosList, getAgentDefinition, getContextWindowMode, getPlanTemplate, getTemplate, githubServer, goalFilePath, googleMapsServer, isAgentError, isConfigError, isContextWindowModeId, isFsError, isImageBlock, isPluginError, isSessionError, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isWrongStackError, listContextWindowModes, listPlanTemplates, listTemplates, loadDirectorState, loadGoal, loadPlan, loadPlugins, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeAutonomyPromptContributor, makeContinueToNextIterationTool, makeDirectorSessionFactory, makeLLMClassifier, matchAny, matchGlob, migratePlaintextSecrets, miniMaxVisionServer, normalizeToLf, parseContinueDirective, parseSkillRef, projectHash, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, resolveContextWindowPolicy, resolveWstackPaths, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, safeParse, safeStringify, sanitizeJsonString, saveGoal, savePlan, saveTodosCheckpoint, scoreAgents, securitySlashCommand, sentinelServer, setPlanItemStatus, slackServer, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, stripAnsi, summarizeUsage, templateToMarkdown, toStyle, toWrongStackError, topologicalSort, unifiedDiff, unloadPlugins, validateAgainstSchema, wireMetricsToEvents, wrapAsState, zaiVisionServer };
22911
+ export { AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, AUDIT_LOG_AGENT, Agent, AgentError, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutonomousRunner, BUG_HUNTER_AGENT, BudgetExceededError, CONTEXT_WINDOW_MODES, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FleetBus, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, FsError, GitignoreUpdater, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, MAX_JOURNAL_ENTRIES, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, ScopedEventBus, SddParallelRun, SddTaskDecomposer, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolError, ToolExecutor, ToolRegistry, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, appendJournal, applyRosterBudget, asBlocks, asText, atomicWrite, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, braveSearchServer, buildChildEnv, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, color, compileGlob, compileUserRegex, composeDirectorPrompt, composeSubagentPrompt, computeTaskProgress, context7Server, contextManagerTool, createAutoExecutor, createContextManagerTool, createDefaultPipelines, createDelegateTool, createMcpControlTool, createMessage, createSecuritySlashCommand, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, dispatchAgent, downloadGitHubTarball, emptyGoal, emptyPlan, encryptConfigSecrets, ensureDir, estimateRequestTokens, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, extractRunEnv, filesystemServer, findCriticalPath, formatContextWindowModeList, formatGoal, formatPlan, formatPlanTemplates, formatTodosList, getAgentDefinition, getContextWindowMode, getPlanTemplate, getTemplate, githubServer, goalFilePath, googleMapsServer, isAgentError, isConfigError, isContextWindowModeId, isFsError, isImageBlock, isPluginError, isSessionError, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isWrongStackError, listContextWindowModes, listPlanTemplates, listTemplates, loadDirectorState, loadGoal, loadPlan, loadPlugins, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeAutonomyPromptContributor, makeContinueToNextIterationTool, makeDirectorSessionFactory, makeLLMClassifier, matchAny, matchGlob, migratePlaintextSecrets, miniMaxVisionServer, normalizeToLf, parseContinueDirective, parseSkillRef, projectHash, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, resolveContextWindowPolicy, resolveWstackPaths, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, safeParse, safeStringify, sanitizeJsonString, saveGoal, savePlan, saveTodosCheckpoint, scoreAgents, securitySlashCommand, sentinelServer, setPlanItemStatus, slackServer, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, stripAnsi, summarizeUsage, templateToMarkdown, toStyle, toWrongStackError, topologicalSort, unifiedDiff, unloadPlugins, validateAgainstSchema, wireMetricsToEvents, wrapAsState, zaiVisionServer };
22621
22912
  //# sourceMappingURL=index.js.map
22622
22913
  //# sourceMappingURL=index.js.map