@intutic/shared-types 2.9.0 → 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/decide.d.ts +269 -0
- package/dist/decide.d.ts.map +1 -0
- package/dist/decide.js +781 -0
- package/dist/decide.js.map +1 -0
- package/dist/decideEngine.d.ts +195 -0
- package/dist/decideEngine.d.ts.map +1 -0
- package/dist/decideEngine.js +720 -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 +518 -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 +200 -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 +543 -0
- package/dist/decideLog.js.map +1 -0
- package/dist/decideLogRedaction.d.ts +12 -0
- package/dist/decideLogRedaction.d.ts.map +1 -0
- package/dist/decideLogRedaction.js +19 -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 +266 -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 +151 -0
- package/dist/decideSdk.js.map +1 -0
- package/dist/errors.d.ts +11 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +12 -1
- package/dist/errors.js.map +1 -1
- package/dist/gateLimits.d.ts +27 -0
- package/dist/gateLimits.d.ts.map +1 -1
- package/dist/gateLimits.js +29 -1
- package/dist/gateLimits.js.map +1 -1
- package/dist/gateRuleRecord.d.ts +244 -0
- package/dist/gateRuleRecord.d.ts.map +1 -0
- package/dist/gateRuleRecord.js +474 -0
- package/dist/gateRuleRecord.js.map +1 -0
- package/dist/guardrailIr.d.ts +301 -10
- package/dist/guardrailIr.d.ts.map +1 -1
- package/dist/guardrailIr.js +86 -7
- package/dist/guardrailIr.js.map +1 -1
- package/dist/guardrailRender.d.ts +38 -4
- package/dist/guardrailRender.d.ts.map +1 -1
- package/dist/guardrailRender.js +155 -14
- package/dist/guardrailRender.js.map +1 -1
- package/dist/index.d.ts +28 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +162 -8
- 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 +160 -0
- package/dist/lanes.js.map +1 -0
- package/dist/loopVerify.d.ts +49 -0
- package/dist/loopVerify.d.ts.map +1 -0
- package/dist/loopVerify.js +77 -0
- package/dist/loopVerify.js.map +1 -0
- package/dist/mcpBudgets.d.ts +8 -8
- package/dist/notifications.d.ts +1 -1
- package/dist/notifications.d.ts.map +1 -1
- package/dist/notifications.js +14 -0
- package/dist/notifications.js.map +1 -1
- package/dist/providers.d.ts +13 -0
- package/dist/providers.d.ts.map +1 -1
- package/dist/providers.js +31 -0
- package/dist/providers.js.map +1 -1
- package/dist/refusalDetail.d.ts +58 -0
- package/dist/refusalDetail.d.ts.map +1 -0
- package/dist/refusalDetail.js +128 -0
- package/dist/refusalDetail.js.map +1 -0
- package/dist/responses/decide.d.ts +1858 -0
- package/dist/responses/decide.d.ts.map +1 -0
- package/dist/responses/decide.js +166 -0
- package/dist/responses/decide.js.map +1 -0
- package/dist/responses/gateways.d.ts +745 -101
- package/dist/responses/gateways.d.ts.map +1 -1
- package/dist/responses/gateways.js +34 -2
- package/dist/responses/gateways.js.map +1 -1
- package/dist/responses/guardrails.d.ts +1434 -144
- package/dist/responses/guardrails.d.ts.map +1 -1
- package/dist/responses/identity.d.ts +6 -6
- package/dist/responses/index.d.ts +1 -0
- package/dist/responses/index.d.ts.map +1 -1
- package/dist/responses/index.js +1 -0
- package/dist/responses/index.js.map +1 -1
- package/dist/responses/integrations.d.ts +84 -84
- package/dist/responses/observability.d.ts +272 -92
- package/dist/responses/observability.d.ts.map +1 -1
- package/dist/responses/observability.js +31 -1
- package/dist/responses/observability.js.map +1 -1
- package/dist/responses/rules.d.ts +1026 -187
- package/dist/responses/rules.d.ts.map +1 -1
- package/dist/responses/rules.js +47 -1
- package/dist/responses/rules.js.map +1 -1
- package/dist/scopeMatch.d.ts +156 -0
- package/dist/scopeMatch.d.ts.map +1 -0
- package/dist/scopeMatch.js +451 -0
- package/dist/scopeMatch.js.map +1 -0
- package/dist/sopKeySince.d.ts +41 -0
- package/dist/sopKeySince.d.ts.map +1 -0
- package/dist/sopKeySince.js +81 -0
- package/dist/sopKeySince.js.map +1 -0
- package/dist/testOutcome.d.ts +164 -0
- package/dist/testOutcome.d.ts.map +1 -0
- package/dist/testOutcome.js +454 -0
- package/dist/testOutcome.js.map +1 -0
- package/dist/upstreamRetry.d.ts +2 -2
- package/dist/workspaceSettings.d.ts +91 -0
- package/dist/workspaceSettings.d.ts.map +1 -1
- package/dist/workspaceSettings.js +48 -2
- package/dist/workspaceSettings.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,164 @@
|
|
|
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 declare const OUTCOME_TOKENS: readonly ["action:run_tests"];
|
|
51
|
+
/** The qualifiers there are. */
|
|
52
|
+
export declare const OUTCOME_QUALIFIERS: readonly ["ok"];
|
|
53
|
+
/** The one qualified token there is. */
|
|
54
|
+
export declare const QUALIFIED_TOKEN_RE: RegExp;
|
|
55
|
+
/** How much of a run's output the summaries are read from: its last 64 KiB. */
|
|
56
|
+
export declare const TEST_OUTPUT_TAIL_BYTES = 65536;
|
|
57
|
+
/** Each line is cut to this many bytes before it is matched. */
|
|
58
|
+
export declare const TEST_OUTPUT_LINE_BYTES = 1024;
|
|
59
|
+
/** The longest output whose JSON form is parsed for an exit code. */
|
|
60
|
+
export declare const TEST_OUTPUT_JSON_MAX_CHARS = 1048576;
|
|
61
|
+
/** An outcome older than this is ignored: a day. */
|
|
62
|
+
export declare const OUTCOME_STATE_TTL_MS = 86400000;
|
|
63
|
+
export type TestOutcome = 'ok' | 'failed' | 'unknown';
|
|
64
|
+
/** Why {@link decideTestOutcome} said what it said, by the step that decided. */
|
|
65
|
+
export type TestOutcomeWhy = 'exit_code' | 'is_error' | 'success_false' | 'summary_failed' | 'no_tests' | 'exit_zero' | 'summary_passed' | 'no_signal';
|
|
66
|
+
export interface TestOutcomeInput {
|
|
67
|
+
exitCode?: number | null;
|
|
68
|
+
isError?: boolean | null;
|
|
69
|
+
success?: boolean | null;
|
|
70
|
+
output?: string | null;
|
|
71
|
+
}
|
|
72
|
+
export interface TestOutcomeDecision {
|
|
73
|
+
outcome: TestOutcome;
|
|
74
|
+
why: TestOutcomeWhy;
|
|
75
|
+
}
|
|
76
|
+
/** One runner's summary: its counts, and whether it said no tests ran. */
|
|
77
|
+
export interface TestRunnerSummary {
|
|
78
|
+
runner: 'pytest' | 'jest' | 'vitest' | 'go' | 'cargo' | 'mocha' | 'rspec';
|
|
79
|
+
passed: number;
|
|
80
|
+
/** Failures and errors together. */
|
|
81
|
+
failed: number;
|
|
82
|
+
noTests: boolean;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The exit code a run's text reports, or null. A whole-output JSON object
|
|
86
|
+
* with `metadata.exit_code`, else `exit_code`, else `exitCode`; otherwise the
|
|
87
|
+
* first line, of the first 64 KiB then the last 64 KiB, that is
|
|
88
|
+
* `Exit code N` / `Exit code: N` (any case), `exit status N`, or begins
|
|
89
|
+
* `Process exited with code N` / `Command exited with code N`.
|
|
90
|
+
*/
|
|
91
|
+
export declare function extractExitCode(output: string | null | undefined): number | null;
|
|
92
|
+
/** The runner summaries in the last 64 KiB of `output`, in the order they appear (go and mocha folded into one each). */
|
|
93
|
+
export declare function parseTestSummaries(output: string | null | undefined): TestRunnerSummary[];
|
|
94
|
+
/** The outcome of one test run. See the module doc for the steps. */
|
|
95
|
+
export declare function decideTestOutcome(input: TestOutcomeInput): TestOutcomeDecision;
|
|
96
|
+
/**
|
|
97
|
+
* Why one side of an ordering rule cannot carry the qualifier it carries, or
|
|
98
|
+
* null when it is fine. A side carries a qualifier when it holds `[` or `]`;
|
|
99
|
+
* only `action:run_tests[ok]`, on the left of the arrow, is one. The error
|
|
100
|
+
* names the side as written, quoted as the parser quotes it.
|
|
101
|
+
*/
|
|
102
|
+
export declare function orderingQualifierError(side: string, left: boolean): string | null;
|
|
103
|
+
/** `action:run_tests[ok]` as `{ token: 'action:run_tests', qualifier: 'ok' }`; any other token unqualified. */
|
|
104
|
+
export declare function splitQualifier(token: string): {
|
|
105
|
+
token: string;
|
|
106
|
+
qualifier: 'ok' | null;
|
|
107
|
+
};
|
|
108
|
+
/** The latest outcome of one token in a session. */
|
|
109
|
+
export interface OutcomeEntry {
|
|
110
|
+
o: TestOutcome;
|
|
111
|
+
/** Epoch milliseconds. */
|
|
112
|
+
at: number;
|
|
113
|
+
/** Why `o` is what it is ({@link TestOutcomeWhy}). */
|
|
114
|
+
why?: string;
|
|
115
|
+
/** A file changed after the run: a pass no longer counts. */
|
|
116
|
+
changed?: true;
|
|
117
|
+
/** Another call completed after the run: it is not adjacent to the next one. */
|
|
118
|
+
later?: true;
|
|
119
|
+
}
|
|
120
|
+
/** `~/.intutic/hooks/state/outcomes/<key>.json`, and a gate SDK's memory. */
|
|
121
|
+
export interface OutcomeState {
|
|
122
|
+
v: 1;
|
|
123
|
+
outcomes: Record<string, OutcomeEntry>;
|
|
124
|
+
}
|
|
125
|
+
/** A state with nothing in it. */
|
|
126
|
+
export declare function emptyOutcomeState(): OutcomeState;
|
|
127
|
+
/** The state file's name for one session: the first 32 hex of sha256(harness NUL sessionId), and `.json`. */
|
|
128
|
+
export declare function outcomeStateFileName(harness: string, sessionId: string, sha256Hex: (text: string) => string): string;
|
|
129
|
+
/** 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. */
|
|
130
|
+
export declare function parseOutcomeState(text: string): OutcomeState | null;
|
|
131
|
+
/** `state` with `token`'s outcome replaced by this run's. */
|
|
132
|
+
export declare function recordTestOutcome(state: OutcomeState, token: string, decision: TestOutcomeDecision, atMs: number): OutcomeState;
|
|
133
|
+
/**
|
|
134
|
+
* `state` after another call completed: every entry is no longer adjacent to
|
|
135
|
+
* what comes next, and when the call changed a file (`changedFiles`), a pass
|
|
136
|
+
* before it no longer counts.
|
|
137
|
+
*/
|
|
138
|
+
export declare function noteCompletedCall(state: OutcomeState, changedFiles: boolean): OutcomeState;
|
|
139
|
+
/** Why a qualified prerequisite is unmet, or `met`. */
|
|
140
|
+
export type PrerequisiteCase = 'met' | 'none' | 'failed' | 'unknown' | 'changed' | 'not_adjacent' | 'not_observable' | 'no_session';
|
|
141
|
+
/**
|
|
142
|
+
* Whether `token`'s latest outcome in `state` meets a qualified rule now:
|
|
143
|
+
* `met` only for an `ok` younger than {@link OUTCOME_STATE_TTL_MS} that no
|
|
144
|
+
* file change followed (and, for `~>`, that no other call followed). A null
|
|
145
|
+
* state (none, or unreadable) is `none`.
|
|
146
|
+
*/
|
|
147
|
+
export declare function prerequisiteCase(state: OutcomeState | null, token: string, adjacent: boolean, nowMs: number): {
|
|
148
|
+
case: PrerequisiteCase;
|
|
149
|
+
why: string | null;
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* The reason a refusal (`PREREQUISITE_UNMET`) gives, for every case but
|
|
153
|
+
* `met`. `harness` names the surface for `not_observable` and `no_session`.
|
|
154
|
+
* Byte-stable: every port answers with these exact words.
|
|
155
|
+
*/
|
|
156
|
+
export declare function prerequisiteUnmetReason(first: string, then: string, c: PrerequisiteCase, why: string | null, harness: string): string;
|
|
157
|
+
/**
|
|
158
|
+
* The functions above as JavaScript source, for the hook gates to embed: the
|
|
159
|
+
* gates run this exact code. A CommonJS build names an exported function
|
|
160
|
+
* `exports.X` inside another; the source defines each as a plain `X`, so that
|
|
161
|
+
* prefix is dropped.
|
|
162
|
+
*/
|
|
163
|
+
export declare const TEST_OUTCOME_JS_SOURCE: string;
|
|
164
|
+
//# sourceMappingURL=testOutcome.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testOutcome.d.ts","sourceRoot":"","sources":["../src/testOutcome.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Did the tests pass? The deciding function behind the qualified ordering
|
|
4
|
+
* rule `requires_before: action:run_tests[ok] -> action:deploy`, and the
|
|
5
|
+
* per-session state the gates keep of it.
|
|
6
|
+
*
|
|
7
|
+
* {@link decideTestOutcome} reads what a surface saw of one test run (an exit
|
|
8
|
+
* code, an error flag, a success flag, the output) and says `ok`, `failed` or
|
|
9
|
+
* `unknown`, in this order:
|
|
10
|
+
*
|
|
11
|
+
* 1. an integer exit code other than 0, `isError === true` or
|
|
12
|
+
* `success === false`: failed;
|
|
13
|
+
* 2. any runner summary in the output that reports failures or errors: failed;
|
|
14
|
+
* 3. a summary that says no tests ran (`no tests ran`, `0 passed`, `0 total`,
|
|
15
|
+
* `0 passing`, `0 examples`) while no summary counts a pass: failed
|
|
16
|
+
* (`no_tests`);
|
|
17
|
+
* 4. exit code 0: ok;
|
|
18
|
+
* 5. no exit code, and at least one summary counts a pass: ok;
|
|
19
|
+
* 6. anything else: unknown.
|
|
20
|
+
*
|
|
21
|
+
* Unknown leaves a qualified rule unmet, as a failure does: a result that
|
|
22
|
+
* cannot be read is not a pass.
|
|
23
|
+
*
|
|
24
|
+
* {@link extractExitCode} reads an exit code out of text, for a surface that
|
|
25
|
+
* reports only text (Codex's JSON shell output, Claude Code's `Exit code N`
|
|
26
|
+
* error results, `exit status N`, `Process exited with code N`).
|
|
27
|
+
*
|
|
28
|
+
* Runner summaries are read line by line from the last
|
|
29
|
+
* {@link TEST_OUTPUT_TAIL_BYTES} bytes of the output, each line cut to
|
|
30
|
+
* {@link TEST_OUTPUT_LINE_BYTES} bytes, carriage returns and ANSI colour
|
|
31
|
+
* sequences removed. Every pattern is anchored and has no nested quantifier;
|
|
32
|
+
* a summary's counts are read by splitting it, not by a regex, so the whole
|
|
33
|
+
* read is linear in the output.
|
|
34
|
+
*
|
|
35
|
+
* The outcome state ({@link OutcomeState}) is what a gate keeps per session:
|
|
36
|
+
* the latest outcome per outcome token, with when it was recorded, whether a
|
|
37
|
+
* file changed after it (a pass describes the code it ran
|
|
38
|
+
* against, so a later write makes it stale), and whether any other call
|
|
39
|
+
* completed after it (for `~>`).
|
|
40
|
+
*
|
|
41
|
+
* Self-contained (no imports, no module state the emitted source does not
|
|
42
|
+
* carry) so `@intutic/gate` keeps a byte-identical copy and the JavaScript
|
|
43
|
+
* hook gates embed {@link TEST_OUTCOME_JS_SOURCE}. The Python port is
|
|
44
|
+
* `intutic_clawde/gate/test_outcome.py`, the Rust one
|
|
45
|
+
* `packages/proxy/src/plugins/anomaly/outcome.rs`; all of them run
|
|
46
|
+
* `fixtures/test-outcome-vectors.json`.
|
|
47
|
+
*
|
|
48
|
+
* @module
|
|
49
|
+
*/
|
|
50
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
51
|
+
exports.TEST_OUTCOME_JS_SOURCE = exports.OUTCOME_STATE_TTL_MS = exports.TEST_OUTPUT_JSON_MAX_CHARS = exports.TEST_OUTPUT_LINE_BYTES = exports.TEST_OUTPUT_TAIL_BYTES = exports.QUALIFIED_TOKEN_RE = exports.OUTCOME_QUALIFIERS = exports.OUTCOME_TOKENS = void 0;
|
|
52
|
+
exports.extractExitCode = extractExitCode;
|
|
53
|
+
exports.parseTestSummaries = parseTestSummaries;
|
|
54
|
+
exports.decideTestOutcome = decideTestOutcome;
|
|
55
|
+
exports.orderingQualifierError = orderingQualifierError;
|
|
56
|
+
exports.splitQualifier = splitQualifier;
|
|
57
|
+
exports.emptyOutcomeState = emptyOutcomeState;
|
|
58
|
+
exports.outcomeStateFileName = outcomeStateFileName;
|
|
59
|
+
exports.parseOutcomeState = parseOutcomeState;
|
|
60
|
+
exports.recordTestOutcome = recordTestOutcome;
|
|
61
|
+
exports.noteCompletedCall = noteCompletedCall;
|
|
62
|
+
exports.prerequisiteCase = prerequisiteCase;
|
|
63
|
+
exports.prerequisiteUnmetReason = prerequisiteUnmetReason;
|
|
64
|
+
/** The tokens a `[ok]` qualifier may stand on. */
|
|
65
|
+
exports.OUTCOME_TOKENS = ['action:run_tests'];
|
|
66
|
+
/** The qualifiers there are. */
|
|
67
|
+
exports.OUTCOME_QUALIFIERS = ['ok'];
|
|
68
|
+
/** The one qualified token there is. */
|
|
69
|
+
exports.QUALIFIED_TOKEN_RE = /^action:run_tests\[ok\]$/;
|
|
70
|
+
/** How much of a run's output the summaries are read from: its last 64 KiB. */
|
|
71
|
+
exports.TEST_OUTPUT_TAIL_BYTES = 65536;
|
|
72
|
+
/** Each line is cut to this many bytes before it is matched. */
|
|
73
|
+
exports.TEST_OUTPUT_LINE_BYTES = 1024;
|
|
74
|
+
/** The longest output whose JSON form is parsed for an exit code. */
|
|
75
|
+
exports.TEST_OUTPUT_JSON_MAX_CHARS = 1048576;
|
|
76
|
+
/** An outcome older than this is ignored: a day. */
|
|
77
|
+
exports.OUTCOME_STATE_TTL_MS = 86400000;
|
|
78
|
+
/** The last `maxBytes` bytes of `s` as UTF-8, starting on a character. */
|
|
79
|
+
function testOutcomeUtf8Tail(s, maxBytes) {
|
|
80
|
+
let bytes = 0;
|
|
81
|
+
let i = s.length;
|
|
82
|
+
while (i > 0) {
|
|
83
|
+
const c = s.charCodeAt(i - 1);
|
|
84
|
+
let n = 3;
|
|
85
|
+
let w = 1;
|
|
86
|
+
if (c < 0x80)
|
|
87
|
+
n = 1;
|
|
88
|
+
else if (c < 0x800)
|
|
89
|
+
n = 2;
|
|
90
|
+
else if (c >= 0xdc00 && c <= 0xdfff && i > 1) {
|
|
91
|
+
const h = s.charCodeAt(i - 2);
|
|
92
|
+
if (h >= 0xd800 && h <= 0xdbff) {
|
|
93
|
+
n = 4;
|
|
94
|
+
w = 2;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (bytes + n > maxBytes)
|
|
98
|
+
break;
|
|
99
|
+
bytes += n;
|
|
100
|
+
i -= w;
|
|
101
|
+
}
|
|
102
|
+
return s.slice(i);
|
|
103
|
+
}
|
|
104
|
+
/** The first `maxBytes` bytes of `s` as UTF-8, ending on a character. */
|
|
105
|
+
function testOutcomeUtf8Head(s, maxBytes) {
|
|
106
|
+
let bytes = 0;
|
|
107
|
+
let i = 0;
|
|
108
|
+
while (i < s.length) {
|
|
109
|
+
const c = s.charCodeAt(i);
|
|
110
|
+
let n = 3;
|
|
111
|
+
let w = 1;
|
|
112
|
+
if (c < 0x80)
|
|
113
|
+
n = 1;
|
|
114
|
+
else if (c < 0x800)
|
|
115
|
+
n = 2;
|
|
116
|
+
else if (c >= 0xd800 && c <= 0xdbff && i + 1 < s.length) {
|
|
117
|
+
const l = s.charCodeAt(i + 1);
|
|
118
|
+
if (l >= 0xdc00 && l <= 0xdfff) {
|
|
119
|
+
n = 4;
|
|
120
|
+
w = 2;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (bytes + n > maxBytes)
|
|
124
|
+
break;
|
|
125
|
+
bytes += n;
|
|
126
|
+
i += w;
|
|
127
|
+
}
|
|
128
|
+
return s.slice(0, i);
|
|
129
|
+
}
|
|
130
|
+
/** The lines of `text`, each without carriage returns or ANSI sequences and cut to {@link TEST_OUTPUT_LINE_BYTES} bytes. */
|
|
131
|
+
function testOutcomeLines(text) {
|
|
132
|
+
const out = [];
|
|
133
|
+
for (const raw of text.split('\n')) {
|
|
134
|
+
// eslint-disable-next-line no-control-regex -- removing control characters is the point
|
|
135
|
+
const line = testOutcomeUtf8Head(raw, 1024).replace(/\r/g, '').replace(/\x1b\[[0-9;?]*[A-Za-z]/g, '');
|
|
136
|
+
out.push(line);
|
|
137
|
+
}
|
|
138
|
+
return out;
|
|
139
|
+
}
|
|
140
|
+
/** A JSON integer exit code, or null. */
|
|
141
|
+
function testOutcomeIntegerOrNull(v) {
|
|
142
|
+
return typeof v === 'number' && Number.isSafeInteger(v) ? v : null;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The exit code a run's text reports, or null. A whole-output JSON object
|
|
146
|
+
* with `metadata.exit_code`, else `exit_code`, else `exitCode`; otherwise the
|
|
147
|
+
* first line, of the first 64 KiB then the last 64 KiB, that is
|
|
148
|
+
* `Exit code N` / `Exit code: N` (any case), `exit status N`, or begins
|
|
149
|
+
* `Process exited with code N` / `Command exited with code N`.
|
|
150
|
+
*/
|
|
151
|
+
function extractExitCode(output) {
|
|
152
|
+
if (typeof output !== 'string' || output === '')
|
|
153
|
+
return null;
|
|
154
|
+
const trimmed = output.trim();
|
|
155
|
+
if (trimmed.length <= 1048576 && trimmed.charAt(0) === '{' && trimmed.charAt(trimmed.length - 1) === '}') {
|
|
156
|
+
try {
|
|
157
|
+
const parsed = JSON.parse(trimmed);
|
|
158
|
+
if (parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
159
|
+
const o = parsed;
|
|
160
|
+
const meta = o.metadata;
|
|
161
|
+
if (meta !== null && typeof meta === 'object' && !Array.isArray(meta)) {
|
|
162
|
+
const m = testOutcomeIntegerOrNull(meta.exit_code);
|
|
163
|
+
if (m !== null)
|
|
164
|
+
return m;
|
|
165
|
+
}
|
|
166
|
+
const a = testOutcomeIntegerOrNull(o.exit_code);
|
|
167
|
+
if (a !== null)
|
|
168
|
+
return a;
|
|
169
|
+
const b = testOutcomeIntegerOrNull(o.exitCode);
|
|
170
|
+
if (b !== null)
|
|
171
|
+
return b;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// Not JSON: read the lines.
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const head = testOutcomeUtf8Head(output, 65536);
|
|
179
|
+
const parts = head.length === output.length ? [head] : [head, testOutcomeUtf8Tail(output.slice(head.length), 65536)];
|
|
180
|
+
for (const part of parts) {
|
|
181
|
+
for (const raw of testOutcomeLines(part)) {
|
|
182
|
+
const line = raw.replace(/^[ \t]+/, '').replace(/[ \t]+$/, '');
|
|
183
|
+
let m = /^exit code:? (-?[0-9]{1,9})$/i.exec(line);
|
|
184
|
+
if (!m)
|
|
185
|
+
m = /^exit status ([0-9]{1,9})$/.exec(line);
|
|
186
|
+
if (!m)
|
|
187
|
+
m = /^(?:Process|Command) exited with code (-?[0-9]{1,9})/.exec(line);
|
|
188
|
+
if (m)
|
|
189
|
+
return Number(m[1]);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
/** `N word` pieces of a summary, split on `,` and `|`: the count of each word. */
|
|
195
|
+
function testOutcomeCounts(text) {
|
|
196
|
+
const counts = {};
|
|
197
|
+
for (const piece of text.split(/[,|]/)) {
|
|
198
|
+
const m = /^([0-9]{1,9}) ([a-z]+)/.exec(piece.replace(/^[ \t]+/, ''));
|
|
199
|
+
if (m)
|
|
200
|
+
counts[m[2]] = (counts[m[2]] ?? 0) + Number(m[1]);
|
|
201
|
+
}
|
|
202
|
+
return counts;
|
|
203
|
+
}
|
|
204
|
+
/** The runner summaries in the last 64 KiB of `output`, in the order they appear (go and mocha folded into one each). */
|
|
205
|
+
function parseTestSummaries(output) {
|
|
206
|
+
if (typeof output !== 'string' || output === '')
|
|
207
|
+
return [];
|
|
208
|
+
const out = [];
|
|
209
|
+
let go = null;
|
|
210
|
+
let mocha = null;
|
|
211
|
+
for (const line of testOutcomeLines(testOutcomeUtf8Tail(output, 65536))) {
|
|
212
|
+
let m;
|
|
213
|
+
if (/^=+ no tests ran/.test(line)) {
|
|
214
|
+
out.push({ runner: 'pytest', passed: 0, failed: 0, noTests: true });
|
|
215
|
+
}
|
|
216
|
+
else if ((m = /^=+ (.+) in [0-9.]+s.* =+$/.exec(line))) {
|
|
217
|
+
const c = testOutcomeCounts(m[1]);
|
|
218
|
+
if (c.passed === undefined && c.failed === undefined && c.error === undefined && c.errors === undefined)
|
|
219
|
+
continue;
|
|
220
|
+
out.push({ runner: 'pytest', passed: c.passed ?? 0, failed: (c.failed ?? 0) + (c.error ?? 0) + (c.errors ?? 0), noTests: c.passed === 0 });
|
|
221
|
+
}
|
|
222
|
+
else if ((m = /^Tests:[ \t]+(.+)$/.exec(line))) {
|
|
223
|
+
const c = testOutcomeCounts(m[1]);
|
|
224
|
+
out.push({ runner: 'jest', passed: c.passed ?? 0, failed: c.failed ?? 0, noTests: c.passed === 0 || c.total === 0 });
|
|
225
|
+
}
|
|
226
|
+
else if ((m = /^[ \t]*Tests[ \t]+(.+)$/.exec(line))) {
|
|
227
|
+
const c = testOutcomeCounts(m[1]);
|
|
228
|
+
if (c.passed === undefined && c.failed === undefined)
|
|
229
|
+
continue;
|
|
230
|
+
out.push({ runner: 'vitest', passed: c.passed ?? 0, failed: c.failed ?? 0, noTests: c.passed === 0 });
|
|
231
|
+
}
|
|
232
|
+
else if (/^ok[ \t]+[^ \t]+/.test(line)) {
|
|
233
|
+
if (go === null)
|
|
234
|
+
out.push((go = { runner: 'go', passed: 0, failed: 0, noTests: false }));
|
|
235
|
+
go.passed += 1;
|
|
236
|
+
}
|
|
237
|
+
else if (/^FAIL([ \t]|$)/.test(line) || /^--- FAIL:/.test(line)) {
|
|
238
|
+
if (go === null)
|
|
239
|
+
out.push((go = { runner: 'go', passed: 0, failed: 0, noTests: false }));
|
|
240
|
+
go.failed += 1;
|
|
241
|
+
}
|
|
242
|
+
else if ((m = /^test result: (ok|FAILED)\. ([0-9]{1,9}) passed; ([0-9]{1,9}) failed;/.exec(line))) {
|
|
243
|
+
const passed = Number(m[2]);
|
|
244
|
+
const failed = Number(m[3]);
|
|
245
|
+
out.push({ runner: 'cargo', passed, failed: m[1] === 'FAILED' && failed === 0 ? 1 : failed, noTests: passed === 0 });
|
|
246
|
+
}
|
|
247
|
+
else if ((m = /^[ \t]*([0-9]{1,9}) passing/.exec(line))) {
|
|
248
|
+
if (mocha === null)
|
|
249
|
+
out.push((mocha = { runner: 'mocha', passed: 0, failed: 0, noTests: false }));
|
|
250
|
+
mocha.passed += Number(m[1]);
|
|
251
|
+
if (Number(m[1]) === 0)
|
|
252
|
+
mocha.noTests = true;
|
|
253
|
+
}
|
|
254
|
+
else if ((m = /^[ \t]*([0-9]{1,9}) failing/.exec(line))) {
|
|
255
|
+
if (mocha === null)
|
|
256
|
+
out.push((mocha = { runner: 'mocha', passed: 0, failed: 0, noTests: false }));
|
|
257
|
+
mocha.failed += Number(m[1]);
|
|
258
|
+
}
|
|
259
|
+
else if ((m = /^([0-9]{1,9}) examples?, ([0-9]{1,9}) failures?/.exec(line))) {
|
|
260
|
+
const examples = Number(m[1]);
|
|
261
|
+
const failures = Number(m[2]);
|
|
262
|
+
out.push({ runner: 'rspec', passed: Math.max(0, examples - failures), failed: failures, noTests: examples === 0 });
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return out;
|
|
266
|
+
}
|
|
267
|
+
/** The outcome of one test run. See the module doc for the steps. */
|
|
268
|
+
function decideTestOutcome(input) {
|
|
269
|
+
const exit = typeof input.exitCode === 'number' && Number.isSafeInteger(input.exitCode) ? input.exitCode : null;
|
|
270
|
+
if (exit !== null && exit !== 0)
|
|
271
|
+
return { outcome: 'failed', why: 'exit_code' };
|
|
272
|
+
if (input.isError === true)
|
|
273
|
+
return { outcome: 'failed', why: 'is_error' };
|
|
274
|
+
if (input.success === false)
|
|
275
|
+
return { outcome: 'failed', why: 'success_false' };
|
|
276
|
+
const summaries = parseTestSummaries(input.output);
|
|
277
|
+
let passed = 0;
|
|
278
|
+
let noTests = false;
|
|
279
|
+
for (const s of summaries) {
|
|
280
|
+
if (s.failed > 0)
|
|
281
|
+
return { outcome: 'failed', why: 'summary_failed' };
|
|
282
|
+
passed += s.passed;
|
|
283
|
+
if (s.noTests)
|
|
284
|
+
noTests = true;
|
|
285
|
+
}
|
|
286
|
+
if (passed === 0 && noTests)
|
|
287
|
+
return { outcome: 'failed', why: 'no_tests' };
|
|
288
|
+
if (exit === 0)
|
|
289
|
+
return { outcome: 'ok', why: 'exit_zero' };
|
|
290
|
+
if (passed >= 1)
|
|
291
|
+
return { outcome: 'ok', why: 'summary_passed' };
|
|
292
|
+
return { outcome: 'unknown', why: 'no_signal' };
|
|
293
|
+
}
|
|
294
|
+
// ---------------------------------------------------------------------------
|
|
295
|
+
// The qualifier
|
|
296
|
+
// ---------------------------------------------------------------------------
|
|
297
|
+
/**
|
|
298
|
+
* Why one side of an ordering rule cannot carry the qualifier it carries, or
|
|
299
|
+
* null when it is fine. A side carries a qualifier when it holds `[` or `]`;
|
|
300
|
+
* only `action:run_tests[ok]`, on the left of the arrow, is one. The error
|
|
301
|
+
* names the side as written, quoted as the parser quotes it.
|
|
302
|
+
*/
|
|
303
|
+
function orderingQualifierError(side, left) {
|
|
304
|
+
if (side.indexOf('[') === -1 && side.indexOf(']') === -1)
|
|
305
|
+
return null;
|
|
306
|
+
if (left && side === 'action:run_tests[ok]')
|
|
307
|
+
return null;
|
|
308
|
+
return JSON.stringify(side) + ': [ok] qualifies only action:run_tests, on the left of ->';
|
|
309
|
+
}
|
|
310
|
+
/** `action:run_tests[ok]` as `{ token: 'action:run_tests', qualifier: 'ok' }`; any other token unqualified. */
|
|
311
|
+
function splitQualifier(token) {
|
|
312
|
+
return token === 'action:run_tests[ok]' ? { token: 'action:run_tests', qualifier: 'ok' } : { token, qualifier: null };
|
|
313
|
+
}
|
|
314
|
+
/** A state with nothing in it. */
|
|
315
|
+
function emptyOutcomeState() {
|
|
316
|
+
return { v: 1, outcomes: {} };
|
|
317
|
+
}
|
|
318
|
+
/** The state file's name for one session: the first 32 hex of sha256(harness NUL sessionId), and `.json`. */
|
|
319
|
+
function outcomeStateFileName(harness, sessionId, sha256Hex) {
|
|
320
|
+
return sha256Hex(harness + '\0' + sessionId).slice(0, 32) + '.json';
|
|
321
|
+
}
|
|
322
|
+
/** 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. */
|
|
323
|
+
function parseOutcomeState(text) {
|
|
324
|
+
let v;
|
|
325
|
+
try {
|
|
326
|
+
v = JSON.parse(text);
|
|
327
|
+
}
|
|
328
|
+
catch {
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
if (v === null || typeof v !== 'object' || Array.isArray(v))
|
|
332
|
+
return null;
|
|
333
|
+
const s = v;
|
|
334
|
+
if (s.v !== 1 || s.outcomes === null || typeof s.outcomes !== 'object' || Array.isArray(s.outcomes))
|
|
335
|
+
return null;
|
|
336
|
+
const outcomes = {};
|
|
337
|
+
for (const key of Object.keys(s.outcomes)) {
|
|
338
|
+
const e = s.outcomes[key];
|
|
339
|
+
if (e === null || typeof e !== 'object' || Array.isArray(e))
|
|
340
|
+
return null;
|
|
341
|
+
const r = e;
|
|
342
|
+
if ((r.o !== 'ok' && r.o !== 'failed' && r.o !== 'unknown') || typeof r.at !== 'number' || !Number.isFinite(r.at))
|
|
343
|
+
return null;
|
|
344
|
+
if (r.why !== undefined && typeof r.why !== 'string')
|
|
345
|
+
return null;
|
|
346
|
+
if (r.changed !== undefined && r.changed !== true)
|
|
347
|
+
return null;
|
|
348
|
+
if (r.later !== undefined && r.later !== true)
|
|
349
|
+
return null;
|
|
350
|
+
outcomes[key] = r;
|
|
351
|
+
}
|
|
352
|
+
return { v: 1, outcomes };
|
|
353
|
+
}
|
|
354
|
+
/** `state` with `token`'s outcome replaced by this run's. */
|
|
355
|
+
function recordTestOutcome(state, token, decision, atMs) {
|
|
356
|
+
const outcomes = {};
|
|
357
|
+
for (const k of Object.keys(state.outcomes))
|
|
358
|
+
outcomes[k] = state.outcomes[k];
|
|
359
|
+
outcomes[token] = { o: decision.outcome, at: atMs, why: decision.why };
|
|
360
|
+
return { v: 1, outcomes };
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* `state` after another call completed: every entry is no longer adjacent to
|
|
364
|
+
* what comes next, and when the call changed a file (`changedFiles`), a pass
|
|
365
|
+
* before it no longer counts.
|
|
366
|
+
*/
|
|
367
|
+
function noteCompletedCall(state, changedFiles) {
|
|
368
|
+
const outcomes = {};
|
|
369
|
+
for (const k of Object.keys(state.outcomes)) {
|
|
370
|
+
const e = state.outcomes[k];
|
|
371
|
+
const next = { o: e.o, at: e.at };
|
|
372
|
+
if (e.why !== undefined)
|
|
373
|
+
next.why = e.why;
|
|
374
|
+
if (e.changed || changedFiles)
|
|
375
|
+
next.changed = true;
|
|
376
|
+
next.later = true;
|
|
377
|
+
outcomes[k] = next;
|
|
378
|
+
}
|
|
379
|
+
return { v: 1, outcomes };
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Whether `token`'s latest outcome in `state` meets a qualified rule now:
|
|
383
|
+
* `met` only for an `ok` younger than {@link OUTCOME_STATE_TTL_MS} that no
|
|
384
|
+
* file change followed (and, for `~>`, that no other call followed). A null
|
|
385
|
+
* state (none, or unreadable) is `none`.
|
|
386
|
+
*/
|
|
387
|
+
function prerequisiteCase(state, token, adjacent, nowMs) {
|
|
388
|
+
const e = state === null ? undefined : state.outcomes[token];
|
|
389
|
+
if (e === undefined || !(nowMs - e.at < 86400000) || e.at > nowMs)
|
|
390
|
+
return { case: 'none', why: null };
|
|
391
|
+
if (e.o === 'failed')
|
|
392
|
+
return { case: 'failed', why: e.why ?? null };
|
|
393
|
+
if (e.o === 'unknown')
|
|
394
|
+
return { case: 'unknown', why: e.why ?? null };
|
|
395
|
+
if (e.changed)
|
|
396
|
+
return { case: 'changed', why: null };
|
|
397
|
+
if (adjacent && e.later)
|
|
398
|
+
return { case: 'not_adjacent', why: null };
|
|
399
|
+
return { case: 'met', why: null };
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* The reason a refusal (`PREREQUISITE_UNMET`) gives, for every case but
|
|
403
|
+
* `met`. `harness` names the surface for `not_observable` and `no_session`.
|
|
404
|
+
* Byte-stable: every port answers with these exact words.
|
|
405
|
+
*/
|
|
406
|
+
function prerequisiteUnmetReason(first, then, c, why, harness) {
|
|
407
|
+
const head = then + ' needs a passing ' + first + ' first; ';
|
|
408
|
+
switch (c) {
|
|
409
|
+
case 'none':
|
|
410
|
+
return head + 'none ran in this session';
|
|
411
|
+
case 'failed':
|
|
412
|
+
return head + 'the last ' + first + ' failed (' + (why ?? 'failed') + ')';
|
|
413
|
+
case 'unknown':
|
|
414
|
+
return head + 'the result of the last ' + first + ' could not be read; rerun the tests so their summary is visible';
|
|
415
|
+
case 'changed':
|
|
416
|
+
return head + 'files changed after the last passing ' + first + '; rerun the tests';
|
|
417
|
+
case 'not_adjacent':
|
|
418
|
+
return head + then + ' must come directly after it, and another call came between';
|
|
419
|
+
case 'not_observable':
|
|
420
|
+
return head + harness + ' reports no tool results Intutic can read, so a passing run cannot be observed here';
|
|
421
|
+
case 'no_session':
|
|
422
|
+
return head + harness + ' sent no session id, so test results cannot be tied to this session';
|
|
423
|
+
default:
|
|
424
|
+
return '';
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* The functions above as JavaScript source, for the hook gates to embed: the
|
|
429
|
+
* gates run this exact code. A CommonJS build names an exported function
|
|
430
|
+
* `exports.X` inside another; the source defines each as a plain `X`, so that
|
|
431
|
+
* prefix is dropped.
|
|
432
|
+
*/
|
|
433
|
+
exports.TEST_OUTCOME_JS_SOURCE = [
|
|
434
|
+
testOutcomeUtf8Tail,
|
|
435
|
+
testOutcomeUtf8Head,
|
|
436
|
+
testOutcomeLines,
|
|
437
|
+
testOutcomeIntegerOrNull,
|
|
438
|
+
extractExitCode,
|
|
439
|
+
testOutcomeCounts,
|
|
440
|
+
parseTestSummaries,
|
|
441
|
+
decideTestOutcome,
|
|
442
|
+
orderingQualifierError,
|
|
443
|
+
splitQualifier,
|
|
444
|
+
emptyOutcomeState,
|
|
445
|
+
outcomeStateFileName,
|
|
446
|
+
parseOutcomeState,
|
|
447
|
+
recordTestOutcome,
|
|
448
|
+
noteCompletedCall,
|
|
449
|
+
prerequisiteCase,
|
|
450
|
+
prerequisiteUnmetReason,
|
|
451
|
+
]
|
|
452
|
+
.map((fn) => fn.toString().replace(/\bexports\./g, ''))
|
|
453
|
+
.join('\n');
|
|
454
|
+
//# sourceMappingURL=testOutcome.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testOutcome.js","sourceRoot":"","sources":["../src/testOutcome.ts"],"names":[],"mappings":"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"}
|