@zigrivers/mmr 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/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +21 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/config.d.ts +7 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +98 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/jobs.d.ts +7 -0
- package/dist/commands/jobs.d.ts.map +1 -0
- package/dist/commands/jobs.js +48 -0
- package/dist/commands/jobs.js.map +1 -0
- package/dist/commands/results.d.ts +9 -0
- package/dist/commands/results.d.ts.map +1 -0
- package/dist/commands/results.js +145 -0
- package/dist/commands/results.js.map +1 -0
- package/dist/commands/review.d.ts +18 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +203 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +56 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/config/defaults.d.ts +12 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +69 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/loader.d.ts +23 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +100 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +207 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +38 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/auth.d.ts +17 -0
- package/dist/core/auth.d.ts.map +1 -0
- package/dist/core/auth.js +60 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/dispatcher.d.ts +15 -0
- package/dist/core/dispatcher.d.ts.map +1 -0
- package/dist/core/dispatcher.js +107 -0
- package/dist/core/dispatcher.js.map +1 -0
- package/dist/core/job-store.d.ts +46 -0
- package/dist/core/job-store.d.ts.map +1 -0
- package/dist/core/job-store.js +141 -0
- package/dist/core/job-store.js.map +1 -0
- package/dist/core/parser.d.ts +16 -0
- package/dist/core/parser.d.ts.map +1 -0
- package/dist/core/parser.js +123 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core/prompt.d.ts +26 -0
- package/dist/core/prompt.d.ts.map +1 -0
- package/dist/core/prompt.js +53 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/core/reconciler.d.ts +17 -0
- package/dist/core/reconciler.d.ts.map +1 -0
- package/dist/core/reconciler.js +84 -0
- package/dist/core/reconciler.js.map +1 -0
- package/dist/formatters/json.d.ts +3 -0
- package/dist/formatters/json.d.ts.map +1 -0
- package/dist/formatters/json.js +4 -0
- package/dist/formatters/json.js.map +1 -0
- package/dist/formatters/markdown.d.ts +3 -0
- package/dist/formatters/markdown.d.ts.map +1 -0
- package/dist/formatters/markdown.js +36 -0
- package/dist/formatters/markdown.js.map +1 -0
- package/dist/formatters/text.d.ts +3 -0
- package/dist/formatters/text.d.ts.map +1 -0
- package/dist/formatters/text.js +31 -0
- package/dist/formatters/text.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +59 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +45 -0
- package/templates/core-prompt.md +33 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { SEVERITY_ORDER } from '../types.js';
|
|
2
|
+
function normalizeLocation(location) {
|
|
3
|
+
return location.toLowerCase().trim();
|
|
4
|
+
}
|
|
5
|
+
function higherSeverity(a, b) {
|
|
6
|
+
return SEVERITY_ORDER[a] <= SEVERITY_ORDER[b] ? a : b;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Reconcile findings from multiple channels into a unified list with
|
|
10
|
+
* consensus scoring.
|
|
11
|
+
*
|
|
12
|
+
* 1. Flatten all findings with source attribution
|
|
13
|
+
* 2. Group by normalized location
|
|
14
|
+
* 3. For each group, determine agreement, confidence, and effective severity
|
|
15
|
+
* 4. Sort by severity (P0 first)
|
|
16
|
+
*/
|
|
17
|
+
export function reconcile(channelFindings) {
|
|
18
|
+
// Step 1: Flatten with source attribution
|
|
19
|
+
const attributed = [];
|
|
20
|
+
for (const [source, findings] of Object.entries(channelFindings)) {
|
|
21
|
+
for (const finding of findings) {
|
|
22
|
+
attributed.push({ ...finding, source });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (attributed.length === 0)
|
|
26
|
+
return [];
|
|
27
|
+
// Step 2: Group by normalized location
|
|
28
|
+
const groups = new Map();
|
|
29
|
+
for (const finding of attributed) {
|
|
30
|
+
const key = normalizeLocation(finding.location);
|
|
31
|
+
const group = groups.get(key) ?? [];
|
|
32
|
+
group.push(finding);
|
|
33
|
+
groups.set(key, group);
|
|
34
|
+
}
|
|
35
|
+
// Step 3: Reconcile each group
|
|
36
|
+
const results = [];
|
|
37
|
+
for (const group of groups.values()) {
|
|
38
|
+
const sources = [...new Set(group.map((f) => f.source))];
|
|
39
|
+
const severities = [...new Set(group.map((f) => f.severity))];
|
|
40
|
+
const effectiveSeverity = severities.reduce(higherSeverity);
|
|
41
|
+
let agreement;
|
|
42
|
+
let confidence;
|
|
43
|
+
if (sources.length >= 2) {
|
|
44
|
+
if (severities.length === 1) {
|
|
45
|
+
// 2+ sources, same severity -> consensus, high
|
|
46
|
+
agreement = 'consensus';
|
|
47
|
+
confidence = 'high';
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
// 2+ sources, different severity -> majority, medium
|
|
51
|
+
agreement = 'majority';
|
|
52
|
+
confidence = 'medium';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// Single source -> unique
|
|
57
|
+
agreement = 'unique';
|
|
58
|
+
confidence = effectiveSeverity === 'P0' ? 'high' : 'medium';
|
|
59
|
+
}
|
|
60
|
+
// Use first finding's description/suggestion as representative
|
|
61
|
+
const representative = group[0];
|
|
62
|
+
results.push({
|
|
63
|
+
severity: effectiveSeverity,
|
|
64
|
+
location: representative.location,
|
|
65
|
+
description: representative.description,
|
|
66
|
+
suggestion: representative.suggestion,
|
|
67
|
+
confidence,
|
|
68
|
+
sources,
|
|
69
|
+
agreement,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
// Step 4: Sort by severity (P0 first)
|
|
73
|
+
results.sort((a, b) => SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity]);
|
|
74
|
+
return results;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Evaluate the quality gate: passes if no finding has severity at or above
|
|
78
|
+
* the threshold (i.e., no finding with SEVERITY_ORDER <= threshold order).
|
|
79
|
+
*/
|
|
80
|
+
export function evaluateGate(findings, threshold) {
|
|
81
|
+
const thresholdOrder = SEVERITY_ORDER[threshold];
|
|
82
|
+
return findings.every((f) => SEVERITY_ORDER[f.severity] > thresholdOrder);
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=reconciler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconciler.js","sourceRoot":"","sources":["../../src/core/reconciler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/formatters/json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEpD,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAE7D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/formatters/json.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,UAAU,CAAC,OAA0B;IACnD,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;AACzC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/formatters/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEpD,wBAAgB,cAAc,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAuCjE"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export function formatMarkdown(results) {
|
|
2
|
+
const lines = [];
|
|
3
|
+
const gate = results.gate_passed ? 'PASSED' : 'FAILED';
|
|
4
|
+
lines.push(`## Multi-Model Review — ${gate}`);
|
|
5
|
+
lines.push('');
|
|
6
|
+
lines.push(`**Job:** ${results.job_id} | **Threshold:** ${results.fix_threshold}` +
|
|
7
|
+
` | **Elapsed:** ${results.metadata.total_elapsed}`);
|
|
8
|
+
lines.push('');
|
|
9
|
+
if (results.reconciled_findings.length > 0) {
|
|
10
|
+
lines.push('### Findings');
|
|
11
|
+
lines.push('');
|
|
12
|
+
lines.push('| Severity | Location | Description | Suggestion | Sources | Agreement |');
|
|
13
|
+
lines.push('|----------|----------|-------------|------------|---------|-----------|');
|
|
14
|
+
for (const f of results.reconciled_findings) {
|
|
15
|
+
const src = f.sources.join(', ');
|
|
16
|
+
const esc = (s) => s.replace(/\|/g, '\\|');
|
|
17
|
+
const row = [
|
|
18
|
+
f.severity, f.location, esc(f.description),
|
|
19
|
+
esc(f.suggestion), src, f.agreement,
|
|
20
|
+
].map((c) => ` ${c} `).join('|');
|
|
21
|
+
lines.push(`|${row}|`);
|
|
22
|
+
}
|
|
23
|
+
lines.push('');
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
lines.push('No findings.');
|
|
27
|
+
lines.push('');
|
|
28
|
+
}
|
|
29
|
+
lines.push('### Channels');
|
|
30
|
+
lines.push('');
|
|
31
|
+
for (const [name, ch] of Object.entries(results.per_channel)) {
|
|
32
|
+
lines.push(`- **${name}:** ${ch.status} (${ch.elapsed})`);
|
|
33
|
+
}
|
|
34
|
+
return lines.join('\n');
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/formatters/markdown.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,cAAc,CAAC,OAA0B;IACvD,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAA;IAEtD,KAAK,CAAC,IAAI,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAA;IAC7C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACd,KAAK,CAAC,IAAI,CACR,YAAY,OAAO,CAAC,MAAM,qBAAqB,OAAO,CAAC,aAAa,EAAE;QACtE,mBAAmB,OAAO,CAAC,QAAQ,CAAC,aAAa,EAAE,CACpD,CAAA;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAEd,IAAI,OAAO,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QAC1B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACd,KAAK,CAAC,IAAI,CAAC,0EAA0E,CAAC,CAAA;QACtF,KAAK,CAAC,IAAI,CAAC,0EAA0E,CAAC,CAAA;QACtF,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;YAC5C,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAChC,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;YAClD,MAAM,GAAG,GAAG;gBACV,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;gBAC1C,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,SAAS;aACpC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAChC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,CAAA;QACxB,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAChB,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QAC1B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAChB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;IAC1B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACd,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7D,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,EAAE,CAAC,MAAM,KAAK,EAAE,CAAC,OAAO,GAAG,CAAC,CAAA;IAC3D,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/formatters/text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEpD,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAkC7D"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function formatText(results) {
|
|
2
|
+
const lines = [];
|
|
3
|
+
const gate = results.gate_passed ? 'PASSED' : 'FAILED';
|
|
4
|
+
lines.push(`MMR ${gate} — ${results.job_id}`);
|
|
5
|
+
const chCount = `${results.metadata.channels_completed}/${results.metadata.channels_dispatched}`;
|
|
6
|
+
lines.push(`Threshold: ${results.fix_threshold} | Channels: ${chCount}` +
|
|
7
|
+
` | Elapsed: ${results.metadata.total_elapsed}`);
|
|
8
|
+
lines.push('');
|
|
9
|
+
if (results.reconciled_findings.length > 0) {
|
|
10
|
+
lines.push(`Findings (${results.reconciled_findings.length}):`);
|
|
11
|
+
lines.push('');
|
|
12
|
+
for (const f of results.reconciled_findings) {
|
|
13
|
+
lines.push(` [${f.severity}] ${f.location}`);
|
|
14
|
+
lines.push(` ${f.description}`);
|
|
15
|
+
if (f.suggestion) {
|
|
16
|
+
lines.push(` Suggestion: ${f.suggestion}`);
|
|
17
|
+
}
|
|
18
|
+
lines.push(` Sources: ${f.sources.join(', ')} (${f.agreement})`);
|
|
19
|
+
lines.push('');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
lines.push('No findings.');
|
|
24
|
+
}
|
|
25
|
+
lines.push('Channels:');
|
|
26
|
+
for (const [name, ch] of Object.entries(results.per_channel)) {
|
|
27
|
+
lines.push(` ${name}: ${ch.status} (${ch.elapsed})`);
|
|
28
|
+
}
|
|
29
|
+
return lines.join('\n');
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/formatters/text.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,UAAU,CAAC,OAA0B;IACnD,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAA;IAEtD,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IAC7C,MAAM,OAAO,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,kBAAkB,IAAI,OAAO,CAAC,QAAQ,CAAC,mBAAmB,EAAE,CAAA;IAChG,KAAK,CAAC,IAAI,CACR,cAAc,OAAO,CAAC,aAAa,gBAAgB,OAAO,EAAE;QAC5D,eAAe,OAAO,CAAC,QAAQ,CAAC,aAAa,EAAE,CAChD,CAAA;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAEd,IAAI,OAAO,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,aAAa,OAAO,CAAC,mBAAmB,CAAC,MAAM,IAAI,CAAC,CAAA;QAC/D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACd,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;YAC5C,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAA;YAC7C,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,CAAA;YAClC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;gBACjB,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,UAAU,EAAE,CAAC,CAAA;YAC/C,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,CAAC,CAAA;YACnE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAChB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IACvB,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7D,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC,MAAM,KAAK,EAAE,CAAC,OAAO,GAAG,CAAC,CAAA;IACvD,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEjC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC1C,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export type Severity = 'P0' | 'P1' | 'P2' | 'P3';
|
|
2
|
+
export declare const SEVERITY_ORDER: Record<Severity, number>;
|
|
3
|
+
export type ChannelStatus = 'dispatched' | 'running' | 'completed' | 'timeout' | 'failed' | 'auth_failed' | 'skipped';
|
|
4
|
+
export type JobStatus = 'dispatched' | 'running' | 'completed';
|
|
5
|
+
export type Agreement = 'consensus' | 'majority' | 'unique' | 'divergent';
|
|
6
|
+
export type Confidence = 'high' | 'medium' | 'low';
|
|
7
|
+
export type OutputFormat = 'json' | 'text' | 'markdown' | 'sarif';
|
|
8
|
+
export interface Finding {
|
|
9
|
+
severity: Severity;
|
|
10
|
+
location: string;
|
|
11
|
+
description: string;
|
|
12
|
+
suggestion: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ReconciledFinding extends Finding {
|
|
15
|
+
confidence: Confidence;
|
|
16
|
+
sources: string[];
|
|
17
|
+
agreement: Agreement;
|
|
18
|
+
}
|
|
19
|
+
export interface ChannelResult {
|
|
20
|
+
status: ChannelStatus;
|
|
21
|
+
elapsed: string;
|
|
22
|
+
findings: Finding[];
|
|
23
|
+
raw_output?: string;
|
|
24
|
+
error?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface JobMetadata {
|
|
27
|
+
job_id: string;
|
|
28
|
+
status: JobStatus;
|
|
29
|
+
fix_threshold: Severity;
|
|
30
|
+
format: OutputFormat;
|
|
31
|
+
created_at: string;
|
|
32
|
+
channels: Record<string, ChannelJobEntry>;
|
|
33
|
+
}
|
|
34
|
+
export interface ChannelJobEntry {
|
|
35
|
+
status: ChannelStatus;
|
|
36
|
+
auth: 'ok' | 'failed' | 'skipped';
|
|
37
|
+
recovery?: string;
|
|
38
|
+
pid?: number;
|
|
39
|
+
started_at?: string;
|
|
40
|
+
completed_at?: string;
|
|
41
|
+
elapsed?: string;
|
|
42
|
+
findings_count?: number;
|
|
43
|
+
output_parser?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface ReconciledResults {
|
|
46
|
+
job_id: string;
|
|
47
|
+
gate_passed: boolean;
|
|
48
|
+
fix_threshold: Severity;
|
|
49
|
+
reconciled_findings: ReconciledFinding[];
|
|
50
|
+
per_channel: Record<string, ChannelResult>;
|
|
51
|
+
metadata: {
|
|
52
|
+
channels_dispatched: number;
|
|
53
|
+
channels_completed: number;
|
|
54
|
+
channels_partial: number;
|
|
55
|
+
total_elapsed: string;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export type { MmrConfigParsed as MmrConfig, ChannelConfigParsed as ChannelConfig } from './config/schema.js';
|
|
59
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAEhD,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAKnD,CAAA;AAED,MAAM,MAAM,aAAa,GACrB,YAAY,GACZ,SAAS,GACT,WAAW,GACX,SAAS,GACT,QAAQ,GACR,aAAa,GACb,SAAS,CAAA;AAEb,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,SAAS,GAAG,WAAW,CAAA;AAE9D,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAA;AAEzE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAA;AAElD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,CAAA;AAEjE,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,QAAQ,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,iBAAkB,SAAQ,OAAO;IAChD,UAAU,EAAE,UAAU,CAAA;IACtB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,SAAS,EAAE,SAAS,CAAA;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,aAAa,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,SAAS,CAAA;IACjB,aAAa,EAAE,QAAQ,CAAA;IACvB,MAAM,EAAE,YAAY,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;CAC1C;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,aAAa,CAAA;IACrB,IAAI,EAAE,IAAI,GAAG,QAAQ,GAAG,SAAS,CAAA;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,OAAO,CAAA;IACpB,aAAa,EAAE,QAAQ,CAAA;IACvB,mBAAmB,EAAE,iBAAiB,EAAE,CAAA;IACxC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IAC1C,QAAQ,EAAE;QACR,mBAAmB,EAAE,MAAM,CAAA;QAC3B,kBAAkB,EAAE,MAAM,CAAA;QAC1B,gBAAgB,EAAE,MAAM,CAAA;QACxB,aAAa,EAAE,MAAM,CAAA;KACtB,CAAA;CACF;AAID,YAAY,EAAE,eAAe,IAAI,SAAS,EAAE,mBAAmB,IAAI,aAAa,EAAE,MAAM,oBAAoB,CAAA"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAA6B;IACtD,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;CACN,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zigrivers/mmr",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Multi-model code review CLI — async dispatch, reconciliation, and severity gating",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/zigrivers/scaffold.git",
|
|
10
|
+
"directory": "packages/mmr"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public",
|
|
14
|
+
"registry": "https://registry.npmjs.org"
|
|
15
|
+
},
|
|
16
|
+
"files": ["dist/", "templates/", "README.md", "LICENSE"],
|
|
17
|
+
"engines": { "node": ">=18" },
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"bin": { "mmr": "dist/index.js" },
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc -p tsconfig.build.json",
|
|
23
|
+
"test": "vitest run",
|
|
24
|
+
"test:coverage": "vitest run --coverage",
|
|
25
|
+
"lint": "eslint src/",
|
|
26
|
+
"type-check": "tsc --noEmit",
|
|
27
|
+
"check": "npm run lint && npm run type-check && npm test"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"js-yaml": "^4.1.0",
|
|
31
|
+
"yargs": "^17.7.2",
|
|
32
|
+
"zod": "^3.24.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@eslint/js": "^9.21.0",
|
|
36
|
+
"@types/js-yaml": "^4.0.9",
|
|
37
|
+
"@types/node": "^22.13.0",
|
|
38
|
+
"@types/yargs": "^17.0.33",
|
|
39
|
+
"@vitest/coverage-v8": "^3.0.7",
|
|
40
|
+
"eslint": "^9.21.0",
|
|
41
|
+
"typescript": "^5.8.2",
|
|
42
|
+
"typescript-eslint": "^8.26.0",
|
|
43
|
+
"vitest": "^3.0.7"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
You are reviewing code changes. Return ONLY a JSON object with your findings.
|
|
2
|
+
|
|
3
|
+
## Severity Definitions
|
|
4
|
+
- P0 (Critical): Will cause failure, data loss, security vulnerability, or fundamental architectural flaw
|
|
5
|
+
- P1 (High): Will cause bugs in normal usage, inconsistency, or blocks downstream work
|
|
6
|
+
- P2 (Medium): Improvement opportunity — style, naming, documentation, minor optimization
|
|
7
|
+
- P3 (Trivial): Personal preference, trivial nits — only report if nothing else found
|
|
8
|
+
|
|
9
|
+
## Review Criteria
|
|
10
|
+
- Correctness: Does the logic do what it claims?
|
|
11
|
+
- Regressions: Does this break existing behavior?
|
|
12
|
+
- Edge cases: What inputs/states are unhandled?
|
|
13
|
+
- Test coverage: Are changes tested? Are tests meaningful?
|
|
14
|
+
- Security: Injection, auth bypass, data exposure?
|
|
15
|
+
|
|
16
|
+
## Output Format
|
|
17
|
+
Return valid JSON matching this schema exactly:
|
|
18
|
+
{
|
|
19
|
+
"approved": true | false,
|
|
20
|
+
"findings": [
|
|
21
|
+
{
|
|
22
|
+
"severity": "P0 | P1 | P2 | P3",
|
|
23
|
+
"location": "file:line",
|
|
24
|
+
"description": "what is wrong",
|
|
25
|
+
"suggestion": "specific fix"
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"summary": "one-line assessment"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
If no issues found, return: {"approved": true, "findings": [], "summary": "No issues found."}
|
|
32
|
+
|
|
33
|
+
Do NOT include markdown fences, preamble, or commentary outside the JSON object.
|