@addai/node 0.4.0 → 0.5.0

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/tui.js DELETED
@@ -1,314 +0,0 @@
1
- "use strict";
2
- // `entities-runtime harnesses` — interactive harness manager in the
3
- // Claude Code terminal idiom: alt-screen, rounded panels, dim chrome,
4
- // ❯ selection, braille spinner, ⏺ status dots. Hand-rolled ANSI — the
5
- // daemon deliberately has no TUI framework dependency.
6
- //
7
- // Local actions hand the real terminal to the harness CLI itself (there
8
- // is nothing to bridge when you're already at the machine): install
9
- // streams npm output into a panel; login leaves the alt screen, runs the
10
- // CLI's own login flow attached to your TTY, then re-probes on return.
11
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
- if (k2 === undefined) k2 = k;
13
- var desc = Object.getOwnPropertyDescriptor(m, k);
14
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
- desc = { enumerable: true, get: function() { return m[k]; } };
16
- }
17
- Object.defineProperty(o, k2, desc);
18
- }) : (function(o, m, k, k2) {
19
- if (k2 === undefined) k2 = k;
20
- o[k2] = m[k];
21
- }));
22
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
- Object.defineProperty(o, "default", { enumerable: true, value: v });
24
- }) : function(o, v) {
25
- o["default"] = v;
26
- });
27
- var __importStar = (this && this.__importStar) || (function () {
28
- var ownKeys = function(o) {
29
- ownKeys = Object.getOwnPropertyNames || function (o) {
30
- var ar = [];
31
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
- return ar;
33
- };
34
- return ownKeys(o);
35
- };
36
- return function (mod) {
37
- if (mod && mod.__esModule) return mod;
38
- var result = {};
39
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
- __setModuleDefault(result, mod);
41
- return result;
42
- };
43
- })();
44
- Object.defineProperty(exports, "__esModule", { value: true });
45
- exports.runHarnessesTui = runHarnessesTui;
46
- const child_process_1 = require("child_process");
47
- const readline = __importStar(require("readline"));
48
- const capabilities_1 = require("./capabilities");
49
- const win_1 = require("./win");
50
- const fs = __importStar(require("fs"));
51
- const os = __importStar(require("os"));
52
- const path = __importStar(require("path"));
53
- const harness_registry_1 = require("./harness-registry");
54
- /* ── ansi helpers ────────────────────────────────────────────────────── */
55
- const ESC = '\x1b[';
56
- const dim = (s) => `${ESC}2m${s}${ESC}22m`;
57
- const bold = (s) => `${ESC}1m${s}${ESC}22m`;
58
- const fg = (n, s) => `${ESC}38;5;${n}m${s}${ESC}39m`;
59
- const green = (s) => fg(114, s);
60
- const yellow = (s) => fg(179, s);
61
- const grey = (s) => fg(244, s);
62
- const cyan = (s) => fg(80, s);
63
- const altOn = () => process.stdout.write(`${ESC}?1049h${ESC}?25l`);
64
- const altOff = () => process.stdout.write(`${ESC}?1049l${ESC}?25h`);
65
- const home = () => process.stdout.write(`${ESC}H${ESC}2J`);
66
- const SPIN = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
67
- const width = () => Math.min(process.stdout.columns || 100, 110);
68
- function panel(title, lines) {
69
- const w = width() - 2;
70
- const strip = (s) => s.replace(/\x1b\[[0-9;]*m/g, '');
71
- const top = `${dim('╭─')} ${bold(title)} ${dim('─'.repeat(Math.max(1, w - strip(title).length - 4)) + '╮')}`;
72
- const body = lines.map(l => {
73
- const pad = Math.max(0, w - 2 - strip(l).length);
74
- return `${dim('│')} ${l}${' '.repeat(pad)} ${dim('│')}`;
75
- });
76
- const bottom = dim(`╰${'─'.repeat(w)}╯`);
77
- return [top, ...body, bottom].join('\n');
78
- }
79
- function dot(p) {
80
- if (!p?.available)
81
- return grey('⏺');
82
- return p.authed ? green('⏺') : yellow('⏺');
83
- }
84
- function actionFor(id, p) {
85
- if (!p?.available)
86
- return (0, harness_registry_1.isInstallable)(id) ? 'install' : 'how to install';
87
- if (!p.authed)
88
- return 'log in';
89
- return harness_registry_1.HARNESSES[id].logout ? 'log out' : 'ok';
90
- }
91
- function row(id, p, selected) {
92
- const spec = harness_registry_1.HARNESSES[id];
93
- const name = spec.label.padEnd(13);
94
- const ver = (p?.version ? `v${p.version}` : '—').padEnd(12).slice(0, 12);
95
- const who = (p?.authed
96
- ? `${p.account ?? p.accountKind ?? 'logged in'}${p.plan ? ` · ${p.plan}` : ''}`
97
- : p?.available ? 'not logged in' : 'not installed').padEnd(28).slice(0, 28);
98
- const models = `${p?.models?.length ?? 0} models`.padEnd(10);
99
- const efforts = spec.efforts.length ? spec.efforts.join('/') : '—';
100
- const act = actionFor(id, p);
101
- const actTxt = act === 'ok' ? green('✓') : act === 'log out' ? dim('↵ log out') : cyan(`↵ ${act}`);
102
- const line = `${dot(p)} ${name} ${dim(ver)} ${who} ${dim(models)} ${dim(efforts.padEnd(26).slice(0, 26))} ${actTxt}`;
103
- return selected ? `${cyan('❯')} ${bold(line)}` : ` ${line}`;
104
- }
105
- function render(st) {
106
- home();
107
- const lines = [];
108
- if (!st.caps) {
109
- lines.push(`${cyan(SPIN[st.spin % SPIN.length])} probing installed harnesses…`);
110
- }
111
- else {
112
- lines.push(dim(' harness version account models efforts'));
113
- harness_registry_1.HARNESS_IDS.forEach((id, i) => lines.push(row(id, st.caps[id], i === st.sel)));
114
- }
115
- if (st.busy)
116
- lines.push('', `${cyan(SPIN[st.spin % SPIN.length])} ${st.busy}`);
117
- if (st.log.length) {
118
- lines.push('');
119
- st.log.slice(-8).forEach(l => lines.push(dim(l.slice(0, width() - 8))));
120
- }
121
- if (st.note)
122
- lines.push('', st.note);
123
- process.stdout.write(panel('Harnesses', lines) + '\n');
124
- process.stdout.write(dim(' ↑/↓ move · ↵ install / log in · r refresh · q quit\n'));
125
- }
126
- /* ── actions ─────────────────────────────────────────────────────────── */
127
- async function installSelected(st, id, redraw) {
128
- const spec = harness_registry_1.HARNESSES[id];
129
- if (!(0, harness_registry_1.isInstallable)(id)) {
130
- st.note = yellow(`${spec.label}: ${spec.login.instructions}`);
131
- return;
132
- }
133
- st.busy = `installing ${spec.label} (npm i -g ${spec.npmPackage})`;
134
- st.log = [];
135
- redraw();
136
- const inv = (0, win_1.resolveCliInvocation)('npm', ['install', '-g', spec.npmPackage]);
137
- await new Promise(resolve => {
138
- const child = (0, child_process_1.spawn)(inv.file, inv.args, { env: process.env });
139
- const onChunk = (b) => {
140
- st.log.push(...b.toString('utf8').split('\n').filter(Boolean));
141
- redraw();
142
- };
143
- child.stdout?.on('data', onChunk);
144
- child.stderr?.on('data', onChunk);
145
- child.on('exit', code => {
146
- st.busy = null;
147
- st.note = code === 0 ? green(`✓ ${spec.label} installed`) : fg(203, `✗ npm exited ${code}`);
148
- resolve();
149
- });
150
- child.on('error', err => { st.busy = null; st.note = fg(203, `✗ ${err.message}`); resolve(); });
151
- });
152
- }
153
- function logoutSelected(id) {
154
- const spec = harness_registry_1.HARNESSES[id];
155
- if (!spec.logout)
156
- return `${spec.label} can only be logged out on the device`;
157
- if (spec.logout.cmd) {
158
- const bin = spec.findBinary();
159
- if (!bin)
160
- return `${spec.label} is not installed`;
161
- const inv = (0, win_1.resolveCliInvocation)(bin, spec.logout.cmd);
162
- const res = (0, child_process_1.spawnSync)(inv.file, inv.args, { stdio: 'ignore', env: process.env, timeout: 60_000 });
163
- if (res.status !== 0)
164
- return `logout exited with code ${res.status ?? '?'}`;
165
- }
166
- for (const rel of spec.logout.files ?? []) {
167
- try {
168
- fs.rmSync(path.join(os.homedir(), rel), { force: true });
169
- }
170
- catch { /* best effort */ }
171
- }
172
- for (const [rel, varName] of spec.logout.envStrip ?? []) {
173
- const envPath = path.join(os.homedir(), rel);
174
- try {
175
- const body = fs.readFileSync(envPath, 'utf8');
176
- fs.writeFileSync(envPath, body.split('\n').filter(l => !l.startsWith(`${varName}=`)).join('\n'), { mode: 0o600 });
177
- }
178
- catch { /* nothing to strip */ }
179
- }
180
- return null;
181
- }
182
- function loginSelected(id) {
183
- const spec = harness_registry_1.HARNESSES[id];
184
- const bin = spec.findBinary();
185
- if (!bin)
186
- return `${spec.label} is not installed`;
187
- // Hand the real terminal to the CLI — leave the alt screen first.
188
- altOff();
189
- console.log(cyan(`\n— ${spec.label} login —`));
190
- console.log(dim(spec.login.instructions) + '\n');
191
- const args = spec.login.strategy === 'pty-url-code' ? (spec.login.loginArgs ?? []) : [];
192
- const inv = (0, win_1.resolveCliInvocation)(bin, args);
193
- const res = (0, child_process_1.spawnSync)(inv.file, inv.args, { stdio: 'inherit', env: process.env });
194
- altOn();
195
- return res.status === 0 ? null : `login exited with code ${res.status ?? '?'}`;
196
- }
197
- /* ── entry ───────────────────────────────────────────────────────────── */
198
- async function plainStatus() {
199
- const caps = await (0, capabilities_1.probeCapabilities)();
200
- for (const id of harness_registry_1.HARNESS_IDS) {
201
- const p = caps[id];
202
- const state = !p?.available ? 'not installed' : p.authed ? `authed (${p.account ?? p.accountKind ?? '?'})` : 'not logged in';
203
- console.log(`${id.padEnd(8)} ${(p?.version ?? '—').padEnd(12)} ${state}`);
204
- }
205
- }
206
- async function runHarnessesTui() {
207
- if (!process.stdout.isTTY || !process.stdin.isTTY) {
208
- await plainStatus();
209
- return;
210
- }
211
- const st = { caps: null, sel: 0, spin: 0, busy: null, log: [], note: null, confirmLogout: null };
212
- const redraw = () => render(st);
213
- altOn();
214
- readline.emitKeypressEvents(process.stdin);
215
- process.stdin.setRawMode(true);
216
- process.stdin.resume();
217
- const spinTimer = setInterval(() => { st.spin++; if (st.busy || !st.caps)
218
- redraw(); }, 90);
219
- const quit = () => {
220
- clearInterval(spinTimer);
221
- process.stdin.setRawMode(false);
222
- process.stdin.pause();
223
- altOff();
224
- process.exit(0);
225
- };
226
- const reprobe = async () => {
227
- st.caps = null;
228
- redraw();
229
- st.caps = await (0, capabilities_1.probeCapabilities)();
230
- redraw();
231
- };
232
- let acting = false;
233
- process.stdin.on('keypress', (_str, key) => {
234
- void (async () => {
235
- if (!key || acting)
236
- return;
237
- if (key.name === 'q' || (key.ctrl && key.name === 'c')) {
238
- quit();
239
- return;
240
- }
241
- if (!st.caps)
242
- return;
243
- if (st.confirmLogout) {
244
- const target = st.confirmLogout;
245
- st.confirmLogout = null;
246
- if (key.name === 'y') {
247
- acting = true;
248
- try {
249
- const err = logoutSelected(target);
250
- st.note = err ? fg(203, `✗ ${err}`) : green(`✓ ${harness_registry_1.HARNESSES[target].label} logged out`);
251
- await reprobe();
252
- }
253
- finally {
254
- acting = false;
255
- }
256
- }
257
- else {
258
- st.note = dim('logout cancelled');
259
- redraw();
260
- }
261
- return;
262
- }
263
- if (key.name === 'up' || key.name === 'k') {
264
- st.sel = (st.sel + harness_registry_1.HARNESS_IDS.length - 1) % harness_registry_1.HARNESS_IDS.length;
265
- redraw();
266
- return;
267
- }
268
- if (key.name === 'down' || key.name === 'j') {
269
- st.sel = (st.sel + 1) % harness_registry_1.HARNESS_IDS.length;
270
- redraw();
271
- return;
272
- }
273
- if (key.name === 'r') {
274
- await reprobe();
275
- return;
276
- }
277
- if (key.name !== 'return')
278
- return;
279
- const id = harness_registry_1.HARNESS_IDS[st.sel];
280
- const p = st.caps[id];
281
- acting = true;
282
- try {
283
- if (!p?.available) {
284
- await installSelected(st, id, redraw);
285
- await reprobe();
286
- }
287
- else if (!p.authed) {
288
- const err = loginSelected(id);
289
- st.note = err ? fg(203, `✗ ${err}`) : green('✓ login flow finished — verifying…');
290
- await reprobe();
291
- const now = st.caps?.[id];
292
- if (now?.authed)
293
- st.note = green(`✓ ${harness_registry_1.HARNESSES[id].label} logged in as ${now.account ?? now.accountKind ?? '?'}`);
294
- else if (!err)
295
- st.note = yellow(`${harness_registry_1.HARNESSES[id].label} still reports unauthenticated`);
296
- redraw();
297
- }
298
- else if (harness_registry_1.HARNESSES[id].logout) {
299
- st.confirmLogout = id;
300
- st.note = yellow(`log out of ${harness_registry_1.HARNESSES[id].label}? press y to confirm`);
301
- redraw();
302
- }
303
- else {
304
- st.note = green(`${harness_registry_1.HARNESSES[id].label} is installed and logged in.`);
305
- redraw();
306
- }
307
- }
308
- finally {
309
- acting = false;
310
- }
311
- })();
312
- });
313
- await reprobe();
314
- }