@coderifts/agent-hooks 0.3.0 → 0.3.1
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/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +6 -0
- package/claude-code/hook.mjs +3 -3
- package/claude-code/marketplace-entry.json +1 -1
- package/gate.js +12 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.1 — 2026-10-04
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- **When CodeRifts could not decide, the refusal says so in one sentence** — the one the GitHub App, `coderifts claude-hook` and the CodeRifts mod write: `GOVERNANCE_UNAVAILABLE: CodeRifts could not decide (<why>); this is not a finding about your change.` It is added to the unreachable and unreadable-answer approvals (`gate.js`) and to the Claude hook's fail-closed messages (`claude-code/hook.mjs`); nothing that stopped now passes. `governanceUnavailable(why)` is exported from `gate.js`.
|
|
8
|
+
|
|
3
9
|
## 0.3.0 — 2026-10-03
|
|
4
10
|
|
|
5
11
|
### Changed
|
package/claude-code/hook.mjs
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
import { resolve } from "node:path";
|
|
20
20
|
import { pathToFileURL } from "node:url";
|
|
21
21
|
import { afterText, decideToolCall } from "../contract-write.mjs";
|
|
22
|
-
import { createGate, DOES_NOT_PROVE, hostIo } from "../gate.js";
|
|
22
|
+
import { createGate, DOES_NOT_PROVE, governanceUnavailable, hostIo } from "../gate.js";
|
|
23
23
|
|
|
24
24
|
/** The file after an Edit (`params` is the edit) or a MultiEdit (`params.edits`, in order): contract-write's afterText. */
|
|
25
25
|
export function applyEdits(params, before) {
|
|
@@ -135,7 +135,7 @@ export async function runClaudeHook(stdinText, { env = process.env, deps } = {})
|
|
|
135
135
|
const r = await shellDecision(String(payload.tool_input?.command ?? ""), hostIo(payload.cwd, deps?.readFile, deps?.listDir));
|
|
136
136
|
return r ? jsonDecision(r.decision, r.text) : emptyPass();
|
|
137
137
|
} catch (err) {
|
|
138
|
-
return failClosed(`CodeRifts Claude hook failed on a Bash call (${String(err?.message ?? err)}). Not knowing is not permission.`);
|
|
138
|
+
return failClosed(`CodeRifts Claude hook failed on a Bash call (${String(err?.message ?? err)}). ${governanceUnavailable("the Bash check failed")} Not knowing is not permission.`);
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
|
|
@@ -151,7 +151,7 @@ export async function runClaudeHook(stdinText, { env = process.env, deps } = {})
|
|
|
151
151
|
return mapGateResult(result);
|
|
152
152
|
} catch (err) {
|
|
153
153
|
return failClosed(
|
|
154
|
-
`CodeRifts Claude hook failed before a decision (${String(err?.message ?? err)}). Not knowing is not permission.`,
|
|
154
|
+
`CodeRifts Claude hook failed before a decision (${String(err?.message ?? err)}). ${governanceUnavailable("the hook failed before a decision")} Not knowing is not permission.`,
|
|
155
155
|
);
|
|
156
156
|
}
|
|
157
157
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"repo": "coderifts/agent-hooks"
|
|
6
6
|
},
|
|
7
7
|
"description": "Host adapters for CodeRifts: Claude Code PreToolUse asks before Write/Edit of OpenAPI, AsyncAPI, GraphQL, protobuf, or MCP manifest files. Not the GitHub Action (coderifts/contract-gate) and not the guard library (@coderifts/agent-guard).",
|
|
8
|
-
"version": "0.3.
|
|
8
|
+
"version": "0.3.1",
|
|
9
9
|
"author": {
|
|
10
10
|
"name": "CodeRifts",
|
|
11
11
|
"email": "peter@coderifts.com"
|
package/gate.js
CHANGED
|
@@ -122,6 +122,15 @@ export async function askCodeRifts({ endpoint, apiKey, timeoutMs, operation, art
|
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
/**
|
|
126
|
+
* GOVERNANCE_UNAVAILABLE (2026-10-04): the one sentence the App, the CLI hook and the Claude Code mod
|
|
127
|
+
* write verbatim when CodeRifts could not decide. The call still stops; the sentence says the stop is
|
|
128
|
+
* about CodeRifts, not about the change.
|
|
129
|
+
*/
|
|
130
|
+
export function governanceUnavailable(why) {
|
|
131
|
+
return `GOVERNANCE_UNAVAILABLE: CodeRifts could not decide (${why}); this is not a finding about your change.`;
|
|
132
|
+
}
|
|
133
|
+
|
|
125
134
|
/** Ask for a human, always with a reason. Never `{}`. */
|
|
126
135
|
const ask = (title, description) => ({
|
|
127
136
|
requireApproval: {
|
|
@@ -146,6 +155,7 @@ export function decide(outcome, { operation, path }) {
|
|
|
146
155
|
return ask(
|
|
147
156
|
"CodeRifts did not answer",
|
|
148
157
|
`${path} is a contract artifact and CodeRifts could not be reached (${outcome.detail}). ` +
|
|
158
|
+
`${governanceUnavailable(`CodeRifts could not be reached: ${outcome.detail}`)} ` +
|
|
149
159
|
`No decision was obtained, and not knowing is not permission.`,
|
|
150
160
|
);
|
|
151
161
|
}
|
|
@@ -153,7 +163,8 @@ export function decide(outcome, { operation, path }) {
|
|
|
153
163
|
return ask(
|
|
154
164
|
"CodeRifts answer could not be read",
|
|
155
165
|
`${path} is a contract artifact and CodeRifts replied with something this gate cannot interpret ` +
|
|
156
|
-
`(${outcome.detail}).
|
|
166
|
+
`(${outcome.detail}). ${governanceUnavailable(`the answer could not be read: ${outcome.detail}`)} ` +
|
|
167
|
+
`No decision was obtained, and not knowing is not permission.`,
|
|
157
168
|
);
|
|
158
169
|
}
|
|
159
170
|
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coderifts/agent-hooks",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Ask CodeRifts before an agent writes a contract artifact (OpenClaw before_tool_call and Claude Code PreToolUse).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/coderifts/agent-hooks#readme",
|