@addai/node 0.30.2 → 0.30.3
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/capabilities.js +8 -1
- package/dist/claude-binary.js +7 -1
- package/dist/claude-print.js +3 -0
- package/dist/codex-spawn.js +3 -0
- package/dist/desktop/learn/browser.js +26 -1
- package/dist/gemini-spawn.js +3 -0
- package/dist/git-identity.js +3 -1
- package/dist/grok-spawn.js +3 -0
- package/dist/kimi-spawn.js +3 -0
- package/dist/projects.js +6 -1
- package/dist/win.js +13 -1
- package/package.json +1 -1
package/dist/capabilities.js
CHANGED
|
@@ -76,7 +76,14 @@ function runCmd(cmd, args, timeoutMs = 5000) {
|
|
|
76
76
|
// a single failing probe must not take down the whole heartbeat.
|
|
77
77
|
try {
|
|
78
78
|
const inv = (0, win_1.resolveCliInvocation)(cmd, args);
|
|
79
|
-
|
|
79
|
+
// windowsHide: this probe runs for every harness on every heartbeat, so
|
|
80
|
+
// without it a Windows node flashes a console window several times a
|
|
81
|
+
// minute, for ever. stderr is captured here rather than discarded — a
|
|
82
|
+
// probe's error text is the diagnosis when a harness is present but
|
|
83
|
+
// broken, unlike the "not found" that whereLookup drops.
|
|
84
|
+
(0, child_process_1.execFile)(inv.file, inv.args, {
|
|
85
|
+
timeout: timeoutMs, maxBuffer: 256 * 1024, windowsHide: true,
|
|
86
|
+
}, (err, stdout, stderr) => {
|
|
80
87
|
resolve({ ok: !err, stdout: (stdout ?? '').trim(), stderr: (stderr ?? '').trim() });
|
|
81
88
|
});
|
|
82
89
|
}
|
package/dist/claude-binary.js
CHANGED
|
@@ -86,7 +86,13 @@ function findClaudeBinary() {
|
|
|
86
86
|
// (extensionless bash script, .cmd, .ps1). Prefer a native .exe
|
|
87
87
|
// (installer builds), then .cmd — never the extensionless one,
|
|
88
88
|
// which CreateProcess can't run.
|
|
89
|
-
|
|
89
|
+
// windowsHide and a discarded stderr — see whereLookup in win.ts for
|
|
90
|
+
// why. execSync goes through cmd.exe, so a miss here costs a console
|
|
91
|
+
// window AND a line of noise in daemon.log every time it runs.
|
|
92
|
+
const lines = (0, child_process_1.execSync)('where claude', {
|
|
93
|
+
encoding: 'utf-8', timeout: 5000, windowsHide: true,
|
|
94
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
95
|
+
})
|
|
90
96
|
.split(/\r?\n/)
|
|
91
97
|
.map(l => l.trim())
|
|
92
98
|
.filter(Boolean);
|
package/dist/claude-print.js
CHANGED
|
@@ -181,6 +181,9 @@ function spawnClaudePrint(input) {
|
|
|
181
181
|
cwd: input.workingDirectory,
|
|
182
182
|
env: { ...process.env, TERM: 'dumb' },
|
|
183
183
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
184
|
+
// No console window. This is headless work on somebody's machine —
|
|
185
|
+
// on Windows a spawn without this flashes a terminal every run.
|
|
186
|
+
windowsHide: true,
|
|
184
187
|
});
|
|
185
188
|
}
|
|
186
189
|
catch (err) {
|
package/dist/codex-spawn.js
CHANGED
|
@@ -301,6 +301,9 @@ function spawnCodex(input) {
|
|
|
301
301
|
cwd: input.workingDirectory,
|
|
302
302
|
env: childEnv,
|
|
303
303
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
304
|
+
// No console window. This is headless work on somebody's machine —
|
|
305
|
+
// on Windows a spawn without this flashes a terminal every run.
|
|
306
|
+
windowsHide: true,
|
|
304
307
|
});
|
|
305
308
|
}
|
|
306
309
|
catch (err) {
|
|
@@ -87,6 +87,31 @@ exports.WRAPPER_PATH = '/usr/local/bin/browser';
|
|
|
87
87
|
* so the loop cannot be rebuilt even if something else recreates the shape.
|
|
88
88
|
*/
|
|
89
89
|
exports.WRAPPER_MARKER = 'Written by @addai/node';
|
|
90
|
+
/**
|
|
91
|
+
* The first-run flow, off.
|
|
92
|
+
*
|
|
93
|
+
* ⚠️ Without these you do not get a browser. You get Chrome's first-run
|
|
94
|
+
* DIALOGS — the terms of service, then "make Chrome your default" — each one a
|
|
95
|
+
* separate top-level X window. Over xpra, which forwards windows one at a
|
|
96
|
+
* time, that is what lands on somebody's desktop: a 610x564 dialog, then a
|
|
97
|
+
* 490x162 one, and never the browser behind them.
|
|
98
|
+
*
|
|
99
|
+
* Worse, they are modal and they are traps. Escape on the terms dialog means
|
|
100
|
+
* DECLINE, and Chrome exits — so "close that popup" closed the whole thing,
|
|
101
|
+
* and an entity typing into what it assumed was a search box was typing into
|
|
102
|
+
* a consent prompt.
|
|
103
|
+
*
|
|
104
|
+
* Every container starts with a fresh profile, so this happened on every
|
|
105
|
+
* desktop, every time, and only ever looked like the browser being broken.
|
|
106
|
+
*
|
|
107
|
+
* The crash bubble is the same class of problem: any unclean exit — a rebuild,
|
|
108
|
+
* a killed container — and the next launch opens with "Restore pages?" over
|
|
109
|
+
* the top of whatever was asked for.
|
|
110
|
+
*
|
|
111
|
+
* Verified on a live container: with these flags the first window is
|
|
112
|
+
* 1918x1078 with a tab strip and an address bar, instead of a dialog.
|
|
113
|
+
*/
|
|
114
|
+
const FIRST_RUN = ' --no-first-run --no-default-browser-check --hide-crash-restore-bubble';
|
|
90
115
|
/** The in-container script that signs the browser in. Beside the extension,
|
|
91
116
|
* under the same bind mount, so it arrives by the same route. */
|
|
92
117
|
exports.SEED_SCRIPT = '/conf/vault/vault-seed.mjs';
|
|
@@ -117,7 +142,7 @@ function wrapperScript(realBrowser, extensionDir) {
|
|
|
117
142
|
return `#!/bin/sh
|
|
118
143
|
# Written by @addai/node so +Ai Learn can watch this browser${extensionDir ? ' and the +Ai Vault can fill logins in it' : ''}.
|
|
119
144
|
# Removing it costs you the page detail in a lesson${extensionDir ? ' and vault autofill' : ''} and nothing else.
|
|
120
|
-
${seed}exec ${realBrowser} --remote-debugging-port=${exports.DEBUG_PORT} --remote-debugging-address=127.0.0.1${ext} "$@"
|
|
145
|
+
${seed}exec ${realBrowser} --remote-debugging-port=${exports.DEBUG_PORT} --remote-debugging-address=127.0.0.1${FIRST_RUN}${ext} "$@"
|
|
121
146
|
`;
|
|
122
147
|
}
|
|
123
148
|
/** Is what is on disk already what we would write? Exact match, so a change to
|
package/dist/gemini-spawn.js
CHANGED
|
@@ -357,6 +357,9 @@ function spawnGemini(input) {
|
|
|
357
357
|
cwd: input.workingDirectory,
|
|
358
358
|
env: childEnv,
|
|
359
359
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
360
|
+
// No console window. This is headless work on somebody's machine —
|
|
361
|
+
// on Windows a spawn without this flashes a terminal every run.
|
|
362
|
+
windowsHide: true,
|
|
360
363
|
});
|
|
361
364
|
}
|
|
362
365
|
catch (err) {
|
package/dist/git-identity.js
CHANGED
|
@@ -66,7 +66,9 @@ async function applyGitIdentity(dir, requestId, token) {
|
|
|
66
66
|
if (!ident?.configured || !ident.author_name || !ident.author_email)
|
|
67
67
|
return;
|
|
68
68
|
const git = (args) => new Promise((resolve) => {
|
|
69
|
-
(0, child_process_1.execFile)('git', ['-C', dir, ...args],
|
|
69
|
+
(0, child_process_1.execFile)('git', ['-C', dir, ...args],
|
|
70
|
+
// Headless: no console window on Windows.
|
|
71
|
+
{ timeout: 10_000, windowsHide: true }, () => resolve());
|
|
70
72
|
});
|
|
71
73
|
// Repo-local only — never touch the machine's global config, which other
|
|
72
74
|
// entities and the human owner share.
|
package/dist/grok-spawn.js
CHANGED
|
@@ -349,6 +349,9 @@ function spawnGrok(input) {
|
|
|
349
349
|
cwd: input.workingDirectory,
|
|
350
350
|
env: childEnv,
|
|
351
351
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
352
|
+
// No console window. This is headless work on somebody's machine —
|
|
353
|
+
// on Windows a spawn without this flashes a terminal every run.
|
|
354
|
+
windowsHide: true,
|
|
352
355
|
});
|
|
353
356
|
}
|
|
354
357
|
catch (err) {
|
package/dist/kimi-spawn.js
CHANGED
|
@@ -390,6 +390,9 @@ function spawnKimi(input) {
|
|
|
390
390
|
cwd: input.workingDirectory,
|
|
391
391
|
env: childEnv,
|
|
392
392
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
393
|
+
// No console window. This is headless work on somebody's machine —
|
|
394
|
+
// on Windows a spawn without this flashes a terminal every run.
|
|
395
|
+
windowsHide: true,
|
|
393
396
|
});
|
|
394
397
|
}
|
|
395
398
|
catch (err) {
|
package/dist/projects.js
CHANGED
|
@@ -105,7 +105,12 @@ function projectDir(p) {
|
|
|
105
105
|
}
|
|
106
106
|
function run(cmd, args, opts = {}) {
|
|
107
107
|
return new Promise(resolve => {
|
|
108
|
-
(0, child_process_1.execFile)(cmd, args, {
|
|
108
|
+
(0, child_process_1.execFile)(cmd, args, {
|
|
109
|
+
cwd: opts.cwd, timeout: opts.timeoutMs ?? 5 * 60_000,
|
|
110
|
+
maxBuffer: 4 * 1024 * 1024,
|
|
111
|
+
// Headless: no console window on Windows.
|
|
112
|
+
windowsHide: true,
|
|
113
|
+
}, (err, stdout, stderr) => {
|
|
109
114
|
resolve({ ok: !err, stdout: stdout.toString(), stderr: stderr.toString() });
|
|
110
115
|
});
|
|
111
116
|
});
|
package/dist/win.js
CHANGED
|
@@ -91,7 +91,19 @@ function whereLookup(name) {
|
|
|
91
91
|
if (!exports.IS_WINDOWS)
|
|
92
92
|
return null;
|
|
93
93
|
try {
|
|
94
|
-
|
|
94
|
+
// ⚠️ windowsHide, and stderr thrown away. Both for the same reason: this
|
|
95
|
+
// runs for every CLI we look for, on a timer, and most of them are not
|
|
96
|
+
// installed. Without windowsHide each miss flashes a console window on
|
|
97
|
+
// the user's screen; without the stdio the miss writes
|
|
98
|
+
//
|
|
99
|
+
// INFO: Could not find files for the given pattern(s).
|
|
100
|
+
//
|
|
101
|
+
// to our stderr, and daemon.log fills with nothing else. "Not found" is
|
|
102
|
+
// the return value here, not an event worth reporting.
|
|
103
|
+
const out = (0, child_process_1.execFileSync)('where', [name], {
|
|
104
|
+
encoding: 'utf8', timeout: 5000, windowsHide: true,
|
|
105
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
106
|
+
});
|
|
95
107
|
const lines = out.split(/\r?\n/).map(l => l.trim()).filter(Boolean);
|
|
96
108
|
const pick = lines.find(l => /\.exe$/i.test(l)) ??
|
|
97
109
|
lines.find(l => /\.cmd$/i.test(l)) ??
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@addai/node",
|
|
3
|
-
"version": "0.30.
|
|
3
|
+
"version": "0.30.3",
|
|
4
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
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|