@coderifts/agent-hooks 0.3.1 → 0.3.2

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-hooks",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Ask CodeRifts before Claude Code writes a contract artifact (OpenAPI, AsyncAPI, GraphQL, protobuf, MCP manifest).",
5
5
  "author": {
6
6
  "name": "CodeRifts",
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.2 — 2026-10-06
4
+ ### Fixed
5
+ - **An MCP client configuration is never treated as a contract (contract-write 1.2.0, P65).** `.mcp.json`, `mcp.json`
6
+ (also under `.cursor/` and `.vscode/`), `claude_desktop_config.json` and `(cline_)mcp_settings.json`: an edit of one
7
+ sent its whole text, the servers' `env` credentials included, to CodeRifts preflight. They are decided by name and
8
+ never read; MCP tool manifests are unchanged.
9
+
3
10
  ## 0.3.1 — 2026-10-04
4
11
 
5
12
  ### Changed
@@ -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.1",
8
+ "version": "0.3.2",
9
9
  "author": {
10
10
  "name": "CodeRifts",
11
11
  "email": "peter@coderifts.com"
@@ -27,7 +27,7 @@
27
27
  // written by scripts/generate-contract-write-copies.js, byte for byte (the CommonJS twin is a
28
28
  // mechanical transform), and its --check fails on any difference. Do not edit a copy.
29
29
 
30
- export const CONTRACT_WRITE_VERSION = '1.1.0';
30
+ export const CONTRACT_WRITE_VERSION = '1.2.0';
31
31
 
32
32
  /** What a shell write to a named contract file gets, and what an unnamed one gets. */
33
33
  export const SHELL_NAMED_DECISION = 'refuse';
@@ -41,9 +41,21 @@ export const LISTING_LIMITS = Object.freeze({ depth: 8, entries: 5000 });
41
41
  /** The @coderifts/contract-path list (index.cjs), word for word; test/contract-write.test.js holds them equal. */
42
42
  export const CONTRACT_EXT = /\.(ya?ml|json|graphql|gql|proto)$/i;
43
43
 
44
+ /*
45
+ * 1.2.0 (2026-10-06, the Claude directory's hold MCP_FORWARDS_CREDENTIAL_ENV): an MCP CLIENT
46
+ * configuration file — the list of servers a client starts, with their `env` credentials — is not a
47
+ * contract. `.mcp.json` and `mcp.json` matched the list above (".json" + "mcp") as mcp_manifest, so an
48
+ * Edit of one sent its whole text, tokens included, to preflight. Decided by name, so the file is never
49
+ * read to decide; it wins over the project's own `schema:` list too. MCP tool manifests are unchanged.
50
+ * P65 (2026-10-06): the required check uses this same pattern — index.cjs requires it from here, and its
51
+ * looksLikeContractPath says no first, word for word as below.
52
+ */
53
+ export const MCP_CLIENT_CONFIG = /(^|\/)(\.?mcp\.json|claude_desktop_config\.json|(cline_)?mcp_settings\.json)$/i;
54
+
44
55
  export function looksLikeContractPath(p) {
45
56
  const s = String(p || '').toLowerCase();
46
57
  if (s.includes('node_modules/') || s.includes('vendor/')) return false;
58
+ if (MCP_CLIENT_CONFIG.test(s)) return false;
47
59
  return CONTRACT_EXT.test(s) && (s.includes('openapi') || s.includes('swagger') || s.includes('asyncapi')
48
60
  || s.endsWith('.graphql') || s.endsWith('.gql') || s.endsWith('.proto') || s.includes('mcp'));
49
61
  }
@@ -68,6 +80,7 @@ const HOOK_EXTRAS = Object.freeze([
68
80
  [/(^|\/)tools\.(wire\.v1\.)?json$/i, 'mcp_manifest'],
69
81
  ]);
70
82
 
83
+
71
84
  /** `a/./b/../c` → `a/c`; backslashes become slashes; a leading `./` goes. */
72
85
  export function normalizePath(p) {
73
86
  const s = String(p || '').replace(/\\/g, '/');
@@ -114,6 +127,7 @@ export function contractType(p, { named = [], excluded = [] } = {}) {
114
127
  const rel = normalizePath(p);
115
128
  if (!rel) return null;
116
129
  if (excluded.some((x) => matchesPattern(rel, x))) return null;
130
+ if (MCP_CLIENT_CONFIG.test(rel)) return null;
117
131
  for (const [re, type] of HOOK_EXTRAS) if (re.test(rel) && !/(^|\/)(node_modules|vendor)\//i.test(rel)) return type;
118
132
  if (looksLikeContractPath(rel)) return typeForPath(rel);
119
133
  if (named.some((x) => matchesPattern(rel, x))) return typeForPath(rel);
@@ -2,7 +2,7 @@
2
2
  "id": "coderifts-contract-gate",
3
3
  "name": "CodeRifts contract gate",
4
4
  "description": "Ask CodeRifts before an agent writes a contract artifact.",
5
- "version": "0.3.1",
5
+ "version": "0.3.2",
6
6
  "configSchema": {
7
7
  "type": "object",
8
8
  "additionalProperties": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coderifts/agent-hooks",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
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",