@cleocode/adapters 2026.10.8 → 2026.10.9-rc.ci.676
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/dist/heavy-command-hook.js +13 -12
- package/dist/heavy-command-hook.js.map +1 -1
- package/dist/index.js +60 -133
- package/dist/index.js.map +2 -2
- package/dist/project-hook-delivery.d.ts +6 -0
- package/dist/project-hook-delivery.d.ts.map +1 -0
- package/dist/project-hook-delivery.js +527 -0
- package/dist/project-hook-delivery.js.map +6 -0
- package/dist/project-hook-native.d.ts +7 -0
- package/dist/project-hook-native.d.ts.map +1 -0
- package/dist/project-hook-native.js +84 -0
- package/dist/project-hook-native.js.map +6 -0
- package/dist/providers/claude-code/hooks.d.ts.map +1 -1
- package/dist/providers/codex/hooks.d.ts +5 -4
- package/dist/providers/codex/hooks.d.ts.map +1 -1
- package/dist/providers/cursor/hooks.d.ts.map +1 -1
- package/dist/providers/gemini-cli/hooks.d.ts.map +1 -1
- package/dist/providers/opencode/hooks.d.ts.map +1 -1
- package/dist/providers/pi/hooks.d.ts.map +1 -1
- package/dist/providers/shared/heavy-command-hook-install.d.ts +2 -1
- package/dist/providers/shared/heavy-command-hook-install.d.ts.map +1 -1
- package/package.json +14 -5
- package/src/__tests__/project-hook-delivery.test.ts +319 -0
- package/src/project-hook-delivery.ts +532 -0
- package/src/project-hook-native.ts +128 -0
- package/src/providers/claude-code/hooks.ts +2 -30
- package/src/providers/codex/hooks.ts +7 -9
- package/src/providers/cursor/hooks.ts +2 -22
- package/src/providers/gemini-cli/hooks.ts +2 -12
- package/src/providers/opencode/hooks.ts +2 -22
- package/src/providers/pi/hooks.ts +2 -26
- package/src/providers/shared/heavy-command-hook-install.ts +21 -10
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type ProjectHookDeliveryOptions, type ProjectHookDeliveryResult } from '@cleocode/contracts/project-hook-delivery.js';
|
|
2
|
+
/** Report unsupported bindings even when the same provider delivered other eligible events. */
|
|
3
|
+
export declare function hasUnsupportedProjectHookDelivery(results: readonly ProjectHookDeliveryResult[]): boolean;
|
|
4
|
+
/** Inspect or sync only project-local entries; no provider trust settings are written. */
|
|
5
|
+
export declare function syncProjectHookProviders(options: ProjectHookDeliveryOptions): Promise<ProjectHookDeliveryResult[]>;
|
|
6
|
+
//# sourceMappingURL=project-hook-delivery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-hook-delivery.d.ts","sourceRoot":"","sources":["../src/project-hook-delivery.ts"],"names":[],"mappings":"AAeA,OAAO,EAGL,KAAK,0BAA0B,EAG/B,KAAK,yBAAyB,EAG/B,MAAM,8CAA8C,CAAC;AAwZtD,+FAA+F;AAC/F,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,SAAS,yBAAyB,EAAE,GAC5C,OAAO,CAUT;AAqCD,0FAA0F;AAC1F,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,yBAAyB,EAAE,CAAC,CA8CtC"}
|
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
// packages/adapters/src/project-hook-delivery.ts
|
|
2
|
+
import { execFileSync as execFileSync2, spawnSync } from "node:child_process";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
5
|
+
import { lstat, realpath, unlink } from "node:fs/promises";
|
|
6
|
+
import { homedir } from "node:os";
|
|
7
|
+
import { dirname as dirname2, isAbsolute as isAbsolute2, join as join2, relative, resolve as resolve2, sep } from "node:path";
|
|
8
|
+
import {
|
|
9
|
+
editJsonConfigFile,
|
|
10
|
+
readManagedJsonConfigFile,
|
|
11
|
+
withFileLock,
|
|
12
|
+
writeFileAtomic
|
|
13
|
+
} from "@cleocode/caamp/atomic";
|
|
14
|
+
import { GENERATED_PROVIDER_HOOK_PROFILES } from "@cleocode/caamp/hooks";
|
|
15
|
+
import {
|
|
16
|
+
ProjectHookDeliveryReceiptSchema
|
|
17
|
+
} from "@cleocode/contracts/project-hook-delivery.js";
|
|
18
|
+
|
|
19
|
+
// packages/adapters/src/providers/shared/heavy-command-hook-install.ts
|
|
20
|
+
import { execFileSync } from "node:child_process";
|
|
21
|
+
import {
|
|
22
|
+
existsSync,
|
|
23
|
+
mkdirSync,
|
|
24
|
+
readdirSync,
|
|
25
|
+
readFileSync,
|
|
26
|
+
realpathSync,
|
|
27
|
+
rmSync,
|
|
28
|
+
statSync,
|
|
29
|
+
writeFileSync
|
|
30
|
+
} from "node:fs";
|
|
31
|
+
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
32
|
+
import { updateJsonConfigFile } from "@cleocode/caamp";
|
|
33
|
+
var OPENCODE_HEAVY_COMMAND_PLUGIN = "cleo-heavy-command.js";
|
|
34
|
+
var HEAVY_TOOL_WORDS = Object.freeze([
|
|
35
|
+
"vitest",
|
|
36
|
+
"jest",
|
|
37
|
+
"mocha",
|
|
38
|
+
"ava",
|
|
39
|
+
"tap",
|
|
40
|
+
"playwright",
|
|
41
|
+
"pytest",
|
|
42
|
+
"rspec",
|
|
43
|
+
"phpunit",
|
|
44
|
+
"tsc",
|
|
45
|
+
"tsup",
|
|
46
|
+
"turbo",
|
|
47
|
+
"vite",
|
|
48
|
+
"esbuild",
|
|
49
|
+
"webpack",
|
|
50
|
+
"rollup",
|
|
51
|
+
"next",
|
|
52
|
+
"nx",
|
|
53
|
+
"biome",
|
|
54
|
+
"eslint",
|
|
55
|
+
"svelte-check",
|
|
56
|
+
"npm",
|
|
57
|
+
"pnpm",
|
|
58
|
+
"yarn",
|
|
59
|
+
"bun",
|
|
60
|
+
"npx",
|
|
61
|
+
"pnpx",
|
|
62
|
+
"bunx",
|
|
63
|
+
"cargo",
|
|
64
|
+
"go"
|
|
65
|
+
]);
|
|
66
|
+
var OLDER_CLEO_HOOK_ANSWER = JSON.stringify({
|
|
67
|
+
hookSpecificOutput: {
|
|
68
|
+
hookEventName: "PreToolUse",
|
|
69
|
+
additionalContext: "[cleo] This may be a heavy command, but the cleo on PATH predates cleo hook and cleo run, so it runs outside the machine-wide resource budget. Upgrade CLEO to govern it."
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
var HOOK_FILE_EXCLUDE_MARKER = "# cleo-hook: keep a per-machine heavy-command hook file out of git (T13124)";
|
|
73
|
+
var OPENCODE_PLUGIN_FILE = `.opencode/plugins/${OPENCODE_HEAVY_COMMAND_PLUGIN}`;
|
|
74
|
+
function gitOutput(projectDir, args, env = process.env) {
|
|
75
|
+
try {
|
|
76
|
+
return execFileSync("git", ["-C", projectDir, ...args], {
|
|
77
|
+
encoding: "utf-8",
|
|
78
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
79
|
+
timeout: 5e3,
|
|
80
|
+
env
|
|
81
|
+
}).trim();
|
|
82
|
+
} catch {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function excludeFile(projectDir, env = process.env) {
|
|
87
|
+
if (gitOutput(projectDir, ["rev-parse", "--is-inside-work-tree"], env) !== "true") return null;
|
|
88
|
+
const path = gitOutput(projectDir, ["rev-parse", "--git-path", "info/exclude"], env);
|
|
89
|
+
if (path === null || path === "") return null;
|
|
90
|
+
return isAbsolute(path) ? path : join(projectDir, path);
|
|
91
|
+
}
|
|
92
|
+
function excludeLine(projectDir, relPath, env = process.env) {
|
|
93
|
+
const prefix = gitOutput(projectDir, ["rev-parse", "--show-prefix"], env) ?? "";
|
|
94
|
+
return `/${prefix}${relPath}`;
|
|
95
|
+
}
|
|
96
|
+
function excludeHookFileFromGit(projectDir, relPath, marker = HOOK_FILE_EXCLUDE_MARKER, env = process.env) {
|
|
97
|
+
const exclude = excludeFile(projectDir, env);
|
|
98
|
+
if (exclude === null) return false;
|
|
99
|
+
if (gitOutput(projectDir, ["check-ignore", relPath], env) !== null) return false;
|
|
100
|
+
if (gitOutput(projectDir, ["ls-files", "--error-unmatch", relPath], env) !== null) return false;
|
|
101
|
+
const line = excludeLine(projectDir, relPath, env);
|
|
102
|
+
const text = existsSync(exclude) ? readFileSync(exclude, "utf-8") : "";
|
|
103
|
+
if (text.split("\n").includes(line)) return false;
|
|
104
|
+
const block = `${marker}
|
|
105
|
+
${line}
|
|
106
|
+
`;
|
|
107
|
+
mkdirSync(dirname(exclude), { recursive: true });
|
|
108
|
+
writeFileSync(exclude, text === "" || text.endsWith("\n") ? text + block : `${text}
|
|
109
|
+
${block}`);
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// packages/adapters/src/project-hook-delivery.ts
|
|
114
|
+
var MARKER = "# cleo-project-hook:v1";
|
|
115
|
+
var BINARIES = {
|
|
116
|
+
"claude-code": "claude",
|
|
117
|
+
codex: "codex",
|
|
118
|
+
opencode: "opencode",
|
|
119
|
+
kimi: "kimi"
|
|
120
|
+
};
|
|
121
|
+
var hash = (value) => createHash("sha256").update(value).digest("hex");
|
|
122
|
+
var object = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
123
|
+
function probeVersion(provider) {
|
|
124
|
+
const binary = BINARIES[provider];
|
|
125
|
+
if (!binary) return void 0;
|
|
126
|
+
try {
|
|
127
|
+
return execFileSync2(binary, ["--version"], {
|
|
128
|
+
encoding: "utf8",
|
|
129
|
+
timeout: 2e3,
|
|
130
|
+
maxBuffer: 8192,
|
|
131
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
132
|
+
}).match(/\d+\.\d+\.\d+/)?.[0];
|
|
133
|
+
} catch {
|
|
134
|
+
return void 0;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async function localTarget(root, path) {
|
|
138
|
+
if (await realpath(root) === await realpath(homedir()))
|
|
139
|
+
throw new Error("HOOK_GLOBAL_CONFIG_FORBIDDEN");
|
|
140
|
+
if (isAbsolute2(path) || path.split(/[\\/]/).includes(".."))
|
|
141
|
+
throw new Error("HOOK_CONFIG_PATH_ESCAPE");
|
|
142
|
+
const target = resolve2(root, path);
|
|
143
|
+
let ancestor = target;
|
|
144
|
+
while (!existsSync2(ancestor)) ancestor = dirname2(ancestor);
|
|
145
|
+
const resolved = await realpath(ancestor);
|
|
146
|
+
const rel = relative(await realpath(root), resolved);
|
|
147
|
+
if (rel === ".." || rel.startsWith(".." + sep) || isAbsolute2(rel))
|
|
148
|
+
throw new Error("HOOK_CONFIG_PATH_ESCAPE");
|
|
149
|
+
if (existsSync2(target) && (await lstat(target)).isSymbolicLink())
|
|
150
|
+
throw new Error("HOOK_CONFIG_SYMLINK");
|
|
151
|
+
return target;
|
|
152
|
+
}
|
|
153
|
+
function command(provider, event) {
|
|
154
|
+
const invocation = "cleo hook run --source agent --provider " + provider + " --event " + event;
|
|
155
|
+
return 'if command -v cleo >/dev/null 2>&1 && [ "$(cleo hook run --probe </dev/null 2>/dev/null)" = "CLEO_PROJECT_HOOK_V1" ]; then ' + invocation + '; else printf "%s\\n" "[cleo hook] project runner unavailable; operation allowed. Run cleo doctor hooks." >&2; fi # cleo-hook ' + MARKER;
|
|
156
|
+
}
|
|
157
|
+
function desiredEntries(provider, events) {
|
|
158
|
+
const profile = GENERATED_PROVIDER_HOOK_PROFILES[provider];
|
|
159
|
+
const result = [];
|
|
160
|
+
for (const canonical of new Set(events)) {
|
|
161
|
+
const mapping = Object.entries(profile?.mappings ?? {}).find(
|
|
162
|
+
([event]) => event === canonical
|
|
163
|
+
)?.[1];
|
|
164
|
+
if (!mapping?.supported || !mapping.nativeName || !/^[A-Za-z][A-Za-z0-9]*$/.test(canonical))
|
|
165
|
+
continue;
|
|
166
|
+
const cmd = command(provider, canonical);
|
|
167
|
+
result.push({
|
|
168
|
+
event: mapping.nativeName,
|
|
169
|
+
command: cmd,
|
|
170
|
+
hash: hash(JSON.stringify(entry(cmd)))
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
function entry(cmd, timeout = 130) {
|
|
176
|
+
return {
|
|
177
|
+
matcher: "",
|
|
178
|
+
hooks: [{ type: "command", command: cmd, ...timeout === null ? {} : { timeout } }]
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
async function receiptAt(path, services) {
|
|
182
|
+
try {
|
|
183
|
+
const info = await lstat(path);
|
|
184
|
+
if (!info.isFile() || info.isSymbolicLink() || info.size > 262144)
|
|
185
|
+
throw new Error("HOOK_RECEIPT_UNSAFE");
|
|
186
|
+
return ProjectHookDeliveryReceiptSchema.parse(
|
|
187
|
+
JSON.parse(await services.readTextFile(path, 262144))
|
|
188
|
+
);
|
|
189
|
+
} catch (error) {
|
|
190
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") return void 0;
|
|
191
|
+
throw new Error("HOOK_RECEIPT_INVALID");
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function entryCommand(value) {
|
|
195
|
+
if (!object(value) || !Array.isArray(value.hooks) || value.hooks.length !== 1) return void 0;
|
|
196
|
+
const hook = value.hooks[0];
|
|
197
|
+
return object(hook) && typeof hook.command === "string" ? hook.command : void 0;
|
|
198
|
+
}
|
|
199
|
+
function inspectEntries(config, receipt) {
|
|
200
|
+
const result = [];
|
|
201
|
+
if (!object(config.hooks)) return result;
|
|
202
|
+
for (const [event, entries] of Object.entries(config.hooks)) {
|
|
203
|
+
if (!Array.isArray(entries)) continue;
|
|
204
|
+
for (const [index, value] of entries.entries()) {
|
|
205
|
+
const digest = hash(JSON.stringify(value));
|
|
206
|
+
const owned = receipt?.entries.some((item) => item.event === event && item.hash === digest);
|
|
207
|
+
result.push({
|
|
208
|
+
event,
|
|
209
|
+
index,
|
|
210
|
+
hash: digest,
|
|
211
|
+
owner: owned ? "project" : "unknown",
|
|
212
|
+
provenance: owned ? "cleo-receipt" : "unknown",
|
|
213
|
+
...owned ? { source: ".cleo/hooks.json" } : {}
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return result;
|
|
218
|
+
}
|
|
219
|
+
function configEdits(config, prior, desired) {
|
|
220
|
+
if (config.hooks !== void 0 && !object(config.hooks))
|
|
221
|
+
throw new Error("HOOK_CONFIG_HOOKS_SHAPE");
|
|
222
|
+
const hooks = object(config.hooks) ? config.hooks : {};
|
|
223
|
+
const edits = [];
|
|
224
|
+
const found = /* @__PURE__ */ new Set();
|
|
225
|
+
const retained = /* @__PURE__ */ new Set();
|
|
226
|
+
for (const [event, entries] of Object.entries(hooks)) {
|
|
227
|
+
if (!Array.isArray(entries)) throw new Error("HOOK_CONFIG_EVENT_SHAPE");
|
|
228
|
+
for (let index = entries.length - 1; index >= 0; index--) {
|
|
229
|
+
const value = entries[index];
|
|
230
|
+
if (value === void 0) continue;
|
|
231
|
+
const cmd = entryCommand(value);
|
|
232
|
+
const owns = prior?.entries.find((old) => old.event === event && old.command === cmd);
|
|
233
|
+
const hasMarker = JSON.stringify(value).includes(MARKER);
|
|
234
|
+
if (!owns && hasMarker) throw new Error("HOOK_CONFIG_UNATTRIBUTED_ENTRY");
|
|
235
|
+
if (!owns) continue;
|
|
236
|
+
if (hash(JSON.stringify(value)) !== owns.hash || found.has(event + ":" + cmd))
|
|
237
|
+
throw new Error("HOOK_CONFIG_MANAGED_DRIFT");
|
|
238
|
+
found.add(event + ":" + cmd);
|
|
239
|
+
if (desired.some((next) => next.event === event && next.hash === owns.hash))
|
|
240
|
+
retained.add(event + ":" + cmd);
|
|
241
|
+
else edits.push({ path: ["hooks", event, index] });
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
for (const next of desired) {
|
|
245
|
+
const entries = hooks[next.event];
|
|
246
|
+
if (entries !== void 0 && !Array.isArray(entries))
|
|
247
|
+
throw new Error("HOOK_CONFIG_EVENT_SHAPE");
|
|
248
|
+
if (retained.has(next.event + ":" + next.command)) continue;
|
|
249
|
+
const removals = edits.filter((change) => change.path[1] === next.event).length;
|
|
250
|
+
edits.push(
|
|
251
|
+
Array.isArray(entries) ? {
|
|
252
|
+
path: ["hooks", next.event, entries.length - removals],
|
|
253
|
+
value: entry(next.command),
|
|
254
|
+
insert: true
|
|
255
|
+
} : { path: ["hooks", next.event], value: [entry(next.command)] }
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
return edits;
|
|
259
|
+
}
|
|
260
|
+
function pluginSource(events) {
|
|
261
|
+
if (!events.includes("PreToolUse"))
|
|
262
|
+
return "// CLEO project hooks v1; no supported bindings.\nexport default async () => ({});\n";
|
|
263
|
+
return [
|
|
264
|
+
"// CLEO project hooks v1; managed by a local hash receipt.",
|
|
265
|
+
'import { execFile } from "node:child_process";',
|
|
266
|
+
"export const CleoProjectHooks = async ({directory}) => {",
|
|
267
|
+
" const contexts = new Map();",
|
|
268
|
+
" return {",
|
|
269
|
+
' "tool.execute.before": async (input, output) => {',
|
|
270
|
+
" const context = await new Promise(done => {",
|
|
271
|
+
' const child = execFile("cleo", ["hook","run","--source","agent","--provider","opencode","--event","PreToolUse"], {cwd:directory, timeout:130000, maxBuffer:32768}, (error, stdout, stderr) => {',
|
|
272
|
+
' if(error) {done("CLEO project hook unavailable; operation allowed. Run cleo doctor hooks."); return}',
|
|
273
|
+
' try {const answer=JSON.parse(stdout || "{}"); done(typeof answer.context === "string" ? answer.context : stderr ? "CLEO project hook infrastructure warning; operation allowed. Run cleo doctor hooks." : "")} catch {done("CLEO project hook response unavailable; operation allowed. Run cleo doctor hooks.")}',
|
|
274
|
+
" });",
|
|
275
|
+
' child.on("error", () => done("CLEO project hook unavailable; operation allowed. Run cleo doctor hooks."));',
|
|
276
|
+
' child.stdin?.on("error", () => {}); child.stdin?.end(JSON.stringify({tool_name:input.tool,tool_input:output.args,cwd:directory}));',
|
|
277
|
+
" });",
|
|
278
|
+
" if(context && input.callID) {if(contexts.size >= 128) contexts.delete(contexts.keys().next().value); contexts.set(input.callID, context.slice(0,8192))}",
|
|
279
|
+
" },",
|
|
280
|
+
' "tool.execute.after": async (input, output) => {',
|
|
281
|
+
" const context=contexts.get(input.callID); contexts.delete(input.callID);",
|
|
282
|
+
' if(context && typeof output.output === "string") output.output += "\\n\\n" + context;',
|
|
283
|
+
" },",
|
|
284
|
+
" };",
|
|
285
|
+
"};",
|
|
286
|
+
""
|
|
287
|
+
].join("\n");
|
|
288
|
+
}
|
|
289
|
+
async function deliverProvider(options, provider) {
|
|
290
|
+
const profile = GENERATED_PROVIDER_HOOK_PROFILES[provider];
|
|
291
|
+
const capability = profile?.projectDelivery;
|
|
292
|
+
const version = probeVersion(provider);
|
|
293
|
+
const result = {
|
|
294
|
+
provider,
|
|
295
|
+
version,
|
|
296
|
+
state: "unsupported",
|
|
297
|
+
capability: version && capability?.verifiedVersions.includes(version) ? "verified" : version && capability?.documentedVersions.includes(version) ? "documented" : "unverified",
|
|
298
|
+
nativeTrust: "unverified",
|
|
299
|
+
provenance: "unknown",
|
|
300
|
+
diagnostics: []
|
|
301
|
+
};
|
|
302
|
+
if (result.capability !== "verified") result.diagnostics.push("HOOK_LIVE_DELIVERY_UNVERIFIED");
|
|
303
|
+
if (!capability?.configPath) {
|
|
304
|
+
result.diagnostics.push("HOOK_PROJECT_LOCAL_UNSUPPORTED");
|
|
305
|
+
return result;
|
|
306
|
+
}
|
|
307
|
+
const configPath = capability.configPath;
|
|
308
|
+
const target = await localTarget(options.projectRoot, configPath);
|
|
309
|
+
result.configPath = target;
|
|
310
|
+
const receiptPath = join2(options.stateDir, "provider-" + provider + ".json");
|
|
311
|
+
const prior = await receiptAt(receiptPath, options.services);
|
|
312
|
+
if (prior && (prior.provider !== provider || prior.configPath !== target))
|
|
313
|
+
throw new Error("HOOK_RECEIPT_PATH_MISMATCH");
|
|
314
|
+
if (prior) {
|
|
315
|
+
const allowed = desiredEntries(provider, Object.keys(profile.mappings));
|
|
316
|
+
for (const [canonical, mapping] of Object.entries(profile.mappings)) {
|
|
317
|
+
if (!mapping?.supported || !mapping.nativeName) continue;
|
|
318
|
+
const former = "cleo hook run --source agent --provider " + provider + " --event " + canonical + " # cleo-hook " + MARKER;
|
|
319
|
+
for (const generated of [former, command(provider, canonical)]) {
|
|
320
|
+
allowed.push({
|
|
321
|
+
event: mapping.nativeName,
|
|
322
|
+
command: generated,
|
|
323
|
+
hash: hash(JSON.stringify(entry(generated, null)))
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
const valid = profile.hookSystem === "plugin" ? prior.entries.length === 1 && prior.entries[0]?.event === "plugin" && prior.entries[0]?.command === "cleo hook run" && [pluginSource([]), pluginSource(["PreToolUse"])].some(
|
|
328
|
+
(body) => hash(body) === prior.entries[0]?.hash
|
|
329
|
+
) : prior.entries.every(
|
|
330
|
+
(item) => allowed.some(
|
|
331
|
+
(candidate) => candidate.event === item.event && candidate.command === item.command && candidate.hash === item.hash
|
|
332
|
+
)
|
|
333
|
+
);
|
|
334
|
+
if (!valid) throw new Error("HOOK_RECEIPT_OWNERSHIP_INVALID");
|
|
335
|
+
result.provenance = "cleo-receipt";
|
|
336
|
+
}
|
|
337
|
+
if (options.events.length === 0 && !prior && !options.rollback) {
|
|
338
|
+
result.state = "unsupported";
|
|
339
|
+
result.diagnostics.push("HOOK_NO_AGENT_BINDINGS");
|
|
340
|
+
return result;
|
|
341
|
+
}
|
|
342
|
+
if (!options.enabled && !options.rollback) {
|
|
343
|
+
result.state = "disabled";
|
|
344
|
+
return result;
|
|
345
|
+
}
|
|
346
|
+
const desired = options.rollback ? [] : desiredEntries(provider, options.events);
|
|
347
|
+
const tracking = spawnSync(
|
|
348
|
+
"git",
|
|
349
|
+
["-C", options.projectRoot, "ls-files", "--error-unmatch", "--", capability.configPath],
|
|
350
|
+
{ timeout: 2e3, stdio: "ignore", env: options.services.gitEnvironment }
|
|
351
|
+
);
|
|
352
|
+
if (tracking.status === 0) {
|
|
353
|
+
result.state = "conflict";
|
|
354
|
+
result.diagnostics.push("HOOK_CONFIG_TRACKED_REVIEW_REQUIRED");
|
|
355
|
+
result.integrationSnippet = JSON.stringify(
|
|
356
|
+
{ hooks: Object.fromEntries(desired.map((item) => [item.event, [entry(item.command)]])) },
|
|
357
|
+
null,
|
|
358
|
+
2
|
|
359
|
+
);
|
|
360
|
+
return result;
|
|
361
|
+
}
|
|
362
|
+
if (tracking.error || tracking.signal || tracking.status !== 1)
|
|
363
|
+
throw new Error("HOOK_GIT_TRACKING_UNVERIFIED");
|
|
364
|
+
for (const event of options.events) {
|
|
365
|
+
if (!desired.some((item) => item.command === command(provider, event)))
|
|
366
|
+
result.diagnostics.push("HOOK_EVENT_UNSUPPORTED:" + event);
|
|
367
|
+
}
|
|
368
|
+
if (profile.hookSystem === "plugin") {
|
|
369
|
+
for (const event of options.events.filter((event2) => event2 !== "PreToolUse"))
|
|
370
|
+
result.diagnostics.push("HOOK_PLUGIN_EVENT_UNSUPPORTED:" + event);
|
|
371
|
+
if (!options.rollback && !options.events.includes("PreToolUse")) {
|
|
372
|
+
result.state = "unsupported";
|
|
373
|
+
return result;
|
|
374
|
+
}
|
|
375
|
+
const body = pluginSource(options.events);
|
|
376
|
+
const existing = existsSync2(target) ? await options.services.readTextFile(target, 262144) : void 0;
|
|
377
|
+
if (existing !== void 0 && (!prior || prior.entries[0]?.hash !== hash(existing))) {
|
|
378
|
+
result.state = "conflict";
|
|
379
|
+
result.diagnostics.push("HOOK_CONFIG_MANAGED_DRIFT");
|
|
380
|
+
return result;
|
|
381
|
+
}
|
|
382
|
+
if (options.rollback) {
|
|
383
|
+
if (existing !== void 0 && !options.dryRun)
|
|
384
|
+
await withFileLock(target, async () => {
|
|
385
|
+
await localTarget(options.projectRoot, configPath);
|
|
386
|
+
const current = existsSync2(target) ? await options.services.readTextFile(target, 262144) : void 0;
|
|
387
|
+
if (current !== existing) throw new Error("HOOK_CONFIG_CONCURRENT_EDIT");
|
|
388
|
+
await unlink(target);
|
|
389
|
+
});
|
|
390
|
+
result.state = "disabled";
|
|
391
|
+
return result;
|
|
392
|
+
}
|
|
393
|
+
result.state = existing === body ? "current" : "planned";
|
|
394
|
+
if (!options.dryRun && existing !== body) {
|
|
395
|
+
if (existing === void 0)
|
|
396
|
+
excludeHookFileFromGit(
|
|
397
|
+
options.projectRoot,
|
|
398
|
+
capability.configPath,
|
|
399
|
+
void 0,
|
|
400
|
+
options.services.gitEnvironment
|
|
401
|
+
);
|
|
402
|
+
await withFileLock(target, async () => {
|
|
403
|
+
await localTarget(options.projectRoot, configPath);
|
|
404
|
+
const current = existsSync2(target) ? await options.services.readTextFile(target, 262144) : void 0;
|
|
405
|
+
if (current !== existing) throw new Error("HOOK_CONFIG_CONCURRENT_EDIT");
|
|
406
|
+
await writeFileAtomic({ path: target, content: body });
|
|
407
|
+
});
|
|
408
|
+
await writeFileAtomic({
|
|
409
|
+
path: receiptPath,
|
|
410
|
+
content: JSON.stringify({
|
|
411
|
+
schemaVersion: 1,
|
|
412
|
+
provider,
|
|
413
|
+
configPath: target,
|
|
414
|
+
entries: [{ event: "plugin", command: "cleo hook run", hash: hash(body) }],
|
|
415
|
+
recordedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
416
|
+
}) + "\n"
|
|
417
|
+
});
|
|
418
|
+
result.state = "installed";
|
|
419
|
+
result.provenance = "cleo-receipt";
|
|
420
|
+
}
|
|
421
|
+
return result;
|
|
422
|
+
}
|
|
423
|
+
const config = await readManagedJsonConfigFile(target);
|
|
424
|
+
result.entries = inspectEntries(config, prior);
|
|
425
|
+
const edits = configEdits(config, prior, desired);
|
|
426
|
+
result.state = edits.length ? "planned" : "current";
|
|
427
|
+
if (!options.dryRun) {
|
|
428
|
+
if (!existsSync2(target))
|
|
429
|
+
excludeHookFileFromGit(
|
|
430
|
+
options.projectRoot,
|
|
431
|
+
capability.configPath,
|
|
432
|
+
void 0,
|
|
433
|
+
options.services.gitEnvironment
|
|
434
|
+
);
|
|
435
|
+
await editJsonConfigFile(target, (current) => configEdits(current, prior, desired));
|
|
436
|
+
await writeFileAtomic({
|
|
437
|
+
path: receiptPath,
|
|
438
|
+
content: JSON.stringify({
|
|
439
|
+
schemaVersion: 1,
|
|
440
|
+
provider,
|
|
441
|
+
configPath: target,
|
|
442
|
+
entries: desired,
|
|
443
|
+
recordedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
444
|
+
}) + "\n"
|
|
445
|
+
});
|
|
446
|
+
result.state = edits.length ? "installed" : "current";
|
|
447
|
+
result.provenance = "cleo-receipt";
|
|
448
|
+
result.entries = inspectEntries(
|
|
449
|
+
await readManagedJsonConfigFile(target),
|
|
450
|
+
await receiptAt(receiptPath, options.services)
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
return result;
|
|
454
|
+
}
|
|
455
|
+
function hasUnsupportedProjectHookDelivery(results) {
|
|
456
|
+
return results.some(
|
|
457
|
+
(result) => result.state === "unsupported" || result.diagnostics.some(
|
|
458
|
+
(code) => code.startsWith("HOOK_EVENT_UNSUPPORTED:") || code.startsWith("HOOK_PLUGIN_EVENT_UNSUPPORTED:")
|
|
459
|
+
)
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
async function validateStateDirectory(options) {
|
|
463
|
+
const gitState = resolve2(
|
|
464
|
+
options.projectRoot,
|
|
465
|
+
execFileSync2(
|
|
466
|
+
"git",
|
|
467
|
+
[
|
|
468
|
+
"-C",
|
|
469
|
+
options.projectRoot,
|
|
470
|
+
"rev-parse",
|
|
471
|
+
"--path-format=absolute",
|
|
472
|
+
"--git-path",
|
|
473
|
+
"cleo-project-hooks"
|
|
474
|
+
],
|
|
475
|
+
{
|
|
476
|
+
encoding: "utf8",
|
|
477
|
+
timeout: 2e3,
|
|
478
|
+
maxBuffer: 16384,
|
|
479
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
480
|
+
env: options.services.gitEnvironment
|
|
481
|
+
}
|
|
482
|
+
).trim()
|
|
483
|
+
);
|
|
484
|
+
const parent = await realpath(dirname2(gitState));
|
|
485
|
+
if (resolve2(options.stateDir) !== gitState || await realpath(dirname2(resolve2(options.stateDir))) !== parent)
|
|
486
|
+
throw new Error("HOOK_STATE_DIRECTORY_INVALID");
|
|
487
|
+
if (existsSync2(gitState) && (!(await lstat(gitState)).isDirectory() || (await lstat(gitState)).isSymbolicLink()))
|
|
488
|
+
throw new Error("HOOK_STATE_DIRECTORY_INVALID");
|
|
489
|
+
}
|
|
490
|
+
async function syncProjectHookProviders(options) {
|
|
491
|
+
const providers = options.providers ?? Object.entries(GENERATED_PROVIDER_HOOK_PROFILES).filter(
|
|
492
|
+
([id, profile]) => profile.projectDelivery && (probeVersion(id) !== void 0 || profile.projectDelivery.configPath !== null && existsSync2(
|
|
493
|
+
join2(options.projectRoot, profile.projectDelivery.configPath.split("/")[0] ?? "")
|
|
494
|
+
))
|
|
495
|
+
).map(([id]) => id);
|
|
496
|
+
const outcomes = [];
|
|
497
|
+
for (const provider of providers) {
|
|
498
|
+
try {
|
|
499
|
+
if (!Object.hasOwn(GENERATED_PROVIDER_HOOK_PROFILES, provider) || !/^[a-z][a-z0-9-]*$/.test(provider))
|
|
500
|
+
throw new Error("HOOK_PROVIDER_INVALID");
|
|
501
|
+
await validateStateDirectory(options);
|
|
502
|
+
outcomes.push(
|
|
503
|
+
options.dryRun ? await deliverProvider(options, provider) : await withFileLock(
|
|
504
|
+
join2(options.stateDir, "provider-" + provider + ".json"),
|
|
505
|
+
() => deliverProvider(options, provider)
|
|
506
|
+
)
|
|
507
|
+
);
|
|
508
|
+
} catch (error) {
|
|
509
|
+
outcomes.push({
|
|
510
|
+
provider,
|
|
511
|
+
state: "conflict",
|
|
512
|
+
capability: "unverified",
|
|
513
|
+
nativeTrust: "unverified",
|
|
514
|
+
provenance: "unknown",
|
|
515
|
+
diagnostics: [
|
|
516
|
+
error instanceof Error && /^HOOK_[A-Z_]+$/.test(error.message) ? error.message : "HOOK_DELIVERY_FAILED"
|
|
517
|
+
]
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
return outcomes;
|
|
522
|
+
}
|
|
523
|
+
export {
|
|
524
|
+
hasUnsupportedProjectHookDelivery,
|
|
525
|
+
syncProjectHookProviders
|
|
526
|
+
};
|
|
527
|
+
//# sourceMappingURL=project-hook-delivery.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/project-hook-delivery.ts", "../src/providers/shared/heavy-command-hook-install.ts"],
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": ["execFileSync", "existsSync", "dirname", "isAbsolute", "join", "resolve", "execFileSync", "isAbsolute", "resolve", "existsSync", "dirname", "join", "event"]
|
|
6
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ProjectHookNativeRequest, ProjectHookNativeResult } from '@cleocode/contracts/project-hook-delivery.js';
|
|
2
|
+
import type { HookOutcome } from '@cleocode/contracts/project-hooks.js';
|
|
3
|
+
/** Normalize actual Git ref updates or native agent JSON; no Claude environment dependency. */
|
|
4
|
+
export declare function normalizeNativeProjectHook(argv: readonly string[], body: string, cwd: string): ProjectHookNativeRequest;
|
|
5
|
+
/** Produce advisory-only native output; project blocks apply solely to Git. */
|
|
6
|
+
export declare function renderNativeProjectHook(request: ProjectHookNativeRequest, outcomes: HookOutcome[]): ProjectHookNativeResult;
|
|
7
|
+
//# sourceMappingURL=project-hook-native.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-hook-native.d.ts","sourceRoot":"","sources":["../src/project-hook-native.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,wBAAwB,EACxB,uBAAuB,EACxB,MAAM,8CAA8C,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAiB,MAAM,sCAAsC,CAAC;AAmCvF,+FAA+F;AAC/F,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACV,wBAAwB,CA+B1B;AAED,+EAA+E;AAC/E,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,wBAAwB,EACjC,QAAQ,EAAE,WAAW,EAAE,GACtB,uBAAuB,CA4CzB"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// packages/adapters/src/project-hook-native.ts
|
|
2
|
+
function flag(argv, name) {
|
|
3
|
+
const separator = argv.indexOf("--");
|
|
4
|
+
const options = separator < 0 ? argv : argv.slice(0, separator);
|
|
5
|
+
const index = options.findIndex(
|
|
6
|
+
(arg) => arg === "--" + name || arg.startsWith("--" + name + "=")
|
|
7
|
+
);
|
|
8
|
+
return index < 0 ? void 0 : options[index]?.split("=").slice(1).join("=") || options[index + 1];
|
|
9
|
+
}
|
|
10
|
+
function object(value) {
|
|
11
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12
|
+
}
|
|
13
|
+
function refsFromStdin(body) {
|
|
14
|
+
const refs = [];
|
|
15
|
+
for (const line of body.split(/\r?\n/).filter((line2) => line2.trim())) {
|
|
16
|
+
const fields = line.trim().split(/\s+/);
|
|
17
|
+
const [localRef, localOid, remoteRef, remoteOid] = fields;
|
|
18
|
+
if (fields.length !== 4 || !localRef || !remoteRef || !localOid || !remoteOid || !/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/.test(localOid) || !/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/.test(remoteOid))
|
|
19
|
+
throw new Error("HOOK_GIT_INPUT_INVALID");
|
|
20
|
+
refs.push({ localRef, localOid, remoteRef, remoteOid });
|
|
21
|
+
}
|
|
22
|
+
return refs;
|
|
23
|
+
}
|
|
24
|
+
function normalizeNativeProjectHook(argv, body, cwd) {
|
|
25
|
+
if (Buffer.byteLength(body) > 262144) throw new Error("HOOK_INPUT_TOO_LARGE");
|
|
26
|
+
const source = flag(argv, "source") ?? "agent";
|
|
27
|
+
if (source !== "agent" && source !== "git") throw new Error("HOOK_SOURCE_INVALID");
|
|
28
|
+
const provider = flag(argv, "provider") ?? "claude-code";
|
|
29
|
+
const event = flag(argv, "event") ?? (source === "git" ? "pre-push" : "PreToolUse");
|
|
30
|
+
const separator = argv.indexOf("--");
|
|
31
|
+
if (source === "git")
|
|
32
|
+
return {
|
|
33
|
+
cwd,
|
|
34
|
+
provider,
|
|
35
|
+
input: {
|
|
36
|
+
schemaVersion: 1,
|
|
37
|
+
source,
|
|
38
|
+
event,
|
|
39
|
+
refs: refsFromStdin(body),
|
|
40
|
+
remote: {
|
|
41
|
+
name: flag(argv, "remote-name") ?? (separator < 0 ? "" : argv[separator + 1]) ?? "",
|
|
42
|
+
location: flag(argv, "remote-location") ?? (separator < 0 ? "" : argv[separator + 2]) ?? ""
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const payload = JSON.parse(body || "{}");
|
|
47
|
+
if (!object(payload)) throw new Error("HOOK_AGENT_INPUT_INVALID");
|
|
48
|
+
return {
|
|
49
|
+
cwd: typeof payload.cwd === "string" ? payload.cwd : cwd,
|
|
50
|
+
provider,
|
|
51
|
+
nativeEvent: typeof payload.hook_event_name === "string" ? payload.hook_event_name : event,
|
|
52
|
+
input: { schemaVersion: 1, source, event, toolInput: payload.tool_input ?? {} }
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function renderNativeProjectHook(request, outcomes) {
|
|
56
|
+
const message = outcomes.filter((outcome) => outcome.status !== "pass" && outcome.status !== "skip").map(
|
|
57
|
+
(outcome) => "CLEO project hook " + outcome.id + ": " + outcome.status + " (" + outcome.code + ")" + (outcome.message ? ": " + outcome.message : "")
|
|
58
|
+
).join("\n").slice(0, 8192);
|
|
59
|
+
if (request.input.source === "agent")
|
|
60
|
+
return {
|
|
61
|
+
exitCode: 0,
|
|
62
|
+
stderr: "",
|
|
63
|
+
stdout: message ? JSON.stringify(
|
|
64
|
+
request.provider === "opencode" ? { context: message } : request.input.event === "PreToolUse" ? {
|
|
65
|
+
hookSpecificOutput: {
|
|
66
|
+
hookEventName: request.nativeEvent ?? request.input.event,
|
|
67
|
+
additionalContext: message
|
|
68
|
+
}
|
|
69
|
+
} : { systemMessage: message }
|
|
70
|
+
) + "\n" : ""
|
|
71
|
+
};
|
|
72
|
+
return {
|
|
73
|
+
stdout: "",
|
|
74
|
+
stderr: message ? message + "\n" : "",
|
|
75
|
+
exitCode: outcomes.some(
|
|
76
|
+
(outcome) => outcome.blocks && outcome.status !== "infrastructure-error"
|
|
77
|
+
) ? 1 : 0
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export {
|
|
81
|
+
normalizeNativeProjectHook,
|
|
82
|
+
renderNativeProjectHook
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=project-hook-native.js.map
|