@intutic/gate 2.9.1 → 3.0.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/actions.d.ts +39 -0
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +139 -0
- package/dist/actions.js.map +1 -1
- package/dist/client.d.ts +10 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +19 -0
- package/dist/client.js.map +1 -1
- package/dist/decide.d.ts +269 -0
- package/dist/decide.d.ts.map +1 -0
- package/dist/decide.js +757 -0
- package/dist/decide.js.map +1 -0
- package/dist/decideApi.d.ts +24 -0
- package/dist/decideApi.d.ts.map +1 -0
- package/dist/decideApi.js +32 -0
- package/dist/decideApi.js.map +1 -0
- package/dist/decideEngine.d.ts +195 -0
- package/dist/decideEngine.d.ts.map +1 -0
- package/dist/decideEngine.js +707 -0
- package/dist/decideEngine.js.map +1 -0
- package/dist/decideEvaluate.d.ts +250 -0
- package/dist/decideEvaluate.d.ts.map +1 -0
- package/dist/decideEvaluate.js +504 -0
- package/dist/decideEvaluate.js.map +1 -0
- package/dist/decideHostGuard.d.ts +56 -0
- package/dist/decideHostGuard.d.ts.map +1 -0
- package/dist/decideHostGuard.js +194 -0
- package/dist/decideHostGuard.js.map +1 -0
- package/dist/decideLog.d.ts +287 -0
- package/dist/decideLog.d.ts.map +1 -0
- package/dist/decideLog.js +521 -0
- package/dist/decideLog.js.map +1 -0
- package/dist/decideLogRedaction.d.ts +17 -0
- package/dist/decideLogRedaction.d.ts.map +1 -0
- package/dist/decideLogRedaction.js +33 -0
- package/dist/decideLogRedaction.js.map +1 -0
- package/dist/decideRecord.d.ts +128 -0
- package/dist/decideRecord.d.ts.map +1 -0
- package/dist/decideRecord.js +254 -0
- package/dist/decideRecord.js.map +1 -0
- package/dist/decideSdk.d.ts +86 -0
- package/dist/decideSdk.d.ts.map +1 -0
- package/dist/decideSdk.js +146 -0
- package/dist/decideSdk.js.map +1 -0
- package/dist/dsh.d.ts.map +1 -1
- package/dist/dsh.js +6 -1
- package/dist/dsh.js.map +1 -1
- package/dist/errors.d.ts +26 -2
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +38 -1
- package/dist/errors.js.map +1 -1
- package/dist/gate.d.ts +85 -1
- package/dist/gate.d.ts.map +1 -1
- package/dist/gate.js +314 -18
- package/dist/gate.js.map +1 -1
- package/dist/gateRuleRecord.d.ts +244 -0
- package/dist/gateRuleRecord.d.ts.map +1 -0
- package/dist/gateRuleRecord.js +459 -0
- package/dist/gateRuleRecord.js.map +1 -0
- package/dist/harness.d.ts.map +1 -1
- package/dist/harness.js +22 -10
- package/dist/harness.js.map +1 -1
- package/dist/index.d.ts +14 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/lanes.d.ts +94 -0
- package/dist/lanes.d.ts.map +1 -0
- package/dist/lanes.js +150 -0
- package/dist/lanes.js.map +1 -0
- package/dist/limits.d.ts +6 -0
- package/dist/limits.d.ts.map +1 -1
- package/dist/limits.js +6 -0
- package/dist/limits.js.map +1 -1
- package/dist/refusalDetail.d.ts +58 -0
- package/dist/refusalDetail.d.ts.map +1 -0
- package/dist/refusalDetail.js +121 -0
- package/dist/refusalDetail.js.map +1 -0
- package/dist/scopeMatch.d.ts +156 -0
- package/dist/scopeMatch.d.ts.map +1 -0
- package/dist/scopeMatch.js +438 -0
- package/dist/scopeMatch.js.map +1 -0
- package/dist/snapshot.d.ts +51 -3
- package/dist/snapshot.d.ts.map +1 -1
- package/dist/snapshot.js +86 -13
- package/dist/snapshot.js.map +1 -1
- package/dist/testOutcome.d.ts +164 -0
- package/dist/testOutcome.d.ts.map +1 -0
- package/dist/testOutcome.js +439 -0
- package/dist/testOutcome.js.map +1 -0
- package/dist/wrapTools.d.ts +7 -1
- package/dist/wrapTools.d.ts.map +1 -1
- package/dist/wrapTools.js +30 -2
- package/dist/wrapTools.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Did the tests pass? The deciding function behind the qualified ordering
|
|
3
|
+
* rule `requires_before: action:run_tests[ok] -> action:deploy`, and the
|
|
4
|
+
* per-session state the gates keep of it.
|
|
5
|
+
*
|
|
6
|
+
* {@link decideTestOutcome} reads what a surface saw of one test run (an exit
|
|
7
|
+
* code, an error flag, a success flag, the output) and says `ok`, `failed` or
|
|
8
|
+
* `unknown`, in this order:
|
|
9
|
+
*
|
|
10
|
+
* 1. an integer exit code other than 0, `isError === true` or
|
|
11
|
+
* `success === false`: failed;
|
|
12
|
+
* 2. any runner summary in the output that reports failures or errors: failed;
|
|
13
|
+
* 3. a summary that says no tests ran (`no tests ran`, `0 passed`, `0 total`,
|
|
14
|
+
* `0 passing`, `0 examples`) while no summary counts a pass: failed
|
|
15
|
+
* (`no_tests`);
|
|
16
|
+
* 4. exit code 0: ok;
|
|
17
|
+
* 5. no exit code, and at least one summary counts a pass: ok;
|
|
18
|
+
* 6. anything else: unknown.
|
|
19
|
+
*
|
|
20
|
+
* Unknown leaves a qualified rule unmet, as a failure does: a result that
|
|
21
|
+
* cannot be read is not a pass.
|
|
22
|
+
*
|
|
23
|
+
* {@link extractExitCode} reads an exit code out of text, for a surface that
|
|
24
|
+
* reports only text (Codex's JSON shell output, Claude Code's `Exit code N`
|
|
25
|
+
* error results, `exit status N`, `Process exited with code N`).
|
|
26
|
+
*
|
|
27
|
+
* Runner summaries are read line by line from the last
|
|
28
|
+
* {@link TEST_OUTPUT_TAIL_BYTES} bytes of the output, each line cut to
|
|
29
|
+
* {@link TEST_OUTPUT_LINE_BYTES} bytes, carriage returns and ANSI colour
|
|
30
|
+
* sequences removed. Every pattern is anchored and has no nested quantifier;
|
|
31
|
+
* a summary's counts are read by splitting it, not by a regex, so the whole
|
|
32
|
+
* read is linear in the output.
|
|
33
|
+
*
|
|
34
|
+
* The outcome state ({@link OutcomeState}) is what a gate keeps per session:
|
|
35
|
+
* the latest outcome per outcome token, with when it was recorded, whether a
|
|
36
|
+
* file changed after it (a pass describes the code it ran
|
|
37
|
+
* against, so a later write makes it stale), and whether any other call
|
|
38
|
+
* completed after it (for `~>`).
|
|
39
|
+
*
|
|
40
|
+
* Self-contained (no imports, no module state the emitted source does not
|
|
41
|
+
* carry) so `@intutic/gate` keeps a byte-identical copy and the JavaScript
|
|
42
|
+
* hook gates embed {@link TEST_OUTCOME_JS_SOURCE}. The Python port is
|
|
43
|
+
* `intutic_clawde/gate/test_outcome.py`, the Rust one
|
|
44
|
+
* `packages/proxy/src/plugins/anomaly/outcome.rs`; all of them run
|
|
45
|
+
* `fixtures/test-outcome-vectors.json`.
|
|
46
|
+
*
|
|
47
|
+
* @module
|
|
48
|
+
*/
|
|
49
|
+
/** The tokens a `[ok]` qualifier may stand on. */
|
|
50
|
+
export const OUTCOME_TOKENS = ['action:run_tests'];
|
|
51
|
+
/** The qualifiers there are. */
|
|
52
|
+
export const OUTCOME_QUALIFIERS = ['ok'];
|
|
53
|
+
/** The one qualified token there is. */
|
|
54
|
+
export const QUALIFIED_TOKEN_RE = /^action:run_tests\[ok\]$/;
|
|
55
|
+
/** How much of a run's output the summaries are read from: its last 64 KiB. */
|
|
56
|
+
export const TEST_OUTPUT_TAIL_BYTES = 65536;
|
|
57
|
+
/** Each line is cut to this many bytes before it is matched. */
|
|
58
|
+
export const TEST_OUTPUT_LINE_BYTES = 1024;
|
|
59
|
+
/** The longest output whose JSON form is parsed for an exit code. */
|
|
60
|
+
export const TEST_OUTPUT_JSON_MAX_CHARS = 1048576;
|
|
61
|
+
/** An outcome older than this is ignored: a day. */
|
|
62
|
+
export const OUTCOME_STATE_TTL_MS = 86400000;
|
|
63
|
+
/** The last `maxBytes` bytes of `s` as UTF-8, starting on a character. */
|
|
64
|
+
function testOutcomeUtf8Tail(s, maxBytes) {
|
|
65
|
+
let bytes = 0;
|
|
66
|
+
let i = s.length;
|
|
67
|
+
while (i > 0) {
|
|
68
|
+
const c = s.charCodeAt(i - 1);
|
|
69
|
+
let n = 3;
|
|
70
|
+
let w = 1;
|
|
71
|
+
if (c < 0x80)
|
|
72
|
+
n = 1;
|
|
73
|
+
else if (c < 0x800)
|
|
74
|
+
n = 2;
|
|
75
|
+
else if (c >= 0xdc00 && c <= 0xdfff && i > 1) {
|
|
76
|
+
const h = s.charCodeAt(i - 2);
|
|
77
|
+
if (h >= 0xd800 && h <= 0xdbff) {
|
|
78
|
+
n = 4;
|
|
79
|
+
w = 2;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (bytes + n > maxBytes)
|
|
83
|
+
break;
|
|
84
|
+
bytes += n;
|
|
85
|
+
i -= w;
|
|
86
|
+
}
|
|
87
|
+
return s.slice(i);
|
|
88
|
+
}
|
|
89
|
+
/** The first `maxBytes` bytes of `s` as UTF-8, ending on a character. */
|
|
90
|
+
function testOutcomeUtf8Head(s, maxBytes) {
|
|
91
|
+
let bytes = 0;
|
|
92
|
+
let i = 0;
|
|
93
|
+
while (i < s.length) {
|
|
94
|
+
const c = s.charCodeAt(i);
|
|
95
|
+
let n = 3;
|
|
96
|
+
let w = 1;
|
|
97
|
+
if (c < 0x80)
|
|
98
|
+
n = 1;
|
|
99
|
+
else if (c < 0x800)
|
|
100
|
+
n = 2;
|
|
101
|
+
else if (c >= 0xd800 && c <= 0xdbff && i + 1 < s.length) {
|
|
102
|
+
const l = s.charCodeAt(i + 1);
|
|
103
|
+
if (l >= 0xdc00 && l <= 0xdfff) {
|
|
104
|
+
n = 4;
|
|
105
|
+
w = 2;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (bytes + n > maxBytes)
|
|
109
|
+
break;
|
|
110
|
+
bytes += n;
|
|
111
|
+
i += w;
|
|
112
|
+
}
|
|
113
|
+
return s.slice(0, i);
|
|
114
|
+
}
|
|
115
|
+
/** The lines of `text`, each without carriage returns or ANSI sequences and cut to {@link TEST_OUTPUT_LINE_BYTES} bytes. */
|
|
116
|
+
function testOutcomeLines(text) {
|
|
117
|
+
const out = [];
|
|
118
|
+
for (const raw of text.split('\n')) {
|
|
119
|
+
// eslint-disable-next-line no-control-regex -- removing control characters is the point
|
|
120
|
+
const line = testOutcomeUtf8Head(raw, 1024).replace(/\r/g, '').replace(/\x1b\[[0-9;?]*[A-Za-z]/g, '');
|
|
121
|
+
out.push(line);
|
|
122
|
+
}
|
|
123
|
+
return out;
|
|
124
|
+
}
|
|
125
|
+
/** A JSON integer exit code, or null. */
|
|
126
|
+
function testOutcomeIntegerOrNull(v) {
|
|
127
|
+
return typeof v === 'number' && Number.isSafeInteger(v) ? v : null;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* The exit code a run's text reports, or null. A whole-output JSON object
|
|
131
|
+
* with `metadata.exit_code`, else `exit_code`, else `exitCode`; otherwise the
|
|
132
|
+
* first line, of the first 64 KiB then the last 64 KiB, that is
|
|
133
|
+
* `Exit code N` / `Exit code: N` (any case), `exit status N`, or begins
|
|
134
|
+
* `Process exited with code N` / `Command exited with code N`.
|
|
135
|
+
*/
|
|
136
|
+
export function extractExitCode(output) {
|
|
137
|
+
if (typeof output !== 'string' || output === '')
|
|
138
|
+
return null;
|
|
139
|
+
const trimmed = output.trim();
|
|
140
|
+
if (trimmed.length <= 1048576 && trimmed.charAt(0) === '{' && trimmed.charAt(trimmed.length - 1) === '}') {
|
|
141
|
+
try {
|
|
142
|
+
const parsed = JSON.parse(trimmed);
|
|
143
|
+
if (parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
144
|
+
const o = parsed;
|
|
145
|
+
const meta = o.metadata;
|
|
146
|
+
if (meta !== null && typeof meta === 'object' && !Array.isArray(meta)) {
|
|
147
|
+
const m = testOutcomeIntegerOrNull(meta.exit_code);
|
|
148
|
+
if (m !== null)
|
|
149
|
+
return m;
|
|
150
|
+
}
|
|
151
|
+
const a = testOutcomeIntegerOrNull(o.exit_code);
|
|
152
|
+
if (a !== null)
|
|
153
|
+
return a;
|
|
154
|
+
const b = testOutcomeIntegerOrNull(o.exitCode);
|
|
155
|
+
if (b !== null)
|
|
156
|
+
return b;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// Not JSON: read the lines.
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
const head = testOutcomeUtf8Head(output, 65536);
|
|
164
|
+
const parts = head.length === output.length ? [head] : [head, testOutcomeUtf8Tail(output.slice(head.length), 65536)];
|
|
165
|
+
for (const part of parts) {
|
|
166
|
+
for (const raw of testOutcomeLines(part)) {
|
|
167
|
+
const line = raw.replace(/^[ \t]+/, '').replace(/[ \t]+$/, '');
|
|
168
|
+
let m = /^exit code:? (-?[0-9]{1,9})$/i.exec(line);
|
|
169
|
+
if (!m)
|
|
170
|
+
m = /^exit status ([0-9]{1,9})$/.exec(line);
|
|
171
|
+
if (!m)
|
|
172
|
+
m = /^(?:Process|Command) exited with code (-?[0-9]{1,9})/.exec(line);
|
|
173
|
+
if (m)
|
|
174
|
+
return Number(m[1]);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
/** `N word` pieces of a summary, split on `,` and `|`: the count of each word. */
|
|
180
|
+
function testOutcomeCounts(text) {
|
|
181
|
+
const counts = {};
|
|
182
|
+
for (const piece of text.split(/[,|]/)) {
|
|
183
|
+
const m = /^([0-9]{1,9}) ([a-z]+)/.exec(piece.replace(/^[ \t]+/, ''));
|
|
184
|
+
if (m)
|
|
185
|
+
counts[m[2]] = (counts[m[2]] ?? 0) + Number(m[1]);
|
|
186
|
+
}
|
|
187
|
+
return counts;
|
|
188
|
+
}
|
|
189
|
+
/** The runner summaries in the last 64 KiB of `output`, in the order they appear (go and mocha folded into one each). */
|
|
190
|
+
export function parseTestSummaries(output) {
|
|
191
|
+
if (typeof output !== 'string' || output === '')
|
|
192
|
+
return [];
|
|
193
|
+
const out = [];
|
|
194
|
+
let go = null;
|
|
195
|
+
let mocha = null;
|
|
196
|
+
for (const line of testOutcomeLines(testOutcomeUtf8Tail(output, 65536))) {
|
|
197
|
+
let m;
|
|
198
|
+
if (/^=+ no tests ran/.test(line)) {
|
|
199
|
+
out.push({ runner: 'pytest', passed: 0, failed: 0, noTests: true });
|
|
200
|
+
}
|
|
201
|
+
else if ((m = /^=+ (.+) in [0-9.]+s.* =+$/.exec(line))) {
|
|
202
|
+
const c = testOutcomeCounts(m[1]);
|
|
203
|
+
if (c.passed === undefined && c.failed === undefined && c.error === undefined && c.errors === undefined)
|
|
204
|
+
continue;
|
|
205
|
+
out.push({ runner: 'pytest', passed: c.passed ?? 0, failed: (c.failed ?? 0) + (c.error ?? 0) + (c.errors ?? 0), noTests: c.passed === 0 });
|
|
206
|
+
}
|
|
207
|
+
else if ((m = /^Tests:[ \t]+(.+)$/.exec(line))) {
|
|
208
|
+
const c = testOutcomeCounts(m[1]);
|
|
209
|
+
out.push({ runner: 'jest', passed: c.passed ?? 0, failed: c.failed ?? 0, noTests: c.passed === 0 || c.total === 0 });
|
|
210
|
+
}
|
|
211
|
+
else if ((m = /^[ \t]*Tests[ \t]+(.+)$/.exec(line))) {
|
|
212
|
+
const c = testOutcomeCounts(m[1]);
|
|
213
|
+
if (c.passed === undefined && c.failed === undefined)
|
|
214
|
+
continue;
|
|
215
|
+
out.push({ runner: 'vitest', passed: c.passed ?? 0, failed: c.failed ?? 0, noTests: c.passed === 0 });
|
|
216
|
+
}
|
|
217
|
+
else if (/^ok[ \t]+[^ \t]+/.test(line)) {
|
|
218
|
+
if (go === null)
|
|
219
|
+
out.push((go = { runner: 'go', passed: 0, failed: 0, noTests: false }));
|
|
220
|
+
go.passed += 1;
|
|
221
|
+
}
|
|
222
|
+
else if (/^FAIL([ \t]|$)/.test(line) || /^--- FAIL:/.test(line)) {
|
|
223
|
+
if (go === null)
|
|
224
|
+
out.push((go = { runner: 'go', passed: 0, failed: 0, noTests: false }));
|
|
225
|
+
go.failed += 1;
|
|
226
|
+
}
|
|
227
|
+
else if ((m = /^test result: (ok|FAILED)\. ([0-9]{1,9}) passed; ([0-9]{1,9}) failed;/.exec(line))) {
|
|
228
|
+
const passed = Number(m[2]);
|
|
229
|
+
const failed = Number(m[3]);
|
|
230
|
+
out.push({ runner: 'cargo', passed, failed: m[1] === 'FAILED' && failed === 0 ? 1 : failed, noTests: passed === 0 });
|
|
231
|
+
}
|
|
232
|
+
else if ((m = /^[ \t]*([0-9]{1,9}) passing/.exec(line))) {
|
|
233
|
+
if (mocha === null)
|
|
234
|
+
out.push((mocha = { runner: 'mocha', passed: 0, failed: 0, noTests: false }));
|
|
235
|
+
mocha.passed += Number(m[1]);
|
|
236
|
+
if (Number(m[1]) === 0)
|
|
237
|
+
mocha.noTests = true;
|
|
238
|
+
}
|
|
239
|
+
else if ((m = /^[ \t]*([0-9]{1,9}) failing/.exec(line))) {
|
|
240
|
+
if (mocha === null)
|
|
241
|
+
out.push((mocha = { runner: 'mocha', passed: 0, failed: 0, noTests: false }));
|
|
242
|
+
mocha.failed += Number(m[1]);
|
|
243
|
+
}
|
|
244
|
+
else if ((m = /^([0-9]{1,9}) examples?, ([0-9]{1,9}) failures?/.exec(line))) {
|
|
245
|
+
const examples = Number(m[1]);
|
|
246
|
+
const failures = Number(m[2]);
|
|
247
|
+
out.push({ runner: 'rspec', passed: Math.max(0, examples - failures), failed: failures, noTests: examples === 0 });
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return out;
|
|
251
|
+
}
|
|
252
|
+
/** The outcome of one test run. See the module doc for the steps. */
|
|
253
|
+
export function decideTestOutcome(input) {
|
|
254
|
+
const exit = typeof input.exitCode === 'number' && Number.isSafeInteger(input.exitCode) ? input.exitCode : null;
|
|
255
|
+
if (exit !== null && exit !== 0)
|
|
256
|
+
return { outcome: 'failed', why: 'exit_code' };
|
|
257
|
+
if (input.isError === true)
|
|
258
|
+
return { outcome: 'failed', why: 'is_error' };
|
|
259
|
+
if (input.success === false)
|
|
260
|
+
return { outcome: 'failed', why: 'success_false' };
|
|
261
|
+
const summaries = parseTestSummaries(input.output);
|
|
262
|
+
let passed = 0;
|
|
263
|
+
let noTests = false;
|
|
264
|
+
for (const s of summaries) {
|
|
265
|
+
if (s.failed > 0)
|
|
266
|
+
return { outcome: 'failed', why: 'summary_failed' };
|
|
267
|
+
passed += s.passed;
|
|
268
|
+
if (s.noTests)
|
|
269
|
+
noTests = true;
|
|
270
|
+
}
|
|
271
|
+
if (passed === 0 && noTests)
|
|
272
|
+
return { outcome: 'failed', why: 'no_tests' };
|
|
273
|
+
if (exit === 0)
|
|
274
|
+
return { outcome: 'ok', why: 'exit_zero' };
|
|
275
|
+
if (passed >= 1)
|
|
276
|
+
return { outcome: 'ok', why: 'summary_passed' };
|
|
277
|
+
return { outcome: 'unknown', why: 'no_signal' };
|
|
278
|
+
}
|
|
279
|
+
// ---------------------------------------------------------------------------
|
|
280
|
+
// The qualifier
|
|
281
|
+
// ---------------------------------------------------------------------------
|
|
282
|
+
/**
|
|
283
|
+
* Why one side of an ordering rule cannot carry the qualifier it carries, or
|
|
284
|
+
* null when it is fine. A side carries a qualifier when it holds `[` or `]`;
|
|
285
|
+
* only `action:run_tests[ok]`, on the left of the arrow, is one. The error
|
|
286
|
+
* names the side as written, quoted as the parser quotes it.
|
|
287
|
+
*/
|
|
288
|
+
export function orderingQualifierError(side, left) {
|
|
289
|
+
if (side.indexOf('[') === -1 && side.indexOf(']') === -1)
|
|
290
|
+
return null;
|
|
291
|
+
if (left && side === 'action:run_tests[ok]')
|
|
292
|
+
return null;
|
|
293
|
+
return JSON.stringify(side) + ': [ok] qualifies only action:run_tests, on the left of ->';
|
|
294
|
+
}
|
|
295
|
+
/** `action:run_tests[ok]` as `{ token: 'action:run_tests', qualifier: 'ok' }`; any other token unqualified. */
|
|
296
|
+
export function splitQualifier(token) {
|
|
297
|
+
return token === 'action:run_tests[ok]' ? { token: 'action:run_tests', qualifier: 'ok' } : { token, qualifier: null };
|
|
298
|
+
}
|
|
299
|
+
/** A state with nothing in it. */
|
|
300
|
+
export function emptyOutcomeState() {
|
|
301
|
+
return { v: 1, outcomes: {} };
|
|
302
|
+
}
|
|
303
|
+
/** The state file's name for one session: the first 32 hex of sha256(harness NUL sessionId), and `.json`. */
|
|
304
|
+
export function outcomeStateFileName(harness, sessionId, sha256Hex) {
|
|
305
|
+
return sha256Hex(harness + '\0' + sessionId).slice(0, 32) + '.json';
|
|
306
|
+
}
|
|
307
|
+
/** A state file's text as a state, or null when it is not one: a damaged file is no state, which leaves every rule unmet. */
|
|
308
|
+
export function parseOutcomeState(text) {
|
|
309
|
+
let v;
|
|
310
|
+
try {
|
|
311
|
+
v = JSON.parse(text);
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
if (v === null || typeof v !== 'object' || Array.isArray(v))
|
|
317
|
+
return null;
|
|
318
|
+
const s = v;
|
|
319
|
+
if (s.v !== 1 || s.outcomes === null || typeof s.outcomes !== 'object' || Array.isArray(s.outcomes))
|
|
320
|
+
return null;
|
|
321
|
+
const outcomes = {};
|
|
322
|
+
for (const key of Object.keys(s.outcomes)) {
|
|
323
|
+
const e = s.outcomes[key];
|
|
324
|
+
if (e === null || typeof e !== 'object' || Array.isArray(e))
|
|
325
|
+
return null;
|
|
326
|
+
const r = e;
|
|
327
|
+
if ((r.o !== 'ok' && r.o !== 'failed' && r.o !== 'unknown') || typeof r.at !== 'number' || !Number.isFinite(r.at))
|
|
328
|
+
return null;
|
|
329
|
+
if (r.why !== undefined && typeof r.why !== 'string')
|
|
330
|
+
return null;
|
|
331
|
+
if (r.changed !== undefined && r.changed !== true)
|
|
332
|
+
return null;
|
|
333
|
+
if (r.later !== undefined && r.later !== true)
|
|
334
|
+
return null;
|
|
335
|
+
outcomes[key] = r;
|
|
336
|
+
}
|
|
337
|
+
return { v: 1, outcomes };
|
|
338
|
+
}
|
|
339
|
+
/** `state` with `token`'s outcome replaced by this run's. */
|
|
340
|
+
export function recordTestOutcome(state, token, decision, atMs) {
|
|
341
|
+
const outcomes = {};
|
|
342
|
+
for (const k of Object.keys(state.outcomes))
|
|
343
|
+
outcomes[k] = state.outcomes[k];
|
|
344
|
+
outcomes[token] = { o: decision.outcome, at: atMs, why: decision.why };
|
|
345
|
+
return { v: 1, outcomes };
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* `state` after another call completed: every entry is no longer adjacent to
|
|
349
|
+
* what comes next, and when the call changed a file (`changedFiles`), a pass
|
|
350
|
+
* before it no longer counts.
|
|
351
|
+
*/
|
|
352
|
+
export function noteCompletedCall(state, changedFiles) {
|
|
353
|
+
const outcomes = {};
|
|
354
|
+
for (const k of Object.keys(state.outcomes)) {
|
|
355
|
+
const e = state.outcomes[k];
|
|
356
|
+
const next = { o: e.o, at: e.at };
|
|
357
|
+
if (e.why !== undefined)
|
|
358
|
+
next.why = e.why;
|
|
359
|
+
if (e.changed || changedFiles)
|
|
360
|
+
next.changed = true;
|
|
361
|
+
next.later = true;
|
|
362
|
+
outcomes[k] = next;
|
|
363
|
+
}
|
|
364
|
+
return { v: 1, outcomes };
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Whether `token`'s latest outcome in `state` meets a qualified rule now:
|
|
368
|
+
* `met` only for an `ok` younger than {@link OUTCOME_STATE_TTL_MS} that no
|
|
369
|
+
* file change followed (and, for `~>`, that no other call followed). A null
|
|
370
|
+
* state (none, or unreadable) is `none`.
|
|
371
|
+
*/
|
|
372
|
+
export function prerequisiteCase(state, token, adjacent, nowMs) {
|
|
373
|
+
const e = state === null ? undefined : state.outcomes[token];
|
|
374
|
+
if (e === undefined || !(nowMs - e.at < 86400000) || e.at > nowMs)
|
|
375
|
+
return { case: 'none', why: null };
|
|
376
|
+
if (e.o === 'failed')
|
|
377
|
+
return { case: 'failed', why: e.why ?? null };
|
|
378
|
+
if (e.o === 'unknown')
|
|
379
|
+
return { case: 'unknown', why: e.why ?? null };
|
|
380
|
+
if (e.changed)
|
|
381
|
+
return { case: 'changed', why: null };
|
|
382
|
+
if (adjacent && e.later)
|
|
383
|
+
return { case: 'not_adjacent', why: null };
|
|
384
|
+
return { case: 'met', why: null };
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* The reason a refusal (`PREREQUISITE_UNMET`) gives, for every case but
|
|
388
|
+
* `met`. `harness` names the surface for `not_observable` and `no_session`.
|
|
389
|
+
* Byte-stable: every port answers with these exact words.
|
|
390
|
+
*/
|
|
391
|
+
export function prerequisiteUnmetReason(first, then, c, why, harness) {
|
|
392
|
+
const head = then + ' needs a passing ' + first + ' first; ';
|
|
393
|
+
switch (c) {
|
|
394
|
+
case 'none':
|
|
395
|
+
return head + 'none ran in this session';
|
|
396
|
+
case 'failed':
|
|
397
|
+
return head + 'the last ' + first + ' failed (' + (why ?? 'failed') + ')';
|
|
398
|
+
case 'unknown':
|
|
399
|
+
return head + 'the result of the last ' + first + ' could not be read; rerun the tests so their summary is visible';
|
|
400
|
+
case 'changed':
|
|
401
|
+
return head + 'files changed after the last passing ' + first + '; rerun the tests';
|
|
402
|
+
case 'not_adjacent':
|
|
403
|
+
return head + then + ' must come directly after it, and another call came between';
|
|
404
|
+
case 'not_observable':
|
|
405
|
+
return head + harness + ' reports no tool results Intutic can read, so a passing run cannot be observed here';
|
|
406
|
+
case 'no_session':
|
|
407
|
+
return head + harness + ' sent no session id, so test results cannot be tied to this session';
|
|
408
|
+
default:
|
|
409
|
+
return '';
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* The functions above as JavaScript source, for the hook gates to embed: the
|
|
414
|
+
* gates run this exact code. A CommonJS build names an exported function
|
|
415
|
+
* `exports.X` inside another; the source defines each as a plain `X`, so that
|
|
416
|
+
* prefix is dropped.
|
|
417
|
+
*/
|
|
418
|
+
export const TEST_OUTCOME_JS_SOURCE = [
|
|
419
|
+
testOutcomeUtf8Tail,
|
|
420
|
+
testOutcomeUtf8Head,
|
|
421
|
+
testOutcomeLines,
|
|
422
|
+
testOutcomeIntegerOrNull,
|
|
423
|
+
extractExitCode,
|
|
424
|
+
testOutcomeCounts,
|
|
425
|
+
parseTestSummaries,
|
|
426
|
+
decideTestOutcome,
|
|
427
|
+
orderingQualifierError,
|
|
428
|
+
splitQualifier,
|
|
429
|
+
emptyOutcomeState,
|
|
430
|
+
outcomeStateFileName,
|
|
431
|
+
parseOutcomeState,
|
|
432
|
+
recordTestOutcome,
|
|
433
|
+
noteCompletedCall,
|
|
434
|
+
prerequisiteCase,
|
|
435
|
+
prerequisiteUnmetReason,
|
|
436
|
+
]
|
|
437
|
+
.map((fn) => fn.toString().replace(/\bexports\./g, ''))
|
|
438
|
+
.join('\n');
|
|
439
|
+
//# sourceMappingURL=testOutcome.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testOutcome.js","sourceRoot":"","sources":["../src/testOutcome.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,kDAAkD;AAClD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,kBAAkB,CAAU,CAAA;AAC3D,gCAAgC;AAChC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,IAAI,CAAU,CAAA;AACjD,wCAAwC;AACxC,MAAM,CAAC,MAAM,kBAAkB,GAAG,0BAA0B,CAAA;AAC5D,+EAA+E;AAC/E,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAA;AAC3C,gEAAgE;AAChE,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAA;AAC1C,qEAAqE;AACrE,MAAM,CAAC,MAAM,0BAA0B,GAAG,OAAO,CAAA;AACjD,oDAAoD;AACpD,MAAM,CAAC,MAAM,oBAAoB,GAAG,QAAQ,CAAA;AAoC5C,0EAA0E;AAC1E,SAAS,mBAAmB,CAAC,CAAS,EAAE,QAAgB;IACtD,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAA;IAChB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QAC7B,IAAI,CAAC,GAAG,CAAC,CAAA;QACT,IAAI,CAAC,GAAG,CAAC,CAAA;QACT,IAAI,CAAC,GAAG,IAAI;YAAE,CAAC,GAAG,CAAC,CAAA;aACd,IAAI,CAAC,GAAG,KAAK;YAAE,CAAC,GAAG,CAAC,CAAA;aACpB,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7C,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YAC7B,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,EAAE,CAAC;gBAC/B,CAAC,GAAG,CAAC,CAAA;gBACL,CAAC,GAAG,CAAC,CAAA;YACP,CAAC;QACH,CAAC;QACD,IAAI,KAAK,GAAG,CAAC,GAAG,QAAQ;YAAE,MAAK;QAC/B,KAAK,IAAI,CAAC,CAAA;QACV,CAAC,IAAI,CAAC,CAAA;IACR,CAAC;IACD,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AACnB,CAAC;AAED,yEAAyE;AACzE,SAAS,mBAAmB,CAAC,CAAS,EAAE,QAAgB;IACtD,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,IAAI,CAAC,GAAG,CAAC,CAAA;IACT,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QACzB,IAAI,CAAC,GAAG,CAAC,CAAA;QACT,IAAI,CAAC,GAAG,CAAC,CAAA;QACT,IAAI,CAAC,GAAG,IAAI;YAAE,CAAC,GAAG,CAAC,CAAA;aACd,IAAI,CAAC,GAAG,KAAK;YAAE,CAAC,GAAG,CAAC,CAAA;aACpB,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;YACxD,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YAC7B,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,EAAE,CAAC;gBAC/B,CAAC,GAAG,CAAC,CAAA;gBACL,CAAC,GAAG,CAAC,CAAA;YACP,CAAC;QACH,CAAC;QACD,IAAI,KAAK,GAAG,CAAC,GAAG,QAAQ;YAAE,MAAK;QAC/B,KAAK,IAAI,CAAC,CAAA;QACV,CAAC,IAAI,CAAC,CAAA;IACR,CAAC;IACD,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACtB,CAAC;AAED,4HAA4H;AAC5H,SAAS,gBAAgB,CAAC,IAAY;IACpC,MAAM,GAAG,GAAa,EAAE,CAAA;IACxB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,wFAAwF;QACxF,MAAM,IAAI,GAAG,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAA;QACrG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAChB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,yCAAyC;AACzC,SAAS,wBAAwB,CAAC,CAAU;IAC1C,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AACpE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,MAAiC;IAC/D,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,EAAE;QAAE,OAAO,IAAI,CAAA;IAC5D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAA;IAC7B,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;QACzG,IAAI,CAAC;YACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YAC3C,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5E,MAAM,CAAC,GAAG,MAAiC,CAAA;gBAC3C,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAA;gBACvB,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;oBACtE,MAAM,CAAC,GAAG,wBAAwB,CAAE,IAAgC,CAAC,SAAS,CAAC,CAAA;oBAC/E,IAAI,CAAC,KAAK,IAAI;wBAAE,OAAO,CAAC,CAAA;gBAC1B,CAAC;gBACD,MAAM,CAAC,GAAG,wBAAwB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;gBAC/C,IAAI,CAAC,KAAK,IAAI;oBAAE,OAAO,CAAC,CAAA;gBACxB,MAAM,CAAC,GAAG,wBAAwB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;gBAC9C,IAAI,CAAC,KAAK,IAAI;oBAAE,OAAO,CAAC,CAAA;YAC1B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,4BAA4B;QAC9B,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAG,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC,CAAA;IACpH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;YAC9D,IAAI,CAAC,GAAG,+BAA+B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAClD,IAAI,CAAC,CAAC;gBAAE,CAAC,GAAG,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACnD,IAAI,CAAC,CAAC;gBAAE,CAAC,GAAG,sDAAsD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAC7E,IAAI,CAAC;gBAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,kFAAkF;AAClF,SAAS,iBAAiB,CAAC,IAAY;IACrC,MAAM,MAAM,GAA2B,EAAE,CAAA;IACzC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,MAAM,CAAC,GAAG,wBAAwB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAA;QACrE,IAAI,CAAC;YAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC5D,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,yHAAyH;AACzH,MAAM,UAAU,kBAAkB,CAAC,MAAiC;IAClE,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,EAAE;QAAE,OAAO,EAAE,CAAA;IAC1D,MAAM,GAAG,GAAwB,EAAE,CAAA;IACnC,IAAI,EAAE,GAA6B,IAAI,CAAA;IACvC,IAAI,KAAK,GAA6B,IAAI,CAAA;IAC1C,KAAK,MAAM,IAAI,IAAI,gBAAgB,CAAC,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;QACxE,IAAI,CAAyB,CAAA;QAC7B,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;QACrE,CAAC;aAAM,IAAI,CAAC,CAAC,GAAG,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACzD,MAAM,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAA;YAClC,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS;gBAAE,SAAQ;YACjH,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC,CAAA;QAC5I,CAAC;aAAM,IAAI,CAAC,CAAC,GAAG,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACjD,MAAM,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAA;YAClC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC,CAAA;QACtH,CAAC;aAAM,IAAI,CAAC,CAAC,GAAG,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACtD,MAAM,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAA;YAClC,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS;gBAAE,SAAQ;YAC9D,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC,CAAA;QACvG,CAAC;aAAM,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,IAAI,EAAE,KAAK,IAAI;gBAAE,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;YACxF,EAAE,CAAC,MAAM,IAAI,CAAC,CAAA;QAChB,CAAC;aAAM,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAClE,IAAI,EAAE,KAAK,IAAI;gBAAE,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;YACxF,EAAE,CAAC,MAAM,IAAI,CAAC,CAAA;QAChB,CAAC;aAAM,IAAI,CAAC,CAAC,GAAG,uEAAuE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACpG,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC3B,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC,EAAE,CAAC,CAAA;QACtH,CAAC;aAAM,IAAI,CAAC,CAAC,GAAG,6BAA6B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC1D,IAAI,KAAK,KAAK,IAAI;gBAAE,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;YACjG,KAAK,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC5B,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;gBAAE,KAAK,CAAC,OAAO,GAAG,IAAI,CAAA;QAC9C,CAAC;aAAM,IAAI,CAAC,CAAC,GAAG,6BAA6B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC1D,IAAI,KAAK,KAAK,IAAI;gBAAE,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;YACjG,KAAK,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC9B,CAAC;aAAM,IAAI,CAAC,CAAC,GAAG,iDAAiD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC9E,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC7B,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC7B,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,KAAK,CAAC,EAAE,CAAC,CAAA;QACpH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,iBAAiB,CAAC,KAAuB;IACvD,MAAM,IAAI,GAAG,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAA;IAC/G,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,CAAA;IAC/E,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI;QAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,CAAA;IACzE,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK;QAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,eAAe,EAAE,CAAA;IAC/E,MAAM,SAAS,GAAG,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAClD,IAAI,MAAM,GAAG,CAAC,CAAA;IACd,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAA;QACrE,MAAM,IAAI,CAAC,CAAC,MAAM,CAAA;QAClB,IAAI,CAAC,CAAC,OAAO;YAAE,OAAO,GAAG,IAAI,CAAA;IAC/B,CAAC;IACD,IAAI,MAAM,KAAK,CAAC,IAAI,OAAO;QAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,CAAA;IAC1E,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,CAAA;IAC1D,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAA;IAChE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,CAAA;AACjD,CAAC;AAED,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY,EAAE,IAAa;IAChE,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IACrE,IAAI,IAAI,IAAI,IAAI,KAAK,sBAAsB;QAAE,OAAO,IAAI,CAAA;IACxD,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,2DAA2D,CAAA;AAC3F,CAAC;AAED,+GAA+G;AAC/G,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,KAAK,KAAK,sBAAsB,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;AACvH,CAAC;AAyBD,kCAAkC;AAClC,MAAM,UAAU,iBAAiB;IAC/B,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAA;AAC/B,CAAC;AAED,6GAA6G;AAC7G,MAAM,UAAU,oBAAoB,CAAC,OAAe,EAAE,SAAiB,EAAE,SAAmC;IAC1G,OAAO,SAAS,CAAC,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,CAAA;AACrE,CAAC;AAED,6HAA6H;AAC7H,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,CAAU,CAAA;IACd,IAAI,CAAC;QACH,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IACxE,MAAM,CAAC,GAAG,CAA4B,CAAA;IACtC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAA;IAChH,MAAM,QAAQ,GAAiC,EAAE,CAAA;IACjD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAkB,CAAC,EAAE,CAAC;QACpD,MAAM,CAAC,GAAI,CAAC,CAAC,QAAoC,CAAC,GAAG,CAAC,CAAA;QACtD,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;QACxE,MAAM,CAAC,GAAG,CAA4B,CAAA;QACtC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;YAAE,OAAO,IAAI,CAAA;QAC9H,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAA;QACjE,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,CAAC,OAAO,KAAK,IAAI;YAAE,OAAO,IAAI,CAAA;QAC9D,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI;YAAE,OAAO,IAAI,CAAA;QAC1D,QAAQ,CAAC,GAAG,CAAC,GAAG,CAA4B,CAAA;IAC9C,CAAC;IACD,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAA;AAC3B,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,iBAAiB,CAAC,KAAmB,EAAE,KAAa,EAAE,QAA6B,EAAE,IAAY;IAC/G,MAAM,QAAQ,GAAiC,EAAE,CAAA;IACjD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;QAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAA;IAC7E,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,QAAQ,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAA;IACtE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAA;AAC3B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAmB,EAAE,YAAqB;IAC1E,MAAM,QAAQ,GAAiC,EAAE,CAAA;IACjD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5C,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAA;QAC5B,MAAM,IAAI,GAAiB,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAA;QAC/C,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS;YAAE,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAA;QACzC,IAAI,CAAC,CAAC,OAAO,IAAI,YAAY;YAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QAClD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;QACjB,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;IACpB,CAAC;IACD,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAA;AAC3B,CAAC;AAKD;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAA0B,EAAE,KAAa,EAAE,QAAiB,EAAE,KAAa;IAC1G,MAAM,CAAC,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC5D,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,KAAK;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,CAAA;IACrG,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,CAAA;IACnE,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,CAAA;IACrE,IAAI,CAAC,CAAC,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,CAAA;IACpD,IAAI,QAAQ,IAAI,CAAC,CAAC,KAAK;QAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,IAAI,EAAE,CAAA;IACnE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,CAAA;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAa,EAAE,IAAY,EAAE,CAAmB,EAAE,GAAkB,EAAE,OAAe;IAC3H,MAAM,IAAI,GAAG,IAAI,GAAG,mBAAmB,GAAG,KAAK,GAAG,UAAU,CAAA;IAC5D,QAAQ,CAAC,EAAE,CAAC;QACV,KAAK,MAAM;YACT,OAAO,IAAI,GAAG,0BAA0B,CAAA;QAC1C,KAAK,QAAQ;YACX,OAAO,IAAI,GAAG,WAAW,GAAG,KAAK,GAAG,WAAW,GAAG,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG,GAAG,CAAA;QAC3E,KAAK,SAAS;YACZ,OAAO,IAAI,GAAG,yBAAyB,GAAG,KAAK,GAAG,iEAAiE,CAAA;QACrH,KAAK,SAAS;YACZ,OAAO,IAAI,GAAG,uCAAuC,GAAG,KAAK,GAAG,mBAAmB,CAAA;QACrF,KAAK,cAAc;YACjB,OAAO,IAAI,GAAG,IAAI,GAAG,6DAA6D,CAAA;QACpF,KAAK,gBAAgB;YACnB,OAAO,IAAI,GAAG,OAAO,GAAG,qFAAqF,CAAA;QAC/G,KAAK,YAAY;YACf,OAAO,IAAI,GAAG,OAAO,GAAG,qEAAqE,CAAA;QAC/F;YACE,OAAO,EAAE,CAAA;IACb,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,mBAAmB;IACnB,mBAAmB;IACnB,gBAAgB;IAChB,wBAAwB;IACxB,eAAe;IACf,iBAAiB;IACjB,kBAAkB;IAClB,iBAAiB;IACjB,sBAAsB;IACtB,cAAc;IACd,iBAAiB;IACjB,oBAAoB;IACpB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,gBAAgB;IAChB,uBAAuB;CACxB;KACE,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;KACtD,IAAI,CAAC,IAAI,CAAC,CAAA"}
|
package/dist/wrapTools.d.ts
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
* wrapped tool with neither throws, refusing to run the tool unguarded
|
|
29
29
|
* rather than silently skipping enforcement.
|
|
30
30
|
*/
|
|
31
|
-
import type { Gate } from './gate.js';
|
|
31
|
+
import type { Gate, ToolOutcome } from './gate.js';
|
|
32
32
|
export type AnyFn = (...args: any[]) => any;
|
|
33
33
|
export interface ExecutableTool {
|
|
34
34
|
execute: AnyFn;
|
|
@@ -43,6 +43,12 @@ export interface WrapToolOptions {
|
|
|
43
43
|
/** Overrides the process-wide installed gate for this tool only. */
|
|
44
44
|
gate?: Gate;
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* What a tool's return value says about how it went: a string is its
|
|
48
|
+
* output; an object's numeric `exitCode`, `exit_code` or `returncode` is its
|
|
49
|
+
* exit code, and its string `output`, `stdout` or `stderr` its output.
|
|
50
|
+
*/
|
|
51
|
+
export declare function toolOutcomeOf(result: unknown): ToolOutcome;
|
|
46
52
|
/**
|
|
47
53
|
* Wrap a single tool — a plain async function, or a `{ execute, ... }`
|
|
48
54
|
* object — so `Gate.guard()` runs before the real implementation.
|
package/dist/wrapTools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrapTools.d.ts","sourceRoot":"","sources":["../src/wrapTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"wrapTools.d.ts","sourceRoot":"","sources":["../src/wrapTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAIlD,MAAM,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAA;AAE3C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,KAAK,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,oCAAoC;AACpC,MAAM,WAAW,eAAe;IAC9B;uEACmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,oEAAoE;IACpE,IAAI,CAAC,EAAE,IAAI,CAAA;CACZ;AA2BD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,WAAW,CAO1D;AAmCD;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,CAAC,CAAA;AAC3E,wBAAgB,QAAQ,CAAC,CAAC,SAAS,cAAc,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,CAAC,CAAA;AAgBtF;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,KAAK,GAAG,cAAc,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,CAAA;AAClG,wBAAgB,SAAS,CAAC,CAAC,SAAS,KAAK,GAAG,cAAc,EACxD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EACxB,IAAI,CAAC,EAAE,IAAI,GACV,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA"}
|
package/dist/wrapTools.js
CHANGED
|
@@ -51,6 +51,21 @@ function renderToolInput(args) {
|
|
|
51
51
|
}
|
|
52
52
|
return { args };
|
|
53
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* What a tool's return value says about how it went: a string is its
|
|
56
|
+
* output; an object's numeric `exitCode`, `exit_code` or `returncode` is its
|
|
57
|
+
* exit code, and its string `output`, `stdout` or `stderr` its output.
|
|
58
|
+
*/
|
|
59
|
+
export function toolOutcomeOf(result) {
|
|
60
|
+
if (typeof result === 'string')
|
|
61
|
+
return { output: result };
|
|
62
|
+
if (result === null || typeof result !== 'object' || Array.isArray(result))
|
|
63
|
+
return {};
|
|
64
|
+
const r = result;
|
|
65
|
+
const code = [r.exitCode, r.exit_code, r.returncode].find((v) => typeof v === 'number');
|
|
66
|
+
const text = [r.output, r.stdout, r.stderr].filter((v) => typeof v === 'string').join('\n');
|
|
67
|
+
return { ...(typeof code === 'number' ? { exitCode: code } : {}), ...(text ? { output: text } : {}) };
|
|
68
|
+
}
|
|
54
69
|
function wrapFn(fn, toolName, gate) {
|
|
55
70
|
if (isGuarded(fn))
|
|
56
71
|
return fn;
|
|
@@ -61,8 +76,21 @@ function wrapFn(fn, toolName, gate) {
|
|
|
61
76
|
throw new Error('No gate configured: call install(new Gate(...)) from @intutic/gate, or pass ' +
|
|
62
77
|
'{ gate } to wrapTool()/wrapTools(). Refusing to run the tool unguarded.');
|
|
63
78
|
}
|
|
64
|
-
|
|
65
|
-
|
|
79
|
+
const input = renderToolInput(args);
|
|
80
|
+
await g.guard(toolName, input);
|
|
81
|
+
// How the call went feeds Tier R (a qualified requires_before):
|
|
82
|
+
// a throw is a failure; a returned exit code or text is read by the
|
|
83
|
+
// test-outcome rules. Recording never changes what the tool returns.
|
|
84
|
+
let result;
|
|
85
|
+
try {
|
|
86
|
+
result = await fn(...args);
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
g.recordOutcome(toolName, input, { isError: true, output: err instanceof Error ? err.message : String(err) });
|
|
90
|
+
throw err;
|
|
91
|
+
}
|
|
92
|
+
g.recordOutcome(toolName, input, toolOutcomeOf(result));
|
|
93
|
+
return result;
|
|
66
94
|
};
|
|
67
95
|
Object.defineProperty(wrapped, GUARDED, { value: true, enumerable: false });
|
|
68
96
|
Object.defineProperty(wrapped, 'name', { value: toolName, configurable: true });
|
package/dist/wrapTools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrapTools.js","sourceRoot":"","sources":["../src/wrapTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,eAAe,CAAA;AAoBpD,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAA;AAElD,SAAS,SAAS,CAAC,EAAS;IAC1B,OAAQ,EAAyC,CAAC,OAAO,CAAC,KAAK,IAAI,CAAA;AACrE,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,eAAe,CAAC,IAAe;IACtC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;IACpB,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzE,OAAO,KAAgC,CAAA;IACzC,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,CAAA;AACjB,CAAC;AAED,SAAS,MAAM,CAAC,EAAS,EAAE,QAAgB,EAAE,IAAsB;IACjE,IAAI,SAAS,CAAC,EAAE,CAAC;QAAE,OAAO,EAAE,CAAA;IAE5B,8DAA8D;IAC9D,MAAM,OAAO,GAAG,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE;QACvC,MAAM,CAAC,GAAG,IAAI,IAAI,UAAU,EAAE,CAAA;QAC9B,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,8EAA8E;gBAC5E,yEAAyE,CAC5E,CAAA;QACH,CAAC;QACD,MAAM,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"wrapTools.js","sourceRoot":"","sources":["../src/wrapTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,eAAe,CAAA;AAoBpD,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAA;AAElD,SAAS,SAAS,CAAC,EAAS;IAC1B,OAAQ,EAAyC,CAAC,OAAO,CAAC,KAAK,IAAI,CAAA;AACrE,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,eAAe,CAAC,IAAe;IACtC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;IACpB,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzE,OAAO,KAAgC,CAAA;IACzC,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,CAAA;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,MAAe;IAC3C,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAA;IACzD,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAA;IACrF,MAAM,CAAC,GAAG,MAAiC,CAAA;IAC3C,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAA;IACvF,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACxG,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAA;AACvG,CAAC;AAED,SAAS,MAAM,CAAC,EAAS,EAAE,QAAgB,EAAE,IAAsB;IACjE,IAAI,SAAS,CAAC,EAAE,CAAC;QAAE,OAAO,EAAE,CAAA;IAE5B,8DAA8D;IAC9D,MAAM,OAAO,GAAG,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE;QACvC,MAAM,CAAC,GAAG,IAAI,IAAI,UAAU,EAAE,CAAA;QAC9B,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,8EAA8E;gBAC5E,yEAAyE,CAC5E,CAAA;QACH,CAAC;QACD,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,CAAA;QACnC,MAAM,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QAC9B,gEAAgE;QAChE,oEAAoE;QACpE,qEAAqE;QACrE,IAAI,MAAe,CAAA;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAA;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,CAAC,CAAC,aAAa,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YAC7G,MAAM,GAAG,CAAA;QACX,CAAC;QACD,CAAC,CAAC,aAAa,CAAC,QAAQ,EAAE,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAA;QACvD,OAAO,MAAM,CAAA;IACf,CAAC,CAAA;IAED,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAA;IAC3E,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAA;IAC/E,OAAO,OAAO,CAAA;AAChB,CAAC;AAcD,MAAM,UAAU,QAAQ,CAAC,QAAgC,EAAE,OAAwB,EAAE;IACnF,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,MAAM,CAAC,CAAA;QACnD,OAAO,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;IAC1C,CAAC;IACD,IAAI,QAAQ,KAAK,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAChG,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,IAAI,MAAM,CAAA;QACjD,OAAO,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;IAC5E,CAAC;IACD,MAAM,IAAI,SAAS,CACjB,sFAAsF;QACpF,GAAG,OAAO,QAAQ,EAAE,CACvB,CAAA;AACH,CAAC;AAgBD,MAAM,UAAU,SAAS,CACvB,KAAuC,EACvC,IAAW;IAEX,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,8DAA8D;QAC9D,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAQ,CAAA;IAC9D,CAAC;IACD,MAAM,GAAG,GAAsB,EAAE,CAAA;IACjC,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7C,8DAA8D;QAC9D,GAAG,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAQ,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAA;IACpD,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intutic/gate",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Intutic pre-execution tool gate for JS/TS agent frameworks without a shipped Intutic harness (Mastra, the Vercel AI SDK, LangChain.js, dsh, and hand-rolled agent loops)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
"vitest": "^4",
|
|
113
113
|
"workflow": "^5.0.1",
|
|
114
114
|
"zod": "^4.2.0",
|
|
115
|
-
"@intutic/shared-types": "
|
|
115
|
+
"@intutic/shared-types": "3.0.0"
|
|
116
116
|
},
|
|
117
117
|
"engines": {
|
|
118
118
|
"node": ">=18"
|