@wrongstack/cli 0.9.0 → 0.9.1

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,8 +5,8 @@ import * as fsp3 from 'fs/promises';
5
5
  import { readdir, readFile } from 'fs/promises';
6
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, PhaseStore, AutoPhasePlanner, PhaseGraphBuilder, WorktreeManager, PhaseOrchestrator, makeLLMClassifier, resolveWstackPaths, DefaultSecretVault, migratePlaintextSecrets, DefaultConfigLoader, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, atomicWrite, DefaultPluginAPI, makeAgentSubagentRunner, NULL_FLEET_BUS, buildChildEnv, 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
- import * as os6 from 'os';
9
- import os6__default from 'os';
8
+ import * as os4 from 'os';
9
+ import os4__default from 'os';
10
10
  import * as crypto2 from 'crypto';
11
11
  import { randomUUID } from 'crypto';
12
12
  import { DefaultSecretVault as DefaultSecretVault$1, encryptConfigSecrets, isSecretField, decryptConfigSecrets as decryptConfigSecrets$1 } from '@wrongstack/core/security';
@@ -18,7 +18,7 @@ import { builtinToolsPack, rememberTool, forgetTool } from '@wrongstack/tools';
18
18
  import { spawn } from 'child_process';
19
19
  import { SkillInstaller } from '@wrongstack/core/skills';
20
20
  import * as readline from 'readline';
21
- import * as fs9 from 'fs';
21
+ import * as fs10 from 'fs';
22
22
  import { writeFileSync } from 'fs';
23
23
  import { WrongStackACPServer } from '@wrongstack/acp/agent';
24
24
  import { ACP_AGENT_COMMANDS, makeACPSubagentRunner, makeACPSubagentRunnerWithStop } from '@wrongstack/acp';
@@ -1686,7 +1686,7 @@ async function getUpdateNotification(signal, homeFn) {
1686
1686
  var defaultHomeDir2, CACHE_TTL_MS;
1687
1687
  var init_update_check = __esm({
1688
1688
  "src/update-check.ts"() {
1689
- defaultHomeDir2 = () => os6.homedir();
1689
+ defaultHomeDir2 = () => os4.homedir();
1690
1690
  CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
1691
1691
  }
1692
1692
  });
@@ -5824,7 +5824,7 @@ When the error confidence is low (< 0.85) or the problem spans multiple files,
5824
5824
  };
5825
5825
  }
