@wrongstack/cli 0.7.6 → 0.7.8

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
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import * as path23 from 'path';
2
+ import * as path24 from 'path';
3
3
  import { join } from 'path';
4
4
  import * as fsp2 from 'fs/promises';
5
5
  import { readdir, readFile } from 'fs/promises';
6
- import { color, DefaultPathResolver, TOKENS, DefaultSystemPromptBuilder, makeAutonomyPromptContributor, ToolRegistry, createContextManagerTool, EventBus, SlashCommandRegistry, createDelegateTool, FLEET_ROSTER, createMcpControlTool, EternalAutonomyEngine, DefaultLogger, DefaultModelsRegistry, ProviderRegistry, InMemoryMetricsSink, wireMetricsToEvents, DefaultHealthRegistry, startMetricsServer, RecoveryLock, DefaultAttachmentStore, QueueStore, Context, loadTodosCheckpoint, attachTodosCheckpoint, loadDirectorState, loadPlan, createDefaultPipelines, AutoCompactionMiddleware, estimateRequestTokens, Agent, loadPlugins, FleetManager, makeDirectorSessionFactory, Director, AutoApprovePermissionPolicy, makeLLMClassifier, resolveWstackPaths, DefaultSecretVault, migratePlaintextSecrets, DefaultConfigLoader, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, atomicWrite, DefaultPluginAPI, makeAgentSubagentRunner, NULL_FLEET_BUS, formatContextWindowModeList, repairToolUseAdjacency, getContextWindowMode, resolveContextWindowPolicy, AGENTS_BY_PHASE, dispatchAgent, formatTodosList, emptyPlan, clearPlan, savePlan, formatPlanTemplates, getPlanTemplate, addPlanItem, formatPlan, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, SpecStore, TaskGraphStore, analyzeCriticalPath, getTemplate, listTemplates, templateToMarkdown, SpecParser, renderSpecAnalysis, AISpecBuilder, DefaultTaskStore, TaskTracker, renderProgress, renderTaskGraph, loadGoal, goalFilePath, summarizeUsage, saveGoal, emptyGoal, buildGoalPreamble, formatGoal, InputBuilder, FsError, ERROR_CODES, projectHash, WrongStackError, defaultOrchestrator, decryptConfigSecrets, encryptConfigSecrets as encryptConfigSecrets$1, SpecVersioning, ParallelEternalEngine, allServers as allServers$1 } from '@wrongstack/core';
6
+ import { color, DefaultPathResolver, TOKENS, DefaultSystemPromptBuilder, makeAutonomyPromptContributor, ToolRegistry, createContextManagerTool, EventBus, SlashCommandRegistry, createDelegateTool, FLEET_ROSTER, createMcpControlTool, EternalAutonomyEngine, DefaultLogger, DefaultModelsRegistry, ProviderRegistry, InMemoryMetricsSink, wireMetricsToEvents, DefaultHealthRegistry, startMetricsServer, RecoveryLock, DefaultAttachmentStore, QueueStore, Context, loadTodosCheckpoint, attachTodosCheckpoint, loadDirectorState, loadPlan, createDefaultPipelines, AutoCompactionMiddleware, estimateRequestTokens, Agent, loadPlugins, FleetManager, makeDirectorSessionFactory, Director, AutoApprovePermissionPolicy, makeLLMClassifier, resolveWstackPaths, DefaultSecretVault, migratePlaintextSecrets, DefaultConfigLoader, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, atomicWrite, DefaultPluginAPI, makeAgentSubagentRunner, NULL_FLEET_BUS, formatContextWindowModeList, repairToolUseAdjacency, getContextWindowMode, resolveContextWindowPolicy, AGENTS_BY_PHASE, dispatchAgent, formatTodosList, emptyPlan, clearPlan, savePlan, formatPlanTemplates, getPlanTemplate, addPlanItem, formatPlan, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, SpecStore, TaskGraphStore, analyzeCriticalPath, getTemplate, listTemplates, templateToMarkdown, SpecParser, renderSpecAnalysis, AISpecBuilder, DefaultTaskStore, TaskTracker, renderProgress, renderTaskGraph, loadGoal, goalFilePath, summarizeUsage, saveGoal, emptyGoal, buildGoalPreamble, formatGoal, pendingBtwCount, setBtwNote, InputBuilder, FsError, ERROR_CODES, projectHash, WrongStackError, defaultOrchestrator, decryptConfigSecrets, encryptConfigSecrets as encryptConfigSecrets$1, SpecVersioning, ParallelEternalEngine, allServers as allServers$1 } from '@wrongstack/core';
7
7
  import { createRequire } from 'module';
8
8
  import * as os6 from 'os';
9
9
  import os6__default from 'os';
