cascade-ai 0.12.3 → 0.12.4

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/cli.cjs CHANGED
@@ -6,7 +6,7 @@ var genai = require('@google/genai');
6
6
  var ink = require('ink');
7
7
  var commander = require('commander');
8
8
  var React2 = require('react');
9
- var chalk11 = require('chalk');
9
+ var chalk9 = require('chalk');
10
10
  var dotenv = require('dotenv');
11
11
  var fs21 = require('fs');
12
12
  var path23 = require('path');
@@ -64,7 +64,7 @@ function _interopNamespace(e) {
64
64
  var Anthropic__default = /*#__PURE__*/_interopDefault(Anthropic);
65
65
  var OpenAI__default = /*#__PURE__*/_interopDefault(OpenAI);
66
66
  var React2__default = /*#__PURE__*/_interopDefault(React2);
67
- var chalk11__default = /*#__PURE__*/_interopDefault(chalk11);
67
+ var chalk9__default = /*#__PURE__*/_interopDefault(chalk9);
68
68
  var dotenv__default = /*#__PURE__*/_interopDefault(dotenv);
69
69
  var fs21__default = /*#__PURE__*/_interopDefault(fs21);
70
70
  var path23__default = /*#__PURE__*/_interopDefault(path23);
@@ -3236,15 +3236,15 @@ function SafeTextInput(props) {
3236
3236
  const displayValue = mask ? mask.repeat(value.length) : value;
3237
3237
  let rendered;
3238
3238
  if (displayValue.length === 0) {
3239
- rendered = showCursor && focus ? placeholder.length > 0 ? chalk11__default.default.inverse(placeholder[0]) + chalk11__default.default.grey(placeholder.slice(1)) : chalk11__default.default.inverse(" ") : placeholder.length > 0 ? chalk11__default.default.grey(placeholder) : "";
3239
+ rendered = showCursor && focus ? placeholder.length > 0 ? chalk9__default.default.inverse(placeholder[0]) + chalk9__default.default.grey(placeholder.slice(1)) : chalk9__default.default.inverse(" ") : placeholder.length > 0 ? chalk9__default.default.grey(placeholder) : "";
3240
3240
  } else if (!showCursor || !focus) {
3241
3241
  rendered = displayValue;
3242
3242
  } else {
3243
3243
  let out = "";
3244
3244
  for (let i = 0; i < displayValue.length; i++) {
3245
- out += i === cursorOffset ? chalk11__default.default.inverse(displayValue[i]) : displayValue[i];
3245
+ out += i === cursorOffset ? chalk9__default.default.inverse(displayValue[i]) : displayValue[i];
3246
3246
  }
3247
- if (cursorOffset >= displayValue.length) out += chalk11__default.default.inverse(" ");
3247
+ if (cursorOffset >= displayValue.length) out += chalk9__default.default.inverse(" ");
3248
3248
  rendered = out;
3249
3249
  }
3250
3250
  return /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { children: rendered });
@@ -4094,7 +4094,7 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
4094
4094
  }
4095
4095
  for (const tier of ["T1", "T2", "T3"]) {
4096
4096
  const override = tier === "T1" ? config.models.t1 : tier === "T2" ? config.models.t2 : config.models.t3;
4097
- if (!override) continue;
4097
+ if (!override || override === "auto") continue;
4098
4098
  const model = this.selector.selectForTier(tier, override);
4099
4099
  if (!model) {
4100
4100
  const knownProviders = ["anthropic", "openai", "gemini", "azure", "openai-compatible", "ollama"];
@@ -11497,7 +11497,7 @@ function StatusBarInternal({
11497
11497
  const savedStr = savedUsd > 0 ? ` \xB7 saved $${savedUsd.toFixed(4)}` : "";
11498
11498
  const rightStr = ` ${formatTokens(tokens)} \xB7 $${costUsd.toFixed(4)}${savedStr} ${isExecuting ? "\u26A1" : "\xB7"} `;
11499
11499
  const gap = Math.max(0, width - leftStr.length - rightStr.length);
11500
- const line = chalk11__default.default.bgHex(theme.colors.primary).hex(theme.colors.background)(chalk11__default.default.bold(leftStr) + " ".repeat(gap) + rightStr);
11500
+ const line = chalk9__default.default.bgHex(theme.colors.primary).hex(theme.colors.background)(chalk9__default.default.bold(leftStr) + " ".repeat(gap) + rightStr);
11501
11501
  return /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { children: line });
11502
11502
  }
11503
11503
  function formatTokens(n) {
@@ -11908,7 +11908,7 @@ function renderContent(content, theme) {
11908
11908
  i
11909
11909
  );
11910
11910
  }
11911
- const rendered = part.replace(/\*\*(.*?)\*\*/g, (_, t) => chalk11__default.default.bold(t)).replace(/`(.*?)`/g, (_, t) => chalk11__default.default.bgHex(theme.colors.border)(t));
11911
+ const rendered = part.replace(/\*\*(.*?)\*\*/g, (_, t) => chalk9__default.default.bold(t)).replace(/`(.*?)`/g, (_, t) => chalk9__default.default.bgHex(theme.colors.border)(t));
11912
11912
  return /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { wrap: "wrap", children: rendered }, i);
11913
11913
  });
11914
11914
  }
@@ -14114,20 +14114,20 @@ async function initCommand(workspacePath = process.cwd()) {
14114
14114
  const mdPath = path23__default.default.join(workspacePath, "CASCADE.md");
14115
14115
  if (!await fileExists(mdPath)) {
14116
14116
  await createDefaultCascadeMd(workspacePath);
14117
- spin.succeed(chalk11__default.default.green("Created CASCADE.md"));
14117
+ spin.succeed(chalk9__default.default.green("Created CASCADE.md"));
14118
14118
  }
14119
14119
  const ignorePath = path23__default.default.join(workspacePath, ".cascadeignore");
14120
14120
  if (!await fileExists(ignorePath)) {
14121
14121
  await createDefaultIgnoreFile(workspacePath);
14122
- spin.succeed(chalk11__default.default.green("Created .cascadeignore"));
14122
+ spin.succeed(chalk9__default.default.green("Created .cascadeignore"));
14123
14123
  }
14124
14124
  spin.stop();
14125
14125
  console.log();
14126
- console.log(chalk11__default.default.magenta(" \u25C8 Cascade AI \u2014 Project initialized"));
14126
+ console.log(chalk9__default.default.magenta(" \u25C8 Cascade AI \u2014 Project initialized"));
14127
14127
  console.log();
14128
14128
  const configPath = path23__default.default.join(workspacePath, CASCADE_CONFIG_FILE);
14129
14129
  if (await fileExists(configPath)) {
14130
- console.log(chalk11__default.default.yellow(" .cascade/config.json already exists \u2014 launching wizard to reconfigure."));
14130
+ console.log(chalk9__default.default.yellow(" .cascade/config.json already exists \u2014 launching wizard to reconfigure."));
14131
14131
  console.log();
14132
14132
  }
14133
14133
  const config = await runSetupWizard(workspacePath);
@@ -14135,10 +14135,10 @@ async function initCommand(workspacePath = process.cwd()) {
14135
14135
  await cm.load();
14136
14136
  await cm.updateConfig(config);
14137
14137
  console.log();
14138
- console.log(chalk11__default.default.green(" \u25C8 Setup complete! Run `cascade` to start."));
14138
+ console.log(chalk9__default.default.green(" \u25C8 Setup complete! Run `cascade` to start."));
14139
14139
  console.log();
14140
14140
  } catch (err) {
14141
- console.error(chalk11__default.default.red(`Init failed: ${err instanceof Error ? err.message : String(err)}`));
14141
+ console.error(chalk9__default.default.red(`Init failed: ${err instanceof Error ? err.message : String(err)}`));
14142
14142
  process.exit(1);
14143
14143
  }
14144
14144
  }
