aiden-runtime 4.6.0 → 4.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/v4/aidenCLI.js +22 -1
- package/dist/cli/v4/chatSession.js +13 -0
- package/dist/cli/v4/commands/help.js +2 -0
- package/dist/cli/v4/commands/index.js +6 -1
- package/dist/cli/v4/commands/walkthrough.js +140 -0
- package/dist/cli/v4/onboarding/disclaimer.js +162 -0
- package/dist/cli/v4/onboarding/loading.js +208 -0
- package/dist/cli/v4/onboarding/providerPicker.js +126 -0
- package/dist/cli/v4/onboarding/successScreen.js +68 -0
- package/dist/cli/v4/repl/firstRunHint.js +107 -0
- package/dist/cli/v4/setupWizard.js +201 -31
- package/dist/core/v4/providers/modelFetch.js +179 -0
- package/dist/core/v4/providers/probe.js +275 -0
- package/dist/core/v4/ui/banner.js +133 -0
- package/dist/core/v4/ui/theme.js +164 -0
- package/dist/core/version.js +1 -1
- package/dist/tools/v4/ui/_uiSmokeTool.js +60 -0
- package/package.json +1 -1
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 Shiva Deore (Taracod).
|
|
4
|
+
* Licensed under AGPL-3.0. See LICENSE for details.
|
|
5
|
+
*
|
|
6
|
+
* Aiden — local-first agent.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* core/v4/ui/theme.ts — ONB1 (v4.7 onboarding rework).
|
|
10
|
+
*
|
|
11
|
+
* Self-contained theme module for the redesigned first-run experience.
|
|
12
|
+
* Lives alongside, NOT instead of, the existing skin engine
|
|
13
|
+
* (cli/v4/skinEngine.ts). The skin engine drives the REPL / boot card
|
|
14
|
+
* / every post-onboarding surface; this theme drives only the
|
|
15
|
+
* onboarding screens (slices 1–10 of dispatch ONB1).
|
|
16
|
+
*
|
|
17
|
+
* Why a separate module:
|
|
18
|
+
* - Onboarding palette is specified to a different muted/text spec
|
|
19
|
+
* than the existing skin (e.g. cool-grey #71717A vs warm-tan
|
|
20
|
+
* #B8A89A). Swapping the skin would re-paint every chat turn the
|
|
21
|
+
* user sees afterwards, surprising the eye on the *second* boot.
|
|
22
|
+
* - Onboarding is a single-shot surface — no per-user customisation,
|
|
23
|
+
* no YAML loader, no `monochrome`/`light` variants needed beyond
|
|
24
|
+
* graceful colour-depth degradation.
|
|
25
|
+
*
|
|
26
|
+
* Truecolor → 256 → 16 detection runs once at module load and is
|
|
27
|
+
* cached. Set `AIDEN_FORCE_COLOR_DEPTH=truecolor|256|16|none` to
|
|
28
|
+
* override (smoke tests rely on this).
|
|
29
|
+
*/
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.SEP_LIGHT = exports.SEP_HEAVY = exports.dim = exports.italic = exports.bold = exports.c = exports.PALETTE = void 0;
|
|
32
|
+
exports.getColorDepth = getColorDepth;
|
|
33
|
+
exports.paint = paint;
|
|
34
|
+
exports.separator = separator;
|
|
35
|
+
exports.termWidth = termWidth;
|
|
36
|
+
/**
|
|
37
|
+
* The 8-colour onboarding palette. Hex strings are the source of
|
|
38
|
+
* truth; the emit functions below convert per detected depth.
|
|
39
|
+
*/
|
|
40
|
+
exports.PALETTE = {
|
|
41
|
+
primary: '#FF6B35', // brand orange — Aiden hero
|
|
42
|
+
accent: '#FFB088', // light orange — highlights
|
|
43
|
+
success: '#4ADE80', // green checkmarks
|
|
44
|
+
warning: '#FBBF24', // amber warnings
|
|
45
|
+
error: '#EF4444', // red errors
|
|
46
|
+
text: '#F5F5F5', // bright white — headers/titles
|
|
47
|
+
muted: '#71717A', // dim grey — secondary text/hints
|
|
48
|
+
rule: '#27272A', // dark grey — separators
|
|
49
|
+
};
|
|
50
|
+
/** Parse a `#RRGGBB` hex string into [r,g,b]. */
|
|
51
|
+
function hexToRgb(hex) {
|
|
52
|
+
const m = /^#?([0-9a-fA-F]{6})$/.exec(hex);
|
|
53
|
+
if (!m)
|
|
54
|
+
return [255, 255, 255];
|
|
55
|
+
const n = parseInt(m[1], 16);
|
|
56
|
+
return [(n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff];
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Map a 24-bit RGB triple to the closest xterm-256 colour index.
|
|
60
|
+
* Uses the standard 6×6×6 cube + grey-ramp approximation.
|
|
61
|
+
*/
|
|
62
|
+
function rgbTo256(r, g, b) {
|
|
63
|
+
// Grey-ramp fast path: when r==g==b within 8, prefer the 24-step ramp.
|
|
64
|
+
if (Math.abs(r - g) < 8 && Math.abs(g - b) < 8) {
|
|
65
|
+
if (r < 8)
|
|
66
|
+
return 16;
|
|
67
|
+
if (r > 248)
|
|
68
|
+
return 231;
|
|
69
|
+
return Math.round(((r - 8) / 247) * 24) + 232;
|
|
70
|
+
}
|
|
71
|
+
const q = (v) => Math.round(v / 51);
|
|
72
|
+
return 16 + 36 * q(r) + 6 * q(g) + q(b);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Map a 24-bit RGB triple to a low-fidelity 16-colour ANSI code
|
|
76
|
+
* (30–37 / 90–97). Picks the closest of the 16 standard slots.
|
|
77
|
+
*/
|
|
78
|
+
function rgbTo16(r, g, b) {
|
|
79
|
+
const STD = [
|
|
80
|
+
[30, 0, 0, 0], [31, 205, 49, 49], [32, 13, 188, 121], [33, 229, 229, 16],
|
|
81
|
+
[34, 36, 114, 200], [35, 188, 63, 188], [36, 17, 168, 205], [37, 229, 229, 229],
|
|
82
|
+
[90, 102, 102, 102], [91, 241, 76, 76], [92, 35, 209, 139], [93, 245, 245, 67],
|
|
83
|
+
[94, 59, 142, 234], [95, 214, 112, 214], [96, 41, 184, 219], [97, 229, 229, 229],
|
|
84
|
+
];
|
|
85
|
+
let best = STD[0];
|
|
86
|
+
let bestDist = Infinity;
|
|
87
|
+
for (const cand of STD) {
|
|
88
|
+
const [, cr, cg, cb] = cand;
|
|
89
|
+
const d = (r - cr) ** 2 + (g - cg) ** 2 + (b - cb) ** 2;
|
|
90
|
+
if (d < bestDist) {
|
|
91
|
+
bestDist = d;
|
|
92
|
+
best = cand;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return best[0];
|
|
96
|
+
}
|
|
97
|
+
/** Detect the terminal's effective colour depth. Cached at module load. */
|
|
98
|
+
function detectColorDepth() {
|
|
99
|
+
const forced = process.env.AIDEN_FORCE_COLOR_DEPTH?.toLowerCase();
|
|
100
|
+
if (forced === 'truecolor' || forced === '256' || forced === '16' || forced === 'none') {
|
|
101
|
+
return forced;
|
|
102
|
+
}
|
|
103
|
+
if (process.env.NO_COLOR && process.env.NO_COLOR !== '')
|
|
104
|
+
return 'none';
|
|
105
|
+
if (!process.stdout.isTTY)
|
|
106
|
+
return 'none';
|
|
107
|
+
const ct = (process.env.COLORTERM ?? '').toLowerCase();
|
|
108
|
+
if (ct === 'truecolor' || ct === '24bit')
|
|
109
|
+
return 'truecolor';
|
|
110
|
+
const term = (process.env.TERM ?? '').toLowerCase();
|
|
111
|
+
if (term.includes('256'))
|
|
112
|
+
return '256';
|
|
113
|
+
if (term === 'dumb' || term === '')
|
|
114
|
+
return 'none';
|
|
115
|
+
return '16';
|
|
116
|
+
}
|
|
117
|
+
const COLOR_DEPTH = detectColorDepth();
|
|
118
|
+
/** Public: report the depth (smoke tests + diagnostics). */
|
|
119
|
+
function getColorDepth() { return COLOR_DEPTH; }
|
|
120
|
+
/** Wrap `text` in the SGR sequence for `kind`, degrading per depth. */
|
|
121
|
+
function paint(text, kind) {
|
|
122
|
+
if (COLOR_DEPTH === 'none')
|
|
123
|
+
return text;
|
|
124
|
+
const [r, g, b] = hexToRgb(exports.PALETTE[kind]);
|
|
125
|
+
if (COLOR_DEPTH === 'truecolor')
|
|
126
|
+
return `\x1b[38;2;${r};${g};${b}m${text}\x1b[39m`;
|
|
127
|
+
if (COLOR_DEPTH === '256')
|
|
128
|
+
return `\x1b[38;5;${rgbTo256(r, g, b)}m${text}\x1b[39m`;
|
|
129
|
+
return `\x1b[${rgbTo16(r, g, b)}m${text}\x1b[39m`;
|
|
130
|
+
}
|
|
131
|
+
/** Convenience helpers — one per palette key. */
|
|
132
|
+
exports.c = {
|
|
133
|
+
primary: (s) => paint(s, 'primary'),
|
|
134
|
+
accent: (s) => paint(s, 'accent'),
|
|
135
|
+
success: (s) => paint(s, 'success'),
|
|
136
|
+
warning: (s) => paint(s, 'warning'),
|
|
137
|
+
error: (s) => paint(s, 'error'),
|
|
138
|
+
text: (s) => paint(s, 'text'),
|
|
139
|
+
muted: (s) => paint(s, 'muted'),
|
|
140
|
+
rule: (s) => paint(s, 'rule'),
|
|
141
|
+
};
|
|
142
|
+
/** SGR helpers for emphasis. Italic gracefully degrades when unsupported. */
|
|
143
|
+
const bold = (s) => (COLOR_DEPTH === 'none' ? s : `\x1b[1m${s}\x1b[22m`);
|
|
144
|
+
exports.bold = bold;
|
|
145
|
+
const italic = (s) => (COLOR_DEPTH === 'none' ? s : `\x1b[3m${s}\x1b[23m`);
|
|
146
|
+
exports.italic = italic;
|
|
147
|
+
const dim = (s) => (COLOR_DEPTH === 'none' ? s : `\x1b[2m${s}\x1b[22m`);
|
|
148
|
+
exports.dim = dim;
|
|
149
|
+
/**
|
|
150
|
+
* Common ornaments — single source so onboarding screens share rhythm.
|
|
151
|
+
*/
|
|
152
|
+
exports.SEP_HEAVY = '━';
|
|
153
|
+
exports.SEP_LIGHT = '─';
|
|
154
|
+
/** Render a full-width separator in RULE colour, optionally heavy. */
|
|
155
|
+
function separator(width, heavy = true) {
|
|
156
|
+
const w = Math.max(8, Math.min(width, 100));
|
|
157
|
+
const ch = heavy ? exports.SEP_HEAVY : exports.SEP_LIGHT;
|
|
158
|
+
return exports.c.rule(ch.repeat(w));
|
|
159
|
+
}
|
|
160
|
+
/** Effective terminal width clamped to a sane band. */
|
|
161
|
+
function termWidth() {
|
|
162
|
+
const raw = process.stdout.columns ?? 80;
|
|
163
|
+
return Math.max(40, Math.min(raw, 100));
|
|
164
|
+
}
|
package/dist/core/version.js
CHANGED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 Shiva Deore (Taracod).
|
|
4
|
+
* Licensed under AGPL-3.0. See LICENSE for details.
|
|
5
|
+
*
|
|
6
|
+
* Aiden — local-first agent.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* tools/v4/ui/_uiSmokeTool.ts — v4.7 Slice 1 smoke harness.
|
|
10
|
+
*
|
|
11
|
+
* Internal tool used ONLY to verify the uiOnly dispatch seam from
|
|
12
|
+
* Slice 1 (ToolHandler.uiOnly + resolveUiOnly + onUiEvent +
|
|
13
|
+
* Display.renderUiEvent). NOT for end-user LLM workflows.
|
|
14
|
+
*
|
|
15
|
+
* Registered behind `AIDEN_UI_SMOKE=1` env flag in
|
|
16
|
+
* `tools/v4/index.ts::registerAllTools`. Will be deleted once
|
|
17
|
+
* Slice 2 lands the real ui_task_update / ui_task_done tools.
|
|
18
|
+
*
|
|
19
|
+
* When invoked, the agent's dispatch loop:
|
|
20
|
+
* - resolves uiOnly=true via the resolveUiOnly closure
|
|
21
|
+
* - fires runOptions.onUiEvent('_ui_smoke', args)
|
|
22
|
+
* - SKIPS execute() entirely
|
|
23
|
+
* - SKIPS turnToolMessages push + toolCallCount increment + verifier
|
|
24
|
+
*
|
|
25
|
+
* The handler's `execute` MUST never be called by the dispatch path
|
|
26
|
+
* when uiOnly is honoured. Throws if reached — that throw is a
|
|
27
|
+
* regression alarm.
|
|
28
|
+
*/
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
exports.uiSmokeTool = void 0;
|
|
31
|
+
exports.uiSmokeTool = {
|
|
32
|
+
schema: {
|
|
33
|
+
name: '_ui_smoke',
|
|
34
|
+
description: 'Internal smoke-test tool for the v4.7 uiOnly dispatch path. ' +
|
|
35
|
+
'Renders a single debug line through the UI event seam. ' +
|
|
36
|
+
'Does NOT round-trip back to the model. Only available when ' +
|
|
37
|
+
'AIDEN_UI_SMOKE=1.',
|
|
38
|
+
inputSchema: {
|
|
39
|
+
type: 'object',
|
|
40
|
+
properties: {
|
|
41
|
+
message: {
|
|
42
|
+
type: 'string',
|
|
43
|
+
description: 'Free-text payload echoed in the rendered debug line.',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
required: ['message'],
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
category: 'read',
|
|
50
|
+
mutates: false,
|
|
51
|
+
uiOnly: true,
|
|
52
|
+
execute() {
|
|
53
|
+
// Defensive — if `resolveUiOnly` is wired correctly, the
|
|
54
|
+
// dispatch loop short-circuits BEFORE reaching this body. A
|
|
55
|
+
// call here means the resolver returned false/undefined and
|
|
56
|
+
// the seam regressed. Throwing surfaces the regression at
|
|
57
|
+
// smoke time instead of silently behaving like a regular tool.
|
|
58
|
+
throw new Error('_ui_smoke.execute() should never be called — uiOnly dispatch path regressed');
|
|
59
|
+
},
|
|
60
|
+
};
|