@@ -16,6 +16,8 @@ import { buildProviderFactoriesFromRegistry, makeProviderFromConfig, capabilitie
16
16
  import { createDefaultContainer, routeImagesForModel, readClipboardImage } from '@wrongstack/runtime';
17
17
  import { builtinToolsPack, rememberTool, forgetTool } from '@wrongstack/tools';
18
18
  import * as readline from 'readline';
19
+ import * as fs4 from 'fs';
20
+ import { writeFileSync } from 'fs';
19
21
  import { spawn } from 'child_process';
20
22
  import { SkillInstaller } from '@wrongstack/core/skills';
21
23
  import { WrongStackACPServer } from '@wrongstack/acp/agent';
@@ -24,7 +26,6 @@ import { ACP_AGENTS, SubagentBudget } from '@wrongstack/core/coordination';
24
26
  import { allServers } from '@wrongstack/core/infrastructure';
25
27
  import { createToolVisionAdapters } from '@wrongstack/runtime/vision';
26
28
  import { ToolExecutor } from '@wrongstack/core/execution';
27
- import { writeFileSync } from 'fs';
28
29
 
29
30
  var __defProp = Object.defineProperty;
30
31
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -1397,7 +1398,7 @@ function sddHelp() {
1397
1398
  async function gatherProjectContext(projectRoot) {
1398
1399
  const parts = [];
1399
1400
  try {
1400
- const pkgPath = path23.join(projectRoot, "package.json");
1401
+ const pkgPath = path24.join(projectRoot, "package.json");
1401
1402
  const pkgRaw = await fsp2.readFile(pkgPath, "utf8");
1402
1403
  const pkg = JSON.parse(pkgRaw);
1403
1404
  parts.push(`Project: ${String(pkg.name ?? "unknown")}`);
@@ -1413,13 +1414,13 @@ async function gatherProjectContext(projectRoot) {
1413
1414
  } catch {
1414
1415
  }
1415
1416
  try {
1416
- const tsconfigPath = path23.join(projectRoot, "tsconfig.json");
1417
+ const tsconfigPath = path24.join(projectRoot, "tsconfig.json");
1417
1418
  await fsp2.access(tsconfigPath);
1418
1419
  parts.push("Language: TypeScript");
1419
1420
  } catch {
1420
1421
  }
1421
1422
  try {
1422
- const srcDir = path23.join(projectRoot, "src");
1423
+ const srcDir = path24.join(projectRoot, "src");
1423
1424
  const entries = await fsp2.readdir(srcDir, { withFileTypes: true });
1424
1425
  const dirs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
1425
1426
  if (dirs.length > 0) {
@@ -1575,7 +1576,7 @@ __export(update_check_exports, {
1575
1576
  getUpdateNotification: () => getUpdateNotification
1576
1577
  });
1577
1578
  function cachePath(homeFn = defaultHomeDir2) {
1578
- return path23.join(homeFn(), ".wrongstack", "update-cache.json");
1579
+ return path24.join(homeFn(), ".wrongstack", "update-cache.json");
1579
1580
  }
1580
1581
  function currentVersion() {
1581
1582
  const req2 = createRequire(import.meta.url);
@@ -1612,7 +1613,7 @@ async function readCache(homeFn = defaultHomeDir2) {
1612
1613
  }
1613
1614
  async function writeCache(entry, homeFn = defaultHomeDir2) {
1614
1615
  try {
1615
- const dir = path23.dirname(cachePath(homeFn));
1616
+ const dir = path24.dirname(cachePath(homeFn));
1616
1617
  await fsp2.mkdir(dir, { recursive: true });
1617
1618
  await fsp2.writeFile(cachePath(homeFn), JSON.stringify(entry, null, 2), "utf8");
1618
1619
  } catch {
@@ -2216,7 +2217,7 @@ async function runWebUI(opts) {
2216
2217
  return {};
2217
2218
  }
2218
2219
  if (!parsed.providers) return {};
2219
- const keyFile = path23.join(path23.dirname(opts.globalConfigPath), ".key");
2220
+ const keyFile = path24.join(path24.dirname(opts.globalConfigPath), ".key");
2220
2221
  const vault = new DefaultSecretVault$1({ keyFile });
2221
2222
  return decryptConfigSecrets$1(parsed.providers, vault);
2222
2223
  }
@@ -2249,7 +2250,7 @@ async function runWebUI(opts) {
2249
2250
  parsed = {};
2250
2251
  }
2251
2252
  parsed.providers = providers;
2252
- const keyFile = path23.join(path23.dirname(opts.globalConfigPath), ".key");
2253
+ const keyFile = path24.join(path24.dirname(opts.globalConfigPath), ".key");
2253
2254
  const vault = new DefaultSecretVault$1({ keyFile });
2254
2255
  const encrypted = encryptConfigSecrets(parsed, vault);
2255
2256
  await atomicWrite(opts.globalConfigPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
@@ -2453,7 +2454,7 @@ function parseSpawnFlags(input) {
2453
2454
  return { description: rest.trim(), opts };
2454
2455
  }
2455
2456
  async function bootConfig(flags) {
2456
- const cwd = typeof flags["cwd"] === "string" ? path23.resolve(flags["cwd"]) : process.cwd();
2457
+ const cwd = typeof flags["cwd"] === "string" ? path24.resolve(flags["cwd"]) : process.cwd();
2457
2458
  const pathResolver = new DefaultPathResolver(cwd);
2458
2459
  const projectRoot = pathResolver.projectRoot;
2459
2460
  const userHome = os6.homedir();
@@ -2520,7 +2521,7 @@ var ReadlineInputReader = class {
2520
2521
  history = [];
2521
2522
  pending = false;
2522
2523
  constructor(opts = {}) {
2523
- this.historyFile = opts.historyFile ?? path23.join(os6.homedir(), ".wrongstack", "history");
2524
+ this.historyFile = opts.historyFile ?? path24.join(os6.homedir(), ".wrongstack", "history");
2524
2525
  }
2525
2526
  async loadHistory() {
2526
2527
  try {
@@ -2532,7 +2533,7 @@ var ReadlineInputReader = class {
2532
2533
  }
2533
2534
  async saveHistory() {
2534
2535
  try {
2535
- await fsp2.mkdir(path23.dirname(this.historyFile), { recursive: true });
2536
+ await fsp2.mkdir(path24.dirname(this.historyFile), { recursive: true });
2536
2537
  await fsp2.writeFile(this.historyFile, this.history.slice(-1e3).join("\n"));
2537
2538
  } catch {
2538
2539
  }
@@ -2759,20 +2760,20 @@ function assertSafeToDelete(filename, parentDir) {
2759
2760
  if (PROTECTED_BASENAMES.has(filename)) {
2760
2761
  throw new Error(`Refusing to delete protected file: ${filename}`);
2761
2762
  }
2762
- if (filename !== path23.basename(filename)) {
2763
+ if (filename !== path24.basename(filename)) {
2763
2764
  throw new Error(`Refusing to delete path with traversal: ${filename}`);
2764
2765
  }
2765
2766
  if (!filename.startsWith("config.json.") || !filename.endsWith(".bak")) {
2766
2767
  throw new Error(`Refusing to delete unknown file: ${filename}`);
2767
2768
  }
2768
- const resolvedParent = path23.resolve(parentDir);
2769
+ const resolvedParent = path24.resolve(parentDir);
2769
2770
  if (!resolvedParent.endsWith(".wrongstack")) {
2770
2771
  throw new Error(`Unexpected parent directory for bak prune: ${resolvedParent}`);
2771
2772
  }
2772
2773
  }
2773
2774
  async function safeDelete(filePath) {
2774
- const dir = path23.dirname(filePath);
2775
- const filename = path23.basename(filePath);
2775
+ const dir = path24.dirname(filePath);
2776
+ const filename = path24.basename(filePath);
2776
2777
  try {
2777
2778
  assertSafeToDelete(filename, dir);
2778
2779
  await fsp2.unlink(filePath);
@@ -2817,16 +2818,16 @@ function diffSummary(oldCfg, newCfg) {
2817
2818
  }
2818
2819
  var defaultHomeDir = () => os6__default.homedir();
2819
2820
  function historyDir(homeFn = defaultHomeDir) {
2820
- return path23.join(homeFn(), ".wrongstack", "config.history", "entries");
2821
+ return path24.join(homeFn(), ".wrongstack", "config.history", "entries");
2821
2822
  }
2822
2823
  function historyIndexPath(homeFn = defaultHomeDir) {
2823
- return path23.join(homeFn(), ".wrongstack", "config.history", "index.json");
2824
+ return path24.join(homeFn(), ".wrongstack", "config.history", "index.json");
2824
2825
  }
2825
2826
  function configPath(homeFn = defaultHomeDir) {
2826
- return path23.join(homeFn(), ".wrongstack", "config.json");
2827
+ return path24.join(homeFn(), ".wrongstack", "config.json");
2827
2828
  }
2828
2829
  function backupLastPath(homeFn = defaultHomeDir) {
2829
- return path23.join(homeFn(), ".wrongstack", "config.json.last");
2830
+ return path24.join(homeFn(), ".wrongstack", "config.json.last");
2830
2831
  }
2831
2832
  function entryId(ts) {
2832
2833
  return ts.replace(/[:.]/g, "-").slice(0, 19);
@@ -2881,17 +2882,17 @@ async function backupCurrent(homeFn = defaultHomeDir) {
2881
2882
  }
2882
2883
  if (content !== void 0) {
2883
2884
  try {
2884
- const bakPath = path23.join(homeFn(), ".wrongstack", `config.json.${ts}.bak`);
2885
+ const bakPath = path24.join(homeFn(), ".wrongstack", `config.json.${ts}.bak`);
2885
2886
  await atomicWrite(bakPath, content);
2886
2887
  } catch {
2887
2888
  }
2888
2889
  }
2889
2890
  try {
2890
- const dir = path23.join(homeFn(), ".wrongstack");
2891
+ const dir = path24.join(homeFn(), ".wrongstack");
2891
2892
  const files = await fsp2.readdir(dir);
2892
2893
  const baks = files.filter((f) => f.startsWith("config.json.") && f.endsWith(".bak")).sort().reverse();
2893
2894
  for (const f of baks.slice(10)) {
2894
- await safeDelete(path23.join(dir, f));
2895
+ await safeDelete(path24.join(dir, f));
2895
2896
  }
2896
2897
  } catch {
2897
2898
  }
@@ -2909,7 +2910,7 @@ async function appendHistory(oldCfg, newCfg, description, homeFn = defaultHomeDi
2909
2910
  };
2910
2911
  try {
2911
2912
  await fsp2.writeFile(
2912
- path23.join(historyDir(homeFn), `${id}.json`),
2913
+ path24.join(historyDir(homeFn), `${id}.json`),
2913
2914
  JSON.stringify(entry, null, 2),
2914
2915
  "utf8"
2915
2916
  );
@@ -2917,7 +2918,7 @@ async function appendHistory(oldCfg, newCfg, description, homeFn = defaultHomeDi
2917
2918
  throw new FsError({
2918
2919
  message: err instanceof Error ? err.message : String(err),
2919
2920
  code: ERROR_CODES.FS_WRITE_FAILED,
2920
- path: path23.join(historyDir(homeFn), `${id}.json`),
2921
+ path: path24.join(historyDir(homeFn), `${id}.json`),
2921
2922
  cause: err
2922
2923
  });
2923
2924
  }
@@ -2932,7 +2933,7 @@ async function listHistory(homeFn = defaultHomeDir) {
2932
2933
  }
2933
2934
  async function getHistoryEntry(id, homeFn = defaultHomeDir) {
2934
2935
  try {
2935
- const raw = await fsp2.readFile(path23.join(historyDir(homeFn), `${id}.json`), "utf8");
2936
+ const raw = await fsp2.readFile(path24.join(historyDir(homeFn), `${id}.json`), "utf8");
2936
2937
  return JSON.parse(raw);
2937
2938
  } catch {
2938
2939
  return null;
@@ -2992,10 +2993,10 @@ var theme = { primary: color.amber };
2992
2993
  async function saveToGlobalConfig(configPath2, provider, model, homeFn = () => process.env.HOME ?? __require("os").homedir()) {
2993
2994
  try {
2994
2995
  const { atomicWrite: atomicWrite8 } = await import('@wrongstack/core');
2995
- const fs20 = await import('fs/promises');
2996
+ const fs21 = await import('fs/promises');
2996
2997
  let existing = {};
2997
2998
  try {
2998
- const raw = await fs20.readFile(configPath2, "utf8");
2999
+ const raw = await fs21.readFile(configPath2, "utf8");
2999
3000
  existing = JSON.parse(raw);
3000
3001
  } catch {
3001
3002
  }
@@ -3284,6 +3285,7 @@ var GROUPS = [
3284
3285
  items: [
3285
3286
  { key: "Esc (while busy)", blurb: "soft interrupt \u2014 next message carries a STEERING preamble" },
3286
3287
  { key: "/steer <text>", blurb: "mid-flight redirect, works when Esc is eaten by tmux" },
3288
+ { key: "/btw <note>", blurb: "non-aborting nudge \u2014 agent folds it in at its next step" },
3287
3289
  { key: "Ctrl+C \xD7 1 / \xD7 2 / \xD7 3", blurb: "cancel iteration \xB7 force-exit Ink \xB7 hard exit(130)" }
3288
3290
  ]
3289
3291
  },
@@ -3309,7 +3311,8 @@ var GROUPS = [
3309
3311
  ]
3310
3312
  }
3311
3313
  ];
3312
- var HINT_COUNT = GROUPS.reduce((n, g) => n + g.items.length, 0);
3314
+ GROUPS.reduce((n, g) => n + g.items.length, 0);
3315
+ GROUPS.map((g) => g.title);
3313
3316
  function shouldSuppress(flags) {
3314
3317
  if (flags["no-hints"] === true) return true;
3315
3318
  if (flags["hints"] === false) return true;
@@ -3317,22 +3320,41 @@ function shouldSuppress(flags) {
3317
3320
  if (env && env !== "0" && env.toLowerCase() !== "false") return true;
3318
3321
  return false;
3319
3322
  }
3320
- function printLaunchHints(renderer, flags) {
3323
+ var wrap = (n) => (n % GROUPS.length + GROUPS.length) % GROUPS.length;
3324
+ function pickGroupIndex(opts) {
3325
+ if (typeof opts.groupIndex === "number") return wrap(opts.groupIndex);
3326
+ if (opts.cursorFile) {
3327
+ try {
3328
+ let current = 0;
3329
+ try {
3330
+ const parsed = Number.parseInt(fs4.readFileSync(opts.cursorFile, "utf8").trim(), 10);
3331
+ if (Number.isFinite(parsed)) current = wrap(parsed);
3332
+ } catch {
3333
+ }
3334
+ fs4.mkdirSync(path24.dirname(opts.cursorFile), { recursive: true });
3335
+ fs4.writeFileSync(opts.cursorFile, String(wrap(current + 1)));
3336
+ return current;
3337
+ } catch {
3338
+ }
3339
+ }
3340
+ return Math.floor(Math.random() * GROUPS.length);
3341
+ }
3342
+ function printLaunchHints(renderer, flags, opts = {}) {
3321
3343
  if (shouldSuppress(flags)) return;
3344
+ const idx = pickGroupIndex(opts);
3345
+ const group = GROUPS[idx];
3346
+ if (!group) return;
3322
3347
  const lines = [];
3323
3348
  lines.push("");
3324
3349
  lines.push(
3325
- ` ${color.cyan("\u25C6")} ${color.bold(`WrongStack \u2014 ${HINT_COUNT} things you can do here`)}`
3350
+ ` ${color.cyan("\u25C6")} ${color.bold(group.title)} ${color.dim(`(${idx + 1}/${GROUPS.length} \xB7 more each launch)`)}`
3326
3351
  );
3327
- for (const group of GROUPS) {
3328
- lines.push(` ${color.dim("\u2500")} ${color.cyan(group.title)}`);
3329
- for (const item of group.items) {
3330
- lines.push(` ${color.bold(item.key)} ${color.dim("\u2014")} ${color.dim(item.blurb)}`);
3331
- }
3352
+ for (const item of group.items) {
3353
+ lines.push(` ${color.bold(item.key)} ${color.dim("\u2014")} ${color.dim(item.blurb)}`);
3332
3354
  }
3333
3355
  lines.push("");
3334
3356
  lines.push(
3335
- ` ${color.dim(`tip: hide this with ${color.bold("--no-hints")} or ${color.bold("WRONGSTACK_NO_HINTS=1")}`)}`
3357
+ ` ${color.dim(`${color.bold("/help")} lists everything \xB7 hide with ${color.bold("--no-hints")}`)}`
3336
3358
  );
3337
3359
  lines.push("");
3338
3360
  renderer.write(`${lines.join("\n")}
@@ -3351,10 +3373,10 @@ async function detectPackageManager(root, declared) {
3351
3373
  const name = declared.split("@")[0];
3352
3374
  if (name) return name;
3353
3375
  }
3354
- if (await pathExists(path23.join(root, "pnpm-lock.yaml"))) return "pnpm";
3355
- if (await pathExists(path23.join(root, "bun.lockb"))) return "bun";
3356
- if (await pathExists(path23.join(root, "bun.lock"))) return "bun";
3357
- if (await pathExists(path23.join(root, "yarn.lock"))) return "yarn";
3376
+ if (await pathExists(path24.join(root, "pnpm-lock.yaml"))) return "pnpm";
3377
+ if (await pathExists(path24.join(root, "bun.lockb"))) return "bun";
3378
+ if (await pathExists(path24.join(root, "bun.lock"))) return "bun";
3379
+ if (await pathExists(path24.join(root, "yarn.lock"))) return "yarn";
3358
3380
  return "npm";
3359
3381
  }
3360
3382
  function hasUsableScript(scripts, name) {
@@ -3375,7 +3397,7 @@ function parseMakeTargets(makefile) {
3375
3397
  async function detectProjectFacts(root) {
3376
3398
  const facts = { hints: [] };
3377
3399
  try {
3378
- const pkg = JSON.parse(await fsp2.readFile(path23.join(root, "package.json"), "utf8"));
3400
+ const pkg = JSON.parse(await fsp2.readFile(path24.join(root, "package.json"), "utf8"));
3379
3401
  const scripts = pkg.scripts ?? {};
3380
3402
  const pm = await detectPackageManager(root, pkg.packageManager);
3381
3403
  if (hasUsableScript(scripts, "build")) facts.build = `${pm} run build`;
@@ -3389,14 +3411,14 @@ async function detectProjectFacts(root) {
3389
3411
  } catch {
3390
3412
  }
3391
3413
  try {
3392
- if (!await pathExists(path23.join(root, "pyproject.toml"))) throw new Error("not python");
3414
+ if (!await pathExists(path24.join(root, "pyproject.toml"))) throw new Error("not python");
3393
3415
  facts.test ??= "pytest";
3394
3416
  facts.lint ??= "ruff check .";
3395
3417
  facts.hints.push("pyproject.toml");
3396
3418
  } catch {
3397
3419
  }
3398
3420
  try {
3399
- if (!await pathExists(path23.join(root, "go.mod"))) throw new Error("not go");
3421
+ if (!await pathExists(path24.join(root, "go.mod"))) throw new Error("not go");
3400
3422
  facts.build ??= "go build ./...";
3401
3423
  facts.test ??= "go test ./...";
3402
3424
  facts.run ??= "go run .";
@@ -3404,7 +3426,7 @@ async function detectProjectFacts(root) {
3404
3426
  } catch {
3405
3427
  }
3406
3428
  try {
3407
- if (!await pathExists(path23.join(root, "Cargo.toml"))) throw new Error("not rust");
3429
+ if (!await pathExists(path24.join(root, "Cargo.toml"))) throw new Error("not rust");
3408
3430
  facts.build ??= "cargo build";
3409
3431
  facts.test ??= "cargo test";
3410
3432
  facts.lint ??= "cargo clippy";
@@ -3413,7 +3435,7 @@ async function detectProjectFacts(root) {
3413
3435
  } catch {
3414
3436
  }
3415
3437
  try {
3416
- const makefile = await fsp2.readFile(path23.join(root, "Makefile"), "utf8");
3438
+ const makefile = await fsp2.readFile(path24.join(root, "Makefile"), "utf8");
3417
3439
  const targets = parseMakeTargets(makefile);
3418
3440
  facts.build ??= targets.has("build") ? "make build" : "make";
3419
3441
  if (targets.has("test")) facts.test ??= "make test";
@@ -4305,8 +4327,8 @@ function buildInitCommand(opts) {
4305
4327
  name: "init",
4306
4328
  description: "Create or update .wrongstack/AGENTS.md project context for the system prompt.",
4307
4329
  async run(_args, ctx) {
4308
- const dir = path23.join(ctx.projectRoot, ".wrongstack");
4309
- const file = path23.join(dir, "AGENTS.md");
4330
+ const dir = path24.join(ctx.projectRoot, ".wrongstack");
4331
+ const file = path24.join(dir, "AGENTS.md");
4310
4332
  const detected = await detectProjectFacts(ctx.projectRoot);
4311
4333
  const body = renderAgentsTemplate(detected);
4312
4334
  await fsp2.mkdir(dir, { recursive: true });
@@ -4497,18 +4519,18 @@ function stateBadge(state) {
4497
4519
  return color.dim(state);
4498
4520
  }
4499
4521
  }
4500
- async function readConfig(path24) {
4522
+ async function readConfig(path25) {
4501
4523
  try {
4502
- return JSON.parse(await fsp2.readFile(path24, "utf8"));
4524
+ return JSON.parse(await fsp2.readFile(path25, "utf8"));
4503
4525
  } catch {
4504
4526
  return {};
4505
4527
  }
4506
4528
  }
4507
- async function writeConfig(path24, cfg) {
4529
+ async function writeConfig(path25, cfg) {
4508
4530
  const raw = JSON.stringify(cfg, null, 2);
4509
- const tmp = path24 + ".tmp";
4531
+ const tmp = path25 + ".tmp";
4510
4532
  await fsp2.writeFile(tmp, raw, "utf8");
4511
- await fsp2.rename(tmp, path24);
4533
+ await fsp2.rename(tmp, path25);
4512
4534
  }
4513
4535
 
4514
4536
  // src/slash-commands/mcp.ts
@@ -5194,6 +5216,38 @@ ${color.dim("YOLO forced ON. Use /autonomy stop to end. Journal at /goal journal
5194
5216
  }
5195
5217
  };
5196
5218
  }
5219
+ function buildBtwCommand(opts) {
5220
+ return {
5221
+ name: "btw",
5222
+ description: 'Drop a "by the way" note for the running agent without interrupting it \u2014 delivered at the next step',
5223
+ argsHint: "<note>",
5224
+ help: [
5225
+ "/btw <note> Stash a note; the agent reads it at the start of its next",
5226
+ " iteration (between tool calls) without restarting.",
5227
+ "/btw Show how many notes are pending.",
5228
+ "",
5229
+ "Use `/steer` instead when you need to abort the current work immediately."
5230
+ ].join("\n"),
5231
+ async run(args) {
5232
+ const ctx = opts.context;
5233
+ if (!ctx) {
5234
+ return { message: "No active session \u2014 start a turn first, then use /btw to nudge it." };
5235
+ }
5236
+ const text = args.trim();
5237
+ if (!text) {
5238
+ const n = pendingBtwCount(ctx);
5239
+ return {
5240
+ message: n === 0 ? "No notes pending. Usage: /btw <note>" : `${n} note(s) pending \u2014 will reach the agent at its next step.`
5241
+ };
5242
+ }
5243
+ const pending = setBtwNote(ctx, text);
5244
+ return {
5245
+ message: `\u21AF Noted (${pending} pending) \u2014 the agent will fold this in at its next step:
5246
+ ${text}`
5247
+ };
5248
+ }
5249
+ };
5250
+ }
5197
5251
  var KNOWN_VERBS = /* @__PURE__ */ new Set([
5198
5252
  "",
5199
5253
  "show",
@@ -5705,7 +5759,7 @@ var DEFAULTS = {
5705
5759
  cost: true
5706
5760
  };
5707
5761
  function resolveConfigPath() {
5708
- return process.env[CONFIG_ENV] ?? path23.join(process.env.HOME ?? "", ".wrongstack", "statusline.json");
5762
+ return process.env[CONFIG_ENV] ?? path24.join(process.env.HOME ?? "", ".wrongstack", "statusline.json");
5709
5763
  }
5710
5764
  async function loadStatuslineConfig() {
5711
5765
  const p = resolveConfigPath();
@@ -5719,7 +5773,7 @@ async function loadStatuslineConfig() {
5719
5773
  async function saveStatuslineConfig(cfg) {
5720
5774
  const p = resolveConfigPath();
5721
5775
  try {
5722
- await fsp2.mkdir(path23.dirname(p), { recursive: true });
5776
+ await fsp2.mkdir(path24.dirname(p), { recursive: true });
5723
5777
  await atomicWrite(p, JSON.stringify(cfg, null, 2));
5724
5778
  } catch (err) {
5725
5779
  throw new FsError({
@@ -6618,11 +6672,11 @@ When the error confidence is low (< 0.85) or the problem spans multiple files,
6618
6672
  };
6619
6673
  }
6620
6674
  function makeInstaller(opts, projectRoot, global) {
6621
- const globalRoot = path23.join(os6.homedir(), ".wrongstack");
6675
+ const globalRoot = path24.join(os6.homedir(), ".wrongstack");
6622
6676
  return new SkillInstaller({
6623
- manifestPath: path23.join(globalRoot, "installed-skills.json"),
6624
- projectSkillsDir: path23.join(projectRoot, ".wrongstack", "skills"),
6625
- globalSkillsDir: path23.join(globalRoot, "skills"),
6677
+ manifestPath: path24.join(globalRoot, "installed-skills.json"),
6678
+ projectSkillsDir: path24.join(projectRoot, ".wrongstack", "skills"),
6679
+ globalSkillsDir: path24.join(globalRoot, "skills"),
6626
6680
  projectHash: projectHash(projectRoot),
6627
6681
  skillLoader: opts.skillLoader
6628
6682
  });
@@ -6812,6 +6866,7 @@ function buildBuiltinSlashCommands(opts) {
6812
6866
  buildYoloCommand(opts),
6813
6867
  buildAutonomyCommand(opts),
6814
6868
  buildGoalCommand(opts),
6869
+ buildBtwCommand(opts),
6815
6870
  buildModeCommand(opts),
6816
6871
  buildExitCommand(opts),
6817
6872
  buildCommitCommand(),
@@ -6846,13 +6901,13 @@ var MANIFESTS = [
6846
6901
  ];
6847
6902
  async function detectProjectKind(projectRoot) {
6848
6903
  try {
6849
- await fsp2.access(path23.join(projectRoot, ".wrongstack", "AGENTS.md"));
6904
+ await fsp2.access(path24.join(projectRoot, ".wrongstack", "AGENTS.md"));
6850
6905
  return "initialized";
6851
6906
  } catch {
6852
6907
  }
6853
6908
  for (const m of MANIFESTS) {
6854
6909
  try {
6855
- await fsp2.access(path23.join(projectRoot, m));
6910
+ await fsp2.access(path24.join(projectRoot, m));
6856
6911
  return "project";
6857
6912
  } catch {
6858
6913
  }
@@ -6860,8 +6915,8 @@ async function detectProjectKind(projectRoot) {
6860
6915
  return "empty";
6861
6916
  }
6862
6917
  async function scaffoldAgentsMd(projectRoot) {
6863
- const dir = path23.join(projectRoot, ".wrongstack");
6864
- const file = path23.join(dir, "AGENTS.md");
6918
+ const dir = path24.join(projectRoot, ".wrongstack");
6919
+ const file = path24.join(dir, "AGENTS.md");
6865
6920
  const facts = await detectProjectFacts(projectRoot);
6866
6921
  const body = renderAgentsTemplate(facts);
6867
6922
  await fsp2.mkdir(dir, { recursive: true });
@@ -6874,7 +6929,7 @@ async function runProjectCheck(opts) {
6874
6929
  if (kind === "initialized") {
6875
6930
  renderer.write(
6876
6931
  `
6877
- ${color.green("\u2713")} Project initialized ${color.dim(`(${path23.join(projectRoot, ".wrongstack", "AGENTS.md")})`)}
6932
+ ${color.green("\u2713")} Project initialized ${color.dim(`(${path24.join(projectRoot, ".wrongstack", "AGENTS.md")})`)}
6878
6933
  `
6879
6934
  );
6880
6935
  return true;
@@ -6905,7 +6960,7 @@ async function runProjectCheck(opts) {
6905
6960
  }
6906
6961
  return true;
6907
6962
  }
6908
- const gitDir = path23.join(projectRoot, ".git");
6963
+ const gitDir = path24.join(projectRoot, ".git");
6909
6964
  let hasGit = false;
6910
6965
  try {
6911
6966
  await fsp2.access(gitDir);
@@ -7298,14 +7353,14 @@ function summarize(value, name) {
7298
7353
  if (typeof v === "object" && v !== null) {
7299
7354
  const o = v;
7300
7355
  if (name === "edit") {
7301
- const path24 = typeof o["path"] === "string" ? o["path"] : "";
7356
+ const path25 = typeof o["path"] === "string" ? o["path"] : "";
7302
7357
  const reps = typeof o["replacements"] === "number" ? o["replacements"] : 0;
7303
- return `${path24} ${reps} replacement${reps === 1 ? "" : "s"}`.trim();
7358
+ return `${path25} ${reps} replacement${reps === 1 ? "" : "s"}`.trim();
7304
7359
  }
7305
7360
  if (name === "write") {
7306
- const path24 = typeof o["path"] === "string" ? o["path"] : "";
7361
+ const path25 = typeof o["path"] === "string" ? o["path"] : "";
7307
7362
  const bytes = typeof o["bytes"] === "number" ? o["bytes"] : void 0;
7308
- return bytes !== void 0 ? `${path24} ${bytes}B` : path24;
7363
+ return bytes !== void 0 ? `${path25} ${bytes}B` : path25;
7309
7364
  }
7310
7365
  if (typeof o["count"] === "number") {
7311
7366
  return `${o["count"]} match${o["count"] === 1 ? "" : "es"}`;
@@ -8315,7 +8370,7 @@ var doctorCmd = async (_args, deps) => {
8315
8370
  }
8316
8371
  try {
8317
8372
  await fsp2.mkdir(deps.paths.projectSessions, { recursive: true });
8318
- const probe = path23.join(deps.paths.projectSessions, `.probe-${Date.now()}`);
8373
+ const probe = path24.join(deps.paths.projectSessions, `.probe-${Date.now()}`);
8319
8374
  await fsp2.writeFile(probe, "");
8320
8375
  await fsp2.unlink(probe);
8321
8376
  checks.push({ name: "sessions writable", status: "ok", detail: deps.paths.projectSessions });
@@ -8418,8 +8473,8 @@ var exportCmd = async (args, deps) => {
8418
8473
  return 1;
8419
8474
  }
8420
8475
  if (output) {
8421
- await fsp2.mkdir(path23.dirname(path23.resolve(deps.cwd, output)), { recursive: true });
8422
- await fsp2.writeFile(path23.resolve(deps.cwd, output), rendered, "utf8");
8476
+ await fsp2.mkdir(path24.dirname(path24.resolve(deps.cwd, output)), { recursive: true });
8477
+ await fsp2.writeFile(path24.resolve(deps.cwd, output), rendered, "utf8");
8423
8478
  deps.renderer.write(`Wrote ${rendered.length} bytes to ${output}
8424
8479
  `);
8425
8480
  } else {
@@ -8492,8 +8547,8 @@ var initCmd = async (_args, deps) => {
8492
8547
  const vault = new DefaultSecretVault$1({ keyFile: deps.paths.secretsKey });
8493
8548
  const encrypted = encryptConfigSecrets(config, vault);
8494
8549
  await atomicWrite(deps.paths.globalConfig, JSON.stringify(encrypted, null, 2));
8495
- await fsp2.mkdir(path23.join(deps.projectRoot, ".wrongstack"), { recursive: true });
8496
- const agentsFile = path23.join(deps.projectRoot, ".wrongstack", "AGENTS.md");
8550
+ await fsp2.mkdir(path24.join(deps.projectRoot, ".wrongstack"), { recursive: true });
8551
+ const agentsFile = path24.join(deps.projectRoot, ".wrongstack", "AGENTS.md");
8497
8552
  const projectFacts = await detectProjectFacts(deps.projectRoot);
8498
8553
  await atomicWrite(agentsFile, renderAgentsTemplate(projectFacts));
8499
8554
  deps.renderer.writeInfo(`Wrote ${deps.paths.globalConfig}`);
@@ -8799,7 +8854,7 @@ var usageCmd = async (_args, deps) => {
8799
8854
  return 0;
8800
8855
  };
8801
8856
  var projectsCmd = async (_args, deps) => {
8802
- const projectsRoot = path23.join(deps.paths.globalRoot, "projects");
8857
+ const projectsRoot = path24.join(deps.paths.globalRoot, "projects");
8803
8858
  try {
8804
8859
  const entries = await fsp2.readdir(projectsRoot);
8805
8860
  if (entries.length === 0) {
@@ -8809,7 +8864,7 @@ var projectsCmd = async (_args, deps) => {
8809
8864
  for (const hash of entries) {
8810
8865
  try {
8811
8866
  const meta = JSON.parse(
8812
- await fsp2.readFile(path23.join(projectsRoot, hash, "meta.json"), "utf8")
8867
+ await fsp2.readFile(path24.join(projectsRoot, hash, "meta.json"), "utf8")
8813
8868
  );
8814
8869
  deps.renderer.write(
8815
8870
  ` ${color.dim(hash)} ${color.dim(meta.lastSeen ?? "")} ${meta.root ?? "?"}
@@ -8968,7 +9023,7 @@ async function listFleetRuns(deps) {
8968
9023
  }
8969
9024
  const runs = [];
8970
9025
  for (const id of entries) {
8971
- const runDir = path23.join(deps.paths.projectSessions, id);
9026
+ const runDir = path24.join(deps.paths.projectSessions, id);
8972
9027
  let stat3;
8973
9028
  try {
8974
9029
  stat3 = await fsp2.stat(runDir);
@@ -8981,17 +9036,17 @@ async function listFleetRuns(deps) {
8981
9036
  let subagentCount = 0;
8982
9037
  let subagentsDir;
8983
9038
  try {
8984
- await fsp2.access(path23.join(runDir, "fleet.json"));
9039
+ await fsp2.access(path24.join(runDir, "fleet.json"));
8985
9040
  manifest = true;
8986
9041
  } catch {
8987
9042
  }
8988
9043
  try {
8989
- await fsp2.access(path23.join(runDir, "checkpoint.json"));
9044
+ await fsp2.access(path24.join(runDir, "checkpoint.json"));
8990
9045
  checkpoint = true;
8991
9046
  } catch {
8992
9047
  }
8993
9048
  try {
8994
- subagentsDir = path23.join(runDir, "subagents");
9049
+ subagentsDir = path24.join(runDir, "subagents");
8995
9050
  const files = await fsp2.readdir(subagentsDir);
8996
9051
  subagentCount = files.filter((f) => f.endsWith(".jsonl")).length;
8997
9052
  } catch {
@@ -9020,7 +9075,7 @@ async function listFleetRuns(deps) {
9020
9075
  return 0;
9021
9076
  }
9022
9077
  async function showFleetRun(runId, deps) {
9023
- const runDir = path23.join(deps.paths.projectSessions, runId);
9078
+ const runDir = path24.join(deps.paths.projectSessions, runId);
9024
9079
  let stat3;
9025
9080
  try {
9026
9081
  stat3 = await fsp2.stat(runDir);
@@ -9037,7 +9092,7 @@ async function showFleetRun(runId, deps) {
9037
9092
  deps.renderer.write(color.bold(`
9038
9093
  Fleet Run: ${runId}
9039
9094
  `) + "\n");
9040
- const manifestPath = path23.join(runDir, "fleet.json");
9095
+ const manifestPath = path24.join(runDir, "fleet.json");
9041
9096
  let manifestData = null;
9042
9097
  try {
9043
9098
  manifestData = await fsp2.readFile(manifestPath, "utf8");
@@ -9053,7 +9108,7 @@ Fleet Run: ${runId}
9053
9108
  deps.renderer.write(` ${color.dim("\u25CB")} fleet.json \u2014 not found
9054
9109
  `);
9055
9110
  }
9056
- const checkpointPath = path23.join(runDir, "checkpoint.json");
9111
+ const checkpointPath = path24.join(runDir, "checkpoint.json");
9057
9112
  let checkpointData = null;
9058
9113
  try {
9059
9114
  checkpointData = await fsp2.readFile(checkpointPath, "utf8");
@@ -9100,7 +9155,7 @@ Fleet Run: ${runId}
9100
9155
  } catch {
9101
9156
  }
9102
9157
  }
9103
- const subagentsDir = path23.join(runDir, "subagents");
9158
+ const subagentsDir = path24.join(runDir, "subagents");
9104
9159
  let subagentFiles = [];
9105
9160
  try {
9106
9161
  subagentFiles = await fsp2.readdir(subagentsDir);
@@ -9112,7 +9167,7 @@ Fleet Run: ${runId}
9112
9167
  Subagent transcripts (${subagentFiles.length}):
9113
9168
  `);
9114
9169
  for (const f of subagentFiles.sort()) {
9115
- const filePath = path23.join(subagentsDir, f);
9170
+ const filePath = path24.join(subagentsDir, f);
9116
9171
  let size;
9117
9172
  try {
9118
9173
  const s = await fsp2.stat(filePath);
@@ -9129,7 +9184,7 @@ Fleet Run: ${runId}
9129
9184
  ${color.dim("\u25CB")} No subagent transcripts
9130
9185
  `);
9131
9186
  }
9132
- const sharedDir = path23.join(runDir, "shared");
9187
+ const sharedDir = path24.join(runDir, "shared");
9133
9188
  try {
9134
9189
  const files = await fsp2.readdir(sharedDir);
9135
9190
  deps.renderer.write(`
@@ -9296,7 +9351,7 @@ function findSessionId(args) {
9296
9351
  var rewindCmd = async (args, deps) => {
9297
9352
  const flags = parseRewindFlags(args);
9298
9353
  const wpaths = resolveWstackPaths({ projectRoot: deps.projectRoot });
9299
- const sessionsDir = path23.join(wpaths.globalRoot, "sessions");
9354
+ const sessionsDir = path24.join(wpaths.globalRoot, "sessions");
9300
9355
  const rewind = new DefaultSessionRewinder(sessionsDir);
9301
9356
  let sessionId = findSessionId(args);
9302
9357
  if (!sessionId) {
@@ -9533,7 +9588,7 @@ function resolveBundledSkillsDir() {
9533
9588
  try {
9534
9589
  const req2 = createRequire(import.meta.url);
9535
9590
  const corePkg = req2.resolve("@wrongstack/core/package.json");
9536
- return path23.join(path23.dirname(corePkg), "skills");
9591
+ return path24.join(path24.dirname(corePkg), "skills");
9537
9592
  } catch {
9538
9593
  return void 0;
9539
9594
  }
@@ -9664,7 +9719,9 @@ async function boot(argv) {
9664
9719
  flags["no-tui"] = true;
9665
9720
  }
9666
9721
  if (choices.yolo !== config.yolo) config = patchConfig(config, { yolo: choices.yolo });
9667
- printLaunchHints(renderer, flags);
9722
+ printLaunchHints(renderer, flags, {
9723
+ cursorFile: path24.join(wpaths.cacheDir, "hint-cursor")
9724
+ });
9668
9725
  }
9669
9726
  return {
9670
9727
  config,
@@ -10694,7 +10751,7 @@ async function execute(deps) {
10694
10751
  supportsVision,
10695
10752
  attachments,
10696
10753
  effectiveMaxContext,
10697
- projectName: path23.basename(projectRoot) || void 0,
10754
+ projectName: path24.basename(projectRoot) || void 0,
10698
10755
  projectRoot,
10699
10756
  getAutonomy,
10700
10757
  onAutonomy,
@@ -10716,7 +10773,7 @@ async function execute(deps) {
10716
10773
  supportsVision,
10717
10774
  attachments,
10718
10775
  effectiveMaxContext,
10719
- projectName: path23.basename(projectRoot) || void 0,
10776
+ projectName: path24.basename(projectRoot) || void 0,
10720
10777
  getAutonomy,
10721
10778
  onAutonomy,
10722
10779
  getEternalEngine,
@@ -10818,7 +10875,7 @@ var MultiAgentHost = class {
10818
10875
  doneCondition: { type: "all_tasks_done" },
10819
10876
  maxConcurrent: this.opts.maxConcurrent ?? 4
10820
10877
  };
10821
- const defaultScratchpad = this.opts.sharedScratchpadPath || (this.opts.sessionsRoot && this.opts.directorRunId ? path23.join(this.opts.sessionsRoot, this.opts.directorRunId, "shared") : void 0);
10878
+ const defaultScratchpad = this.opts.sharedScratchpadPath || (this.opts.sessionsRoot && this.opts.directorRunId ? path24.join(this.opts.sessionsRoot, this.opts.directorRunId, "shared") : void 0);
10822
10879
  this.director = new Director({
10823
10880
  config: coordinatorConfig,
10824
10881
  manifestPath: this.opts.manifestPath,
@@ -11063,7 +11120,7 @@ var MultiAgentHost = class {
11063
11120
  model: opts?.model,
11064
11121
  tools: opts?.tools
11065
11122
  };
11066
- const transcriptPath = this.sessionFactory ? path23.join(this.sessionFactory.dir, `${subagentConfig.name}.jsonl`) : void 0;
11123
+ const transcriptPath = this.sessionFactory ? path24.join(this.sessionFactory.dir, `${subagentConfig.name}.jsonl`) : void 0;
11067
11124
  const { subagentId, taskId } = await this._spawnAndAssign(subagentConfig);
11068
11125
  this.fleetManager?.addPendingTask(taskId, subagentId, description);
11069
11126
  this.deps.events.emit("subagent.spawned", {
@@ -11206,16 +11263,16 @@ var MultiAgentHost = class {
11206
11263
  if (this.director) return this.director;
11207
11264
  this.opts.directorMode = true;
11208
11265
  if (this.opts.fleetRoot && !this.opts.manifestPath) {
11209
- this.opts.manifestPath = path23.join(this.opts.fleetRoot, "fleet.json");
11266
+ this.opts.manifestPath = path24.join(this.opts.fleetRoot, "fleet.json");
11210
11267
  }
11211
11268
  if (this.opts.fleetRoot && !this.opts.sharedScratchpadPath) {
11212
- this.opts.sharedScratchpadPath = path23.join(this.opts.fleetRoot, "shared");
11269
+ this.opts.sharedScratchpadPath = path24.join(this.opts.fleetRoot, "shared");
11213
11270
  }
11214
11271
  if (this.opts.fleetRoot && !this.opts.sessionsRoot) {
11215
- this.opts.sessionsRoot = path23.join(this.opts.fleetRoot, "subagents");
11272
+ this.opts.sessionsRoot = path24.join(this.opts.fleetRoot, "subagents");
11216
11273
  }
11217
11274
  if (this.opts.fleetRoot && !this.opts.stateCheckpointPath) {
11218
- this.opts.stateCheckpointPath = path23.join(this.opts.fleetRoot, "director-state.json");
11275
+ this.opts.stateCheckpointPath = path24.join(this.opts.fleetRoot, "director-state.json");
11219
11276
  }
11220
11277
  await this.ensureDirector();
11221
11278
  return this.director ?? null;
@@ -11381,11 +11438,11 @@ var SessionStats = class {
11381
11438
  if (e.name === "bash") this.bashCommands++;
11382
11439
  else if (e.name === "fetch") this.fetches++;
11383
11440
  if (!e.ok) return;
11384
- const path24 = typeof input?.path === "string" ? input.path : void 0;
11385
- if (e.name === "read" && path24) this.readPaths.add(path24);
11386
- else if (e.name === "edit" && path24) this.editedPaths.add(path24);
11387
- else if (e.name === "write" && path24) {
11388
- this.writtenPaths.add(path24);
11441
+ const path25 = typeof input?.path === "string" ? input.path : void 0;
11442
+ if (e.name === "read" && path25) this.readPaths.add(path25);
11443
+ else if (e.name === "edit" && path25) this.editedPaths.add(path25);
11444
+ else if (e.name === "write" && path25) {
11445
+ this.writtenPaths.add(path25);
11389
11446
  const content = typeof input?.content === "string" ? input.content : "";
11390
11447
  this.bytesWritten += Buffer.byteLength(content, "utf8");
11391
11448
  }
@@ -11673,7 +11730,7 @@ function setupMetrics(params) {
11673
11730
  const dumpMetrics = () => {
11674
11731
  if (!metricsSink) return;
11675
11732
  try {
11676
- const out = path23.join(wpaths.projectSessions, "metrics.json");
11733
+ const out = path24.join(wpaths.projectSessions, "metrics.json");
11677
11734
  const snap = metricsSink.snapshot();
11678
11735
  writeFileSync(out, JSON.stringify(snap, null, 2));
11679
11736
  } catch {
@@ -11864,12 +11921,12 @@ async function setupSession(params) {
11864
11921
  }
11865
11922
  const sessionRef = { current: session };
11866
11923
  await recoveryLock.write(session.id).catch(() => void 0);
11867
- const attachments = new DefaultAttachmentStore({ spoolDir: path23.join(wpaths.projectSessions, session.id, "attachments") });
11868
- const queueStore = new QueueStore({ dir: path23.join(wpaths.projectSessions, session.id) });
11924
+ const attachments = new DefaultAttachmentStore({ spoolDir: path24.join(wpaths.projectSessions, session.id, "attachments") });
11925
+ const queueStore = new QueueStore({ dir: path24.join(wpaths.projectSessions, session.id) });
11869
11926
  const ctxSignal = new AbortController().signal;
11870
11927
  const context = new Context({ systemPrompt, provider, session, signal: ctxSignal, tokenCounter, cwd, projectRoot, model: config.model });
11871
11928
  if (restoredMessages.length > 0) context.state.replaceMessages(restoredMessages);
11872
- const todosCheckpointPath = path23.join(wpaths.projectSessions, `${session.id}.todos.json`);
11929
+ const todosCheckpointPath = path24.join(wpaths.projectSessions, `${session.id}.todos.json`);
11873
11930
  if (resumeId) {
11874
11931
  try {
11875
11932
  const restoredTodos = await loadTodosCheckpoint(todosCheckpointPath);
@@ -11881,13 +11938,13 @@ async function setupSession(params) {
11881
11938
  }
11882
11939
  }
11883
11940
  const detachTodosCheckpoint = attachTodosCheckpoint(context.state, todosCheckpointPath, session.id);
11884
- const planPath = path23.join(wpaths.projectSessions, `${session.id}.plan.json`);
11941
+ const planPath = path24.join(wpaths.projectSessions, `${session.id}.plan.json`);
11885
11942
  context.state.setMeta("plan.path", planPath);
11886
11943
  let dirState;
11887
11944
  if (resumeId) {
11888
11945
  try {
11889
- const fleetRoot = path23.join(wpaths.projectSessions, session.id);
11890
- dirState = await loadDirectorState(path23.join(fleetRoot, "director-state.json"));
11946
+ const fleetRoot = path24.join(wpaths.projectSessions, session.id);
11947
+ dirState = await loadDirectorState(path24.join(fleetRoot, "director-state.json"));
11891
11948
  if (dirState) {
11892
11949
  const tCounts = {};
11893
11950
  for (const t of dirState.tasks) tCounts[t.status] = (tCounts[t.status] ?? 0) + 1;
@@ -11914,7 +11971,7 @@ function resolveBundledSkillsDir2() {
11914
11971
  try {
11915
11972
  const req2 = createRequire(import.meta.url);
11916
11973
  const corePkg = req2.resolve("@wrongstack/core/package.json");
11917
- return path23.join(path23.dirname(corePkg), "skills");
11974
+ return path24.join(path24.dirname(corePkg), "skills");
11918
11975
  } catch {
11919
11976
  return void 0;
11920
11977
  }
@@ -12014,7 +12071,7 @@ async function main(argv) {
12014
12071
  modeId,
12015
12072
  modePrompt,
12016
12073
  modelCapabilities,
12017
- planPath: () => sessionRef.current ? path23.join(wpaths.projectSessions, `${sessionRef.current.id}.plan.json`) : void 0,
12074
+ planPath: () => sessionRef.current ? path24.join(wpaths.projectSessions, `${sessionRef.current.id}.plan.json`) : void 0,
12018
12075
  contributors: [
12019
12076
  // Injects the ETERNAL AUTONOMY block when the user has activated
12020
12077
  // `/autonomy eternal`. Without this, the per-iteration directive
@@ -12213,12 +12270,12 @@ async function main(argv) {
12213
12270
  }
12214
12271
  }
12215
12272
  };
12216
- const fleetRoot = directorMode ? path23.join(wpaths.projectSessions, session.id) : void 0;
12217
- const manifestPath = directorMode ? typeof process.env["WRONGSTACK_FLEET_MANIFEST"] === "string" ? process.env["WRONGSTACK_FLEET_MANIFEST"] : path23.join(fleetRoot, "fleet.json") : void 0;
12218
- const sharedScratchpadPath = directorMode ? path23.join(fleetRoot, "shared") : void 0;
12219
- const subagentSessionsRoot = directorMode ? path23.join(fleetRoot, "subagents") : void 0;
12220
- const stateCheckpointPath = directorMode ? path23.join(fleetRoot, "director-state.json") : void 0;
12221
- const fleetRootForPromotion = path23.join(wpaths.projectSessions, session.id);
12273
+ const fleetRoot = directorMode ? path24.join(wpaths.projectSessions, session.id) : void 0;
12274
+ const manifestPath = directorMode ? typeof process.env["WRONGSTACK_FLEET_MANIFEST"] === "string" ? process.env["WRONGSTACK_FLEET_MANIFEST"] : path24.join(fleetRoot, "fleet.json") : void 0;
12275
+ const sharedScratchpadPath = directorMode ? path24.join(fleetRoot, "shared") : void 0;
12276
+ const subagentSessionsRoot = directorMode ? path24.join(fleetRoot, "subagents") : void 0;
12277
+ const stateCheckpointPath = directorMode ? path24.join(fleetRoot, "director-state.json") : void 0;
12278
+ const fleetRootForPromotion = path24.join(wpaths.projectSessions, session.id);
12222
12279
  const multiAgentHost = new MultiAgentHost(
12223
12280
  {
12224
12281
  container,
@@ -12528,7 +12585,7 @@ async function main(argv) {
12528
12585
  return director.spawn(cfg);
12529
12586
  },
12530
12587
  onFleetLog: async (subagentId, mode) => {
12531
- const subagentsRoot = path23.join(fleetRootForPromotion, "subagents");
12588
+ const subagentsRoot = path24.join(fleetRootForPromotion, "subagents");
12532
12589
  let runDirs;
12533
12590
  try {
12534
12591
  runDirs = await fsp2.readdir(subagentsRoot);
@@ -12537,7 +12594,7 @@ async function main(argv) {
12537
12594
  }
12538
12595
  const found = [];
12539
12596
  for (const runId of runDirs) {
12540
- const runDir = path23.join(subagentsRoot, runId);
12597
+ const runDir = path24.join(subagentsRoot, runId);
12541
12598
  let files;
12542
12599
  try {
12543
12600
  files = await fsp2.readdir(runDir);
@@ -12546,7 +12603,7 @@ async function main(argv) {
12546
12603
  }
12547
12604
  for (const f of files) {
12548
12605
  if (!f.endsWith(".jsonl")) continue;
12549
- const full = path23.join(runDir, f);
12606
+ const full = path24.join(runDir, f);
12550
12607
  try {
12551
12608
  const stat3 = await fsp2.stat(full);
12552
12609
  found.push({
@@ -12643,7 +12700,7 @@ async function main(argv) {
12643
12700
  }
12644
12701
  const dir = await multiAgentHost.ensureDirector();
12645
12702
  if (!dir) return "Director is not available.";
12646
- const dirStatePath = path23.join(fleetRootForPromotion, "director-state.json");
12703
+ const dirStatePath = path24.join(fleetRootForPromotion, "director-state.json");
12647
12704
  const prior = await loadDirectorState(dirStatePath);
12648
12705
  if (!prior) {
12649
12706
  return "No prior director-state.json found \u2014 nothing to retry.";
@@ -12714,9 +12771,9 @@ async function main(argv) {
12714
12771
  for (const tool of director2.tools(FLEET_ROSTER)) {
12715
12772
  toolRegistry.register(tool);
12716
12773
  }
12717
- const mp = path23.join(fleetRootForPromotion, "fleet.json");
12718
- const sp = path23.join(fleetRootForPromotion, "shared");
12719
- const ss = path23.join(fleetRootForPromotion, "subagents");
12774
+ const mp = path24.join(fleetRootForPromotion, "fleet.json");
12775
+ const sp = path24.join(fleetRootForPromotion, "shared");
12776
+ const ss = path24.join(fleetRootForPromotion, "subagents");
12720
12777
  const lines = [
12721
12778
  `${color.green("\u2713")} Promoted to director mode.`,
12722
12779
  ` Roster: ${Object.keys(FLEET_ROSTER).join(", ")}`,
@@ -12906,7 +12963,7 @@ Restart WrongStack to load or unload plugin code in this session.`;
12906
12963
  });
12907
12964
  globalThis.__sddParallelRun = run;
12908
12965
  const result = await run.run();
12909
- delete globalThis.__sddParallelRun;
12966
+ globalThis.__sddParallelRun = void 0;
12910
12967
  const lines = [
12911
12968
  `SDD parallel run complete:`,
12912
12969
  ` ${result.totalWaves} waves \xB7 ${result.totalCompleted} done \xB7 ${result.totalFailed} failed`,