@opensip-cli/contracts 0.1.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/LICENSE +202 -0
- package/NOTICE +8 -0
- package/README.md +31 -0
- package/dist/__tests__/exit-codes.test.d.ts +2 -0
- package/dist/__tests__/exit-codes.test.d.ts.map +1 -0
- package/dist/__tests__/exit-codes.test.js +185 -0
- package/dist/__tests__/exit-codes.test.js.map +1 -0
- package/dist/__tests__/manifest-reexport.test.d.ts +6 -0
- package/dist/__tests__/manifest-reexport.test.d.ts.map +1 -0
- package/dist/__tests__/manifest-reexport.test.js +38 -0
- package/dist/__tests__/manifest-reexport.test.js.map +1 -0
- package/dist/__tests__/types-only.test.d.ts +10 -0
- package/dist/__tests__/types-only.test.d.ts.map +1 -0
- package/dist/__tests__/types-only.test.js +49 -0
- package/dist/__tests__/types-only.test.js.map +1 -0
- package/dist/cli-flags.d.ts +56 -0
- package/dist/cli-flags.d.ts.map +1 -0
- package/dist/cli-flags.js +85 -0
- package/dist/cli-flags.js.map +1 -0
- package/dist/cli-flags.test.d.ts +2 -0
- package/dist/cli-flags.test.d.ts.map +1 -0
- package/dist/cli-flags.test.js +51 -0
- package/dist/cli-flags.test.js.map +1 -0
- package/dist/command-outcome.d.ts +87 -0
- package/dist/command-outcome.d.ts.map +1 -0
- package/dist/command-outcome.js +32 -0
- package/dist/command-outcome.js.map +1 -0
- package/dist/command-outcome.test.d.ts +10 -0
- package/dist/command-outcome.test.d.ts.map +1 -0
- package/dist/command-outcome.test.js +68 -0
- package/dist/command-outcome.test.js.map +1 -0
- package/dist/command-results.d.ts +501 -0
- package/dist/command-results.d.ts.map +1 -0
- package/dist/command-results.js +14 -0
- package/dist/command-results.js.map +1 -0
- package/dist/exit-codes.d.ts +44 -0
- package/dist/exit-codes.d.ts.map +1 -0
- package/dist/exit-codes.js +186 -0
- package/dist/exit-codes.js.map +1 -0
- package/dist/graph-catalog.d.ts +143 -0
- package/dist/graph-catalog.d.ts.map +1 -0
- package/dist/graph-catalog.js +13 -0
- package/dist/graph-catalog.js.map +1 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/recipe-default.d.ts +53 -0
- package/dist/recipe-default.d.ts.map +1 -0
- package/dist/recipe-default.js +55 -0
- package/dist/recipe-default.js.map +1 -0
- package/dist/recipe-default.test.d.ts +2 -0
- package/dist/recipe-default.test.d.ts.map +1 -0
- package/dist/recipe-default.test.js +32 -0
- package/dist/recipe-default.test.js.map +1 -0
- package/dist/score.d.ts +26 -0
- package/dist/score.d.ts.map +1 -0
- package/dist/score.js +25 -0
- package/dist/score.js.map +1 -0
- package/dist/score.test.d.ts +2 -0
- package/dist/score.test.d.ts.map +1 -0
- package/dist/score.test.js +22 -0
- package/dist/score.test.js.map +1 -0
- package/dist/session-types.d.ts +132 -0
- package/dist/session-types.d.ts.map +1 -0
- package/dist/session-types.js +11 -0
- package/dist/session-types.js.map +1 -0
- package/dist/signal-envelope.d.ts +118 -0
- package/dist/signal-envelope.d.ts.map +1 -0
- package/dist/signal-envelope.js +84 -0
- package/dist/signal-envelope.js.map +1 -0
- package/dist/signal-envelope.test.d.ts +2 -0
- package/dist/signal-envelope.test.d.ts.map +1 -0
- package/dist/signal-envelope.test.js +168 -0
- package/dist/signal-envelope.test.js.map +1 -0
- package/dist/types.d.ts +78 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/verbose-detail.d.ts +26 -0
- package/dist/verbose-detail.d.ts.map +1 -0
- package/dist/verbose-detail.js +75 -0
- package/dist/verbose-detail.js.map +1 -0
- package/dist/verbose-detail.test.d.ts +2 -0
- package/dist/verbose-detail.test.d.ts.map +1 -0
- package/dist/verbose-detail.test.js +53 -0
- package/dist/verbose-detail.test.js.map +1 -0
- package/dist/verdict-envelope.test.d.ts +8 -0
- package/dist/verdict-envelope.test.d.ts.map +1 -0
- package/dist/verdict-envelope.test.js +67 -0
- package/dist/verdict-envelope.test.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { createSignal, defaultFingerprintStrategy, HOST_VERDICT_POLICY_FALLBACK, } from '@opensip-cli/core';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { buildSignalEnvelope } from './signal-envelope.js';
|
|
4
|
+
function signal(severity) {
|
|
5
|
+
return createSignal({
|
|
6
|
+
source: 'test',
|
|
7
|
+
severity,
|
|
8
|
+
ruleId: `rule-${severity}`,
|
|
9
|
+
message: `a ${severity} finding`,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
function unit(slug, passed) {
|
|
13
|
+
return { slug, passed, durationMs: 1 };
|
|
14
|
+
}
|
|
15
|
+
const BASE = {
|
|
16
|
+
tool: 'fit',
|
|
17
|
+
runId: 'run-1',
|
|
18
|
+
createdAt: '2026-01-01T00:00:00.000Z',
|
|
19
|
+
// ADR-0035: verdict is policy-driven. The {1,0} fallback (fail on any error,
|
|
20
|
+
// warnings informational) reproduces the pre-ADR `errors === 0` behavior these
|
|
21
|
+
// baseline cases assert. The full policy matrix lives in verdict-envelope.test.ts.
|
|
22
|
+
policy: HOST_VERDICT_POLICY_FALLBACK,
|
|
23
|
+
runFaulted: false,
|
|
24
|
+
};
|
|
25
|
+
/** A recognizable non-default strategy for the stamping cases. */
|
|
26
|
+
const toolStrategy = (s) => `tool:${s.ruleId}`;
|
|
27
|
+
describe('buildSignalEnvelope', () => {
|
|
28
|
+
it('stamps the schema version and identity, and passes units through verbatim', () => {
|
|
29
|
+
const units = [unit('a', true), unit('b', true)];
|
|
30
|
+
const signals = [signal('low')];
|
|
31
|
+
const env = buildSignalEnvelope({
|
|
32
|
+
...BASE,
|
|
33
|
+
recipe: 'example',
|
|
34
|
+
units,
|
|
35
|
+
signals,
|
|
36
|
+
resolutionMode: 'fast',
|
|
37
|
+
});
|
|
38
|
+
expect(env.schemaVersion).toBe(2);
|
|
39
|
+
expect(env.tool).toBe('fit');
|
|
40
|
+
expect(env.recipe).toBe('example');
|
|
41
|
+
expect(env.runId).toBe('run-1');
|
|
42
|
+
expect(env.createdAt).toBe('2026-01-01T00:00:00.000Z');
|
|
43
|
+
expect(env.resolutionMode).toBe('fast');
|
|
44
|
+
// units pass through, not copies
|
|
45
|
+
expect(env.units).toBe(units);
|
|
46
|
+
});
|
|
47
|
+
// ADR-0036: fingerprints are an envelope-construction concern — every built
|
|
48
|
+
// envelope is gate-ready, so the "tool forgot to stamp" class cannot occur.
|
|
49
|
+
describe('fingerprint stamping (ADR-0036)', () => {
|
|
50
|
+
it('stamps every signal with the host default strategy when none is passed', () => {
|
|
51
|
+
const env = buildSignalEnvelope({
|
|
52
|
+
...BASE,
|
|
53
|
+
units: [unit('a', false)],
|
|
54
|
+
signals: [signal('low')],
|
|
55
|
+
});
|
|
56
|
+
const stamped = env.signals[0];
|
|
57
|
+
expect(stamped.fingerprint).toBe(defaultFingerprintStrategy(stamped));
|
|
58
|
+
});
|
|
59
|
+
it('stamps with the tool strategy when one is passed', () => {
|
|
60
|
+
const env = buildSignalEnvelope({
|
|
61
|
+
...BASE,
|
|
62
|
+
units: [unit('a', false)],
|
|
63
|
+
signals: [signal('high')],
|
|
64
|
+
fingerprintStrategy: toolStrategy,
|
|
65
|
+
});
|
|
66
|
+
expect(env.signals[0]?.fingerprint).toBe('tool:rule-high');
|
|
67
|
+
});
|
|
68
|
+
it('preserves pre-stamped signals byte-for-byte and by array identity', () => {
|
|
69
|
+
const preStamped = [{ ...signal('low'), fingerprint: 'pre-existing' }];
|
|
70
|
+
const env = buildSignalEnvelope({
|
|
71
|
+
...BASE,
|
|
72
|
+
units: [unit('a', true)],
|
|
73
|
+
signals: preStamped,
|
|
74
|
+
fingerprintStrategy: () => 'would-clobber',
|
|
75
|
+
});
|
|
76
|
+
expect(env.signals[0]?.fingerprint).toBe('pre-existing');
|
|
77
|
+
// fully pre-stamped sets pass through by identity (no re-allocation)
|
|
78
|
+
expect(env.signals).toBe(preStamped);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
it('derives summary.total/passed/failed from the units (units are what "ran")', () => {
|
|
82
|
+
const env = buildSignalEnvelope({
|
|
83
|
+
...BASE,
|
|
84
|
+
units: [unit('a', true), unit('b', false), unit('c', true), unit('d', false)],
|
|
85
|
+
signals: [],
|
|
86
|
+
});
|
|
87
|
+
expect(env.verdict.summary.total).toBe(4);
|
|
88
|
+
expect(env.verdict.summary.passed).toBe(2);
|
|
89
|
+
expect(env.verdict.summary.failed).toBe(2);
|
|
90
|
+
});
|
|
91
|
+
it('counts critical and high signals as errors; medium and low as warnings', () => {
|
|
92
|
+
const env = buildSignalEnvelope({
|
|
93
|
+
...BASE,
|
|
94
|
+
units: [unit('a', false)],
|
|
95
|
+
signals: [signal('critical'), signal('high'), signal('medium'), signal('low')],
|
|
96
|
+
});
|
|
97
|
+
expect(env.verdict.summary.errors).toBe(2);
|
|
98
|
+
expect(env.verdict.summary.warnings).toBe(2);
|
|
99
|
+
});
|
|
100
|
+
it('passed ⇔ zero error-rung signals: a warnings-only run still passes', () => {
|
|
101
|
+
const env = buildSignalEnvelope({
|
|
102
|
+
...BASE,
|
|
103
|
+
units: [unit('a', true)],
|
|
104
|
+
signals: [signal('medium'), signal('low')],
|
|
105
|
+
});
|
|
106
|
+
expect(env.verdict.summary.errors).toBe(0);
|
|
107
|
+
expect(env.verdict.passed).toBe(true);
|
|
108
|
+
});
|
|
109
|
+
it('passed is false as soon as a single error-rung signal is present', () => {
|
|
110
|
+
const env = buildSignalEnvelope({
|
|
111
|
+
...BASE,
|
|
112
|
+
// every unit reported passed, but an error-rung signal still fails the run
|
|
113
|
+
units: [unit('a', true)],
|
|
114
|
+
signals: [signal('high')],
|
|
115
|
+
});
|
|
116
|
+
expect(env.verdict.summary.errors).toBe(1);
|
|
117
|
+
expect(env.verdict.passed).toBe(false);
|
|
118
|
+
});
|
|
119
|
+
it('score is passRate over the unit summary (rounded passed/total percentage)', () => {
|
|
120
|
+
const env = buildSignalEnvelope({
|
|
121
|
+
...BASE,
|
|
122
|
+
units: [unit('a', true), unit('b', true), unit('c', false)],
|
|
123
|
+
signals: [],
|
|
124
|
+
});
|
|
125
|
+
// 2 of 3 passed → round(66.67) === 67
|
|
126
|
+
expect(env.verdict.score).toBe(67);
|
|
127
|
+
});
|
|
128
|
+
it('scores 100 for an empty run (no units) and reports it as passed', () => {
|
|
129
|
+
const env = buildSignalEnvelope({
|
|
130
|
+
...BASE,
|
|
131
|
+
units: [],
|
|
132
|
+
signals: [],
|
|
133
|
+
});
|
|
134
|
+
expect(env.verdict.summary.total).toBe(0);
|
|
135
|
+
expect(env.verdict.summary.passed).toBe(0);
|
|
136
|
+
expect(env.verdict.summary.failed).toBe(0);
|
|
137
|
+
expect(env.verdict.score).toBe(100);
|
|
138
|
+
expect(env.verdict.passed).toBe(true);
|
|
139
|
+
});
|
|
140
|
+
it('expresses "ran, errored, 0 signals": a unit can carry an error with no signals', () => {
|
|
141
|
+
const errored = {
|
|
142
|
+
slug: 'boom',
|
|
143
|
+
passed: false,
|
|
144
|
+
durationMs: 5,
|
|
145
|
+
error: 'adapter exploded',
|
|
146
|
+
};
|
|
147
|
+
const env = buildSignalEnvelope({
|
|
148
|
+
...BASE,
|
|
149
|
+
units: [errored],
|
|
150
|
+
signals: [],
|
|
151
|
+
});
|
|
152
|
+
expect(env.units[0]?.error).toBe('adapter exploded');
|
|
153
|
+
expect(env.verdict.summary.failed).toBe(1);
|
|
154
|
+
// no signals → no errors counted, but the failed unit drags the score down
|
|
155
|
+
expect(env.verdict.summary.errors).toBe(0);
|
|
156
|
+
expect(env.verdict.score).toBe(0);
|
|
157
|
+
});
|
|
158
|
+
it('omits optional recipe and resolutionMode when not supplied', () => {
|
|
159
|
+
const env = buildSignalEnvelope({
|
|
160
|
+
...BASE,
|
|
161
|
+
units: [unit('a', true)],
|
|
162
|
+
signals: [],
|
|
163
|
+
});
|
|
164
|
+
expect(env.recipe).toBeUndefined();
|
|
165
|
+
expect(env.resolutionMode).toBeUndefined();
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
//# sourceMappingURL=signal-envelope.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal-envelope.test.js","sourceRoot":"","sources":["../src/signal-envelope.test.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/** Options for the `fit` subcommand (derived from Commander flags). */
|
|
2
|
+
export interface FitOptions {
|
|
3
|
+
recipe?: string;
|
|
4
|
+
check?: string;
|
|
5
|
+
/**
|
|
6
|
+
* Tag filters for ad-hoc check selection. Repeatable and/or
|
|
7
|
+
* comma-separated: `--tags a --tags b` and `--tags a,b` both accumulate
|
|
8
|
+
* (the `--tags` OptionSpec declares an array accumulator). Each element
|
|
9
|
+
* may itself be a comma-separated list; consumers flatten + trim.
|
|
10
|
+
*/
|
|
11
|
+
tags?: string[];
|
|
12
|
+
list: boolean;
|
|
13
|
+
recipes: boolean;
|
|
14
|
+
json: boolean;
|
|
15
|
+
verbose: boolean;
|
|
16
|
+
reportTo?: string;
|
|
17
|
+
apiKey?: string;
|
|
18
|
+
exclude: string[];
|
|
19
|
+
cwd: string;
|
|
20
|
+
/** Explicit path to opensip-cli.config.yml (overrides package.json pointer and default location). */
|
|
21
|
+
config?: string;
|
|
22
|
+
debug: boolean;
|
|
23
|
+
/** Suppress banner/boxes; show only the pass-fail summary line. */
|
|
24
|
+
quiet?: boolean;
|
|
25
|
+
/** Open the HTML report in the default browser after a successful run. */
|
|
26
|
+
open?: boolean;
|
|
27
|
+
/** Replay a stored fit session by id, or `latest` for the latest fit session. */
|
|
28
|
+
show?: string;
|
|
29
|
+
/** Architecture-gate: save the current run's findings as a baseline. Mutually exclusive with --gate-compare. */
|
|
30
|
+
gateSave?: boolean;
|
|
31
|
+
/** Architecture-gate: compare current findings against a saved baseline; exit 1 if regressions found. Mutually exclusive with --gate-save. */
|
|
32
|
+
gateCompare?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/** Options for the `init` subcommand. */
|
|
35
|
+
export interface InitOptions {
|
|
36
|
+
cwd: string;
|
|
37
|
+
json: boolean;
|
|
38
|
+
debug: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Language list. Repeatable and/or comma-separated: `--language ts
|
|
41
|
+
* --language rust` and `--language ts,rust` both accumulate (the
|
|
42
|
+
* `--language` OptionSpec declares an array accumulator). When omitted,
|
|
43
|
+
* init detects the project's primary language(s) by inspecting filesystem
|
|
44
|
+
* markers (Cargo.toml, pyproject.toml, etc.) and exits 2 with a prompt if
|
|
45
|
+
* the result is ambiguous.
|
|
46
|
+
*/
|
|
47
|
+
language?: string[];
|
|
48
|
+
/**
|
|
49
|
+
* Re-scaffold example files. Preserve any custom files in
|
|
50
|
+
* `opensip-cli/`. Mutually exclusive with `remove`.
|
|
51
|
+
*/
|
|
52
|
+
keep?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Delete `opensip-cli/` entirely, then scaffold fresh. Mutually
|
|
55
|
+
* exclusive with `keep`.
|
|
56
|
+
*/
|
|
57
|
+
remove?: boolean;
|
|
58
|
+
}
|
|
59
|
+
/** Options for `sim` subcommand. */
|
|
60
|
+
export interface ToolOptions {
|
|
61
|
+
cwd: string;
|
|
62
|
+
json: boolean;
|
|
63
|
+
debug: boolean;
|
|
64
|
+
/** Recipe name to run. Defaults to the built-in `default` if omitted. */
|
|
65
|
+
recipe?: string;
|
|
66
|
+
/**
|
|
67
|
+
* `--report-to <url>` — POST the run's signals to OpenSIP Cloud or a
|
|
68
|
+
* compatible receiver. sim gained cloud egress when it began emitting the
|
|
69
|
+
* signal envelope (ADR-0011, Phase 4); the composition root's
|
|
70
|
+
* `deliverSignals` owns the actual egress (and exit code 4).
|
|
71
|
+
*/
|
|
72
|
+
reportTo?: string;
|
|
73
|
+
/** `--api-key <key>` — auth for `--report-to`. */
|
|
74
|
+
apiKey?: string;
|
|
75
|
+
/** Replay a stored tool session by id, or `latest` for the latest session for this tool. */
|
|
76
|
+
show?: string;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAIA,uEAAuE;AACvE,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,qGAAqG;IACrG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,mEAAmE;IACnE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0EAA0E;IAC1E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gHAAgH;IAChH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8IAA8I;IAC9I,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,yCAAyC;AACzC,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,oCAAoC;AACpC,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4FAA4F;IAC5F,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,oBAAoB;AACpB,gFAAgF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verbose-detail builders (ADR-0021) — the shared transform from a run's
|
|
3
|
+
* `Signal[]` + units into the renderer-agnostic `FindingGroup[]` carried on a
|
|
4
|
+
* `*DoneResult` and rendered by the cli `resultToView` seam.
|
|
5
|
+
*
|
|
6
|
+
* Lives in contracts (next to `buildSignalEnvelope`) so fit and sim — peer
|
|
7
|
+
* packages that cannot import each other — share ONE mapping rather than each
|
|
8
|
+
* re-deriving it (which would also trip the `graph:duplicated-function-body`
|
|
9
|
+
* dogfood check). contracts may import `@opensip-cli/core` at runtime (the
|
|
10
|
+
* layer below it), so `isErrorSignal` is available here.
|
|
11
|
+
*/
|
|
12
|
+
import { type Signal } from '@opensip-cli/core';
|
|
13
|
+
import type { FindingGroup } from './command-results.js';
|
|
14
|
+
/** A unit identity the grouping needs: its slug and (optional) own error. */
|
|
15
|
+
export interface FindingGroupUnit {
|
|
16
|
+
readonly slug: string;
|
|
17
|
+
readonly error?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Group a run's signals by `signal.source` (the emitting unit's slug) into the
|
|
21
|
+
* verbose `FindingGroup[]` — one block per unit that emitted ≥1 finding or that
|
|
22
|
+
* errored. `displayName` resolves a unit slug to its pretty title (fitness
|
|
23
|
+
* passes its display registry; sim passes identity).
|
|
24
|
+
*/
|
|
25
|
+
export declare function buildFindingGroups(units: readonly FindingGroupUnit[], signals: readonly Signal[], displayName?: (slug: string) => string): FindingGroup[];
|
|
26
|
+
//# sourceMappingURL=verbose-detail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verbose-detail.d.ts","sourceRoot":"","sources":["../src/verbose-detail.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE/D,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,sBAAsB,CAAC;AAkBtE,6EAA6E;AAC7E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAkCD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,SAAS,gBAAgB,EAAE,EAClC,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,WAAW,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAuB,GACrD,YAAY,EAAE,CAShB"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verbose-detail builders (ADR-0021) — the shared transform from a run's
|
|
3
|
+
* `Signal[]` + units into the renderer-agnostic `FindingGroup[]` carried on a
|
|
4
|
+
* `*DoneResult` and rendered by the cli `resultToView` seam.
|
|
5
|
+
*
|
|
6
|
+
* Lives in contracts (next to `buildSignalEnvelope`) so fit and sim — peer
|
|
7
|
+
* packages that cannot import each other — share ONE mapping rather than each
|
|
8
|
+
* re-deriving it (which would also trip the `graph:duplicated-function-body`
|
|
9
|
+
* dogfood check). contracts may import `@opensip-cli/core` at runtime (the
|
|
10
|
+
* layer below it), so `isErrorSignal` is available here.
|
|
11
|
+
*/
|
|
12
|
+
import { isErrorSignal } from '@opensip-cli/core';
|
|
13
|
+
/** Map one `Signal` to a renderer-agnostic `FindingLine` (display fields only,
|
|
14
|
+
* 4-level severity collapsed to the 2-level error/warning rung). */
|
|
15
|
+
function toFindingLine(signal) {
|
|
16
|
+
let location;
|
|
17
|
+
if (signal.filePath !== '') {
|
|
18
|
+
location =
|
|
19
|
+
signal.line === undefined ? signal.filePath : `${signal.filePath}:${String(signal.line)}`;
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
severity: isErrorSignal(signal) ? 'error' : 'warning',
|
|
23
|
+
message: signal.message,
|
|
24
|
+
...(location === undefined ? {} : { location }),
|
|
25
|
+
...(signal.suggestion === undefined ? {} : { suggestion: signal.suggestion }),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/** Group a run's signals by `signal.source` (the emitting unit's slug). */
|
|
29
|
+
function indexBySource(signals) {
|
|
30
|
+
const bySource = new Map();
|
|
31
|
+
for (const signal of signals) {
|
|
32
|
+
const bucket = bySource.get(signal.source);
|
|
33
|
+
if (bucket)
|
|
34
|
+
bucket.push(signal);
|
|
35
|
+
else
|
|
36
|
+
bySource.set(signal.source, [signal]);
|
|
37
|
+
}
|
|
38
|
+
return bySource;
|
|
39
|
+
}
|
|
40
|
+
/** Build one finding group for a unit + its findings (counts the rungs). */
|
|
41
|
+
function groupForUnit(unit, findings, title) {
|
|
42
|
+
let errorCount = 0;
|
|
43
|
+
let warningCount = 0;
|
|
44
|
+
for (const s of findings) {
|
|
45
|
+
if (isErrorSignal(s))
|
|
46
|
+
errorCount += 1;
|
|
47
|
+
else
|
|
48
|
+
warningCount += 1;
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
title,
|
|
52
|
+
...(unit.error === undefined ? {} : { error: unit.error }),
|
|
53
|
+
errorCount,
|
|
54
|
+
warningCount,
|
|
55
|
+
findings: findings.map(toFindingLine),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Group a run's signals by `signal.source` (the emitting unit's slug) into the
|
|
60
|
+
* verbose `FindingGroup[]` — one block per unit that emitted ≥1 finding or that
|
|
61
|
+
* errored. `displayName` resolves a unit slug to its pretty title (fitness
|
|
62
|
+
* passes its display registry; sim passes identity).
|
|
63
|
+
*/
|
|
64
|
+
export function buildFindingGroups(units, signals, displayName = (slug) => slug) {
|
|
65
|
+
const bySource = indexBySource(signals);
|
|
66
|
+
const groups = [];
|
|
67
|
+
for (const unit of units) {
|
|
68
|
+
const findings = bySource.get(unit.slug) ?? [];
|
|
69
|
+
if (findings.length === 0 && unit.error === undefined)
|
|
70
|
+
continue;
|
|
71
|
+
groups.push(groupForUnit(unit, findings, displayName(unit.slug)));
|
|
72
|
+
}
|
|
73
|
+
return groups;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=verbose-detail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verbose-detail.js","sourceRoot":"","sources":["../src/verbose-detail.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verbose-detail.test.d.ts","sourceRoot":"","sources":["../src/verbose-detail.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { createSignal } from '@opensip-cli/core';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { buildFindingGroups } from './verbose-detail.js';
|
|
4
|
+
function sig(source, severity, message, file = 'a.ts', line) {
|
|
5
|
+
return createSignal({
|
|
6
|
+
source,
|
|
7
|
+
severity,
|
|
8
|
+
ruleId: `${source}-rule`,
|
|
9
|
+
message,
|
|
10
|
+
code: { file, line },
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
describe('buildFindingGroups', () => {
|
|
14
|
+
it('groups signals by source, collapses 4→2 severity, and counts each rung', () => {
|
|
15
|
+
const units = [{ slug: 'check-a' }, { slug: 'check-b' }];
|
|
16
|
+
const signals = [
|
|
17
|
+
sig('check-a', 'critical', 'boom', 'x.ts', 10),
|
|
18
|
+
sig('check-a', 'low', 'meh', 'y.ts'),
|
|
19
|
+
sig('check-b', 'high', 'bad', 'z.ts', 3),
|
|
20
|
+
];
|
|
21
|
+
const groups = buildFindingGroups(units, signals);
|
|
22
|
+
expect(groups).toHaveLength(2);
|
|
23
|
+
const a = groups[0];
|
|
24
|
+
expect(a.title).toBe('check-a'); // identity display name
|
|
25
|
+
expect(a.errorCount).toBe(1); // critical → error rung
|
|
26
|
+
expect(a.warningCount).toBe(1); // low → warning rung
|
|
27
|
+
expect(a.findings[0]).toEqual({ severity: 'error', message: 'boom', location: 'x.ts:10' });
|
|
28
|
+
expect(a.findings[1]).toEqual({ severity: 'warning', message: 'meh', location: 'y.ts' });
|
|
29
|
+
const b = groups[1];
|
|
30
|
+
expect(b.findings[0]).toEqual({ severity: 'error', message: 'bad', location: 'z.ts:3' });
|
|
31
|
+
});
|
|
32
|
+
it('applies the displayName resolver to the group title', () => {
|
|
33
|
+
const groups = buildFindingGroups([{ slug: 'no-todos' }], [sig('no-todos', 'high', 'x')], (s) => `Pretty ${s}`);
|
|
34
|
+
expect(groups[0].title).toBe('Pretty no-todos');
|
|
35
|
+
});
|
|
36
|
+
it('includes a unit that errored even with no signals; skips clean units', () => {
|
|
37
|
+
const units = [{ slug: 'errored', error: 'timed out' }, { slug: 'clean' }];
|
|
38
|
+
const groups = buildFindingGroups(units, []);
|
|
39
|
+
expect(groups).toHaveLength(1);
|
|
40
|
+
expect(groups[0]).toMatchObject({
|
|
41
|
+
title: 'errored',
|
|
42
|
+
error: 'timed out',
|
|
43
|
+
errorCount: 0,
|
|
44
|
+
warningCount: 0,
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
it('omits location when the signal has no file path', () => {
|
|
48
|
+
const s = createSignal({ source: 'u', severity: 'high', ruleId: 'r', message: 'no loc' });
|
|
49
|
+
const groups = buildFindingGroups([{ slug: 'u' }], [s]);
|
|
50
|
+
expect(groups[0].findings[0].location).toBeUndefined();
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=verbose-detail.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verbose-detail.test.js","sourceRoot":"","sources":["../src/verbose-detail.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* verdict-envelope — `buildSignalEnvelope`'s verdict computation (ADR-0035).
|
|
3
|
+
* Pins that `verdict.passed = !runFaulted && !unitErrored && policyPasses(...)`,
|
|
4
|
+
* and that the per-unit `summary.{passed,failed}` counts are INDEPENDENT of the
|
|
5
|
+
* run verdict (they feed the table; the verdict feeds the headline + exit code).
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=verdict-envelope.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verdict-envelope.test.d.ts","sourceRoot":"","sources":["../src/verdict-envelope.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* verdict-envelope — `buildSignalEnvelope`'s verdict computation (ADR-0035).
|
|
3
|
+
* Pins that `verdict.passed = !runFaulted && !unitErrored && policyPasses(...)`,
|
|
4
|
+
* and that the per-unit `summary.{passed,failed}` counts are INDEPENDENT of the
|
|
5
|
+
* run verdict (they feed the table; the verdict feeds the headline + exit code).
|
|
6
|
+
*/
|
|
7
|
+
import { createSignal, } from '@opensip-cli/core';
|
|
8
|
+
import { describe, expect, it } from 'vitest';
|
|
9
|
+
import { buildSignalEnvelope } from './signal-envelope.js';
|
|
10
|
+
function sig(severity) {
|
|
11
|
+
return createSignal({ source: 'u', severity, ruleId: `r-${severity}`, message: 'x' });
|
|
12
|
+
}
|
|
13
|
+
const FALLBACK = { failOnErrors: 1, failOnWarnings: 0 };
|
|
14
|
+
function verdictOf(opts) {
|
|
15
|
+
return buildSignalEnvelope({
|
|
16
|
+
tool: 'fit',
|
|
17
|
+
runId: 'r',
|
|
18
|
+
createdAt: '2026-01-01T00:00:00.000Z',
|
|
19
|
+
units: opts.units ?? [{ slug: 'a', passed: true, durationMs: 1 }],
|
|
20
|
+
signals: opts.signals ?? [],
|
|
21
|
+
policy: opts.policy ?? FALLBACK,
|
|
22
|
+
runFaulted: opts.runFaulted ?? false,
|
|
23
|
+
}).verdict;
|
|
24
|
+
}
|
|
25
|
+
describe('buildSignalEnvelope · verdict.passed (ADR-0035)', () => {
|
|
26
|
+
it('passes a clean run under the {1,0} fallback', () => {
|
|
27
|
+
expect(verdictOf({}).passed).toBe(true);
|
|
28
|
+
});
|
|
29
|
+
it('fails as soon as one error-rung signal is present', () => {
|
|
30
|
+
expect(verdictOf({ signals: [sig('high')] }).passed).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
it('passes a warning-only run under {1,0} (warnings informational)', () => {
|
|
33
|
+
expect(verdictOf({ signals: [sig('medium'), sig('low')] }).passed).toBe(true);
|
|
34
|
+
});
|
|
35
|
+
it('fails a warning-only run when failOnWarnings is active', () => {
|
|
36
|
+
expect(verdictOf({ signals: [sig('medium')], policy: { failOnErrors: 1, failOnWarnings: 1 } })
|
|
37
|
+
.passed).toBe(false);
|
|
38
|
+
});
|
|
39
|
+
it('tolerates errors when failOnErrors is 0 (ratchet/warn-only mode)', () => {
|
|
40
|
+
expect(verdictOf({
|
|
41
|
+
signals: [sig('high'), sig('critical')],
|
|
42
|
+
policy: { failOnErrors: 0, failOnWarnings: 0 },
|
|
43
|
+
}).passed).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
it('FAILS on a run-level fault (runFaulted) even with zero findings', () => {
|
|
46
|
+
expect(verdictOf({ signals: [], runFaulted: true }).passed).toBe(false);
|
|
47
|
+
});
|
|
48
|
+
it('FAILS when a unit carries an error, even with zero signals', () => {
|
|
49
|
+
const errored = { slug: 'boom', passed: false, durationMs: 1, error: 'exploded' };
|
|
50
|
+
expect(verdictOf({ units: [errored], signals: [] }).passed).toBe(false);
|
|
51
|
+
});
|
|
52
|
+
it('keeps summary.{passed,failed} independent of verdict.passed', () => {
|
|
53
|
+
// 1 failing unit (no error/signal) → summary.failed=1, but with no error
|
|
54
|
+
// signals and no fault the policy verdict still PASSES under {1,0}.
|
|
55
|
+
const v = verdictOf({
|
|
56
|
+
units: [
|
|
57
|
+
{ slug: 'a', passed: true, durationMs: 1 },
|
|
58
|
+
{ slug: 'b', passed: false, durationMs: 1 },
|
|
59
|
+
],
|
|
60
|
+
signals: [],
|
|
61
|
+
});
|
|
62
|
+
expect(v.summary.passed).toBe(1);
|
|
63
|
+
expect(v.summary.failed).toBe(1);
|
|
64
|
+
expect(v.passed).toBe(true);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
//# sourceMappingURL=verdict-envelope.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verdict-envelope.test.js","sourceRoot":"","sources":["../src/verdict-envelope.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@opensip-cli/contracts",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"description": "Shared contract types for OpenSIP CLI — SignalEnvelope / CommandResult shapes, exit codes, session persistence",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"opensip-cli",
|
|
8
|
+
"static-analysis",
|
|
9
|
+
"code-quality",
|
|
10
|
+
"types",
|
|
11
|
+
"contracts"
|
|
12
|
+
],
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/opensip-ai/opensip-cli.git",
|
|
16
|
+
"directory": "packages/contracts"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/opensip-ai/opensip-cli",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/opensip-ai/opensip-cli/issues"
|
|
21
|
+
},
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": "./dist/index.js"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"LICENSE",
|
|
31
|
+
"NOTICE"
|
|
32
|
+
],
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@opensip-cli/core": "0.1.0"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"commander": "^14.0.0 || ^15.0.0"
|
|
38
|
+
},
|
|
39
|
+
"peerDependenciesMeta": {
|
|
40
|
+
"commander": {
|
|
41
|
+
"optional": true
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^24.13.2",
|
|
46
|
+
"commander": "^15.0.0",
|
|
47
|
+
"typescript": "~6.0.3",
|
|
48
|
+
"vitest": "^4.1.8"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsc",
|
|
52
|
+
"test": "vitest run --passWithNoTests",
|
|
53
|
+
"typecheck": "tsc --noEmit",
|
|
54
|
+
"clean": "rm -rf dist"
|
|
55
|
+
}
|
|
56
|
+
}
|