@miraland-labs/conduit-bridge 0.16.27 → 0.16.28
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/ensure-test-evidence.js +43 -7
- package/package.json +2 -2
|
@@ -97,6 +97,48 @@ export async function captureVerificationFailure(input) {
|
|
|
97
97
|
// Every bounded command passed (or none could start): agent failed for another reason.
|
|
98
98
|
return null;
|
|
99
99
|
}
|
|
100
|
+
/** Longest failure detail Bridge will attach. Enough to diagnose; short enough to store and read. */
|
|
101
|
+
export const FAILURE_DETAIL_MAX_CHARS = 4_000;
|
|
102
|
+
/** Leading lines kept for orientation before the elision. */
|
|
103
|
+
const FAILURE_DETAIL_HEAD_LINES = 3;
|
|
104
|
+
/**
|
|
105
|
+
* A failure detail that keeps the part which explains the failure.
|
|
106
|
+
*
|
|
107
|
+
* This used to keep the first 100 lines and then the first 2,000 characters of the join. A failing
|
|
108
|
+
* command explains itself at the **end** — the assertion, the stack, the summary line, and the exit
|
|
109
|
+
* code — so head-truncation discarded exactly the evidence and kept a screen of `... ok`. A real
|
|
110
|
+
* incident cost three attempts on one task because every report looked like a passing test run cut
|
|
111
|
+
* short, and nobody could see the actual error.
|
|
112
|
+
*
|
|
113
|
+
* So: the command line for orientation, a few opening lines, then the **tail**, and the exit code
|
|
114
|
+
* always. What was dropped is stated rather than silently vanishing, because a reader must be able
|
|
115
|
+
* to tell a short failure from a truncated one.
|
|
116
|
+
*/
|
|
117
|
+
export function boundedFailureDetail(command, stdoutLines, stderrLines, code, maxChars = FAILURE_DETAIL_MAX_CHARS) {
|
|
118
|
+
const cap = (line) => (line.length > 500 ? `${line.slice(0, 500)}…` : line);
|
|
119
|
+
const body = [...stdoutLines, ...stderrLines].map(cap);
|
|
120
|
+
const first = `$ ${command}`;
|
|
121
|
+
const last = `exit ${code}`;
|
|
122
|
+
// The exit code is never a candidate for elision: it is the one line that always carries meaning.
|
|
123
|
+
const fixed = `${first}\n${last}`.length;
|
|
124
|
+
const budget = Math.max(0, maxChars - fixed - 1);
|
|
125
|
+
const head = body.slice(0, FAILURE_DETAIL_HEAD_LINES);
|
|
126
|
+
const rest = body.slice(FAILURE_DETAIL_HEAD_LINES);
|
|
127
|
+
const tail = [];
|
|
128
|
+
let used = head.join("\n").length;
|
|
129
|
+
for (let index = rest.length - 1; index >= 0; index -= 1) {
|
|
130
|
+
const line = rest[index];
|
|
131
|
+
if (used + line.length + 1 > budget)
|
|
132
|
+
break;
|
|
133
|
+
tail.unshift(line);
|
|
134
|
+
used += line.length + 1;
|
|
135
|
+
}
|
|
136
|
+
const dropped = rest.length - tail.length;
|
|
137
|
+
const middle = dropped > 0
|
|
138
|
+
? [...head, `… ${dropped} line${dropped === 1 ? "" : "s"} omitted …`, ...tail]
|
|
139
|
+
: [...head, ...tail];
|
|
140
|
+
return [first, ...middle, last].join("\n");
|
|
141
|
+
}
|
|
100
142
|
async function defaultRunCommand(command, workspace) {
|
|
101
143
|
const argv = argvForBoundedCommand(command);
|
|
102
144
|
const bin = argv[0];
|
|
@@ -175,13 +217,7 @@ export async function ensureTestEvidence(input) {
|
|
|
175
217
|
const stderrLines = result.stderr.trim() ? result.stderr.trim().split("\n") : [];
|
|
176
218
|
if (result.code !== 0) {
|
|
177
219
|
// Prefix must match FINALIZE_CONTRACT_PATTERN ("Agent report") — not Bridge-fault laundering.
|
|
178
|
-
|
|
179
|
-
`$ ${command}`,
|
|
180
|
-
...stdoutLines,
|
|
181
|
-
...stderrLines,
|
|
182
|
-
`exit ${result.code}`,
|
|
183
|
-
].map((line) => line.slice(0, 4_000)).slice(0, 100);
|
|
184
|
-
throw new Error(`Agent report: Verification failed (${command}): ${failedDetails.join("\n").slice(0, 2_000)}`);
|
|
220
|
+
throw new Error(`Agent report: Verification failed (${command}): ${boundedFailureDetail(command, stdoutLines, stderrLines, result.code)}`);
|
|
185
221
|
}
|
|
186
222
|
// Empty exit-0 is not proof — a no-op recipe (`@true`) must not clear required_evidence: test.
|
|
187
223
|
if (stdoutLines.length === 0 && stderrLines.length === 0) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@miraland-labs/conduit-bridge",
|
|
3
|
-
"version": "0.16.
|
|
4
|
-
"description": "Conduit Bridge CLI
|
|
3
|
+
"version": "0.16.28",
|
|
4
|
+
"description": "Conduit Bridge CLI \u2014 join, connect, disconnect, multi-driver lanes, and run Claude Code / Codex / Cursor / OpenCode / Pi / Kiro / Antigravity / Grok Build agents for a Conduit organization",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"conduit": "dist/cli.js"
|