@wrongstack/cli 0.291.0 → 0.291.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6804,6 +6804,13 @@ var init_plugin_management = __esm({
6804
6804
  defaultState: "inactive",
6805
6805
  canDisable: true
6806
6806
  },
6807
+ {
6808
+ name: "process-guard",
6809
+ risk: "high",
6810
+ summary: "Blocks commands that target active WrongStack processes or host terminals.",
6811
+ defaultState: "active",
6812
+ canDisable: true
6813
+ },
6807
6814
  {
6808
6815
  name: "context-pins",
6809
6816
  risk: "low",
@@ -12000,6 +12007,7 @@ import {
12000
12007
  handleSuperMemoryDelete,
12001
12008
  handleSuperMemoryGet,
12002
12009
  handleSuperMemoryList,
12010
+ handleSuperMemoryListPage,
12003
12011
  handleSuperMemoryRemember,
12004
12012
  handleSuperMemoryUpdate,
12005
12013
  handleSuperMemoryRecover,
@@ -12537,6 +12545,16 @@ function createMessageRouter(deps) {
12537
12545
  }
12538
12546
  return handleSuperMemoryList(ws, opts.memoryStore);
12539
12547
  },
12548
+ "memory.super.listPage": (msg, ws) => {
12549
+ if (!opts.memoryStore) {
12550
+ send2(ws, {
12551
+ type: "memory.super.listPage",
12552
+ payload: { error: "Memory store not available" }
12553
+ });
12554
+ return;
12555
+ }
12556
+ return handleSuperMemoryListPage(ws, msg, opts.memoryStore);
12557
+ },
12540
12558
  "memory.super.get": (msg, ws) => {
12541
12559
  if (!opts.memoryStore) {
12542
12560
  send2(ws, {
@@ -12769,118 +12787,122 @@ import {
12769
12787
  FallbackProfileManager
12770
12788
  } from "@wrongstack/core";
12771
12789
  async function seedConfigToMeta(opts) {
12772
- const configPath2 = opts.globalConfigPath;
12773
- if (!configPath2) return;
12774
- try {
12775
- const raw = await fs29.readFile(configPath2, "utf8");
12776
- const cfg = JSON.parse(raw);
12777
- const autonomyCfg = cfg.autonomy ?? {};
12778
- const features = cfg.features ?? {};
12779
- const meta = opts.agent.ctx.meta;
12780
- const rawMode = autonomyCfg["defaultMode"];
12781
- meta["autonomy"] = rawMode === "suggest" || rawMode === "auto" ? rawMode : "off";
12782
- meta["autonomyDelayMs"] = autonomyCfg["autoProceedDelayMs"] ?? 45e3;
12783
- meta["autoProceedMaxIterations"] = autonomyCfg["autoProceedMaxIterations"] ?? 50;
12784
- meta["yolo"] = autonomyCfg["yolo"] ?? cfg.yolo ?? false;
12785
- meta["chime"] = autonomyCfg["chime"] ?? false;
12786
- meta["confirmExit"] = autonomyCfg["confirmExit"] !== false;
12787
- meta["streamFleet"] = autonomyCfg["streamFleet"] !== false;
12788
- meta["enhanceEnabled"] = autonomyCfg["enhance"] ?? true;
12789
- meta["enhanceDelayMs"] = autonomyCfg["enhanceDelayMs"] ?? 6e4;
12790
- meta["enhanceLanguage"] = autonomyCfg["enhanceLanguage"] ?? "original";
12791
- meta["nextPrediction"] = cfg.nextPrediction ?? false;
12792
- meta["fallbackModels"] = cfg.fallbackModels ?? [];
12793
- meta["fallbackProfiles"] = cfg.fallbackProfiles ?? {};
12794
- meta["favoriteModels"] = cfg.favoriteModels ?? [];
12795
- meta["favoriteModelsOnly"] = cfg.favoriteModelsOnly === true;
12796
- meta["modelAvailabilitySchedule"] = cfg.modelAvailabilitySchedule ?? [];
12797
- meta["modelMatrix"] = cfg.modelMatrix ?? {};
12798
- meta["fallbackAuto"] = cfg.fallbackAuto !== false;
12799
- if (typeof cfg.uiLocale === "string" && cfg.uiLocale) meta["uiLocale"] = cfg.uiLocale;
12800
- meta["featureMcp"] = features["mcp"] !== false;
12801
- meta["featurePlugins"] = features["plugins"] !== false;
12802
- meta["featureMemory"] = features["memory"] !== false;
12803
- meta["featureSkills"] = features["skills"] !== false;
12804
- meta["featureModelsRegistry"] = features["modelsRegistry"] !== false;
12805
- meta["indexOnStart"] = cfg.indexing?.["onSessionStart"] !== false;
12806
- meta["contextAutoCompact"] = cfg.context?.["autoCompact"] !== false;
12807
- meta["contextStrategy"] = cfg.context?.["strategy"] ?? "hybrid";
12808
- meta["contextMode"] = cfg.context?.["mode"] ?? "balanced";
12809
- {
12810
- const tsm = features["tokenSavingMode"];
12811
- meta["tokenSavingTier"] = typeof tsm === "string" ? tsm : tsm ? "medium" : "off";
12790
+ let cfg = opts.appConfig;
12791
+ if (!cfg || Object.keys(cfg).length === 0) {
12792
+ const configPath2 = opts.profileConfigPath ?? opts.globalConfigPath;
12793
+ if (!configPath2) return;
12794
+ try {
12795
+ const raw = await fs29.readFile(configPath2, "utf8");
12796
+ cfg = JSON.parse(raw);
12797
+ } catch {
12798
+ return;
12812
12799
  }
12813
- meta["maxConcurrent"] = typeof cfg.maxConcurrent === "number" ? cfg.maxConcurrent : 10;
12814
- meta["titleAnimation"] = autonomyCfg["terminalTitleAnimation"] !== false;
12815
- {
12816
- const mr = cfg.modelRuntime ?? {};
12817
- const reasoning = mr["reasoning"] ?? {};
12818
- const cache = mr["cache"] ?? {};
12819
- meta["reasoningMode"] = reasoning["mode"] ?? "auto";
12820
- meta["reasoningEffort"] = reasoning["effort"] ?? "high";
12821
- meta["reasoningPreserve"] = reasoning["preserve"] === true;
12822
- meta["cacheTtl"] = cache["ttl"] ?? "default";
12823
- }
12824
- meta["logLevel"] = cfg.log?.["level"] ?? "info";
12825
- meta["auditLevel"] = cfg.session?.["auditLevel"] ?? "standard";
12826
- meta["maxIterations"] = cfg.tools?.["maxIterations"] ?? 500;
12827
- const hqCfg = cfg.hq ?? {};
12828
- meta["hqEnabled"] = hqCfg["enabled"] === true;
12829
- meta["hqUrl"] = typeof hqCfg["url"] === "string" ? hqCfg["url"] : "";
12830
- meta["hqToken"] = typeof hqCfg["token"] === "string" ? hqCfg["token"] : "";
12831
- meta["hqRawContent"] = hqCfg["rawContent"] === true;
12832
- meta["refinerProvider"] = autonomyCfg["refinerProvider"] ?? "";
12833
- meta["refinerModel"] = autonomyCfg["refinerModel"] ?? "";
12834
- meta["refinerFallbackProfile"] = autonomyCfg["refinerFallbackProfile"] ?? "";
12835
- meta["thinkingWord"] = autonomyCfg["thinkingWord"] ?? "thinking";
12836
- meta["statuslineMode"] = autonomyCfg["statuslineMode"] ?? "detailed";
12837
- meta["animationStyle"] = autonomyCfg["animationStyle"] ?? "rainbow";
12838
- const tgExt = cfg.extensions?.["telegram"];
12839
- meta["tgConfigured"] = typeof tgExt?.["botToken"] === "string" && tgExt["botToken"].length > 0;
12840
- meta["tgSessionEnd"] = tgExt?.["notifyOnSessionEnd"] === true;
12841
- meta["tgDelegate"] = tgExt?.["notifyOnDelegate"] !== false;
12842
- const tgMs = tgExt?.["longToolThresholdMs"];
12843
- meta["tgLongToolMs"] = typeof tgMs === "number" ? tgMs : 3e4;
12844
- const cbCfg = cfg.circuitBreaker ?? {};
12845
- meta["breakerEnabled"] = cbCfg["enabled"] === true;
12846
- meta["breakerAutoKillResetMs"] = typeof cbCfg["autoKillResetMs"] === "number" ? cbCfg["autoKillResetMs"] : 6e4;
12847
- {
12848
- const featuresAllow = features["allowOutsideProjectRoot"];
12849
- const toolsRestrict = cfg.tools?.["restrictToProjectRoot"];
12850
- const allow = featuresAllow !== void 0 ? featuresAllow === true : toolsRestrict !== void 0 ? toolsRestrict !== true : true;
12851
- meta["fsAccess"] = allow ? "unrestricted" : "project";
12852
- }
12853
- meta["debugStream"] = cfg.debugStream === true;
12854
- const chimeraExt = cfg.extensions?.["wstack-chimera"];
12855
- meta["chimeraEnabled"] = chimeraExt?.["enabled"] !== false;
12856
- meta["chimeraProvider"] = chimeraExt?.["provider"] ?? "";
12857
- meta["chimeraModel"] = chimeraExt?.["model"] ?? "";
12858
- meta["chimeraMaxFiles"] = typeof chimeraExt?.["maxFiles"] === "number" && chimeraExt["maxFiles"] >= 1 ? chimeraExt["maxFiles"] : 15;
12859
- const autoFix = chimeraExt?.["autoFix"];
12860
- meta["chimeraAutoFix"] = autoFix === "off" || autoFix === "ask" || autoFix === "auto" ? autoFix : "off";
12861
- const autoReviewExt = cfg.extensions?.["wstack-auto-review"];
12862
- meta["autoReviewEnabled"] = autoReviewExt?.["enabled"] === true;
12863
- meta["autoReviewProvider"] = autoReviewExt?.["provider"] ?? "";
12864
- meta["autoReviewModel"] = autoReviewExt?.["model"] ?? "";
12865
- meta["autoReviewFallbackProfile"] = autoReviewExt?.["fallbackProfile"] ?? "";
12866
- {
12867
- let resolvedChain = [];
12868
- try {
12869
- const mgr = new FallbackProfileManager(cfg);
12870
- const named = autoReviewExt?.["fallbackProfile"];
12871
- resolvedChain = typeof named === "string" && named.length > 0 ? mgr.resolve(named) : mgr.resolveEffective({ fallbackAuto: true });
12872
- } catch {
12873
- resolvedChain = [];
12874
- }
12875
- meta["autoReviewFallbackModels"] = resolvedChain.map((e) => `${e.providerId}/${e.model}`);
12800
+ }
12801
+ const autonomyCfg = cfg.autonomy ?? {};
12802
+ const features = cfg.features ?? {};
12803
+ const meta = opts.agent.ctx.meta ??= {};
12804
+ const rawMode = autonomyCfg["defaultMode"];
12805
+ meta["autonomy"] = rawMode === "suggest" || rawMode === "auto" ? rawMode : "off";
12806
+ meta["autonomyDelayMs"] = autonomyCfg["autoProceedDelayMs"] ?? 45e3;
12807
+ meta["autoProceedMaxIterations"] = autonomyCfg["autoProceedMaxIterations"] ?? 50;
12808
+ meta["yolo"] = autonomyCfg["yolo"] ?? cfg.yolo ?? false;
12809
+ meta["chime"] = autonomyCfg["chime"] ?? false;
12810
+ meta["confirmExit"] = autonomyCfg["confirmExit"] !== false;
12811
+ meta["streamFleet"] = autonomyCfg["streamFleet"] !== false;
12812
+ meta["enhanceEnabled"] = autonomyCfg["enhance"] ?? true;
12813
+ meta["enhanceDelayMs"] = autonomyCfg["enhanceDelayMs"] ?? 6e4;
12814
+ meta["enhanceLanguage"] = autonomyCfg["enhanceLanguage"] ?? "original";
12815
+ meta["nextPrediction"] = cfg.nextPrediction ?? false;
12816
+ meta["fallbackModels"] = cfg.fallbackModels ?? [];
12817
+ meta["fallbackProfiles"] = cfg.fallbackProfiles ?? {};
12818
+ meta["favoriteModels"] = cfg.favoriteModels ?? [];
12819
+ meta["favoriteModelsOnly"] = cfg.favoriteModelsOnly === true;
12820
+ meta["modelAvailabilitySchedule"] = cfg.modelAvailabilitySchedule ?? [];
12821
+ meta["modelMatrix"] = cfg.modelMatrix ?? {};
12822
+ meta["fallbackAuto"] = cfg.fallbackAuto !== false;
12823
+ if (typeof cfg.uiLocale === "string" && cfg.uiLocale) meta["uiLocale"] = cfg.uiLocale;
12824
+ meta["featureMcp"] = features["mcp"] !== false;
12825
+ meta["featurePlugins"] = features["plugins"] !== false;
12826
+ meta["featureMemory"] = features["memory"] !== false;
12827
+ meta["featureSkills"] = features["skills"] !== false;
12828
+ meta["featureModelsRegistry"] = features["modelsRegistry"] !== false;
12829
+ meta["indexOnStart"] = cfg.indexing?.["onSessionStart"] !== false;
12830
+ meta["contextAutoCompact"] = cfg.context?.["autoCompact"] !== false;
12831
+ meta["contextStrategy"] = cfg.context?.["strategy"] ?? "hybrid";
12832
+ meta["contextMode"] = cfg.context?.["mode"] ?? "balanced";
12833
+ {
12834
+ const tsm = features["tokenSavingMode"];
12835
+ meta["tokenSavingTier"] = typeof tsm === "string" ? tsm : tsm ? "medium" : "off";
12836
+ }
12837
+ meta["maxConcurrent"] = typeof cfg.maxConcurrent === "number" ? cfg.maxConcurrent : 10;
12838
+ meta["titleAnimation"] = autonomyCfg["terminalTitleAnimation"] !== false;
12839
+ {
12840
+ const mr = cfg.modelRuntime ?? {};
12841
+ const reasoning = mr["reasoning"] ?? {};
12842
+ const cache = mr["cache"] ?? {};
12843
+ meta["reasoningMode"] = reasoning["mode"] ?? "auto";
12844
+ meta["reasoningEffort"] = reasoning["effort"] ?? "high";
12845
+ meta["reasoningPreserve"] = reasoning["preserve"] === true;
12846
+ meta["cacheTtl"] = cache["ttl"] ?? "default";
12847
+ }
12848
+ meta["logLevel"] = cfg.log?.["level"] ?? "info";
12849
+ meta["auditLevel"] = cfg.session?.["auditLevel"] ?? "standard";
12850
+ meta["maxIterations"] = cfg.tools?.["maxIterations"] ?? 500;
12851
+ const hqCfg = cfg.hq ?? {};
12852
+ meta["hqEnabled"] = hqCfg["enabled"] === true;
12853
+ meta["hqUrl"] = typeof hqCfg["url"] === "string" ? hqCfg["url"] : "";
12854
+ meta["hqToken"] = typeof hqCfg["token"] === "string" ? hqCfg["token"] : "";
12855
+ meta["hqRawContent"] = hqCfg["rawContent"] === true;
12856
+ meta["refinerProvider"] = autonomyCfg["refinerProvider"] ?? "";
12857
+ meta["refinerModel"] = autonomyCfg["refinerModel"] ?? "";
12858
+ meta["refinerFallbackProfile"] = autonomyCfg["refinerFallbackProfile"] ?? "";
12859
+ meta["thinkingWord"] = autonomyCfg["thinkingWord"] ?? "thinking";
12860
+ meta["statuslineMode"] = autonomyCfg["statuslineMode"] ?? "detailed";
12861
+ meta["animationStyle"] = autonomyCfg["animationStyle"] ?? "rainbow";
12862
+ const tgExt = cfg.extensions?.["telegram"];
12863
+ meta["tgConfigured"] = typeof tgExt?.["botToken"] === "string" && tgExt["botToken"].length > 0;
12864
+ meta["tgSessionEnd"] = tgExt?.["notifyOnSessionEnd"] === true;
12865
+ meta["tgDelegate"] = tgExt?.["notifyOnDelegate"] !== false;
12866
+ const tgMs = tgExt?.["longToolThresholdMs"];
12867
+ meta["tgLongToolMs"] = typeof tgMs === "number" ? tgMs : 3e4;
12868
+ const cbCfg = cfg.circuitBreaker ?? {};
12869
+ meta["breakerEnabled"] = cbCfg["enabled"] === true;
12870
+ meta["breakerAutoKillResetMs"] = typeof cbCfg["autoKillResetMs"] === "number" ? cbCfg["autoKillResetMs"] : 6e4;
12871
+ {
12872
+ const featuresAllow = features["allowOutsideProjectRoot"];
12873
+ const toolsRestrict = cfg.tools?.["restrictToProjectRoot"];
12874
+ const allow = featuresAllow !== void 0 ? featuresAllow === true : toolsRestrict !== void 0 ? toolsRestrict !== true : true;
12875
+ meta["fsAccess"] = allow ? "unrestricted" : "project";
12876
+ }
12877
+ meta["debugStream"] = cfg.debugStream === true;
12878
+ const chimeraExt = cfg.extensions?.["wstack-chimera"];
12879
+ meta["chimeraEnabled"] = chimeraExt?.["enabled"] !== false;
12880
+ meta["chimeraProvider"] = chimeraExt?.["provider"] ?? "";
12881
+ meta["chimeraModel"] = chimeraExt?.["model"] ?? "";
12882
+ meta["chimeraMaxFiles"] = typeof chimeraExt?.["maxFiles"] === "number" && chimeraExt["maxFiles"] >= 1 ? chimeraExt["maxFiles"] : 15;
12883
+ const autoFix = chimeraExt?.["autoFix"];
12884
+ meta["chimeraAutoFix"] = autoFix === "off" || autoFix === "ask" || autoFix === "auto" ? autoFix : "off";
12885
+ const autoReviewExt = cfg.extensions?.["wstack-auto-review"];
12886
+ meta["autoReviewEnabled"] = autoReviewExt?.["enabled"] === true;
12887
+ meta["autoReviewProvider"] = autoReviewExt?.["provider"] ?? "";
12888
+ meta["autoReviewModel"] = autoReviewExt?.["model"] ?? "";
12889
+ meta["autoReviewFallbackProfile"] = autoReviewExt?.["fallbackProfile"] ?? "";
12890
+ {
12891
+ let resolvedChain = [];
12892
+ try {
12893
+ const mgr = new FallbackProfileManager(cfg);
12894
+ const named = autoReviewExt?.["fallbackProfile"];
12895
+ resolvedChain = typeof named === "string" && named.length > 0 ? mgr.resolve(named) : mgr.resolveEffective({ fallbackAuto: true });
12896
+ } catch {
12897
+ resolvedChain = [];
12876
12898
  }
12877
- meta["autoReviewDebounceMs"] = typeof autoReviewExt?.["debounceMs"] === "number" && autoReviewExt["debounceMs"] >= 0 ? autoReviewExt["debounceMs"] : 5e3;
12878
- meta["autoReviewMaxFilesPerBatch"] = typeof autoReviewExt?.["maxFilesPerBatch"] === "number" && autoReviewExt["maxFilesPerBatch"] >= 1 ? autoReviewExt["maxFilesPerBatch"] : 15;
12879
- meta["autoReviewMaxConcurrentReviews"] = typeof autoReviewExt?.["maxConcurrentReviews"] === "number" && autoReviewExt["maxConcurrentReviews"] >= 1 ? autoReviewExt["maxConcurrentReviews"] : 2;
12880
- const cascade = autoReviewExt?.["cascadeOn"];
12881
- meta["autoReviewCascadeOn"] = cascade === "critical" || cascade === "high" ? cascade : "off";
12882
- } catch {
12899
+ meta["autoReviewFallbackModels"] = resolvedChain.map((e) => `${e.providerId}/${e.model}`);
12883
12900
  }
12901
+ meta["autoReviewDebounceMs"] = typeof autoReviewExt?.["debounceMs"] === "number" && autoReviewExt["debounceMs"] >= 0 ? autoReviewExt["debounceMs"] : 5e3;
12902
+ meta["autoReviewMaxFilesPerBatch"] = typeof autoReviewExt?.["maxFilesPerBatch"] === "number" && autoReviewExt["maxFilesPerBatch"] >= 1 ? autoReviewExt["maxFilesPerBatch"] : 15;
12903
+ meta["autoReviewMaxConcurrentReviews"] = typeof autoReviewExt?.["maxConcurrentReviews"] === "number" && autoReviewExt["maxConcurrentReviews"] >= 1 ? autoReviewExt["maxConcurrentReviews"] : 2;
12904
+ const cascade = autoReviewExt?.["cascadeOn"];
12905
+ meta["autoReviewCascadeOn"] = cascade === "critical" || cascade === "high" ? cascade : "off";
12884
12906
  }
12885
12907
  function createPrefsSeeding(opts) {
12886
12908
  let prefWriteLock = Promise.resolve();
@@ -12896,7 +12918,7 @@ function createPrefsSeeding(opts) {
12896
12918
  return snapshot;
12897
12919
  };
12898
12920
  const persistPrefs = async (payload) => {
12899
- const configPath2 = opts.globalConfigPath;
12921
+ const configPath2 = opts.profileConfigPath ?? opts.globalConfigPath;
12900
12922
  if (Array.isArray(payload["fallbackModels"]))
12901
12923
  patchLiveAppConfig({ fallbackModels: payload["fallbackModels"] });
12902
12924
  if (payload["fallbackProfiles"] && typeof payload["fallbackProfiles"] === "object" && !Array.isArray(payload["fallbackProfiles"])) {
@@ -12923,8 +12945,9 @@ function createPrefsSeeding(opts) {
12923
12945
  const write = async () => {
12924
12946
  const raw = await fs29.readFile(configPath2, "utf8");
12925
12947
  const parsed = JSON.parse(raw);
12948
+ const globalRoot = opts.globalConfigPath ? path35.dirname(opts.globalConfigPath) : void 0;
12926
12949
  const vault = new DefaultSecretVault2({
12927
- keyFile: path35.join(path35.dirname(configPath2), ".key")
12950
+ keyFile: globalRoot ? path35.join(globalRoot, ".key") : path35.join(path35.dirname(configPath2), ".key")
12928
12951
  });
12929
12952
  const decrypted = decryptConfigSecrets3(parsed, vault);
12930
12953
  const autonomy = decrypted.autonomy ?? {};
@@ -14730,14 +14753,17 @@ async function runWebUI(opts) {
14730
14753
  broadcast,
14731
14754
  log: (m) => console.log(m)
14732
14755
  };
14756
+ const watchConfigPath = opts.profileConfigPath ?? opts.globalConfigPath;
14733
14757
  let credentialWatcherClose;
14734
- if (opts.globalConfigPath && process.env["WRONGSTACK_DISABLE_CONFIG_WATCH"] !== "1") {
14758
+ if (watchConfigPath && process.env["WRONGSTACK_DISABLE_CONFIG_WATCH"] !== "1") {
14735
14759
  let lastActiveCfg = JSON.stringify(
14736
14760
  opts.appConfig?.providers?.[opts.agent.ctx.provider.id] ?? null
14737
14761
  );
14738
14762
  let lastUiLocale = opts.appConfig?.uiLocale;
14739
14763
  const watcher = watchProviderConfig(
14740
- opts.globalConfigPath,
14764
+ watchConfigPath,
14765
+ // Vault key lives at ~/.wrongstack/.key (derived from globalConfigPath),
14766
+ // not inside the profile directory — resolve via global root to stay correct.
14741
14767
  getVault(opts.globalConfigPath),
14742
14768
  (snapshot) => {
14743
14769
  try {
@@ -17514,6 +17540,7 @@ var init_plugins = __esm({
17514
17540
  async () => (await import("@wrongstack/plugins/spec-linker")).default,
17515
17541
  async () => (await import("@wrongstack/plugins/loop-breaker")).default,
17516
17542
  async () => (await import("@wrongstack/plugins/path-guard")).default,
17543
+ async () => (await import("@wrongstack/plugins/process-guard")).default,
17517
17544
  async () => (await import("@wrongstack/plugins/context-pins")).default,
17518
17545
  async () => (await import("@wrongstack/plugins/checkpoint")).default,
17519
17546
  async () => (await import("@wrongstack/plugins/error-lens")).default,
@@ -22183,6 +22210,7 @@ import { builtinToolsPack as builtinToolsPack3 } from "@wrongstack/tools";
22183
22210
  // src/arg-parser.ts
22184
22211
  var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
22185
22212
  "yolo",
22213
+ "no-yolo",
22186
22214
  "yolo-destructive",
22187
22215
  "confirm-destructive",
22188
22216
  "force-all-yolo",
@@ -22560,7 +22588,8 @@ var ReadlineInputReader = class {
22560
22588
  fresh.once("close", () => settle(""));
22561
22589
  fresh.on?.("error", (_e) => settle(""));
22562
22590
  }).then((result) => {
22563
- this.rl?.close();
22591
+ if (this.rl === fresh) this.rl = void 0;
22592
+ fresh.close();
22564
22593
  return result;
22565
22594
  });
22566
22595
  } finally {
@@ -29217,7 +29246,7 @@ var helpCmd = async (_args, deps) => {
29217
29246
  " wstack version Print version",
29218
29247
  "",
29219
29248
  color34.bold("Common flags"),
29220
- " --yolo Auto-approve tool calls unless explicitly denied",
29249
+ " --yolo / --no-yolo Force auto-approval on or off at startup",
29221
29250
  " --confirm-destructive Deprecated \u2014 YOLO no longer prompts by destructiveness",
29222
29251
  " --yolo-destructive Deprecated compatibility flag; YOLO no longer prompts by destructiveness",
29223
29252
  " --tui / --no-tui Force or disable TUI mode",
@@ -29342,6 +29371,9 @@ function resolveBundledPromptsDir() {
29342
29371
  return void 0;
29343
29372
  }
29344
29373
  }
29374
+ function shouldPrintYoloNotice(lastChoices, yoloPinned, yolo) {
29375
+ return !lastChoices && yoloPinned === void 0 && yolo;
29376
+ }
29345
29377
  async function boot(argv) {
29346
29378
  const { flags, positional } = parseArgs(argv);
29347
29379
  if (positional[0] === "update") {
@@ -29584,7 +29616,7 @@ async function boot(argv) {
29584
29616
  let modePinned;
29585
29617
  if (flags["no-tui"]) modePinned = "repl";
29586
29618
  else if (flags["tui"]) modePinned = "tui";
29587
- const yoloPinned = flags["yolo"] === true ? true : void 0;
29619
+ const yoloPinned = flags["no-yolo"] === true ? false : flags["yolo"] === true ? true : void 0;
29588
29620
  let autonomyPinned;
29589
29621
  if (flags["no-autonomy"] === true) autonomyPinned = "off";
29590
29622
  else if (flags["eternal"] === true)
@@ -29626,6 +29658,15 @@ async function boot(argv) {
29626
29658
  }
29627
29659
  if (choices.yolo !== config.yolo) config = patchConfig(config, { yolo: choices.yolo });
29628
29660
  flags["autonomy"] = choices.autonomy;
29661
+ if (shouldPrintYoloNotice(lastChoices, yoloPinned, choices.yolo)) {
29662
+ writeErr3(
29663
+ `
29664
+ ${color35.yellow("YOLO is on")}: non-denied tool calls, including shell and file writes, run without confirmation.
29665
+ ${color35.dim("Explicit deny rules still apply. Use")} --no-yolo ${color35.dim("or")} /yolo off ${color35.dim("to require prompts.")}
29666
+
29667
+ `
29668
+ );
29669
+ }
29629
29670
  let indexingAnswer;
29630
29671
  if (flags["skip-index"] || flags["skip"]) {
29631
29672
  indexingAnswer = false;
@@ -30491,21 +30532,27 @@ async function initializeCli(argv) {
30491
30532
  const desktopExit = await handleDesktopShortCircuit(earlyFlags, argv);
30492
30533
  if (desktopExit !== null) return desktopExit;
30493
30534
  const { flags: _earlyForMenu, positional: _positionalForMenu } = parseArgs(argv);
30494
- const menuResult = await runLaunchMenu({
30495
- argv,
30496
- flags: _earlyForMenu,
30497
- positional: _positionalForMenu,
30498
- renderer: new TerminalRenderer(),
30499
- reader: new ReadlineInputReader(),
30500
- // Last-saved menu choice wiring is intentionally minimal here:
30501
- // we only honor it when the user has *also* chosen no other
30502
- // surface flag. The persisted record is updated lazily inside
30503
- // boot() via a follow-up patch in the wiring layer, but the
30504
- // menu itself stays stateless so unit tests don't need to mock
30505
- // a ConfigStore. Users who want the saved-port shortcut without
30506
- // the menu can pass `--no-menu --webui --port=<saved>`.
30507
- lastChoice: void 0
30508
- });
30535
+ const launchMenuReader = new ReadlineInputReader();
30536
+ let menuResult;
30537
+ try {
30538
+ menuResult = await runLaunchMenu({
30539
+ argv,
30540
+ flags: _earlyForMenu,
30541
+ positional: _positionalForMenu,
30542
+ renderer: new TerminalRenderer(),
30543
+ reader: launchMenuReader,
30544
+ // Last-saved menu choice wiring is intentionally minimal here:
30545
+ // we only honor it when the user has *also* chosen no other
30546
+ // surface flag. The persisted record is updated lazily inside
30547
+ // boot() via a follow-up patch in the wiring layer, but the
30548
+ // menu itself stays stateless so unit tests don't need to mock
30549
+ // a ConfigStore. Users who want the saved-port shortcut without
30550
+ // the menu can pass `--no-menu --webui --port=<saved>`.
30551
+ lastChoice: void 0
30552
+ });
30553
+ } finally {
30554
+ await launchMenuReader.close();
30555
+ }
30509
30556
  let effectiveArgv = argv;
30510
30557
  if (menuResult !== null) {
30511
30558
  if (menuResult.cancelled) {
@@ -30775,6 +30822,7 @@ import * as path51 from "node:path";
30775
30822
  import {
30776
30823
  attachTodosCheckpoint as attachTodosCheckpoint2,
30777
30824
  CHIMERA_REVIEW_PROMPT,
30825
+ DEFAULT_REVIEW_FALLBACK_MODELS,
30778
30826
  fallbackProfileChain,
30779
30827
  mergeCustomModelDefs as mergeCustomModelDefs3,
30780
30828
  normalizeTokenSavingTier as normalizeTokenSavingTier3,
@@ -31009,6 +31057,7 @@ async function runWebUIDispatch(ctx) {
31009
31057
  hqAllowExec: flagBoolean(["hq-allow-exec"]) ?? false,
31010
31058
  modelsRegistry,
31011
31059
  globalConfigPath,
31060
+ profileConfigPath: ctx.profileConfigPath,
31012
31061
  mcpRegistry,
31013
31062
  subscribeEternalIteration,
31014
31063
  sessionStore,
@@ -33740,6 +33789,13 @@ function printBanner(renderer, projectName) {
33740
33789
 
33741
33790
  // src/execution.ts
33742
33791
  init_kanban_run_mirror();
33792
+ function resolveReviewerFallbackModels(reviewFallbackModels, sessionRef) {
33793
+ const base = reviewFallbackModels && reviewFallbackModels.length > 0 ? [...reviewFallbackModels] : [...DEFAULT_REVIEW_FALLBACK_MODELS];
33794
+ if (sessionRef && !base.includes(sessionRef)) {
33795
+ base.push(sessionRef);
33796
+ }
33797
+ return base;
33798
+ }
33743
33799
  async function execute(deps) {
33744
33800
  const {
33745
33801
  core: {
@@ -33864,6 +33920,7 @@ async function execute(deps) {
33864
33920
  const activeRecoveryLock = initialRecoveryLock;
33865
33921
  let currentRecoveryLock = activeRecoveryLock;
33866
33922
  const detachActiveTodosCheckpoint = detachTodosCheckpoint;
33923
+ const profileName = config.activeProfile ?? "default";
33867
33924
  const rootTraceId = context.traceId;
33868
33925
  const storageLog = (event, payload) => {
33869
33926
  const traceId = payload.traceId ?? rootTraceId;
@@ -33974,13 +34031,12 @@ async function execute(deps) {
33974
34031
  lines.push("Check for bugs, type issues, security problems, and produce a");
33975
34032
  lines.push("structured review report.");
33976
34033
  const taskDesc = lines.join("\n");
33977
- const defaultReviewFallbackModels = [
33978
- "opencode/deepseek-chat",
33979
- "opencode-go/deepseek-v4-pro",
33980
- "deepseek/deepseek-chat",
33981
- "anthropic-oauth/claude-opus-4-8",
33982
- "openai-codex/gpt-5.3-codex-spark"
33983
- ];
34034
+ const tProvider = config.provider?.trim() || void 0;
34035
+ const tModel = config.model?.trim() || void 0;
34036
+ const rawProvider = p.reviewFallbackModels ? p.config.provider?.trim() || void 0 : tProvider;
34037
+ const rawModel = p.reviewFallbackModels ? p.config.model?.trim() || void 0 : tModel;
34038
+ const effectiveProvider = rawProvider || tProvider;
34039
+ const effectiveModel = rawModel || tModel;
33984
34040
  const cfg = {
33985
34041
  name: "chimera-review",
33986
34042
  role: "reviewer",
@@ -33988,13 +34044,9 @@ async function execute(deps) {
33988
34044
  maxIterations: 50,
33989
34045
  maxToolCalls: 250,
33990
34046
  timeoutMs: 9e5,
33991
- // Auto-review resolves its configured profile before emitting the bundle.
33992
- // Ordinary Chimera/manual reviews retain the established reviewer defaults.
33993
- ...p.reviewFallbackModels ? {
33994
- provider: p.config.provider,
33995
- model: p.config.model,
33996
- fallbackModels: p.reviewFallbackModels
33997
- } : { fallbackModels: defaultReviewFallbackModels }
34047
+ provider: effectiveProvider,
34048
+ model: effectiveModel,
34049
+ ...p.reviewFallbackModels ? { fallbackModels: p.reviewFallbackModels } : { fallbackModels: resolveReviewerFallbackModels(void 0) }
33998
34050
  };
33999
34051
  const subagentId = await dir.spawn(cfg);
34000
34052
  const { randomUUID: randomUUID11 } = await import("node:crypto");
@@ -34485,6 +34537,7 @@ async function execute(deps) {
34485
34537
  provider: config.provider,
34486
34538
  family: banneredFamily,
34487
34539
  keyTail: banneredKeyTail,
34540
+ profile: profileName,
34488
34541
  getPickableProviders,
34489
34542
  switchProviderAndModel,
34490
34543
  switchAutonomy: (mode) => {
@@ -34757,6 +34810,7 @@ async function execute(deps) {
34757
34810
  flags,
34758
34811
  projectRoot,
34759
34812
  globalConfigPath: wpaths.globalConfig,
34813
+ profileConfigPath: wpaths.profileConfig(profileName),
34760
34814
  projectSessionsDir: wpaths.projectSessions,
34761
34815
  modelsRegistry,
34762
34816
  mcpRegistry,
@@ -53618,6 +53672,10 @@ var MultiAgentHost = class _MultiAgentHost {
53618
53672
  taskResultNotifier: (n) => this.reportTaskResultToLeader(n),
53619
53673
  subagentIdleTimeoutMs,
53620
53674
  ...this.opts.statusTracker ? { statusTracker: this.opts.statusTracker } : {},
53675
+ // Session's own working provider/model — absolute last-resort fallback
53676
+ // for every subagent when matrix resolution leaves model undefined.
53677
+ sessionProvider: this.deps.configStore.get().provider,
53678
+ sessionModel: this.deps.configStore.get().model,
53621
53679
  retireSubagentOnTaskComplete: this.opts.retireSubagentOnTaskComplete ?? fleetLifecycle?.retireOnTaskComplete ?? true
53622
53680
  });
53623
53681
  this.director.on("task.completed", ({ task, result }) => {
@@ -56590,10 +56648,16 @@ function setupProviderRuntime(deps) {
56590
56648
  "uiLocale"
56591
56649
  ];
56592
56650
  if (process.env["WRONGSTACK_DISABLE_CONFIG_WATCH"] !== "1") {
56651
+ const activeProfile = typeof cfg.activeProfile === "string" && cfg.activeProfile ? cfg.activeProfile : "default";
56593
56652
  const configLayers = [
56594
56653
  { path: wpaths.globalConfig, priority: 1 },
56595
- { path: wpaths.projectLocalConfig, priority: 2 },
56596
- { path: wpaths.inProjectConfig, priority: 3 }
56654
+ // Profile config (~/.wrongstack/profiles/<name>/config.json) sits between
56655
+ // the thin global bootstrap (version + activeProfile only) and the
56656
+ // project-local override. All user settings, providers, and routing configs
56657
+ // live in the profile — without this layer, hot-reload never reads them.
56658
+ { path: wpaths.profileConfig(activeProfile), priority: 2 },
56659
+ { path: wpaths.projectLocalConfig, priority: 3 },
56660
+ { path: wpaths.inProjectConfig, priority: 4 }
56597
56661
  ];
56598
56662
  const readMergedSnapshot = async () => {
56599
56663
  let merged;
@@ -56605,7 +56669,11 @@ function setupProviderRuntime(deps) {
56605
56669
  );
56606
56670
  if (!snap) continue;
56607
56671
  if (!merged) {
56608
- merged = { ...snap, providers: { ...snap.providers } };
56672
+ merged = {
56673
+ ...snap,
56674
+ providers: { ...snap.providers },
56675
+ snapshotHasProviders: snap.snapshotHasProviders
56676
+ };
56609
56677
  } else {
56610
56678
  merged = {
56611
56679
  providers: { ...merged.providers, ...snap.providers },
@@ -56618,7 +56686,10 @@ function setupProviderRuntime(deps) {
56618
56686
  ...snap.modelAvailabilitySchedule !== void 0 ? { modelAvailabilitySchedule: snap.modelAvailabilitySchedule } : merged.modelAvailabilitySchedule !== void 0 ? { modelAvailabilitySchedule: merged.modelAvailabilitySchedule } : {},
56619
56687
  ...snap.modelMatrix !== void 0 ? { modelMatrix: snap.modelMatrix } : merged.modelMatrix !== void 0 ? { modelMatrix: merged.modelMatrix } : {},
56620
56688
  ...snap.fallbackAuto !== void 0 ? { fallbackAuto: snap.fallbackAuto } : merged.fallbackAuto !== void 0 ? { fallbackAuto: merged.fallbackAuto } : {},
56621
- ...snap.uiLocale !== void 0 ? { uiLocale: snap.uiLocale } : merged.uiLocale !== void 0 ? { uiLocale: merged.uiLocale } : {}
56689
+ ...snap.uiLocale !== void 0 ? { uiLocale: snap.uiLocale } : merged.uiLocale !== void 0 ? { uiLocale: merged.uiLocale } : {},
56690
+ // Carry forward the snapshotHasProviders flag from the higher-priority layer.
56691
+ // When a layer has providers, merged knows providers were found somewhere.
56692
+ snapshotHasProviders: snap.snapshotHasProviders || merged.snapshotHasProviders
56622
56693
  };
56623
56694
  }
56624
56695
  }