@@ -14284,7 +14284,7 @@ function maskSecret(secret) {
14284
14284
 
14285
14285
  // src/cli/commands/doctor.ts
14286
14286
  async function doctorCommand() {
14287
- console.log(chalk11__default.default.magenta("\n \u25C8 Cascade Doctor \u2014 System Diagnostics\n"));
14287
+ console.log(chalk9__default.default.magenta("\n \u25C8 Cascade Doctor \u2014 System Diagnostics\n"));
14288
14288
  const checks = [];
14289
14289
  const nodeVersion = process.versions.node;
14290
14290
  const [major] = nodeVersion.split(".").map(Number);
@@ -14376,22 +14376,22 @@ async function doctorCommand() {
14376
14376
  } catch {
14377
14377
  }
14378
14378
  for (const c of checks) {
14379
- const icon = c.ok ? chalk11__default.default.green(" \u2713") : chalk11__default.default.yellow(" \u25CB");
14380
- const label = c.ok ? chalk11__default.default.white(c.label) : chalk11__default.default.gray(c.label);
14381
- const detail = c.detail ? chalk11__default.default.gray(` \u2014 ${c.detail}`) : "";
14379
+ const icon = c.ok ? chalk9__default.default.green(" \u2713") : chalk9__default.default.yellow(" \u25CB");
14380
+ const label = c.ok ? chalk9__default.default.white(c.label) : chalk9__default.default.gray(c.label);
14381
+ const detail = c.detail ? chalk9__default.default.gray(` \u2014 ${c.detail}`) : "";
14382
14382
  console.log(`${icon} ${label}${detail}`);
14383
14383
  }
14384
14384
  const failures = checks.filter((c) => !c.ok);
14385
14385
  console.log();
14386
14386
  if (failures.length === 0) {
14387
- console.log(chalk11__default.default.green(" All checks passed!\n"));
14387
+ console.log(chalk9__default.default.green(" All checks passed!\n"));
14388
14388
  } else {
14389
14389
  const critical = failures.filter((c) => c.label.includes("Node") || c.label.includes("API key"));
14390
14390
  if (critical.length) {
14391
- console.log(chalk11__default.default.yellow(` ${critical.length} issue(s) need attention.
14391
+ console.log(chalk9__default.default.yellow(` ${critical.length} issue(s) need attention.
14392
14392
  `));
14393
14393
  } else {
14394
- console.log(chalk11__default.default.gray(` ${failures.length} optional item(s) not configured.
14394
+ console.log(chalk9__default.default.gray(` ${failures.length} optional item(s) not configured.
14395
14395
  `));
14396
14396
  }
14397
14397
  }
@@ -14418,14 +14418,14 @@ async function updateCommand() {
14418
14418
  const { stdout } = await execAsync2("npm show cascade-ai version", { timeout: 1e4 });
14419
14419
  const latest = stdout.trim().split("\n").filter(Boolean).pop() ?? "";
14420
14420
  if (latest === CASCADE_VERSION) {
14421
- spin.succeed(chalk11__default.default.green(`Already up to date (v${CASCADE_VERSION})`));
14421
+ spin.succeed(chalk9__default.default.green(`Already up to date (v${CASCADE_VERSION})`));
14422
14422
  return;
14423
14423
  }
14424
14424
  spin.text = `Updating cascade-ai ${CASCADE_VERSION} \u2192 ${latest}\u2026`;
14425
14425
  await execAsync2("npm install -g cascade-ai@latest", { timeout: 6e4 });
14426
- spin.succeed(chalk11__default.default.green(`Updated to v${latest}! Restart your terminal.`));
14426
+ spin.succeed(chalk9__default.default.green(`Updated to v${latest}! Restart your terminal.`));
14427
14427
  } catch (err) {
14428
- spin.fail(chalk11__default.default.red(`Update failed: ${err instanceof Error ? err.message : String(err)}`));
14428
+ spin.fail(chalk9__default.default.red(`Update failed: ${err instanceof Error ? err.message : String(err)}`));
14429
14429
  }
14430
14430
  }
14431
14431
  init_constants();
@@ -14590,6 +14590,11 @@ var DashboardSocket = class {
14590
14590
  emitToSocket(socketId, event, data) {
14591
14591
  this.io.sockets.sockets.get(socketId)?.emit(event, data);
14592
14592
  }
14593
+ onConfigGet(callback) {
14594
+ this.io.on("connection", (socket) => {
14595
+ socket.on("config:get", () => callback(socket.id));
14596
+ });
14597
+ }
14593
14598
  onCascadeRun(callback) {
14594
14599
  this.io.on("connection", (socket) => {
14595
14600
  socket.on("cascade:run", (payload) => {
@@ -14639,6 +14644,16 @@ var DashboardServer = class {
14639
14644
  this.socket.onSessionRate((sessionId, rating) => {
14640
14645
  this.activeSessions.get(sessionId)?.rateLastRun(rating);
14641
14646
  });
14647
+ this.socket.onConfigGet((socketId) => {
14648
+ this.socket.emitToSocket(socketId, "config:current", {
14649
+ models: this.config.models ?? {},
14650
+ budget: {
14651
+ maxCostPerRun: this.config.budget?.maxCostPerRunUsd,
14652
+ autoBias: this.config.autoBias
14653
+ },
14654
+ providersWithKey: (this.config.providers ?? []).filter((p) => typeof p.apiKey === "string" && p.apiKey.length > 0).map((p) => p.type)
14655
+ });
14656
+ });
14642
14657
  this.socket.onConfigUpdate((data) => {
14643
14658
  if (data.keys) {
14644
14659
  for (const [type, apiKey] of Object.entries(data.keys)) {
@@ -14649,7 +14664,11 @@ var DashboardServer = class {
14649
14664
  }
14650
14665
  }
14651
14666
  if (data.models) {
14652
- this.config.models = { ...this.config.models, ...data.models };
14667
+ const models = this.config.models;
14668
+ for (const [tier, val] of Object.entries(data.models)) {
14669
+ if (val && val !== "auto") models[tier] = val;
14670
+ else delete models[tier];
14671
+ }
14653
14672
  }
14654
14673
  if (data.budget) {
14655
14674
  if (typeof data.budget.maxCostPerRun === "number") {
@@ -14659,6 +14678,7 @@ var DashboardServer = class {
14659
14678
  this.config.autoBias = data.budget.autoBias;
14660
14679
  }
14661
14680
  }
14681
+ this.persistConfig();
14662
14682
  });
14663
14683
  this.socket.onCascadeRun(async (prompt, model, socketId) => {
14664
14684
  const sessionId = crypto.randomUUID();
@@ -14735,6 +14755,20 @@ var DashboardServer = class {
14735
14755
  getSocket() {
14736
14756
  return this.socket;
14737
14757
  }
14758
+ /**
14759
+ * Write the in-memory config back to the workspace config file so mutations
14760
+ * made over the socket (Settings → Save) persist across restarts. Best-effort:
14761
+ * a write failure is logged but never crashes the running dashboard.
14762
+ */
14763
+ persistConfig() {
14764
+ try {
14765
+ const configPath = path23__default.default.join(this.workspacePath, CASCADE_CONFIG_FILE);
14766
+ fs21__default.default.mkdirSync(path23__default.default.dirname(configPath), { recursive: true });
14767
+ fs21__default.default.writeFileSync(configPath, JSON.stringify(this.config, null, 2), "utf-8");
14768
+ } catch (err) {
14769
+ console.warn(`[dashboard] Failed to persist config: ${err instanceof Error ? err.message : String(err)}`);
14770
+ }
14771
+ }
14738
14772
  /**
14739
14773
  * Produce a stable dashboard JWT signing secret.
14740
14774
  *
@@ -15234,10 +15268,10 @@ async function dashboardCommand(config, workspacePath = process.cwd()) {
15234
15268
  process.once("exit", onExit);
15235
15269
  try {
15236
15270
  await server.start();
15237
- spin.succeed(chalk11__default.default.green(`Dashboard running at http://localhost:${port}`));
15271
+ spin.succeed(chalk9__default.default.green(`Dashboard running at http://localhost:${port}`));
15238
15272
  server.refreshRuntime("workspace");
15239
15273
  server.refreshRuntime("global");
15240
- console.log(chalk11__default.default.gray(` Press Ctrl+C to stop
15274
+ console.log(chalk9__default.default.gray(` Press Ctrl+C to stop
15241
15275
  `));
15242
15276
  await new Promise(() => {
15243
15277
  });
@@ -15246,7 +15280,7 @@ async function dashboardCommand(config, workspacePath = process.cwd()) {
15246
15280
  await server.stop().catch(() => {
15247
15281
  });
15248
15282
  onExit();
15249
- spin.fail(chalk11__default.default.red(`Dashboard failed: ${err instanceof Error ? err.message : String(err)}`));
15283
+ spin.fail(chalk9__default.default.red(`Dashboard failed: ${err instanceof Error ? err.message : String(err)}`));
15250
15284
  process.exit(1);
15251
15285
  }
15252
15286
  }
@@ -15257,15 +15291,15 @@ function makeIdentityCommand(workspacePath = process.cwd()) {
15257
15291
  const store = new MemoryStore(path23__default.default.join(workspacePath, CASCADE_DB_FILE));
15258
15292
  try {
15259
15293
  const identities = store.listIdentities();
15260
- console.log(chalk11__default.default.bold("\n Identities:"));
15294
+ console.log(chalk9__default.default.bold("\n Identities:"));
15261
15295
  if (identities.length === 0) {
15262
- console.log(chalk11__default.default.gray(" No identities found."));
15296
+ console.log(chalk9__default.default.gray(" No identities found."));
15263
15297
  } else {
15264
15298
  identities.forEach((id) => {
15265
- const defaultLabel = id.isDefault ? chalk11__default.default.green(" [Default]") : "";
15266
- console.log(` - ${chalk11__default.default.cyan(id.name)}${defaultLabel}`);
15267
- console.log(chalk11__default.default.gray(` ID: ${id.id}`));
15268
- if (id.description) console.log(chalk11__default.default.gray(` ${id.description}`));
15299
+ const defaultLabel = id.isDefault ? chalk9__default.default.green(" [Default]") : "";
15300
+ console.log(` - ${chalk9__default.default.cyan(id.name)}${defaultLabel}`);
15301
+ console.log(chalk9__default.default.gray(` ID: ${id.id}`));
15302
+ if (id.description) console.log(chalk9__default.default.gray(` ${id.description}`));
15269
15303
  });
15270
15304
  }
15271
15305
  console.log();
@@ -15291,9 +15325,9 @@ function makeIdentityCommand(workspacePath = process.cwd()) {
15291
15325
  isDefault: !!options.default,
15292
15326
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
15293
15327
  });
15294
- console.log(chalk11__default.default.green(`
15328
+ console.log(chalk9__default.default.green(`
15295
15329
  Successfully created identity: ${name} (${id})`));
15296
- if (options.default) console.log(chalk11__default.default.green(" Set as default."));
15330
+ if (options.default) console.log(chalk9__default.default.green(" Set as default."));
15297
15331
  console.log();
15298
15332
  } finally {
15299
15333
  store.close();
@@ -15305,7 +15339,7 @@ function makeIdentityCommand(workspacePath = process.cwd()) {
15305
15339
  const identities = store.listIdentities();
15306
15340
  const match = identities.find((i) => i.id === query || i.name.toLowerCase() === query.toLowerCase());
15307
15341
  if (!match) {
15308
- console.error(chalk11__default.default.red(`
15342
+ console.error(chalk9__default.default.red(`
15309
15343
  Identity '${query}' not found.
15310
15344
  `));
15311
15345
  process.exit(1);
@@ -15315,7 +15349,7 @@ function makeIdentityCommand(workspacePath = process.cwd()) {
15315
15349
  store.updateIdentity(existingDefault.id, { isDefault: false });
15316
15350
  }
15317
15351
  store.updateIdentity(match.id, { isDefault: true });
15318
- console.log(chalk11__default.default.green(`
15352
+ console.log(chalk9__default.default.green(`
15319
15353
  Identity ${match.name} is now the default.
15320
15354
  `));
15321
15355
  } finally {
@@ -15325,7 +15359,7 @@ function makeIdentityCommand(workspacePath = process.cwd()) {
15325
15359
  return identity;
15326
15360
  }
15327
15361
  async function modelsCommand(options = {}) {
15328
- console.log(chalk11__default.default.magenta("\n \u25C8 Cascade Models\n"));
15362
+ console.log(chalk9__default.default.magenta("\n \u25C8 Cascade Models\n"));
15329
15363
  const cm = new ConfigManager(process.cwd());
15330
15364
  await cm.load();
15331
15365
  const config = cm.getConfig();
@@ -15333,16 +15367,16 @@ async function modelsCommand(options = {}) {
15333
15367
  try {
15334
15368
  await router.init(config);
15335
15369
  } catch (err) {
15336
- console.error(chalk11__default.default.red(` Failed to initialize router: ${err instanceof Error ? err.message : String(err)}`));
15370
+ console.error(chalk9__default.default.red(` Failed to initialize router: ${err instanceof Error ? err.message : String(err)}`));
15337
15371
  process.exit(1);
15338
15372
  }
15339
15373
  await withTimeout(router.refreshLiveData(), 6e3, "live data timeout").catch(() => {
15340
15374
  });
15341
15375
  const liveData = router.getLiveData();
15342
15376
  const tiers = [
15343
- { tier: "T1", label: "T1 Administrator", color: chalk11__default.default.hex("#7C6AF7") },
15344
- { tier: "T2", label: "T2 Manager", color: chalk11__default.default.hex("#5AB4E8") },
15345
- { tier: "T3", label: "T3 Worker", color: chalk11__default.default.hex("#5AE8A4") }
15377
+ { tier: "T1", label: "T1 Administrator", color: chalk9__default.default.hex("#7C6AF7") },
15378
+ { tier: "T2", label: "T2 Manager", color: chalk9__default.default.hex("#5AB4E8") },
15379
+ { tier: "T3", label: "T3 Worker", color: chalk9__default.default.hex("#5AE8A4") }
15346
15380
  ];
15347
15381
  let anyMissing = false;
15348
15382
  for (const { tier, label, color } of tiers) {
@@ -15351,48 +15385,72 @@ async function modelsCommand(options = {}) {
15351
15385
  const costIn = model.inputCostPer1kTokens === 0 ? "free" : `$${model.inputCostPer1kTokens.toFixed(4)}/1K in`;
15352
15386
  const costOut = model.outputCostPer1kTokens === 0 ? "free" : `$${model.outputCostPer1kTokens.toFixed(4)}/1K out`;
15353
15387
  const ctx = model.contextWindow >= 1e6 ? `${(model.contextWindow / 1e6).toFixed(1)}M ctx` : `${(model.contextWindow / 1e3).toFixed(0)}K ctx`;
15354
- const local = model.isLocal ? chalk11__default.default.gray(" [local]") : "";
15355
- const vision = model.isVisionCapable ? chalk11__default.default.gray(" \u{1F441}") : "";
15388
+ const local = model.isLocal ? chalk9__default.default.gray(" [local]") : "";
15389
+ const vision = model.isVisionCapable ? chalk9__default.default.gray(" \u{1F441}") : "";
15356
15390
  const bench = Math.round(benchmarkScore01(model, "mixed") * 100);
15357
15391
  console.log(
15358
- ` ${color.bold(tier)} ${chalk11__default.default.white(col(model.name, 24))}${chalk11__default.default.gray(col(model.provider, 16))}` + (options.verbose ? `${chalk11__default.default.gray(col(ctx, 12))}${chalk11__default.default.gray(col(`bench ${bench}/100`, 14))}${chalk11__default.default.gray(`${costIn}, ${costOut}`)}` : `${chalk11__default.default.gray(col(ctx, 10))}${chalk11__default.default.gray(`bench ${bench}/100`)}`) + local + vision
15392
+ ` ${color.bold(tier)} ${chalk9__default.default.white(col(model.name, 24))}${chalk9__default.default.gray(col(model.provider, 16))}` + (options.verbose ? `${chalk9__default.default.gray(col(ctx, 12))}${chalk9__default.default.gray(col(`bench ${bench}/100`, 14))}${chalk9__default.default.gray(`${costIn}, ${costOut}`)}` : `${chalk9__default.default.gray(col(ctx, 10))}${chalk9__default.default.gray(`bench ${bench}/100`)}`) + local + vision
15359
15393
  );
15360
15394
  } else {
15361
- console.log(` ${color.bold(tier)} ${chalk11__default.default.red("No model available")} ${chalk11__default.default.gray(`(check provider config for ${label})`)}`);
15395
+ console.log(` ${color.bold(tier)} ${chalk9__default.default.red("No model available")} ${chalk9__default.default.gray(`(check provider config for ${label})`)}`);
15362
15396
  anyMissing = true;
15363
15397
  }
15364
15398
  }
15365
15399
  console.log();
15366
15400
  const providers = config.providers.map((p) => p.type).join(", ") || "(none)";
15367
- console.log(chalk11__default.default.gray(` Configured providers: ${providers}`));
15401
+ console.log(chalk9__default.default.gray(` Configured providers: ${providers}`));
15368
15402
  if (liveData) {
15369
15403
  const src = liveData.getDataSource();
15370
15404
  const gen = liveData.getGeneratedAt();
15371
15405
  const srcLabel = src === "live" ? "live (just fetched)" : src === "cache" ? "cached" : "bundled";
15372
- console.log(chalk11__default.default.gray(
15406
+ console.log(chalk9__default.default.gray(
15373
15407
  ` Benchmark data: ${srcLabel}` + (gen ? ` \xB7 updated ${gen.slice(0, 10)}` : "") + ` \xB7 pricing: ${liveData.hasLivePricing() ? "live (OpenRouter)" : "catalog"}`
15374
15408
  ));
15375
15409
  }
15376
15410
  if (options.verbose) {
15377
15411
  console.log();
15378
- console.log(chalk11__default.default.white(" Available models by provider:\n"));
15412
+ console.log(chalk9__default.default.white(" Available models by provider:\n"));
15379
15413
  const allProviderTypes = [...new Set(config.providers.map((p) => p.type))];
15380
15414
  for (const providerType of allProviderTypes) {
15381
15415
  const available = router.getModelsForProvider(providerType);
15382
15416
  if (available.length === 0) continue;
15383
- console.log(chalk11__default.default.gray(` ${providerType}:`));
15417
+ console.log(chalk9__default.default.gray(` ${providerType}:`));
15384
15418
  for (const m of available) {
15385
15419
  const override = config.models.t1 === m.id ? " \u2190 T1" : config.models.t2 === m.id ? " \u2190 T2" : config.models.t3 === m.id ? " \u2190 T3" : "";
15386
- console.log(` ${chalk11__default.default.white(col(m.name, 28))}${chalk11__default.default.gray(m.id)}${chalk11__default.default.yellow(override)}`);
15420
+ console.log(` ${chalk9__default.default.white(col(m.name, 28))}${chalk9__default.default.gray(m.id)}${chalk9__default.default.yellow(override)}`);
15387
15421
  }
15388
15422
  console.log();
15389
15423
  }
15390
15424
  }
15391
15425
  if (anyMissing) {
15392
- console.log(chalk11__default.default.yellow(" Some tiers have no available model. Run `cascade doctor` for details.\n"));
15426
+ console.log(chalk9__default.default.yellow(" Some tiers have no available model. Run `cascade doctor` for details.\n"));
15393
15427
  } else {
15394
- console.log(chalk11__default.default.green(" All tiers are configured.\n"));
15428
+ console.log(chalk9__default.default.green(" All tiers are configured.\n"));
15429
+ }
15430
+ }
15431
+ async function setModelCommand(action, tierArg, value) {
15432
+ const tier = (tierArg ?? "").toLowerCase();
15433
+ if (!["t1", "t2", "t3"].includes(tier)) {
15434
+ console.error(chalk9__default.default.red(` Invalid tier "${tierArg ?? ""}". Use t1, t2, or t3.`));
15435
+ console.log(chalk9__default.default.gray(" e.g. cascade models set t1 anthropic:claude-opus-4-8"));
15436
+ process.exit(1);
15437
+ }
15438
+ const override = action === "unset" ? "auto" : (value ?? "").trim();
15439
+ if (action === "set" && !override) {
15440
+ console.error(chalk9__default.default.red(' Missing value. e.g. cascade models set t3 openai:gpt-4o-mini (or "auto")'));
15441
+ process.exit(1);
15395
15442
  }
15443
+ const cm = new ConfigManager(process.cwd());
15444
+ await cm.load();
15445
+ const config = cm.getConfig();
15446
+ const models = { ...config.models };
15447
+ if (override === "auto") delete models[tier];
15448
+ else models[tier] = override;
15449
+ await cm.updateConfig({ models });
15450
+ const label = override === "auto" ? chalk9__default.default.gray("auto (routing decides)") : chalk9__default.default.white(override);
15451
+ console.log(chalk9__default.default.green(`
15452
+ \u2713 ${tier.toUpperCase()} model set to ${label}
15453
+ `));
15396
15454
  }
15397
15455
  function col(s, width) {
15398
15456
  return s.length < width ? s.padEnd(width) : `${s} `;
@@ -15414,7 +15472,7 @@ async function exportCommand(options = {}) {
15414
15472
  }
15415
15473
  store = new MemoryStore(dbPath);
15416
15474
  } catch (err) {
15417
- spin.fail(chalk11__default.default.red(`Cannot open memory store: ${err instanceof Error ? err.message : String(err)}`));
15475
+ spin.fail(chalk9__default.default.red(`Cannot open memory store: ${err instanceof Error ? err.message : String(err)}`));
15418
15476
  process.exit(1);
15419
15477
  }
15420
15478
  try {
@@ -15422,7 +15480,7 @@ async function exportCommand(options = {}) {
15422
15480
  if (options.sessionId) {
15423
15481
  const session2 = store.getSession(options.sessionId);
15424
15482
  if (!session2) {
15425
- spin.fail(chalk11__default.default.red(`Session "${options.sessionId}" not found.`));
15483
+ spin.fail(chalk9__default.default.red(`Session "${options.sessionId}" not found.`));
15426
15484
  process.exit(1);
15427
15485
  }
15428
15486
  sessions = [session2];
@@ -15430,14 +15488,14 @@ async function exportCommand(options = {}) {
15430
15488
  const limit = options.last ?? 10;
15431
15489
  sessions = store.listSessions(void 0, limit);
15432
15490
  if (sessions.length === 0) {
15433
- spin.warn(chalk11__default.default.yellow("No sessions found."));
15491
+ spin.warn(chalk9__default.default.yellow("No sessions found."));
15434
15492
  return;
15435
15493
  }
15436
15494
  const latest = sessions[0];
15437
15495
  const full = store.getSession(latest.id);
15438
15496
  sessions = full ? [full] : [];
15439
15497
  if (sessions.length === 0) {
15440
- spin.fail(chalk11__default.default.red("Could not load latest session."));
15498
+ spin.fail(chalk9__default.default.red("Could not load latest session."));
15441
15499
  process.exit(1);
15442
15500
  }
15443
15501
  }
@@ -15449,15 +15507,15 @@ async function exportCommand(options = {}) {
15449
15507
  const defaultFile = `cascade-export-${safeName}${ext}`;
15450
15508
  const outPath = options.output ? path23__default.default.resolve(options.output) : path23__default.default.join(process.cwd(), defaultFile);
15451
15509
  await fs9__default.default.writeFile(outPath, content, "utf-8");
15452
- spin.succeed(chalk11__default.default.green(`Exported to ${chalk11__default.default.white(outPath)}`));
15510
+ spin.succeed(chalk9__default.default.green(`Exported to ${chalk9__default.default.white(outPath)}`));
15453
15511
  const messageCount = Array.isArray(session.messages) ? session.messages.length : 0;
15454
15512
  console.log();
15455
- console.log(chalk11__default.default.gray(` Session: ${session.title}`));
15456
- console.log(chalk11__default.default.gray(` Messages: ${messageCount}`));
15457
- console.log(chalk11__default.default.gray(` Format: ${format}`));
15513
+ console.log(chalk9__default.default.gray(` Session: ${session.title}`));
15514
+ console.log(chalk9__default.default.gray(` Messages: ${messageCount}`));
15515
+ console.log(chalk9__default.default.gray(` Format: ${format}`));
15458
15516
  console.log();
15459
15517
  } catch (err) {
15460
- spin.fail(chalk11__default.default.red(`Export failed: ${err instanceof Error ? err.message : String(err)}`));
15518
+ spin.fail(chalk9__default.default.red(`Export failed: ${err instanceof Error ? err.message : String(err)}`));
15461
15519
  process.exit(1);
15462
15520
  }
15463
15521
  }
@@ -15514,9 +15572,9 @@ function buildJsonExport(session) {
15514
15572
  async function linkCommand(target, options = {}) {
15515
15573
  const found = await discoverCredentials();
15516
15574
  if (found.length === 0) {
15517
- console.log(chalk11__default.default.yellow("\n No reusable credentials found.\n"));
15518
- console.log(chalk11__default.default.gray(" Cascade looks for Claude Code, Codex, Gemini CLI, and GitHub Copilot logins,"));
15519
- console.log(chalk11__default.default.gray(" plus ANTHROPIC_API_KEY / OPENAI_API_KEY / GEMINI_API_KEY in your environment.\n"));
15575
+ console.log(chalk9__default.default.yellow("\n No reusable credentials found.\n"));
15576
+ console.log(chalk9__default.default.gray(" Cascade looks for Claude Code, Codex, Gemini CLI, and GitHub Copilot logins,"));
15577
+ console.log(chalk9__default.default.gray(" plus ANTHROPIC_API_KEY / OPENAI_API_KEY / GEMINI_API_KEY in your environment.\n"));
15520
15578
  return;
15521
15579
  }
15522
15580
  if (!target) {
@@ -15525,7 +15583,7 @@ async function linkCommand(target, options = {}) {
15525
15583
  }
15526
15584
  const provider = normalizeProvider(target);
15527
15585
  if (!provider) {
15528
- console.log(chalk11__default.default.red(`
15586
+ console.log(chalk9__default.default.red(`
15529
15587
  Unknown provider "${target}". Use one of: anthropic, openai, gemini.
15530
15588
  `));
15531
15589
  return;
@@ -15533,46 +15591,46 @@ async function linkCommand(target, options = {}) {
15533
15591
  const candidates2 = found.filter((c) => c.provider === provider);
15534
15592
  const chosen = candidates2.find((c) => c.directlyUsable) ?? candidates2[0];
15535
15593
  if (!chosen) {
15536
- console.log(chalk11__default.default.yellow(`
15594
+ console.log(chalk9__default.default.yellow(`
15537
15595
  No detected credential maps to "${provider}".
15538
15596
  `));
15539
15597
  return;
15540
15598
  }
15541
15599
  if (!chosen.directlyUsable) {
15542
- console.log(chalk11__default.default.yellow(`
15600
+ console.log(chalk9__default.default.yellow(`
15543
15601
  Found a ${chosen.sourceTool} credential, but it can't be used against the standard ${provider} API.`));
15544
- if (chosen.warning) console.log(chalk11__default.default.gray(` ${chosen.warning}`));
15545
- console.log(chalk11__default.default.gray(" Cascade won't adopt it because it would create a non-working provider.\n"));
15602
+ if (chosen.warning) console.log(chalk9__default.default.gray(` ${chosen.warning}`));
15603
+ console.log(chalk9__default.default.gray(" Cascade won't adopt it because it would create a non-working provider.\n"));
15546
15604
  return;
15547
15605
  }
15548
15606
  if (chosen.kind === "oauth" && !options.acceptRisk) {
15549
- console.log(chalk11__default.default.yellow(`
15607
+ console.log(chalk9__default.default.yellow(`
15550
15608
  ${chosen.sourceTool} provides a subscription OAuth token, not an API key.`));
15551
- if (chosen.warning) console.log(chalk11__default.default.gray(` ${chosen.warning}`));
15552
- console.log(chalk11__default.default.gray(" Re-run with --accept-risk to adopt it anyway:\n"));
15553
- console.log(chalk11__default.default.cyan(` cascade link ${provider} --accept-risk
15609
+ if (chosen.warning) console.log(chalk9__default.default.gray(` ${chosen.warning}`));
15610
+ console.log(chalk9__default.default.gray(" Re-run with --accept-risk to adopt it anyway:\n"));
15611
+ console.log(chalk9__default.default.cyan(` cascade link ${provider} --accept-risk
15554
15612
  `));
15555
15613
  return;
15556
15614
  }
15557
15615
  await adoptCredential(chosen, options.workspace ?? process.cwd());
15558
- console.log(chalk11__default.default.green(`
15616
+ console.log(chalk9__default.default.green(`
15559
15617
  \u2713 Linked ${provider} using your ${chosen.sourceTool} credential (${maskSecret(chosen.secret)}).`));
15560
15618
  if (chosen.kind === "oauth") {
15561
- console.log(chalk11__default.default.gray(" Adopted as an OAuth bearer token \u2014 revoke it in the source tool to disable."));
15619
+ console.log(chalk9__default.default.gray(" Adopted as an OAuth bearer token \u2014 revoke it in the source tool to disable."));
15562
15620
  }
15563
- console.log(chalk11__default.default.gray(" Run `cascade doctor` to verify, or `cascade` to start.\n"));
15621
+ console.log(chalk9__default.default.gray(" Run `cascade doctor` to verify, or `cascade` to start.\n"));
15564
15622
  }
15565
15623
  function printDiscovered(found) {
15566
- console.log(chalk11__default.default.magenta("\n \u25C8 Detected credentials\n"));
15624
+ console.log(chalk9__default.default.magenta("\n \u25C8 Detected credentials\n"));
15567
15625
  for (const c of found) {
15568
- const usable = c.directlyUsable ? chalk11__default.default.green("usable") : chalk11__default.default.yellow("needs vendor backend");
15569
- const kind = c.kind === "oauth" ? chalk11__default.default.yellow("oauth") : chalk11__default.default.gray("api-key");
15570
- console.log(` ${chalk11__default.default.white(c.provider.padEnd(18))} ${chalk11__default.default.gray(maskSecret(c.secret).padEnd(12))} ${kind} ${usable}`);
15571
- console.log(chalk11__default.default.gray(` from ${c.sourceTool}`));
15572
- if (c.warning) console.log(chalk11__default.default.yellow(` \u26A0 ${c.warning}`));
15626
+ const usable = c.directlyUsable ? chalk9__default.default.green("usable") : chalk9__default.default.yellow("needs vendor backend");
15627
+ const kind = c.kind === "oauth" ? chalk9__default.default.yellow("oauth") : chalk9__default.default.gray("api-key");
15628
+ console.log(` ${chalk9__default.default.white(c.provider.padEnd(18))} ${chalk9__default.default.gray(maskSecret(c.secret).padEnd(12))} ${kind} ${usable}`);
15629
+ console.log(chalk9__default.default.gray(` from ${c.sourceTool}`));
15630
+ if (c.warning) console.log(chalk9__default.default.yellow(` \u26A0 ${c.warning}`));
15573
15631
  }
15574
- console.log(chalk11__default.default.gray("\n Adopt one with: ") + chalk11__default.default.cyan("cascade link <provider> [--accept-risk]"));
15575
- console.log(chalk11__default.default.gray(" --accept-risk is required for subscription OAuth tokens.\n"));
15632
+ console.log(chalk9__default.default.gray("\n Adopt one with: ") + chalk9__default.default.cyan("cascade link <provider> [--accept-risk]"));
15633
+ console.log(chalk9__default.default.gray(" --accept-risk is required for subscription OAuth tokens.\n"));
15576
15634
  }
15577
15635
  function normalizeProvider(target) {
15578
15636
  const t = target.toLowerCase();
@@ -15605,12 +15663,12 @@ async function telemetryCommand(action) {
15605
15663
  if (action === "status") {
15606
15664
  const state = config.telemetry?.enabled ? "ON" : "OFF";
15607
15665
  console.log();
15608
- console.log(chalk11__default.default.magenta(" \u25C8 Cascade Telemetry"));
15666
+ console.log(chalk9__default.default.magenta(" \u25C8 Cascade Telemetry"));
15609
15667
  console.log();
15610
- console.log(` Status: ${config.telemetry?.enabled ? chalk11__default.default.green(state) : chalk11__default.default.gray(state)}`);
15611
- console.log(chalk11__default.default.gray(" Scope: anonymous session metadata only (no prompts/outputs)"));
15668
+ console.log(` Status: ${config.telemetry?.enabled ? chalk9__default.default.green(state) : chalk9__default.default.gray(state)}`);
15669
+ console.log(chalk9__default.default.gray(" Scope: anonymous session metadata only (no prompts/outputs)"));
15612
15670
  console.log();
15613
- console.log(chalk11__default.default.gray(" Toggle with: cascade telemetry on | cascade telemetry off"));
15671
+ console.log(chalk9__default.default.gray(" Toggle with: cascade telemetry on | cascade telemetry off"));
15614
15672
  console.log();
15615
15673
  return;
15616
15674
  }
@@ -15624,11 +15682,11 @@ async function telemetryCommand(action) {
15624
15682
  });
15625
15683
  console.log();
15626
15684
  if (enabled) {
15627
- console.log(chalk11__default.default.green(` \u2713 Telemetry enabled.`));
15628
- console.log(chalk11__default.default.gray(" Anonymous session metadata (no prompts, no outputs) will be sent."));
15685
+ console.log(chalk9__default.default.green(` \u2713 Telemetry enabled.`));
15686
+ console.log(chalk9__default.default.gray(" Anonymous session metadata (no prompts, no outputs) will be sent."));
15629
15687
  } else {
15630
- console.log(chalk11__default.default.yellow(` \u2713 Telemetry disabled.`));
15631
- console.log(chalk11__default.default.gray(" No events will be transmitted from this workspace."));
15688
+ console.log(chalk9__default.default.yellow(` \u2713 Telemetry disabled.`));
15689
+ console.log(chalk9__default.default.gray(" No events will be transmitted from this workspace."));
15632
15690
  }
15633
15691
  console.log();
15634
15692
  }
@@ -15638,11 +15696,11 @@ async function statsCommand() {
15638
15696
  await tracker.load();
15639
15697
  const all = tracker.getAll();
15640
15698
  if (all.size === 0) {
15641
- console.log(chalk11__default.default.dim("\n No routing history yet \u2014 run some tasks first.\n"));
15699
+ console.log(chalk9__default.default.dim("\n No routing history yet \u2014 run some tasks first.\n"));
15642
15700
  return;
15643
15701
  }
15644
- console.log(chalk11__default.default.magenta("\n \u25C8 Auto-Routing History\n"));
15645
- console.log(chalk11__default.default.dim(" Per-task-type model performance learned from past runs.\n"));
15702
+ console.log(chalk9__default.default.magenta("\n \u25C8 Auto-Routing History\n"));
15703
+ console.log(chalk9__default.default.dim(" Per-task-type model performance learned from past runs.\n"));
15646
15704
  for (const taskType of TASK_TYPES) {
15647
15705
  const entries = [];
15648
15706
  for (const [key, stat] of all) {
@@ -15654,21 +15712,21 @@ async function statsCommand() {
15654
15712
  }
15655
15713
  if (entries.length === 0) continue;
15656
15714
  entries.sort((a, b) => b.successRate - a.successRate || b.samples - a.samples);
15657
- console.log(chalk11__default.default.bold(` ${taskType.toUpperCase()}`));
15715
+ console.log(chalk9__default.default.bold(` ${taskType.toUpperCase()}`));
15658
15716
  const header = ` ${"Model".padEnd(36)} ${"Success".padEnd(9)} ${"Samples".padEnd(9)} Avg cost`;
15659
- console.log(chalk11__default.default.dim(header));
15660
- console.log(chalk11__default.default.dim(" " + "\u2500".repeat(62)));
15717
+ console.log(chalk9__default.default.dim(header));
15718
+ console.log(chalk9__default.default.dim(" " + "\u2500".repeat(62)));
15661
15719
  for (const e of entries) {
15662
15720
  const pct = `${Math.round(e.successRate * 100)}%`;
15663
15721
  const cost = e.avgCostUsd < 1e-4 ? "<$0.0001" : `$${e.avgCostUsd.toFixed(4)}`;
15664
- const color = e.successRate >= 0.8 ? chalk11__default.default.green : e.successRate >= 0.5 ? chalk11__default.default.yellow : chalk11__default.default.red;
15722
+ const color = e.successRate >= 0.8 ? chalk9__default.default.green : e.successRate >= 0.5 ? chalk9__default.default.yellow : chalk9__default.default.red;
15665
15723
  console.log(
15666
- ` ${e.modelId.padEnd(36)} ${color(pct.padEnd(9))} ${String(e.samples).padEnd(9)} ${chalk11__default.default.dim(cost)}`
15724
+ ` ${e.modelId.padEnd(36)} ${color(pct.padEnd(9))} ${String(e.samples).padEnd(9)} ${chalk9__default.default.dim(cost)}`
15667
15725
  );
15668
15726
  }
15669
15727
  console.log();
15670
15728
  }
15671
- console.log(chalk11__default.default.dim(" tip: use /rate good | bad after a task to improve these scores.\n"));
15729
+ console.log(chalk9__default.default.dim(" tip: use /rate good | bad after a task to improve these scores.\n"));
15672
15730
  }
15673
15731
 
15674
15732
  // src/cli/index.ts
@@ -15683,7 +15741,7 @@ function warnIfBuildIsStale() {
15683
15741
  if (pkg.name !== "cascade-ai") continue;
15684
15742
  if (pkg.version && pkg.version !== CASCADE_VERSION) {
15685
15743
  console.error(
15686
- chalk11__default.default.yellow(
15744
+ chalk9__default.default.yellow(
15687
15745
  `\u26A0 Stale build: compiled output is v${CASCADE_VERSION} but the source tree is v${pkg.version}.
15688
15746
  Run: npm install && npm run build`
15689
15747
  )
@@ -15751,13 +15809,17 @@ program.command("dashboard").description("Launch the web dashboard").option("-p,
15751
15809
  program.command("run <prompt>").description("Run a single prompt and exit").option("-t, --theme <name>", "Color theme", DEFAULT_THEME).option("-i, --identity <name>", "Identity name or ID").action(async (prompt, opts) => {
15752
15810
  await runHeadless(prompt, { theme: opts.theme, workspace: process.cwd(), identity: opts.identity });
15753
15811
  });
15754
- program.command("models").description("List available AI models for each tier").option("-v, --verbose", "Show all models per provider with pricing").action(async (opts) => {
15755
- await modelsCommand({ verbose: opts.verbose });
15812
+ program.command("models [action] [tier] [value]").description("List AI models per tier, or set/unset a tier provider+model (e.g. models set t1 anthropic:claude-opus-4-8)").option("-v, --verbose", "Show all models per provider with pricing").action(async (action, tier, value, opts) => {
15813
+ if (action === "set" || action === "unset") {
15814
+ await setModelCommand(action, tier, value);
15815
+ } else {
15816
+ await modelsCommand({ verbose: opts.verbose });
15817
+ }
15756
15818
  });
15757
15819
  program.command("telemetry [action]").description("Toggle anonymous usage telemetry (on | off | status). Default: status").action(async (action) => {
15758
15820
  const normalized = (action ?? "status").toLowerCase();
15759
15821
  if (normalized !== "on" && normalized !== "off" && normalized !== "status") {
15760
- console.error(chalk11__default.default.red(`Unknown action: ${action}. Use: on | off | status`));
15822
+ console.error(chalk9__default.default.red(`Unknown action: ${action}. Use: on | off | status`));
15761
15823
  process.exit(1);
15762
15824
  }
15763
15825
  await telemetryCommand(normalized);
@@ -15779,14 +15841,14 @@ async function startRepl(options) {
15779
15841
  try {
15780
15842
  await cm.load();
15781
15843
  } catch (err) {
15782
- console.error(chalk11__default.default.red(`Config error: ${err instanceof Error ? err.message : String(err)}`));
15783
- console.error(chalk11__default.default.gray("Run `cascade init` to set up this directory."));
15844
+ console.error(chalk9__default.default.red(`Config error: ${err instanceof Error ? err.message : String(err)}`));
15845
+ console.error(chalk9__default.default.gray("Run `cascade init` to set up this directory."));
15784
15846
  process.exit(1);
15785
15847
  }
15786
15848
  let config = cm.getConfig();
15787
15849
  const needsSetup = !config.providers?.length || config.providers.every((p) => p.type !== "ollama" && !p.apiKey);
15788
15850
  if (needsSetup) {
15789
- console.log(chalk11__default.default.magenta(" \u25C8 No providers configured \u2014 launching setup wizard\u2026"));
15851
+ console.log(chalk9__default.default.magenta(" \u25C8 No providers configured \u2014 launching setup wizard\u2026"));
15790
15852
  console.log();
15791
15853
  config = await runSetupWizard(workspacePath);
15792
15854
  await cm.updateConfig(config);
@@ -15820,24 +15882,24 @@ async function runHeadless(prompt, options) {
15820
15882
  try {
15821
15883
  await cm.load();
15822
15884
  } catch (err) {
15823
- console.error(chalk11__default.default.red(`Config error: ${err instanceof Error ? err.message : String(err)}`));
15824
- console.error(chalk11__default.default.gray("Run `cascade init` to set up this directory."));
15885
+ console.error(chalk9__default.default.red(`Config error: ${err instanceof Error ? err.message : String(err)}`));
15886
+ console.error(chalk9__default.default.gray("Run `cascade init` to set up this directory."));
15825
15887
  process.exit(1);
15826
15888
  }
15827
15889
  const config = cm.getConfig();
15828
15890
  const needsSetup = !config.providers?.length || config.providers.every((p) => p.type !== "ollama" && !p.apiKey);
15829
15891
  if (needsSetup) {
15830
- console.error(chalk11__default.default.red("No providers configured. Run `cascade init` first."));
15892
+ console.error(chalk9__default.default.red("No providers configured. Run `cascade init` first."));
15831
15893
  process.exit(1);
15832
15894
  }
15833
15895
  const cascade = new Cascade(config, workspacePath);
15834
15896
  try {
15835
15897
  await cascade.init();
15836
15898
  } catch (err) {
15837
- console.error(chalk11__default.default.red(`Initialization failed: ${err instanceof Error ? err.message : String(err)}`));
15899
+ console.error(chalk9__default.default.red(`Initialization failed: ${err instanceof Error ? err.message : String(err)}`));
15838
15900
  process.exit(1);
15839
15901
  }
15840
- console.error(chalk11__default.default.gray(" \u25C8 Running headlessly \u2014 tool approvals are auto-granted."));
15902
+ console.error(chalk9__default.default.gray(" \u25C8 Running headlessly \u2014 tool approvals are auto-granted."));
15841
15903
  let lastProgress = "";
15842
15904
  cascade.on("tier:status", (ev) => {
15843
15905
  const action = ev?.currentAction?.trim();
@@ -15845,7 +15907,7 @@ async function runHeadless(prompt, options) {
15845
15907
  const line = ` \xB7 ${ev.role ?? ""} ${action}`.trimEnd();
15846
15908
  if (line === lastProgress) return;
15847
15909
  lastProgress = line;
15848
- console.error(chalk11__default.default.gray(line));
15910
+ console.error(chalk9__default.default.gray(line));
15849
15911
  });
15850
15912
  try {
15851
15913
  const result = await cascade.run({
@@ -15856,7 +15918,7 @@ async function runHeadless(prompt, options) {
15856
15918
  });
15857
15919
  process.stdout.write(result.output.trimEnd() + "\n");
15858
15920
  } catch (err) {
15859
- console.error(chalk11__default.default.red(`Error: ${err instanceof Error ? err.message : String(err)}`));
15921
+ console.error(chalk9__default.default.red(`Error: ${err instanceof Error ? err.message : String(err)}`));
15860
15922
  await cascade.close().catch(() => {
15861
15923
  });
15862
15924
  process.exit(1);
@@ -15868,10 +15930,10 @@ async function runHeadless(prompt, options) {
15868
15930
  function printBanner() {
15869
15931
  if (process.stdout.columns < 60) return;
15870
15932
  console.log();
15871
- console.log(chalk11__default.default.hex("#7C6AF7").bold(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
15872
- console.log(chalk11__default.default.hex("#7C6AF7").bold(" \u2551") + chalk11__default.default.white.bold(" \u25C8 CASCADE AI") + chalk11__default.default.gray(" v" + CASCADE_VERSION + " ") + chalk11__default.default.hex("#7C6AF7").bold("\u2551"));
15873
- console.log(chalk11__default.default.hex("#7C6AF7").bold(" \u2551") + chalk11__default.default.gray(" Multi-Tier Orchestration ") + chalk11__default.default.hex("#7C6AF7").bold("\u2551"));
15874
- console.log(chalk11__default.default.hex("#7C6AF7").bold(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
15933
+ console.log(chalk9__default.default.hex("#7C6AF7").bold(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
15934
+ console.log(chalk9__default.default.hex("#7C6AF7").bold(" \u2551") + chalk9__default.default.white.bold(" \u25C8 CASCADE AI") + chalk9__default.default.gray(" v" + CASCADE_VERSION + " ") + chalk9__default.default.hex("#7C6AF7").bold("\u2551"));
15935
+ console.log(chalk9__default.default.hex("#7C6AF7").bold(" \u2551") + chalk9__default.default.gray(" Multi-Tier Orchestration ") + chalk9__default.default.hex("#7C6AF7").bold("\u2551"));
15936
+ console.log(chalk9__default.default.hex("#7C6AF7").bold(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
15875
15937
  console.log();
15876
15938
  }
15877
15939
  program.parse(process.argv);