a2acalling 0.6.13 → 0.6.15
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/package.json +1 -1
- package/scripts/postinstall.js +69 -11
package/package.json
CHANGED
package/scripts/postinstall.js
CHANGED
|
@@ -15,12 +15,19 @@
|
|
|
15
15
|
// so the full onboarding completes unattended: port selection, hostname
|
|
16
16
|
// detection, server start, and disclosure prompt output.
|
|
17
17
|
//
|
|
18
|
-
// 2.
|
|
19
|
-
// internal
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
18
|
+
// 2. Bypassing npm's output capture. npm v7+ pipes lifecycle script stdout
|
|
19
|
+
// AND stderr to an internal buffer, only showing them on failure. This
|
|
20
|
+
// means normal console.log/console.error from postinstall is invisible.
|
|
21
|
+
// To make onboarding output visible:
|
|
22
|
+
//
|
|
23
|
+
// a) Run quickstart with piped stdio, capturing all its output.
|
|
24
|
+
// b) Save the output to a2a-onboarding.txt in the config dir (reliable
|
|
25
|
+
// fallback — agents can always read this file).
|
|
26
|
+
// c) Try /proc/$PPID/fd/2 FIRST (Linux — writes directly to npm's
|
|
27
|
+
// stderr fd, which IS the caller's output stream. Agents capture
|
|
28
|
+
// via pipes, so this is the primary delivery path).
|
|
29
|
+
// d) Try /dev/tty (macOS/non-Linux — interactive terminals).
|
|
30
|
+
// e) Last resort: process.stderr.write (npm may still buffer this).
|
|
24
31
|
//
|
|
25
32
|
// 3. Never fail the install. If quickstart can't launch (e.g. missing node
|
|
26
33
|
// binary edge case), we print a hint and exit 0. A broken postinstall
|
|
@@ -35,16 +42,17 @@ if (process.env.CI || process.env.CONTINUOUS_INTEGRATION) process.exit(0);
|
|
|
35
42
|
if (process.env.DOCKER) process.exit(0);
|
|
36
43
|
if (process.env.npm_config_global !== 'true') process.exit(0);
|
|
37
44
|
|
|
45
|
+
const fs = require('fs');
|
|
38
46
|
const path = require('path');
|
|
39
47
|
const { spawnSync } = require('child_process');
|
|
40
48
|
|
|
41
49
|
const initCwd = process.env.INIT_CWD || process.env.HOME || process.cwd();
|
|
42
50
|
const cliPath = path.join(__dirname, '..', 'bin', 'cli.js');
|
|
43
51
|
|
|
44
|
-
//
|
|
52
|
+
// Run quickstart with piped stdio so we capture all its output.
|
|
45
53
|
// stdin is piped (empty) so all prompts auto-accept their defaults.
|
|
46
54
|
const result = spawnSync(process.execPath, [cliPath, 'quickstart'], {
|
|
47
|
-
stdio: ['pipe',
|
|
55
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
48
56
|
cwd: initCwd,
|
|
49
57
|
env: {
|
|
50
58
|
...process.env,
|
|
@@ -53,10 +61,60 @@ const result = spawnSync(process.execPath, [cliPath, 'quickstart'], {
|
|
|
53
61
|
});
|
|
54
62
|
|
|
55
63
|
if (result.error) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
64
|
+
process.stderr.write('\nCould not auto-launch onboarding.\n');
|
|
65
|
+
process.stderr.write(`Reason: ${result.error.message}\n`);
|
|
66
|
+
process.stderr.write('\nRun manually: a2a quickstart\n\n');
|
|
59
67
|
process.exit(0); // don't fail the install
|
|
60
68
|
}
|
|
61
69
|
|
|
70
|
+
const output = (result.stdout || '').toString() + (result.stderr || '').toString();
|
|
71
|
+
|
|
72
|
+
// ── Always save to file (reliable fallback) ──────────────────────────────
|
|
73
|
+
// Agents can read this after install regardless of output visibility.
|
|
74
|
+
try {
|
|
75
|
+
const configDir = process.env.A2A_CONFIG_DIR
|
|
76
|
+
|| path.join(process.env.HOME || '/root', '.config', 'openclaw');
|
|
77
|
+
if (fs.existsSync(configDir)) {
|
|
78
|
+
fs.writeFileSync(path.join(configDir, 'a2a-onboarding.txt'), output);
|
|
79
|
+
}
|
|
80
|
+
} catch (_) {}
|
|
81
|
+
|
|
82
|
+
// ── Make output visible to the caller ────────────────────────────────────
|
|
83
|
+
// npm pipes BOTH stdout and stderr of lifecycle scripts (v7+), so writing
|
|
84
|
+
// to our own fds goes into npm's buffer. We need to bypass npm entirely.
|
|
85
|
+
|
|
86
|
+
function tryWrite(output) {
|
|
87
|
+
// Strategy 1: /proc/$PPID/fd/2 — Linux, write to npm's stderr directly.
|
|
88
|
+
// npm's stderr IS the caller's stderr (the agent's output stream).
|
|
89
|
+
// This bypasses npm's pipe buffer because we open the fd independently.
|
|
90
|
+
// This is tried FIRST because agents are the primary users — their output
|
|
91
|
+
// is captured via pipes, and /dev/tty would send output to a terminal
|
|
92
|
+
// device they can't read from.
|
|
93
|
+
try {
|
|
94
|
+
const fd = fs.openSync(`/proc/${process.ppid}/fd/2`, 'w');
|
|
95
|
+
fs.writeSync(fd, output);
|
|
96
|
+
fs.closeSync(fd);
|
|
97
|
+
return true;
|
|
98
|
+
} catch (_) {}
|
|
99
|
+
|
|
100
|
+
// Strategy 2: /dev/tty — interactive terminals (macOS, non-Linux).
|
|
101
|
+
// Talks directly to the user's terminal, bypassing npm's pipe.
|
|
102
|
+
try {
|
|
103
|
+
const fd = fs.openSync('/dev/tty', 'w');
|
|
104
|
+
fs.writeSync(fd, output);
|
|
105
|
+
fs.closeSync(fd);
|
|
106
|
+
return true;
|
|
107
|
+
} catch (_) {}
|
|
108
|
+
|
|
109
|
+
// Strategy 3: process.stderr — last resort, npm may still buffer this.
|
|
110
|
+
try {
|
|
111
|
+
process.stderr.write(output);
|
|
112
|
+
return true;
|
|
113
|
+
} catch (_) {}
|
|
114
|
+
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
tryWrite(output);
|
|
119
|
+
|
|
62
120
|
process.exit(result.status || 0);
|