@bridge4dev/runner 0.49.0 → 0.50.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/agent-versions.d.ts +33 -2
- package/dist/agent-versions.js +29 -5
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/agent-versions.d.ts
CHANGED
|
@@ -58,8 +58,39 @@ export interface ProbeResult {
|
|
|
58
58
|
stdout: string;
|
|
59
59
|
stderr: string;
|
|
60
60
|
}
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
export interface ProbeOptions {
|
|
62
|
+
/**
|
|
63
|
+
* Keep the output of a command that exited non-zero.
|
|
64
|
+
*
|
|
65
|
+
* **This is the bug the flag exists for, and it is worth stating in full.**
|
|
66
|
+
* `codex doctor --json` exits 1 whenever ANY of its checks fails — and three
|
|
67
|
+
* of them are network checks (`network.provider_reachability`,
|
|
68
|
+
* `network.websocket_reachability`, `updates.status`) that have nothing to
|
|
69
|
+
* do with the question we are asking. Measured on a live machine
|
|
70
|
+
* (codex-cli 0.153.4): with the network reachable, exit 0; with it blocked,
|
|
71
|
+
* **exit 1 while `runtime.provenance` still reports `status: ok` and
|
|
72
|
+
* `install method: npm (…)` on stdout**.
|
|
73
|
+
*
|
|
74
|
+
* So a passing hiccup on somebody's dev server used to throw away an answer
|
|
75
|
+
* we already held, the machine reported «install method unknown», and the
|
|
76
|
+
* «Update» button disappeared from that agent's row for the hour the
|
|
77
|
+
* measurement is cached. It came back on its own later, which is why it read
|
|
78
|
+
* as a permanent property of three machines rather than as a fault.
|
|
79
|
+
*
|
|
80
|
+
* A verdict about the machine's health is not a verdict about whether the
|
|
81
|
+
* command told us what we asked. Timeouts and «no such binary» are still
|
|
82
|
+
* failures — those really are «no answer».
|
|
83
|
+
*/
|
|
84
|
+
tolerateExitCode?: boolean;
|
|
85
|
+
}
|
|
86
|
+
/** Run one probe. Rejects on a timeout, a missing binary, or (by default) a non-zero exit. */
|
|
87
|
+
export type ProbeRunner = (file: string, argv: readonly string[], timeoutMs: number, options?: ProbeOptions) => Promise<ProbeResult>;
|
|
88
|
+
/**
|
|
89
|
+
* Exported for its own tests: the interesting behaviour of this function is
|
|
90
|
+
* entirely in how it reads `execFile`'s error, and a stub `ProbeRunner` — which
|
|
91
|
+
* is what every other test here uses — cannot reproduce that by construction.
|
|
92
|
+
*/
|
|
93
|
+
export declare const runProbe: ProbeRunner;
|
|
63
94
|
/**
|
|
64
95
|
* Fold whatever an agent calls its install method into the five values the
|
|
65
96
|
* product reasons about.
|
package/dist/agent-versions.js
CHANGED
|
@@ -26,12 +26,30 @@ let cached = null;
|
|
|
26
26
|
export function invalidateAgentVersions() {
|
|
27
27
|
cached = null;
|
|
28
28
|
}
|
|
29
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Exported for its own tests: the interesting behaviour of this function is
|
|
31
|
+
* entirely in how it reads `execFile`'s error, and a stub `ProbeRunner` — which
|
|
32
|
+
* is what every other test here uses — cannot reproduce that by construction.
|
|
33
|
+
*/
|
|
34
|
+
export const runProbe = (file, argv, timeoutMs, options) => new Promise((resolve, reject) => {
|
|
30
35
|
const child = execFile(file, [...argv], { timeout: timeoutMs, maxBuffer: PROBE_MAX_BUFFER }, (error, stdout, stderr) => {
|
|
31
|
-
if (error)
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
if (!error) {
|
|
37
|
+
resolve({ stdout, stderr });
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
/*
|
|
41
|
+
* `killed` is how Node reports the timeout it was given, and a process
|
|
42
|
+
* we killed produced a TRUNCATED page of JSON — parsing that would be
|
|
43
|
+
* reading half an answer. A missing binary never runs at all and has no
|
|
44
|
+
* numeric exit code, so it falls through to `reject` too.
|
|
45
|
+
*/
|
|
46
|
+
const exited = typeof error.code === 'number';
|
|
47
|
+
const killed = error.killed === true;
|
|
48
|
+
if (options?.tolerateExitCode && exited && !killed) {
|
|
34
49
|
resolve({ stdout, stderr });
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
reject(error);
|
|
35
53
|
});
|
|
36
54
|
// `claude doctor` reads stdin. An `execFile` child inherits an open pipe
|
|
37
55
|
// nobody ever writes to, so without this EOF the probe would sit there
|
|
@@ -117,10 +135,16 @@ export async function measureAgent(runtime, run = runProbe) {
|
|
|
117
135
|
}
|
|
118
136
|
// The install method is a nice-to-have: it decides whether a BUTTON appears,
|
|
119
137
|
// never whether the version is shown. A doctor that failed leaves `unknown`.
|
|
138
|
+
//
|
|
139
|
+
// `tolerateExitCode` — see `ProbeOptions`. The diagnostics command grades the
|
|
140
|
+
// whole machine and fails its own exit code over an unreachable endpoint,
|
|
141
|
+
// while answering our question perfectly on stdout.
|
|
120
142
|
let managedBy = 'unknown';
|
|
121
143
|
try {
|
|
122
144
|
const probe = runtime.managedByProbe;
|
|
123
|
-
const { stdout, stderr } = await run(binary, probe.argv, PROBE_TIMEOUT_MS
|
|
145
|
+
const { stdout, stderr } = await run(binary, probe.argv, PROBE_TIMEOUT_MS, {
|
|
146
|
+
tolerateExitCode: true,
|
|
147
|
+
});
|
|
124
148
|
const output = `${stdout}\n${stderr}`;
|
|
125
149
|
const source = probe.jsonPath ? readJsonPath(stdout, probe.jsonPath) : output;
|
|
126
150
|
managedBy = normalizeManagedBy(source ? matchProbe(probe, source) : null);
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const RUNNER_VERSION = "0.
|
|
1
|
+
export declare const RUNNER_VERSION = "0.50.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
package/package.json
CHANGED