@wrongstack/cli 0.308.7 → 0.309.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.
@@ -50,7 +50,7 @@ import {
50
50
  detectProjectFacts,
51
51
  makeConfirmAwaiter,
52
52
  renderAgentsTemplate
53
- } from "./chunk-DOJLAULS.js";
53
+ } from "./chunk-WOTGMHAH.js";
54
54
  import "./chunk-QD544J2B.js";
55
55
  import {
56
56
  fmtTaskResultLine,
@@ -71,7 +71,7 @@ import {
71
71
  loadCachedAcpRegistry,
72
72
  refreshAcpRegistry,
73
73
  setupProvider
74
- } from "./chunk-JQURRYU4.js";
74
+ } from "./chunk-UINEP3E7.js";
75
75
  import {
76
76
  addCustomProvider,
77
77
  addKeyForCatalogProvider,
@@ -81,7 +81,7 @@ import {
81
81
  runClaudeOAuthLogin,
82
82
  runCopilotOAuthLogin,
83
83
  validateFamily
84
- } from "./chunk-7JOMY3HO.js";
84
+ } from "./chunk-ZRZ54GVL.js";
85
85
  import {
86
86
  LOCAL_LLM_PRESETS,
87
87
  parseSpawnFlags
@@ -98,7 +98,7 @@ import {
98
98
  } from "./chunk-YMXXOOFN.js";
99
99
  import {
100
100
  runCodexOAuthLogin
101
- } from "./chunk-SSSJQVUY.js";
101
+ } from "./chunk-XQ6FI2K6.js";
102
102
  import {
103
103
  activeLabel,
104
104
  loadConfigProviders,
@@ -1877,7 +1877,10 @@ function resolveSubagentCapabilities(subCfg, toolsForAllow) {
1877
1877
  ]).granted;
1878
1878
  }
1879
1879
  const allow = subCfg.tools;
1880
- if (!allow || allow.length === 0) return WIDE_SUBAGENT_CAPABILITIES;
1880
+ if (allow && allow.length === 0) {
1881
+ return clampSubagentCapabilities([ToolCapabilities.COORDINATION_RESULT_SUBMIT]).granted;
1882
+ }
1883
+ if (!allow) return WIDE_SUBAGENT_CAPABILITIES;
1881
1884
  const caps = new Set(WIDE_SUBAGENT_CAPABILITIES);
