canary-test-cli 6.5.0 → 6.7.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/bin/canary.js +69 -1
- package/dist/doctor-manifest.js +6 -1
- package/dist/doctor.js +7 -4
- package/dist/engine/cli-commands.js +84 -25
- package/dist/engine/cli.core.js +1 -1
- package/dist/engine/core/framework-probes.js +218 -0
- package/dist/engine/core/framework-registry.js +4 -1
- package/dist/engine/core/fs-glob.js +185 -0
- package/dist/engine/core/gate-result.js +27 -4
- package/dist/engine/core/migrator.js +240 -289
- package/dist/engine/core/scaffold-templates.js +123 -0
- package/dist/engine/core/scaffolder.js +4 -105
- package/dist/engine/core/static-linter.js +169 -17
- package/dist/engine/core/workspace-detect.js +0 -0
- package/dist/engine/guardian/adjudication.js +34 -30
- package/dist/engine/guardian/analysis-emit.js +13 -4
- package/dist/engine/guardian/cli.js +113 -16
- package/dist/engine/guardian/coverage.js +291 -9
- package/dist/engine/guardian/github-paging.js +97 -0
- package/dist/engine/guardian/pr-check.js +285 -26
- package/dist/engine/guardian/pr-comment.js +29 -15
- package/dist/engine/history/async-store.js +20 -0
- package/dist/gate-result.js +27 -4
- package/dist/overlay-commands.js +31 -3
- package/package.json +2 -2
package/dist/gate-result.js
CHANGED
|
@@ -30,10 +30,33 @@ const CONTROL_CHARS = /[\u0000-\u001F\u007F]/g;
|
|
|
30
30
|
function skippedSuffix(skipped) {
|
|
31
31
|
if (!skipped || skipped.length === 0)
|
|
32
32
|
return '';
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
// #579: `reason` used to be write-only -- every caller set one and no
|
|
34
|
+
// surface ever rendered it, so a reader could see THAT a path was dropped
|
|
35
|
+
// but never WHY. Name and cause now travel together, keeping the D7
|
|
36
|
+
// contract that the path stays visible rather than collapsing into a bare
|
|
37
|
+
// count.
|
|
38
|
+
//
|
|
39
|
+
// Grouped by reason, because producers write reasons at very different
|
|
40
|
+
// grain: the guardian uses short tokens (`skipGlobs`), doctor uses whole
|
|
41
|
+
// remedy sentences. Repeating the reason per name turned one doctor line
|
|
42
|
+
// into 183 characters that said the same thing twice. Groups keep
|
|
43
|
+
// first-appearance order, so output stays deterministic.
|
|
44
|
+
//
|
|
45
|
+
// Reasons are control-char stripped for the same line-forging reason names
|
|
46
|
+
// are -- rendering the field is what made it an injection surface.
|
|
47
|
+
const groups = new Map();
|
|
48
|
+
for (const entry of skipped) {
|
|
49
|
+
const reason = entry.reason.replace(CONTROL_CHARS, '');
|
|
50
|
+
const names = groups.get(reason);
|
|
51
|
+
if (names)
|
|
52
|
+
names.push(entry.name.replace(CONTROL_CHARS, ''));
|
|
53
|
+
else
|
|
54
|
+
groups.set(reason, [entry.name.replace(CONTROL_CHARS, '')]);
|
|
55
|
+
}
|
|
56
|
+
const rendered = [...groups]
|
|
57
|
+
.map(([reason, names]) => reason ? `${names.join(', ')} [${reason}]` : names.join(', '))
|
|
58
|
+
.join('; ');
|
|
59
|
+
return ` (${skipped.length} skipped: ${rendered})`;
|
|
37
60
|
}
|
|
38
61
|
/**
|
|
39
62
|
* The single summary-line/exit-code path for swept commands.
|
package/dist/overlay-commands.js
CHANGED
|
@@ -109,7 +109,9 @@ function collectConsent(dest, name, confirm, out) {
|
|
|
109
109
|
}
|
|
110
110
|
const granted = confirm(`Allow 'canary doctor' to run these commands for "${name}"? [y/N] `);
|
|
111
111
|
if (!granted) {
|
|
112
|
-
out.write("Declined — 'canary doctor' will skip these command checks.
|
|
112
|
+
out.write("Declined — 'canary doctor' will skip these command checks. Run the same " +
|
|
113
|
+
"'canary overlay add' again to change this; it re-asks consent and " +
|
|
114
|
+
'never re-clones.\n');
|
|
113
115
|
}
|
|
114
116
|
return { consent: granted, consentCommandsHash: hash };
|
|
115
117
|
}
|
|
@@ -184,8 +186,34 @@ function add(source, options = {}, deps = {}) {
|
|
|
184
186
|
err.write(`canary overlay add: ${e.message}\n`);
|
|
185
187
|
return 1;
|
|
186
188
|
}
|
|
187
|
-
// Idempotent: re-adding a registered overlay
|
|
188
|
-
|
|
189
|
+
// Idempotent: re-adding a registered overlay never re-clones. It DOES
|
|
190
|
+
// re-run the consent prompt (#505), because `add` is the consent path every
|
|
191
|
+
// other surface points at -- doctor's skip remedy ("re-run 'canary overlay
|
|
192
|
+
// add'") and the decline message ("Re-add the overlay to change this") both
|
|
193
|
+
// said so while this branch returned before reaching `collectConsent`. The
|
|
194
|
+
// advice was a dead end: short of `overlay remove` + `add`, a user who
|
|
195
|
+
// declined once could never grant consent.
|
|
196
|
+
const existing = registry.get(reg, parsed.name);
|
|
197
|
+
if (existing) {
|
|
198
|
+
const refreshed = collectConsent(existing.path, parsed.name, deps.confirm ?? defaultConfirm, out);
|
|
199
|
+
if (refreshed.consentCommandsHash !== existing.consentCommandsHash ||
|
|
200
|
+
refreshed.consent !== existing.consent) {
|
|
201
|
+
const updated = {
|
|
202
|
+
...existing,
|
|
203
|
+
consent: refreshed.consent,
|
|
204
|
+
consentCommandsHash: refreshed.consentCommandsHash,
|
|
205
|
+
};
|
|
206
|
+
try {
|
|
207
|
+
registry.write({
|
|
208
|
+
...reg,
|
|
209
|
+
overlays: reg.overlays.map((o) => o.name === parsed.name ? updated : o),
|
|
210
|
+
}, homeDir);
|
|
211
|
+
}
|
|
212
|
+
catch (e) {
|
|
213
|
+
err.write(`canary overlay add: ${e.message}\n`);
|
|
214
|
+
return 1;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
189
217
|
out.write(`overlay "${parsed.name}" is already added — run 'canary overlay update ${parsed.name}' to refresh it.\n`);
|
|
190
218
|
return 0;
|
|
191
219
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "canary-test-cli",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.7.0",
|
|
4
4
|
"description": "Canary — AI-powered test automation agent",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"test": "tsc && node --test \"scripts/__tests__/*.test.js\""
|
|
35
35
|
},
|
|
36
36
|
"engines": {
|
|
37
|
-
"node": ">=
|
|
37
|
+
"node": ">=22"
|
|
38
38
|
},
|
|
39
39
|
"files": [
|
|
40
40
|
"bin/canary.js",
|