cascade-ai 0.12.2 → 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 +183 -121
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +182 -120
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +36 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +36 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
|
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
|
|
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 ?
|
|
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 ?
|
|
3245
|
+
out += i === cursorOffset ? chalk9__default.default.inverse(displayValue[i]) : displayValue[i];
|
|
3246
3246
|
}
|
|
3247
|
-
if (cursorOffset >= displayValue.length) out +=
|
|
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 =
|
|
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) =>
|
|
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(
|
|
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(
|
|
14122
|
+
spin.succeed(chalk9__default.default.green("Created .cascadeignore"));
|
|
14123
14123
|
}
|
|
14124
14124
|
spin.stop();
|
|
14125
14125
|
console.log();
|
|
14126
|
-
console.log(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 ?
|
|
14380
|
-
const label = c.ok ?
|
|
14381
|
-
const detail = 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(
|
|
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(
|
|
14391
|
+
console.log(chalk9__default.default.yellow(` ${critical.length} issue(s) need attention.
|
|
14392
14392
|
`));
|
|
14393
14393
|
} else {
|
|
14394
|
-
console.log(
|
|
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(
|
|
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(
|
|
14426
|
+
spin.succeed(chalk9__default.default.green(`Updated to v${latest}! Restart your terminal.`));
|
|
14427
14427
|
} catch (err) {
|
|
14428
|
-
spin.fail(
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
15294
|
+
console.log(chalk9__default.default.bold("\n Identities:"));
|
|
15261
15295
|
if (identities.length === 0) {
|
|
15262
|
-
console.log(
|
|
15296
|
+
console.log(chalk9__default.default.gray(" No identities found."));
|
|
15263
15297
|
} else {
|
|
15264
15298
|
identities.forEach((id) => {
|
|
15265
|
-
const defaultLabel = id.isDefault ?
|
|
15266
|
-
console.log(` - ${
|
|
15267
|
-
console.log(
|
|
15268
|
-
if (id.description) console.log(
|
|
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(
|
|
15328
|
+
console.log(chalk9__default.default.green(`
|
|
15295
15329
|
Successfully created identity: ${name} (${id})`));
|
|
15296
|
-
if (options.default) console.log(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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:
|
|
15344
|
-
{ tier: "T2", label: "T2 Manager", color:
|
|
15345
|
-
{ tier: "T3", label: "T3 Worker", color:
|
|
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 ?
|
|
15355
|
-
const vision = model.isVisionCapable ?
|
|
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)} ${
|
|
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)} ${
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(` ${
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
15456
|
-
console.log(
|
|
15457
|
-
console.log(
|
|
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(
|
|
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(
|
|
15518
|
-
console.log(
|
|
15519
|
-
console.log(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
15545
|
-
console.log(
|
|
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(
|
|
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(
|
|
15552
|
-
console.log(
|
|
15553
|
-
console.log(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
15624
|
+
console.log(chalk9__default.default.magenta("\n \u25C8 Detected credentials\n"));
|
|
15567
15625
|
for (const c of found) {
|
|
15568
|
-
const usable = c.directlyUsable ?
|
|
15569
|
-
const kind = c.kind === "oauth" ?
|
|
15570
|
-
console.log(` ${
|
|
15571
|
-
console.log(
|
|
15572
|
-
if (c.warning) console.log(
|
|
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(
|
|
15575
|
-
console.log(
|
|
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(
|
|
15666
|
+
console.log(chalk9__default.default.magenta(" \u25C8 Cascade Telemetry"));
|
|
15609
15667
|
console.log();
|
|
15610
|
-
console.log(` Status: ${config.telemetry?.enabled ?
|
|
15611
|
-
console.log(
|
|
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(
|
|
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(
|
|
15628
|
-
console.log(
|
|
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(
|
|
15631
|
-
console.log(
|
|
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(
|
|
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(
|
|
15645
|
-
console.log(
|
|
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(
|
|
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(
|
|
15660
|
-
console.log(
|
|
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 ?
|
|
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)} ${
|
|
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(
|
|
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
|
-
|
|
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
|
|
15755
|
-
|
|
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(
|
|
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(
|
|
15783
|
-
console.error(
|
|
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(
|
|
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(
|
|
15824
|
-
console.error(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
15872
|
-
console.log(
|
|
15873
|
-
console.log(
|
|
15874
|
-
console.log(
|
|
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);
|