@addai/node 0.30.9 → 0.30.10
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.js +4 -0
- package/dist/index.js +52 -19
- package/dist/tui/run.d.ts +27 -0
- package/dist/tui/run.js +93 -16
- package/package.json +62 -62
package/dist/cli.js
CHANGED
|
@@ -202,6 +202,10 @@ async function main() {
|
|
|
202
202
|
pid: runtime.pid,
|
|
203
203
|
startedAt: Date.now(),
|
|
204
204
|
version: index_1.VERSION,
|
|
205
|
+
// The daemon is running in this process, so the dashboard needs a way to
|
|
206
|
+
// stop it properly when the user actually asks — and, just as important,
|
|
207
|
+
// a way to tell that case apart from the terminal disappearing.
|
|
208
|
+
stop: runtime.stop,
|
|
205
209
|
});
|
|
206
210
|
return;
|
|
207
211
|
}
|
package/dist/index.js
CHANGED
|
@@ -376,7 +376,7 @@ async function sweepStaleSessionDirs() {
|
|
|
376
376
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
377
377
|
const path = require('path');
|
|
378
378
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
379
|
-
const { RUNTIME_SESSIONS_DIR } = require('./paths');
|
|
379
|
+
const { RUNTIME_SESSIONS_DIR, RUNTIME_LOG_FILE } = require('./paths');
|
|
380
380
|
if (!fs.existsSync(RUNTIME_SESSIONS_DIR))
|
|
381
381
|
return;
|
|
382
382
|
const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;
|
|
@@ -404,30 +404,63 @@ async function sweepStaleSessionDirs() {
|
|
|
404
404
|
catch { /* unreadable dir — fall back to its own mtime */ }
|
|
405
405
|
return newest;
|
|
406
406
|
};
|
|
407
|
-
|
|
407
|
+
// Deleting a session dir un-homes any chat still resuming a session keyed to
|
|
408
|
+
// it, so the names have to be recoverable — a bare count made that class of
|
|
409
|
+
// breakage invisible. But a node that has been up for months sweeps hundreds
|
|
410
|
+
// at once, and one console line each buried the dashboard under a screenful
|
|
411
|
+
// of scrollback on every single start. So: the full list goes to the daemon
|
|
412
|
+
// log, and the terminal gets a sample and the totals.
|
|
413
|
+
const SHOWN = 5;
|
|
414
|
+
const swept = [];
|
|
415
|
+
const failures = [];
|
|
408
416
|
let kept = 0;
|
|
409
417
|
for (const name of fs.readdirSync(RUNTIME_SESSIONS_DIR)) {
|
|
410
418
|
const p = path.join(RUNTIME_SESSIONS_DIR, name);
|
|
419
|
+
let st;
|
|
411
420
|
try {
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
421
|
+
st = fs.statSync(p);
|
|
422
|
+
}
|
|
423
|
+
catch {
|
|
424
|
+
continue; /* unreadable entry */
|
|
425
|
+
}
|
|
426
|
+
if (!st.isDirectory())
|
|
427
|
+
continue;
|
|
428
|
+
if (effectiveMtimeMs(p, st.mtimeMs) >= cutoff) {
|
|
429
|
+
kept++;
|
|
430
|
+
continue;
|
|
431
|
+
}
|
|
432
|
+
try {
|
|
433
|
+
fs.rmSync(p, { recursive: true, force: true });
|
|
434
|
+
swept.push(p);
|
|
435
|
+
}
|
|
436
|
+
catch (err) {
|
|
437
|
+
// A dir we cannot delete comes back every start. It used to be announced
|
|
438
|
+
// as swept each time, forever, with the real error swallowed — so the
|
|
439
|
+
// one line that would explain a home disk filling up never appeared.
|
|
440
|
+
failures.push(`${p}: ${err.message}`);
|
|
426
441
|
}
|
|
427
|
-
catch { /* skip unreadable entry */ }
|
|
428
442
|
}
|
|
429
|
-
if (
|
|
430
|
-
|
|
443
|
+
if (swept.length === 0 && failures.length === 0)
|
|
444
|
+
return;
|
|
445
|
+
// Append before logging: the console line points at this file, so it had
|
|
446
|
+
// better already say what happened by the time anyone opens it.
|
|
447
|
+
try {
|
|
448
|
+
const stamp = new Date().toISOString();
|
|
449
|
+
const body = [
|
|
450
|
+
...swept.map(p => `${stamp} [startup] swept stale session dir: ${p}`),
|
|
451
|
+
...failures.map(l => `${stamp} [startup] could NOT sweep session dir ${l}`),
|
|
452
|
+
].join('\n');
|
|
453
|
+
fs.appendFileSync(RUNTIME_LOG_FILE, `${body}\n`);
|
|
454
|
+
}
|
|
455
|
+
catch { /* the sweep still happened; losing the record is not fatal */ }
|
|
456
|
+
if (swept.length > 0) {
|
|
457
|
+
const sample = swept.slice(0, SHOWN).map(p => path.basename(p));
|
|
458
|
+
const more = swept.length > SHOWN ? `, +${swept.length - SHOWN} more` : '';
|
|
459
|
+
console.log(`[startup] swept ${swept.length} session dir(s) unused for 7d; ${kept} kept`);
|
|
460
|
+
console.log(`[startup] ${sample.join(', ')}${more} — full list in ${RUNTIME_LOG_FILE}`);
|
|
461
|
+
}
|
|
462
|
+
if (failures.length > 0) {
|
|
463
|
+
console.error(`[startup] ${failures.length} stale session dir(s) could not be deleted — first: ${failures[0]}`);
|
|
431
464
|
}
|
|
432
465
|
}
|
|
433
466
|
/** How long a remote restart waits for live turns to finish before handing
|
package/dist/tui/run.d.ts
CHANGED
|
@@ -3,11 +3,38 @@ export declare function shouldRenderTui(env: {
|
|
|
3
3
|
stdinTTY: boolean;
|
|
4
4
|
noTui: boolean;
|
|
5
5
|
}): boolean;
|
|
6
|
+
/** Why the console gave the terminal back. Only `quit` is the user asking
|
|
7
|
+
* to stop; the rest are the terminal being taken away underneath us. */
|
|
8
|
+
export type LeaveReason = 'quit' | 'SIGHUP' | 'SIGTTIN' | 'SIGTTOU' | 'stdin-error';
|
|
9
|
+
/** What giving the terminal back should cost. */
|
|
10
|
+
export type LeaveAction =
|
|
11
|
+
/** Close the screen and go — nothing of ours is running here. */
|
|
12
|
+
'exit'
|
|
13
|
+
/** Drain the in-process daemon first, then go. */
|
|
14
|
+
| 'shutdown'
|
|
15
|
+
/** Close the screen and keep the daemon running headless. */
|
|
16
|
+
| 'detach';
|
|
17
|
+
/**
|
|
18
|
+
* The rule that decides whether this node survives the night.
|
|
19
|
+
*
|
|
20
|
+
* `ainode` runs the daemon in the SAME process as the dashboard, and every
|
|
21
|
+
* teardown used to end in process.exit(0). So a terminal that went away while
|
|
22
|
+
* nobody was watching — a closed window, an ssh drop, a stray read from a
|
|
23
|
+
* background process group — stopped the node, and it stayed stopped until
|
|
24
|
+
* someone re-ran `ainode` the next morning. Only `quit` is a person asking.
|
|
25
|
+
*
|
|
26
|
+
* Pure and exported so the rule is checkable without a TTY.
|
|
27
|
+
*/
|
|
28
|
+
export declare function leaveAction(reason: LeaveReason, ownsDaemon: boolean): LeaveAction;
|
|
6
29
|
export declare function runDashboard(opts: {
|
|
7
30
|
viewerMode: boolean;
|
|
8
31
|
pid: number | null;
|
|
9
32
|
startedAt: number | null;
|
|
10
33
|
version: string;
|
|
34
|
+
/** The in-process daemon's graceful shutdown, when this process owns one.
|
|
35
|
+
* Its presence is also how the screen knows quitting means stopping the
|
|
36
|
+
* node rather than closing a window onto someone else's. */
|
|
37
|
+
stop?: () => Promise<void>;
|
|
11
38
|
}): Promise<void>;
|
|
12
39
|
/** `ainode harnesses` — straight to the harness screen. */
|
|
13
40
|
export declare function runHarnessesTui(): Promise<void>;
|
package/dist/tui/run.js
CHANGED
|
@@ -39,6 +39,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
39
39
|
})();
|
|
40
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
41
|
exports.shouldRenderTui = shouldRenderTui;
|
|
42
|
+
exports.leaveAction = leaveAction;
|
|
42
43
|
exports.runDashboard = runDashboard;
|
|
43
44
|
exports.runHarnessesTui = runHarnessesTui;
|
|
44
45
|
const readline = __importStar(require("readline"));
|
|
@@ -62,6 +63,22 @@ function shouldRenderTui(env) {
|
|
|
62
63
|
const TICK_MS = 250;
|
|
63
64
|
/** Spinner cadence. Cheap now that frames are painted as a diff. */
|
|
64
65
|
const SPIN_MS = 120;
|
|
66
|
+
/**
|
|
67
|
+
* The rule that decides whether this node survives the night.
|
|
68
|
+
*
|
|
69
|
+
* `ainode` runs the daemon in the SAME process as the dashboard, and every
|
|
70
|
+
* teardown used to end in process.exit(0). So a terminal that went away while
|
|
71
|
+
* nobody was watching — a closed window, an ssh drop, a stray read from a
|
|
72
|
+
* background process group — stopped the node, and it stayed stopped until
|
|
73
|
+
* someone re-ran `ainode` the next morning. Only `quit` is a person asking.
|
|
74
|
+
*
|
|
75
|
+
* Pure and exported so the rule is checkable without a TTY.
|
|
76
|
+
*/
|
|
77
|
+
function leaveAction(reason, ownsDaemon) {
|
|
78
|
+
if (!ownsDaemon)
|
|
79
|
+
return 'exit';
|
|
80
|
+
return reason === 'quit' ? 'shutdown' : 'detach';
|
|
81
|
+
}
|
|
65
82
|
/**
|
|
66
83
|
* Own the terminal on behalf of a screen stack.
|
|
67
84
|
*
|
|
@@ -69,7 +86,13 @@ const SPIN_MS = 120;
|
|
|
69
86
|
* screen can hand the TTY to a vendor CLI. It returns the root screen.
|
|
70
87
|
*/
|
|
71
88
|
function createConsole(build, hooks = {}) {
|
|
72
|
-
|
|
89
|
+
// A terminal that has gone away makes every write fail with EIO/EPIPE. In
|
|
90
|
+
// daemon mode the node is running in this very process, so a dead screen
|
|
91
|
+
// must never be the thing that takes it down.
|
|
92
|
+
const painter = (0, render_1.createPainter)(s => { try {
|
|
93
|
+
process.stdout.write(s);
|
|
94
|
+
}
|
|
95
|
+
catch { /* screen gone */ } });
|
|
73
96
|
let quitting = false;
|
|
74
97
|
let inputAttached = false;
|
|
75
98
|
// Building the root screen redraws, and that happens before run() has
|
|
@@ -82,7 +105,7 @@ function createConsole(build, hooks = {}) {
|
|
|
82
105
|
// silent: its timers keep firing otherwise and repaint straight over the
|
|
83
106
|
// child's output.
|
|
84
107
|
let suspended = false;
|
|
85
|
-
const app = (0, app_1.createApp)({ id: 'boot', title: '+Ai Node', render: () => [] }, { onQuit: () => teardown(), onRedraw: () => draw() });
|
|
108
|
+
const app = (0, app_1.createApp)({ id: 'boot', title: '+Ai Node', render: () => [] }, { onQuit: () => teardown('quit'), onRedraw: () => draw() });
|
|
86
109
|
function draw() {
|
|
87
110
|
if (!started || quitting || suspended)
|
|
88
111
|
return;
|
|
@@ -92,7 +115,7 @@ function createConsole(build, hooks = {}) {
|
|
|
92
115
|
void app.handleKey(key);
|
|
93
116
|
}
|
|
94
117
|
function onStdinError() {
|
|
95
|
-
teardown();
|
|
118
|
+
teardown('stdin-error');
|
|
96
119
|
}
|
|
97
120
|
function attachInput() {
|
|
98
121
|
if (inputAttached)
|
|
@@ -116,14 +139,24 @@ function createConsole(build, hooks = {}) {
|
|
|
116
139
|
return;
|
|
117
140
|
process.stdin.off('keypress', onKeypress);
|
|
118
141
|
process.stdin.off('error', onStdinError);
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
142
|
+
// Putting a terminal back that no longer exists throws — and this runs
|
|
143
|
+
// from the very signal handler that means it no longer exists. Unguarded,
|
|
144
|
+
// that throw skips the rest of teardown, so onLeave never gets to say the
|
|
145
|
+
// node is still up and the reason is lost.
|
|
146
|
+
try {
|
|
147
|
+
if (process.stdin.isTTY)
|
|
148
|
+
process.stdin.setRawMode(false);
|
|
149
|
+
}
|
|
150
|
+
catch { /* gone */ }
|
|
151
|
+
try {
|
|
152
|
+
process.stdin.pause();
|
|
153
|
+
}
|
|
154
|
+
catch { /* gone */ }
|
|
122
155
|
inputAttached = false;
|
|
123
156
|
}
|
|
124
157
|
let pollTimer = null;
|
|
125
158
|
let spinTimer = null;
|
|
126
|
-
function teardown() {
|
|
159
|
+
function teardown(reason) {
|
|
127
160
|
if (quitting)
|
|
128
161
|
return;
|
|
129
162
|
quitting = true;
|
|
@@ -132,9 +165,14 @@ function createConsole(build, hooks = {}) {
|
|
|
132
165
|
if (spinTimer)
|
|
133
166
|
clearInterval(spinTimer);
|
|
134
167
|
detachInput();
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
168
|
+
try {
|
|
169
|
+
(0, render_1.altOff)();
|
|
170
|
+
}
|
|
171
|
+
catch { /* the terminal is already gone */ }
|
|
172
|
+
if (hooks.onLeave)
|
|
173
|
+
hooks.onLeave(reason);
|
|
174
|
+
else
|
|
175
|
+
process.exit(0);
|
|
138
176
|
}
|
|
139
177
|
const suspend = async (fn) => {
|
|
140
178
|
suspended = true;
|
|
@@ -157,12 +195,21 @@ function createConsole(build, hooks = {}) {
|
|
|
157
195
|
// background process group earns SIGTTIN, and the default action is to STOP
|
|
158
196
|
// the process — which is what "zsh: suspended (tty input)" is. Stopped mid-
|
|
159
197
|
// draw it still holds the terminal in raw mode, so the session it was
|
|
160
|
-
// sharing degrades too. Stop reading and leave instead
|
|
161
|
-
//
|
|
162
|
-
process
|
|
163
|
-
|
|
198
|
+
// sharing degrades too. Stop reading and leave instead.
|
|
199
|
+
//
|
|
200
|
+
// Leaving is NOT exiting: under `ainode` the daemon IS this process, so what
|
|
201
|
+
// the screen does when it loses its terminal decides whether the node
|
|
202
|
+
// survives the night. onLeave settles that — see runDashboard.
|
|
203
|
+
process.on('SIGTTIN', () => teardown('SIGTTIN'));
|
|
204
|
+
process.on('SIGTTOU', () => teardown('SIGTTOU'));
|
|
164
205
|
// The terminal went away without the read failing first.
|
|
165
|
-
process.on('SIGHUP', teardown);
|
|
206
|
+
process.on('SIGHUP', () => teardown('SIGHUP'));
|
|
207
|
+
// An async write to a dead terminal surfaces as an 'error' event, and an
|
|
208
|
+
// 'error' with no listener is a throw. Same reasoning as the write guard.
|
|
209
|
+
process.stdout.on('error', () => { });
|
|
210
|
+
// Same for stdin, which keeps its listener past detachInput's removal so a
|
|
211
|
+
// late EIO on a torn-down terminal has somewhere to land.
|
|
212
|
+
process.stdin.on('error', () => { });
|
|
166
213
|
app.replace(build(app, suspend));
|
|
167
214
|
return {
|
|
168
215
|
host: app,
|
|
@@ -205,6 +252,9 @@ function createConsole(build, hooks = {}) {
|
|
|
205
252
|
},
|
|
206
253
|
};
|
|
207
254
|
}
|
|
255
|
+
/** How long a deliberate quit waits for the daemon to drain before it stops
|
|
256
|
+
* being a courtesy and starts being a hung terminal. */
|
|
257
|
+
const QUIT_DRAIN_CEILING_MS = 20_000;
|
|
208
258
|
async function runDashboard(opts) {
|
|
209
259
|
const pairing = (0, store_1.readPairing)();
|
|
210
260
|
const data = (0, data_1.createDataLayer)({ token: pairing?.daemonToken ?? '' });
|
|
@@ -240,11 +290,38 @@ async function runDashboard(opts) {
|
|
|
240
290
|
})),
|
|
241
291
|
});
|
|
242
292
|
}, {
|
|
243
|
-
|
|
293
|
+
// The screen and the daemon used to share one fate: every teardown ended
|
|
294
|
+
// in process.exit(0), so a terminal that went away overnight — SIGHUP from
|
|
295
|
+
// a closed window, an ssh drop, a stray background read — took the node
|
|
296
|
+
// down with it and left it dead until someone re-ran `ainode` in the
|
|
297
|
+
// morning. Losing a screen is not a reason to stop working.
|
|
298
|
+
onLeave: (reason) => {
|
|
299
|
+
const stop = opts.stop;
|
|
300
|
+
const action = leaveAction(reason, !opts.viewerMode && Boolean(stop));
|
|
301
|
+
if (action === 'detach') {
|
|
302
|
+
// The terminal is gone, the daemon is not. Keep capturing rather than
|
|
303
|
+
// restoring: the real console writes to an fd that no longer exists,
|
|
304
|
+
// whereas the capture keeps appending to the daemon log — which is now
|
|
305
|
+
// the only place anyone can watch this node from.
|
|
306
|
+
console.log(`[tui] terminal gone (${reason}) — dashboard closed; the node is still running (pid ${process.pid})`);
|
|
307
|
+
console.log(`[tui] follow it with: tail -f ${paths_1.RUNTIME_LOG_FILE}`);
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
244
310
|
logs.restore();
|
|
245
311
|
if (logs.count()) {
|
|
246
312
|
console.log(`${logs.count()} daemon log lines this session — ${paths_1.RUNTIME_LOG_FILE}`);
|
|
247
313
|
}
|
|
314
|
+
if (action === 'exit' || !stop) {
|
|
315
|
+
process.exit(0);
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
// Asked for, so drain properly: in-flight turns get to post their final
|
|
319
|
+
// status and the server is told we are going, rather than discovering it
|
|
320
|
+
// 90s later through a missed heartbeat. The ceiling is there because a
|
|
321
|
+
// wedged drain must not become a terminal that never comes back.
|
|
322
|
+
console.log('stopping the node…');
|
|
323
|
+
setTimeout(() => process.exit(0), QUIT_DRAIN_CEILING_MS).unref?.();
|
|
324
|
+
void stop().finally(() => process.exit(0));
|
|
248
325
|
},
|
|
249
326
|
});
|
|
250
327
|
// The daemon's own numbers don't come from an RPC.
|
package/package.json
CHANGED
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@addai/node",
|
|
3
|
-
"version": "0.30.
|
|
4
|
-
"description": "Daemon that pairs a machine with your +Ai account and runs Claude / Codex / Kimi / Gemini agents on its behalf. Reachable via Supabase from Vault, Entity Studio, or any other +Ai surface.",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"keywords": [
|
|
7
|
-
"addai",
|
|
8
|
-
"entity-studio",
|
|
9
|
-
"claude",
|
|
10
|
-
"codex",
|
|
11
|
-
"kimi",
|
|
12
|
-
"gemini",
|
|
13
|
-
"agent",
|
|
14
|
-
"daemon",
|
|
15
|
-
"supabase",
|
|
16
|
-
"mcp"
|
|
17
|
-
],
|
|
18
|
-
"repository": {
|
|
19
|
-
"type": "git",
|
|
20
|
-
"url": "git+https://github.com/just-AddAi/addai-entity-runtime.git"
|
|
21
|
-
},
|
|
22
|
-
"homepage": "https://github.com/just-AddAi/addai-entity-runtime#readme",
|
|
23
|
-
"bugs": {
|
|
24
|
-
"url": "https://github.com/just-AddAi/addai-entity-runtime/issues"
|
|
25
|
-
},
|
|
26
|
-
"type": "commonjs",
|
|
27
|
-
"main": "dist/index.js",
|
|
28
|
-
"bin": {
|
|
29
|
-
"ainode": "dist/cli.js"
|
|
30
|
-
},
|
|
31
|
-
"publishConfig": {
|
|
32
|
-
"access": "public"
|
|
33
|
-
},
|
|
34
|
-
"files": [
|
|
35
|
-
"dist",
|
|
36
|
-
"scripts",
|
|
37
|
-
"README.md",
|
|
38
|
-
"assets"
|
|
39
|
-
],
|
|
40
|
-
"scripts": {
|
|
41
|
-
"build": "tsc -p tsconfig.json && node scripts/copy-assets.js",
|
|
42
|
-
"start": "node dist/cli.js",
|
|
43
|
-
"dev": "tsc -p tsconfig.json && node dist/cli.js",
|
|
44
|
-
"test": "npm run build && node --test test/*.test.mjs",
|
|
45
|
-
"clean": "node -e \"fs.rmSync('dist',{recursive:true,force:true})\"",
|
|
46
|
-
"postinstall": "node scripts/fix-pty-helper.js",
|
|
47
|
-
"prepublishOnly": "npm run build"
|
|
48
|
-
},
|
|
49
|
-
"engines": {
|
|
50
|
-
"node": ">=18"
|
|
51
|
-
},
|
|
52
|
-
"dependencies": {
|
|
53
|
-
"@addai/node-flows": "^1.0.0",
|
|
54
|
-
"node-pty": "^1.1.0",
|
|
55
|
-
"ws": "^8.21.3"
|
|
56
|
-
},
|
|
57
|
-
"devDependencies": {
|
|
58
|
-
"@types/node": "^20.0.0",
|
|
59
|
-
"@types/ws": "^8.18.1",
|
|
60
|
-
"typescript": "^5.6.0"
|
|
61
|
-
}
|
|
62
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@addai/node",
|
|
3
|
+
"version": "0.30.10",
|
|
4
|
+
"description": "Daemon that pairs a machine with your +Ai account and runs Claude / Codex / Kimi / Gemini agents on its behalf. Reachable via Supabase from Vault, Entity Studio, or any other +Ai surface.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"addai",
|
|
8
|
+
"entity-studio",
|
|
9
|
+
"claude",
|
|
10
|
+
"codex",
|
|
11
|
+
"kimi",
|
|
12
|
+
"gemini",
|
|
13
|
+
"agent",
|
|
14
|
+
"daemon",
|
|
15
|
+
"supabase",
|
|
16
|
+
"mcp"
|
|
17
|
+
],
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/just-AddAi/addai-entity-runtime.git"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://github.com/just-AddAi/addai-entity-runtime#readme",
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/just-AddAi/addai-entity-runtime/issues"
|
|
25
|
+
},
|
|
26
|
+
"type": "commonjs",
|
|
27
|
+
"main": "dist/index.js",
|
|
28
|
+
"bin": {
|
|
29
|
+
"ainode": "dist/cli.js"
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"scripts",
|
|
37
|
+
"README.md",
|
|
38
|
+
"assets"
|
|
39
|
+
],
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsc -p tsconfig.json && node scripts/copy-assets.js",
|
|
42
|
+
"start": "node dist/cli.js",
|
|
43
|
+
"dev": "tsc -p tsconfig.json && node dist/cli.js",
|
|
44
|
+
"test": "npm run build && node --test test/*.test.mjs",
|
|
45
|
+
"clean": "node -e \"fs.rmSync('dist',{recursive:true,force:true})\"",
|
|
46
|
+
"postinstall": "node scripts/fix-pty-helper.js",
|
|
47
|
+
"prepublishOnly": "npm run build"
|
|
48
|
+
},
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=18"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@addai/node-flows": "^1.0.0",
|
|
54
|
+
"node-pty": "^1.1.0",
|
|
55
|
+
"ws": "^8.21.3"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/node": "^20.0.0",
|
|
59
|
+
"@types/ws": "^8.18.1",
|
|
60
|
+
"typescript": "^5.6.0"
|
|
61
|
+
}
|
|
62
|
+
}
|