coderifts 4.9.0 → 4.10.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 +8 -0
- package/README.md +2 -1
- package/bin/coderifts.js +2 -0
- package/dist/cli.js +54 -10
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.10.0
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- **`coderifts init --agents --strict`** writes the STRICT contract-gate
|
|
7
|
+
workflow: `require-verified-monitoring: 'true'` (plus attestation /
|
|
8
|
+
keyring inputs). The default template is unchanged (monitoring stays
|
|
9
|
+
commented / false).
|
|
10
|
+
|
|
3
11
|
## 4.9.0
|
|
4
12
|
|
|
5
13
|
### Fixed
|
package/README.md
CHANGED
|
@@ -75,6 +75,7 @@ coderifts init --agents --hosts=cursor # Cursor only
|
|
|
75
75
|
coderifts init --agents --hosts=copilot # GitHub Copilot / VS Code only
|
|
76
76
|
coderifts init --agents --no-hook # skip host hook install
|
|
77
77
|
coderifts init --agents --no-workflow # skip .github/workflows/coderifts.yml
|
|
78
|
+
coderifts init --agents --strict # STRICT: require-verified-monitoring: true
|
|
78
79
|
coderifts init --agents --check # which of the four pieces are present
|
|
79
80
|
```
|
|
80
81
|
|
|
@@ -83,7 +84,7 @@ coderifts init --agents --check # which of the four pieces are present
|
|
|
83
84
|
| **MCP config** | `.mcp.json` (Claude Code), `.cursor/mcp.json` (Cursor), `.vscode/mcp.json` (Copilot / VS Code) | Three shapes, never normalised into one: Claude `mcpServers` + `type: "http"` + `url`; Cursor `mcpServers` + `url` only (no `type`); Copilot **`servers`** (not `mcpServers`) + `type: "http"` + `url`. Never `httpUrl` (that is Gemini, extension-level — this command does not write it). |
|
|
84
85
|
| **Agent rules** | generated host files via `agent-setup`'s writer | `AGENTS.md` is always written. Claude also gets `CLAUDE.md`; Cursor also gets `.cursor/rules/coderifts.mdc`; Copilot also gets `.github/copilot-instructions.md`. `--hosts=all` adds LangGraph and OpenAI instructions. (`coderifts init agent` is a different command — it writes a `.coderifts.yml` template.) |
|
|
85
86
|
| **Host hook** | `.claude/settings.json`, `.cursor/hooks.json` | Reuses `hook install --claude` / `--cursor` (JSON-merge, backup, idempotent). Copilot shares Claude's `.claude/settings.json` — VS Code reads it by default. |
|
|
86
|
-
| **CI workflow** | `.github/workflows/coderifts.yml` | `coderifts/contract-gate@v0`. `require-verified-monitoring`
|
|
87
|
+
| **CI workflow** | `.github/workflows/coderifts.yml` | `coderifts/contract-gate@v0`. Default: `require-verified-monitoring` commented (honest default: **false**). `--strict`: the same file with `require-verified-monitoring: 'true'` |
|
|
87
88
|
|
|
88
89
|
**Next manual step:** add `CODERIFTS_API_KEY` to the repository secrets. The
|
|
89
90
|
CLI never writes a key anywhere.
|
package/bin/coderifts.js
CHANGED
|
@@ -95,6 +95,7 @@ program
|
|
|
95
95
|
.option('--hosts <list>', 'With --agents: claude, cursor, copilot, or all (default: all)', 'all')
|
|
96
96
|
.option('--no-hook', 'With --agents: skip host hook install')
|
|
97
97
|
.option('--no-workflow', 'With --agents: skip writing .github/workflows/coderifts.yml')
|
|
98
|
+
.option('--strict', 'With --agents: STRICT workflow (require-verified-monitoring: true)')
|
|
98
99
|
.option('--dry-run', 'With --agents: print the plan without writing')
|
|
99
100
|
.option('--check', 'With --agents: report which of the four pieces are present (no write)')
|
|
100
101
|
.option('--out <dir>', 'With --agents: target directory (default: cwd)')
|
|
@@ -118,6 +119,7 @@ program
|
|
|
118
119
|
dryRun: !!options.dryRun,
|
|
119
120
|
check: !!options.check,
|
|
120
121
|
out: options.out,
|
|
122
|
+
strict: !!options.strict,
|
|
121
123
|
});
|
|
122
124
|
if (result && typeof result.exitCode === 'number') {
|
|
123
125
|
process.exitCode = result.exitCode;
|
package/dist/cli.js
CHANGED
|
@@ -3028,7 +3028,7 @@ var require_package = __commonJS({
|
|
|
3028
3028
|
"package.json"(exports2, module2) {
|
|
3029
3029
|
module2.exports = {
|
|
3030
3030
|
name: "coderifts",
|
|
3031
|
-
version: "4.
|
|
3031
|
+
version: "4.10.0",
|
|
3032
3032
|
description: "Detect breaking API changes from the command line. Works locally or with the CodeRifts cloud API.",
|
|
3033
3033
|
author: "CodeRifts <hello@coderifts.com>",
|
|
3034
3034
|
license: "MIT",
|
|
@@ -210222,6 +210222,46 @@ jobs:
|
|
|
210222
210222
|
# monitoring-attestation: \${{ vars.CODERIFTS_MONITORING_ATTESTATION }}
|
|
210223
210223
|
# monitoring-keyring: \${{ github.workspace }}/.coderifts/monitoring-keys.json
|
|
210224
210224
|
`;
|
|
210225
|
+
var STRICT_WORKFLOW_BODY = `# Written by \`coderifts init --agents --strict\`. Re-run is a no-op when this file already exists.
|
|
210226
|
+
#
|
|
210227
|
+
# STRICT template: require-verified-monitoring is ON.
|
|
210228
|
+
# This workflow POSTS the Check Run named exactly:
|
|
210229
|
+
# CodeRifts / contract-gate
|
|
210230
|
+
# It does NOT enable branch protection and it does NOT make that check required.
|
|
210231
|
+
# Turn the check on in repo settings to enforce (${ENFORCEMENT_DOC}).
|
|
210232
|
+
#
|
|
210233
|
+
# Copied from the gate repo example (examples/contract-gate.yml) \u2014 action at @v0.
|
|
210234
|
+
name: CodeRifts Contract Gate
|
|
210235
|
+
|
|
210236
|
+
# Run on EVERY pull request. Do NOT add paths: filters \u2014 a required check that
|
|
210237
|
+
# never runs leaves the PR mergeable (see ENFORCEMENT.md, "fail-closed on absence").
|
|
210238
|
+
on:
|
|
210239
|
+
pull_request:
|
|
210240
|
+
|
|
210241
|
+
permissions:
|
|
210242
|
+
checks: write
|
|
210243
|
+
contents: read
|
|
210244
|
+
|
|
210245
|
+
jobs:
|
|
210246
|
+
contract-gate:
|
|
210247
|
+
runs-on: ubuntu-latest
|
|
210248
|
+
steps:
|
|
210249
|
+
- uses: actions/checkout@v4
|
|
210250
|
+
with:
|
|
210251
|
+
# REQUIRED: the gate derives the change set from git diff base...head.
|
|
210252
|
+
fetch-depth: 0
|
|
210253
|
+
|
|
210254
|
+
- uses: ${GATE_ACTION}
|
|
210255
|
+
with:
|
|
210256
|
+
api-key: \${{ secrets.CODERIFTS_API_KEY }}
|
|
210257
|
+
# api-url: https://app.coderifts.com # override only for self-hosted
|
|
210258
|
+
require-verified-monitoring: 'true'
|
|
210259
|
+
monitoring-attestation: \${{ vars.CODERIFTS_MONITORING_ATTESTATION }}
|
|
210260
|
+
monitoring-keyring: \${{ github.workspace }}/.coderifts/monitoring-keys.json
|
|
210261
|
+
`;
|
|
210262
|
+
function workflowBody(strict) {
|
|
210263
|
+
return strict ? STRICT_WORKFLOW_BODY : WORKFLOW_BODY;
|
|
210264
|
+
}
|
|
210225
210265
|
function writeContractGateWorkflow(opts = {}) {
|
|
210226
210266
|
const outDir = opts.outDir;
|
|
210227
210267
|
const dest = path.join(outDir, WORKFLOW_REL);
|
|
@@ -210232,6 +210272,7 @@ jobs:
|
|
|
210232
210272
|
fs.writeFileSync(p, c, "utf8");
|
|
210233
210273
|
});
|
|
210234
210274
|
const dryRun = !!opts.dryRun;
|
|
210275
|
+
const body = workflowBody(!!opts.strict);
|
|
210235
210276
|
if (exists(dest)) {
|
|
210236
210277
|
let onDisk = "";
|
|
210237
210278
|
try {
|
|
@@ -210239,13 +210280,13 @@ jobs:
|
|
|
210239
210280
|
} catch {
|
|
210240
210281
|
onDisk = "";
|
|
210241
210282
|
}
|
|
210242
|
-
const reason = onDisk ===
|
|
210283
|
+
const reason = onDisk === body ? "already present, identical" : "exists; installer does not clobber workflows";
|
|
210243
210284
|
return { action: "skip", relPath: WORKFLOW_REL, reason, exitCode: 0 };
|
|
210244
210285
|
}
|
|
210245
210286
|
if (dryRun) {
|
|
210246
210287
|
return { action: "create", relPath: WORKFLOW_REL, reason: "created", exitCode: 0, dryRun: true };
|
|
210247
210288
|
}
|
|
210248
|
-
writeFile(dest,
|
|
210289
|
+
writeFile(dest, body);
|
|
210249
210290
|
return { action: "create", relPath: WORKFLOW_REL, reason: "created", exitCode: 0 };
|
|
210250
210291
|
}
|
|
210251
210292
|
function workflowPresent(outDir, deps = {}) {
|
|
@@ -210262,6 +210303,7 @@ jobs:
|
|
|
210262
210303
|
module2.exports = {
|
|
210263
210304
|
WORKFLOW_REL,
|
|
210264
210305
|
WORKFLOW_BODY,
|
|
210306
|
+
STRICT_WORKFLOW_BODY,
|
|
210265
210307
|
GATE_ACTION,
|
|
210266
210308
|
ENFORCEMENT_DOC,
|
|
210267
210309
|
writeContractGateWorkflow,
|
|
@@ -210293,7 +210335,7 @@ var require_init_agents = __commonJS({
|
|
|
210293
210335
|
workflowPresent
|
|
210294
210336
|
} = require_contract_gate_workflow();
|
|
210295
210337
|
if (process.env.NO_COLOR) chalk.level = 0;
|
|
210296
|
-
var USAGE = `Usage: coderifts init --agents [--hosts=claude,cursor,copilot,all] [--no-hook] [--no-workflow] [--dry-run] [--check] [--out <dir>]
|
|
210338
|
+
var USAGE = `Usage: coderifts init --agents [--hosts=claude,cursor,copilot,all] [--no-hook] [--no-workflow] [--strict] [--dry-run] [--check] [--out <dir>]
|
|
210297
210339
|
|
|
210298
210340
|
Wire this repository for governed agent work in ONE command:
|
|
210299
210341
|
1. repo-level MCP config (per host: .mcp.json / .cursor/mcp.json / .vscode/mcp.json)
|
|
@@ -210304,6 +210346,7 @@ var require_init_agents = __commonJS({
|
|
|
210304
210346
|
--hosts <list> claude, cursor, copilot, or all (default: all)
|
|
210305
210347
|
--no-hook Skip host hook install
|
|
210306
210348
|
--no-workflow Skip writing the CI workflow
|
|
210349
|
+
--strict STRICT workflow: require-verified-monitoring: true (default template stays false)
|
|
210307
210350
|
--dry-run Print the plan without writing
|
|
210308
210351
|
--check Report which of the four pieces are present (no write)
|
|
210309
210352
|
--out <dir> Target directory (default: cwd)
|
|
@@ -210363,9 +210406,9 @@ ${USAGE}`
|
|
|
210363
210406
|
return { hosts, allRules: false };
|
|
210364
210407
|
}
|
|
210365
210408
|
function agentFlagsRequireAgents(options = {}) {
|
|
210366
|
-
return !!(options.check || options.dryRun || options.out || options.hosts != null && String(options.hosts) !== "all" || options.hook === false || options.workflow === false || options.noHook === true || options.noWorkflow === true);
|
|
210409
|
+
return !!(options.check || options.dryRun || options.out || options.hosts != null && String(options.hosts) !== "all" || options.hook === false || options.workflow === false || options.noHook === true || options.noWorkflow === true || options.strict === true);
|
|
210367
210410
|
}
|
|
210368
|
-
var AGENT_FLAGS_REQUIRE_AGENTS = "Error: --check/--dry-run/--out/--hosts/--no-hook/--no-workflow require --agents";
|
|
210411
|
+
var AGENT_FLAGS_REQUIRE_AGENTS = "Error: --check/--dry-run/--out/--hosts/--no-hook/--no-workflow/--strict require --agents";
|
|
210369
210412
|
var AGENTS_NO_TEMPLATE = "Error: init --agents does not take a template. Did you mean `coderifts init --agents` (not `coderifts init agent`)?";
|
|
210370
210413
|
function rulePathsForHosts(hosts, allRules) {
|
|
210371
210414
|
const out = [SHARED_RULE];
|
|
@@ -210628,12 +210671,12 @@ ${USAGE}`
|
|
|
210628
210671
|
if (!wantWorkflow(options)) {
|
|
210629
210672
|
items.push({ section: "workflow", action: "skip", relPath: WORKFLOW_REL, note: "--no-workflow" });
|
|
210630
210673
|
} else {
|
|
210631
|
-
const r = writeContractGateWorkflow({ outDir, dryRun, ...fsDeps });
|
|
210674
|
+
const r = writeContractGateWorkflow({ outDir, dryRun, strict: !!options.strict, ...fsDeps });
|
|
210632
210675
|
items.push({
|
|
210633
210676
|
section: "workflow",
|
|
210634
210677
|
action: r.action,
|
|
210635
210678
|
relPath: r.relPath,
|
|
210636
|
-
note: r.action === "create" ? `${GATE_ACTION}` : r.reason
|
|
210679
|
+
note: r.action === "create" ? options.strict ? `${GATE_ACTION} (STRICT require-verified-monitoring)` : GATE_ACTION : r.reason
|
|
210637
210680
|
});
|
|
210638
210681
|
}
|
|
210639
210682
|
const created = items.filter((i) => i.action === "create").length;
|
|
@@ -241087,7 +241130,7 @@ program.command("registry-gate [dir]").description("Admit a directory of OpenAPI
|
|
|
241087
241130
|
process.exitCode = code;
|
|
241088
241131
|
process.exit(code);
|
|
241089
241132
|
});
|
|
241090
|
-
program.command("init [template]").description("Generate a .coderifts.yml from a policy template, or wire governed agent work (--agents)").option("--agents", "Wire this repo for governed agent work (MCP config, rule files, host hook, CI gate)").option("--hosts <list>", "With --agents: claude, cursor, copilot, or all (default: all)", "all").option("--no-hook", "With --agents: skip host hook install").option("--no-workflow", "With --agents: skip writing .github/workflows/coderifts.yml").option("--dry-run", "With --agents: print the plan without writing").option("--check", "With --agents: report which of the four pieces are present (no write)").option("--out <dir>", "With --agents: target directory (default: cwd)").action(async (template, options) => {
|
|
241133
|
+
program.command("init [template]").description("Generate a .coderifts.yml from a policy template, or wire governed agent work (--agents)").option("--agents", "Wire this repo for governed agent work (MCP config, rule files, host hook, CI gate)").option("--hosts <list>", "With --agents: claude, cursor, copilot, or all (default: all)", "all").option("--no-hook", "With --agents: skip host hook install").option("--no-workflow", "With --agents: skip writing .github/workflows/coderifts.yml").option("--strict", "With --agents: STRICT workflow (require-verified-monitoring: true)").option("--dry-run", "With --agents: print the plan without writing").option("--check", "With --agents: report which of the four pieces are present (no write)").option("--out <dir>", "With --agents: target directory (default: cwd)").action(async (template, options) => {
|
|
241091
241134
|
const {
|
|
241092
241135
|
runInitAgents,
|
|
241093
241136
|
agentFlagsRequireAgents,
|
|
@@ -241106,7 +241149,8 @@ program.command("init [template]").description("Generate a .coderifts.yml from a
|
|
|
241106
241149
|
workflow: options.workflow,
|
|
241107
241150
|
dryRun: !!options.dryRun,
|
|
241108
241151
|
check: !!options.check,
|
|
241109
|
-
out: options.out
|
|
241152
|
+
out: options.out,
|
|
241153
|
+
strict: !!options.strict
|
|
241110
241154
|
});
|
|
241111
241155
|
if (result && typeof result.exitCode === "number") {
|
|
241112
241156
|
process.exitCode = result.exitCode;
|
package/package.json
CHANGED