coderifts 8.0.0 → 8.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/CHANGELOG.md +13 -0
- package/README.md +23 -13
- package/bin/coderifts.js +6 -3
- package/dist/.build-source-sha +5 -0
- package/dist/cli.js +3839 -564
- package/package.json +5 -5
- package/scripts/assert-guard-major.js +9 -4
- package/scripts/build.js +44 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coderifts",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.1.0",
|
|
4
4
|
"description": "Detect breaking API changes from the command line. Works locally or with the CodeRifts cloud API.",
|
|
5
5
|
"author": "CodeRifts <hello@coderifts.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,17 +36,17 @@
|
|
|
36
36
|
"homepage": "https://coderifts.com",
|
|
37
37
|
"bugs": "https://github.com/coderifts/app/issues",
|
|
38
38
|
"engines": {
|
|
39
|
-
"node": ">=
|
|
39
|
+
"node": ">=20.0.0"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"build": "node scripts/copy-corpus.js && node scripts/build.js",
|
|
43
|
-
"prepublishOnly": "node scripts/assert-guard-major.js && node scripts/assert-changelog-version.js && bash ../../scripts/freeze-gate.sh && npm run build",
|
|
43
|
+
"prepublishOnly": "node scripts/assert-guard-major.js && node scripts/assert-changelog-version.js && bash ../../scripts/freeze-gate.sh && npm run build && bash ../../scripts/release-check.sh .",
|
|
44
44
|
"assert-guard-major": "node scripts/assert-guard-major.js",
|
|
45
45
|
"postinstall": "node scripts/postinstall.js",
|
|
46
46
|
"test": "node --test test/*.test.js"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@coderifts/agent-guard": "^
|
|
49
|
+
"@coderifts/agent-guard": "^16.0.0",
|
|
50
50
|
"chalk": "^4.1.2",
|
|
51
51
|
"cli-table3": "^0.6.4",
|
|
52
52
|
"commander": "^12.0.0",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"json-schema-ref-parser": "npm:@apidevtools/json-schema-ref-parser@^11.7.3",
|
|
61
61
|
"form-data": "^4.0.6",
|
|
62
62
|
"axios": ">=1.18.0",
|
|
63
|
-
"fast-uri": ">=
|
|
63
|
+
"fast-uri": ">=4.1.3",
|
|
64
64
|
"brace-expansion": "5.0.9"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
@@ -73,13 +73,16 @@
|
|
|
73
73
|
* asVerifiedDeployReceiptView, DEPLOY_RECEIPT_VIEW_SPEC and matchGlob — no DeployGateReason
|
|
74
74
|
* exhaustive switch, no V2 config-conflict throw. The raise is installer-facing: the range
|
|
75
75
|
* is what `npm i -g coderifts` resolves.)
|
|
76
|
+
* 8.1.0: floor raised to 16 (published guard 16.0.0 is on npm; 16 makes UNGUARDED_MUTATION
|
|
77
|
+
* fail-closed the default. The CLI range must match so `npm i -g coderifts` installs the guard
|
|
78
|
+
* whose default the docs describe, not the 15.x advisory-default it shipped alongside before.)
|
|
76
79
|
*/
|
|
77
80
|
|
|
78
81
|
const fs = require('fs');
|
|
79
82
|
const path = require('path');
|
|
80
83
|
|
|
81
84
|
/** Minimum acceptable major for @coderifts/agent-guard in THIS package (the CLI). */
|
|
82
|
-
const MIN_GUARD_MAJOR =
|
|
85
|
+
const MIN_GUARD_MAJOR = 16;
|
|
83
86
|
const DEP = '@coderifts/agent-guard';
|
|
84
87
|
|
|
85
88
|
/**
|
|
@@ -109,7 +112,7 @@ const CHECKOUTS = [
|
|
|
109
112
|
id: 'app-root',
|
|
110
113
|
label: 'coderifts-app (root)',
|
|
111
114
|
pkgPath: path.join(__dirname, '..', '..', '..', 'package.json'),
|
|
112
|
-
floor:
|
|
115
|
+
floor: 14,
|
|
113
116
|
/**
|
|
114
117
|
* DELIBERATE, MEASURED, AND LOWER THAN THE CLI'S — recorded so it is a decision, not a default.
|
|
115
118
|
*
|
|
@@ -159,8 +162,10 @@ const CHECKOUTS = [
|
|
|
159
162
|
* So the floor is pinned at 3 to stop it drifting LOWER unnoticed. Raise this number in that
|
|
160
163
|
* round and record the reason on the line below, in the style of the CLI history above.
|
|
161
164
|
*/
|
|
162
|
-
why: '
|
|
163
|
-
+ '
|
|
165
|
+
why: 'floor 14 = last measured merge-gate vintage (webhook-integration.js:344-345: '
|
|
166
|
+
+ 'gateDecision call/return unchanged on 14; protection_inescapable is derived in-app '
|
|
167
|
+
+ 'so a stale package cannot fail-open). Declared range is ^15 (installer). Floor is '
|
|
168
|
+
+ 'not forced to 15: root code does not consume 15-only APIs on this path.',
|
|
164
169
|
},
|
|
165
170
|
];
|
|
166
171
|
|
package/scripts/build.js
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
const path = require('path');
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const crypto = require('crypto');
|
|
11
13
|
const esbuild = require('esbuild');
|
|
12
14
|
|
|
13
15
|
const stub = path.join(__dirname, '..', 'src', 'logger-stub.js');
|
|
@@ -35,6 +37,48 @@ esbuild.build({
|
|
|
35
37
|
});
|
|
36
38
|
},
|
|
37
39
|
}],
|
|
40
|
+
}).then(() => {
|
|
41
|
+
// ── 1353: build freshness ────────────────────────────────────────────────────────────────
|
|
42
|
+
//
|
|
43
|
+
// MEASURED 2026-09-04: dist/cli.js still printed the pre-1305 verdict a day after the source
|
|
44
|
+
// fix. `prepublishOnly` DOES run the build — the premise that it did not is wrong — so the
|
|
45
|
+
// PUBLISHED artifact was never at risk. The gap is LOCAL: dist/ is gitignored and the globally
|
|
46
|
+
// linked `coderifts` points straight at it, so a developer edits src, sees a green suite over
|
|
47
|
+
// src, and runs a stale binary. So does the reviewer.
|
|
48
|
+
//
|
|
49
|
+
// The build records a fingerprint of the sources it consumed; test/build-freshness.test.js
|
|
50
|
+
// recomputes it and fails when dist is behind — catching what a suite over src alone cannot.
|
|
51
|
+
//
|
|
52
|
+
// CONTENT-ADDRESSED, not timestamps: mtimes move on checkout, rebase and copy without the bytes
|
|
53
|
+
// changing, and a freshness check that cries wolf gets deleted.
|
|
54
|
+
const root = path.join(__dirname, '..');
|
|
55
|
+
const files = [];
|
|
56
|
+
const walk = (dir) => {
|
|
57
|
+
if (!fs.existsSync(dir)) return;
|
|
58
|
+
for (const e of fs.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
59
|
+
if (e.name === 'node_modules' || e.name.startsWith('.')) continue;
|
|
60
|
+
const full = path.join(dir, e.name);
|
|
61
|
+
if (e.isDirectory()) walk(full);
|
|
62
|
+
else if (e.name.endsWith('.js')) files.push(full);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
walk(path.join(root, 'src'));
|
|
66
|
+
walk(path.join(root, 'bin'));
|
|
67
|
+
const h = crypto.createHash('sha256');
|
|
68
|
+
for (const f of files.sort()) {
|
|
69
|
+
h.update(path.relative(root, f));
|
|
70
|
+
h.update('\0');
|
|
71
|
+
h.update(fs.readFileSync(f));
|
|
72
|
+
h.update('\0');
|
|
73
|
+
}
|
|
74
|
+
const sha256 = h.digest('hex');
|
|
75
|
+
fs.writeFileSync(path.join(root, 'dist', '.build-source-sha'), `${JSON.stringify({
|
|
76
|
+
$comment: 'GENERATED by scripts/build.js. sha256 over src/**.js + bin/**.js (path + bytes). '
|
|
77
|
+
+ 'test/build-freshness.test.js recomputes it; a mismatch means dist/cli.js is stale.',
|
|
78
|
+
sha256,
|
|
79
|
+
file_count: files.length,
|
|
80
|
+
}, null, 2)}\n`);
|
|
81
|
+
process.stdout.write(`build: source fingerprint ${sha256.slice(0, 12)}… over ${files.length} files\n`);
|
|
38
82
|
}).catch((err) => {
|
|
39
83
|
console.error(err);
|
|
40
84
|
process.exit(1);
|