aiden-runtime 4.0.0 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -14
- package/dist/cli/v4/aidenCLI.js +92 -9
- package/dist/cli/v4/chatSession.js +16 -0
- package/dist/cli/v4/commands/index.js +4 -1
- package/dist/cli/v4/commands/setup.js +34 -0
- package/dist/cli/v4/display.js +3 -1
- package/dist/cli/v4/setupWizard.js +466 -232
- package/dist/core/permissionSystem.js +2 -2
- package/dist/core/toolRegistry.js +2 -2
- package/dist/core/v4/firstRun/providerDetection.js +287 -0
- package/dist/core/version.js +1 -1
- package/dist/providers/v4/nullAdapter.js +58 -0
- package/package.json +14 -6
package/README.md
CHANGED
|
@@ -59,7 +59,7 @@ Local-first · Self-healing routing · Browser & terminal control · Persistent
|
|
|
59
59
|
<p align="center">
|
|
60
60
|
<img src="https://img.shields.io/badge/Vitest-4-6e9f18?logo=vitest&logoColor=white&style=for-the-badge" alt="Vitest 4" />
|
|
61
61
|
<img src="https://img.shields.io/badge/esbuild-bundler-ffcf00?logo=esbuild&logoColor=black&style=for-the-badge" alt="esbuild" />
|
|
62
|
-
<img src="https://img.shields.io/badge/
|
|
62
|
+
<img src="https://img.shields.io/badge/install-npm%20global-cb3837?logo=npm&logoColor=white&style=for-the-badge" alt="npm install -g aiden-runtime" />
|
|
63
63
|
</p>
|
|
64
64
|
|
|
65
65
|
<p align="center">
|
|
@@ -139,7 +139,7 @@ Most AI agents answer questions. Aiden runs work end-to-end on your machine.
|
|
|
139
139
|
- **Plugin extension** — drop a plugin into `<aiden-home>/plugins/` and call `ctx.commandRegistry.register()` to add slash commands without touching core
|
|
140
140
|
- **Open source** — AGPL-3.0 core, Apache-2.0 skills. Read every line, modify anything, contribute back.
|
|
141
141
|
|
|
142
|
-
Aiden is a local-first AI operating system. It runs entirely on your machine — no cloud account required, no telemetry, no data leaving your hardware unless you configure a cloud provider. It
|
|
142
|
+
Aiden is a local-first AI operating system. It runs entirely on your machine — no cloud account required, no telemetry, no data leaving your hardware unless you configure a cloud provider. It installs as a global npm package (`aiden-runtime`, ~16 MB) on Windows, Linux, WSL, and macOS — Node.js 18+ is the only prerequisite. Features: 68 bundled skills, 42 built-in tools across 11 categories, multi-layer memory architecture, self-healing provider routing across 19 providers, the ability to control your screen, browse the web, run code, send emails and messages, manage files, and hold a full conversation — offline via Ollama.
|
|
143
143
|
|
|
144
144
|
---
|
|
145
145
|
|
|
@@ -164,12 +164,14 @@ For commercial deployments with support and indemnification, see [aiden.taracod.
|
|
|
164
164
|
|
|
165
165
|
## Platform support
|
|
166
166
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
|
170
|
-
|
|
171
|
-
| **
|
|
172
|
-
| **
|
|
167
|
+
All platforms use the same npm-based install path. Node.js 18+ is the only prerequisite.
|
|
168
|
+
|
|
169
|
+
| Platform | Install | Skills available |
|
|
170
|
+
|---|---|---|
|
|
171
|
+
| **Windows 10/11** | ✅ `npm install -g aiden-runtime` | All 68 (including Windows-only skills) |
|
|
172
|
+
| **Linux** | ✅ `npm install -g aiden-runtime` | ~62 (Windows-only skills auto-skipped) |
|
|
173
|
+
| **WSL 2** | ✅ `npm install -g aiden-runtime` | ~62 (Windows-only skills auto-skipped) |
|
|
174
|
+
| **macOS** | ✅ `npm install -g aiden-runtime` | ~62 (Windows-only skills auto-skipped) |
|
|
173
175
|
|
|
174
176
|
Windows-only skills (clipboard history, Defender, OneNote, Outlook COM, registry, Task Scheduler, etc.) are tagged `platform: windows` and silently skipped on other platforms at load time.
|
|
175
177
|
|
|
@@ -224,18 +226,18 @@ npm install -g aiden-runtime
|
|
|
224
226
|
aiden
|
|
225
227
|
```
|
|
226
228
|
|
|
227
|
-
### Prerequisites (
|
|
229
|
+
### Prerequisites (all platforms)
|
|
228
230
|
- Node.js 18+
|
|
229
|
-
- Git
|
|
231
|
+
- Git (only for the manual install path below)
|
|
230
232
|
- Ollama (optional, for offline mode): [ollama.ai](https://ollama.ai)
|
|
231
233
|
|
|
232
|
-
### Windows —
|
|
234
|
+
### Windows — one-line install
|
|
233
235
|
|
|
234
236
|
```powershell
|
|
235
237
|
irm aiden.taracod.com/install.ps1 | iex
|
|
236
238
|
```
|
|
237
239
|
|
|
238
|
-
|
|
240
|
+
The installer verifies Node.js 18+ then runs `npm install -g aiden-runtime`. Same package as `npx aiden-runtime` above; just adds the `aiden` command to your PATH so you can launch from any terminal.
|
|
239
241
|
|
|
240
242
|
### Linux / WSL / macOS — one-line install
|
|
241
243
|
|
|
@@ -648,7 +650,7 @@ Both the terminal CLI and the browser dashboard (`localhost:4200/ui`) expose the
|
|
|
648
650
|
|
|
649
651
|
- **TypeScript 5.9** — strict mode, full typing across core, providers, CLI, API.
|
|
650
652
|
- **Node.js 18+** — runtime; `node-fetch` not needed (built-in `fetch`).
|
|
651
|
-
- **Electron 41** —
|
|
653
|
+
- **Electron 41** — optional desktop wrapper; primary install is npm-based.
|
|
652
654
|
- **Next.js (app router)** — `dashboard-next/` for the browser UI.
|
|
653
655
|
- **React 18** — dashboard component model.
|
|
654
656
|
- **Playwright 1.58** — browser automation backbone.
|
|
@@ -658,7 +660,7 @@ Both the terminal CLI and the browser dashboard (`localhost:4200/ui`) expose the
|
|
|
658
660
|
- **croner** — cron scheduler.
|
|
659
661
|
- **discord.js**, **@slack/web-api**, **whatsapp-web.js**, **twilio**, **nodemailer**, **imap-simple** — channel adapters.
|
|
660
662
|
- **Vitest 4** — test runner; ~1,500 unit + integration tests.
|
|
661
|
-
- **esbuild**
|
|
663
|
+
- **esbuild** — bundler for the npm package; **electron-builder** — optional desktop wrapper.
|
|
662
664
|
- **Cloudflare Workers** — landing page + license server + install-script proxy.
|
|
663
665
|
|
|
664
666
|
---
|
package/dist/cli/v4/aidenCLI.js
CHANGED
|
@@ -58,6 +58,9 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
58
58
|
return result;
|
|
59
59
|
};
|
|
60
60
|
})();
|
|
61
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
62
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
63
|
+
};
|
|
61
64
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
62
65
|
exports.getEnvSource = exports.loadAidenEnvFile = void 0;
|
|
63
66
|
exports.main = main;
|
|
@@ -71,6 +74,7 @@ exports.runSkillsSubcommand = runSkillsSubcommand;
|
|
|
71
74
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
72
75
|
const commander_1 = require("commander");
|
|
73
76
|
const node_fs_1 = require("node:fs");
|
|
77
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
74
78
|
const chatSession_1 = require("./chatSession");
|
|
75
79
|
const aidenTUI_1 = require("./aidenTUI");
|
|
76
80
|
const display_1 = require("./display");
|
|
@@ -106,6 +110,7 @@ const runtimeResolver_1 = require("../../providers/v4/runtimeResolver");
|
|
|
106
110
|
const chatCompletionsAdapter_1 = require("../../providers/v4/chatCompletionsAdapter");
|
|
107
111
|
const providerFallback_1 = require("../../core/v4/providerFallback");
|
|
108
112
|
const skillBundledRestore_1 = require("../../core/v4/skillBundledRestore");
|
|
113
|
+
const providerDetection_1 = require("../../core/v4/firstRun/providerDetection");
|
|
109
114
|
const aidenLogger_1 = require("../../core/v4/aidenLogger");
|
|
110
115
|
const plugins_1 = require("../../core/v4/plugins");
|
|
111
116
|
const providerAuth_1 = require("../../core/v4/auth/providerAuth");
|
|
@@ -351,9 +356,70 @@ async function buildAgentRuntime(cliOpts, opts) {
|
|
|
351
356
|
}
|
|
352
357
|
const config = new config_1.ConfigManager(paths);
|
|
353
358
|
await config.load();
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
359
|
+
// Phase 30.2 — fresh-user UX. Detection extends the old
|
|
360
|
+
// `isFreshInstall`-only gate so we cover three new failure modes:
|
|
361
|
+
// 1. fresh user with no env / no OAuth / no config → wizard fires
|
|
362
|
+
// (was working under the old gate; still does).
|
|
363
|
+
// 2. user with config.yaml pointing at chatgpt-plus but a stale /
|
|
364
|
+
// missing OAuth token file → wizard fires (was NOT under old
|
|
365
|
+
// code — it saw config.yaml present and proceeded into a
|
|
366
|
+
// broken resolve, which surfaced as a confusing rate-limit
|
|
367
|
+
// error on the user's first chat).
|
|
368
|
+
// 3. user with no config but Ollama running OR an env API key
|
|
369
|
+
// → wizard fires anyway. ConfigManager's DEFAULT_CONFIG points
|
|
370
|
+
// at `anthropic / claude-opus-4-7`, which doesn't match the
|
|
371
|
+
// detected env / Ollama, so skipping the wizard would surface
|
|
372
|
+
// the same confusing "missing ANTHROPIC_API_KEY" error.
|
|
373
|
+
// 4. moat-boot test fixtures that stub `providers.fake.apiKey`
|
|
374
|
+
// inline in config.yaml count as configured — `isFreshInstall`
|
|
375
|
+
// already returns false for them so `wizardNeeded` stays false.
|
|
376
|
+
const detection = await (0, providerDetection_1.detectAvailableProviders)({ paths });
|
|
377
|
+
const configuredProviderBroken = !!detection.configProvider &&
|
|
378
|
+
!detection.configuredProviderHasCredentials;
|
|
379
|
+
const wizardNeeded = !detection.hasAnyProvider ||
|
|
380
|
+
configuredProviderBroken ||
|
|
381
|
+
(await (0, setupWizard_1.isFreshInstall)(paths));
|
|
382
|
+
// Phase 30.2.1: when the wizard returns 'skipped' (explore mode) we
|
|
383
|
+
// boot the REPL with a NullAdapter instead of trying to resolve a
|
|
384
|
+
// real provider. Flagged here, set inside the wizard block, and
|
|
385
|
+
// consumed when building the adapter.
|
|
386
|
+
let exploreMode = false;
|
|
387
|
+
if (wizardNeeded) {
|
|
388
|
+
if (!detection.hasAnyProvider) {
|
|
389
|
+
// Truly empty: no env, no OAuth, no Ollama, no inline config.
|
|
390
|
+
process.stdout.write(`\n${(0, providerDetection_1.summarizeDetection)(detection)}\n`);
|
|
391
|
+
}
|
|
392
|
+
else if (configuredProviderBroken) {
|
|
393
|
+
// Config points at a provider we can't credential-resolve.
|
|
394
|
+
process.stdout.write(`\nConfigured provider '${detection.configProvider}' has no usable credentials ` +
|
|
395
|
+
`at ${node_path_1.default.join(paths.root, 'auth', `${detection.configProvider}.json`)}.\n`);
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
// Detected something (env / oauth / ollama) but config.yaml is
|
|
399
|
+
// missing or empty — DEFAULT_CONFIG would route to anthropic and
|
|
400
|
+
// the resolver would fail. Surface the detection so the user
|
|
401
|
+
// sees what we found, then walk them through proper setup.
|
|
402
|
+
process.stdout.write(`\n${(0, providerDetection_1.summarizeDetection)(detection)}\n`);
|
|
403
|
+
process.stdout.write('config.yaml is empty — let\'s pick a provider that matches.\n');
|
|
404
|
+
}
|
|
405
|
+
process.stdout.write('Launching setup wizard…\n\n');
|
|
406
|
+
const result = await (0, setupWizard_1.runSetupWizard)({ paths });
|
|
407
|
+
// Phase 30.2.1: three exit states.
|
|
408
|
+
if (result.status === 'exited') {
|
|
409
|
+
// Recovery option [5] — clean exit, no REPL.
|
|
410
|
+
process.exit(0);
|
|
411
|
+
}
|
|
412
|
+
if (result.status === 'skipped') {
|
|
413
|
+
// Recovery option [4] "explore mode" OR Ctrl+C cancellation.
|
|
414
|
+
// Boot continues into the REPL with a NullAdapter; chat is
|
|
415
|
+
// intercepted by ChatSession, slash commands work normally.
|
|
416
|
+
// Flagged here and consumed below where the adapter is built.
|
|
417
|
+
exploreMode = true;
|
|
418
|
+
}
|
|
419
|
+
// 'configured' (or 'skipped' — we still want the env/.env reload
|
|
420
|
+
// for slash commands like /providers that read fresh state) →
|
|
421
|
+
// re-load both so the resolver sees what the wizard wrote.
|
|
422
|
+
(0, envSources_1.loadAidenEnvFile)(paths.envFile);
|
|
357
423
|
await config.load();
|
|
358
424
|
}
|
|
359
425
|
const providerId = cliOpts.provider ??
|
|
@@ -385,19 +451,32 @@ async function buildAgentRuntime(cliOpts, opts) {
|
|
|
385
451
|
const credentialResolver = new credentialResolver_1.CredentialResolver(paths.authJson);
|
|
386
452
|
const resolver = new runtimeResolver_1.RuntimeResolver(credentialResolver);
|
|
387
453
|
let adapter;
|
|
388
|
-
|
|
389
|
-
|
|
454
|
+
if (exploreMode) {
|
|
455
|
+
// Phase 30.2.1 — wizard skipped. Use a NullAdapter so AidenAgent
|
|
456
|
+
// construction succeeds; ChatSession will intercept chat attempts
|
|
457
|
+
// BEFORE calling the adapter and surface the friendly message.
|
|
458
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
459
|
+
const { NullAdapter } = require('../../providers/v4/nullAdapter');
|
|
460
|
+
adapter = new NullAdapter();
|
|
390
461
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
462
|
+
else {
|
|
463
|
+
try {
|
|
464
|
+
adapter = await resolver.resolve({ providerId, modelId, config, paths });
|
|
465
|
+
}
|
|
466
|
+
catch (err) {
|
|
467
|
+
display.printError(`Could not resolve provider '${providerId}' / model '${modelId}': ${err.message}`, 'Run `aiden model` to pick a valid provider, or `aiden doctor`.');
|
|
468
|
+
process.exit(1);
|
|
469
|
+
}
|
|
394
470
|
}
|
|
395
471
|
// Phase 16b.1: wrap chat_completions providers in a FallbackAdapter so
|
|
396
472
|
// 429s on Groq slot 1 transparently retry Groq slot 2/3 and Together.
|
|
397
473
|
// Only activates when there's at least one *additional* slot configured
|
|
398
474
|
// beyond the primary — otherwise the wrapper would just rethrow.
|
|
475
|
+
// Phase 30.2.1: skip in explore mode — wrapping a NullAdapter in
|
|
476
|
+
// FallbackAdapter would just defer the friendly error one layer.
|
|
399
477
|
let fallbackAdapter = null;
|
|
400
|
-
if (
|
|
478
|
+
if (!exploreMode &&
|
|
479
|
+
adapter.apiMode === 'chat_completions' &&
|
|
401
480
|
(providerId === 'groq' || providerId === 'together')) {
|
|
402
481
|
const slots = buildAgentFallbackSlots(adapter, providerId, modelId);
|
|
403
482
|
const reachable = slots.filter((s) => s.keyPresent);
|
|
@@ -820,6 +899,7 @@ async function buildAgentRuntime(cliOpts, opts) {
|
|
|
820
899
|
fallbackAdapter,
|
|
821
900
|
personalityManager,
|
|
822
901
|
pluginLoader,
|
|
902
|
+
exploreMode,
|
|
823
903
|
};
|
|
824
904
|
}
|
|
825
905
|
async function runInteractiveChat(cliOpts, opts) {
|
|
@@ -846,6 +926,9 @@ async function runInteractiveChat(cliOpts, opts) {
|
|
|
846
926
|
paths: runtime.paths,
|
|
847
927
|
personalityManager: runtime.personalityManager,
|
|
848
928
|
pluginLoader: runtime.pluginLoader,
|
|
929
|
+
// Phase 30.2.1 — boot card renders "model not configured" and
|
|
930
|
+
// chat attempts get the friendly NotConfiguredError message.
|
|
931
|
+
unconfigured: runtime.exploreMode,
|
|
849
932
|
};
|
|
850
933
|
if (cliOpts.tui) {
|
|
851
934
|
await (0, aidenTUI_1.runTuiMode)({
|
|
@@ -212,6 +212,18 @@ class ChatSession {
|
|
|
212
212
|
}
|
|
213
213
|
// ── Inner: a single agent turn ─────────────────────────────────────
|
|
214
214
|
async runAgentTurn(userInput) {
|
|
215
|
+
// Phase 30.2.1 — explore mode: short-circuit BEFORE building the
|
|
216
|
+
// turn-status spinner / agent call. The wizard skipped, so there's
|
|
217
|
+
// no real provider to talk to. Print a friendly redirect to /setup
|
|
218
|
+
// (or the env-var alternative) and return — REPL stays alive, user
|
|
219
|
+
// can run slash commands or hit /quit.
|
|
220
|
+
if (this.opts.unconfigured) {
|
|
221
|
+
void userInput; // silence unused-arg warning when this branch fires
|
|
222
|
+
this.opts.display.write('\n');
|
|
223
|
+
this.opts.display.printError('No AI provider configured yet.', 'Run /setup to configure a provider, or set an API key environment variable (e.g. GROQ_API_KEY).');
|
|
224
|
+
this.opts.display.write('\n');
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
215
227
|
// Phase 22 Task 4: status bar reflects the live phase. Set on
|
|
216
228
|
// entry, cleared in both success and error paths below.
|
|
217
229
|
this.setStatusState({ kind: 'generating', sinceMs: Date.now() });
|
|
@@ -353,11 +365,15 @@ class ChatSession {
|
|
|
353
365
|
skillsLoaded = 0;
|
|
354
366
|
}
|
|
355
367
|
// PIECE 1 — status pills row.
|
|
368
|
+
// Phase 30.2.1: in explore mode the model pill renders "not
|
|
369
|
+
// configured" instead of the DEFAULT_CONFIG fallback, so a fresh
|
|
370
|
+
// user who skipped the wizard isn't misled by a stale model name.
|
|
356
371
|
display.write(display.statusPillsRow({
|
|
357
372
|
coreOnline: true,
|
|
358
373
|
mode: 'auto',
|
|
359
374
|
model: this.currentModelId,
|
|
360
375
|
memoryActive: true,
|
|
376
|
+
providerOk: !this.opts.unconfigured,
|
|
361
377
|
}) + '\n');
|
|
362
378
|
display.write(` ${display.rule()}\n`);
|
|
363
379
|
display.write('\n');
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* and registers each on the global CommandRegistry at boot.
|
|
13
13
|
*/
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.allCommands = exports.cron = exports.doctor = exports.license = exports.auth = exports.plugins = exports.streaming = exports.debugPrompt = exports.identity = exports.providers = exports.quit = exports.clear = exports.verbose = exports.reasoning = exports.reloadMcp = exports.skills = exports.skin = exports.yolo = exports.usage = exports.compress = exports.title = exports.save = exports.personality = exports.model = exports.tools = exports.help = void 0;
|
|
15
|
+
exports.allCommands = exports.setup = exports.cron = exports.doctor = exports.license = exports.auth = exports.plugins = exports.streaming = exports.debugPrompt = exports.identity = exports.providers = exports.quit = exports.clear = exports.verbose = exports.reasoning = exports.reloadMcp = exports.skills = exports.skin = exports.yolo = exports.usage = exports.compress = exports.title = exports.save = exports.personality = exports.model = exports.tools = exports.help = void 0;
|
|
16
16
|
const help_1 = require("./help");
|
|
17
17
|
Object.defineProperty(exports, "help", { enumerable: true, get: function () { return help_1.help; } });
|
|
18
18
|
const tools_1 = require("./tools");
|
|
@@ -63,6 +63,8 @@ const doctor_1 = require("./doctor");
|
|
|
63
63
|
Object.defineProperty(exports, "doctor", { enumerable: true, get: function () { return doctor_1.doctor; } });
|
|
64
64
|
const cron_1 = require("./cron");
|
|
65
65
|
Object.defineProperty(exports, "cron", { enumerable: true, get: function () { return cron_1.cron; } });
|
|
66
|
+
const setup_1 = require("./setup");
|
|
67
|
+
Object.defineProperty(exports, "setup", { enumerable: true, get: function () { return setup_1.setup; } });
|
|
66
68
|
/** All built-in system commands, in canonical order. */
|
|
67
69
|
exports.allCommands = [
|
|
68
70
|
help_1.help,
|
|
@@ -85,6 +87,7 @@ exports.allCommands = [
|
|
|
85
87
|
license_1.license,
|
|
86
88
|
doctor_1.doctor,
|
|
87
89
|
cron_1.cron,
|
|
90
|
+
setup_1.setup,
|
|
88
91
|
reloadMcp_1.reloadMcp,
|
|
89
92
|
reasoning_1.reasoning,
|
|
90
93
|
verbose_1.verbose,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setup = void 0;
|
|
4
|
+
const setupWizard_1 = require("../setupWizard");
|
|
5
|
+
exports.setup = {
|
|
6
|
+
name: 'setup',
|
|
7
|
+
description: 'Re-run the setup wizard (configure provider + API key).',
|
|
8
|
+
category: 'system',
|
|
9
|
+
icon: '⚙',
|
|
10
|
+
handler: async (ctx) => {
|
|
11
|
+
if (!ctx.paths) {
|
|
12
|
+
ctx.display.printError('Cannot run wizard from this context — no paths available.', 'This is a wiring bug; please report.');
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const result = await (0, setupWizard_1.runSetupWizard)({
|
|
16
|
+
paths: ctx.paths,
|
|
17
|
+
display: ctx.display,
|
|
18
|
+
force: true,
|
|
19
|
+
});
|
|
20
|
+
if (result.status === 'configured' && result.ran) {
|
|
21
|
+
ctx.display.write('\nProvider configured. ' +
|
|
22
|
+
'Restart Aiden (`/quit` then re-run `aiden`) to pick up the new provider.\n\n');
|
|
23
|
+
}
|
|
24
|
+
else if (result.status === 'skipped') {
|
|
25
|
+
ctx.display.write('\nStill in explore mode. Run /setup again whenever you\'re ready.\n\n');
|
|
26
|
+
}
|
|
27
|
+
else if (result.status === 'exited') {
|
|
28
|
+
// Wizard explicitly chose to exit — but we're inside a REPL,
|
|
29
|
+
// so just report and stay in the session.
|
|
30
|
+
ctx.display.dim('Wizard exited; continuing existing session.');
|
|
31
|
+
}
|
|
32
|
+
return;
|
|
33
|
+
},
|
|
34
|
+
};
|
package/dist/cli/v4/display.js
CHANGED
|
@@ -305,11 +305,13 @@ class Display {
|
|
|
305
305
|
const lab = (s) => sk.applyColors(s, 'muted');
|
|
306
306
|
const val = (s) => sk.applyColors(s, 'agent');
|
|
307
307
|
const pill = (on, label, value) => `${dot(on)} ${lab(label)} ${val(value)}`;
|
|
308
|
+
const providerOk = args.providerOk !== false;
|
|
309
|
+
const modelValue = providerOk ? args.model : 'not configured';
|
|
308
310
|
return (' ' +
|
|
309
311
|
[
|
|
310
312
|
pill(args.coreOnline, 'core', args.coreOnline ? 'online' : 'starting'),
|
|
311
313
|
pill(true, 'mode', args.mode),
|
|
312
|
-
pill(
|
|
314
|
+
pill(providerOk, 'model', modelValue),
|
|
313
315
|
pill(args.memoryActive, 'memory', args.memoryActive ? 'active' : 'off'),
|
|
314
316
|
].join(' '));
|
|
315
317
|
}
|