@cleocode/adapters 2026.10.2 → 2026.10.4
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.d.ts +12 -0
- package/dist/heavy-command-hook.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +647 -49
- package/dist/index.js.map +3 -3
- package/dist/providers/codex/install.d.ts.map +1 -1
- package/dist/providers/shared/heavy-command-hook-delivery.d.ts +97 -0
- package/dist/providers/shared/heavy-command-hook-delivery.d.ts.map +1 -0
- package/dist/providers/shared/heavy-command-hook-install.d.ts +153 -7
- package/dist/providers/shared/heavy-command-hook-install.d.ts.map +1 -1
- package/package.json +9 -5
- package/src/heavy-command-hook.ts +21 -0
- package/src/index.ts +12 -0
- package/src/providers/codex/install.ts +3 -4
- package/src/providers/shared/__tests__/heavy-command-hook-delivery.test.ts +580 -0
- package/src/providers/shared/heavy-command-hook-delivery.ts +620 -0
- package/src/providers/shared/heavy-command-hook-install.ts +395 -31
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/providers/codex/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,sBAAsB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIjG;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,oBAAqB,YAAW,sBAAsB;IACjE;;;;;;OAMG;IACG,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/providers/codex/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,sBAAsB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIjG;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,oBAAqB,YAAW,sBAAsB;IACjE;;;;;;OAMG;IACG,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAwC9D;;;;;OAKG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhC;;;;;OAKG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAerC;;;;;;;OAOG;IACG,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAMrE"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deliver CLEO's heavy-command hook to every provider a project uses (T13124).
|
|
3
|
+
*
|
|
4
|
+
* `cleo init`, `cleo upgrade`, `cleo doctor` and the session briefing reach the
|
|
5
|
+
* per-provider installers in {@link ./heavy-command-hook-install.js} through
|
|
6
|
+
* this module. It used to go through `AdapterManager.discover()`, which looks for
|
|
7
|
+
* manifests at `<project>/packages/adapters/<dir>/manifest.json`, a path that
|
|
8
|
+
* exists in no project, cleocode included. So the hook was never installed
|
|
9
|
+
* anywhere, and the per-adapter try/catch hid every failure.
|
|
10
|
+
*
|
|
11
|
+
* Each provider is handled on its own: a provider that cannot take the hook
|
|
12
|
+
* (a stray `.codex` file, a malformed settings file) gets a `blocked` or
|
|
13
|
+
* `failed` outcome with the reason and the exact remedy, and the other
|
|
14
|
+
* providers still install. Nothing here throws.
|
|
15
|
+
*
|
|
16
|
+
* A provider counts as in use when the project has its config directory, its
|
|
17
|
+
* CLI is on `PATH`, its user config directory exists, or the hook config
|
|
18
|
+
* already exists. The home directory is only READ for that check. CLEO writes
|
|
19
|
+
* project-level configs only, never a user-global one.
|
|
20
|
+
*
|
|
21
|
+
* @task T13124
|
|
22
|
+
* @epic T13121
|
|
23
|
+
*/
|
|
24
|
+
import type { HeavyCommandHookMode, HeavyCommandHookProvider, HeavyHookCliProbe, HeavyHookDeliveryApi, HeavyHookDeliveryOptions, HeavyHookDeliveryOutcome, HeavyHookInspection } from '@cleocode/contracts';
|
|
25
|
+
/** Every provider the delivery considers, in report order. */
|
|
26
|
+
export declare const HEAVY_HOOK_DELIVERY_PROVIDERS: readonly HeavyCommandHookProvider[];
|
|
27
|
+
/** The focused remedy: installs or refreshes only this hook. */
|
|
28
|
+
export declare const HEAVY_HOOK_FIX_COMMAND = "cleo doctor heavy-command-hook --fix";
|
|
29
|
+
type Env = Readonly<Record<string, string | undefined>>;
|
|
30
|
+
/**
|
|
31
|
+
* The file a provider's project-level hook lives in (Kimi: its global config,
|
|
32
|
+
* named for the report only; CLEO never writes it).
|
|
33
|
+
*
|
|
34
|
+
* @param provider - the harness.
|
|
35
|
+
* @param projectDir - the project root.
|
|
36
|
+
* @param env - environment (for Kimi's home directory).
|
|
37
|
+
* @returns the absolute path.
|
|
38
|
+
*/
|
|
39
|
+
export declare function heavyHookTarget(provider: HeavyCommandHookProvider, projectDir: string, env?: Env): string;
|
|
40
|
+
/** Whether a provider is in use, and the first signal that says so. */
|
|
41
|
+
export interface HeavyHookDetection {
|
|
42
|
+
/** The provider is in use on this machine or in this project. */
|
|
43
|
+
readonly detected: boolean;
|
|
44
|
+
/** The signal found, or what was checked when nothing was. */
|
|
45
|
+
readonly why: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Whether `provider` is in use here, from cheap read-only signals: its
|
|
49
|
+
* project config directory, its CLI on `PATH`, its user config directory, or
|
|
50
|
+
* an existing hook config.
|
|
51
|
+
*
|
|
52
|
+
* @param provider - the harness.
|
|
53
|
+
* @param projectDir - the project root.
|
|
54
|
+
* @param env - environment (`PATH`, `HOME`, `CODEX_HOME`, `XDG_CONFIG_HOME`, …).
|
|
55
|
+
* @returns whether it is in use, and why.
|
|
56
|
+
*/
|
|
57
|
+
export declare function detectHeavyHookProvider(provider: HeavyCommandHookProvider, projectDir: string, env?: Env): HeavyHookDetection;
|
|
58
|
+
/**
|
|
59
|
+
* Install, refresh or (mode `off`) remove CLEO's heavy-command hook for every
|
|
60
|
+
* provider in use in `projectDir`, each independently: one provider's failure
|
|
61
|
+
* never stops another. Mode `off` cleans every provider, in use or not. The
|
|
62
|
+
* home directory is skipped (its provider configs are the user-global ones).
|
|
63
|
+
*
|
|
64
|
+
* @param projectDir - the project root.
|
|
65
|
+
* @param mode - the resolved hook mode (`resources.heavyCommandHook`).
|
|
66
|
+
* @param options - environment and provider list (tests).
|
|
67
|
+
* @returns one outcome per provider, in {@link HEAVY_HOOK_DELIVERY_PROVIDERS} order.
|
|
68
|
+
*/
|
|
69
|
+
export declare function syncProjectHeavyCommandHooks(projectDir: string, mode: HeavyCommandHookMode, options?: HeavyHookDeliveryOptions): Promise<readonly HeavyHookDeliveryOutcome[]>;
|
|
70
|
+
/**
|
|
71
|
+
* Read-only: the hook's state for every provider in `projectDir`. Never
|
|
72
|
+
* writes and never throws.
|
|
73
|
+
*
|
|
74
|
+
* @param projectDir - the project root.
|
|
75
|
+
* @param mode - the resolved hook mode (`resources.heavyCommandHook`).
|
|
76
|
+
* @param options - environment and provider list (tests).
|
|
77
|
+
* @returns one inspection per provider, in {@link HEAVY_HOOK_DELIVERY_PROVIDERS} order.
|
|
78
|
+
*/
|
|
79
|
+
export declare function inspectProjectHeavyCommandHooks(projectDir: string, mode: HeavyCommandHookMode, options?: HeavyHookDeliveryOptions): readonly HeavyHookInspection[];
|
|
80
|
+
/**
|
|
81
|
+
* Whether the `cleo` on PATH, as the hook resolves it from `projectDir`, can
|
|
82
|
+
* answer the hook. A hook installed in front of an older CLEO (no `cleo hook`,
|
|
83
|
+
* so no `cleo run`) lets every command run ungoverned, so `cleo doctor` must
|
|
84
|
+
* say so. The check is the hook's own: its marker for this binary and
|
|
85
|
+
* directory, else one call to `cleo hook heavy-command` with an empty payload,
|
|
86
|
+
* where an older CLEO exits 127 with "Unknown command".
|
|
87
|
+
*
|
|
88
|
+
* @param projectDir - the project root (a version-manager shim may resolve a
|
|
89
|
+
* different `cleo` per directory).
|
|
90
|
+
* @param options - environment (tests).
|
|
91
|
+
* @returns the CLI's state.
|
|
92
|
+
*/
|
|
93
|
+
export declare function probeHeavyHookCli(projectDir: string, options?: HeavyHookDeliveryOptions): HeavyHookCliProbe;
|
|
94
|
+
/** The delivery surface `@cleocode/core` loads at run time. */
|
|
95
|
+
export declare const heavyHookDeliveryApi: HeavyHookDeliveryApi;
|
|
96
|
+
export {};
|
|
97
|
+
//# sourceMappingURL=heavy-command-hook-delivery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heavy-command-hook-delivery.d.ts","sourceRoot":"","sources":["../../../src/providers/shared/heavy-command-hook-delivery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAOH,OAAO,KAAK,EACV,oBAAoB,EACpB,wBAAwB,EACxB,iBAAiB,EACjB,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AA0B7B,8DAA8D;AAC9D,eAAO,MAAM,6BAA6B,EAAE,SAAS,wBAAwB,EAK3E,CAAC;AAEH,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,yCAAyC,CAAC;AAE7E,KAAK,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AAgBxD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,wBAAwB,EAClC,UAAU,EAAE,MAAM,EAClB,GAAG,GAAE,GAAiB,GACrB,MAAM,CAWR;AAED,uEAAuE;AACvE,MAAM,WAAW,kBAAkB;IACjC,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,8DAA8D;IAC9D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,wBAAwB,EAClC,UAAU,EAAE,MAAM,EAClB,GAAG,GAAE,GAAiB,GACrB,kBAAkB,CAgDpB;AAgED;;;;;;;;;;GAUG;AACH,wBAAsB,4BAA4B,CAChD,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,oBAAoB,EAC1B,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,SAAS,wBAAwB,EAAE,CAAC,CAwB9C;AA2MD;;;;;;;;GAQG;AACH,wBAAgB,+BAA+B,CAC7C,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,oBAAoB,EAC1B,OAAO,GAAE,wBAA6B,GACrC,SAAS,mBAAmB,EAAE,CAchC;AAwCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,wBAA6B,GACrC,iBAAiB,CAqCnB;AAED,+DAA+D;AAC/D,eAAO,MAAM,oBAAoB,EAAE,oBAIjC,CAAC"}
|
|
@@ -48,6 +48,30 @@ export declare const HEAVY_TOOL_WORDS: readonly string[];
|
|
|
48
48
|
* home directory, whose provider configs are the user-global ones.
|
|
49
49
|
*/
|
|
50
50
|
export type HeavyHookSyncResult = 'installed' | 'updated' | 'removed' | 'unchanged' | 'skipped';
|
|
51
|
+
/**
|
|
52
|
+
* A config path cannot be created because something on the way to it exists
|
|
53
|
+
* but is not a directory (T13124: a stray empty `<project>/.codex` file made
|
|
54
|
+
* `mkdirSync` throw `EEXIST` and aborted the Codex install). Nothing is
|
|
55
|
+
* written; the delivery reports the provider as `blocked`.
|
|
56
|
+
*/
|
|
57
|
+
export declare class HeavyHookPathBlockedError extends Error {
|
|
58
|
+
/** The existing path that is not a directory. */
|
|
59
|
+
readonly path: string;
|
|
60
|
+
/**
|
|
61
|
+
* @param path - the existing non-directory path.
|
|
62
|
+
* @param target - the config file that would have lived under it.
|
|
63
|
+
*/
|
|
64
|
+
constructor(path: string, target: string);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The nearest existing path at or above `dir` when it is NOT a directory, or
|
|
68
|
+
* `null` when the nearest existing one is a directory (so `mkdir -p dir`
|
|
69
|
+
* can succeed). Errors other than "does not exist" return `null` and are left
|
|
70
|
+
* to the write that follows.
|
|
71
|
+
*
|
|
72
|
+
* @param dir - the directory a config file needs.
|
|
73
|
+
*/
|
|
74
|
+
export declare function nonDirectoryAncestor(dir: string): string | null;
|
|
51
75
|
/**
|
|
52
76
|
* Whether `projectDir` is the user's home directory. There,
|
|
53
77
|
* `<home>/.claude/settings.local.json`, `<home>/.codex/hooks.json` and
|
|
@@ -108,6 +132,8 @@ export declare function heavyCommandHookObject(provider: 'claude-code' | 'codex'
|
|
|
108
132
|
* @param provider - `claude-code` or `codex`.
|
|
109
133
|
*/
|
|
110
134
|
export declare function heavyCommandHookEntry(provider: 'claude-code' | 'codex'): Record<string, unknown>;
|
|
135
|
+
/** Whether one hook object is CLEO's heavy-command hook. */
|
|
136
|
+
export declare function isHeavyHookObject(hook: unknown): boolean;
|
|
111
137
|
/**
|
|
112
138
|
* Add, refresh or (mode `off`) remove CLEO's heavy-command hook in a JSON hook
|
|
113
139
|
* config, through CAAMP's locked atomic writer. Only CLEO's own hook object is
|
|
@@ -119,28 +145,147 @@ export declare function heavyCommandHookEntry(provider: 'claude-code' | 'codex')
|
|
|
119
145
|
* @returns what changed.
|
|
120
146
|
*/
|
|
121
147
|
export declare function syncJsonHeavyCommandHook(configPath: string, provider: 'claude-code' | 'codex', mode: HeavyCommandHookMode): Promise<HeavyHookSyncResult>;
|
|
122
|
-
/**
|
|
148
|
+
/** Claude Code's per-machine settings file, relative to the project. */
|
|
149
|
+
export declare const CLAUDE_LOCAL_SETTINGS = ".claude/settings.local.json";
|
|
150
|
+
/** First line of the `info/exclude` block CLEO adds for `settings.local.json` (and alone may remove). */
|
|
123
151
|
export declare const LOCAL_SETTINGS_EXCLUDE_MARKER = "# cleo-hook: keep the per-machine heavy-command hook settings out of git (T12983)";
|
|
124
152
|
/**
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
|
|
153
|
+
* First line of the `info/exclude` block CLEO adds for any other hook file it
|
|
154
|
+
* writes: Codex's `.codex/hooks.json` and the opencode plugin (T13124, gh#1805:
|
|
155
|
+
* an untracked plugin file widened `cleo verify`'s evidence scope).
|
|
156
|
+
*/
|
|
157
|
+
export declare const HOOK_FILE_EXCLUDE_MARKER = "# cleo-hook: keep a per-machine heavy-command hook file out of git (T13124)";
|
|
158
|
+
/** Codex's project hook config, relative to the project. */
|
|
159
|
+
export declare const CODEX_HOOKS_FILE = ".codex/hooks.json";
|
|
160
|
+
/** The opencode plugin, relative to the project. */
|
|
161
|
+
export declare const OPENCODE_PLUGIN_FILE = ".opencode/plugins/cleo-heavy-command.js";
|
|
162
|
+
/**
|
|
163
|
+
* Keep a hook file CLEO wrote out of git when nothing ignores it yet: add a
|
|
164
|
+
* marked block naming this project's file to the repository's `info/exclude`,
|
|
165
|
+
* never to a tracked `.gitignore`. A file git already tracks is left alone (an
|
|
166
|
+
* exclude cannot untrack it). Keyed on the exact path line, so a second CLEO
|
|
129
167
|
* project in a subdirectory of the same repository gets its own line.
|
|
130
168
|
* Idempotent; does nothing outside a git work tree.
|
|
131
169
|
*
|
|
132
170
|
* @param projectDir - the project root.
|
|
171
|
+
* @param relPath - the file, relative to the project (forward slashes).
|
|
172
|
+
* @param marker - the block's first line.
|
|
173
|
+
* @returns whether a block was added.
|
|
174
|
+
*/
|
|
175
|
+
export declare function excludeHookFileFromGit(projectDir: string, relPath: string, marker?: string): boolean;
|
|
176
|
+
/**
|
|
177
|
+
* Remove the block {@link excludeHookFileFromGit} added for this project's
|
|
178
|
+
* file, and only that: the exact path line and the CLEO marker right above it.
|
|
179
|
+
*
|
|
180
|
+
* @param projectDir - the project root.
|
|
181
|
+
* @param relPath - the file, relative to the project (forward slashes).
|
|
182
|
+
* @returns whether a block was removed.
|
|
183
|
+
*/
|
|
184
|
+
export declare function unexcludeHookFileFromGit(projectDir: string, relPath: string): boolean;
|
|
185
|
+
/**
|
|
186
|
+
* Whether git sees a hook file as an untracked change: inside a work tree,
|
|
187
|
+
* not ignored and not tracked. Such a file shows up in `git status` and
|
|
188
|
+
* widens `cleo verify`'s evidence scope (gh#1805).
|
|
189
|
+
*
|
|
190
|
+
* @param projectDir - the project root.
|
|
191
|
+
* @param relPath - the file, relative to the project (forward slashes).
|
|
192
|
+
*/
|
|
193
|
+
export declare function hookFileVisibleToGit(projectDir: string, relPath: string): boolean;
|
|
194
|
+
/**
|
|
195
|
+
* Keep `.claude/settings.local.json` out of git when nothing ignores it yet
|
|
196
|
+
* (Claude Code ignores the file only when it creates it itself). See
|
|
197
|
+
* {@link excludeHookFileFromGit}.
|
|
198
|
+
*
|
|
199
|
+
* @param projectDir - the project root.
|
|
133
200
|
* @returns whether a block was added.
|
|
134
201
|
*/
|
|
135
202
|
export declare function excludeLocalSettingsFromGit(projectDir: string): boolean;
|
|
136
203
|
/**
|
|
137
204
|
* Remove the block {@link excludeLocalSettingsFromGit} added for this
|
|
138
|
-
* project, and only that
|
|
205
|
+
* project, and only that.
|
|
139
206
|
*
|
|
140
207
|
* @param projectDir - the project root.
|
|
141
208
|
* @returns whether a block was removed.
|
|
142
209
|
*/
|
|
143
210
|
export declare function unexcludeLocalSettingsFromGit(projectDir: string): boolean;
|
|
211
|
+
/**
|
|
212
|
+
* A hook config CLEO will not add its per-machine hook to, because it is the
|
|
213
|
+
* project's own: Codex's `.codex/hooks.json` is committable, unlike Claude
|
|
214
|
+
* Code's `settings.local.json`. Writing there would put a per-machine hook
|
|
215
|
+
* into a team file, and excluding it would hide the team's file from git.
|
|
216
|
+
* Nothing is written; the delivery reports `needs-consent` with the entry to
|
|
217
|
+
* add by hand.
|
|
218
|
+
*/
|
|
219
|
+
export declare class HeavyHookSharedConfigError extends Error {
|
|
220
|
+
/** The project's own config file. */
|
|
221
|
+
readonly path: string;
|
|
222
|
+
/**
|
|
223
|
+
* @param path - the config file.
|
|
224
|
+
* @param why - what makes it the project's own.
|
|
225
|
+
*/
|
|
226
|
+
constructor(path: string, why: string);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Why Codex's `.codex/hooks.json` in `projectDir` is the project's own config
|
|
230
|
+
* that CLEO must not write or hide, or `null` when CLEO may: the file is
|
|
231
|
+
* absent, or is one CLEO created and git does not track (review MED-3). An
|
|
232
|
+
* unreadable file is left to the sync, which refuses it.
|
|
233
|
+
*
|
|
234
|
+
* @param projectDir - the project root.
|
|
235
|
+
* @param checkGit - also ask git whether the file is tracked (one spawn);
|
|
236
|
+
* `false` reads the file only (the session briefing).
|
|
237
|
+
*/
|
|
238
|
+
export declare function codexHooksSharedReason(projectDir: string, checkGit?: boolean): string | null;
|
|
239
|
+
/**
|
|
240
|
+
* Whether the committed (`HEAD`) version of Codex's `.codex/hooks.json` holds
|
|
241
|
+
* CLEO's hook: the team adopted it, so mode `off` on one machine must not
|
|
242
|
+
* remove it from the tracked file (review MED-3b).
|
|
243
|
+
*
|
|
244
|
+
* @param projectDir - the project root.
|
|
245
|
+
*/
|
|
246
|
+
export declare function committedCodexHookHoldsCleo(projectDir: string): boolean;
|
|
247
|
+
/**
|
|
248
|
+
* Mode `off` on a TRACKED `hooks.json` whose only change from `HEAD` is
|
|
249
|
+
* CLEO's hook: write `HEAD`'s exact bytes back, so the file returns to its
|
|
250
|
+
* committed state instead of being re-serialised with CLEO's formatting
|
|
251
|
+
* (review LOW-3). Returns whether it did.
|
|
252
|
+
*
|
|
253
|
+
* @param projectDir - the project root.
|
|
254
|
+
*/
|
|
255
|
+
export declare function restoreCommittedCodexHooks(projectDir: string): boolean;
|
|
256
|
+
/**
|
|
257
|
+
* Whether CLEO's own marked `info/exclude` block names this project file
|
|
258
|
+
* (it hides the file from git).
|
|
259
|
+
*
|
|
260
|
+
* @param projectDir - the project root.
|
|
261
|
+
* @param relPath - the file, relative to the project (forward slashes).
|
|
262
|
+
*/
|
|
263
|
+
export declare function excludedByCleo(projectDir: string, relPath: string): boolean;
|
|
264
|
+
/**
|
|
265
|
+
* The exact `PreToolUse` entry to add to Codex's `.codex/hooks.json` by hand,
|
|
266
|
+
* for a project whose own config CLEO does not write (`needs-consent`).
|
|
267
|
+
*/
|
|
268
|
+
export declare function codexHookSnippet(): string;
|
|
269
|
+
/**
|
|
270
|
+
* Whether git tracks a project file and it has uncommitted changes.
|
|
271
|
+
*
|
|
272
|
+
* @param projectDir - the project root.
|
|
273
|
+
* @param relPath - the file, relative to the project (forward slashes).
|
|
274
|
+
*/
|
|
275
|
+
export declare function trackedFileModified(projectDir: string, relPath: string): boolean;
|
|
276
|
+
/**
|
|
277
|
+
* Codex: sync the hook in `<project>/.codex/hooks.json` and keep that file out
|
|
278
|
+
* of git (T13124), as {@link syncClaudeCodeHeavyCommandHook} does for Claude
|
|
279
|
+
* Code's settings. A shared `hooks.json` (tracked, or holding hooks that are
|
|
280
|
+
* not CLEO's) is never written: {@link HeavyHookSharedConfigError}. Mode `off`
|
|
281
|
+
* still removes CLEO's own hook object from it.
|
|
282
|
+
*
|
|
283
|
+
* @param projectDir - the project root.
|
|
284
|
+
* @param mode - the resolved hook mode.
|
|
285
|
+
* @returns what changed in `hooks.json`.
|
|
286
|
+
* @throws {HeavyHookSharedConfigError} when `hooks.json` is shared.
|
|
287
|
+
*/
|
|
288
|
+
export declare function syncCodexHeavyCommandHook(projectDir: string, mode: HeavyCommandHookMode): Promise<HeavyHookSyncResult>;
|
|
144
289
|
/**
|
|
145
290
|
* Claude Code: sync the hook in `<project>/.claude/settings.local.json`, keep
|
|
146
291
|
* that file out of git, and remove a hook an earlier build put in the shared
|
|
@@ -163,7 +308,8 @@ export declare function syncClaudeCodeHeavyCommandHook(projectDir: string, mode:
|
|
|
163
308
|
export declare function opencodeHeavyCommandPluginSource(): string;
|
|
164
309
|
/**
|
|
165
310
|
* Write (or, mode `off`, delete) the opencode plugin in
|
|
166
|
-
* `<projectDir>/.opencode/plugins
|
|
311
|
+
* `<projectDir>/.opencode/plugins/`, and keep it out of git (T13124).
|
|
312
|
+
* Rewritten only when its content changed.
|
|
167
313
|
*
|
|
168
314
|
* @param projectDir - the project root.
|
|
169
315
|
* @param mode - the resolved hook mode.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heavy-command-hook-install.d.ts","sourceRoot":"","sources":["../../../src/providers/shared/heavy-command-hook-install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;
|
|
1
|
+
{"version":3,"file":"heavy-command-hook-install.d.ts","sourceRoot":"","sources":["../../../src/providers/shared/heavy-command-hook-install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAgBH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGhE,oEAAoE;AACpE,eAAO,MAAM,qBAAqB,4BAA4B,CAAC;AAE/D,iFAAiF;AACjF,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAEjD,kDAAkD;AAClD,eAAO,MAAM,6BAA6B,0BAA0B,CAAC;AAErE;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EA+B5C,CAAC;AAEH;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAUhG;;;;;GAKG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;OAGG;gBACS,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAKzC;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAa/D;AASD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,GAAE,MAAkB,GAAG,OAAO,CAEnF;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,QAOjC,CAAC;AAEH,mFAAmF;AACnF,eAAO,MAAM,wBAAwB,2BAA2B,CAAC;AAEjE;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,GAAE,MAAgD,GACpD,MAAM,CAkBR;AAqDD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,GAAG,MAAM,CAIjF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMjG;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEhG;AAED,4DAA4D;AAC5D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAOxD;AAkDD;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,aAAa,GAAG,OAAO,EACjC,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,mBAAmB,CAAC,CA4B9B;AAED,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,gCAAgC,CAAC;AAEnE,yGAAyG;AACzG,eAAO,MAAM,6BAA6B,sFAC2C,CAAC;AAEtF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,gFAC0C,CAAC;AAEhF,4DAA4D;AAC5D,eAAO,MAAM,gBAAgB,sBAAsB,CAAC;AAEpD,oDAAoD;AACpD,eAAO,MAAM,oBAAoB,4CAAuD,CAAC;AA6BzF;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAAiC,GACxC,OAAO,CAYT;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAYrF;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAIjF;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAEvE;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAEzE;AAED;;;;;;;GAOG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;IACnD,qCAAqC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;OAGG;gBACS,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;CAKtC;AA8BD;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,UAAO,GAAG,MAAM,GAAG,IAAI,CAmBzF;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAgBvE;AAsBD;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CA0BtE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAO3E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAGhF;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,mBAAmB,CAAC,CAuB9B;AAED;;;;;;;;GAQG;AACH,wBAAsB,8BAA8B,CAClD,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,mBAAmB,CAAC,CAoB9B;AAED;;;;;;;;GAQG;AACH,wBAAgB,gCAAgC,IAAI,MAAM,CAmDzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAC5C,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,oBAAoB,GACzB,mBAAmB,CAkBrB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cleocode/adapters",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.4",
|
|
4
4
|
"description": "Unified provider adapters for CLEO (Claude Code, OpenCode, Cursor)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -9,15 +9,19 @@
|
|
|
9
9
|
".": {
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
11
|
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./heavy-command-hook": {
|
|
14
|
+
"types": "./dist/heavy-command-hook.d.ts",
|
|
15
|
+
"import": "./dist/heavy-command-hook.js"
|
|
12
16
|
}
|
|
13
17
|
},
|
|
14
18
|
"dependencies": {
|
|
15
19
|
"@ai-sdk/anthropic": "^3.0.69",
|
|
16
20
|
"@ai-sdk/openai": "^2.0.53",
|
|
17
21
|
"ai": "^6.0.168",
|
|
18
|
-
"@cleocode/caamp": "2026.10.
|
|
19
|
-
"@cleocode/paths": "2026.10.
|
|
20
|
-
"@cleocode/contracts": "2026.10.
|
|
22
|
+
"@cleocode/caamp": "2026.10.4",
|
|
23
|
+
"@cleocode/paths": "2026.10.4",
|
|
24
|
+
"@cleocode/contracts": "2026.10.4"
|
|
21
25
|
},
|
|
22
26
|
"license": "MIT",
|
|
23
27
|
"engines": {
|
|
@@ -30,7 +34,7 @@
|
|
|
30
34
|
"devDependencies": {
|
|
31
35
|
"@types/node": "^24.3.0",
|
|
32
36
|
"vitest": "^4.1.4",
|
|
33
|
-
"@cleocode/playbooks": "2026.10.
|
|
37
|
+
"@cleocode/playbooks": "2026.10.4"
|
|
34
38
|
},
|
|
35
39
|
"repository": {
|
|
36
40
|
"type": "git",
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@cleocode/adapters/heavy-command-hook`: project-level delivery of CLEO's
|
|
3
|
+
* heavy-command hook (T13124). A light entry point: `@cleocode/core` loads it
|
|
4
|
+
* at run time for `cleo init`, `cleo upgrade`, `cleo doctor` and the session
|
|
5
|
+
* briefing without pulling in every provider adapter.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
* @task T13124
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export type { HeavyHookDetection } from './providers/shared/heavy-command-hook-delivery.js';
|
|
12
|
+
export {
|
|
13
|
+
detectHeavyHookProvider,
|
|
14
|
+
HEAVY_HOOK_DELIVERY_PROVIDERS,
|
|
15
|
+
HEAVY_HOOK_FIX_COMMAND,
|
|
16
|
+
heavyHookDeliveryApi,
|
|
17
|
+
heavyHookTarget,
|
|
18
|
+
inspectProjectHeavyCommandHooks,
|
|
19
|
+
probeHeavyHookCli,
|
|
20
|
+
syncProjectHeavyCommandHooks,
|
|
21
|
+
} from './providers/shared/heavy-command-hook-delivery.js';
|
package/src/index.ts
CHANGED
|
@@ -87,6 +87,18 @@ export {
|
|
|
87
87
|
OpenCodeInstallProvider,
|
|
88
88
|
OpenCodeSpawnProvider,
|
|
89
89
|
} from './providers/opencode/index.js';
|
|
90
|
+
// T13124 — project-level heavy-command hook delivery (also `@cleocode/adapters/heavy-command-hook`).
|
|
91
|
+
export type { HeavyHookDetection } from './providers/shared/heavy-command-hook-delivery.js';
|
|
92
|
+
export {
|
|
93
|
+
detectHeavyHookProvider,
|
|
94
|
+
HEAVY_HOOK_DELIVERY_PROVIDERS,
|
|
95
|
+
HEAVY_HOOK_FIX_COMMAND,
|
|
96
|
+
heavyHookDeliveryApi,
|
|
97
|
+
heavyHookTarget,
|
|
98
|
+
inspectProjectHeavyCommandHooks,
|
|
99
|
+
probeHeavyHookCli,
|
|
100
|
+
syncProjectHeavyCommandHooks,
|
|
101
|
+
} from './providers/shared/heavy-command-hook-delivery.js';
|
|
90
102
|
export type {
|
|
91
103
|
HookTemplateProviderId,
|
|
92
104
|
InstallHookTemplatesOptions,
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import { join } from 'node:path';
|
|
16
16
|
import { ensureProviderInstructionFile } from '@cleocode/caamp';
|
|
17
17
|
import type { AdapterInstallProvider, InstallOptions, InstallResult } from '@cleocode/contracts';
|
|
18
|
-
import { isUserHomeDir,
|
|
18
|
+
import { isUserHomeDir, syncCodexHeavyCommandHook } from '../shared/heavy-command-hook-install.js';
|
|
19
19
|
import { getCleoTemplatesTildePath } from '../shared/paths.js';
|
|
20
20
|
|
|
21
21
|
/**
|
|
@@ -66,9 +66,8 @@ export class CodexInstallProvider implements AdapterInstallProvider {
|
|
|
66
66
|
details.heavyCommandHook = 'skipped';
|
|
67
67
|
} else if (options.heavyCommandHook !== undefined) {
|
|
68
68
|
try {
|
|
69
|
-
details.heavyCommandHook = await
|
|
70
|
-
|
|
71
|
-
'codex',
|
|
69
|
+
details.heavyCommandHook = await syncCodexHeavyCommandHook(
|
|
70
|
+
projectDir,
|
|
72
71
|
options.heavyCommandHook,
|
|
73
72
|
);
|
|
74
73
|
} catch (err) {
|