1882
1885
  for (const tool of toolsForAllow([...allow])) {
1883
1886
  for (const capability of tool.capabilities ?? []) caps.add(capability);
@@ -5644,7 +5647,7 @@ async function runCliExecution(params) {
5644
5647
  governanceHandle,
5645
5648
  setConfig
5646
5649
  } = params;
5647
- const { execute } = await import("./execution-6HIKTAUB.js");
5650
+ const { execute } = await import("./execution-TYUXABWI.js");
5648
5651
  return execute(
5649
5652
  toExecuteDeps({
5650
5653
  core: {
@@ -5780,7 +5783,11 @@ async function runCliExecution(params) {
5780
5783
  setConfig,
5781
5784
  profileConfigPath,
5782
5785
  mcpRegistry,
5783
- toolRegistry: params.context.toolRegistry ?? params.agent.ctx.tools,
5786
+ // cli-main attaches toolRegistry onto the Context object dynamically
5787
+ // (core Context does not declare it). The previous `?? agent.ctx.tools`
5788
+ // fallback was a latent crash: ctx.tools is a Tool[], which cannot
5789
+ // satisfy the ToolRegistry the picker calls into.
5790
+ toolRegistry: params.context.toolRegistry,
5784
5791
  configStore,
5785
5792
  getPluginItems: getPluginPickerItems,
5786
5793
  togglePlugin: togglePluginFromPicker,
@@ -11316,49 +11323,179 @@ ${menu}` };
11316
11323
  }
11317
11324
 
11318
11325
  // src/slash-commands/dev.ts
11319
- import { execFile } from "node:child_process";
11320
- import { ToolValidationError as ToolValidationError3 } from "@wrongstack/core/types";
11326
+ import { spawn as spawn4 } from "node:child_process";
11327
+ import { StringDecoder } from "node:string_decoder";
11321
11328
  import { color as color23 } from "@wrongstack/core/utils";
11322
11329
  var DEFAULT_TIMEOUT_MS = 6e4;
11323
11330
  var MAX_OUTPUT_LINES = 500;
11324
- var WINDOWS_CMD_METACHARACTERS = /[;&|<>^$,(){}[\]!#%'"\\/`]/;
11325
- function validateCommand(cmd) {
11326
- if (process.platform !== "win32") return;
11327
- if (WINDOWS_CMD_METACHARACTERS.test(cmd)) {
11328
- throw new ToolValidationError3({
11329
- message: `Command contains disallowed metacharacters for Windows: ${cmd.match(WINDOWS_CMD_METACHARACTERS)?.[0] ?? "?"}
11330
- The following characters are not allowed: ; & | < > ^ $ , ( ) { } [ ] ! # % ' " \\ / \` * ?`,
11331
- field: "command",
11332
- context: { platform: "win32", pattern: WINDOWS_CMD_METACHARACTERS.source }
11333
- });
11331
+ var MAX_STREAM_BYTES = 2 * 1024 * 1024;
11332
+ var EXIT_SPAWN_FAILED = 127;
11333
+ var EXIT_TIMEOUT = 124;
11334
+ var SIGNAL_NUMBERS = {
11335
+ SIGHUP: 1,
11336
+ SIGINT: 2,
11337
+ SIGQUIT: 3,
11338
+ SIGABRT: 6,
11339
+ SIGKILL: 9,
11340
+ SIGALRM: 14,
11341
+ SIGTERM: 15
11342
+ };
11343
+ function foreignSignalExitCode(signal) {
11344
+ const n = SIGNAL_NUMBERS[signal];
11345
+ return n === void 0 ? 125 : 128 + n;
11346
+ }
11347
+ function tokenizeCommand(command, platform = process.platform) {
11348
+ const isWin32 = platform === "win32";
11349
+ const args = [];
11350
+ let current = "";
11351
+ let tokenStarted = false;
11352
+ let quote = null;
11353
+ for (let i = 0; i < command.length; i++) {
11354
+ const char = command[i];
11355
+ if (quote) {
11356
+ if (!isWin32 && char === "\\" && quote === '"' && i + 1 < command.length) {
11357
+ const next = command[i + 1];
11358
+ if (next === "\n") {
11359
+ i++;
11360
+ continue;
11361
+ }
11362
+ if (next === '"' || next === "\\" || next === "$" || next === "`") {
11363
+ current += next;
11364
+ i++;
11365
+ continue;
11366
+ }
11367
+ }
11368
+ if (char === quote) quote = null;
11369
+ else current += char;
11370
+ continue;
11371
+ }
11372
+ if (char === '"' || char === "'") {
11373
+ quote = char;
11374
+ tokenStarted = true;
11375
+ continue;
11376
+ }
11377
+ if (!isWin32 && char === "\\" && i + 1 < command.length) {
11378
+ current += command[++i];
11379
+ tokenStarted = true;
11380
+ continue;
11381
+ }
11382
+ if (/\s/.test(char)) {
11383
+ if (tokenStarted) {
11384
+ args.push(current);
11385
+ current = "";
11386
+ tokenStarted = false;
11387
+ }
11388
+ continue;
11389
+ }
11390
+ current += char;
11391
+ tokenStarted = true;
11334
11392
  }
11393
+ if (quote) throw new Error(`Unterminated quoted argument in command: ${command}`);
11394
+ if (tokenStarted) args.push(current);
11395
+ return args;
11396
+ }
11397
+ function spawnFailure(stderr) {
11398
+ return { stdout: "", stderr, exitCode: EXIT_SPAWN_FAILED, killed: false, spawnFailed: true };
11335
11399
  }
11336
- function runCommand(cmd, cwd, timeout) {
11400
+ function runCommand(cmd, cwd, timeout = DEFAULT_TIMEOUT_MS) {
11401
+ let program;
11402
+ let args;
11403
+ try {
11404
+ const tokens = tokenizeCommand(cmd);
11405
+ program = tokens[0] ?? "";
11406
+ args = tokens.slice(1);
11407
+ } catch (err) {
11408
+ return Promise.resolve(spawnFailure(err instanceof Error ? err.message : String(err)));
11409
+ }
11410
+ if (!program) return Promise.resolve(spawnFailure("Empty command."));
11411
+ let command;
11412
+ let spawnArgs;
11413
+ let windowsVerbatimArguments;
11414
+ if (process.platform === "win32") {
11415
+ try {
11416
+ const shim = buildWin32CmdShimInvocation(program, args);
11417
+ command = shim.command;
11418
+ spawnArgs = shim.args;
11419
+ windowsVerbatimArguments = shim.windowsVerbatimArguments;
11420
+ } catch (err) {
11421
+ return Promise.resolve(spawnFailure(err instanceof Error ? err.message : String(err)));
11422
+ }
11423
+ } else {
11424
+ command = program;
11425
+ spawnArgs = args;
11426
+ }
11337
11427
  return new Promise((resolve8) => {
11338
- validateCommand(cmd);
11339
- const opts = {
11340
- cwd,
11341
- timeout,
11342
- maxBuffer: 2 * 1024 * 1024,
11343
- // 2 MB
11344
- windowsHide: true,
11345
- // On POSIX: no shell → command string is a literal argument.
11346
- // On Windows: shell:true → cmd.exe /c "..." handles quoting.
11347
- shell: process.platform === "win32"
11428
+ let child;
11429
+ try {
11430
+ child = spawn4(command, spawnArgs, {
11431
+ cwd,
11432
+ timeout,
11433
+ windowsHide: true,
11434
+ ...windowsVerbatimArguments ? { windowsVerbatimArguments } : {}
11435
+ });
11436
+ } catch (err) {
11437
+ resolve8(spawnFailure(err instanceof Error ? err.message : String(err)));
11438
+ return;
11439
+ }
11440
+ let stdout = "";
11441
+ let stderr = "";
11442
+ const stdoutDecoder = new StringDecoder("utf8");
11443
+ const stderrDecoder = new StringDecoder("utf8");
11444
+ const appendCapped = (acc, decoder, chunk) => acc.length >= MAX_STREAM_BYTES ? acc : acc + decoder.write(chunk).slice(0, MAX_STREAM_BYTES - acc.length);
11445
+ child.stdout?.on("data", (chunk) => {
11446
+ stdout = appendCapped(stdout, stdoutDecoder, chunk);
11447
+ });
11448
+ child.stderr?.on("data", (chunk) => {
11449
+ stderr = appendCapped(stderr, stderrDecoder, chunk);
11450
+ });
11451
+ child.stdout?.on("error", (err) => {
11452
+ stderr = appendCapped(
11453
+ stderr,
11454
+ stderrDecoder,
11455
+ Buffer.from(`
11456
+ [stdout stream error: ${err.message}]`)
11457
+ );
11458
+ });
11459
+ child.stderr?.on("error", () => {
11460
+ });
11461
+ let settled = false;
11462
+ const finish = (result) => {
11463
+ if (settled) return;
11464
+ settled = true;
11465
+ resolve8(result);
11348
11466
  };
11349
- execFile(cmd, [], opts, (error, stdout, stderr) => {
11350
- resolve8({
11467
+ child.on("error", (err) => {
11468
+ finish({
11469
+ stdout,
11470
+ stderr: err.message,
11471
+ exitCode: EXIT_SPAWN_FAILED,
11472
+ killed: false,
11473
+ spawnFailed: true
11474
+ });
11475
+ });
11476
+ child.on("close", (code, signal) => {
11477
+ const timedOut = child.killed && code !== 0;
11478
+ const diedBySignal = signal !== null && !timedOut;
11479
+ const exitCode = timedOut ? EXIT_TIMEOUT : code ?? (diedBySignal ? foreignSignalExitCode(signal ?? "") : EXIT_SPAWN_FAILED);
11480
+ finish({
11351
11481
  stdout,
11352
11482
  stderr,
11353
- exitCode: typeof error?.code === "number" ? error.code : 0,
11354
- killed: error?.killed ?? false
11483
+ exitCode,
11484
+ // Contract (DevCommandResult.killed): true when the process died
11485
+ // from a signal — timeout kill OR foreign. `diedBySignal` alone
11486
+ // excludes our own timeout kill and reported killed:false on every
11487
+ // TIMEOUT (chimera finding).
11488
+ killed: timedOut || diedBySignal,
11489
+ spawnFailed: code === null && signal === null,
11490
+ ...signal !== null ? { signalName: signal } : {},
11491
+ ...timedOut ? { timedOut: true } : {}
11355
11492
  });
11356
11493
  });
11357
11494
  });
11358
11495
  }
11359
11496
  function formatOutput(cmd, result, elapsed) {
11360
11497
  const lines = [];
11361
- const exitLabel = result.killed ? color23.red("TIMEOUT") : result.exitCode === 0 ? color23.green("OK") : color23.red(`EXIT ${result.exitCode}`);
11498
+ const exitLabel = result.timedOut ? color23.red("TIMEOUT") : result.killed ? color23.red(`KILLED${result.signalName ? ` (${result.signalName})` : ""}`) : result.spawnFailed ? color23.red("SPAWN ERROR") : result.exitCode === 0 ? color23.green("OK") : color23.red(`EXIT ${result.exitCode}`);
11362
11499
  lines.push(`${color23.cyan("$")} ${color23.bold(cmd)} ${exitLabel} ${color23.dim(`${elapsed}ms`)}`);
11363
11500
  const combined = (result.stdout + result.stderr).trimEnd();
11364
11501
  if (combined) {
@@ -11416,7 +11553,6 @@ Examples:
11416
11553
  /dev git diff --stat`
11417
11554
  };
11418
11555
  }
11419
- validateCommand(cmd);
11420
11556
  const cwd = opts.cwd;
11421
11557
  const startedAt = Date.now();
11422
11558
  opts.renderer.write(color23.dim(`$ ${cmd}`));
@@ -17241,7 +17377,7 @@ function buildMailboxDemoCommand(opts) {
17241
17377
  }
17242
17378
 
17243
17379
  // src/slash-commands/mailbox-serve.ts
17244
- import { spawn as spawn4 } from "node:child_process";
17380
+ import { spawn as spawn5 } from "node:child_process";
17245
17381
  import * as fs10 from "node:fs/promises";
17246
17382
  import * as os2 from "node:os";
17247
17383
  import * as path14 from "node:path";
@@ -17304,7 +17440,7 @@ function buildMailboxServeCommand(opts) {
17304
17440
  spawnArgs = ["mailbox", "serve", ...flags];
17305
17441
  if (isWin) shim = buildWin32CmdShimInvocation(wstackCmd, spawnArgs);
17306
17442
  }
17307
- const child = spawn4(shim?.command ?? wstackCmd, shim?.args ?? spawnArgs, {
17443
+ const child = spawn5(shim?.command ?? wstackCmd, shim?.args ?? spawnArgs, {
17308
17444
  cwd,
17309
17445
  // POSIX-only: own process group so the bridge outlives the REPL.
17310
17446
  // On win32 `detached` opens a visible console window (project
@@ -20021,7 +20157,7 @@ import * as fs12 from "node:fs/promises";
20021
20157
  import { decryptConfigSecrets as decryptConfigSecrets3, encryptConfigSecrets as encryptConfigSecrets3, noOpVault as noOpVault4 } from "@wrongstack/core/security";
20022
20158
  import {
20023
20159
  ConfigError as ConfigError4,
20024
- ToolValidationError as ToolValidationError4
20160
+ ToolValidationError as ToolValidationError3
20025
20161
  } from "@wrongstack/core/types";
20026
20162
  import { atomicWrite as atomicWrite6, color as color41, toErrorMessage as toErrorMessage18 } from "@wrongstack/core/utils";
20027
20163
  async function patchProfileConfig(mutate, profileConfigPath) {
@@ -20077,7 +20213,7 @@ function fmtModel(id, def) {
20077
20213
  function safeAt(arr, idx) {
20078
20214
  const v = arr[idx];
20079
20215
  if (v === void 0)
20080
- throw new ToolValidationError4({
20216
+ throw new ToolValidationError3({
20081
20217
  message: `Missing value at position ${idx}`,
20082
20218
  field: `argv[${idx}]`
20083
20219
  });
@@ -22966,7 +23102,9 @@ import {
22966
23102
  } from "@wrongstack/core/coordination";
22967
23103
  import { decryptConfigSecrets as decryptConfigSecrets4, encryptConfigSecrets as encryptConfigSecrets4, noOpVault as noOpVault6 } from "@wrongstack/core/security";
22968
23104
  import {
22969
- ConfigError as ConfigError5
23105
+ ConfigError as ConfigError5,
23106
+ REASONING_EFFORT_LEVELS,
23107
+ isReasoningEffort
22970
23108
  } from "@wrongstack/core/types";
22971
23109
  import { atomicWrite as atomicWrite8, color as color48, expectDefined as expectDefined6, toErrorMessage as toErrorMessage21 } from "@wrongstack/core/utils";
22972
23110
  import { catalogProviderIdFor } from "@wrongstack/providers";
@@ -23021,18 +23159,6 @@ function parseTarget(tokens, profiles = {}) {
23021
23159
  }
23022
23160
  return { model: only };
23023
23161
  }
23024
- var REASONING_EFFORTS = [
23025
- "none",
23026
- "minimal",
23027
- "low",
23028
- "medium",
23029
- "high",
23030
- "xhigh",
23031
- "max"
23032
- ];
23033
- function isReasoningEffort(value) {
23034
- return !!value && REASONING_EFFORTS.includes(value);
23035
- }
23036
23162
  function isReasoningMode(value) {
23037
23163
  return value === "auto" || value === "on" || value === "off";
23038
23164
  }
@@ -23410,7 +23536,7 @@ function buildSetModelCommand(opts) {
23410
23536
  const key = parts[1];
23411
23537
  if (!key) {
23412
23538
  return {
23413
- message: `${color48.amber("Usage:")} /setmodel ${sub} <role|phase|*> ${sub === "reasoning" ? "auto|on|off [effort]" : sub === "reasoning-effort" ? REASONING_EFFORTS.join("|") : "on|off"}`
23539
+ message: `${color48.amber("Usage:")} /setmodel ${sub} <role|phase|*> ${sub === "reasoning" ? "auto|on|off [effort]" : sub === "reasoning-effort" ? REASONING_EFFORT_LEVELS.join("|") : "on|off"}`
23414
23540
  };
23415
23541
  }
23416
23542
  if (matrixKeyKind(key) === "unknown") {
@@ -23431,7 +23557,7 @@ function buildSetModelCommand(opts) {
23431
23557
  if (parts[3] !== void 0) {
23432
23558
  if (!isReasoningEffort(parts[3])) {
23433
23559
  return {
23434
- message: `${color48.red("Invalid effort")}: "${parts[3]}". Expected ${REASONING_EFFORTS.join(", ")}.`
23560
+ message: `${color48.red("Invalid effort")}: "${parts[3]}". Expected ${REASONING_EFFORT_LEVELS.join(", ")}.`
23435
23561
  };
23436
23562
  }
23437
23563
  nextEffort = parts[3];
@@ -23439,7 +23565,7 @@ function buildSetModelCommand(opts) {
23439
23565
  } else if (sub === "reasoning-effort") {
23440
23566
  if (!isReasoningEffort(parts[2])) {
23441
23567
  return {
23442
- message: `${color48.amber("Usage:")} /setmodel reasoning-effort ${key} ${REASONING_EFFORTS.join("|")}`
23568
+ message: `${color48.amber("Usage:")} /setmodel reasoning-effort ${key} ${REASONING_EFFORT_LEVELS.join("|")}`
23443
23569
  };
23444
23570
  }
23445
23571
  nextEffort = parts[2];
@@ -23549,17 +23675,219 @@ function buildSetModelCommand(opts) {
23549
23675
  };
23550
23676
  }
23551
23677
 
23678
+ // src/slash-commands/effort.ts
23679
+ import { decryptConfigSecrets as decryptConfigSecrets5, encryptConfigSecrets as encryptConfigSecrets5, noOpVault as noOpVault7 } from "@wrongstack/core/security";
23680
+ import {
23681
+ isReasoningEffort as isReasoningEffort2,
23682
+ REASONING_EFFORT_LEVELS as REASONING_EFFORT_LEVELS2
23683
+ } from "@wrongstack/core/types";
23684
+ import { atomicWrite as atomicWrite9, color as color49 } from "@wrongstack/core/utils";
23685
+ import { catalogProviderIdFor as catalogProviderIdFor2 } from "@wrongstack/providers";
23686
+ import * as fs14 from "node:fs/promises";
23687
+ function buildEffortCommand(opts) {
23688
+ const levelsHint = REASONING_EFFORT_LEVELS2.join("|");
23689
+ const help = [
23690
+ "Usage:",
23691
+ " /effort Show current session effort + supported levels",
23692
+ ` /effort <level> Set session effort (${levelsHint})`,
23693
+ " /effort clear Remove the setting \u2014 provider default applies",
23694
+ " /effort matrix Show per-role/phase effort overrides (/setmodel)",
23695
+ "",
23696
+ "Applies to the active model on the next request. Unsupported values for the",
23697
+ "current model are rejected up front when its capabilities are known.",
23698
+ "Per-subagent overrides: /setmodel reasoning-effort <role|phase|*> <level>."
23699
+ ].join("\n");
23700
+ async function loadModelLevels() {
23701
+ const registry = opts.modelsRegistry;
23702
+ if (!registry) return { levels: void 0, supported: void 0 };
23703
+ const config = opts.configStore.get();
23704
+ try {
23705
+ const catalogId = catalogProviderIdFor2(
23706
+ config.provider,
23707
+ config.providers?.[config.provider]?.type
23708
+ );
23709
+ const resolved = await registry.getModel(catalogId, config.model);
23710
+ const rc = resolved?.capabilities.reasoningConfig;
23711
+ if (!rc) {
23712
+ const provider = await registry.getProvider(catalogId).catch(() => void 0);
23713
+ const raw = provider?.models.find((m) => m.id === config.model);
23714
+ return { levels: void 0, supported: raw?.reasoning === false ? false : void 0 };
23715
+ }
23716
+ return {
23717
+ levels: rc.effortLevels?.length ? rc.effortLevels : void 0,
23718
+ // rc present ⇒ the model is known to reason. Only a DOCUMENTED
23719
+ // absence (`effortSupported === false`) marks it unsupported; an
23720
+ // undocumented vocabulary (`undefined`) is "supported, not
23721
+ // enumerated" — accept any canonical level and let the wire adapter
23722
+ // gate. `undefined` here is reserved for capabilities-unknown above.
23723
+ supported: rc.effortSupported !== false
23724
+ };
23725
+ } catch {
23726
+ return { levels: void 0, supported: void 0 };
23727
+ }
23728
+ }
23729
+ return {
23730
+ name: "effort",
23731
+ category: "Config",
23732
+ description: "View or set the session-wide reasoning effort for the active model.",
23733
+ argsHint: `[${levelsHint}|clear|matrix]`,
23734
+ help,
23735
+ async run(args) {
23736
+ const parts = args.trim().split(/\s+/).filter(Boolean);
23737
+ const sub = (parts[0] ?? "").toLowerCase();
23738
+ if (sub === "help" || sub === "--help") return { message: help };
23739
+ if (!opts.configStore || !opts.paths) {
23740
+ return { message: `${color49.red("Error")} config store not available.` };
23741
+ }
23742
+ const config = opts.configStore.get();
23743
+ if (sub === "matrix") {
23744
+ const matrix = config.modelMatrix ?? {};
23745
+ const entries = Object.entries(matrix).filter(([, e]) => e?.modelRuntime?.reasoning);
23746
+ if (entries.length === 0) {
23747
+ return {
23748
+ message: [
23749
+ `${color49.bold("Effort overrides")} ${color49.dim("(model matrix)")}`,
23750
+ ` ${color49.dim("(none \u2014 set one with /setmodel reasoning-effort <role|phase|*> <level>)")}`
23751
+ ].join("\n")
23752
+ };
23753
+ }
23754
+ const lines = [`${color49.bold("Effort overrides")} ${color49.dim("(model matrix)")}`];
23755
+ for (const [key, entry] of entries.sort(([a], [b]) => a.localeCompare(b))) {
23756
+ const reasoning = entry.modelRuntime.reasoning;
23757
+ const bits = [
23758
+ reasoning.effort ? `effort:${reasoning.effort}` : "",
23759
+ reasoning.mode ? `mode:${reasoning.mode}` : "",
23760
+ reasoning.preserve !== void 0 ? `preserve:${reasoning.preserve ? "on" : "off"}` : ""
23761
+ ].filter(Boolean);
23762
+ lines.push(` ${color49.amber(key.padEnd(22))} \u2192 ${bits.join(" ")}`);
23763
+ }
23764
+ return { message: lines.join("\n") };
23765
+ }
23766
+ const { levels, supported } = await loadModelLevels();
23767
+ const current = config.modelRuntime?.reasoning?.effort;
23768
+ if (!sub) {
23769
+ const lines = [
23770
+ `${color49.bold("WrongStack")} ${color49.dim("\u2014 Session effort")}`,
23771
+ "",
23772
+ ` ${color49.bold("model")} ${color49.cyan(`${config.provider}/${config.model}`)}`
23773
+ ];
23774
+ if (current) {
23775
+ const ok = !levels || levels.includes(current);
23776
+ lines.push(
23777
+ ` ${color49.bold("effort")} ${color49.bold(current)}${ok ? "" : ` ${color49.amber(`(not advertised by this model \u2014 supported: ${levels.join(", ")})`)}`}`
23778
+ );
23779
+ } else {
23780
+ lines.push(` ${color49.bold("effort")} ${color49.dim("(not set \u2014 provider default)")}`);
23781
+ }
23782
+ if (levels) {
23783
+ const rendered = REASONING_EFFORT_LEVELS2.filter((l) => levels.includes(l)).map(
23784
+ (l) => l === current ? color49.bold(l) : l
23785
+ );
23786
+ lines.push(` ${color49.bold("levels")} ${rendered.join(" \xB7 ")}`);
23787
+ } else if (supported === true) {
23788
+ lines.push(
23789
+ ` ${color49.bold("levels")} ${color49.dim("(not enumerated \u2014 any level is accepted; the transport applies its own gating)")}`
23790
+ );
23791
+ } else if (supported === false) {
23792
+ lines.push(
23793
+ ` ${color49.bold("levels")} ${color49.red("no effort control")}${color49.dim(" \u2014 documented as unsupported for this model")}`
23794
+ );
23795
+ } else {
23796
+ lines.push(
23797
+ ` ${color49.bold("levels")} ${color49.dim("(unknown \u2014 the resolver drops unsupported values with a warning)")}`
23798
+ );
23799
+ }
23800
+ lines.push(
23801
+ "",
23802
+ ` ${color49.dim("/effort <level> \xB7 clear \xB7 matrix \xB7 help")}`
23803
+ );
23804
+ return { message: lines.join("\n") };
23805
+ }
23806
+ if (sub === "clear" || sub === "off-default") {
23807
+ if (current === void 0) {
23808
+ return { message: `${color49.dim("No session effort set \u2014 provider default already applies.")}` };
23809
+ }
23810
+ await patchSessionEffort(void 0, opts.paths, config.activeProfile ?? "default");
23811
+ opts.configStore.update({
23812
+ modelRuntime: {
23813
+ ...config.modelRuntime,
23814
+ reasoning: { ...config.modelRuntime?.reasoning, effort: void 0 }
23815
+ }
23816
+ });
23817
+ return {
23818
+ message: `${color49.green("\u2713")} session effort cleared ${color49.dim("\u2014 provider default applies")}`
23819
+ };
23820
+ }
23821
+ if (!isReasoningEffort2(sub)) {
23822
+ return {
23823
+ message: `${color49.amber("Usage:")} /effort ${REASONING_EFFORT_LEVELS2.join("|")} | clear | matrix`
23824
+ };
23825
+ }
23826
+ if (supported === false) {
23827
+ return {
23828
+ message: [
23829
+ `${color49.red("No effort control")} for ${config.provider}/${config.model}: the catalog documents this model's reasoning options without effort levels.`,
23830
+ ` ${color49.dim("/effort clear removes the setting")}`
23831
+ ].join("\n")
23832
+ };
23833
+ }
23834
+ if (levels && !levels.includes(sub)) {
23835
+ return {
23836
+ message: [
23837
+ `${color49.red("Unsupported effort")} for ${config.provider}/${config.model}: "${sub}".`,
23838
+ ` ${color49.dim(`advertised: ${levels.join(", ")}`)}`,
23839
+ ` ${color49.dim("the resolver would drop this value with a warning \u2014 pick an advertised level, or /effort clear")}`
23840
+ ].join("\n")
23841
+ };
23842
+ }
23843
+ await patchSessionEffort(sub, opts.paths, config.activeProfile ?? "default");
23844
+ opts.configStore.update({
23845
+ modelRuntime: {
23846
+ ...config.modelRuntime,
23847
+ reasoning: { ...config.modelRuntime?.reasoning, effort: sub }
23848
+ }
23849
+ });
23850
+ return {
23851
+ message: `${color49.green("\u2713")} session effort \u2192 ${color49.bold(sub)} ${color49.dim(`(${config.provider}/${config.model}, next request)`)}`
23852
+ };
23853
+ }
23854
+ };
23855
+ }
23856
+ async function patchSessionEffort(effort, paths, activeProfile) {
23857
+ const targetPath = paths.profileConfig(activeProfile);
23858
+ let raw = "{}";
23859
+ try {
23860
+ raw = await fs14.readFile(targetPath, "utf8");
23861
+ } catch {
23862
+ }
23863
+ let parsed;
23864
+ try {
23865
+ parsed = JSON.parse(raw);
23866
+ } catch {
23867
+ parsed = {};
23868
+ }
23869
+ const decrypted = decryptConfigSecrets5(parsed, noOpVault7);
23870
+ const mr = decrypted.modelRuntime ?? {};
23871
+ const reasoning = { ...mr.reasoning ?? {} };
23872
+ if (effort === void 0) delete reasoning.effort;
23873
+ else reasoning.effort = effort;
23874
+ mr.reasoning = reasoning;
23875
+ decrypted.modelRuntime = mr;
23876
+ const encrypted = encryptConfigSecrets5(decrypted, noOpVault7);
23877
+ await atomicWrite9(targetPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
23878
+ }
23879
+
23552
23880
  // src/slash-commands/suggest.ts
23553
- import { execFile as execFile2 } from "node:child_process";
23881
+ import { execFile } from "node:child_process";
23554
23882
  import { access as access3 } from "node:fs/promises";
23555
23883
  import * as path16 from "node:path";
23556
- import { color as color49, toErrorMessage as toErrorMessage22 } from "@wrongstack/core/utils";
23884
+ import { color as color50, toErrorMessage as toErrorMessage22 } from "@wrongstack/core/utils";
23557
23885
  import { parseNextSteps } from "@wrongstack/tools/next-steps";
23558
23886
  function readGitStatus(projectRoot, includeBranch) {
23559
23887
  const args = ["status", "--short"];
23560
23888
  if (includeBranch) args.push("--branch");
23561
23889
  return new Promise((resolve8) => {
23562
- execFile2(
23890
+ execFile(
23563
23891
  "git",
23564
23892
  args,
23565
23893
  {
@@ -23645,7 +23973,7 @@ function buildSuggestCommand(opts) {
23645
23973
  const suggestions = await generateHeuristicSuggestions(opts);
23646
23974
  setSuggestions(suggestions);
23647
23975
  opts.onSuggestions?.(suggestions);
23648
- const display = formatSuggestions(suggestions) + "\n" + color49.dim("(Heuristic fallback \u2014 multi-agent not enabled)");
23976
+ const display = formatSuggestions(suggestions) + "\n" + color50.dim("(Heuristic fallback \u2014 multi-agent not enabled)");
23649
23977
  return { message: display };
23650
23978
  }
23651
23979
  if (!fresh && suggestCache && Date.now() - suggestCache.at < SUGGEST_CACHE_TTL_MS) {
@@ -23653,7 +23981,7 @@ function buildSuggestCommand(opts) {
23653
23981
  opts.onSuggestions?.(suggestCache.suggestions);
23654
23982
  const ageSec = Math.round((Date.now() - suggestCache.at) / 1e3);
23655
23983
  return {
23656
- message: formatSuggestions(suggestCache.suggestions) + "\n" + color49.dim(`(cached ${ageSec}s ago \u2014 /suggest --fresh to regenerate)`)
23984
+ message: formatSuggestions(suggestCache.suggestions) + "\n" + color50.dim(`(cached ${ageSec}s ago \u2014 /suggest --fresh to regenerate)`)
23657
23985
  };
23658
23986
  }
23659
23987
  const contextText = await collectContext({
@@ -23661,7 +23989,7 @@ function buildSuggestCommand(opts) {
23661
23989
  projectRoot: opts.projectRoot
23662
23990
  });
23663
23991
  const task = buildSuggestPrompt(contextText);
23664
- opts.renderer.write(color49.dim("Generating suggestions..."));
23992
+ opts.renderer.write(color50.dim("Generating suggestions..."));
23665
23993
  try {
23666
23994
  const raw = await opts.onSpawnAndWait(task, {
23667
23995
  name: "suggest"
@@ -23756,14 +24084,14 @@ async function generateHeuristicSuggestions(opts) {
23756
24084
  }
23757
24085
  function formatSuggestions(suggestions) {
23758
24086
  if (suggestions.length === 0) {
23759
- return color49.dim("No suggestions available.");
24087
+ return color50.dim("No suggestions available.");
23760
24088
  }
23761
24089
  const lines = [
23762
- ` ${color49.cyan("\u{1F4A1} Next steps")} ${color49.dim("(use /next 1, /next 2, or /next 1 2 3)")}`,
24090
+ ` ${color50.cyan("\u{1F4A1} Next steps")} ${color50.dim("(use /next 1, /next 2, or /next 1 2 3)")}`,
23763
24091
  ""
23764
24092
  ];
23765
24093
  for (let i = 0; i < suggestions.length; i++) {
23766
- const num = color49.bold(`${i + 1}.`);
24094
+ const num = color50.bold(`${i + 1}.`);
23767
24095
  const text = suggestions[i] ?? "";
23768
24096
  lines.push(` ${num} ${text}`);
23769
24097
  }
@@ -23830,7 +24158,7 @@ function buildWebuiCommand() {
23830
24158
 
23831
24159
  // src/slash-commands/theme.ts
23832
24160
  import { THEME_PRESET_IDS } from "@wrongstack/core/types";
23833
- import { color as color50, writeOut as writeOut3 } from "@wrongstack/core/utils";
24161
+ import { color as color51, writeOut as writeOut3 } from "@wrongstack/core/utils";
23834
24162
  var THEME_META = {
23835
24163
  catppuccin: { name: "Catppuccin Mocha", desc: "Soft pastel dark theme (Default)" },
23836
24164
  "tokyo-night": { name: "Tokyo Night", desc: "Deep violet, neon orange & cyan" },
@@ -23941,19 +24269,19 @@ async function runThemePicker(reader, activeId) {
23941
24269
  );
23942
24270
  const lines = [];
23943
24271
  lines.push("");
23944
- lines.push(`${color50.bold(color50.amber("WrongStack") + color50.dim(" \u2014 TUI Theme Selection"))}`);
23945
- lines.push(color50.dim(" \u2191\u2193 navigate Enter select q quit"));
24272
+ lines.push(`${color51.bold(color51.amber("WrongStack") + color51.dim(" \u2014 TUI Theme Selection"))}`);
24273
+ lines.push(color51.dim(" \u2191\u2193 navigate Enter select q quit"));
23946
24274
  lines.push("");
23947
- if (hasAbove) lines.push(color50.dim(` \u2026 ${start} more above`));
24275
+ if (hasAbove) lines.push(color51.dim(` \u2026 ${start} more above`));
23948
24276
  for (let i = start; i < end; i++) {
23949
24277
  const p = THEME_OPTIONS[i];
23950
- const mark = p.id === activeId ? color50.green(" [active]") : "";
23951
- const prefix = i === currentCursor ? color50.bold("\u276F ") : " ";
23952
- const name = i === currentCursor ? color50.bold(p.name) : p.name;
24278
+ const mark = p.id === activeId ? color51.green(" [active]") : "";
24279
+ const prefix = i === currentCursor ? color51.bold("\u276F ") : " ";
24280
+ const name = i === currentCursor ? color51.bold(p.name) : p.name;
23953
24281
  const desc = truncateDesc(p.desc, columns, p.id === activeId);
23954
- lines.push(` ${prefix}${name.padEnd(21)} ${color50.dim(desc)}${mark}`);
24282
+ lines.push(` ${prefix}${name.padEnd(21)} ${color51.dim(desc)}${mark}`);
23955
24283
  }
23956
- if (hasBelow) lines.push(color50.dim(` \u2026 ${THEME_OPTIONS.length - end} more below`));
24284
+ if (hasBelow) lines.push(color51.dim(` \u2026 ${THEME_OPTIONS.length - end} more below`));
23957
24285
  lines.push("");
23958
24286
  return lines.join("\n");
23959
24287
  };
@@ -24008,21 +24336,21 @@ function buildThemeCommand(opts) {
24008
24336
  }
24009
24337
  }
24010
24338
  return {
24011
- message: color50.green(`Switched TUI theme preset to "${selected}" (saved to config).`),
24339
+ message: color51.green(`Switched TUI theme preset to "${selected}" (saved to config).`),
24012
24340
  metadata: { themePreset: selected }
24013
24341
  };
24014
24342
  }
24015
24343
  const lines = [
24016
- color50.bold(`Current TUI theme: ${activePreset}`),
24344
+ color51.bold(`Current TUI theme: ${activePreset}`),
24017
24345
  "",
24018
- color50.bold("Available Theme Presets:")
24346
+ color51.bold("Available Theme Presets:")
24019
24347
  ];
24020
24348
  for (const t of THEME_OPTIONS) {
24021
- const mark = t.id === activePreset ? color50.green(" [active]") : "";
24022
- lines.push(` \u2022 ${color50.bold(t.id.padEnd(21))} ${t.desc}${mark}`);
24349
+ const mark = t.id === activePreset ? color51.green(" [active]") : "";
24350
+ lines.push(` \u2022 ${color51.bold(t.id.padEnd(21))} ${t.desc}${mark}`);
24023
24351
  }
24024
24352
  lines.push("");
24025
- lines.push(color50.dim("Usage: /theme <preset>"));
24353
+ lines.push(color51.dim("Usage: /theme <preset>"));
24026
24354
  return { message: lines.join("\n") };
24027
24355
  }
24028
24356
  const preset = args.trim().toLowerCase();
@@ -24038,7 +24366,7 @@ function buildThemeCommand(opts) {
24038
24366
  }
24039
24367
  }
24040
24368
  return {
24041
- message: color50.green(`Switched TUI theme preset to "${preset}" (saved to config).`),
24369
+ message: color51.green(`Switched TUI theme preset to "${preset}" (saved to config).`),
24042
24370
  metadata: { themePreset: preset }
24043
24371
  };
24044
24372
  }
@@ -24046,7 +24374,7 @@ function buildThemeCommand(opts) {
24046
24374
  }
24047
24375
 
24048
24376
  // src/slash-commands/agents.ts
24049
- import { noOpVault as noOpVault7 } from "@wrongstack/core/security";
24377
+ import { noOpVault as noOpVault8 } from "@wrongstack/core/security";
24050
24378
  function formatAgentLine(a) {
24051
24379
  const statusIcon3 = {
24052
24380
  spawned: "\u{1F7E2}",
@@ -24127,7 +24455,7 @@ function buildAgentsCommand(opts) {
24127
24455
  configStore: opts.configStore,
24128
24456
  profileConfigPath: opts.paths.profileConfig(activeProfile),
24129
24457
  inProjectConfigPath: opts.paths.inProjectConfig,
24130
- vault: noOpVault7
24458
+ vault: noOpVault8
24131
24459
  },
24132
24460
  (autonomy) => {
24133
24461
  autonomy.fleetChatVerbosity = mode;
@@ -24285,8 +24613,8 @@ ${lines.join("\n")}` };
24285
24613
 
24286
24614
  // src/slash-commands/hq.ts
24287
24615
  import { readHqRuntimeFileSync, resolveHqConfig, resolveHqDataDir } from "@wrongstack/core/hq";
24288
- import { noOpVault as noOpVault8 } from "@wrongstack/core/security";
24289
- import { color as color51 } from "@wrongstack/core/utils";
24616
+ import { noOpVault as noOpVault9 } from "@wrongstack/core/security";
24617
+ import { color as color52 } from "@wrongstack/core/utils";
24290
24618
  function maskToken(t) {
24291
24619
  if (t.length <= 10) return `${t.slice(0, 2)}\u2026(${t.length})`;
24292
24620
  return `${t.slice(0, 6)}\u2026${t.slice(-4)} (${t.length} chars)`;
@@ -24297,12 +24625,12 @@ async function probeHq(url) {
24297
24625
  const timer = setTimeout(() => ctrl.abort(), 2500);
24298
24626
  const res = await fetch(url, { signal: ctrl.signal, redirect: "manual" }).catch(() => null);
24299
24627
  clearTimeout(timer);
24300
- if (!res) return color51.red("unreachable");
24301
- if (res.ok) return color51.green("reachable");
24302
- if (res.status === 401) return color51.green("reachable") + color51.dim(" (token required)");
24303
- return color51.amber(`reachable (HTTP ${res.status})`);
24628
+ if (!res) return color52.red("unreachable");
24629
+ if (res.ok) return color52.green("reachable");
24630
+ if (res.status === 401) return color52.green("reachable") + color52.dim(" (token required)");
24631
+ return color52.amber(`reachable (HTTP ${res.status})`);
24304
24632
  } catch {
24305
- return color51.red("unreachable");
24633
+ return color52.red("unreachable");
24306
24634
  }
24307
24635
  }
24308
24636
  function buildHqCommand(opts) {
@@ -24336,13 +24664,13 @@ function buildHqCommand(opts) {
24336
24664
  const { cmd, rest } = parseSubcommand(args);
24337
24665
  const sub = cmd;
24338
24666
  if (!opts.configStore || !opts.paths) {
24339
- return { message: `${color51.red("\u2717")} HQ config is unavailable in this surface.` };
24667
+ return { message: `${color52.red("\u2717")} HQ config is unavailable in this surface.` };
24340
24668
  }
24341
24669
  const persistDeps = {
24342
24670
  configStore: opts.configStore,
24343
24671
  profileConfigPath: activeProfileConfigPath(opts.paths, opts.configStore.get()),
24344
24672
  inProjectConfigPath: opts.paths.inProjectConfig,
24345
- vault: noOpVault8,
24673
+ vault: noOpVault9,
24346
24674
  forceGlobal: true
24347
24675
  };
24348
24676
  const currentHq = opts.configStore.get().hq;
@@ -24350,14 +24678,14 @@ function buildHqCommand(opts) {
24350
24678
  const url = (rest[0] ?? "").trim();
24351
24679
  const token = rest.slice(1).join(" ").trim();
24352
24680
  if (!url) {
24353
- return { message: `${color51.amber("Usage:")} /hq set <http://host:3499> [client-token]` };
24681
+ return { message: `${color52.amber("Usage:")} /hq set <http://host:3499> [client-token]` };
24354
24682
  }
24355
24683
  try {
24356
24684
  const parsed = new URL(url);
24357
24685
  if (parsed.protocol !== "http:" && parsed.protocol !== "https:") throw new Error("proto");
24358
24686
  } catch {
24359
24687
  return {
24360
- message: `${color51.red("Invalid URL:")} ${url} ${color51.dim("(expected http://host:3499)")}`
24688
+ message: `${color52.red("Invalid URL:")} ${url} ${color52.dim("(expected http://host:3499)")}`
24361
24689
  };
24362
24690
  }
24363
24691
  await persistConfigSetting(persistDeps, (cfg) => {
@@ -24369,16 +24697,16 @@ function buildHqCommand(opts) {
24369
24697
  });
24370
24698
  const reach = await probeHq(url);
24371
24699
  const tokLine = token ? `
24372
- token: ${color51.dim(maskToken(token))}` : "";
24700
+ token: ${color52.dim(maskToken(token))}` : "";
24373
24701
  return {
24374
- message: `${color51.green("\u2713")} HQ set \u2192 ${color51.cyan(url)}${tokLine}
24702
+ message: `${color52.green("\u2713")} HQ set \u2192 ${color52.cyan(url)}${tokLine}
24375
24703
  status: ${reach}
24376
- ${color51.dim("Connects on the next session start.")}`
24704
+ ${color52.dim("Connects on the next session start.")}`
24377
24705
  };
24378
24706
  }
24379
24707
  if (sub === "token") {
24380
24708
  const token = rest.join(" ").trim();
24381
- if (!token) return { message: `${color51.amber("Usage:")} /hq token <client-token>` };
24709
+ if (!token) return { message: `${color52.amber("Usage:")} /hq token <client-token>` };
24382
24710
  await persistConfigSetting(persistDeps, (cfg) => {
24383
24711
  const hq = cfg.hq ?? {};
24384
24712
  hq.token = token;
@@ -24386,14 +24714,14 @@ function buildHqCommand(opts) {
24386
24714
  cfg.hq = hq;
24387
24715
  });
24388
24716
  return {
24389
- message: `${color51.green("\u2713")} HQ client token saved ${color51.dim(maskToken(token))}`
24717
+ message: `${color52.green("\u2713")} HQ client token saved ${color52.dim(maskToken(token))}`
24390
24718
  };
24391
24719
  }
24392
24720
  if (sub === "raw") {
24393
24721
  const mode = (rest[0] ?? "").trim().toLowerCase();
24394
24722
  if (mode !== "on" && mode !== "off") {
24395
24723
  return {
24396
- message: `${color51.amber("Usage:")} /hq raw on|off ${color51.dim("(publish raw chat/tool content to HQ)")}`
24724
+ message: `${color52.amber("Usage:")} /hq raw on|off ${color52.dim("(publish raw chat/tool content to HQ)")}`
24397
24725
  };
24398
24726
  }
24399
24727
  const on = mode === "on";
@@ -24403,8 +24731,8 @@ function buildHqCommand(opts) {
24403
24731
  cfg.hq = hq;
24404
24732
  });
24405
24733
  return {
24406
- message: `${color51.green("\u2713")} HQ raw content \u2192 ${on ? color51.amber("on (unredacted)") : color51.dim("off (redacted)")}
24407
- ${color51.dim("Applies to sessions started after this change. Only enable for HQ servers you trust.")}`
24734
+ message: `${color52.green("\u2713")} HQ raw content \u2192 ${on ? color52.amber("on (unredacted)") : color52.dim("off (redacted)")}
24735
+ ${color52.dim("Applies to sessions started after this change. Only enable for HQ servers you trust.")}`
24408
24736
  };
24409
24737
  }
24410
24738
  if (sub === "on" || sub === "off") {
@@ -24415,29 +24743,29 @@ function buildHqCommand(opts) {
24415
24743
  cfg.hq = hq;
24416
24744
  });
24417
24745
  return {
24418
- message: `${color51.green("\u2713")} HQ publishing \u2192 ${on ? color51.cyan("on") : color51.dim("off")}`
24746
+ message: `${color52.green("\u2713")} HQ publishing \u2192 ${on ? color52.cyan("on") : color52.dim("off")}`
24419
24747
  };
24420
24748
  }
24421
24749
  if (sub === "clear") {
24422
24750
  await persistConfigSetting(persistDeps, (cfg) => {
24423
24751
  delete cfg.hq;
24424
24752
  });
24425
- return { message: `${color51.green("\u2713")} HQ configuration cleared.` };
24753
+ return { message: `${color52.green("\u2713")} HQ configuration cleared.` };
24426
24754
  }
24427
24755
  if (sub === "" || sub === "status") {
24428
24756
  const dataDir = resolveHqDataDir(currentHq?.dataDir);
24429
24757
  const runtime = readHqRuntimeFileSync(dataDir);
24430
24758
  const resolved = resolveHqConfig({ config: currentHq });
24431
- const lines = [`${color51.bold("\u{1F4CB} WrongStack HQ \u2014 connection")}`, ""];
24759
+ const lines = [`${color52.bold("\u{1F4CB} WrongStack HQ \u2014 connection")}`, ""];
24432
24760
  if (!resolved) {
24433
24761
  lines.push(
24434
- ` ${color51.dim("Not configured.")} Use ${color51.cyan("/hq set <url> [token]")} to connect,`
24762
+ ` ${color52.dim("Not configured.")} Use ${color52.cyan("/hq set <url> [token]")} to connect,`
24435
24763
  );
24436
- lines.push(` or run ${color51.cyan("wstack --hq")} locally (auto-discovered).`);
24764
+ lines.push(` or run ${color52.cyan("wstack --hq")} locally (auto-discovered).`);
24437
24765
  if (runtime) {
24438
24766
  lines.push("");
24439
24767
  lines.push(
24440
- ` ${color51.green("A local HQ is running")} at ${color51.cyan(runtime.url)} ${color51.dim("(start a new session to attach)")}`
24768
+ ` ${color52.green("A local HQ is running")} at ${color52.cyan(runtime.url)} ${color52.dim("(start a new session to attach)")}`
24441
24769
  );
24442
24770
  }
24443
24771
  const message = lines.join("\n");
@@ -24445,35 +24773,35 @@ function buildHqCommand(opts) {
24445
24773
  }
24446
24774
  if (resolved.discover && !runtime) {
24447
24775
  lines.push(
24448
- ` mode: ${color51.cyan("auto-discovery")} ${color51.dim("(no local HQ running yet)")}`
24776
+ ` mode: ${color52.cyan("auto-discovery")} ${color52.dim("(no local HQ running yet)")}`
24449
24777
  );
24450
24778
  lines.push(
24451
- ` ${color51.dim("This session will attach automatically when `wstack --hq` starts")}`
24779
+ ` ${color52.dim("This session will attach automatically when `wstack --hq` starts")}`
24452
24780
  );
24453
- lines.push(` ${color51.dim(`on this machine (watching ${dataDir}).`)}`);
24454
- lines.push(` ${color51.dim("Disable with WRONGSTACK_HQ_ENABLED=0 or /hq off.")}`);
24781
+ lines.push(` ${color52.dim(`on this machine (watching ${dataDir}).`)}`);
24782
+ lines.push(` ${color52.dim("Disable with WRONGSTACK_HQ_ENABLED=0 or /hq off.")}`);
24455
24783
  return { message: lines.join("\n") };
24456
24784
  }
24457
24785
  const source = process.env["WRONGSTACK_HQ_URL"] ? "WRONGSTACK_HQ_URL env" : currentHq?.url ? "config.json" : runtime ? `local HQ marker (pid ${runtime.pid ?? "?"})` : "default";
24458
- lines.push(` url: ${color51.cyan(resolved.url)}`);
24786
+ lines.push(` url: ${color52.cyan(resolved.url)}`);
24459
24787
  lines.push(
24460
- ` enabled: ${resolved.enabled === false ? color51.dim("false") : color51.green("true")}`
24788
+ ` enabled: ${resolved.enabled === false ? color52.dim("false") : color52.green("true")}`
24461
24789
  );
24462
- if (resolved.discover) lines.push(` mode: ${color51.cyan("auto-discovery")}`);
24463
- lines.push(` source: ${color51.dim(source)}`);
24790
+ if (resolved.discover) lines.push(` mode: ${color52.cyan("auto-discovery")}`);
24791
+ lines.push(` source: ${color52.dim(source)}`);
24464
24792
  lines.push(
24465
- ` token: ${resolved.token ? color51.dim(maskToken(resolved.token)) : color51.dim("none (open mode)")}`
24793
+ ` token: ${resolved.token ? color52.dim(maskToken(resolved.token)) : color52.dim("none (open mode)")}`
24466
24794
  );
24467
24795
  lines.push(
24468
- ` content: ${resolved.rawContent === true ? color51.amber("raw (unredacted)") : color51.dim("redacted \u2014 explicitly disabled; enable with /hq raw on")}`
24796
+ ` content: ${resolved.rawContent === true ? color52.amber("raw (unredacted)") : color52.dim("redacted \u2014 explicitly disabled; enable with /hq raw on")}`
24469
24797
  );
24470
- if (resolved.projectAlias) lines.push(` alias: ${color51.cyan(resolved.projectAlias)}`);
24798
+ if (resolved.projectAlias) lines.push(` alias: ${color52.cyan(resolved.projectAlias)}`);
24471
24799
  lines.push(` status: ${await probeHq(resolved.url)}`);
24472
24800
  return { message: lines.join("\n") };
24473
24801
  }
24474
24802
  return {
24475
- message: `${color51.red("Unknown subcommand:")} ${sub}
24476
- ${color51.dim("Try /hq, /hq set <url> [token], /hq raw on|off, /hq on|off, /hq clear, or /help hq")}`
24803
+ message: `${color52.red("Unknown subcommand:")} ${sub}
24804
+ ${color52.dim("Try /hq, /hq set <url> [token], /hq raw on|off, /hq on|off, /hq clear, or /help hq")}`
24477
24805
  };
24478
24806
  }
24479
24807
  };
@@ -24523,12 +24851,12 @@ function buildMouseCommand(_opts) {
24523
24851
  }
24524
24852
 
24525
24853
  // src/slash-commands/project.ts
24526
- import { spawn as spawn5 } from "node:child_process";
24527
- import * as fs14 from "node:fs/promises";
24854
+ import { spawn as spawn6 } from "node:child_process";
24855
+ import * as fs15 from "node:fs/promises";
24528
24856
  import { createRequire } from "node:module";
24529
24857
  import * as path17 from "node:path";
24530
24858
  import {
24531
- color as color52,
24859
+ color as color53,
24532
24860
  ensureProjectGitignore,
24533
24861
  ensureProjectIdentity as ensureProjectIdentity2,
24534
24862
  projectIdentityPath,
@@ -24661,17 +24989,17 @@ async function projectIdentityCommand(opts, ctx, action, confirmed) {
24661
24989
  if (action === "show") {
24662
24990
  const identity = await readProjectIdentity(root);
24663
24991
  return identity ? {
24664
- message: `${color52.bold("Project ID:")} ${color52.cyan(identity.projectId)}
24665
- ${color52.dim(filePath)}`
24666
- } : { message: `No committed project identity. Run ${color52.cyan("/project init")}.` };
24992
+ message: `${color53.bold("Project ID:")} ${color53.cyan(identity.projectId)}
24993
+ ${color53.dim(filePath)}`
24994
+ } : { message: `No committed project identity. Run ${color53.cyan("/project init")}.` };
24667
24995
  }
24668
24996
  if (action === "init") {
24669
24997
  const result2 = await ensureProjectIdentity2(root);
24670
24998
  await ensureProjectGitignore(root);
24671
24999
  return {
24672
- message: result2.created ? `${color52.green("Created")} ${filePath}
24673
- ${color52.cyan(result2.identity.projectId)}
24674
- ${color52.dim("Commit this file so every clone and machine shares the same HQ project.")}` : `${color52.dim("Project identity already exists:")} ${color52.cyan(result2.identity.projectId)}`
25000
+ message: result2.created ? `${color53.green("Created")} ${filePath}
25001
+ ${color53.cyan(result2.identity.projectId)}
25002
+ ${color53.dim("Commit this file so every clone and machine shares the same HQ project.")}` : `${color53.dim("Project identity already exists:")} ${color53.cyan(result2.identity.projectId)}`
24675
25003
  };
24676
25004
  }
24677
25005
  if (!confirmed && opts.confirm) {
@@ -24686,17 +25014,17 @@ ${color52.dim("Commit this file so every clone and machine shares the same HQ pr
24686
25014
  }
24687
25015
  if (!confirmed) {
24688
25016
  return {
24689
- message: `Rekey requires confirmation. Pass ${color52.cyan("--yes")} or ${color52.cyan("-y")}.`
25017
+ message: `Rekey requires confirmation. Pass ${color53.cyan("--yes")} or ${color53.cyan("-y")}.`
24690
25018
  };
24691
25019
  }
24692
25020
  const result = await rekeyProjectIdentity(root);
24693
25021
  await ensureProjectGitignore(root);
24694
25022
  return {
24695
25023
  message: [
24696
- result.previous ? color52.dim(`Previous: ${result.previous.projectId}`) : color52.dim("Previous: none"),
24697
- `${color52.green("New project ID:")} ${color52.cyan(result.identity.projectId)}`,
24698
- color52.dim(`Commit ${filePath} to make this fork independent on every machine.`),
24699
- color52.dim("Restart WrongStack before publishing HQ or Kanban updates under the new ID.")
25024
+ result.previous ? color53.dim(`Previous: ${result.previous.projectId}`) : color53.dim("Previous: none"),
25025
+ `${color53.green("New project ID:")} ${color53.cyan(result.identity.projectId)}`,
25026
+ color53.dim(`Commit ${filePath} to make this fork independent on every machine.`),
25027
+ color53.dim("Restart WrongStack before publishing HQ or Kanban updates under the new ID.")
24700
25028
  ].join("\n")
24701
25029
  };
24702
25030
  }
@@ -24705,7 +25033,7 @@ async function listProjectsCommand(opts, ctx) {
24705
25033
  const currentRoot = ctx?.projectRoot;
24706
25034
  if (manifest.projects.length === 0) {
24707
25035
  return {
24708
- message: color52.dim("No projects registered. Add one: /project add <path> [name]")
25036
+ message: color53.dim("No projects registered. Add one: /project add <path> [name]")
24709
25037
  };
24710
25038
  }
24711
25039
  const sorted = [...manifest.projects].sort((a, b) => {
@@ -24717,19 +25045,19 @@ async function listProjectsCommand(opts, ctx) {
24717
25045
  const lines = [`Projects (${sorted.length}) registered in projects.json:`, ""];
24718
25046
  for (const p of sorted) {
24719
25047
  const isCurrent = p.root === currentRoot;
24720
- const marker = isCurrent ? color52.green("\u25CF") : color52.dim("\u25CB");
24721
- const name = isCurrent ? color52.bold(p.name) : p.name;
24722
- const slug = color52.dim(`[${p.slug}]`);
24723
- const last = color52.dim(fmtLastSeen(p.lastSeen));
25048
+ const marker = isCurrent ? color53.green("\u25CF") : color53.dim("\u25CB");
25049
+ const name = isCurrent ? color53.bold(p.name) : p.name;
25050
+ const slug = color53.dim(`[${p.slug}]`);
25051
+ const last = color53.dim(fmtLastSeen(p.lastSeen));
24724
25052
  lines.push(` ${marker} ${name} ${slug} ${last}`);
24725
25053
  lines.push(` ${p.root}`);
24726
25054
  if (isCurrent) {
24727
- lines.push(` ${color52.green("\u2190 active session")}`);
25055
+ lines.push(` ${color53.green("\u2190 active session")}`);
24728
25056
  }
24729
25057
  lines.push("");
24730
25058
  }
24731
25059
  lines.push(
24732
- color52.dim(
25060
+ color53.dim(
24733
25061
  "Commands: add <path> [name] | rename <slug> <name> | remove <slug> | switch [dir] (no args = picker)"
24734
25062
  )
24735
25063
  );
@@ -24738,19 +25066,19 @@ async function listProjectsCommand(opts, ctx) {
24738
25066
  async function addProjectCommand(opts, ctx, targetPath, displayName) {
24739
25067
  const resolved = path17.resolve(ctx?.projectRoot ?? ctx?.cwd ?? process.cwd(), targetPath);
24740
25068
  try {
24741
- await fs14.access(resolved);
25069
+ await fs15.access(resolved);
24742
25070
  } catch {
24743
- return { message: color52.red(`Directory not found: ${resolved}`) };
25071
+ return { message: color53.red(`Directory not found: ${resolved}`) };
24744
25072
  }
24745
- const stat5 = await fs14.stat(resolved);
25073
+ const stat5 = await fs15.stat(resolved);
24746
25074
  if (!stat5.isDirectory()) {
24747
- return { message: color52.red(`Not a directory: ${resolved}`) };
25075
+ return { message: color53.red(`Not a directory: ${resolved}`) };
24748
25076
  }
24749
25077
  const manifest = await loadManifest(opts.paths?.globalConfig);
24750
25078
  const existing = manifest.projects.find((p) => p.root === resolved);
24751
25079
  if (existing) {
24752
25080
  return {
24753
- message: color52.yellow(`Project already registered: "${existing.name}" (${existing.slug})`)
25081
+ message: color53.yellow(`Project already registered: "${existing.name}" (${existing.slug})`)
24754
25082
  };
24755
25083
  }
24756
25084
  const name = displayName?.trim() || path17.basename(resolved);
@@ -24762,9 +25090,9 @@ async function addProjectCommand(opts, ctx, targetPath, displayName) {
24762
25090
  return {
24763
25091
  message: [
24764
25092
  "",
24765
- color52.green(` Added project: ${name}`),
24766
- color52.dim(` Root: ${resolved}`),
24767
- color52.dim(` Slug: ${slug}`),
25093
+ color53.green(` Added project: ${name}`),
25094
+ color53.dim(` Root: ${resolved}`),
25095
+ color53.dim(` Slug: ${slug}`),
24768
25096
  ""
24769
25097
  ].join("\n")
24770
25098
  };
@@ -24774,7 +25102,7 @@ async function renameProjectCommand(opts, _ctx, slugOrName, newName) {
24774
25102
  const project = findProject(manifest, slugOrName);
24775
25103
  if (!project) {
24776
25104
  return {
24777
- message: color52.red(
25105
+ message: color53.red(
24778
25106
  `Project not found: "${slugOrName}". Use /project list to see available projects.`
24779
25107
  )
24780
25108
  };
@@ -24782,7 +25110,7 @@ async function renameProjectCommand(opts, _ctx, slugOrName, newName) {
24782
25110
  const oldName = project.name;
24783
25111
  project.name = newName;
24784
25112
  await saveManifest(manifest, opts.paths?.globalConfig);
24785
- return { message: color52.green(`Renamed: "${oldName}" \u2192 "${newName}" (${project.slug})`) };
25113
+ return { message: color53.green(`Renamed: "${oldName}" \u2192 "${newName}" (${project.slug})`) };
24786
25114
  }
24787
25115
  async function removeProjectCommand(opts, _ctx, slugOrName) {
24788
25116
  const manifest = await loadManifest(opts.paths?.globalConfig);
@@ -24791,7 +25119,7 @@ async function removeProjectCommand(opts, _ctx, slugOrName) {
24791
25119
  );
24792
25120
  if (idx === -1) {
24793
25121
  return {
24794
- message: color52.red(
25122
+ message: color53.red(
24795
25123
  `Project not found: "${slugOrName}". Use /project list to see available projects.`
24796
25124
  )
24797
25125
  };
@@ -24800,7 +25128,7 @@ async function removeProjectCommand(opts, _ctx, slugOrName) {
24800
25128
  manifest.projects.splice(idx, 1);
24801
25129
  await saveManifest(manifest, opts.paths?.globalConfig);
24802
25130
  return {
24803
- message: color52.dim(
25131
+ message: color53.dim(
24804
25132
  `Removed: "${removed.name}" (${removed.root}) \u2014 data directory kept at ~/.wrongstack/projects/${removed.slug}/`
24805
25133
  )
24806
25134
  };
@@ -24808,13 +25136,13 @@ async function removeProjectCommand(opts, _ctx, slugOrName) {
24808
25136
  async function switchProjectCommand(opts, ctx, target, displayName) {
24809
25137
  const resolved = path17.resolve(ctx?.projectRoot ?? ctx?.cwd ?? process.cwd(), target);
24810
25138
  try {
24811
- await fs14.access(resolved);
25139
+ await fs15.access(resolved);
24812
25140
  } catch {
24813
- return { message: color52.red(`Directory not found: ${resolved}`) };
25141
+ return { message: color53.red(`Directory not found: ${resolved}`) };
24814
25142
  }
24815
- const stat5 = await fs14.stat(resolved);
25143
+ const stat5 = await fs15.stat(resolved);
24816
25144
  if (!stat5.isDirectory()) {
24817
- return { message: color52.red(`Not a directory: ${resolved}`) };
25145
+ return { message: color53.red(`Not a directory: ${resolved}`) };
24818
25146
  }
24819
25147
  let cliPath;
24820
25148
  try {
@@ -24822,12 +25150,12 @@ async function switchProjectCommand(opts, ctx, target, displayName) {
24822
25150
  const pkgPath = req.resolve("@wrongstack/cli/package.json");
24823
25151
  const pkgDir = path17.dirname(pkgPath);
24824
25152
  cliPath = path17.join(pkgDir, "dist", "index.js");
24825
- await fs14.access(cliPath);
25153
+ await fs15.access(cliPath);
24826
25154
  } catch {
24827
25155
  cliPath = process.argv[1] ?? "";
24828
25156
  if (!cliPath) {
24829
25157
  return {
24830
- message: color52.red(
25158
+ message: color53.red(
24831
25159
  "Could not locate the CLI entry point. Run `wstack` manually in the target directory."
24832
25160
  )
24833
25161
  };
@@ -24848,7 +25176,7 @@ async function switchProjectCommand(opts, ctx, target, displayName) {
24848
25176
  const canSwitch = await confirmProjectSwitch(opts, targetName);
24849
25177
  if (!canSwitch) return { message: "" };
24850
25178
  const nodeExe = process.execPath;
24851
- const child = spawn5(nodeExe, [cliPath, "--no-interactive"], {
25179
+ const child = spawn6(nodeExe, [cliPath, "--no-interactive"], {
24852
25180
  cwd: resolved,
24853
25181
  stdio: "inherit",
24854
25182
  detached: false
@@ -24860,14 +25188,14 @@ async function switchProjectCommand(opts, ctx, target, displayName) {
24860
25188
  // and boot/tui-project-spawn.ts documents this exact bug being removed.
24861
25189
  });
24862
25190
  child.on("error", (err) => {
24863
- console.error(color52.red(`Failed to spawn wstack: ${err.message}`));
25191
+ console.error(color53.red(`Failed to spawn wstack: ${err.message}`));
24864
25192
  });
24865
25193
  child.unref();
24866
25194
  return {
24867
25195
  message: [
24868
25196
  "",
24869
- color52.green(` Spawning wstack in ${resolved} ...`),
24870
- color52.dim(" (current session stays open \u2014 Ctrl+C to return)"),
25197
+ color53.green(` Spawning wstack in ${resolved} ...`),
25198
+ color53.dim(" (current session stays open \u2014 Ctrl+C to return)"),
24871
25199
  ""
24872
25200
  ].join("\n")
24873
25201
  };
@@ -24881,45 +25209,45 @@ async function confirmProjectSwitch(opts, targetName) {
24881
25209
  const parallelActive = parallelEngine?.currentState === "running";
24882
25210
  const hasActiveAgents = fleetRunning > 0 || eternalActive || parallelActive;
24883
25211
  if (!hasActiveAgents) return true;
24884
- const parts = [color52.yellow(`\u26A0 Switching projects will stop all running agents.`), ""];
25212
+ const parts = [color53.yellow(`\u26A0 Switching projects will stop all running agents.`), ""];
24885
25213
  if (fleetRunning > 0) {
24886
- parts.push(color52.dim(` \u2022 ${fleetRunning} subagent(s) currently running`));
25214
+ parts.push(color53.dim(` \u2022 ${fleetRunning} subagent(s) currently running`));
24887
25215
  }
24888
25216
  if (eternalActive) {
24889
- parts.push(color52.dim(" \u2022 Eternal engine is active"));
25217
+ parts.push(color53.dim(" \u2022 Eternal engine is active"));
24890
25218
  }
24891
25219
  if (parallelActive) {
24892
- parts.push(color52.dim(" \u2022 Parallel engine is active"));
25220
+ parts.push(color53.dim(" \u2022 Parallel engine is active"));
24893
25221
  }
24894
25222
  parts.push("");
24895
- parts.push(color52.dim(` Target: ${targetName}`));
25223
+ parts.push(color53.dim(` Target: ${targetName}`));
24896
25224
  opts.renderer.write(`
24897
25225
  ${parts.join("\n")}
24898
25226
  `);
24899
25227
  if (!opts.confirm) return true;
24900
25228
  const confirmed = await opts.confirm(
24901
- color52.yellow(`Stop all agents and switch to "${targetName}"?`),
25229
+ color53.yellow(`Stop all agents and switch to "${targetName}"?`),
24902
25230
  false
24903
25231
  // default to No for safety
24904
25232
  );
24905
25233
  if (!confirmed) {
24906
- opts.renderer.write(color52.dim(" Switch cancelled.\n"));
25234
+ opts.renderer.write(color53.dim(" Switch cancelled.\n"));
24907
25235
  return false;
24908
25236
  }
24909
25237
  if (fleetRunning > 0) {
24910
25238
  const killed = opts.onFleetKill ? await opts.onFleetKill() : 0;
24911
25239
  if (killed > 0) {
24912
- opts.renderer.write(color52.dim(` Stopped ${killed} subagent(s).
25240
+ opts.renderer.write(color53.dim(` Stopped ${killed} subagent(s).
24913
25241
  `));
24914
25242
  }
24915
25243
  }
24916
25244
  if (eternalActive) {
24917
25245
  eternalEngine?.stop();
24918
- opts.renderer.write(color52.dim(" Stopped eternal engine.\n"));
25246
+ opts.renderer.write(color53.dim(" Stopped eternal engine.\n"));
24919
25247
  }
24920
25248
  if (parallelActive) {
24921
25249
  parallelEngine?.stop();
24922
- opts.renderer.write(color52.dim(" Stopped parallel engine.\n"));
25250
+ opts.renderer.write(color53.dim(" Stopped parallel engine.\n"));
24923
25251
  }
24924
25252
  return true;
24925
25253
  }
@@ -24931,16 +25259,16 @@ async function switchInteractiveCommand(opts, ctx) {
24931
25259
  currentProjectRoot: currentRoot
24932
25260
  });
24933
25261
  if (!result) {
24934
- return { message: color52.dim("Cancelled.") };
25262
+ return { message: color53.dim("Cancelled.") };
24935
25263
  }
24936
25264
  switch (result.kind) {
24937
25265
  case "project": {
24938
25266
  const project = manifest.projects.find((p) => p.slug === result.key);
24939
25267
  if (!project) {
24940
- return { message: color52.red(`Project not found: ${result.key}`) };
25268
+ return { message: color53.red(`Project not found: ${result.key}`) };
24941
25269
  }
24942
25270
  if (project.root === currentRoot) {
24943
- return { message: color52.dim(`Already in ${project.name} (${project.root})`) };
25271
+ return { message: color53.dim(`Already in ${project.name} (${project.root})`) };
24944
25272
  }
24945
25273
  const canSwitch = await confirmProjectSwitch(opts, project.name);
24946
25274
  if (!canSwitch) return { message: "" };
@@ -24953,11 +25281,11 @@ async function switchInteractiveCommand(opts, ctx) {
24953
25281
  case "prev-sessions":
24954
25282
  return handlePrevSessions(opts, ctx);
24955
25283
  default:
24956
- return { message: color52.dim("Cancelled.") };
25284
+ return { message: color53.dim("Cancelled.") };
24957
25285
  }
24958
25286
  }
24959
25287
  default:
24960
- return { message: color52.dim("Cancelled.") };
25288
+ return { message: color53.dim("Cancelled.") };
24961
25289
  }
24962
25290
  }
24963
25291
  async function spawnInProject(opts, _ctx, root, projectName) {
@@ -24967,12 +25295,12 @@ async function spawnInProject(opts, _ctx, root, projectName) {
24967
25295
  const pkgPath = req.resolve("@wrongstack/cli/package.json");
24968
25296
  const pkgDir = path17.dirname(pkgPath);
24969
25297
  cliPath = path17.join(pkgDir, "dist", "index.js");
24970
- await fs14.access(cliPath);
25298
+ await fs15.access(cliPath);
24971
25299
  } catch {
24972
25300
  cliPath = process.argv[1] ?? "";
24973
25301
  if (!cliPath) {
24974
25302
  return {
24975
- message: color52.red(
25303
+ message: color53.red(
24976
25304
  "Could not locate the CLI entry point. Run `wstack` manually in the target directory."
24977
25305
  )
24978
25306
  };
@@ -24990,7 +25318,7 @@ async function spawnInProject(opts, _ctx, root, projectName) {
24990
25318
  }
24991
25319
  await saveManifest(manifest, opts.paths?.globalConfig);
24992
25320
  const nodeExe = process.execPath;
24993
- const child = spawn5(nodeExe, [cliPath, "--no-interactive"], {
25321
+ const child = spawn6(nodeExe, [cliPath, "--no-interactive"], {
24994
25322
  cwd: root,
24995
25323
  stdio: "inherit",
24996
25324
  detached: false
@@ -25002,15 +25330,15 @@ async function spawnInProject(opts, _ctx, root, projectName) {
25002
25330
  // and boot/tui-project-spawn.ts documents this exact bug being removed.
25003
25331
  });
25004
25332
  child.on("error", (err) => {
25005
- console.error(color52.red(`Failed to spawn wstack: ${err.message}`));
25333
+ console.error(color53.red(`Failed to spawn wstack: ${err.message}`));
25006
25334
  });
25007
25335
  child.unref();
25008
25336
  return {
25009
25337
  message: [
25010
25338
  "",
25011
- color52.green(` Switched to ${projectName}`),
25012
- color52.dim(` Root: ${root}`),
25013
- color52.dim(" (current session stays open \u2014 Ctrl+C to return)"),
25339
+ color53.green(` Switched to ${projectName}`),
25340
+ color53.dim(` Root: ${root}`),
25341
+ color53.dim(" (current session stays open \u2014 Ctrl+C to return)"),
25014
25342
  ""
25015
25343
  ].join("\n")
25016
25344
  };
@@ -25022,17 +25350,17 @@ async function handleNewSession(_opts, _ctx) {
25022
25350
  const pkgPath = req.resolve("@wrongstack/cli/package.json");
25023
25351
  const pkgDir = path17.dirname(pkgPath);
25024
25352
  cliPath = path17.join(pkgDir, "dist", "index.js");
25025
- await fs14.access(cliPath);
25353
+ await fs15.access(cliPath);
25026
25354
  } catch {
25027
25355
  cliPath = process.argv[1] ?? "";
25028
25356
  if (!cliPath) {
25029
25357
  return {
25030
- message: color52.red("Could not locate the CLI entry point. Run `wstack` manually.")
25358
+ message: color53.red("Could not locate the CLI entry point. Run `wstack` manually.")
25031
25359
  };
25032
25360
  }
25033
25361
  }
25034
25362
  const nodeExe = process.execPath;
25035
- const child = spawn5(nodeExe, [cliPath, "--no-interactive"], {
25363
+ const child = spawn6(nodeExe, [cliPath, "--no-interactive"], {
25036
25364
  cwd: process.cwd(),
25037
25365
  stdio: "inherit",
25038
25366
  detached: false
@@ -25044,14 +25372,14 @@ async function handleNewSession(_opts, _ctx) {
25044
25372
  // and boot/tui-project-spawn.ts documents this exact bug being removed.
25045
25373
  });
25046
25374
  child.on("error", (err) => {
25047
- console.error(color52.red(`Failed to spawn wstack: ${err.message}`));
25375
+ console.error(color53.red(`Failed to spawn wstack: ${err.message}`));
25048
25376
  });
25049
25377
  child.unref();
25050
25378
  return {
25051
25379
  message: [
25052
25380
  "",
25053
- color52.green(" Starting new session ..."),
25054
- color52.dim(" (current session stays open \u2014 Ctrl+C to return)"),
25381
+ color53.green(" Starting new session ..."),
25382
+ color53.dim(" (current session stays open \u2014 Ctrl+C to return)"),
25055
25383
  ""
25056
25384
  ].join("\n")
25057
25385
  };
@@ -25062,36 +25390,36 @@ async function handlePrevSessions(opts, _ctx) {
25062
25390
  }
25063
25391
  const list = await opts.sessionStore.list(15);
25064
25392
  if (list.length === 0) {
25065
- return { message: color52.dim("No saved sessions.") };
25393
+ return { message: color53.dim("No saved sessions.") };
25066
25394
  }
25067
25395
  const currentId = opts.context?.session?.id;
25068
- const lines = [color52.bold(`Recent sessions (${list.length}):`), ""];
25396
+ const lines = [color53.bold(`Recent sessions (${list.length}):`), ""];
25069
25397
  for (const s of list) {
25070
25398
  const isCurrent = s.id === currentId;
25071
- const marker = isCurrent ? color52.cyan("\u25CF") : " ";
25072
- const date = color52.dim(s.startedAt.slice(0, 16).replace("T", " "));
25399
+ const marker = isCurrent ? color53.cyan("\u25CF") : " ";
25400
+ const date = color53.dim(s.startedAt.slice(0, 16).replace("T", " "));
25073
25401
  const stats = [
25074
- color52.dim(`${s.tokenTotal.toLocaleString()} tok`),
25075
- s.toolCallCount ? color52.cyan(`${s.toolCallCount} calls`) : "",
25076
- s.iterationCount ? color52.dim(`${s.iterationCount} iter`) : ""
25402
+ color53.dim(`${s.tokenTotal.toLocaleString()} tok`),
25403
+ s.toolCallCount ? color53.cyan(`${s.toolCallCount} calls`) : "",
25404
+ s.iterationCount ? color53.dim(`${s.iterationCount} iter`) : ""
25077
25405
  ].filter(Boolean).join(" ");
25078
- const outcome = s.outcome === "completed" ? color52.green("\u2713") : s.outcome === "aborted" ? color52.yellow("\u26A0") : s.outcome === "error" ? color52.red("\u2717") : color52.dim("?");
25079
- lines.push(` ${marker} ${color52.bold(s.id)} ${date}`);
25080
- lines.push(` ${stats} ${outcome} ${color52.dim(s.title)}`);
25406
+ const outcome = s.outcome === "completed" ? color53.green("\u2713") : s.outcome === "aborted" ? color53.yellow("\u26A0") : s.outcome === "error" ? color53.red("\u2717") : color53.dim("?");
25407
+ lines.push(` ${marker} ${color53.bold(s.id)} ${date}`);
25408
+ lines.push(` ${stats} ${outcome} ${color53.dim(s.title)}`);
25081
25409
  lines.push("");
25082
25410
  }
25083
- lines.push(color52.dim("Resume: /sessions or wstack resume <id>"));
25411
+ lines.push(color53.dim("Resume: /sessions or wstack resume <id>"));
25084
25412
  return { message: lines.join("\n") };
25085
25413
  }
25086
25414
 
25087
25415
  // src/slash-commands/review.ts
25088
- import { spawn as spawn6 } from "node:child_process";
25416
+ import { spawn as spawn7 } from "node:child_process";
25089
25417
  import * as fsp3 from "node:fs/promises";
25090
25418
  import * as path18 from "node:path";
25091
25419
  import { emitReviewIfChanged } from "@wrongstack/core/plugin";
25092
25420
  async function runGit2(args, cwd) {
25093
25421
  return new Promise((resolve8) => {
25094
- const child = spawn6("git", args, {
25422
+ const child = spawn7("git", args, {
25095
25423
  cwd,
25096
25424
  stdio: ["ignore", "pipe", "pipe"],
25097
25425
  signal: AbortSignal.timeout(1e4),
@@ -25288,11 +25616,15 @@ function buildSecurityCommand(opts) {
25288
25616
  }
25289
25617
 
25290
25618
  // src/slash-commands/settings.ts
25291
- import { color as color55 } from "@wrongstack/core/utils";
25619
+ import { color as color56 } from "@wrongstack/core/utils";
25292
25620
 
25293
25621
  // src/slash-commands/settings-mutations.ts
25294
- import { noOpVault as noOpVault9 } from "@wrongstack/core/security";
25295
- import { color as color53, toErrorMessage as toErrorMessage23 } from "@wrongstack/core/utils";
25622
+ import { noOpVault as noOpVault10 } from "@wrongstack/core/security";
25623
+ import {
25624
+ isReasoningEffort as isReasoningEffort3,
25625
+ REASONING_EFFORT_LEVELS as REASONING_EFFORT_LEVELS3
25626
+ } from "@wrongstack/core/types";
25627
+ import { color as color54, toErrorMessage as toErrorMessage23 } from "@wrongstack/core/utils";
25296
25628
  import { getProcessRegistry } from "@wrongstack/tools";
25297
25629
 
25298
25630
  // src/utils/delay-format.ts
@@ -25355,13 +25687,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25355
25687
  configStore: opts.configStore,
25356
25688
  profileConfigPath: opts.paths.profileConfig(activeProfile),
25357
25689
  inProjectConfigPath: opts.paths.inProjectConfig,
25358
- vault: noOpVault9
25690
+ vault: noOpVault10
25359
25691
  };
25360
25692
  try {
25361
25693
  if (sub === "hq") {
25362
25694
  const raw = (rest[0] ?? "").toLowerCase();
25363
25695
  if (!["on", "off"].includes(raw)) {
25364
- return { message: `${color53.amber("Usage:")} /settings hq on|off` };
25696
+ return { message: `${color54.amber("Usage:")} /settings hq on|off` };
25365
25697
  }
25366
25698
  const on = raw === "on";
25367
25699
  await persistConfigSetting({ ...persistDeps, forceGlobal: true }, (cfg) => {
@@ -25370,19 +25702,19 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25370
25702
  cfg.hq = hq;
25371
25703
  });
25372
25704
  return {
25373
- message: `${color53.green("\u2713")} HQ publishing \u2192 ${on ? color53.cyan("on") : color53.dim("off")}`
25705
+ message: `${color54.green("\u2713")} HQ publishing \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
25374
25706
  };
25375
25707
  }
25376
25708
  if (sub === "hq-url") {
25377
25709
  const raw = rest.join(" ").trim();
25378
25710
  if (!raw)
25379
- return { message: `${color53.amber("Usage:")} /settings hq-url <http://host:3499>` };
25711
+ return { message: `${color54.amber("Usage:")} /settings hq-url <http://host:3499>` };
25380
25712
  try {
25381
25713
  const url = new URL(raw);
25382
25714
  if (url.protocol !== "http:" && url.protocol !== "https:")
25383
25715
  throw new Error("bad protocol");
25384
25716
  } catch {
25385
- return { message: `${color53.red("Invalid URL")}: ${raw}` };
25717
+ return { message: `${color54.red("Invalid URL")}: ${raw}` };
25386
25718
  }
25387
25719
  await persistConfigSetting({ ...persistDeps, forceGlobal: true }, (cfg) => {
25388
25720
  const hq = cfg.hq ?? {};
@@ -25390,12 +25722,12 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25390
25722
  hq.enabled = true;
25391
25723
  cfg.hq = hq;
25392
25724
  });
25393
- return { message: `${color53.green("\u2713")} HQ URL \u2192 ${color53.cyan(raw)}` };
25725
+ return { message: `${color54.green("\u2713")} HQ URL \u2192 ${color54.cyan(raw)}` };
25394
25726
  }
25395
25727
  if (sub === "hq-token") {
25396
25728
  const token = rest.join(" ").trim();
25397
25729
  if (!token)
25398
- return { message: `${color53.amber("Usage:")} /settings hq-token <client-token>` };
25730
+ return { message: `${color54.amber("Usage:")} /settings hq-token <client-token>` };
25399
25731
  await persistConfigSetting({ ...persistDeps, forceGlobal: true }, (cfg) => {
25400
25732
  const hq = cfg.hq ?? {};
25401
25733
  hq.token = token;
@@ -25403,13 +25735,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25403
25735
  cfg.hq = hq;
25404
25736
  });
25405
25737
  return {
25406
- message: `${color53.green("\u2713")} HQ token saved ${color53.dim("(active profile config)")}`
25738
+ message: `${color54.green("\u2713")} HQ token saved ${color54.dim("(active profile config)")}`
25407
25739
  };
25408
25740
  }
25409
25741
  if (sub === "hq-raw") {
25410
25742
  const raw = (rest[0] ?? "").toLowerCase();
25411
25743
  if (!["on", "off"].includes(raw)) {
25412
- return { message: `${color53.amber("Usage:")} /settings hq-raw on|off` };
25744
+ return { message: `${color54.amber("Usage:")} /settings hq-raw on|off` };
25413
25745
  }
25414
25746
  const on = raw === "on";
25415
25747
  await persistConfigSetting({ ...persistDeps, forceGlobal: true }, (cfg) => {
@@ -25418,56 +25750,56 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25418
25750
  cfg.hq = hq;
25419
25751
  });
25420
25752
  return {
25421
- message: `${color53.green("\u2713")} HQ raw content \u2192 ${on ? color53.cyan("on") : color53.dim("off")}`
25753
+ message: `${color54.green("\u2713")} HQ raw content \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
25422
25754
  };
25423
25755
  }
25424
25756
  if (sub === "delay") {
25425
25757
  const raw = rest[0];
25426
25758
  if (raw === void 0) {
25427
25759
  return {
25428
- message: `${color53.amber("Usage:")} /settings delay <seconds> ${color53.dim("(0 disables)")}`
25760
+ message: `${color54.amber("Usage:")} /settings delay <seconds> ${color54.dim("(0 disables)")}`
25429
25761
  };
25430
25762
  }
25431
25763
  const seconds = Number.parseFloat(raw);
25432
25764
  if (Number.isNaN(seconds) || seconds < 0) {
25433
25765
  return {
25434
- message: `${color53.red("Invalid number")}: "${raw}". Enter seconds, e.g. /settings delay 30`
25766
+ message: `${color54.red("Invalid number")}: "${raw}". Enter seconds, e.g. /settings delay 30`
25435
25767
  };
25436
25768
  }
25437
25769
  const ms = Math.round(seconds * 1e3);
25438
25770
  await persistAutonomySetting(persistDeps, (autonomy) => {
25439
25771
  autonomy.autoProceedDelayMs = ms;
25440
25772
  });
25441
- return { message: `${color53.green("\u2713")} auto-proceed delay \u2192 ${formatDelay(ms)}` };
25773
+ return { message: `${color54.green("\u2713")} auto-proceed delay \u2192 ${formatDelay(ms)}` };
25442
25774
  }
25443
25775
  if (sub === "mode") {
25444
25776
  const raw = (rest[0] ?? "").toLowerCase();
25445
25777
  const modes = ["off", "suggest", "auto"];
25446
25778
  if (!modes.includes(raw)) {
25447
- return { message: `${color53.amber("Usage:")} /settings mode off|suggest|auto` };
25779
+ return { message: `${color54.amber("Usage:")} /settings mode off|suggest|auto` };
25448
25780
  }
25449
25781
  await persistAutonomySetting(persistDeps, (autonomy) => {
25450
25782
  autonomy.defaultMode = raw;
25451
25783
  });
25452
- return { message: `${color53.green("\u2713")} default autonomy \u2192 ${color53.bold(raw)}` };
25784
+ return { message: `${color54.green("\u2713")} default autonomy \u2192 ${color54.bold(raw)}` };
25453
25785
  }
25454
25786
  if (sub === "hints") {
25455
25787
  const raw = (rest[0] ?? "").toLowerCase();
25456
25788
  if (!["on", "off"].includes(raw)) {
25457
- return { message: `${color53.amber("Usage:")} /settings hints on|off` };
25789
+ return { message: `${color54.amber("Usage:")} /settings hints on|off` };
25458
25790
  }
25459
25791
  const on = raw === "on";
25460
25792
  await persistConfigSetting(persistDeps, (cfg) => {
25461
25793
  cfg.hints = on;
25462
25794
  });
25463
25795
  return {
25464
- message: `${color53.green("\u2713")} launch hints \u2192 ${on ? color53.cyan("on") : color53.dim("off")}`
25796
+ message: `${color54.green("\u2713")} launch hints \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
25465
25797
  };
25466
25798
  }
25467
25799
  if (sub === "debug-stream") {
25468
25800
  const raw = (rest[0] ?? "").toLowerCase();
25469
25801
  if (!["on", "off"].includes(raw)) {
25470
- return { message: `${color53.amber("Usage:")} /settings debug-stream on|off` };
25802
+ return { message: `${color54.amber("Usage:")} /settings debug-stream on|off` };
25471
25803
  }
25472
25804
  const on = raw === "on";
25473
25805
  const { setDebugStreamEnabled } = await import("@wrongstack/providers");
@@ -25476,24 +25808,24 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25476
25808
  cfg.debugStream = on;
25477
25809
  });
25478
25810
  return {
25479
- message: `${color53.green("\u2713")} debug stream \u2192 ${on ? color53.cyan("on") : color53.dim("off")} ${color53.dim("raw SSE hex-dump to stderr")}`
25811
+ message: `${color54.green("\u2713")} debug stream \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("raw SSE hex-dump to stderr")}`
25480
25812
  };
25481
25813
  }
25482
25814
  if (sub === "config-scope") {
25483
25815
  const raw = (rest[0] ?? "").toLowerCase();
25484
25816
  if (!["global", "project"].includes(raw)) {
25485
- return { message: `${color53.amber("Usage:")} /settings config-scope global|project` };
25817
+ return { message: `${color54.amber("Usage:")} /settings config-scope global|project` };
25486
25818
  }
25487
25819
  await persistConfigSetting(persistDeps, (cfg) => {
25488
25820
  cfg.configScope = raw;
25489
25821
  });
25490
- const label = raw === "project" ? `${color53.cyan("project")} \u2014 settings saved to <project>/.wrongstack/config.json` : `${color53.cyan("global")} \u2014 settings saved to ~/.wrongstack/profiles/${activeProfile}/config.json`;
25491
- return { message: `${color53.green("\u2713")} config scope \u2192 ${label}` };
25822
+ const label = raw === "project" ? `${color54.cyan("project")} \u2014 settings saved to <project>/.wrongstack/config.json` : `${color54.cyan("global")} \u2014 settings saved to ~/.wrongstack/profiles/${activeProfile}/config.json`;
25823
+ return { message: `${color54.green("\u2713")} config scope \u2192 ${label}` };
25492
25824
  }
25493
25825
  if (sub === "fs-access") {
25494
25826
  const raw = (rest[0] ?? "").toLowerCase();
25495
25827
  if (!["unrestricted", "project"].includes(raw)) {
25496
- return { message: `${color53.amber("Usage:")} /settings fs-access unrestricted|project` };
25828
+ return { message: `${color54.amber("Usage:")} /settings fs-access unrestricted|project` };
25497
25829
  }
25498
25830
  const restrict = raw === "project";
25499
25831
  const fsAccess = deriveFsAccessPair({ restrictFsToRoot: restrict });
@@ -25505,15 +25837,15 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25505
25837
  features.allowOutsideProjectRoot = fsAccess.allowOutsideProjectRoot;
25506
25838
  cfg.features = features;
25507
25839
  });
25508
- const label = restrict ? `${color53.cyan("project")} \u2014 file tools confined to the project root` : `${color53.cyan("unrestricted")} \u2014 file tools may access paths outside the project root`;
25840
+ const label = restrict ? `${color54.cyan("project")} \u2014 file tools confined to the project root` : `${color54.cyan("unrestricted")} \u2014 file tools may access paths outside the project root`;
25509
25841
  return {
25510
- message: `${color53.green("\u2713")} filesystem access \u2192 ${label} ${color53.dim("(restart or re-open the session to apply)")}`
25842
+ message: `${color54.green("\u2713")} filesystem access \u2192 ${label} ${color54.dim("(restart or re-open the session to apply)")}`
25511
25843
  };
25512
25844
  }
25513
25845
  if (sub === "refine") {
25514
25846
  const raw = (rest[0] ?? "").toLowerCase();
25515
25847
  if (!["on", "off"].includes(raw)) {
25516
- return { message: `${color53.amber("Usage:")} /settings refine on|off` };
25848
+ return { message: `${color54.amber("Usage:")} /settings refine on|off` };
25517
25849
  }
25518
25850
  const on = raw === "on";
25519
25851
  await persistAutonomySetting(persistDeps, (autonomy) => {
@@ -25523,52 +25855,52 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25523
25855
  opts.enhanceController.setEnabled(on);
25524
25856
  }
25525
25857
  return {
25526
- message: `${color53.green("\u2713")} refine \u2192 ${on ? color53.cyan("on") : color53.dim("off")} ${color53.dim(on ? "prompts will be refined before sending" : "prompts sent verbatim")}`
25858
+ message: `${color54.green("\u2713")} refine \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim(on ? "prompts will be refined before sending" : "prompts sent verbatim")}`
25527
25859
  };
25528
25860
  }
25529
25861
  if (sub === "refine-delay") {
25530
25862
  const raw = rest[0];
25531
25863
  if (raw === void 0) {
25532
- return { message: `${color53.amber("Usage:")} /settings refine-delay <seconds>` };
25864
+ return { message: `${color54.amber("Usage:")} /settings refine-delay <seconds>` };
25533
25865
  }
25534
25866
  const seconds = Number.parseFloat(raw);
25535
25867
  if (Number.isNaN(seconds) || seconds < 0) {
25536
25868
  return {
25537
- message: `${color53.red("Invalid number")}: "${raw}". Enter seconds, e.g. /settings refine-delay 30`
25869
+ message: `${color54.red("Invalid number")}: "${raw}". Enter seconds, e.g. /settings refine-delay 30`
25538
25870
  };
25539
25871
  }
25540
25872
  const ms = Math.round(seconds * 1e3);
25541
25873
  await persistAutonomySetting(persistDeps, (autonomy) => {
25542
25874
  autonomy.enhanceDelayMs = ms;
25543
25875
  });
25544
- return { message: `${color53.green("\u2713")} refine-delay \u2192 ${formatDelay(ms)}` };
25876
+ return { message: `${color54.green("\u2713")} refine-delay \u2192 ${formatDelay(ms)}` };
25545
25877
  }
25546
25878
  if (sub === "refine-language") {
25547
25879
  const raw = (rest[0] ?? "").toLowerCase();
25548
25880
  if (!["original", "english"].includes(raw)) {
25549
25881
  return {
25550
- message: `${color53.amber("Usage:")} /settings refine-language original|english`
25882
+ message: `${color54.amber("Usage:")} /settings refine-language original|english`
25551
25883
  };
25552
25884
  }
25553
25885
  await persistAutonomySetting(persistDeps, (autonomy) => {
25554
25886
  autonomy.enhanceLanguage = raw;
25555
25887
  });
25556
- const label = raw === "original" ? `${color53.cyan("original")} \u2014 use the language you wrote in` : `${color53.cyan("english")} \u2014 translate to English`;
25557
- return { message: `${color53.green("\u2713")} refine-language \u2192 ${label}` };
25888
+ const label = raw === "original" ? `${color54.cyan("original")} \u2014 use the language you wrote in` : `${color54.cyan("english")} \u2014 translate to English`;
25889
+ return { message: `${color54.green("\u2713")} refine-language \u2192 ${label}` };
25558
25890
  }
25559
25891
  if (sub === "refiner-provider") {
25560
25892
  const raw = rest.join(" ").trim();
25561
25893
  const currentProvider = opts.configStore.get().autonomy?.refinerProvider;
25562
25894
  if (!raw) {
25563
25895
  return {
25564
- message: `${color53.amber("Usage:")} /settings refiner-provider <providerId> ${color53.dim('(e.g. "openai", "anthropic")' + (currentProvider ? ` Current: ${currentProvider}` : ""))}`
25896
+ message: `${color54.amber("Usage:")} /settings refiner-provider <providerId> ${color54.dim('(e.g. "openai", "anthropic")' + (currentProvider ? ` Current: ${currentProvider}` : ""))}`
25565
25897
  };
25566
25898
  }
25567
25899
  await persistAutonomySetting(persistDeps, (autonomy) => {
25568
25900
  autonomy.refinerProvider = raw;
25569
25901
  });
25570
25902
  return {
25571
- message: `${color53.green("\u2713")} refiner-provider \u2192 ${color53.cyan(raw)} ${color53.dim("goal refinement will use this provider when refiner-model is also set")}`
25903
+ message: `${color54.green("\u2713")} refiner-provider \u2192 ${color54.cyan(raw)} ${color54.dim("goal refinement will use this provider when refiner-model is also set")}`
25572
25904
  };
25573
25905
  }
25574
25906
  if (sub === "refiner-model") {
@@ -25576,14 +25908,14 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25576
25908
  const currentModel = opts.configStore.get().autonomy?.refinerModel;
25577
25909
  if (!raw) {
25578
25910
  return {
25579
- message: `${color53.amber("Usage:")} /settings refiner-model <modelId> ${color53.dim('(must be a favorite or the active model; e.g. "gpt-4o-mini")' + (currentModel ? ` Current: ${currentModel}` : ""))}`
25911
+ message: `${color54.amber("Usage:")} /settings refiner-model <modelId> ${color54.dim('(must be a favorite or the active model; e.g. "gpt-4o-mini")' + (currentModel ? ` Current: ${currentModel}` : ""))}`
25580
25912
  };
25581
25913
  }
25582
25914
  await persistAutonomySetting(persistDeps, (autonomy) => {
25583
25915
  autonomy.refinerModel = raw;
25584
25916
  });
25585
25917
  return {
25586
- message: `${color53.green("\u2713")} refiner-model \u2192 ${color53.cyan(raw)} ${color53.dim("goal refinement will use this model when it passes favorites/active validation")}`
25918
+ message: `${color54.green("\u2713")} refiner-model \u2192 ${color54.cyan(raw)} ${color54.dim("goal refinement will use this model when it passes favorites/active validation")}`
25587
25919
  };
25588
25920
  }
25589
25921
  if (sub === "refiner-fallback-profile") {
@@ -25591,14 +25923,14 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25591
25923
  const currentProfile = opts.configStore.get().autonomy?.refinerFallbackProfile;
25592
25924
  if (!raw) {
25593
25925
  return {
25594
- message: `${color53.amber("Usage:")} /settings refiner-fallback-profile <name> ${color53.dim('(e.g. "default")' + (currentProfile ? ` Current: ${currentProfile}` : ""))}`
25926
+ message: `${color54.amber("Usage:")} /settings refiner-fallback-profile <name> ${color54.dim('(e.g. "default")' + (currentProfile ? ` Current: ${currentProfile}` : ""))}`
25595
25927
  };
25596
25928
  }
25597
25929
  await persistAutonomySetting(persistDeps, (autonomy) => {
25598
25930
  autonomy.refinerFallbackProfile = raw;
25599
25931
  });
25600
25932
  return {
25601
- message: `${color53.green("\u2713")} refiner-fallback-profile \u2192 ${color53.cyan(raw)} ${color53.dim("goal refinement will use the first valid entry from this profile chain")}`
25933
+ message: `${color54.green("\u2713")} refiner-fallback-profile \u2192 ${color54.cyan(raw)} ${color54.dim("goal refinement will use the first valid entry from this profile chain")}`
25602
25934
  };
25603
25935
  }
25604
25936
  if (sub === "refiner-clear") {
@@ -25608,7 +25940,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25608
25940
  autonomy.refinerFallbackProfile = void 0;
25609
25941
  });
25610
25942
  return {
25611
- message: `${color53.green("\u2713")} Refiner config cleared ${color53.dim("goal refinement will use the session provider+model")}`
25943
+ message: `${color54.green("\u2713")} Refiner config cleared ${color54.dim("goal refinement will use the session provider+model")}`
25612
25944
  };
25613
25945
  }
25614
25946
  if (sub === "semver-part") {
@@ -25616,7 +25948,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25616
25948
  const parts = ["patch", "minor", "major", "auto"];
25617
25949
  if (!parts.includes(raw)) {
25618
25950
  return {
25619
- message: `${color53.amber("Usage:")} /settings semver-part patch|minor|major|auto`
25951
+ message: `${color54.amber("Usage:")} /settings semver-part patch|minor|major|auto`
25620
25952
  };
25621
25953
  }
25622
25954
  await persistConfigSetting({ ...persistDeps, inProjectConfigPath: void 0 }, (cfg) => {
@@ -25625,13 +25957,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25625
25957
  cfg.extensions = ext;
25626
25958
  });
25627
25959
  return {
25628
- message: `${color53.green("\u2713")} semver default part \u2192 ${color53.bold(raw)} ${color53.dim("saved to active profile config; used when /semver or semver_bump gets no explicit part")}`
25960
+ message: `${color54.green("\u2713")} semver default part \u2192 ${color54.bold(raw)} ${color54.dim("saved to active profile config; used when /semver or semver_bump gets no explicit part")}`
25629
25961
  };
25630
25962
  }
25631
25963
  if (sub === "breaker") {
25632
25964
  const raw = (rest[0] ?? "").toLowerCase();
25633
25965
  if (!["on", "off"].includes(raw)) {
25634
- return { message: `${color53.amber("Usage:")} /settings breaker on|off` };
25966
+ return { message: `${color54.amber("Usage:")} /settings breaker on|off` };
25635
25967
  }
25636
25968
  const on = raw === "on";
25637
25969
  await persistConfigSetting(persistDeps, (cfg) => {
@@ -25640,20 +25972,20 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25640
25972
  });
25641
25973
  getProcessRegistry().setBreakerConfig({ enabled: on });
25642
25974
  return {
25643
- message: `${color53.green("\u2713")} circuit breaker \u2192 ${on ? color53.cyan("on") : color53.dim("off")} ${color53.dim(on ? "bash/exec gated on repeated failures; trips arm the kill/reset countdown" : "bash/exec always proceed")}`
25975
+ message: `${color54.green("\u2713")} circuit breaker \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim(on ? "bash/exec gated on repeated failures; trips arm the kill/reset countdown" : "bash/exec always proceed")}`
25644
25976
  };
25645
25977
  }
25646
25978
  if (sub === "breaker-timeout") {
25647
25979
  const raw = rest[0];
25648
25980
  if (raw === void 0) {
25649
25981
  return {
25650
- message: `${color53.amber("Usage:")} /settings breaker-timeout <seconds> ${color53.dim("(0 = manual recovery only)")}`
25982
+ message: `${color54.amber("Usage:")} /settings breaker-timeout <seconds> ${color54.dim("(0 = manual recovery only)")}`
25651
25983
  };
25652
25984
  }
25653
25985
  const seconds = Number.parseFloat(raw);
25654
25986
  if (Number.isNaN(seconds) || seconds < 0) {
25655
25987
  return {
25656
- message: `${color53.red("Invalid number")}: "${raw}". Enter seconds, e.g. /settings breaker-timeout 60`
25988
+ message: `${color54.red("Invalid number")}: "${raw}". Enter seconds, e.g. /settings breaker-timeout 60`
25657
25989
  };
25658
25990
  }
25659
25991
  const ms = Math.round(seconds * 1e3);
@@ -25666,7 +25998,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25666
25998
  });
25667
25999
  getProcessRegistry().setBreakerConfig({ autoKillResetMs: ms });
25668
26000
  return {
25669
- message: `${color53.green("\u2713")} breaker kill/reset timeout \u2192 ${ms > 0 ? formatDelay(ms) : color53.dim("manual")} ${color53.dim(ms > 0 ? "statusline shows a countdown when the breaker trips" : "breaker trips require /kill reset")}`
26001
+ message: `${color54.green("\u2713")} breaker kill/reset timeout \u2192 ${ms > 0 ? formatDelay(ms) : color54.dim("manual")} ${color54.dim(ms > 0 ? "statusline shows a countdown when the breaker trips" : "breaker trips require /kill reset")}`
25670
26002
  };
25671
26003
  }
25672
26004
  if (sub === "context-mode") {
@@ -25674,7 +26006,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25674
26006
  const modes = ["balanced", "frugal", "deep"];
25675
26007
  if (!modes.includes(raw)) {
25676
26008
  return {
25677
- message: `${color53.amber("Usage:")} /settings context-mode balanced|frugal|deep`
26009
+ message: `${color54.amber("Usage:")} /settings context-mode balanced|frugal|deep`
25678
26010
  };
25679
26011
  }
25680
26012
  await persistConfigSetting(persistDeps, (cfg) => {
@@ -25683,7 +26015,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25683
26015
  cfg.context = ctx;
25684
26016
  });
25685
26017
  return {
25686
- message: `${color53.green("\u2713")} context mode \u2192 ${color53.cyan(raw)} ${color53.dim("context window policy")}`
26018
+ message: `${color54.green("\u2713")} context mode \u2192 ${color54.cyan(raw)} ${color54.dim("context window policy")}`
25687
26019
  };
25688
26020
  }
25689
26021
  if (sub === "context-strategy") {
@@ -25691,7 +26023,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25691
26023
  const strategies = ["hybrid", "intelligent", "selective"];
25692
26024
  if (!strategies.includes(raw)) {
25693
26025
  return {
25694
- message: `${color53.amber("Usage:")} /settings context-strategy hybrid|intelligent|selective`
26026
+ message: `${color54.amber("Usage:")} /settings context-strategy hybrid|intelligent|selective`
25695
26027
  };
25696
26028
  }
25697
26029
  await persistConfigSetting(persistDeps, (cfg) => {
@@ -25700,13 +26032,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25700
26032
  cfg.context = ctx;
25701
26033
  });
25702
26034
  return {
25703
- message: `${color53.green("\u2713")} context strategy \u2192 ${color53.cyan(raw)} ${color53.dim("compactor strategy")}`
26035
+ message: `${color54.green("\u2713")} context strategy \u2192 ${color54.cyan(raw)} ${color54.dim("compactor strategy")}`
25704
26036
  };
25705
26037
  }
25706
26038
  if (sub === "context-auto-compact") {
25707
26039
  const raw = (rest[0] ?? "").toLowerCase();
25708
26040
  if (!["on", "off"].includes(raw)) {
25709
- return { message: `${color53.amber("Usage:")} /settings context-auto-compact on|off` };
26041
+ return { message: `${color54.amber("Usage:")} /settings context-auto-compact on|off` };
25710
26042
  }
25711
26043
  const on = raw === "on";
25712
26044
  await persistConfigSetting(persistDeps, (cfg) => {
@@ -25715,13 +26047,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25715
26047
  cfg.context = ctx;
25716
26048
  });
25717
26049
  return {
25718
- message: `${color53.green("\u2713")} context auto-compact \u2192 ${on ? color53.cyan("on") : color53.dim("off")} ${color53.dim("auto-compact context when thresholds crossed")}`
26050
+ message: `${color54.green("\u2713")} context auto-compact \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("auto-compact context when thresholds crossed")}`
25719
26051
  };
25720
26052
  }
25721
26053
  if (sub === "nextsteps-tool") {
25722
26054
  const raw = (rest[0] ?? "").toLowerCase();
25723
26055
  if (!["on", "off"].includes(raw)) {
25724
- return { message: `${color53.amber("Usage:")} /settings nextsteps-tool on|off` };
26056
+ return { message: `${color54.amber("Usage:")} /settings nextsteps-tool on|off` };
25725
26057
  }
25726
26058
  const on = raw === "on";
25727
26059
  await persistConfigSetting(persistDeps, (cfg) => {
@@ -25730,7 +26062,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25730
26062
  cfg.tools = tools;
25731
26063
  });
25732
26064
  return {
25733
- message: `${color53.green("\u2713")} nextsteps tool \u2192 ${on ? color53.cyan("on") : color53.dim("off")} ${color53.dim("takes effect in the next session")}`
26065
+ message: `${color54.green("\u2713")} nextsteps tool \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("takes effect in the next session")}`
25734
26066
  };
25735
26067
  }
25736
26068
  if (sub === "token-saving") {
@@ -25738,7 +26070,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25738
26070
  const tiers = ["off", "minimal", "light", "medium", "aggressive"];
25739
26071
  if (!tiers.includes(raw)) {
25740
26072
  return {
25741
- message: `${color53.amber("Usage:")} /settings token-saving off|minimal|light|medium|aggressive`
26073
+ message: `${color54.amber("Usage:")} /settings token-saving off|minimal|light|medium|aggressive`
25742
26074
  };
25743
26075
  }
25744
26076
  await persistConfigSetting(persistDeps, (cfg) => {
@@ -25747,47 +26079,47 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25747
26079
  cfg.features = feat;
25748
26080
  });
25749
26081
  return {
25750
- message: `${color53.green("\u2713")} token-saving \u2192 ${color53.cyan(raw)} ${color53.dim("token-saving mode")}`
26082
+ message: `${color54.green("\u2713")} token-saving \u2192 ${color54.cyan(raw)} ${color54.dim("token-saving mode")}`
25751
26083
  };
25752
26084
  }
25753
26085
  if (sub === "max-concurrent") {
25754
26086
  const raw = rest[0];
25755
26087
  if (raw === void 0) {
25756
26088
  return {
25757
- message: `${color53.amber("Usage:")} /settings max-concurrent <n> ${color53.dim("(0 = default)")}`
26089
+ message: `${color54.amber("Usage:")} /settings max-concurrent <n> ${color54.dim("(0 = default)")}`
25758
26090
  };
25759
26091
  }
25760
26092
  const n = Number.parseInt(raw, 10);
25761
26093
  if (Number.isNaN(n) || n < 0) {
25762
26094
  return {
25763
- message: `${color53.red("Invalid number")}: "${raw}". Enter a non-negative integer (0 = default)`
26095
+ message: `${color54.red("Invalid number")}: "${raw}". Enter a non-negative integer (0 = default)`
25764
26096
  };
25765
26097
  }
25766
26098
  await persistConfigSetting(persistDeps, (cfg) => {
25767
26099
  cfg.maxConcurrent = n;
25768
26100
  });
25769
26101
  return {
25770
- message: `${color53.green("\u2713")} max-concurrent \u2192 ${color53.cyan(n === 0 ? "default" : String(n))} ${color53.dim("max concurrent subagents")}`
26102
+ message: `${color54.green("\u2713")} max-concurrent \u2192 ${color54.cyan(n === 0 ? "default" : String(n))} ${color54.dim("max concurrent subagents")}`
25771
26103
  };
25772
26104
  }
25773
26105
  if (sub === "title-animation") {
25774
26106
  const raw = (rest[0] ?? "").toLowerCase();
25775
26107
  if (!["on", "off"].includes(raw)) {
25776
- return { message: `${color53.amber("Usage:")} /settings title-animation on|off` };
26108
+ return { message: `${color54.amber("Usage:")} /settings title-animation on|off` };
25777
26109
  }
25778
26110
  const on = raw === "on";
25779
26111
  await persistAutonomySetting(persistDeps, (autonomy) => {
25780
26112
  autonomy.terminalTitleAnimation = on;
25781
26113
  });
25782
26114
  return {
25783
- message: `${color53.green("\u2713")} title animation \u2192 ${on ? color53.cyan("on") : color53.dim("off")} ${color53.dim("terminal title animation")}`
26115
+ message: `${color54.green("\u2713")} title animation \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("terminal title animation")}`
25784
26116
  };
25785
26117
  }
25786
26118
  if (sub === "reasoning") {
25787
26119
  const raw = (rest[0] ?? "").toLowerCase();
25788
26120
  const modes = ["auto", "on", "off"];
25789
26121
  if (!modes.includes(raw)) {
25790
- return { message: `${color53.amber("Usage:")} /settings reasoning auto|on|off` };
26122
+ return { message: `${color54.amber("Usage:")} /settings reasoning auto|on|off` };
25791
26123
  }
25792
26124
  await persistConfigSetting(persistDeps, (cfg) => {
25793
26125
  const mr = cfg.modelRuntime;
@@ -25795,14 +26127,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25795
26127
  reasoning.mode = raw;
25796
26128
  cfg.modelRuntime = { ...mr, reasoning };
25797
26129
  });
25798
- return { message: `${color53.green("\u2713")} reasoning mode \u2192 ${color53.bold(raw)}` };
26130
+ return { message: `${color54.green("\u2713")} reasoning mode \u2192 ${color54.bold(raw)}` };
25799
26131
  }
25800
26132
  if (sub === "reasoning-effort") {
25801
26133
  const raw = (rest[0] ?? "").toLowerCase();
25802
- const efforts = ["none", "minimal", "low", "medium", "high", "xhigh", "max"];
25803
- if (!efforts.includes(raw)) {
26134
+ if (!isReasoningEffort3(raw)) {
25804
26135
  return {
25805
- message: `${color53.amber("Usage:")} /settings reasoning-effort none|minimal|low|medium|high|xhigh|max`
26136
+ message: `${color54.amber("Usage:")} /settings reasoning-effort ${REASONING_EFFORT_LEVELS3.join("|")}`
25806
26137
  };
25807
26138
  }
25808
26139
  await persistConfigSetting(persistDeps, (cfg) => {
@@ -25811,12 +26142,12 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25811
26142
  reasoning.effort = raw;
25812
26143
  cfg.modelRuntime = { ...mr, reasoning };
25813
26144
  });
25814
- return { message: `${color53.green("\u2713")} reasoning effort \u2192 ${color53.bold(raw)}` };
26145
+ return { message: `${color54.green("\u2713")} reasoning effort \u2192 ${color54.bold(raw)}` };
25815
26146
  }
25816
26147
  if (sub === "reasoning-preserve") {
25817
26148
  const raw = (rest[0] ?? "").toLowerCase();
25818
26149
  if (!["on", "off"].includes(raw)) {
25819
- return { message: `${color53.amber("Usage:")} /settings reasoning-preserve on|off` };
26150
+ return { message: `${color54.amber("Usage:")} /settings reasoning-preserve on|off` };
25820
26151
  }
25821
26152
  const on = raw === "on";
25822
26153
  await persistConfigSetting(persistDeps, (cfg) => {
@@ -25826,24 +26157,24 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25826
26157
  cfg.modelRuntime = { ...mr, reasoning };
25827
26158
  });
25828
26159
  return {
25829
- message: `${color53.green("\u2713")} reasoning preserve \u2192 ${on ? color53.cyan("on") : color53.dim("off")}`
26160
+ message: `${color54.green("\u2713")} reasoning preserve \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
25830
26161
  };
25831
26162
  }
25832
26163
  if (sub === "cache-ttl") {
25833
26164
  const raw = (rest[0] ?? "").toLowerCase();
25834
26165
  if (!["5m", "1h"].includes(raw)) {
25835
- return { message: `${color53.amber("Usage:")} /settings cache-ttl 5m|1h` };
26166
+ return { message: `${color54.amber("Usage:")} /settings cache-ttl 5m|1h` };
25836
26167
  }
25837
26168
  await persistConfigSetting(persistDeps, (cfg) => {
25838
26169
  const mr = cfg.modelRuntime;
25839
26170
  cfg.modelRuntime = { ...mr, cache: { ttl: raw } };
25840
26171
  });
25841
- return { message: `${color53.green("\u2713")} cache TTL \u2192 ${color53.bold(raw)}` };
26172
+ return { message: `${color54.green("\u2713")} cache TTL \u2192 ${color54.bold(raw)}` };
25842
26173
  }
25843
26174
  if (sub === "mcp") {
25844
26175
  const raw = (rest[0] ?? "").toLowerCase();
25845
26176
  if (!["on", "off"].includes(raw))
25846
- return { message: `${color53.amber("Usage:")} /settings mcp on|off` };
26177
+ return { message: `${color54.amber("Usage:")} /settings mcp on|off` };
25847
26178
  const on = raw === "on";
25848
26179
  await persistConfigSetting(persistDeps, (cfg) => {
25849
26180
  const feats = cfg.features ?? {};
@@ -25851,13 +26182,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25851
26182
  cfg.features = feats;
25852
26183
  });
25853
26184
  return {
25854
- message: `${color53.green("\u2713")} MCP features \u2192 ${on ? color53.cyan("on") : color53.dim("off")} ${color53.dim("restart to apply")}`
26185
+ message: `${color54.green("\u2713")} MCP features \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("restart to apply")}`
25855
26186
  };
25856
26187
  }
25857
26188
  if (sub === "plugins") {
25858
26189
  const raw = (rest[0] ?? "").toLowerCase();
25859
26190
  if (!["on", "off"].includes(raw))
25860
- return { message: `${color53.amber("Usage:")} /settings plugins on|off` };
26191
+ return { message: `${color54.amber("Usage:")} /settings plugins on|off` };
25861
26192
  const on = raw === "on";
25862
26193
  await persistConfigSetting(persistDeps, (cfg) => {
25863
26194
  const feats = cfg.features ?? {};
@@ -25865,13 +26196,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25865
26196
  cfg.features = feats;
25866
26197
  });
25867
26198
  return {
25868
- message: `${color53.green("\u2713")} Plugin features \u2192 ${on ? color53.cyan("on") : color53.dim("off")} ${color53.dim("restart to apply")}`
26199
+ message: `${color54.green("\u2713")} Plugin features \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("restart to apply")}`
25869
26200
  };
25870
26201
  }
25871
26202
  if (sub === "memory") {
25872
26203
  const raw = (rest[0] ?? "").toLowerCase();
25873
26204
  if (!["on", "off"].includes(raw))
25874
- return { message: `${color53.amber("Usage:")} /settings memory on|off` };
26205
+ return { message: `${color54.amber("Usage:")} /settings memory on|off` };
25875
26206
  const on = raw === "on";
25876
26207
  await persistConfigSetting(persistDeps, (cfg) => {
25877
26208
  const feats = cfg.features ?? {};
@@ -25879,13 +26210,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25879
26210
  cfg.features = feats;
25880
26211
  });
25881
26212
  return {
25882
- message: `${color53.green("\u2713")} Memory features \u2192 ${on ? color53.cyan("on") : color53.dim("off")} ${color53.dim("restart to apply")}`
26213
+ message: `${color54.green("\u2713")} Memory features \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("restart to apply")}`
25883
26214
  };
25884
26215
  }
25885
26216
  if (sub === "skills") {
25886
26217
  const raw = (rest[0] ?? "").toLowerCase();
25887
26218
  if (!["on", "off"].includes(raw))
25888
- return { message: `${color53.amber("Usage:")} /settings skills on|off` };
26219
+ return { message: `${color54.amber("Usage:")} /settings skills on|off` };
25889
26220
  const on = raw === "on";
25890
26221
  await persistConfigSetting(persistDeps, (cfg) => {
25891
26222
  const feats = cfg.features ?? {};
@@ -25893,13 +26224,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25893
26224
  cfg.features = feats;
25894
26225
  });
25895
26226
  return {
25896
- message: `${color53.green("\u2713")} Skills features \u2192 ${on ? color53.cyan("on") : color53.dim("off")} ${color53.dim("restart to apply")}`
26227
+ message: `${color54.green("\u2713")} Skills features \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("restart to apply")}`
25897
26228
  };
25898
26229
  }
25899
26230
  if (sub === "models-registry") {
25900
26231
  const raw = (rest[0] ?? "").toLowerCase();
25901
26232
  if (!["on", "off"].includes(raw))
25902
- return { message: `${color53.amber("Usage:")} /settings models-registry on|off` };
26233
+ return { message: `${color54.amber("Usage:")} /settings models-registry on|off` };
25903
26234
  const on = raw === "on";
25904
26235
  await persistConfigSetting(persistDeps, (cfg) => {
25905
26236
  const feats = cfg.features ?? {};
@@ -25907,7 +26238,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25907
26238
  cfg.features = feats;
25908
26239
  });
25909
26240
  return {
25910
- message: `${color53.green("\u2713")} Models registry \u2192 ${on ? color53.cyan("on") : color53.dim("off")} ${color53.dim("restart to apply")}`
26241
+ message: `${color54.green("\u2713")} Models registry \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("restart to apply")}`
25911
26242
  };
25912
26243
  }
25913
26244
  if (sub === "stream-fleet") {
@@ -25915,7 +26246,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25915
26246
  const mode = raw === "on" ? "full" : raw === "off" || raw === "full" ? raw : void 0;
25916
26247
  if (!mode)
25917
26248
  return {
25918
- message: `${color53.amber("Usage:")} /settings stream-fleet off|full (on = full)`
26249
+ message: `${color54.amber("Usage:")} /settings stream-fleet off|full (on = full)`
25919
26250
  };
25920
26251
  await persistAutonomySetting(persistDeps, (autonomy) => {
25921
26252
  autonomy.fleetChatVerbosity = mode;
@@ -25923,43 +26254,43 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25923
26254
  opts.fleetStreamController?.setMode(mode);
25924
26255
  const desc = mode === "full" ? "every subagent tool call and message in chat" : "subagent chat lines hidden (F2/F3 stay live)";
25925
26256
  return {
25926
- message: `${color53.green("\u2713")} fleet chat \u2192 ${color53.cyan(mode)} ${color53.dim(desc)}`
26257
+ message: `${color54.green("\u2713")} fleet chat \u2192 ${color54.cyan(mode)} ${color54.dim(desc)}`
25927
26258
  };
25928
26259
  }
25929
26260
  if (sub === "chime") {
25930
26261
  const raw = (rest[0] ?? "").toLowerCase();
25931
26262
  if (!["on", "off"].includes(raw))
25932
- return { message: `${color53.amber("Usage:")} /settings chime on|off` };
26263
+ return { message: `${color54.amber("Usage:")} /settings chime on|off` };
25933
26264
  const on = raw === "on";
25934
26265
  await persistAutonomySetting(persistDeps, (autonomy) => {
25935
26266
  autonomy.chime = on;
25936
26267
  });
25937
26268
  return {
25938
- message: `${color53.green("\u2713")} completion chime \u2192 ${on ? color53.cyan("on") : color53.dim("off")}`
26269
+ message: `${color54.green("\u2713")} completion chime \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
25939
26270
  };
25940
26271
  }
25941
26272
  if (sub === "confirm-exit") {
25942
26273
  const raw = (rest[0] ?? "").toLowerCase();
25943
26274
  if (!["on", "off"].includes(raw))
25944
- return { message: `${color53.amber("Usage:")} /settings confirm-exit on|off` };
26275
+ return { message: `${color54.amber("Usage:")} /settings confirm-exit on|off` };
25945
26276
  const on = raw === "on";
25946
26277
  await persistAutonomySetting(persistDeps, (autonomy) => {
25947
26278
  autonomy.confirmExit = on;
25948
26279
  });
25949
26280
  return {
25950
- message: `${color53.green("\u2713")} confirm before exit \u2192 ${on ? color53.cyan("on") : color53.dim("off")}`
26281
+ message: `${color54.green("\u2713")} confirm before exit \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
25951
26282
  };
25952
26283
  }
25953
26284
  if (sub === "max-iterations") {
25954
26285
  const raw = rest[0];
25955
26286
  if (raw === void 0)
25956
26287
  return {
25957
- message: `${color53.amber("Usage:")} /settings max-iterations <n> ${color53.dim("(0 = default)")}`
26288
+ message: `${color54.amber("Usage:")} /settings max-iterations <n> ${color54.dim("(0 = default)")}`
25958
26289
  };
25959
26290
  const n = Number.parseInt(raw, 10);
25960
26291
  if (Number.isNaN(n) || n < 0)
25961
26292
  return {
25962
- message: `${color53.red("Invalid number")}: "${raw}". Enter a non-negative integer.`
26293
+ message: `${color54.red("Invalid number")}: "${raw}". Enter a non-negative integer.`
25963
26294
  };
25964
26295
  await persistConfigSetting(persistDeps, (cfg) => {
25965
26296
  const tools = cfg.tools ?? {};
@@ -25967,31 +26298,31 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25967
26298
  cfg.tools = tools;
25968
26299
  });
25969
26300
  return {
25970
- message: `${color53.green("\u2713")} max iterations \u2192 ${color53.cyan(n === 0 ? "default" : String(n))} ${color53.dim("agent pauses after this many iterations")}`
26301
+ message: `${color54.green("\u2713")} max iterations \u2192 ${color54.cyan(n === 0 ? "default" : String(n))} ${color54.dim("agent pauses after this many iterations")}`
25971
26302
  };
25972
26303
  }
25973
26304
  if (sub === "auto-proceed-max-iterations") {
25974
26305
  const raw = rest[0];
25975
26306
  if (raw === void 0)
25976
26307
  return {
25977
- message: `${color53.amber("Usage:")} /settings auto-proceed-max-iterations <n> ${color53.dim("(0 = unlimited)")}`
26308
+ message: `${color54.amber("Usage:")} /settings auto-proceed-max-iterations <n> ${color54.dim("(0 = unlimited)")}`
25978
26309
  };
25979
26310
  const n = Number.parseInt(raw, 10);
25980
26311
  if (Number.isNaN(n) || n < 0)
25981
26312
  return {
25982
- message: `${color53.red("Invalid number")}: "${raw}". Enter a non-negative integer.`
26313
+ message: `${color54.red("Invalid number")}: "${raw}". Enter a non-negative integer.`
25983
26314
  };
25984
26315
  await persistAutonomySetting(persistDeps, (autonomy) => {
25985
26316
  autonomy.autoProceedMaxIterations = n;
25986
26317
  });
25987
26318
  return {
25988
- message: `${color53.green("\u2713")} auto-proceed max iterations \u2192 ${color53.cyan(n === 0 ? "unlimited" : String(n))}`
26319
+ message: `${color54.green("\u2713")} auto-proceed max iterations \u2192 ${color54.cyan(n === 0 ? "unlimited" : String(n))}`
25989
26320
  };
25990
26321
  }
25991
26322
  if (sub === "index-on-start") {
25992
26323
  const raw = (rest[0] ?? "").toLowerCase();
25993
26324
  if (!["on", "off"].includes(raw))
25994
- return { message: `${color53.amber("Usage:")} /settings index-on-start on|off` };
26325
+ return { message: `${color54.amber("Usage:")} /settings index-on-start on|off` };
25995
26326
  const on = raw === "on";
25996
26327
  await persistConfigSetting(persistDeps, (cfg) => {
25997
26328
  const idx = cfg.indexing ?? {};
@@ -25999,7 +26330,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
25999
26330
  cfg.indexing = idx;
26000
26331
  });
26001
26332
  return {
26002
- message: `${color53.green("\u2713")} index on session start \u2192 ${on ? color53.cyan("on") : color53.dim("off")} ${color53.dim("effective next session")}`
26333
+ message: `${color54.green("\u2713")} index on session start \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("effective next session")}`
26003
26334
  };
26004
26335
  }
26005
26336
  if (sub === "log-level") {
@@ -26007,21 +26338,21 @@ async function executeSettingsSubcommand(sub, rest, opts) {
26007
26338
  const levels = ["error", "warn", "info", "debug", "trace"];
26008
26339
  if (!levels.includes(raw))
26009
26340
  return {
26010
- message: `${color53.amber("Usage:")} /settings log-level error|warn|info|debug|trace`
26341
+ message: `${color54.amber("Usage:")} /settings log-level error|warn|info|debug|trace`
26011
26342
  };
26012
26343
  await persistConfigSetting(persistDeps, (cfg) => {
26013
26344
  const log = cfg.log ?? {};
26014
26345
  log.level = raw;
26015
26346
  cfg.log = log;
26016
26347
  });
26017
- return { message: `${color53.green("\u2713")} log level \u2192 ${color53.cyan(raw)}` };
26348
+ return { message: `${color54.green("\u2713")} log level \u2192 ${color54.cyan(raw)}` };
26018
26349
  }
26019
26350
  if (sub === "audit-level") {
26020
26351
  const raw = (rest[0] ?? "").toLowerCase();
26021
26352
  const levels = ["minimal", "standard", "full"];
26022
26353
  if (!levels.includes(raw))
26023
26354
  return {
26024
- message: `${color53.amber("Usage:")} /settings audit-level minimal|standard|full`
26355
+ message: `${color54.amber("Usage:")} /settings audit-level minimal|standard|full`
26025
26356
  };
26026
26357
  await persistConfigSetting(persistDeps, (cfg) => {
26027
26358
  const sess = cfg.session ?? {};
@@ -26029,38 +26360,38 @@ async function executeSettingsSubcommand(sub, rest, opts) {
26029
26360
  cfg.session = sess;
26030
26361
  });
26031
26362
  return {
26032
- message: `${color53.green("\u2713")} audit level \u2192 ${color53.cyan(raw)} ${color53.dim("restart to apply")}`
26363
+ message: `${color54.green("\u2713")} audit level \u2192 ${color54.cyan(raw)} ${color54.dim("restart to apply")}`
26033
26364
  };
26034
26365
  }
26035
26366
  if (sub === "thinking-word") {
26036
26367
  const raw = rest.join(" ").trim();
26037
26368
  if (!raw)
26038
26369
  return {
26039
- message: `${color53.amber("Usage:")} /settings thinking-word <word> ${color53.dim('single short word, e.g. "thinking", "vibing", "cooking"')}`
26370
+ message: `${color54.amber("Usage:")} /settings thinking-word <word> ${color54.dim('single short word, e.g. "thinking", "vibing", "cooking"')}`
26040
26371
  };
26041
26372
  if (raw.length > 16)
26042
- return { message: `${color53.red("Word too long")}: max 16 characters.` };
26373
+ return { message: `${color54.red("Word too long")}: max 16 characters.` };
26043
26374
  await persistAutonomySetting(persistDeps, (autonomy) => {
26044
26375
  autonomy.thinkingWord = raw;
26045
26376
  });
26046
- return { message: `${color53.green("\u2713")} thinking word \u2192 ${color53.cyan(raw)}` };
26377
+ return { message: `${color54.green("\u2713")} thinking word \u2192 ${color54.cyan(raw)}` };
26047
26378
  }
26048
26379
  if (sub === "statusline") {
26049
26380
  const raw = (rest[0] ?? "").toLowerCase();
26050
26381
  const modes = ["minimum", "detailed", "no-color"];
26051
26382
  if (!modes.includes(raw))
26052
26383
  return {
26053
- message: `${color53.amber("Usage:")} /settings statusline minimum|detailed|no-color`
26384
+ message: `${color54.amber("Usage:")} /settings statusline minimum|detailed|no-color`
26054
26385
  };
26055
26386
  await persistAutonomySetting(persistDeps, (autonomy) => {
26056
26387
  autonomy.statuslineMode = raw;
26057
26388
  });
26058
- return { message: `${color53.green("\u2713")} statusline mode \u2192 ${color53.cyan(raw)}` };
26389
+ return { message: `${color54.green("\u2713")} statusline mode \u2192 ${color54.cyan(raw)}` };
26059
26390
  }
26060
26391
  if (sub === "read-symbols") {
26061
26392
  const raw = (rest[0] ?? "").toLowerCase();
26062
26393
  if (!["on", "off"].includes(raw)) {
26063
- return { message: `${color53.amber("Usage:")} /settings read-symbols on|off` };
26394
+ return { message: `${color54.amber("Usage:")} /settings read-symbols on|off` };
26064
26395
  }
26065
26396
  const on = raw === "on";
26066
26397
  await persistAutonomySetting(persistDeps, (autonomy) => {
@@ -26070,7 +26401,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
26070
26401
  opts.context.meta["tools.read.advancedMode"] = on;
26071
26402
  }
26072
26403
  return {
26073
- message: `${color53.green("\u2713")} read symbols \u2192 ${on ? color53.cyan("on") : color53.dim("off")} ${color53.dim(on ? "codebase-index symbols will be included in read tool results" : "read tool returns file content only")}`
26404
+ message: `${color54.green("\u2713")} read symbols \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim(on ? "codebase-index symbols will be included in read tool results" : "read tool returns file content only")}`
26074
26405
  };
26075
26406
  }
26076
26407
  if (sub === "animation") {
@@ -26078,26 +26409,26 @@ async function executeSettingsSubcommand(sub, rest, opts) {
26078
26409
  const styles = ["rainbow", "wave", "pulse", "dots", "breathe", "cycle"];
26079
26410
  if (!styles.includes(raw))
26080
26411
  return {
26081
- message: `${color53.amber("Usage:")} /settings animation rainbow|wave|pulse|dots|breathe|cycle`
26412
+ message: `${color54.amber("Usage:")} /settings animation rainbow|wave|pulse|dots|breathe|cycle`
26082
26413
  };
26083
26414
  await persistAutonomySetting(persistDeps, (autonomy) => {
26084
26415
  autonomy.animationStyle = raw;
26085
26416
  });
26086
- return { message: `${color53.green("\u2713")} animation style \u2192 ${color53.cyan(raw)}` };
26417
+ return { message: `${color54.green("\u2713")} animation style \u2192 ${color54.cyan(raw)}` };
26087
26418
  }
26088
26419
  return {
26089
- message: `${color53.red("Unknown setting")} "${sub}". ${unknownSubcommand(sub, ALL_SETTINGS_KEYS, "settings")}`
26420
+ message: `${color54.red("Unknown setting")} "${sub}". ${unknownSubcommand(sub, ALL_SETTINGS_KEYS, "settings")}`
26090
26421
  };
26091
26422
  } catch (err) {
26092
26423
  return {
26093
- message: `${color53.red("Settings error")}: ${toErrorMessage23(err)}`
26424
+ message: `${color54.red("Settings error")}: ${toErrorMessage23(err)}`
26094
26425
  };
26095
26426
  }
26096
26427
  }
26097
26428
 
26098
26429
  // src/slash-commands/settings-view.ts
26099
26430
  import { resolveFleetChatVerbosity } from "@wrongstack/core/types";
26100
- import { color as color54 } from "@wrongstack/core/utils";
26431
+ import { color as color55 } from "@wrongstack/core/utils";
26101
26432
  var SETTINGS_HELP = [
26102
26433
  "Usage:",
26103
26434
  " /settings Show current settings",
@@ -26155,16 +26486,16 @@ var SETTINGS_HELP = [
26155
26486
  ].join("\n");
26156
26487
  function formatSettingsDefaults() {
26157
26488
  return [
26158
- `${color54.bold("Default Values")}`,
26489
+ `${color55.bold("Default Values")}`,
26159
26490
  "",
26160
- ` auto-proceed delay: ${color54.cyan("45s")} ${color54.dim("(WRONGSTACK_AUTO_PROCEED_DELAY_MS env)")}`,
26161
- ` default autonomy mode: ${color54.cyan("off")}`,
26162
- ` launch hints: ${color54.cyan("on")}`,
26163
- ` iteration timeout: ${color54.cyan("5 min")}`,
26164
- ` session timeout: ${color54.cyan("30 min")}`,
26165
- ` max iterations: ${color54.cyan("100")}`,
26166
- ` max concurrent: ${color54.cyan("4")}`,
26167
- ` semver default part: ${color54.cyan("patch")}`
26491
+ ` auto-proceed delay: ${color55.cyan("45s")} ${color55.dim("(WRONGSTACK_AUTO_PROCEED_DELAY_MS env)")}`,
26492
+ ` default autonomy mode: ${color55.cyan("off")}`,
26493
+ ` launch hints: ${color55.cyan("on")}`,
26494
+ ` iteration timeout: ${color55.cyan("5 min")}`,
26495
+ ` session timeout: ${color55.cyan("30 min")}`,
26496
+ ` max iterations: ${color55.cyan("100")}`,
26497
+ ` max concurrent: ${color55.cyan("4")}`,
26498
+ ` semver default part: ${color55.cyan("patch")}`
26168
26499
  ].join("\n");
26169
26500
  }
26170
26501
  function formatCurrentSettingsView(opts) {
@@ -26208,56 +26539,56 @@ function formatCurrentSettingsView(opts) {
26208
26539
  const idx = opts.configStore.get().indexing;
26209
26540
  const sess = opts.configStore.get().session;
26210
26541
  return [
26211
- `${color54.bold("WrongStack")} ${color54.dim("\u2014 Settings")}`,
26542
+ `${color55.bold("WrongStack")} ${color55.dim("\u2014 Settings")}`,
26212
26543
  "",
26213
- ` auto-proceed delay: ${color54.cyan(formatDelay(delay))} ${color54.dim("change: /settings delay <seconds>")}`,
26214
- ` default autonomy mode: ${color54.cyan(mode)} ${color54.dim("change: /settings mode off|suggest|auto")}`,
26215
- ` fleet chat: ${color54.cyan(resolveFleetChatVerbosity(au))} ${color54.dim("change: /settings stream-fleet off|full")}`,
26216
- ` completion chime: ${au?.chime === true ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings chime on|off")}`,
26217
- ` confirm before exit: ${au?.confirmExit !== false ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings confirm-exit on|off")}`,
26218
- ` launch hints: ${hints ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings hints on|off")}`,
26219
- ` debug stream: ${debugStream ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings debug-stream on|off")}`,
26220
- ` config scope: ${color54.cyan(configScope)} ${color54.dim("change: /settings config-scope global|project")}`,
26221
- ` filesystem access: ${color54.cyan(fsAccess)} ${color54.dim("change: /settings fs-access unrestricted|project")}`,
26222
- ` refine: ${enhanceEnabled ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings refine on|off")}`,
26223
- ` refine-delay: ${color54.cyan(formatDelay(enhanceDelay))} ${color54.dim("change: /settings refine-delay <seconds>")}`,
26224
- ` refine-language: ${color54.cyan(enhanceLanguage)} ${color54.dim("change: /settings refine-language original|english")}`,
26225
- ` refiner-provider: ${color54.cyan(au?.refinerProvider ?? color54.dim("(unset)"))} ${color54.dim("change: /settings refiner-provider <id>")}`,
26226
- ` refiner-model: ${color54.cyan(au?.refinerModel ?? color54.dim("(unset)"))} ${color54.dim("change: /settings refiner-model <model>")}`,
26227
- ` refiner-fallback-profile: ${color54.cyan(au?.refinerFallbackProfile ?? color54.dim("(unset)"))} ${color54.dim("change: /settings refiner-fallback-profile <name>")}`,
26228
- ` semver default part: ${color54.cyan(semverPart)} ${color54.dim("change: /settings semver-part patch|minor|major|auto")}`,
26229
- ` circuit breaker: ${breakerEnabled ? color54.cyan("on") : color54.dim("off")} (${breakerTimeout > 0 ? formatDelay(breakerTimeout) : color54.dim("manual")}) ${color54.dim("change: /settings breaker on|off")}`,
26230
- ` context mode: ${color54.cyan(contextMode)} ${color54.dim("change: /settings context-mode balanced|frugal|deep")}`,
26231
- ` context strategy: ${color54.cyan(contextStrategy)} ${color54.dim("change: /settings context-strategy hybrid|intelligent|selective")}`,
26232
- ` context auto-compact: ${contextAutoCompact ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings context-auto-compact on|off")}`,
26233
- ` token-saving: ${color54.cyan(tokenSavingTier)} ${color54.dim("change: /settings token-saving off|minimal|light|medium|aggressive")}`,
26234
- ` nextsteps tool: ${nextStepsToolEnabled ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings nextsteps-tool on|off")}`,
26235
- ` MCP features: ${feats?.mcp !== false ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings mcp on|off")}`,
26236
- ` plugin features: ${feats?.plugins !== false ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings plugins on|off")}`,
26237
- ` memory features: ${feats?.memory !== false ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings memory on|off")}`,
26238
- ` skills features: ${feats?.skills !== false ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings skills on|off")}`,
26239
- ` models registry: ${feats?.modelsRegistry !== false ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings models-registry on|off")}`,
26240
- ` max concurrent: ${color54.cyan(maxConcurrent === 0 ? "default" : String(maxConcurrent))} ${color54.dim("change: /settings max-concurrent <n>")}`,
26241
- ` max iterations: ${color54.cyan(String(tools?.maxIterations ?? "default"))} ${color54.dim("change: /settings max-iterations <n>")}`,
26242
- ` auto-proceed max iters: ${color54.cyan(String(au?.autoProceedMaxIterations ?? "unlimited"))} ${color54.dim("change: /settings auto-proceed-max-iterations <n>")}`,
26243
- ` title animation: ${titleAnimation ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings title-animation on|off")}`,
26244
- ` thinking word: ${color54.cyan(au?.thinkingWord ?? "thinking")} ${color54.dim("change: /settings thinking-word <word>")}`,
26245
- ` statusline mode: ${color54.cyan(au?.statuslineMode ?? "minimum")} ${color54.dim("change: /settings statusline minimum|detailed|no-color")}`,
26246
- ` animation style: ${color54.cyan(au?.animationStyle ?? "rainbow")} ${color54.dim("change: /settings animation rainbow|wave|pulse|dots|breathe|cycle")}`,
26247
- ` read symbols: ${au?.readAdvancedMode === true ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings read-symbols on|off")}`,
26248
- ` reasoning mode: ${color54.cyan(reasoningMode)} ${color54.dim("change: /settings reasoning auto|on|off")}`,
26249
- ` reasoning effort: ${color54.cyan(reasoningEffort)} ${color54.dim("change: /settings reasoning-effort <level>")}`,
26250
- ` reasoning preserve: ${reasoningPreserve ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings reasoning-preserve on|off")}`,
26251
- ` cache TTL: ${color54.cyan(cacheTtl)} ${color54.dim("change: /settings cache-ttl 5m|1h")}`,
26252
- ` index on start: ${idx?.onSessionStart !== false ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings index-on-start on|off")}`,
26253
- ` log level: ${color54.cyan(log?.level ?? "info")} ${color54.dim("change: /settings log-level error|warn|info|debug|trace")}`,
26254
- ` audit level: ${color54.cyan(sess?.auditLevel ?? "standard")} ${color54.dim("change: /settings audit-level minimal|standard|full")}`,
26255
- ` HQ publishing: ${hqEnabled ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings hq on|off")}`,
26256
- ` HQ URL: ${color54.cyan(hqUrl)} ${color54.dim("change: /settings hq-url <url>")}`,
26257
- ` HQ token: ${color54.cyan(hqToken)} ${color54.dim("change: /settings hq-token <token>")}`,
26258
- ` HQ raw content: ${hq?.rawContent === true ? color54.cyan("on") : color54.dim("off")} ${color54.dim("change: /settings hq-raw on|off")}`,
26544
+ ` auto-proceed delay: ${color55.cyan(formatDelay(delay))} ${color55.dim("change: /settings delay <seconds>")}`,
26545
+ ` default autonomy mode: ${color55.cyan(mode)} ${color55.dim("change: /settings mode off|suggest|auto")}`,
26546
+ ` fleet chat: ${color55.cyan(resolveFleetChatVerbosity(au))} ${color55.dim("change: /settings stream-fleet off|full")}`,
26547
+ ` completion chime: ${au?.chime === true ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings chime on|off")}`,
26548
+ ` confirm before exit: ${au?.confirmExit !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings confirm-exit on|off")}`,
26549
+ ` launch hints: ${hints ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings hints on|off")}`,
26550
+ ` debug stream: ${debugStream ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings debug-stream on|off")}`,
26551
+ ` config scope: ${color55.cyan(configScope)} ${color55.dim("change: /settings config-scope global|project")}`,
26552
+ ` filesystem access: ${color55.cyan(fsAccess)} ${color55.dim("change: /settings fs-access unrestricted|project")}`,
26553
+ ` refine: ${enhanceEnabled ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings refine on|off")}`,
26554
+ ` refine-delay: ${color55.cyan(formatDelay(enhanceDelay))} ${color55.dim("change: /settings refine-delay <seconds>")}`,
26555
+ ` refine-language: ${color55.cyan(enhanceLanguage)} ${color55.dim("change: /settings refine-language original|english")}`,
26556
+ ` refiner-provider: ${color55.cyan(au?.refinerProvider ?? color55.dim("(unset)"))} ${color55.dim("change: /settings refiner-provider <id>")}`,
26557
+ ` refiner-model: ${color55.cyan(au?.refinerModel ?? color55.dim("(unset)"))} ${color55.dim("change: /settings refiner-model <model>")}`,
26558
+ ` refiner-fallback-profile: ${color55.cyan(au?.refinerFallbackProfile ?? color55.dim("(unset)"))} ${color55.dim("change: /settings refiner-fallback-profile <name>")}`,
26559
+ ` semver default part: ${color55.cyan(semverPart)} ${color55.dim("change: /settings semver-part patch|minor|major|auto")}`,
26560
+ ` circuit breaker: ${breakerEnabled ? color55.cyan("on") : color55.dim("off")} (${breakerTimeout > 0 ? formatDelay(breakerTimeout) : color55.dim("manual")}) ${color55.dim("change: /settings breaker on|off")}`,
26561
+ ` context mode: ${color55.cyan(contextMode)} ${color55.dim("change: /settings context-mode balanced|frugal|deep")}`,
26562
+ ` context strategy: ${color55.cyan(contextStrategy)} ${color55.dim("change: /settings context-strategy hybrid|intelligent|selective")}`,
26563
+ ` context auto-compact: ${contextAutoCompact ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings context-auto-compact on|off")}`,
26564
+ ` token-saving: ${color55.cyan(tokenSavingTier)} ${color55.dim("change: /settings token-saving off|minimal|light|medium|aggressive")}`,
26565
+ ` nextsteps tool: ${nextStepsToolEnabled ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings nextsteps-tool on|off")}`,
26566
+ ` MCP features: ${feats?.mcp !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings mcp on|off")}`,
26567
+ ` plugin features: ${feats?.plugins !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings plugins on|off")}`,
26568
+ ` memory features: ${feats?.memory !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings memory on|off")}`,
26569
+ ` skills features: ${feats?.skills !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings skills on|off")}`,
26570
+ ` models registry: ${feats?.modelsRegistry !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings models-registry on|off")}`,
26571
+ ` max concurrent: ${color55.cyan(maxConcurrent === 0 ? "default" : String(maxConcurrent))} ${color55.dim("change: /settings max-concurrent <n>")}`,
26572
+ ` max iterations: ${color55.cyan(String(tools?.maxIterations ?? "default"))} ${color55.dim("change: /settings max-iterations <n>")}`,
26573
+ ` auto-proceed max iters: ${color55.cyan(String(au?.autoProceedMaxIterations ?? "unlimited"))} ${color55.dim("change: /settings auto-proceed-max-iterations <n>")}`,
26574
+ ` title animation: ${titleAnimation ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings title-animation on|off")}`,
26575
+ ` thinking word: ${color55.cyan(au?.thinkingWord ?? "thinking")} ${color55.dim("change: /settings thinking-word <word>")}`,
26576
+ ` statusline mode: ${color55.cyan(au?.statuslineMode ?? "minimum")} ${color55.dim("change: /settings statusline minimum|detailed|no-color")}`,
26577
+ ` animation style: ${color55.cyan(au?.animationStyle ?? "rainbow")} ${color55.dim("change: /settings animation rainbow|wave|pulse|dots|breathe|cycle")}`,
26578
+ ` read symbols: ${au?.readAdvancedMode === true ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings read-symbols on|off")}`,
26579
+ ` reasoning mode: ${color55.cyan(reasoningMode)} ${color55.dim("change: /settings reasoning auto|on|off")}`,
26580
+ ` reasoning effort: ${color55.cyan(reasoningEffort)} ${color55.dim("change: /settings reasoning-effort <level>")}`,
26581
+ ` reasoning preserve: ${reasoningPreserve ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings reasoning-preserve on|off")}`,
26582
+ ` cache TTL: ${color55.cyan(cacheTtl)} ${color55.dim("change: /settings cache-ttl 5m|1h")}`,
26583
+ ` index on start: ${idx?.onSessionStart !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings index-on-start on|off")}`,
26584
+ ` log level: ${color55.cyan(log?.level ?? "info")} ${color55.dim("change: /settings log-level error|warn|info|debug|trace")}`,
26585
+ ` audit level: ${color55.cyan(sess?.auditLevel ?? "standard")} ${color55.dim("change: /settings audit-level minimal|standard|full")}`,
26586
+ ` HQ publishing: ${hqEnabled ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings hq on|off")}`,
26587
+ ` HQ URL: ${color55.cyan(hqUrl)} ${color55.dim("change: /settings hq-url <url>")}`,
26588
+ ` HQ token: ${color55.cyan(hqToken)} ${color55.dim("change: /settings hq-token <token>")}`,
26589
+ ` HQ raw content: ${hq?.rawContent === true ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings hq-raw on|off")}`,
26259
26590
  "",
26260
- color54.dim(` Persisted to ${persistedTo} \xB7 /settings help for more`)
26591
+ color55.dim(` Persisted to ${persistedTo} \xB7 /settings help for more`)
26261
26592
  ].join("\n");
26262
26593
  }
26263
26594
 
@@ -26275,7 +26606,7 @@ function buildSettingsCommand(opts) {
26275
26606
  return { message: this.help ?? "" };
26276
26607
  }
26277
26608
  if (!opts.configStore || !opts.paths) {
26278
- return { message: `${color55.red("Error")} config store not available.` };
26609
+ return { message: `${color56.red("Error")} config store not available.` };
26279
26610
  }
26280
26611
  if (!sub) {
26281
26612
  return { message: formatCurrentSettingsView(opts) };
@@ -26291,8 +26622,8 @@ function buildSettingsCommand(opts) {
26291
26622
  }
26292
26623
 
26293
26624
  // src/slash-commands/shadow.ts
26294
- import { ToolValidationError as ToolValidationError5 } from "@wrongstack/core/types";
26295
- import { color as color56 } from "@wrongstack/core/utils";
26625
+ import { ToolValidationError as ToolValidationError4 } from "@wrongstack/core/types";
26626
+ import { color as color57 } from "@wrongstack/core/utils";
26296
26627
  var DEFAULT_SHADOW_INTERVAL_MS = 3e4;
26297
26628
  var MIN_SHADOW_INTERVAL_MS = 5e3;
26298
26629
  function buildShadowCommand(opts) {
@@ -26362,7 +26693,7 @@ function buildShadowCommand(opts) {
26362
26693
  if (opts.shadowController?.activeId != null) {
26363
26694
  return {
26364
26695
  message: [
26365
- `${color56.yellow("\u26A0")} A Shadow Agent is already running (${opts.shadowController.activeId.slice(0, 8)}).`,
26696
+ `${color57.yellow("\u26A0")} A Shadow Agent is already running (${opts.shadowController.activeId.slice(0, 8)}).`,
26366
26697
  "",
26367
26698
  "Only one Shadow Agent instance is allowed per session.",
26368
26699
  "Use /shadow status to view the current instance."
@@ -26401,16 +26732,16 @@ function buildShadowCommand(opts) {
26401
26732
  shadowIntervalMs: intervalMs
26402
26733
  });
26403
26734
  return {
26404
- message: `${color56.green("\u2713")} Shadow Agent queued: ${spawnId}
26405
- ${color56.dim("Mode:")} one-shot quiet check
26406
- ${color56.dim("Model:")} ${modelRef.label}`
26735
+ message: `${color57.green("\u2713")} Shadow Agent queued: ${spawnId}
26736
+ ${color57.dim("Mode:")} one-shot quiet check
26737
+ ${color57.dim("Model:")} ${modelRef.label}`
26407
26738
  };
26408
26739
  }
26409
26740
  case "stop": {
26410
26741
  const activeId = opts.shadowController?.activeId;
26411
26742
  if (!activeId) {
26412
26743
  return {
26413
- message: `${color56.yellow("\u26A0")} No active Shadow Agent is registered for this session.`
26744
+ message: `${color57.yellow("\u26A0")} No active Shadow Agent is registered for this session.`
26414
26745
  };
26415
26746
  }
26416
26747
  if (!opts.onFleetTerminate) {
@@ -26419,12 +26750,12 @@ ${color56.dim("Model:")} ${modelRef.label}`
26419
26750
  const ok = await opts.onFleetTerminate(activeId);
26420
26751
  if (ok) {
26421
26752
  opts.shadowController?.clear();
26422
- return { message: `${color56.green("\u2713")} Shadow Agent stopped: ${activeId}` };
26753
+ return { message: `${color57.green("\u2713")} Shadow Agent stopped: ${activeId}` };
26423
26754
  }
26424
26755
  return {
26425
26756
  message: [
26426
- `${color56.red("\u2717")} Failed to stop Shadow Agent ${color56.bold(activeId)}.`,
26427
- `It may already be stopped. Use ${color56.bold("/shadow status")} to inspect active agents.`
26757
+ `${color57.red("\u2717")} Failed to stop Shadow Agent ${color57.bold(activeId)}.`,
26758
+ `It may already be stopped. Use ${color57.bold("/shadow status")} to inspect active agents.`
26428
26759
  ].join("\n")
26429
26760
  };
26430
26761
  }
@@ -26452,10 +26783,10 @@ ${color56.dim("Model:")} ${modelRef.label}`
26452
26783
  opts.shadowController?.clear();
26453
26784
  return {
26454
26785
  message: [
26455
- `${color56.red("\u26A0")} HOOP: Stopped ${killed} running agent(s)`,
26786
+ `${color57.red("\u26A0")} HOOP: Stopped ${killed} running agent(s)`,
26456
26787
  "",
26457
- `Target: ${color56.bold("all")}`,
26458
- `Reason: ${color56.yellow(reason)}`
26788
+ `Target: ${color57.bold("all")}`,
26789
+ `Reason: ${color57.yellow(reason)}`
26459
26790
  ].join("\n")
26460
26791
  };
26461
26792
  }
@@ -26469,10 +26800,10 @@ ${color56.dim("Model:")} ${modelRef.label}`
26469
26800
  }
26470
26801
  return {
26471
26802
  message: [
26472
- ok ? `${color56.red("\u26A0")} HOOP: Stopped agent` : `${color56.red("\u2717")} HOOP: Failed to stop agent`,
26803
+ ok ? `${color57.red("\u26A0")} HOOP: Stopped agent` : `${color57.red("\u2717")} HOOP: Failed to stop agent`,
26473
26804
  "",
26474
- `Target: ${color56.bold(targetId)}`,
26475
- `Reason: ${color56.yellow(reason)}`,
26805
+ `Target: ${color57.bold(targetId)}`,
26806
+ `Reason: ${color57.yellow(reason)}`,
26476
26807
  agentInfo ? `
26477
26808
  Agent info:
26478
26809
  ${agentInfo}` : ""
@@ -26497,7 +26828,7 @@ Current default: ${defaultModelRef.label}`
26497
26828
  opts.shadowController?.setDefaults?.({ provider: parsed.provider, model: parsed.model });
26498
26829
  return {
26499
26830
  message: `/shadow model ${parsed.label}
26500
- ${color56.dim("Model will be applied on next /shadow start")}`
26831
+ ${color57.dim("Model will be applied on next /shadow start")}`
26501
26832
  };
26502
26833
  }
26503
26834
  case "interval": {
@@ -26517,7 +26848,7 @@ Current default: ${DEFAULT_SHADOW_INTERVAL_MS}ms (30 seconds)`
26517
26848
  opts.shadowController?.setDefaults?.({ intervalMs: ms });
26518
26849
  return {
26519
26850
  message: `/shadow interval ${ms}ms
26520
- ${color56.dim("Interval will be applied on next /shadow start")}`
26851
+ ${color57.dim("Interval will be applied on next /shadow start")}`
26521
26852
  };
26522
26853
  }
26523
26854
  default: {
@@ -26544,7 +26875,7 @@ function parseProviderModelRef(model, defaultRef) {
26544
26875
  }
26545
26876
  const slash = model.indexOf("/");
26546
26877
  if (slash <= 0 || slash === model.length - 1) {
26547
- throw new ToolValidationError5({
26878
+ throw new ToolValidationError4({
26548
26879
  message: `Model must be in provider/model format (e.g. provider/configured-model), got: "${model}"`,
26549
26880
  field: "model",
26550
26881
  context: { received: model }
@@ -26558,14 +26889,14 @@ function parseProviderModelRef(model, defaultRef) {
26558
26889
  }
26559
26890
  function parseInterval(value) {
26560
26891
  if (value === true || !/^\d+$/.test(value)) {
26561
- throw new ToolValidationError5({
26892
+ throw new ToolValidationError4({
26562
26893
  message: `interval must be an integer >= ${MIN_SHADOW_INTERVAL_MS}ms`,
26563
26894
  field: "interval"
26564
26895
  });
26565
26896
  }
26566
26897
  const ms = Number.parseInt(value, 10);
26567
26898
  if (!Number.isFinite(ms) || ms < MIN_SHADOW_INTERVAL_MS) {
26568
- throw new ToolValidationError5({
26899
+ throw new ToolValidationError4({
26569
26900
  message: `interval must be an integer >= ${MIN_SHADOW_INTERVAL_MS}ms`,
26570
26901
  field: "interval",
26571
26902
  context: { received: ms, minimum: MIN_SHADOW_INTERVAL_MS }
@@ -26790,7 +27121,7 @@ function buildStatuslineCommand(deps) {
26790
27121
  }
26791
27122
 
26792
27123
  // src/slash-commands/supervisor.ts
26793
- import { color as color57 } from "@wrongstack/core/utils";
27124
+ import { color as color58 } from "@wrongstack/core/utils";
26794
27125
  function fmtAge4(at) {
26795
27126
  const s = Math.max(0, Math.round((Date.now() - at) / 1e3));
26796
27127
  if (s < 60) return `${s}s ago`;
@@ -26826,13 +27157,13 @@ function buildSupervisorCommand(opts) {
26826
27157
  }
26827
27158
  if (sub === "on") {
26828
27159
  supervisor.start();
26829
- const msg2 = `Fleet supervisor ${color57.green("armed")} \u2014 evaluating every ${Math.round(supervisor.configSnapshot().intervalMs / 1e3)}s.`;
27160
+ const msg2 = `Fleet supervisor ${color58.green("armed")} \u2014 evaluating every ${Math.round(supervisor.configSnapshot().intervalMs / 1e3)}s.`;
26830
27161
  opts.renderer.write(msg2);
26831
27162
  return { message: msg2 };
26832
27163
  }
26833
27164
  if (sub === "off") {
26834
27165
  supervisor.stop();
26835
- const msg2 = `Fleet supervisor ${color57.yellow("disarmed")} \u2014 no further automatic interventions this session.`;
27166
+ const msg2 = `Fleet supervisor ${color58.yellow("disarmed")} \u2014 no further automatic interventions this session.`;
26836
27167
  opts.renderer.write(msg2);
26837
27168
  return { message: msg2 };
26838
27169
  }
@@ -26845,10 +27176,10 @@ function buildSupervisorCommand(opts) {
26845
27176
  return { message: msg3 };
26846
27177
  }
26847
27178
  const lines2 = entries.map((e) => {
26848
- const who = e.subagentId ? ` ${color57.cyan(e.subagentId)}` : "";
27179
+ const who = e.subagentId ? ` ${color58.cyan(e.subagentId)}` : "";
26849
27180
  const task = e.taskId ? ` task=${e.taskId.slice(0, 8)}` : "";
26850
- const outcome = e.outcome === "approved" ? color57.green(e.outcome) : e.outcome === "denied" || e.outcome === "error" ? color57.red(e.outcome) : color57.yellow(e.outcome);
26851
- return `${color57.dim(fmtAge4(e.at))} ${e.kind}${who}${task} \u2192 ${e.proposedAction} [${outcome}] ${color57.dim(e.detail)}`;
27181
+ const outcome = e.outcome === "approved" ? color58.green(e.outcome) : e.outcome === "denied" || e.outcome === "error" ? color58.red(e.outcome) : color58.yellow(e.outcome);
27182
+ return `${color58.dim(fmtAge4(e.at))} ${e.kind}${who}${task} \u2192 ${e.proposedAction} [${outcome}] ${color58.dim(e.detail)}`;
26852
27183
  });
26853
27184
  const msg2 = lines2.join("\n");
26854
27185
  opts.renderer.write(msg2);
@@ -26858,12 +27189,12 @@ function buildSupervisorCommand(opts) {
26858
27189
  const history = supervisor.history();
26859
27190
  const last = history[history.length - 1];
26860
27191
  const lines = [
26861
- `Fleet supervisor: ${supervisor.isRunning() ? color57.green("armed") : color57.yellow("disarmed")}`,
27192
+ `Fleet supervisor: ${supervisor.isRunning() ? color58.green("armed") : color58.yellow("disarmed")}`,
26862
27193
  ` interval ${Math.round(cfg.intervalMs / 1e3)}s \xB7 cooldown ${Math.round(cfg.cooldownMs / 1e3)}s \xB7 max ${cfg.maxInterventionsPerSubagent} interventions/agent`,
26863
27194
  ` signals: starvation>${Math.round(cfg.pinnedWaitMs / 1e3)}s \xB7 overload\u2265${cfg.overloadPinnedThreshold} pinned \xB7 backlog>${cfg.backlogFactor}\xD7workers \xB7 stuck>${Math.round(cfg.stuckMs / 1e3)}s \xB7 failstreak\u2265${cfg.failureStreak}`,
26864
27195
  ` actions: retarget \u2713 \xB7 spawn ${cfg.allowSpawn ? "\u2713" : "\u2717"} \xB7 steer \u2713 \xB7 terminate ${cfg.allowTerminate ? "\u2713" : "\u2717 (config fleet.supervisor.allowTerminate)"}`,
26865
27196
  ` activity: ${history.length} engagement(s)${last ? ` \u2014 last: ${last.kind} \u2192 ${last.proposedAction} [${last.outcome}] ${fmtAge4(last.at)}` : ""}`,
26866
- color57.dim(" decisions are gated by the Brain \u2014 see /brain (risk ceiling applies)")
27197
+ color58.dim(" decisions are gated by the Brain \u2014 see /brain (risk ceiling applies)")
26867
27198
  ];
26868
27199
  const msg = lines.join("\n");
26869
27200
  opts.renderer.write(msg);
@@ -27290,21 +27621,21 @@ ${formatTaskProgress(file.tasks)}`;
27290
27621
  }
27291
27622
 
27292
27623
  // src/slash-commands/techstack.ts
27293
- import * as fs15 from "node:fs/promises";
27624
+ import * as fs16 from "node:fs/promises";
27294
27625
  import * as path19 from "node:path";
27295
- import { color as color58, toErrorMessage as toErrorMessage25 } from "@wrongstack/core/utils";
27626
+ import { color as color59, toErrorMessage as toErrorMessage25 } from "@wrongstack/core/utils";
27296
27627
  async function discoverPackageFiles(projectRoot) {
27297
27628
  const files = [];
27298
27629
  const rootPkg = path19.join(projectRoot, "package.json");
27299
27630
  try {
27300
- await fs15.access(rootPkg);
27631
+ await fs16.access(rootPkg);
27301
27632
  files.push(rootPkg);
27302
27633
  } catch {
27303
27634
  }
27304
27635
  const workspaceFile = path19.join(projectRoot, "pnpm-workspace.yaml");
27305
27636
  try {
27306
- await fs15.access(workspaceFile);
27307
- const content = await fs15.readFile(workspaceFile, "utf8");
27637
+ await fs16.access(workspaceFile);
27638
+ const content = await fs16.readFile(workspaceFile, "utf8");
27308
27639
  const globMatch = /packages?:\s*\[([^\]]+)\]/s.exec(content);
27309
27640
  const rawGlobs = globMatch?.[1];
27310
27641
  if (!rawGlobs) return files;
@@ -27313,12 +27644,12 @@ async function discoverPackageFiles(projectRoot) {
27313
27644
  const dirPrefix = g.replace(/\/?\*$/, "").replace(/\/\*$/, "");
27314
27645
  const dir = path19.join(projectRoot, dirPrefix);
27315
27646
  try {
27316
- const entries = await fs15.readdir(dir, { withFileTypes: true });
27647
+ const entries = await fs16.readdir(dir, { withFileTypes: true });
27317
27648
  for (const e of entries) {
27318
27649
  if (!e.isDirectory()) continue;
27319
27650
  const subPkg = path19.join(dir, e.name, "package.json");
27320
27651
  try {
27321
- await fs15.access(subPkg);
27652
+ await fs16.access(subPkg);
27322
27653
  files.push(subPkg);
27323
27654
  } catch {
27324
27655
  }
@@ -27442,10 +27773,10 @@ function buildTechStackCommand(opts) {
27442
27773
  " 1. Reads every package.json in the project",
27443
27774
  " 2. Looks up latest versions on the npm registry",
27444
27775
  " 3. Flags outdated, dead, or obsolete packages",
27445
- ` 4. Writes a ${color58.cyan("techstack.md")} (or .json) report to the project root`,
27776
+ ` 4. Writes a ${color59.cyan("techstack.md")} (or .json) report to the project root`,
27446
27777
  "",
27447
27778
  "Uses the `tech-stack` skill for version verification rules.",
27448
- `Hooked into ${color58.cyan("/init")} \u2014 runs automatically on first project setup.`
27779
+ `Hooked into ${color59.cyan("/init")} \u2014 runs automatically on first project setup.`
27449
27780
  ].join("\n"),
27450
27781
  async run(args, _ctx) {
27451
27782
  const trimmed = args.trim().toLowerCase();
@@ -27529,12 +27860,12 @@ function buildTechStackCommand(opts) {
27529
27860
  try {
27530
27861
  packageFiles = await discoverPackageFiles(opts.projectRoot);
27531
27862
  if (packageFiles.length === 0) {
27532
- discoveryNote = color58.amber(
27863
+ discoveryNote = color59.amber(
27533
27864
  "\u26A0 No package.json files found. This does not look like a Node.js project."
27534
27865
  );
27535
27866
  }
27536
27867
  } catch (err) {
27537
- discoveryNote = color58.red(`Could not scan for package files: ${toErrorMessage25(err)}`);
27868
+ discoveryNote = color59.red(`Could not scan for package files: ${toErrorMessage25(err)}`);
27538
27869
  }
27539
27870
  const task = buildTechStackTask({
27540
27871
  projectRoot: opts.projectRoot,
@@ -27557,11 +27888,11 @@ function buildTechStackCommand(opts) {
27557
27888
  };
27558
27889
  }
27559
27890
  const header = isInit ? "Tech Stack Init Audit" : "Tech Stack Audit";
27560
- const label = `${color58.cyan("\u{1F50D}")} ${color58.bold(header)} ${color58.dim(`(${packageFiles.length} package files)`)}`;
27891
+ const label = `${color59.cyan("\u{1F50D}")} ${color59.bold(header)} ${color59.dim(`(${packageFiles.length} package files)`)}`;
27561
27892
  opts.renderer.write(label);
27562
27893
  if (discoveryNote) opts.renderer.write(discoveryNote);
27563
27894
  opts.renderer.write(
27564
- color58.dim(
27895
+ color59.dim(
27565
27896
  `Spawning tech-stack subagent \u2192 writes ${outputFormat === "json" ? "techstack.json" : "techstack.md"} when done.`
27566
27897
  )
27567
27898
  );
@@ -27583,10 +27914,10 @@ function buildTechStackCommand(opts) {
27583
27914
  }
27584
27915
 
27585
27916
  // src/slash-commands/telegram-settings.ts
27586
- import { color as color60, toErrorMessage as toErrorMessage26 } from "@wrongstack/core/utils";
27917
+ import { color as color61, toErrorMessage as toErrorMessage26 } from "@wrongstack/core/utils";
27587
27918
 
27588
27919
  // src/slash-commands/telegram-setup.ts
27589
- import { color as color59 } from "@wrongstack/core/utils";
27920
+ import { color as color60 } from "@wrongstack/core/utils";
27590
27921
 
27591
27922
  // src/slash-commands/telegram-pairing.ts
27592
27923
  var DISCOVERY_LIMIT = 25;
@@ -27702,31 +28033,31 @@ function buildTelegramSetupCommand(opts) {
27702
28033
  if (BOT_TOKEN_RE.test(first)) {
27703
28034
  return {
27704
28035
  message: [
27705
- `${color59.red("\u2717")} Bot tokens are no longer accepted as slash-command arguments.`,
27706
- `Run ${color59.cyan("/telegram-setup [chatId]")} and enter it at the masked prompt.`
28036
+ `${color60.red("\u2717")} Bot tokens are no longer accepted as slash-command arguments.`,
28037
+ `Run ${color60.cyan("/telegram-setup [chatId]")} and enter it at the masked prompt.`
27707
28038
  ].join("\n")
27708
28039
  };
27709
28040
  }
27710
28041
  if (parts.length > 1) {
27711
- return { message: `${color59.amber("Usage:")} /telegram-setup [chatId]` };
28042
+ return { message: `${color60.amber("Usage:")} /telegram-setup [chatId]` };
27712
28043
  }
27713
28044
  if (!opts.readSecret || !opts.vault || !opts.paths?.globalConfig) {
27714
28045
  return {
27715
- message: `${color59.red("\u2717")} Secure Telegram setup is unavailable in this session.`
28046
+ message: `${color60.red("\u2717")} Secure Telegram setup is unavailable in this session.`
27716
28047
  };
27717
28048
  }
27718
28049
  let botToken;
27719
28050
  try {
27720
- botToken = (await opts.readSecret(`Telegram bot token ${color59.dim("(hidden, paste OK)")}: `)).trim();
28051
+ botToken = (await opts.readSecret(`Telegram bot token ${color60.dim("(hidden, paste OK)")}: `)).trim();
27721
28052
  } catch {
27722
- return { message: color59.dim("Telegram setup cancelled.") };
28053
+ return { message: color60.dim("Telegram setup cancelled.") };
27723
28054
  }
27724
- if (!botToken) return { message: color59.dim("Telegram setup cancelled.") };
28055
+ if (!botToken) return { message: color60.dim("Telegram setup cancelled.") };
27725
28056
  if (!BOT_TOKEN_RE.test(botToken)) {
27726
28057
  return {
27727
28058
  message: [
27728
- `${color59.red("\u2717")} Invalid token format.`,
27729
- `Expected: ${color59.dim("123456789:ABCdefGHIjkl...")}`,
28059
+ `${color60.red("\u2717")} Invalid token format.`,
28060
+ `Expected: ${color60.dim("123456789:ABCdefGHIjkl...")}`,
27730
28061
  "",
27731
28062
  "Get a valid token from @BotFather on Telegram."
27732
28063
  ].join("\n")
@@ -27741,7 +28072,7 @@ function buildTelegramSetupCommand(opts) {
27741
28072
  } catch {
27742
28073
  return {
27743
28074
  message: [
27744
- `${color59.red("\u2717")} Could not reach Telegram API.`,
28075
+ `${color60.red("\u2717")} Could not reach Telegram API.`,
27745
28076
  "",
27746
28077
  "Check your network connection and try again."
27747
28078
  ].join("\n")
@@ -27750,7 +28081,7 @@ function buildTelegramSetupCommand(opts) {
27750
28081
  if (!botInfo.ok || !botInfo.result) {
27751
28082
  return {
27752
28083
  message: [
27753
- `${color59.red("\u2717")} Invalid bot token.`,
28084
+ `${color60.red("\u2717")} Invalid bot token.`,
27754
28085
  "",
27755
28086
  "Get a valid token from @BotFather on Telegram."
27756
28087
  ].join("\n")
@@ -27760,13 +28091,13 @@ function buildTelegramSetupCommand(opts) {
27760
28091
  const classifiedChatId = chatId ? classifyTelegramChatId(chatId) : void 0;
27761
28092
  if (classifiedChatId?.kind === "invalid") {
27762
28093
  return {
27763
- message: `${color59.red("\u2717")} Invalid Telegram chat ID. Expected a positive private chat ID.`
28094
+ message: `${color60.red("\u2717")} Invalid Telegram chat ID. Expected a positive private chat ID.`
27764
28095
  };
27765
28096
  }
27766
28097
  if (classifiedChatId?.kind === "group") {
27767
28098
  return {
27768
28099
  message: [
27769
- `${color59.amber("\u26A0")} Shared group, supergroup, and channel IDs cannot be paired by manual ID.`,
28100
+ `${color60.amber("\u26A0")} Shared group, supergroup, and channel IDs cannot be paired by manual ID.`,
27770
28101
  "Run /telegram-setup without a chat ID and select a discovered private identity.",
27771
28102
  "No configuration was changed."
27772
28103
  ].join("\n")
@@ -27780,7 +28111,7 @@ function buildTelegramSetupCommand(opts) {
27780
28111
  } catch {
27781
28112
  return {
27782
28113
  message: [
27783
- `${color59.red("\u2717")} Could not discover recent Telegram chats.`,
28114
+ `${color60.red("\u2717")} Could not discover recent Telegram chats.`,
27784
28115
  "Message the bot once, then run /telegram-setup again.",
27785
28116
  "No configuration was changed."
27786
28117
  ].join("\n")
@@ -27789,7 +28120,7 @@ function buildTelegramSetupCommand(opts) {
27789
28120
  if (candidates.length === 0) {
27790
28121
  return {
27791
28122
  message: [
27792
- `${color59.amber("No recent chats found.")}`,
28123
+ `${color60.amber("No recent chats found.")}`,
27793
28124
  "Message the bot from the private account you want to pair, then run setup again.",
27794
28125
  "No configuration was changed."
27795
28126
  ].join("\n")
@@ -27797,31 +28128,31 @@ function buildTelegramSetupCommand(opts) {
27797
28128
  }
27798
28129
  opts.renderer.write(
27799
28130
  [
27800
- color59.bold("Recent Telegram identities"),
28131
+ color60.bold("Recent Telegram identities"),
27801
28132
  formatTelegramPairingCandidates(candidates),
27802
28133
  "",
27803
- color59.dim("Choose a private candidate number, or press Enter to cancel.")
28134
+ color60.dim("Choose a private candidate number, or press Enter to cancel.")
27804
28135
  ].join("\n")
27805
28136
  );
27806
28137
  let choiceInput;
27807
28138
  try {
27808
28139
  choiceInput = opts.readText ? await opts.readText("Pair candidate \u203A ") : await opts.reader.readLine("Pair candidate \u203A ");
27809
28140
  } catch {
27810
- return { message: color59.dim("Telegram setup cancelled. No configuration was changed.") };
28141
+ return { message: color60.dim("Telegram setup cancelled. No configuration was changed.") };
27811
28142
  }
27812
28143
  const choice = parseTelegramPairingChoice(choiceInput, candidates);
27813
28144
  if (choice.kind === "cancel") {
27814
- return { message: color59.dim("Telegram setup cancelled. No configuration was changed.") };
28145
+ return { message: color60.dim("Telegram setup cancelled. No configuration was changed.") };
27815
28146
  }
27816
28147
  if (choice.kind === "invalid") {
27817
28148
  return {
27818
- message: `${color59.red("\u2717")} Invalid pairing choice. No configuration was changed.`
28149
+ message: `${color60.red("\u2717")} Invalid pairing choice. No configuration was changed.`
27819
28150
  };
27820
28151
  }
27821
28152
  if (!choice.candidate.eligible) {
27822
28153
  return {
27823
28154
  message: [
27824
- `${color59.amber("\u26A0")} Shared, group, or ambiguous identities are not paired automatically.`,
28155
+ `${color60.amber("\u26A0")} Shared, group, or ambiguous identities are not paired automatically.`,
27825
28156
  "Use a private chat where chat_id and user_id identify the same account.",
27826
28157
  "No configuration was changed."
27827
28158
  ].join("\n")
@@ -27863,7 +28194,7 @@ function buildTelegramSetupCommand(opts) {
27863
28194
  } catch {
27864
28195
  return {
27865
28196
  message: [
27866
- `${color59.red("\u2717")} Failed to save Telegram configuration.`,
28197
+ `${color60.red("\u2717")} Failed to save Telegram configuration.`,
27867
28198
  "The token was not printed. Check the config path and vault, then try again."
27868
28199
  ].join("\n")
27869
28200
  };
@@ -27871,15 +28202,15 @@ function buildTelegramSetupCommand(opts) {
27871
28202
  const bot = botInfo.result;
27872
28203
  return {
27873
28204
  message: [
27874
- `${color59.green("\u2713")} Telegram configured successfully.`,
28205
+ `${color60.green("\u2713")} Telegram configured successfully.`,
27875
28206
  "",
27876
- `Bot: ${color59.bold(`@${bot.username ?? bot.first_name}`)}`,
28207
+ `Bot: ${color60.bold(`@${bot.username ?? bot.first_name}`)}`,
27877
28208
  ...pairedCandidate ? [
27878
- `Paired private chat: ${color59.green(String(pairedCandidate.chatId))}`,
27879
- `Paired user: ${color59.green(String(pairedCandidate.userId))}`
27880
- ] : chatId ? [`Default chat: ${color59.green(chatId)}`] : [],
28209
+ `Paired private chat: ${color60.green(String(pairedCandidate.chatId))}`,
28210
+ `Paired user: ${color60.green(String(pairedCandidate.userId))}`
28211
+ ] : chatId ? [`Default chat: ${color60.green(chatId)}`] : [],
27881
28212
  "",
27882
- `${color59.amber("\u26A0")} Restart WrongStack for the plugin to load the new token.`
28213
+ `${color60.amber("\u26A0")} Restart WrongStack for the plugin to load the new token.`
27883
28214
  ].join("\n")
27884
28215
  };
27885
28216
  }
@@ -27913,15 +28244,15 @@ function buildTelegramSettingsCommand(opts) {
27913
28244
  const chat = tg.notifyChatId !== void 0 && tg.notifyChatId !== null ? String(tg.notifyChatId) : "not set";
27914
28245
  const hasToken = typeof tg.botToken === "string" && tg.botToken.length > 0;
27915
28246
  return [
27916
- `${color60.bold("Telegram")} ${color60.dim("\u2014 Notification Settings")}`,
28247
+ `${color61.bold("Telegram")} ${color61.dim("\u2014 Notification Settings")}`,
27917
28248
  "",
27918
- ` session end: ${sessionEnd ? color60.cyan("on") : color60.dim("off")} ${color60.dim("change: /telegram-settings session-end on|off")}`,
27919
- ` delegate done: ${delegate ? color60.cyan("on") : color60.dim("off")} ${color60.dim("change: /telegram-settings delegate on|off")}`,
27920
- ` long tool: ${color60.cyan(longTool)} ${color60.dim("change: /telegram-settings long-tool <ms|off>")}`,
27921
- ` poll interval: ${color60.cyan(poll)} ${color60.dim("change: /telegram-settings poll <seconds>")}`,
27922
- ` notify chat: ${color60.cyan(chat)} ${color60.dim("change: /telegram-settings chat <chatId>")}`,
28249
+ ` session end: ${sessionEnd ? color61.cyan("on") : color61.dim("off")} ${color61.dim("change: /telegram-settings session-end on|off")}`,
28250
+ ` delegate done: ${delegate ? color61.cyan("on") : color61.dim("off")} ${color61.dim("change: /telegram-settings delegate on|off")}`,
28251
+ ` long tool: ${color61.cyan(longTool)} ${color61.dim("change: /telegram-settings long-tool <ms|off>")}`,
28252
+ ` poll interval: ${color61.cyan(poll)} ${color61.dim("change: /telegram-settings poll <seconds>")}`,
28253
+ ` notify chat: ${color61.cyan(chat)} ${color61.dim("change: /telegram-settings chat <chatId>")}`,
27923
28254
  "",
27924
- hasToken ? color60.dim(" Bot token configured. Changes apply immediately.") : `${color60.amber("\u26A0")} No bot token configured. Run: /telegram-setup <botToken> [chatId]`
28255
+ hasToken ? color61.dim(" Bot token configured. Changes apply immediately.") : `${color61.amber("\u26A0")} No bot token configured. Run: /telegram-setup <botToken> [chatId]`
27925
28256
  ].join("\n");
27926
28257
  }
27927
28258
  return {
@@ -27937,7 +28268,7 @@ function buildTelegramSettingsCommand(opts) {
27937
28268
  return { message: HELP2 };
27938
28269
  }
27939
28270
  if (!opts.configStore || !opts.paths?.globalConfig || !opts.vault) {
27940
- return { message: `${color60.red("Error")} secure config persistence not available.` };
28271
+ return { message: `${color61.red("Error")} secure config persistence not available.` };
27941
28272
  }
27942
28273
  if (!sub) {
27943
28274
  return { message: currentView() };
@@ -27951,7 +28282,7 @@ function buildTelegramSettingsCommand(opts) {
27951
28282
  if (sub === "all") {
27952
28283
  const raw = (rest[0] ?? "").toLowerCase();
27953
28284
  if (!["on", "off"].includes(raw)) {
27954
- return { message: `${color60.amber("Usage:")} /telegram-settings all on|off` };
28285
+ return { message: `${color61.amber("Usage:")} /telegram-settings all on|off` };
27955
28286
  }
27956
28287
  const on = raw === "on";
27957
28288
  await persistTelegramConfig(persistDeps, (tg) => {
@@ -27959,40 +28290,40 @@ function buildTelegramSettingsCommand(opts) {
27959
28290
  tg.notifyOnDelegate = on;
27960
28291
  });
27961
28292
  return {
27962
- message: `${color60.green("\u2713")} all event notifications \u2192 ${on ? color60.cyan("on") : color60.dim("off")} ${color60.dim("(session-end, delegate)")}`
28293
+ message: `${color61.green("\u2713")} all event notifications \u2192 ${on ? color61.cyan("on") : color61.dim("off")} ${color61.dim("(session-end, delegate)")}`
27963
28294
  };
27964
28295
  }
27965
28296
  if (sub === "session-end") {
27966
28297
  const raw = (rest[0] ?? "").toLowerCase();
27967
28298
  if (!["on", "off"].includes(raw)) {
27968
- return { message: `${color60.amber("Usage:")} /telegram-settings session-end on|off` };
28299
+ return { message: `${color61.amber("Usage:")} /telegram-settings session-end on|off` };
27969
28300
  }
27970
28301
  const on = raw === "on";
27971
28302
  await persistTelegramConfig(persistDeps, (tg) => {
27972
28303
  tg.notifyOnSessionEnd = on;
27973
28304
  });
27974
28305
  return {
27975
- message: `${color60.green("\u2713")} session-end \u2192 ${on ? color60.cyan("on") : color60.dim("off")}`
28306
+ message: `${color61.green("\u2713")} session-end \u2192 ${on ? color61.cyan("on") : color61.dim("off")}`
27976
28307
  };
27977
28308
  }
27978
28309
  if (sub === "delegate") {
27979
28310
  const raw = (rest[0] ?? "").toLowerCase();
27980
28311
  if (!["on", "off"].includes(raw)) {
27981
- return { message: `${color60.amber("Usage:")} /telegram-settings delegate on|off` };
28312
+ return { message: `${color61.amber("Usage:")} /telegram-settings delegate on|off` };
27982
28313
  }
27983
28314
  const on = raw === "on";
27984
28315
  await persistTelegramConfig(persistDeps, (tg) => {
27985
28316
  tg.notifyOnDelegate = on;
27986
28317
  });
27987
28318
  return {
27988
- message: `${color60.green("\u2713")} delegate \u2192 ${on ? color60.cyan("on") : color60.dim("off")}`
28319
+ message: `${color61.green("\u2713")} delegate \u2192 ${on ? color61.cyan("on") : color61.dim("off")}`
27989
28320
  };
27990
28321
  }
27991
28322
  if (sub === "long-tool") {
27992
28323
  const raw = rest[0];
27993
28324
  if (raw === void 0) {
27994
28325
  return {
27995
- message: `${color60.amber("Usage:")} /telegram-settings long-tool <ms|off> ${color60.dim("(0 or off disables)")}`
28326
+ message: `${color61.amber("Usage:")} /telegram-settings long-tool <ms|off> ${color61.dim("(0 or off disables)")}`
27996
28327
  };
27997
28328
  }
27998
28329
  if (raw === "off") {
@@ -28000,57 +28331,57 @@ function buildTelegramSettingsCommand(opts) {
28000
28331
  tg.longToolThresholdMs = 0;
28001
28332
  });
28002
28333
  return {
28003
- message: `${color60.green("\u2713")} long-tool \u2192 ${color60.dim("off")}`
28334
+ message: `${color61.green("\u2713")} long-tool \u2192 ${color61.dim("off")}`
28004
28335
  };
28005
28336
  }
28006
28337
  const ms = Number.parseInt(raw, 10);
28007
28338
  if (Number.isNaN(ms) || ms < 0) {
28008
28339
  return {
28009
- message: `${color60.red("Invalid number")}: "${raw}". Enter milliseconds, e.g. /telegram-settings long-tool 15000`
28340
+ message: `${color61.red("Invalid number")}: "${raw}". Enter milliseconds, e.g. /telegram-settings long-tool 15000`
28010
28341
  };
28011
28342
  }
28012
28343
  await persistTelegramConfig(persistDeps, (tg) => {
28013
28344
  tg.longToolThresholdMs = ms;
28014
28345
  });
28015
28346
  return {
28016
- message: `${color60.green("\u2713")} long-tool \u2192 ${color60.cyan(`${ms}ms`)}`
28347
+ message: `${color61.green("\u2713")} long-tool \u2192 ${color61.cyan(`${ms}ms`)}`
28017
28348
  };
28018
28349
  }
28019
28350
  if (sub === "poll") {
28020
28351
  const raw = rest[0];
28021
28352
  if (raw === void 0) {
28022
28353
  return {
28023
- message: `${color60.amber("Usage:")} /telegram-settings poll <seconds> ${color60.dim("(1\u201360)")}`
28354
+ message: `${color61.amber("Usage:")} /telegram-settings poll <seconds> ${color61.dim("(1\u201360)")}`
28024
28355
  };
28025
28356
  }
28026
28357
  const sec = Number.parseInt(raw, 10);
28027
28358
  if (Number.isNaN(sec) || sec < 1 || sec > 60) {
28028
28359
  return {
28029
- message: `${color60.red("Invalid value")}: "${raw}". Enter seconds between 1 and 60.`
28360
+ message: `${color61.red("Invalid value")}: "${raw}". Enter seconds between 1 and 60.`
28030
28361
  };
28031
28362
  }
28032
28363
  await persistTelegramConfig(persistDeps, (tg) => {
28033
28364
  tg.pollIntervalSec = sec;
28034
28365
  });
28035
28366
  return {
28036
- message: `${color60.green("\u2713")} poll \u2192 ${color60.cyan(`${sec}s`)}`
28367
+ message: `${color61.green("\u2713")} poll \u2192 ${color61.cyan(`${sec}s`)}`
28037
28368
  };
28038
28369
  }
28039
28370
  if (sub === "chat") {
28040
28371
  const raw = rest[0];
28041
28372
  if (!raw) {
28042
- return { message: `${color60.amber("Usage:")} /telegram-settings chat <chatId>` };
28373
+ return { message: `${color61.amber("Usage:")} /telegram-settings chat <chatId>` };
28043
28374
  }
28044
28375
  const classification = classifyTelegramChatId(raw);
28045
28376
  if (classification.kind === "invalid") {
28046
- return { message: `${color60.red("Invalid chat ID")}: expected a non-zero integer.` };
28377
+ return { message: `${color61.red("Invalid chat ID")}: expected a non-zero integer.` };
28047
28378
  }
28048
28379
  const current = opts.configStore.get();
28049
28380
  const allowGroupChats = current.extensions?.telegram?.allowGroupChats === true;
28050
28381
  if (classification.kind === "group" && !allowGroupChats) {
28051
28382
  return {
28052
28383
  message: [
28053
- `${color60.amber("\u26A0")} Group, supergroup, and channel targets require explicit allowGroupChats=true.`,
28384
+ `${color61.amber("\u26A0")} Group, supergroup, and channel targets require explicit allowGroupChats=true.`,
28054
28385
  "No configuration was changed."
28055
28386
  ].join("\n")
28056
28387
  };
@@ -28073,15 +28404,15 @@ function buildTelegramSettingsCommand(opts) {
28073
28404
  }
28074
28405
  });
28075
28406
  return {
28076
- message: `${color60.green("\u2713")} notify chat \u2192 ${color60.cyan(raw)}`
28407
+ message: `${color61.green("\u2713")} notify chat \u2192 ${color61.cyan(raw)}`
28077
28408
  };
28078
28409
  }
28079
28410
  return {
28080
- message: `${color60.red("Unknown setting")} "${sub}". ${unknownSubcommand(sub, ["session-end", "delegate", "long-tool", "poll", "chat", "all"], "telegram-settings")}`
28411
+ message: `${color61.red("Unknown setting")} "${sub}". ${unknownSubcommand(sub, ["session-end", "delegate", "long-tool", "poll", "chat", "all"], "telegram-settings")}`
28081
28412
  };
28082
28413
  } catch (err) {
28083
28414
  return {
28084
- message: `${color60.red("Settings error")}: ${toErrorMessage26(err)}`
28415
+ message: `${color61.red("Settings error")}: ${toErrorMessage26(err)}`
28085
28416
  };
28086
28417
  }
28087
28418
  }
@@ -28227,9 +28558,9 @@ function buildTodosCommand(opts) {
28227
28558
  }
28228
28559
 
28229
28560
  // src/slash-commands/tool.ts
28230
- import { noOpVault as noOpVault10 } from "@wrongstack/core/security";
28561
+ import { noOpVault as noOpVault11 } from "@wrongstack/core/security";
28231
28562
  import {
28232
- color as color61,
28563
+ color as color62,
28233
28564
  getToolDescriptionMode,
28234
28565
  getToolResultRenderMode,
28235
28566
  normalizeToolDescriptionMode,
@@ -28243,11 +28574,11 @@ function fit(text, width) {
28243
28574
  }
28244
28575
  function formatDescriptionMode(mode) {
28245
28576
  const raw = `desc:${mode}`;
28246
- return mode === "simple" ? color61.amber(raw) : color61.cyan(raw);
28577
+ return mode === "simple" ? color62.amber(raw) : color62.cyan(raw);
28247
28578
  }
28248
28579
  function formatResultRenderMode(mode) {
28249
28580
  const raw = `result:${mode}`;
28250
- return mode === "simple" ? color61.amber(raw) : color61.cyan(raw);
28581
+ return mode === "simple" ? color62.amber(raw) : color62.cyan(raw);
28251
28582
  }
28252
28583
  function buildToolCommand(opts) {
28253
28584
  const help = [
@@ -28311,7 +28642,7 @@ function buildToolCommand(opts) {
28311
28642
  configStore: opts.configStore,
28312
28643
  profileConfigPath: activeProfileConfigPath(opts.paths, opts.configStore.get()),
28313
28644
  inProjectConfigPath: opts.paths.inProjectConfig,
28314
- vault: noOpVault10
28645
+ vault: noOpVault11
28315
28646
  },
28316
28647
  (cfg) => {
28317
28648
  cfg.tools = next;
@@ -28340,7 +28671,7 @@ function buildToolCommand(opts) {
28340
28671
  configStore: opts.configStore,
28341
28672
  profileConfigPath: activeProfileConfigPath(opts.paths, opts.configStore.get()),
28342
28673
  inProjectConfigPath: opts.paths.inProjectConfig,
28343
- vault: noOpVault10
28674
+ vault: noOpVault11
28344
28675
  },
28345
28676
  (cfg) => {
28346
28677
  cfg.tools = nextTools;
@@ -28353,38 +28684,38 @@ function buildToolCommand(opts) {
28353
28684
  const resultSimple = Object.entries(configured.resultRenderMode ?? {}).filter(([, mode]) => normalizeToolResultRenderMode(mode) === "simple").map(([name]) => name).sort();
28354
28685
  const disabled = opts.toolRegistry.listDisabled();
28355
28686
  const lines = [
28356
- `${color61.bold("Tool modes")} ${color61.dim("(default: extend on both axes)")}`,
28687
+ `${color62.bold("Tool modes")} ${color62.dim("(default: extend on both axes)")}`,
28357
28688
  "",
28358
- `${formatDescriptionMode("simple")}: ${descSimple.length > 0 ? descSimple.map((n) => color61.cyan(n)).join(", ") : color61.dim("none")}`,
28359
- `${formatResultRenderMode("simple")}: ${resultSimple.length > 0 ? resultSimple.map((n) => color61.cyan(n)).join(", ") : color61.dim("none")}`,
28689
+ `${formatDescriptionMode("simple")}: ${descSimple.length > 0 ? descSimple.map((n) => color62.cyan(n)).join(", ") : color62.dim("none")}`,
28690
+ `${formatResultRenderMode("simple")}: ${resultSimple.length > 0 ? resultSimple.map((n) => color62.cyan(n)).join(", ") : color62.dim("none")}`,
28360
28691
  ""
28361
28692
  ];
28362
28693
  if (disabled.length > 0) {
28363
28694
  lines.push(
28364
- `${color61.bold("Disabled tools")}`,
28695
+ `${color62.bold("Disabled tools")}`,
28365
28696
  "",
28366
- ` ${color61.red("disabled")}: ${disabled.map(({ tool }) => color61.dim(tool.name)).join(", ")}`,
28697
+ ` ${color62.red("disabled")}: ${disabled.map(({ tool }) => color62.dim(tool.name)).join(", ")}`,
28367
28698
  ""
28368
28699
  );
28369
28700
  }
28370
28701
  lines.push(
28371
- color61.dim(
28702
+ color62.dim(
28372
28703
  " /tool <name> desc simple \xB7 /tool <name> result simple \xB7 /tool list \xB7 /tool disable|enable <name>"
28373
28704
  )
28374
28705
  );
28375
28706
  return lines.join("\n");
28376
28707
  }
28377
28708
  function formatList() {
28378
- const header = ` ${color61.dim(fit("tool", 28))} ${color61.dim(fit("owner", 28))} ${color61.dim(fit("status", 10))} ${color61.dim(fit("desc", 14))} ` + color61.dim("result");
28709
+ const header = ` ${color62.dim(fit("tool", 28))} ${color62.dim(fit("owner", 28))} ${color62.dim(fit("status", 10))} ${color62.dim(fit("desc", 14))} ` + color62.dim("result");
28379
28710
  const rows = opts.toolRegistry.listWithOwner().map(({ tool }) => {
28380
28711
  const descMode = getToolDescriptionMode(opts.toolRegistry, tool.name);
28381
28712
  const resultMode = getToolResultRenderMode(opts.toolRegistry, tool.name);
28382
28713
  const owner = opts.toolRegistry.ownerOf(tool.name) ?? "core";
28383
- const status = opts.toolRegistry.isDisabled(tool.name) ? color61.red("disabled") : color61.green("active");
28384
- return ` ${fit(tool.name, 28)} ${color61.dim(fit(`[${owner}]`, 28))} ${fit(status, 10)} ${fit(formatDescriptionMode(descMode), 14)} ` + formatResultRenderMode(resultMode);
28714
+ const status = opts.toolRegistry.isDisabled(tool.name) ? color62.red("disabled") : color62.green("active");
28715
+ return ` ${fit(tool.name, 28)} ${color62.dim(fit(`[${owner}]`, 28))} ${fit(status, 10)} ${fit(formatDescriptionMode(descMode), 14)} ` + formatResultRenderMode(resultMode);
28385
28716
  });
28386
28717
  return [
28387
- `${color61.bold("Tool modes")} ${color61.dim("(default: extend on both axes)")}`,
28718
+ `${color62.bold("Tool modes")} ${color62.dim("(default: extend on both axes)")}`,
28388
28719
  "",
28389
28720
  header,
28390
28721
  ...rows
@@ -28395,55 +28726,55 @@ function buildToolCommand(opts) {
28395
28726
  const tool = reg.get(name);
28396
28727
  if (!tool) {
28397
28728
  if (reg.isDisabled(name)) {
28398
- return `${color61.amber(name)} is disabled. Use ${color61.dim(`/tool enable ${name}`)} to restore.`;
28729
+ return `${color62.amber(name)} is disabled. Use ${color62.dim(`/tool enable ${name}`)} to restore.`;
28399
28730
  }
28400
- return `${color61.red("Unknown tool")}: ${name}. Use ${color61.dim("/tools")} to list registered tools.`;
28731
+ return `${color62.red("Unknown tool")}: ${name}. Use ${color62.dim("/tools")} to list registered tools.`;
28401
28732
  }
28402
28733
  const descMode = getToolDescriptionMode(reg, name);
28403
28734
  const resultMode = getToolResultRenderMode(reg, name);
28404
- const status = reg.isDisabled(name) ? color61.red("disabled") : color61.green("active");
28735
+ const status = reg.isDisabled(name) ? color62.red("disabled") : color62.green("active");
28405
28736
  return [
28406
- `${color61.bold(name)} ${status}`,
28737
+ `${color62.bold(name)} ${status}`,
28407
28738
  `description mode: ${formatDescriptionMode(descMode)}`,
28408
28739
  `result mode: ${formatResultRenderMode(resultMode)}`,
28409
28740
  "",
28410
- color61.dim(tool.description)
28741
+ color62.dim(tool.description)
28411
28742
  ].join("\n");
28412
28743
  }
28413
28744
  async function cmdEnable(name) {
28414
28745
  const reg = opts.toolRegistry;
28415
28746
  if (!reg.isDisabled(name)) {
28416
- return `${color61.amber(name)} is not disabled.`;
28747
+ return `${color62.amber(name)} is not disabled.`;
28417
28748
  }
28418
28749
  const ok = reg.enable(name);
28419
- if (!ok) return `${color61.red("Could not enable")}: ${name}.`;
28750
+ if (!ok) return `${color62.red("Could not enable")}: ${name}.`;
28420
28751
  const disabled = currentDisabledSet();
28421
28752
  disabled.delete(name);
28422
28753
  await persistDisabled(Array.from(disabled));
28423
- return `${color61.green("\u2713")} ${color61.cyan(name)} re-enabled \u2014 will appear in next provider request.`;
28754
+ return `${color62.green("\u2713")} ${color62.cyan(name)} re-enabled \u2014 will appear in next provider request.`;
28424
28755
  }
28425
28756
  async function cmdEnableAll() {
28426
28757
  const reg = opts.toolRegistry;
28427
28758
  const count = reg.enableAll();
28428
- if (count === 0) return `${color61.amber("No disabled tools to re-enable.")}`;
28759
+ if (count === 0) return `${color62.amber("No disabled tools to re-enable.")}`;
28429
28760
  await persistDisabled([]);
28430
- return `${color61.green("\u2713")} All ${count} disabled tool(s) re-enabled.`;
28761
+ return `${color62.green("\u2713")} All ${count} disabled tool(s) re-enabled.`;
28431
28762
  }
28432
28763
  async function cmdDisable(name) {
28433
28764
  const reg = opts.toolRegistry;
28434
28765
  const tool = reg.get(name);
28435
28766
  if (!tool) {
28436
28767
  if (reg.isDisabled(name)) {
28437
- return `${color61.amber(name)} is already disabled.`;
28768
+ return `${color62.amber(name)} is already disabled.`;
28438
28769
  }
28439
- return `${color61.red("Unknown tool")}: ${name}. Use ${color61.dim("/tools")} to list registered tools.`;
28770
+ return `${color62.red("Unknown tool")}: ${name}. Use ${color62.dim("/tools")} to list registered tools.`;
28440
28771
  }
28441
28772
  const ok = reg.disable(name);
28442
- if (!ok) return `${color61.red("Could not disable")}: ${name}.`;
28773
+ if (!ok) return `${color62.red("Could not disable")}: ${name}.`;
28443
28774
  const disabled = currentDisabledSet();
28444
28775
  disabled.add(name);
28445
28776
  await persistDisabled(Array.from(disabled));
28446
- return `${color61.green("\u2713")} ${color61.cyan(name)} disabled \u2014 removed from system prompt and tool registry.`;
28777
+ return `${color62.green("\u2713")} ${color62.cyan(name)} disabled \u2014 removed from system prompt and tool registry.`;
28447
28778
  }
28448
28779
  function applyDescMode(name, mode) {
28449
28780
  opts.toolRegistry.setDescriptionMode?.(name, mode);
@@ -28459,7 +28790,7 @@ function buildToolCommand(opts) {
28459
28790
  help,
28460
28791
  async run(args) {
28461
28792
  if (!opts.configStore) {
28462
- return { message: `${color61.red("Error")} config store not available.` };
28793
+ return { message: `${color62.red("Error")} config store not available.` };
28463
28794
  }
28464
28795
  const parts = args.trim().split(/\s+/).filter(Boolean);
28465
28796
  const sub = (parts[0] ?? "").toLowerCase();
@@ -28470,7 +28801,7 @@ function buildToolCommand(opts) {
28470
28801
  try {
28471
28802
  return { message: await cmdEnableAll() };
28472
28803
  } catch (err) {
28473
- return { message: `${color61.red("Error")}: ${toErrorMessage27(err)}` };
28804
+ return { message: `${color62.red("Error")}: ${toErrorMessage27(err)}` };
28474
28805
  }
28475
28806
  }
28476
28807
  const name = parts[0] ?? "";
@@ -28478,43 +28809,43 @@ function buildToolCommand(opts) {
28478
28809
  if (sub === "disable") {
28479
28810
  const targets = parts.slice(1);
28480
28811
  if (targets.length === 0)
28481
- return { message: `${color61.amber("Usage:")} /tool disable <name> [name...]` };
28812
+ return { message: `${color62.amber("Usage:")} /tool disable <name> [name...]` };
28482
28813
  try {
28483
28814
  const results = [];
28484
28815
  for (const t of targets) results.push(await cmdDisable(t));
28485
28816
  return { message: results.join("\n") };
28486
28817
  } catch (err) {
28487
- return { message: `${color61.red("Error")}: ${toErrorMessage27(err)}` };
28818
+ return { message: `${color62.red("Error")}: ${toErrorMessage27(err)}` };
28488
28819
  }
28489
28820
  }
28490
28821
  if (sub === "enable") {
28491
28822
  const targets = parts.slice(1);
28492
28823
  if (targets.length === 0)
28493
- return { message: `${color61.amber("Usage:")} /tool enable <name> [name...]` };
28824
+ return { message: `${color62.amber("Usage:")} /tool enable <name> [name...]` };
28494
28825
  try {
28495
28826
  const results = [];
28496
28827
  for (const t of targets) results.push(await cmdEnable(t));
28497
28828
  return { message: results.join("\n") };
28498
28829
  } catch (err) {
28499
- return { message: `${color61.red("Error")}: ${toErrorMessage27(err)}` };
28830
+ return { message: `${color62.red("Error")}: ${toErrorMessage27(err)}` };
28500
28831
  }
28501
28832
  }
28502
28833
  const action = parts[1]?.toLowerCase();
28503
28834
  if (action === "disable" || action === "enable") {
28504
28835
  if (parts.length > 2) {
28505
28836
  return {
28506
- message: `${color61.amber("Usage:")} /tool ${name} ${action}`
28837
+ message: `${color62.amber("Usage:")} /tool ${name} ${action}`
28507
28838
  };
28508
28839
  }
28509
28840
  try {
28510
28841
  return { message: action === "disable" ? await cmdDisable(name) : await cmdEnable(name) };
28511
28842
  } catch (err) {
28512
- return { message: `${color61.red("Error")}: ${toErrorMessage27(err)}` };
28843
+ return { message: `${color62.red("Error")}: ${toErrorMessage27(err)}` };
28513
28844
  }
28514
28845
  }
28515
28846
  if (!opts.toolRegistry.get(name) && !opts.toolRegistry.isDisabled(name)) {
28516
28847
  return {
28517
- message: `${color61.red("Unknown tool")}: ${name}. Use ${color61.dim("/tools")} to list registered tools.`
28848
+ message: `${color62.red("Unknown tool")}: ${name}. Use ${color62.dim("/tools")} to list registered tools.`
28518
28849
  };
28519
28850
  }
28520
28851
  if (parts.length === 1) return { message: formatOne(name) };
@@ -28523,53 +28854,53 @@ function buildToolCommand(opts) {
28523
28854
  const rawMode = parts[2];
28524
28855
  if (!rawMode) {
28525
28856
  return {
28526
- message: `${color61.amber("Usage:")} /tool ${name} ${axis} simple|extend`
28857
+ message: `${color62.amber("Usage:")} /tool ${name} ${axis} simple|extend`
28527
28858
  };
28528
28859
  }
28529
28860
  const mode2 = normalizeToolDescriptionMode(rawMode);
28530
28861
  if (!mode2) {
28531
28862
  return {
28532
- message: `${color61.amber("Usage:")} /tool ${name} ${axis} simple|extend`
28863
+ message: `${color62.amber("Usage:")} /tool ${name} ${axis} simple|extend`
28533
28864
  };
28534
28865
  }
28535
28866
  try {
28536
28867
  if (axis === "desc") {
28537
28868
  const persisted2 = await persistModeForAxis(name, "desc", mode2);
28538
28869
  applyDescMode(name, mode2);
28539
- const persistence2 = persisted2 ? color61.dim("saved") : color61.dim("runtime only; config paths unavailable");
28870
+ const persistence2 = persisted2 ? color62.dim("saved") : color62.dim("runtime only; config paths unavailable");
28540
28871
  return {
28541
- message: `${color61.green("\u2713")} ${color61.cyan(name)} ${formatDescriptionMode(mode2)} ${persistence2}`
28872
+ message: `${color62.green("\u2713")} ${color62.cyan(name)} ${formatDescriptionMode(mode2)} ${persistence2}`
28542
28873
  };
28543
28874
  }
28544
28875
  const persisted = await persistModeForAxis(name, "result", mode2);
28545
28876
  applyResultMode(name, mode2);
28546
- const persistence = persisted ? color61.dim("saved") : color61.dim("runtime only; config paths unavailable");
28877
+ const persistence = persisted ? color62.dim("saved") : color62.dim("runtime only; config paths unavailable");
28547
28878
  return {
28548
- message: `${color61.green("\u2713")} ${color61.cyan(name)} ${formatResultRenderMode(mode2)} ${persistence}`
28879
+ message: `${color62.green("\u2713")} ${color62.cyan(name)} ${formatResultRenderMode(mode2)} ${persistence}`
28549
28880
  };
28550
28881
  } catch (err) {
28551
28882
  return {
28552
- message: `${color61.red("Could not save tool setting")}: ${toErrorMessage27(err)}`
28883
+ message: `${color62.red("Could not save tool setting")}: ${toErrorMessage27(err)}`
28553
28884
  };
28554
28885
  }
28555
28886
  }
28556
28887
  const mode = normalizeToolDescriptionMode(axis);
28557
28888
  if (!mode) {
28558
28889
  return {
28559
- message: `${color61.amber("Usage:")} /tool ${name} [desc|result] simple|extend`
28890
+ message: `${color62.amber("Usage:")} /tool ${name} [desc|result] simple|extend`
28560
28891
  };
28561
28892
  }
28562
28893
  try {
28563
28894
  const persisted = await persistModeBoth(name, mode);
28564
28895
  applyDescMode(name, mode);
28565
28896
  applyResultMode(name, mode);
28566
- const persistence = persisted ? color61.dim("saved (both axes)") : color61.dim("runtime only; config paths unavailable");
28897
+ const persistence = persisted ? color62.dim("saved (both axes)") : color62.dim("runtime only; config paths unavailable");
28567
28898
  return {
28568
- message: `${color61.green("\u2713")} ${color61.cyan(name)} ${formatDescriptionMode(mode)} + ${formatResultRenderMode(mode)} ${persistence}`
28899
+ message: `${color62.green("\u2713")} ${color62.cyan(name)} ${formatDescriptionMode(mode)} + ${formatResultRenderMode(mode)} ${persistence}`
28569
28900
  };
28570
28901
  } catch (err) {
28571
28902
  return {
28572
- message: `${color61.red("Could not save tool setting")}: ${toErrorMessage27(err)}`
28903
+ message: `${color62.red("Could not save tool setting")}: ${toErrorMessage27(err)}`
28573
28904
  };
28574
28905
  }
28575
28906
  }
@@ -28577,14 +28908,14 @@ function buildToolCommand(opts) {
28577
28908
  }
28578
28909
 
28579
28910
  // src/slash-commands/tools.ts
28580
- import { color as color62, getToolDescriptionMode as getToolDescriptionMode2 } from "@wrongstack/core/utils";
28911
+ import { color as color63, getToolDescriptionMode as getToolDescriptionMode2 } from "@wrongstack/core/utils";
28581
28912
  function fit2(text, width) {
28582
28913
  if (text.length <= width) return text.padEnd(width);
28583
28914
  return `${text.slice(0, Math.max(0, width - 3))}...`;
28584
28915
  }
28585
28916
  function formatDescriptionMode2(mode) {
28586
28917
  const raw = `desc:${mode}`;
28587
- return mode === "simple" ? color62.amber(raw) : color62.dim(raw);
28918
+ return mode === "simple" ? color63.amber(raw) : color63.dim(raw);
28588
28919
  }
28589
28920
  function buildToolsCommand(opts) {
28590
28921
  return {
@@ -28605,21 +28936,21 @@ function buildToolsCommand(opts) {
28605
28936
  if (opened) return { message: "" };
28606
28937
  }
28607
28938
  if (filter && all.length === 0) {
28608
- const msg2 = `${color62.bold("Tools")} \u2014 no tool name or owner matched "${filter}".`;
28939
+ const msg2 = `${color63.bold("Tools")} \u2014 no tool name or owner matched "${filter}".`;
28609
28940
  opts.renderer.write(msg2);
28610
28941
  return { message: msg2 };
28611
28942
  }
28612
- const header = ` ${color62.dim(fit2("tool", 28))} ${color62.dim(fit2("owner", 28))} ${color62.dim(fit2("rw", 4))} ${color62.dim(fit2("perm", 8))} ${color62.dim(fit2("status", 10))} ` + color62.dim("description");
28943
+ const header = ` ${color63.dim(fit2("tool", 28))} ${color63.dim(fit2("owner", 28))} ${color63.dim(fit2("rw", 4))} ${color63.dim(fit2("perm", 8))} ${color63.dim(fit2("status", 10))} ` + color63.dim("description");
28613
28944
  const lines = all.map(({ tool, owner }) => {
28614
28945
  const mode = getToolDescriptionMode2(reg, tool.name);
28615
- const rw = tool.mutating ? color62.yellow(fit2("mut", 4)) : color62.cyan(fit2("ro", 4));
28616
- const status = reg.isDisabled(tool.name) ? color62.red("disabled") : color62.green("active");
28617
- return ` ${fit2(tool.name, 28)} ${color62.dim(fit2(`[${owner}]`, 28))} ${rw} ${color62.dim(fit2(tool.permission, 8))} ${fit2(status, 10)} ` + formatDescriptionMode2(mode);
28946
+ const rw = tool.mutating ? color63.yellow(fit2("mut", 4)) : color63.cyan(fit2("ro", 4));
28947
+ const status = reg.isDisabled(tool.name) ? color63.red("disabled") : color63.green("active");
28948
+ return ` ${fit2(tool.name, 28)} ${color63.dim(fit2(`[${owner}]`, 28))} ${rw} ${color63.dim(fit2(tool.permission, 8))} ${fit2(status, 10)} ` + formatDescriptionMode2(mode);
28618
28949
  });
28619
28950
  const extra = disabled.length > 0 ? `
28620
- ${color62.dim(`${disabled.length} tool(s) disabled. Use /tool enable <name> or /tool enable-all to restore.`)}` : "";
28621
- const filterNote = filter ? color62.dim(` matching "${filter}" (${all.length} of ${allTools.length})`) : "";
28622
- const msg = `${color62.bold("Tools")}${filterNote} (${all.length} shown, ${disabled.length} disabled) ${color62.dim("description detail via /tool <name> simple|extend")}:
28951
+ ${color63.dim(`${disabled.length} tool(s) disabled. Use /tool enable <name> or /tool enable-all to restore.`)}` : "";
28952
+ const filterNote = filter ? color63.dim(` matching "${filter}" (${all.length} of ${allTools.length})`) : "";
28953
+ const msg = `${color63.bold("Tools")}${filterNote} (${all.length} shown, ${disabled.length} disabled) ${color63.dim("description detail via /tool <name> simple|extend")}:
28623
28954
  ${header}
28624
28955
  ${lines.join("\n")}${extra}
28625
28956
  `;
@@ -28630,10 +28961,10 @@ ${lines.join("\n")}${extra}
28630
28961
  }
28631
28962
 
28632
28963
  // src/slash-commands/tuneup.ts
28633
- import * as fs16 from "node:fs/promises";
28964
+ import * as fs17 from "node:fs/promises";
28634
28965
  import * as os3 from "node:os";
28635
28966
  import * as path20 from "node:path";
28636
- import { atomicWrite as atomicWrite9, color as color63 } from "@wrongstack/core/utils";
28967
+ import { atomicWrite as atomicWrite10, color as color64 } from "@wrongstack/core/utils";
28637
28968
 
28638
28969
  // src/tuneup.ts
28639
28970
  var DEFAULT_EAGER_MAX_CHARS = 24e3;
@@ -29111,17 +29442,17 @@ function buildTuneupCommand(opts) {
29111
29442
  const parsed = parseArgs(args);
29112
29443
  if (parsed.mode === "help") return { message: help };
29113
29444
  if (parsed.mode === "usage") {
29114
- return { message: `${color63.amber("Usage:")} /tuneup [fix [--power] [--pick] | deep]` };
29445
+ return { message: `${color64.amber("Usage:")} /tuneup [fix [--power] [--pick] | deep]` };
29115
29446
  }
29116
29447
  if (!opts.paths) {
29117
- return { message: `${color63.red("Error")} config paths not available.` };
29448
+ return { message: `${color64.red("Error")} config paths not available.` };
29118
29449
  }
29119
29450
  const input = await gatherInput(opts, parsed.power);
29120
29451
  const report = runTuneup(input);
29121
- const lines = [`${color63.bold("WrongStack")} ${color63.dim("\u2014 Tune-up")}`];
29452
+ const lines = [`${color64.bold("WrongStack")} ${color64.dim("\u2014 Tune-up")}`];
29122
29453
  renderFindings(lines, report.findings);
29123
29454
  if (parsed.mode === "deep") {
29124
- lines.push("", color63.dim(" \u2192 asking the agent for a project-specific optimization plan\u2026"));
29455
+ lines.push("", color64.dim(" \u2192 asking the agent for a project-specific optimization plan\u2026"));
29125
29456
  return { message: lines.join("\n"), runText: buildDeepPrompt(report) };
29126
29457
  }
29127
29458
  if (parsed.mode === "report") {
@@ -29143,18 +29474,18 @@ function buildTuneupCommand(opts) {
29143
29474
  const applied = await applyActions(actions, opts);
29144
29475
  lines.push("");
29145
29476
  if (applied.messages.length === 0) {
29146
- lines.push(color63.dim(" no deterministic fixes to apply"));
29477
+ lines.push(color64.dim(" no deterministic fixes to apply"));
29147
29478
  } else {
29148
- for (const m of applied.messages) lines.push(` ${color63.green("\u2713")} ${m}`);
29479
+ for (const m of applied.messages) lines.push(` ${color64.green("\u2713")} ${m}`);
29149
29480
  if (applied.changed) {
29150
29481
  lines.push(
29151
- ` ${color63.green("\u2713")} written ${color63.dim("(backup: config.json.last + timestamped .bak)")}`
29482
+ ` ${color64.green("\u2713")} written ${color64.dim("(backup: config.json.last + timestamped .bak)")}`
29152
29483
  );
29153
29484
  }
29154
29485
  }
29155
29486
  const runText = report.agentHandoff || void 0;
29156
29487
  if (runText) {
29157
- lines.push("", color63.dim(" \u2192 handing instruction-file cleanups to the agent\u2026"));
29488
+ lines.push("", color64.dim(" \u2192 handing instruction-file cleanups to the agent\u2026"));
29158
29489
  }
29159
29490
  return { message: lines.join("\n"), ...runText ? { runText } : {} };
29160
29491
  }
@@ -29240,7 +29571,7 @@ async function gatherMemoryFiles(opts) {
29240
29571
  const out = [];
29241
29572
  for (const c of candidates) {
29242
29573
  try {
29243
- const content = await fs16.readFile(c.file, "utf8");
29574
+ const content = await fs17.readFile(c.file, "utf8");
29244
29575
  out.push({ label: c.label, path: c.file, content, committed: c.committed });
29245
29576
  } catch {
29246
29577
  }
@@ -29258,7 +29589,7 @@ async function gatherTrust(opts) {
29258
29589
  const file = opts.paths?.projectTrust;
29259
29590
  if (!file) return void 0;
29260
29591
  try {
29261
- const raw = await fs16.readFile(file, "utf8");
29592
+ const raw = await fs17.readFile(file, "utf8");
29262
29593
  const parsed = JSON.parse(raw);
29263
29594
  if (parsed && typeof parsed === "object") return parsed;
29264
29595
  } catch {
@@ -29269,7 +29600,7 @@ async function gatherConfigIssues(opts) {
29269
29600
  if (!opts.paths) return 0;
29270
29601
  const file = activeProfileConfigPath(opts.paths, opts.configStore.get());
29271
29602
  try {
29272
- const raw = await fs16.readFile(file, "utf8");
29603
+ const raw = await fs17.readFile(file, "utf8");
29273
29604
  const parsed = JSON.parse(raw);
29274
29605
  return diagnoseConfig(parsed).findings.length;
29275
29606
  } catch {
@@ -29287,14 +29618,14 @@ async function gatherSessionBytes(opts) {
29287
29618
  }
29288
29619
  async function dirSize(dir) {
29289
29620
  let total = 0;
29290
- const entries = await fs16.readdir(dir, { withFileTypes: true });
29621
+ const entries = await fs17.readdir(dir, { withFileTypes: true });
29291
29622
  for (const e of entries) {
29292
29623
  const full = path20.join(dir, e.name);
29293
29624
  if (e.isDirectory()) {
29294
29625
  total += await dirSize(full);
29295
29626
  } else if (e.isFile()) {
29296
29627
  try {
29297
- total += (await fs16.stat(full)).size;
29628
+ total += (await fs17.stat(full)).size;
29298
29629
  } catch {
29299
29630
  }
29300
29631
  }
@@ -29307,7 +29638,7 @@ async function applyActions(actions, opts) {
29307
29638
  const file = activeProfileConfigPath(opts.paths, opts.configStore.get());
29308
29639
  let raw = "{}";
29309
29640
  try {
29310
- raw = await fs16.readFile(file, "utf8");
29641
+ raw = await fs17.readFile(file, "utf8");
29311
29642
  } catch {
29312
29643
  }
29313
29644
  let parsed;
@@ -29315,7 +29646,7 @@ async function applyActions(actions, opts) {
29315
29646
  parsed = JSON.parse(raw);
29316
29647
  } catch {
29317
29648
  return {
29318
- messages: [`${color63.red("\u2717")} global config is not valid JSON \u2014 run /doctor fix first`],
29649
+ messages: [`${color64.red("\u2717")} global config is not valid JSON \u2014 run /doctor fix first`],
29319
29650
  changed: false
29320
29651
  };
29321
29652
  }
@@ -29353,11 +29684,11 @@ async function applyActions(actions, opts) {
29353
29684
  const changed = JSON.stringify(parsed) !== before;
29354
29685
  if (!changed) return { messages, changed: false };
29355
29686
  try {
29356
- await atomicWrite9(`${file}.last`, raw);
29357
- await atomicWrite9(`${file}.${Date.now()}.bak`, raw);
29687
+ await atomicWrite10(`${file}.last`, raw);
29688
+ await atomicWrite10(`${file}.${Date.now()}.bak`, raw);
29358
29689
  } catch {
29359
29690
  }
29360
- await atomicWrite9(file, JSON.stringify(parsed, null, 2));
29691
+ await atomicWrite10(file, JSON.stringify(parsed, null, 2));
29361
29692
  try {
29362
29693
  const homeFn = () => path20.dirname(path20.dirname(file));
29363
29694
  await appendHistory(JSON.parse(raw), parsed, "tuneup auto-fix", homeFn, file);
@@ -29424,26 +29755,26 @@ var CATEGORY_ORDER = [
29424
29755
  function severityIcon(severity) {
29425
29756
  switch (severity) {
29426
29757
  case "error":
29427
- return color63.red("\u2717");
29758
+ return color64.red("\u2717");
29428
29759
  case "warning":
29429
- return color63.amber("!");
29760
+ return color64.amber("!");
29430
29761
  case "ok":
29431
- return color63.green("\u2713");
29762
+ return color64.green("\u2713");
29432
29763
  default:
29433
- return color63.cyan("\xB7");
29764
+ return color64.cyan("\xB7");
29434
29765
  }
29435
29766
  }
29436
29767
  function renderFindings(lines, findings) {
29437
29768
  for (const category of CATEGORY_ORDER) {
29438
29769
  const group = findings.filter((f) => f.category === category);
29439
29770
  if (group.length === 0) continue;
29440
- lines.push("", color63.bold(CATEGORY_LABELS[category]));
29771
+ lines.push("", color64.bold(CATEGORY_LABELS[category]));
29441
29772
  for (const f of group) {
29442
29773
  lines.push(` ${severityIcon(f.severity)} ${f.problem}`);
29443
29774
  if (f.suggestion) {
29444
- for (const s of f.suggestion.split("\n")) lines.push(color63.dim(` ${s}`));
29775
+ for (const s of f.suggestion.split("\n")) lines.push(color64.dim(` ${s}`));
29445
29776
  }
29446
- if (f.fix) lines.push(color63.dim(` \u2192 fixable: ${f.fix}`));
29777
+ if (f.fix) lines.push(color64.dim(` \u2192 fixable: ${f.fix}`));
29447
29778
  }
29448
29779
  }
29449
29780
  }
@@ -29452,20 +29783,20 @@ function summaryLine(findings, fixable, handoffs, power) {
29452
29783
  (f) => f.severity === "warning" || f.severity === "error"
29453
29784
  ).length;
29454
29785
  if (warnings === 0 && fixable === 0 && handoffs === 0) {
29455
- return `${color63.green("\u2713")} everything looks healthy`;
29786
+ return `${color64.green("\u2713")} everything looks healthy`;
29456
29787
  }
29457
29788
  const parts = [];
29458
29789
  if (warnings > 0) parts.push(`${warnings} warning(s)`);
29459
29790
  if (fixable > 0) parts.push(`${fixable} auto-fixable`);
29460
29791
  if (handoffs > 0) parts.push(`${handoffs} for the agent`);
29461
29792
  const cmd = power ? "/tuneup fix --power" : "/tuneup fix";
29462
- return `${parts.join(", ")} ${color63.dim(`\u2014 run ${cmd}`)}`;
29793
+ return `${parts.join(", ")} ${color64.dim(`\u2014 run ${cmd}`)}`;
29463
29794
  }
29464
29795
 
29465
29796
  // src/slash-commands/working-dir.ts
29466
- import * as fs17 from "node:fs/promises";
29797
+ import * as fs18 from "node:fs/promises";
29467
29798
  import * as path21 from "node:path";
29468
- import { color as color64, toErrorMessage as toErrorMessage28 } from "@wrongstack/core/utils";
29799
+ import { color as color65, toErrorMessage as toErrorMessage28 } from "@wrongstack/core/utils";
29469
29800
  function buildWorkingDirCommand(_opts) {
29470
29801
  return {
29471
29802
  name: "working_dir",
@@ -29484,16 +29815,16 @@ function buildWorkingDirCommand(_opts) {
29484
29815
  ].join("\n"),
29485
29816
  async run(args, ctx) {
29486
29817
  if (!ctx) {
29487
- return { message: color64.yellow("No active context. Start a session first.") };
29818
+ return { message: color65.yellow("No active context. Start a session first.") };
29488
29819
  }
29489
29820
  const trimmed = args.trim();
29490
29821
  if (!trimmed) {
29491
29822
  const rel2 = path21.relative(ctx.projectRoot, ctx.workingDir) || ".";
29492
29823
  return {
29493
29824
  message: [
29494
- `Working directory: ${color64.bold(ctx.workingDir)}`,
29495
- color64.dim(` (relative to root: ${rel2})`),
29496
- color64.dim(` Project root: ${ctx.projectRoot}`)
29825
+ `Working directory: ${color65.bold(ctx.workingDir)}`,
29826
+ color65.dim(` (relative to root: ${rel2})`),
29827
+ color65.dim(` Project root: ${ctx.projectRoot}`)
29497
29828
  ].join("\n")
29498
29829
  };
29499
29830
  }
@@ -29502,7 +29833,7 @@ function buildWorkingDirCommand(_opts) {
29502
29833
  const rel = path21.relative(root, resolved);
29503
29834
  if (rel.startsWith("..") || path21.isAbsolute(rel)) {
29504
29835
  return {
29505
- message: color64.red(
29836
+ message: color65.red(
29506
29837
  `Directory "${trimmed}" is outside the project root.
29507
29838
  Resolved: ${resolved}
29508
29839
  Root: ${root}`
@@ -29510,27 +29841,27 @@ function buildWorkingDirCommand(_opts) {
29510
29841
  };
29511
29842
  }
29512
29843
  try {
29513
- const stat5 = await fs17.stat(resolved);
29844
+ const stat5 = await fs18.stat(resolved);
29514
29845
  if (!stat5.isDirectory()) {
29515
- return { message: color64.red(`Not a directory: ${resolved}`) };
29846
+ return { message: color65.red(`Not a directory: ${resolved}`) };
29516
29847
  }
29517
29848
  } catch {
29518
- return { message: color64.red(`Directory does not exist: ${resolved}`) };
29849
+ return { message: color65.red(`Directory does not exist: ${resolved}`) };
29519
29850
  }
29520
29851
  const previous = ctx.workingDir;
29521
29852
  try {
29522
29853
  ctx.setWorkingDir(resolved);
29523
29854
  } catch (err) {
29524
29855
  return {
29525
- message: color64.red(toErrorMessage28(err))
29856
+ message: color65.red(toErrorMessage28(err))
29526
29857
  };
29527
29858
  }
29528
29859
  const prevRel = path21.relative(ctx.projectRoot, previous) || ".";
29529
29860
  const newRel = path21.relative(ctx.projectRoot, resolved) || ".";
29530
29861
  return {
29531
29862
  message: [
29532
- color64.green(` \u2713 ${prevRel} \u2192 ${color64.bold(newRel)}`),
29533
- color64.dim(` ${resolved}`)
29863
+ color65.green(` \u2713 ${prevRel} \u2192 ${color65.bold(newRel)}`),
29864
+ color65.dim(` ${resolved}`)
29534
29865
  ].join("\n")
29535
29866
  };
29536
29867
  }
@@ -29599,7 +29930,7 @@ function buildWorktreeCommand(opts) {
29599
29930
  }
29600
29931
 
29601
29932
  // src/slash-commands/yolo.ts
29602
- import { color as color65 } from "@wrongstack/core/utils";
29933
+ import { color as color66 } from "@wrongstack/core/utils";
29603
29934
  function buildYoloCommand(opts) {
29604
29935
  return {
29605
29936
  name: "yolo",
@@ -29623,7 +29954,7 @@ function buildYoloCommand(opts) {
29623
29954
  }
29624
29955
  if (!arg) {
29625
29956
  const current = opts.onYolo();
29626
- const status = current ? `${color65.yellow("ON")} ${color65.dim("(auto-approving tool calls)")}` : `${color65.green("OFF")} ${color65.dim("(permission prompts active)")}`;
29957
+ const status = current ? `${color66.yellow("ON")} ${color66.dim("(auto-approving tool calls)")}` : `${color66.green("OFF")} ${color66.dim("(permission prompts active)")}`;
29627
29958
  const msg2 = `YOLO mode: ${status}`;
29628
29959
  opts.renderer.write(msg2);
29629
29960
  return { message: msg2 };
@@ -29638,11 +29969,11 @@ function buildYoloCommand(opts) {
29638
29969
  } else if (arg === "destructive") {
29639
29970
  const currentMode = opts.onYolo();
29640
29971
  if (!currentMode) {
29641
- const msg3 = `${color65.amber("YOLO is OFF.")} Destructive-gate flags are deprecated; prompts are active because YOLO is off.`;
29972
+ const msg3 = `${color66.amber("YOLO is OFF.")} Destructive-gate flags are deprecated; prompts are active because YOLO is off.`;
29642
29973
  opts.renderer.writeWarning(msg3);
29643
29974
  return { message: msg3 };
29644
29975
  }
29645
- const msg2 = `${color65.amber("Destructive gate:")} ${color65.dim("deprecated \u2014 YOLO auto-approves all non-denied tool calls.")}`;
29976
+ const msg2 = `${color66.amber("Destructive gate:")} ${color66.dim("deprecated \u2014 YOLO auto-approves all non-denied tool calls.")}`;
29646
29977
  opts.renderer.writeWarning(msg2);
29647
29978
  return { message: msg2 };
29648
29979
  } else {
@@ -29651,7 +29982,7 @@ function buildYoloCommand(opts) {
29651
29982
  return { message: msg2 };
29652
29983
  }
29653
29984
  opts.onYolo(newState);
29654
- const label = newState ? `${color65.yellow("ENABLED")} \u2014 tool calls will be auto-approved unless explicitly denied` : `${color65.green("DISABLED")} \u2014 permission prompts are active`;
29985
+ const label = newState ? `${color66.yellow("ENABLED")} \u2014 tool calls will be auto-approved unless explicitly denied` : `${color66.green("DISABLED")} \u2014 permission prompts are active`;
29655
29986
  const msg = `YOLO mode: ${label}`;
29656
29987
  opts.renderer.write(msg);
29657
29988
  return { message: msg };
@@ -29729,6 +30060,7 @@ function buildBuiltinSlashCommands(opts) {
29729
30060
  buildTelegramSetupCommand(opts),
29730
30061
  buildTelegramSettingsCommand(opts),
29731
30062
  buildSetModelCommand(opts),
30063
+ buildEffortCommand(opts),
29732
30064
  buildRefinerCommand(opts),
29733
30065
  buildFallbackCommand(opts),
29734
30066
  ...opts.statusTracker ? [buildProviderStatusCommand(opts.statusTracker)] : [],
@@ -29810,7 +30142,7 @@ function setupCliSlashCommands(params) {
29810
30142
  brain,
29811
30143
  brainSettings,
29812
30144
  brainRuntime,
29813
- brainLog,
30145
+ initialBrainLog,
29814
30146
  coordinatorController,
29815
30147
  statusTracker,
29816
30148
  shadowController,
@@ -29871,7 +30203,7 @@ function setupCliSlashCommands(params) {
29871
30203
  modeStore,
29872
30204
  fleetStreamController,
29873
30205
  interruptController,
29874
- enhanceController,
30206
+ ...enhanceController ? { enhanceController } : {},
29875
30207
  llmProvider: provider,
29876
30208
  llmModel: config.model,
29877
30209
  createProvider: (pid) => {
@@ -29881,23 +30213,23 @@ function setupCliSlashCommands(params) {
29881
30213
  return void 0;
29882
30214
  }
29883
30215
  },
29884
- statuslineConfig: statuslineConfigDeps,
30216
+ ...statuslineConfigDeps ? { statuslineConfig: statuslineConfigDeps } : {},
29885
30217
  statuslineHiddenItems: [...getCurrentHiddenItems()],
29886
30218
  setStatuslineHiddenItems,
29887
30219
  saveStatuslineHiddenItems,
29888
- agentsMonitorController,
29889
- agentMonitor,
30220
+ ...agentsMonitorController ? { agentsMonitorController } : {},
30221
+ ...agentMonitor ? { agentMonitor } : {},
29890
30222
  onPanelOpen,
29891
30223
  configStore,
29892
30224
  reader,
29893
- readSecret: (prompt) => secretInputController.readSecret(prompt),
29894
- readText: (prompt) => secretInputController.readText(prompt),
30225
+ readSecret: secretInputController.readSecret,
30226
+ readText: secretInputController.readText,
29895
30227
  vault,
29896
30228
  brain,
29897
30229
  brainSettings,
29898
30230
  brainRuntime,
29899
- getBrainLog: () => brainLog,
29900
- coordinatorController,
30231
+ getBrainLog: () => initialBrainLog,
30232
+ ...coordinatorController ? { coordinatorController } : {},
29901
30233
  statusTracker,
29902
30234
  shadowController,
29903
30235
  ...createFleetCommandHandlers({
@@ -29969,16 +30301,18 @@ function setupCliSlashCommands(params) {
29969
30301
  sddRunRegistry,
29970
30302
  getSddRuntimeState: getSddRuntimeStateForCli
29971
30303
  }),
29972
- onGoalStart: goalHost.onGoalStart,
29973
- onGoalPause: goalHost.onGoalPause,
29974
- onGoalResume: goalHost.onGoalResume,
29975
- onGoalStop: goalHost.onGoalStop,
29976
- getGoalRunner: goalHost.getGoalRunner,
29977
- onGoalMoveTask: goalHost.onGoalMoveTask,
29978
- onGoalAssignTask: goalHost.onGoalAssignTask,
29979
- onGoalAddTask: goalHost.onGoalAddTask,
29980
- onGoalRetryTask: goalHost.onGoalRetryTask,
29981
- onWorktree: goalHost.onWorktree
30304
+ ...goalHost ? {
30305
+ onGoalStart: goalHost.onGoalStart,
30306
+ onGoalPause: goalHost.onGoalPause,
30307
+ onGoalResume: goalHost.onGoalResume,
30308
+ onGoalStop: goalHost.onGoalStop,
30309
+ getGoalRunner: goalHost.getGoalRunner,
30310
+ onGoalMoveTask: goalHost.onGoalMoveTask,
30311
+ onGoalAssignTask: goalHost.onGoalAssignTask,
30312
+ onGoalAddTask: goalHost.onGoalAddTask,
30313
+ onGoalRetryTask: goalHost.onGoalRetryTask,
30314
+ onWorktree: goalHost.onWorktree
30315
+ } : {}
29982
30316
  });
29983
30317
  for (const cmd of slashCmds) {
29984
30318
  slashRegistry.register(cmd);
@@ -30857,7 +31191,7 @@ function installDesignStudio(deps) {
30857
31191
 
30858
31192
  // src/wiring/metrics.ts
30859
31193
  import { constants as fsConstants, writeFileSync } from "node:fs";
30860
- import * as fs18 from "node:fs/promises";
31194
+ import * as fs19 from "node:fs/promises";
30861
31195
  import * as path26 from "node:path";
30862
31196
  import {
30863
31197
  DefaultHealthRegistry,
@@ -31004,7 +31338,7 @@ function setupMetrics(params) {
31004
31338
  name: "session-store",
31005
31339
  check: async () => {
31006
31340
  try {
31007
- await fs18.access(wpaths.projectSessions, fsConstants.R_OK | fsConstants.W_OK);
31341
+ await fs19.access(wpaths.projectSessions, fsConstants.R_OK | fsConstants.W_OK);
31008
31342
  return { status: "healthy" };
31009
31343
  } catch {
31010
31344
  return { status: "unhealthy", detail: "session storage is not readable and writable" };
@@ -31015,7 +31349,7 @@ function setupMetrics(params) {
31015
31349
  name: "project-storage",
31016
31350
  check: async () => {
31017
31351
  try {
31018
- await fs18.access(wpaths.projectDir, fsConstants.R_OK | fsConstants.W_OK);
31352
+ await fs19.access(wpaths.projectDir, fsConstants.R_OK | fsConstants.W_OK);
31019
31353
  return { status: "healthy" };
31020
31354
  } catch {
31021
31355
  return { status: "unhealthy", detail: "project storage is not readable and writable" };
@@ -31088,7 +31422,7 @@ import { resolveProjectDir as resolveProjectDir5 } from "@wrongstack/core/coordi
31088
31422
  import { wstackGlobalRoot as wstackGlobalRoot5 } from "@wrongstack/core/utils";
31089
31423
 
31090
31424
  // src/mailbox-bridge-bootstrap.ts
31091
- import { spawn as spawn7 } from "node:child_process";
31425
+ import { spawn as spawn8 } from "node:child_process";
31092
31426
  import * as path27 from "node:path";
31093
31427
  import { readLiveLock } from "@wrongstack/core/coordination";
31094
31428
  var MAILBOX_BRIDGE_BOOTSTRAP_TIMEOUT_MS = 5e3;
@@ -31169,7 +31503,7 @@ function defaultSpawn(args, cwd) {
31169
31503
  spawnArgs = args;
31170
31504
  if (isWin) shim = buildWin32CmdShimInvocation(cmd, spawnArgs);
31171
31505
  }
31172
- const child = spawn7(shim?.command ?? cmd, shim?.args ?? spawnArgs, {
31506
+ const child = spawn8(shim?.command ?? cmd, shim?.args ?? spawnArgs, {
31173
31507
  cwd,
31174
31508
  // `detached` gives the bridge its own process group on POSIX so it
31175
31509
  // outlives the REPL. On win32 it forces a visible console window
@@ -32349,14 +32683,14 @@ function setupProviderRuntime(deps) {
32349
32683
  }
32350
32684
 
32351
32685
  // src/wiring/provider-status.ts
32352
- import * as fs19 from "node:fs/promises";
32686
+ import * as fs20 from "node:fs/promises";
32353
32687
  import { ProviderModelStatusTracker } from "@wrongstack/core/coordination";
32354
- import { atomicWrite as atomicWrite10, withFileLock } from "@wrongstack/core/utils";
32688
+ import { atomicWrite as atomicWrite11, withFileLock } from "@wrongstack/core/utils";
32355
32689
  async function setupProviderStatus(input) {
32356
32690
  const tracker = new ProviderModelStatusTracker({ events: input.events });
32357
32691
  const statusFile = input.paths.profileProviderStatus(input.paths.profileName);
32358
32692
  try {
32359
- const saved = JSON.parse(await fs19.readFile(statusFile, "utf8"));
32693
+ const saved = JSON.parse(await fs20.readFile(statusFile, "utf8"));
32360
32694
  const restored = tracker.restoreSnapshot(saved);
32361
32695
  if (restored > 0) input.logger.info(`Restored ${restored} provider waiting-room entries`);
32362
32696
  } catch (error) {
@@ -32368,7 +32702,7 @@ async function setupProviderStatus(input) {
32368
32702
  tracker.sweepExpired();
32369
32703
  if (syncRunning) return;
32370
32704
  syncRunning = true;
32371
- void fs19.readFile(statusFile, "utf8").then((raw) => tracker.restoreSnapshot(JSON.parse(raw))).catch((error) => warnUnlessMissing(input.logger, "sync", error)).finally(() => {
32705
+ void fs20.readFile(statusFile, "utf8").then((raw) => tracker.restoreSnapshot(JSON.parse(raw))).catch((error) => warnUnlessMissing(input.logger, "sync", error)).finally(() => {
32372
32706
  syncRunning = false;
32373
32707
  });
32374
32708
  }, 3e4);
@@ -32383,7 +32717,7 @@ async function setupProviderStatus(input) {
32383
32717
  await withFileLock(statusFile, async () => {
32384
32718
  let statuses = [];
32385
32719
  try {
32386
- const current = JSON.parse(await fs19.readFile(statusFile, "utf8"));
32720
+ const current = JSON.parse(await fs20.readFile(statusFile, "utf8"));
32387
32721
  if (Array.isArray(current.statuses)) statuses = current.statuses;
32388
32722
  } catch (error) {
32389
32723
  if (error.code !== "ENOENT") throw error;
@@ -32399,7 +32733,7 @@ async function setupProviderStatus(input) {
32399
32733
  if (current && current.state !== "healthy") statuses.push(current);
32400
32734
  }
32401
32735
  }
32402
- await atomicWrite10(
32736
+ await atomicWrite11(
32403
32737
  statusFile,
32404
32738
  JSON.stringify({ version: 1, updatedAt: Date.now(), statuses }, null, 2),
32405
32739
  { mode: 384 }
@@ -32921,7 +33255,7 @@ async function setupSession(params) {
32921
33255
  }
32922
33256
 
32923
33257
  // src/wiring/session-registry.ts
32924
- import { execFile as execFile3 } from "node:child_process";
33258
+ import { execFile as execFile2 } from "node:child_process";
32925
33259
  import * as path31 from "node:path";
32926
33260
  async function setupSessionRegistry(deps) {
32927
33261
  const { wpaths, projectRoot, session, context, tuiOwnsScreen, events } = deps;
@@ -32935,7 +33269,7 @@ async function setupSessionRegistry(deps) {
32935
33269
  const projectSlug = path31.basename(wpaths.projectDir);
32936
33270
  const projectName = path31.basename(projectRoot);
32937
33271
  let gitBranch = await new Promise((resolve8) => {
32938
- execFile3(
33272
+ execFile2(
32939
33273
  "git",
32940
33274
  ["rev-parse", "--abbrev-ref", "HEAD"],
32941
33275
  {
@@ -33610,7 +33944,7 @@ async function runInteractive(cliCtx) {
33610
33944
  brain,
33611
33945
  brainSettings,
33612
33946
  brainRuntime,
33613
- brainLog,
33947
+ initialBrainLog: brainLog,
33614
33948
  coordinatorController,
33615
33949
  statusTracker,
33616
33950
  shadowController,
@@ -33820,4 +34154,4 @@ export {
33820
34154
  CLI_VERSION,
33821
34155
  runInteractive
33822
34156
  };
33823
- //# sourceMappingURL=cli-main-L3T4KJKU.js.map
34157
+ //# sourceMappingURL=cli-main-XGDOIPN5.js.map