5826
5826
  function makeInstaller(opts, projectRoot, global) {
5827
- const globalRoot = path25.join(os6.homedir(), ".wrongstack");
5827
+ const globalRoot = path25.join(os4.homedir(), ".wrongstack");
5828
5828
  return new SkillInstaller({
5829
5829
  manifestPath: path25.join(globalRoot, "installed-skills.json"),
5830
5830
  projectSkillsDir: path25.join(projectRoot, ".wrongstack", "skills"),
@@ -6185,6 +6185,207 @@ function buildWorktreeCommand(opts) {
6185
6185
  }
6186
6186
  };
6187
6187
  }
6188
+ async function runSettingsMenu(deps) {
6189
+ for (; ; ) {
6190
+ const config = deps.configStore.get();
6191
+ renderSettingsTopMenu(deps.renderer, config);
6192
+ const choice = (await deps.reader.readLine(`
6193
+ ${color.amber("?")} Pick setting to edit: `)).trim().toLowerCase();
6194
+ if (!choice || choice === "q" || choice === "quit" || choice === "exit") {
6195
+ deps.renderer.write(color.dim("Done.\n"));
6196
+ return 0;
6197
+ }
6198
+ switch (choice) {
6199
+ case "1":
6200
+ await editAutoProceedDelay(deps);
6201
+ break;
6202
+ case "2":
6203
+ await editDefaultAutonomy(deps);
6204
+ break;
6205
+ case "d":
6206
+ await showDefaults(deps);
6207
+ break;
6208
+ default:
6209
+ deps.renderer.writeError(`Unknown selection: "${choice}". Try 1, 2, or q to quit.`);
6210
+ }
6211
+ }
6212
+ }
6213
+ function renderSettingsTopMenu(renderer, config) {
6214
+ const delay = config.autonomy?.autoProceedDelayMs ?? 45e3;
6215
+ const defMode = config.autonomy?.defaultMode ?? "off";
6216
+ renderer.write(`
6217
+ ${color.bold("WrongStack")} ${color.dim("\u2014 Settings")}
6218
+
6219
+ `);
6220
+ renderer.write(` ${color.bold("1.")} auto-proceed delay: ${color.cyan(formatDelay(delay))} (in auto mode, wait before continuing)
6221
+ `);
6222
+ renderer.write(` ${color.bold("2.")} default autonomy mode: ${color.cyan(defMode)}
6223
+ `);
6224
+ renderer.write(`
6225
+ ${color.dim("Actions:")}
6226
+ `);
6227
+ renderer.write(` ${color.bold("1")} Edit auto-proceed delay
6228
+ `);
6229
+ renderer.write(` ${color.bold("2")} Edit default autonomy mode
6230
+ `);
6231
+ renderer.write(` ${color.bold("d")} Show all defaults
6232
+ `);
6233
+ renderer.write(` ${color.bold("q")} Quit
6234
+ `);
6235
+ }
6236
+ async function editAutoProceedDelay(deps) {
6237
+ deps.renderer.write(`
6238
+ ${color.bold("Auto-proceed delay")} ${color.dim("\u2014 wait time before auto-continuing in auto mode")}
6239
+ `);
6240
+ deps.renderer.write(color.dim(` Current: ${formatDelay(deps.configStore.get().autonomy?.autoProceedDelayMs ?? 45e3)}
6241
+ `));
6242
+ deps.renderer.write(color.dim(` Enter value in SECONDS (e.g. 30 for 30 seconds, 0 to disable)
6243
+ `));
6244
+ const raw = (await deps.reader.readLine(` ${color.amber("?")} Delay (seconds): `)).trim();
6245
+ if (!raw || raw === "q") return;
6246
+ const seconds = Number.parseFloat(raw);
6247
+ if (Number.isNaN(seconds) || seconds < 0) {
6248
+ deps.renderer.writeError(`Invalid number: "${raw}"`);
6249
+ return;
6250
+ }
6251
+ const ms = Math.round(seconds * 1e3);
6252
+ await mutateAutonomyConfig(deps, (autonomy) => {
6253
+ autonomy.autoProceedDelayMs = ms;
6254
+ });
6255
+ deps.renderer.write(` ${color.green("\u2713")} auto-proceed delay \u2192 ${formatDelay(ms)}
6256
+ `);
6257
+ }
6258
+ async function editDefaultAutonomy(deps) {
6259
+ deps.renderer.write(`
6260
+ ${color.bold("Default Autonomy Mode")}
6261
+
6262
+ `);
6263
+ deps.renderer.write(` ${color.bold("1.")} off \u2014 agent stops after each turn (normal)
6264
+ `);
6265
+ deps.renderer.write(` ${color.bold("2.")} suggest \u2014 shows next-step suggestions
6266
+ `);
6267
+ deps.renderer.write(` ${color.bold("3.")} auto \u2014 self-driving, agent continues automatically
6268
+ `);
6269
+ deps.renderer.write(` ${color.bold("q")} Quit without changing
6270
+ `);
6271
+ const raw = (await deps.reader.readLine(` ${color.amber("?")} Default mode: `)).trim().toLowerCase();
6272
+ if (!raw || raw === "q") return;
6273
+ const modes = ["off", "suggest", "auto"];
6274
+ let selected = null;
6275
+ if (raw === "1") selected = "off";
6276
+ else if (raw === "2") selected = "suggest";
6277
+ else if (raw === "3") selected = "auto";
6278
+ else if (modes.includes(raw)) selected = raw;
6279
+ if (!selected) {
6280
+ deps.renderer.writeError(`Invalid mode: "${raw}". Use off, suggest, or auto.`);
6281
+ return;
6282
+ }
6283
+ await mutateAutonomyConfig(deps, (autonomy) => {
6284
+ autonomy.defaultMode = selected;
6285
+ });
6286
+ deps.renderer.write(` ${color.green("\u2713")} default autonomy \u2192 ${color.bold(selected)}
6287
+ `);
6288
+ }
6289
+ async function showDefaults(deps) {
6290
+ deps.renderer.write(`
6291
+ ${color.bold("Default Values")}
6292
+
6293
+ `);
6294
+ deps.renderer.write(` auto-proceed delay: ${color.cyan("45s")} (WRONGSTACK_AUTO_PROCEED_DELAY_MS env)
6295
+ `);
6296
+ deps.renderer.write(` default autonomy mode: ${color.cyan("off")}
6297
+ `);
6298
+ deps.renderer.write(` iteration timeout: ${color.cyan("5 min")}
6299
+ `);
6300
+ deps.renderer.write(` session timeout: ${color.cyan("30 min")}
6301
+ `);
6302
+ deps.renderer.write(` max iterations: ${color.cyan("100")}
6303
+ `);
6304
+ deps.renderer.write(`
6305
+ ${color.dim(" Press Enter to continue...")}`);
6306
+ await deps.reader.readLine("");
6307
+ }
6308
+ async function mutateAutonomyConfig(deps, mutator) {
6309
+ let raw;
6310
+ let fileExists = true;
6311
+ try {
6312
+ raw = await fsp3.readFile(deps.globalConfigPath, "utf8");
6313
+ } catch (err) {
6314
+ if (err.code !== "ENOENT") {
6315
+ throw new Error(`Could not read ${deps.globalConfigPath}: ${err.message}`);
6316
+ }
6317
+ fileExists = false;
6318
+ raw = "{}";
6319
+ }
6320
+ let parsed;
6321
+ try {
6322
+ parsed = JSON.parse(raw);
6323
+ } catch (err) {
6324
+ if (fileExists) {
6325
+ throw new Error(`Config at ${deps.globalConfigPath} is not valid JSON: ${err.message}`);
6326
+ }
6327
+ parsed = {};
6328
+ }
6329
+ const decrypted = decryptConfigSecrets(parsed, deps.vault);
6330
+ const autonomy = decrypted.autonomy ?? {};
6331
+ mutator(autonomy);
6332
+ decrypted.autonomy = autonomy;
6333
+ const encrypted = encryptConfigSecrets$1(decrypted, deps.vault);
6334
+ await atomicWrite(deps.globalConfigPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
6335
+ deps.configStore.update({ autonomy: decrypted.autonomy });
6336
+ }
6337
+ function formatDelay(ms) {
6338
+ if (ms >= 6e4) return `${Math.round(ms / 6e4)}m`;
6339
+ if (ms === 0) return "disabled";
6340
+ return `${Math.round(ms / 1e3)}s`;
6341
+ }
6342
+
6343
+ // src/slash-commands/settings.ts
6344
+ var noOpVault = {
6345
+ encrypt: (v) => v,
6346
+ decrypt: (v) => v,
6347
+ isEncrypted: () => false
6348
+ };
6349
+ function buildSettingsCommand(opts) {
6350
+ return {
6351
+ name: "settings",
6352
+ description: "Open interactive settings menu (auto-proceed delay, defaults, etc.).",
6353
+ help: [
6354
+ "Usage:",
6355
+ " /settings Open interactive settings menu",
6356
+ "",
6357
+ "Configurable settings:",
6358
+ " auto-proceed delay \u2014 wait time before auto-continuing in auto mode",
6359
+ " default autonomy mode \u2014 startup autonomy mode",
6360
+ "",
6361
+ "Settings are persisted to ~/.wrongstack/config.json."
6362
+ ].join("\n"),
6363
+ async run(args) {
6364
+ const trimmed = args.trim().toLowerCase();
6365
+ if (trimmed === "help" || trimmed === "--help") {
6366
+ return { message: this.help ?? "" };
6367
+ }
6368
+ if (!opts.configStore || !opts.paths) {
6369
+ return { message: `${color.red("Error")} config store not available.` };
6370
+ }
6371
+ if (!opts.reader || !opts.renderer) {
6372
+ return { message: `${color.red("Error")} settings menu requires a terminal (not available in headless mode).` };
6373
+ }
6374
+ try {
6375
+ await runSettingsMenu({
6376
+ renderer: opts.renderer,
6377
+ reader: opts.reader,
6378
+ configStore: opts.configStore,
6379
+ globalConfigPath: opts.paths.globalConfig,
6380
+ vault: noOpVault
6381
+ });
6382
+ return { message: `${color.green("Settings saved.")}` };
6383
+ } catch (err) {
6384
+ return { message: `${color.red("Settings error")}: ${err instanceof Error ? err.message : String(err)}` };
6385
+ }
6386
+ }
6387
+ };
6388
+ }
6188
6389
 
6189
6390
  // src/slash-commands/index.ts
6190
6391
  function buildBuiltinSlashCommands(opts) {
@@ -6229,6 +6430,7 @@ function buildBuiltinSlashCommands(opts) {
6229
6430
  buildFixCommand(opts),
6230
6431
  buildAutoPhaseCommand(opts),
6231
6432
  buildWorktreeCommand(opts),
6433
+ buildSettingsCommand(opts),
6232
6434
  buildStatuslineCommand({
6233
6435
  cwd: opts.cwd,
6234
6436
  hiddenItems: opts.statuslineHiddenItems ?? [],
@@ -6443,7 +6645,7 @@ async function bootConfig(flags) {
6443
6645
  const cwd = typeof flags["cwd"] === "string" ? path25.resolve(flags["cwd"]) : process.cwd();
6444
6646
  const pathResolver = new DefaultPathResolver(cwd);
6445
6647
  const projectRoot = pathResolver.projectRoot;
6446
- const userHome = os6.homedir();
6648
+ const userHome = os4.homedir();
6447
6649
  const wpaths = resolveWstackPaths({ projectRoot, userHome });
6448
6650
  await ensureProjectMeta(wpaths, projectRoot);
6449
6651
  const vault = new DefaultSecretVault({ keyFile: wpaths.secretsKey });
@@ -6507,7 +6709,7 @@ var ReadlineInputReader = class {
6507
6709
  history = [];
6508
6710
  pending = false;
6509
6711
  constructor(opts = {}) {
6510
- this.historyFile = opts.historyFile ?? path25.join(os6.homedir(), ".wrongstack", "history");
6712
+ this.historyFile = opts.historyFile ?? path25.join(os4.homedir(), ".wrongstack", "history");
6511
6713
  }
6512
6714
  async loadHistory() {
6513
6715
  try {
@@ -6737,6 +6939,24 @@ async function buildPickableProviders(modelsRegistry, config) {
6737
6939
  }
6738
6940
  return out;
6739
6941
  }
6942
+ var defaultUidFn = () => os4__default.userInfo().uid;
6943
+ async function getFileUid(filePath) {
6944
+ try {
6945
+ const stat4 = await fsp3.stat(filePath);
6946
+ return stat4.uid;
6947
+ } catch {
6948
+ return void 0;
6949
+ }
6950
+ }
6951
+ async function checkConfigOwnership(homeFn, uidFn = defaultUidFn) {
6952
+ if (os4__default.platform() === "win32") return true;
6953
+ const cfg = configPath(homeFn);
6954
+ const fileUid = await getFileUid(cfg);
6955
+ if (fileUid === void 0) return true;
6956
+ const callerUid = uidFn();
6957
+ if (callerUid === void 0) return true;
6958
+ return fileUid === callerUid;
6959
+ }
6740
6960
  var PROTECTED_BASENAMES = /* @__PURE__ */ new Set([
6741
6961
  "config.json",
6742
6962
  ".key",
@@ -6802,7 +7022,7 @@ function diffSummary(oldCfg, newCfg) {
6802
7022
  }
6803
7023
  return changes.length > 0 ? changes.slice(0, 5).join(", ") : "no changes";
6804
7024
  }
6805
- var defaultHomeDir = () => os6__default.homedir();
7025
+ var defaultHomeDir = () => os4__default.homedir();
6806
7026
  function historyDir(homeFn = defaultHomeDir) {
6807
7027
  return path25.join(homeFn(), ".wrongstack", "config.history", "entries");
6808
7028
  }
@@ -6928,6 +7148,9 @@ async function getHistoryEntry(id, homeFn = defaultHomeDir) {
6928
7148
  async function restoreFromHistory(id, homeFn = defaultHomeDir) {
6929
7149
  const entry = await getHistoryEntry(id, homeFn);
6930
7150
  if (!entry) return { ok: false, backupId: null, error: "History entry not found" };
7151
+ if (!await checkConfigOwnership(homeFn)) {
7152
+ return { ok: false, backupId: null, error: "Operation denied: config file is not owned by current user" };
7153
+ }
6931
7154
  await backupCurrent(homeFn);
6932
7155
  let oldCfg = {};
6933
7156
  try {
@@ -6964,6 +7187,9 @@ async function restoreLast(homeFn = defaultHomeDir) {
6964
7187
  } catch {
6965
7188
  return { ok: false, error: "No prior backup found" };
6966
7189
  }
7190
+ if (!await checkConfigOwnership(homeFn)) {
7191
+ return { ok: false, error: "Operation denied: config file is not owned by current user" };
7192
+ }
6967
7193
  await backupCurrent(homeFn);
6968
7194
  try {
6969
7195
  await atomicWrite(cfg, JSON.stringify(lastCfg, null, 2));
@@ -6978,11 +7204,11 @@ async function restoreLast(homeFn = defaultHomeDir) {
6978
7204
  var theme = { primary: color.amber };
6979
7205
  async function saveToGlobalConfig(configPath2, provider, model, homeFn = () => process.env.HOME ?? __require("os").homedir()) {
6980
7206
  try {
6981
- const { atomicWrite: atomicWrite8 } = await import('@wrongstack/core');
6982
- const fs21 = await import('fs/promises');
7207
+ const { atomicWrite: atomicWrite9 } = await import('@wrongstack/core');
7208
+ const fs22 = await import('fs/promises');
6983
7209
  let existing = {};
6984
7210
  try {
6985
- const raw = await fs21.readFile(configPath2, "utf8");
7211
+ const raw = await fs22.readFile(configPath2, "utf8");
6986
7212
  existing = JSON.parse(raw);
6987
7213
  } catch {
6988
7214
  }
@@ -6990,7 +7216,7 @@ async function saveToGlobalConfig(configPath2, provider, model, homeFn = () => p
6990
7216
  existing.provider = provider;
6991
7217
  existing.model = model;
6992
7218
  await backupCurrent(homeFn);
6993
- await atomicWrite8(configPath2, JSON.stringify(existing, null, 2), { mode: 384 });
7219
+ await atomicWrite9(configPath2, JSON.stringify(existing, null, 2), { mode: 384 });
6994
7220
  try {
6995
7221
  await appendHistory(
6996
7222
  oldCfg,
@@ -7313,12 +7539,12 @@ function pickGroupIndex(opts) {
7313
7539
  try {
7314
7540
  let current = 0;
7315
7541
  try {
7316
- const parsed = Number.parseInt(fs9.readFileSync(opts.cursorFile, "utf8").trim(), 10);
7542
+ const parsed = Number.parseInt(fs10.readFileSync(opts.cursorFile, "utf8").trim(), 10);
7317
7543
  if (Number.isFinite(parsed)) current = wrap(parsed);
7318
7544
  } catch {
7319
7545
  }
7320
- fs9.mkdirSync(path25.dirname(opts.cursorFile), { recursive: true });
7321
- fs9.writeFileSync(opts.cursorFile, String(wrap(current + 1)));
7546
+ fs10.mkdirSync(path25.dirname(opts.cursorFile), { recursive: true });
7547
+ fs10.writeFileSync(opts.cursorFile, String(wrap(current + 1)));
7322
7548
  return current;
7323
7549
  } catch {
7324
7550
  }
@@ -8591,7 +8817,7 @@ var diagCmd = async (_args, deps) => {
8591
8817
  ` modelsCache: ${deps.paths.modelsCache}`,
8592
8818
  ` cacheAge: ${isFinite(age) ? `${Math.round(age / 60)}m` : "never"}`,
8593
8819
  ` node: ${process.version}`,
8594
- ` os: ${os6.platform()} ${os6.release()}`,
8820
+ ` os: ${os4.platform()} ${os4.release()}`,
8595
8821
  ` provider: ${cfg.provider ?? "<unset>"}`,
8596
8822
  ` model: ${cfg.model ?? "<unset>"}`,
8597
8823
  ` tools: ${deps.toolRegistry?.list().length ?? 0}`,
@@ -9324,13 +9550,13 @@ async function listFleetRuns(deps) {
9324
9550
  const runs = [];
9325
9551
  for (const id of entries) {
9326
9552
  const runDir = path25.join(deps.paths.projectSessions, id);
9327
- let stat3;
9553
+ let stat4;
9328
9554
  try {
9329
- stat3 = await fsp3.stat(runDir);
9555
+ stat4 = await fsp3.stat(runDir);
9330
9556
  } catch {
9331
9557
  continue;
9332
9558
  }
9333
- if (!stat3.isDirectory()) continue;
9559
+ if (!stat4.isDirectory()) continue;
9334
9560
  let manifest = false;
9335
9561
  let checkpoint = false;
9336
9562
  let subagentCount = 0;
@@ -9376,15 +9602,15 @@ async function listFleetRuns(deps) {
9376
9602
  }
9377
9603
  async function showFleetRun(runId, deps) {
9378
9604
  const runDir = path25.join(deps.paths.projectSessions, runId);
9379
- let stat3;
9605
+ let stat4;
9380
9606
  try {
9381
- stat3 = await fsp3.stat(runDir);
9607
+ stat4 = await fsp3.stat(runDir);
9382
9608
  } catch {
9383
9609
  deps.renderer.writeError(`Fleet run not found: ${runId}
9384
9610
  `);
9385
9611
  return 1;
9386
9612
  }
9387
- if (!stat3.isDirectory()) {
9613
+ if (!stat4.isDirectory()) {
9388
9614
  deps.renderer.writeError(`Not a directory: ${runId}
9389
9615
  `);
9390
9616
  return 1;
@@ -9783,7 +10009,7 @@ var skillsCmd = async (_args, deps) => {
9783
10009
  };
9784
10010
  var versionCmd = async (_args, deps) => {
9785
10011
  deps.renderer.write(
9786
- `WrongStack ${CLI_VERSION} (apiVersion ${API_VERSION}, node ${process.version}, ${os6.platform()})
10012
+ `WrongStack ${CLI_VERSION} (apiVersion ${API_VERSION}, node ${process.version}, ${os4.platform()})
9787
10013
  `
9788
10014
  );
9789
10015
  return 0;
@@ -9863,22 +10089,22 @@ function fmtDuration(ms) {
9863
10089
  const remMin = m - h * 60;
9864
10090
  return `${h}h${remMin}m`;
9865
10091
  }
9866
- function fmtTaskResultLine(r, color39) {
10092
+ function fmtTaskResultLine(r, color41) {
9867
10093
  const stats = `${r.iterations}it ${r.toolCalls}tc ${fmtDuration(r.durationMs)}`;
9868
10094
  const errMsg = typeof r.error === "string" ? r.error : r.error?.message;
9869
10095
  const errKind = typeof r.error === "object" ? r.error?.kind : void 0;
9870
10096
  const errTail = errMsg ? ` \u2014 ${errMsg.replace(/\s+/g, " ").slice(0, 80)}${errMsg.length > 80 ? "\u2026" : ""}` : "";
9871
- const errKindChip = errKind ? color39.dim(` [${errKind}]`) : "";
9872
- const errSnip = errMsg || errKind ? `${errKindChip}${color39.dim(errTail)}` : "";
10097
+ const errKindChip = errKind ? color41.dim(` [${errKind}]`) : "";
10098
+ const errSnip = errMsg || errKind ? `${errKindChip}${color41.dim(errTail)}` : "";
9873
10099
  switch (r.status) {
9874
10100
  case "success":
9875
- return { mark: color39.green("\u2713"), stats, tail: "" };
10101
+ return { mark: color41.green("\u2713"), stats, tail: "" };
9876
10102
  case "timeout":
9877
- return { mark: color39.yellow("\u23F1"), stats: `${color39.yellow("timeout")} ${stats}`, tail: errSnip };
10103
+ return { mark: color41.yellow("\u23F1"), stats: `${color41.yellow("timeout")} ${stats}`, tail: errSnip };
9878
10104
  case "stopped":
9879
- return { mark: color39.dim("\u2298"), stats: `${color39.dim("stopped")} ${stats}`, tail: errSnip };
10105
+ return { mark: color41.dim("\u2298"), stats: `${color41.dim("stopped")} ${stats}`, tail: errSnip };
9880
10106
  case "failed":
9881
- return { mark: color39.red("\u2717"), stats: `${color39.red("failed")} ${stats}`, tail: errSnip };
10107
+ return { mark: color41.red("\u2717"), stats: `${color41.red("failed")} ${stats}`, tail: errSnip };
9882
10108
  }
9883
10109
  }
9884
10110
 
@@ -12988,6 +13214,8 @@ async function main(argv) {
12988
13214
  statuslineHiddenItems: [...currentHiddenItems],
12989
13215
  setStatuslineHiddenItems,
12990
13216
  agentsMonitorController,
13217
+ configStore,
13218
+ reader,
12991
13219
  confirm: async (question, defaultYes = true) => {
12992
13220
  if (!process.stdin.isTTY) return false;
12993
13221
  const hint = defaultYes ? "[Y/n/q]" : "[y/N/q]";
@@ -13218,12 +13446,12 @@ async function main(argv) {
13218
13446
  if (!f.endsWith(".jsonl")) continue;
13219
13447
  const full = path25.join(runDir, f);
13220
13448
  try {
13221
- const stat3 = await fsp3.stat(full);
13449
+ const stat4 = await fsp3.stat(full);
13222
13450
  found.push({
13223
13451
  runId,
13224
13452
  subagentId: f.replace(/\.jsonl$/, ""),
13225
13453
  file: full,
13226
- size: stat3.size
13454
+ size: stat4.size
13227
13455
  });
13228
13456
  } catch {
13229
13457
  }