@cleocode/adapters 2026.4.38 → 2026.4.39
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/index.js +211 -120
- package/dist/index.js.map +3 -3
- package/dist/providers/claude-code/adapter.d.ts.map +1 -1
- package/dist/providers/claude-code/hooks.d.ts +23 -11
- package/dist/providers/claude-code/hooks.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/providers/claude-code/adapter.ts +4 -0
- package/src/providers/claude-code/hooks.ts +134 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/claude-code/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gCAAgC,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAI7D;;;;;;;;;;;;;;GAcG;AACH,qBAAa,iBAAkB,YAAW,mBAAmB;IAC3D,kCAAkC;IAClC,QAAQ,CAAC,EAAE,iBAAiB;IAC5B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,WAAW;IAE3B,+CAA+C;IAC/C,YAAY,EAAE,mBAAmB,CA6B/B;IAEF,8DAA8D;IAC9D,KAAK,EAAE,sBAAsB,CAAC;IAC9B,wEAAwE;IACxE,KAAK,EAAE,uBAAuB,CAAC;IAC/B,+EAA+E;IAC/E,OAAO,EAAE,yBAAyB,CAAC;IACnC,mEAAmE;IACnE,KAAK,EAAE,sBAAsB,CAAC;IAC9B,+EAA+E;IAC/E,cAAc,EAAE,gCAAgC,CAAC;IACjD,wDAAwD;IACxD,SAAS,EAAE,2BAA2B,CAAC;IACvC,2EAA2E;IAC3E,QAAQ,EAAE,0BAA0B,CAAC;IAErC,oEAAoE;IACpE,OAAO,CAAC,UAAU,CAAuB;IACzC,kDAAkD;IAClD,OAAO,CAAC,WAAW,CAAS;;IAY5B;;;;;;;OAOG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/claude-code/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gCAAgC,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAI7D;;;;;;;;;;;;;;GAcG;AACH,qBAAa,iBAAkB,YAAW,mBAAmB;IAC3D,kCAAkC;IAClC,QAAQ,CAAC,EAAE,iBAAiB;IAC5B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,WAAW;IAE3B,+CAA+C;IAC/C,YAAY,EAAE,mBAAmB,CA6B/B;IAEF,8DAA8D;IAC9D,KAAK,EAAE,sBAAsB,CAAC;IAC9B,wEAAwE;IACxE,KAAK,EAAE,uBAAuB,CAAC;IAC/B,+EAA+E;IAC/E,OAAO,EAAE,yBAAyB,CAAC;IACnC,mEAAmE;IACnE,KAAK,EAAE,sBAAsB,CAAC;IAC9B,+EAA+E;IAC/E,cAAc,EAAE,gCAAgC,CAAC;IACjD,wDAAwD;IACxD,SAAS,EAAE,2BAA2B,CAAC;IACvC,2EAA2E;IAC3E,QAAQ,EAAE,0BAA0B,CAAC;IAErC,oEAAoE;IACpE,OAAO,CAAC,UAAU,CAAuB;IACzC,kDAAkD;IAClD,OAAO,CAAC,WAAW,CAAS;;IAY5B;;;;;;;OAOG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASnD;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;;;;;;;;OASG;IACG,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAyCjD;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI;CAG/B"}
|
|
@@ -55,33 +55,45 @@ export declare class ClaudeCodeHookProvider implements AdapterHookProvider {
|
|
|
55
55
|
* @task T164
|
|
56
56
|
*/
|
|
57
57
|
mapProviderEvent(providerEvent: string): string | null;
|
|
58
|
+
/** Project directory this hook provider was registered for. */
|
|
59
|
+
private projectDir;
|
|
58
60
|
/**
|
|
59
61
|
* Register native hooks for a project.
|
|
60
62
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
63
|
+
* Writes CLEO hook entries to `~/.claude/settings.json` so that Claude Code's
|
|
64
|
+
* native event system calls cleo CLI commands when events fire. This bridges
|
|
65
|
+
* Claude Code's event loop to CLEO's internal hook dispatch.
|
|
64
66
|
*
|
|
65
|
-
*
|
|
66
|
-
* `getSupportedCanonicalEvents()` to enumerate all 14 supported hooks.
|
|
67
|
+
* Idempotent: skips writing if CLEO hooks already exist in settings.json.
|
|
67
68
|
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
69
|
+
* Hook entries registered:
|
|
70
|
+
* - `Stop` → `cleo session end --quiet` (triggers LLM extraction, reflector, consolidation)
|
|
71
|
+
* - `PostToolUse` (Write|Edit) → brain observation for file modifications
|
|
72
|
+
* - `SubagentStop` → brain observation for agent completion
|
|
73
|
+
*
|
|
74
|
+
* @param projectDir - Project directory for context-scoped hook commands
|
|
75
|
+
* @task T164 @task T555
|
|
70
76
|
*/
|
|
71
|
-
registerNativeHooks(
|
|
77
|
+
registerNativeHooks(projectDir: string): Promise<void>;
|
|
72
78
|
/**
|
|
73
79
|
* Unregister native hooks.
|
|
74
80
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
81
|
+
* Removes CLEO hook entries from `~/.claude/settings.json` by filtering out
|
|
82
|
+
* entries containing the `# cleo-hook` marker.
|
|
77
83
|
*
|
|
78
|
-
* @task T164
|
|
84
|
+
* @task T164 @task T555
|
|
79
85
|
*/
|
|
80
86
|
unregisterNativeHooks(): Promise<void>;
|
|
81
87
|
/**
|
|
82
88
|
* Check whether hooks have been registered via `registerNativeHooks`.
|
|
83
89
|
*/
|
|
84
90
|
isRegistered(): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Get the project directory this hook provider was registered for.
|
|
93
|
+
*
|
|
94
|
+
* Returns null if hooks have not been registered yet.
|
|
95
|
+
*/
|
|
96
|
+
getProjectDir(): string | null;
|
|
85
97
|
/**
|
|
86
98
|
* Get the native→canonical event mapping for introspection and debugging.
|
|
87
99
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../src/providers/claude-code/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../src/providers/claude-code/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AA8C/D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,sBAAuB,YAAW,mBAAmB;IAChE,kEAAkE;IAClE,OAAO,CAAC,UAAU,CAAS;IAE3B;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAItD,+DAA+D;IAC/D,OAAO,CAAC,UAAU,CAAuB;IAEzC;;;;;;;;;;;;;;;;OAgBG;IACG,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsE5D;;;;;;;OAOG;IACG,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IA2C5C;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;;;OAIG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI;IAI9B;;;;;;;;OAQG;IACH,WAAW,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAI/C;;;;;;;;;;OAUG;IACG,2BAA2B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAStD;;;;;;;;;;OAUG;IACG,kBAAkB,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IASnD;;;;;;;;;;OAUG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAW9D;;;;;;;;;;;;OAYG;IACG,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CA2DrF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cleocode/adapters",
|
|
3
|
-
"version": "2026.4.
|
|
3
|
+
"version": "2026.4.39",
|
|
4
4
|
"description": "Unified provider adapters for CLEO (Claude Code, OpenCode, Cursor)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@cleocode/caamp": "2026.4.
|
|
16
|
-
"@cleocode/contracts": "2026.4.
|
|
15
|
+
"@cleocode/caamp": "2026.4.39",
|
|
16
|
+
"@cleocode/contracts": "2026.4.39"
|
|
17
17
|
},
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"engines": {
|
|
@@ -123,6 +123,10 @@ export class ClaudeCodeAdapter implements CLEOProviderAdapter {
|
|
|
123
123
|
async initialize(projectDir: string): Promise<void> {
|
|
124
124
|
this.projectDir = projectDir;
|
|
125
125
|
this.initialized = true;
|
|
126
|
+
|
|
127
|
+
// Activate CLEO hook bridge for this project — connects Claude Code
|
|
128
|
+
// native events to CLEO's internal hook dispatch (T555).
|
|
129
|
+
await this.hooks.registerNativeHooks(projectDir);
|
|
126
130
|
}
|
|
127
131
|
|
|
128
132
|
/**
|
|
@@ -16,7 +16,9 @@
|
|
|
16
16
|
* @epic T134
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
19
20
|
import { readdir, readFile } from 'node:fs/promises';
|
|
21
|
+
import { homedir } from 'node:os';
|
|
20
22
|
import { join } from 'node:path';
|
|
21
23
|
import type { AdapterHookProvider } from '@cleocode/contracts';
|
|
22
24
|
|
|
@@ -107,33 +109,145 @@ export class ClaudeCodeHookProvider implements AdapterHookProvider {
|
|
|
107
109
|
return CLAUDE_CODE_EVENT_MAP[providerEvent] ?? null;
|
|
108
110
|
}
|
|
109
111
|
|
|
112
|
+
/** Project directory this hook provider was registered for. */
|
|
113
|
+
private projectDir: string | null = null;
|
|
114
|
+
|
|
110
115
|
/**
|
|
111
116
|
* Register native hooks for a project.
|
|
112
117
|
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
118
|
+
* Writes CLEO hook entries to `~/.claude/settings.json` so that Claude Code's
|
|
119
|
+
* native event system calls cleo CLI commands when events fire. This bridges
|
|
120
|
+
* Claude Code's event loop to CLEO's internal hook dispatch.
|
|
116
121
|
*
|
|
117
|
-
*
|
|
118
|
-
* `getSupportedCanonicalEvents()` to enumerate all 14 supported hooks.
|
|
122
|
+
* Idempotent: skips writing if CLEO hooks already exist in settings.json.
|
|
119
123
|
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
124
|
+
* Hook entries registered:
|
|
125
|
+
* - `Stop` → `cleo session end --quiet` (triggers LLM extraction, reflector, consolidation)
|
|
126
|
+
* - `PostToolUse` (Write|Edit) → brain observation for file modifications
|
|
127
|
+
* - `SubagentStop` → brain observation for agent completion
|
|
128
|
+
*
|
|
129
|
+
* @param projectDir - Project directory for context-scoped hook commands
|
|
130
|
+
* @task T164 @task T555
|
|
122
131
|
*/
|
|
123
|
-
async registerNativeHooks(
|
|
132
|
+
async registerNativeHooks(projectDir: string): Promise<void> {
|
|
133
|
+
this.projectDir = projectDir;
|
|
124
134
|
this.registered = true;
|
|
135
|
+
|
|
136
|
+
// Write CLEO hook entries to ~/.claude/settings.json (idempotent)
|
|
137
|
+
try {
|
|
138
|
+
const home = homedir();
|
|
139
|
+
const settingsPath = join(home, '.claude', 'settings.json');
|
|
140
|
+
|
|
141
|
+
let settings: Record<string, unknown> = {};
|
|
142
|
+
if (existsSync(settingsPath)) {
|
|
143
|
+
try {
|
|
144
|
+
settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
|
|
145
|
+
} catch {
|
|
146
|
+
// Start fresh if settings.json is corrupt
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const hooks = (settings.hooks ?? {}) as Record<string, unknown[]>;
|
|
151
|
+
|
|
152
|
+
// Check if CLEO hooks already registered (look for our marker comment in commands)
|
|
153
|
+
const alreadyRegistered = Object.values(hooks).some((entries) =>
|
|
154
|
+
Array.isArray(entries) &&
|
|
155
|
+
entries.some(
|
|
156
|
+
(e) =>
|
|
157
|
+
typeof e === 'object' &&
|
|
158
|
+
e !== null &&
|
|
159
|
+
Array.isArray((e as Record<string, unknown>).hooks) &&
|
|
160
|
+
((e as Record<string, unknown>).hooks as Array<Record<string, string>>).some(
|
|
161
|
+
(h) => typeof h.command === 'string' && h.command.includes('# cleo-hook'),
|
|
162
|
+
),
|
|
163
|
+
),
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
if (alreadyRegistered) {
|
|
167
|
+
return; // Already wired — idempotent
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Register Stop hook → triggers cleo session end (LLM extraction, reflector, consolidation)
|
|
171
|
+
if (!hooks.Stop) hooks.Stop = [];
|
|
172
|
+
(hooks.Stop as unknown[]).push({
|
|
173
|
+
matcher: '',
|
|
174
|
+
hooks: [
|
|
175
|
+
{
|
|
176
|
+
type: 'command',
|
|
177
|
+
command: `cleo session end --quiet # cleo-hook`,
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// Register PostToolUse hook → brain observation for file writes
|
|
183
|
+
if (!hooks.PostToolUse) hooks.PostToolUse = [];
|
|
184
|
+
(hooks.PostToolUse as unknown[]).push({
|
|
185
|
+
matcher: 'Write|Edit',
|
|
186
|
+
hooks: [
|
|
187
|
+
{
|
|
188
|
+
type: 'command',
|
|
189
|
+
command: `cleo observe "File modified via $TOOL_NAME" --title "tool-use" --quiet # cleo-hook`,
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
settings.hooks = hooks;
|
|
195
|
+
mkdirSync(join(home, '.claude'), { recursive: true });
|
|
196
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
|
|
197
|
+
} catch {
|
|
198
|
+
// Settings write failure is non-fatal — hooks can be registered manually
|
|
199
|
+
}
|
|
125
200
|
}
|
|
126
201
|
|
|
127
202
|
/**
|
|
128
203
|
* Unregister native hooks.
|
|
129
204
|
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
205
|
+
* Removes CLEO hook entries from `~/.claude/settings.json` by filtering out
|
|
206
|
+
* entries containing the `# cleo-hook` marker.
|
|
132
207
|
*
|
|
133
|
-
* @task T164
|
|
208
|
+
* @task T164 @task T555
|
|
134
209
|
*/
|
|
135
210
|
async unregisterNativeHooks(): Promise<void> {
|
|
136
211
|
this.registered = false;
|
|
212
|
+
this.projectDir = null;
|
|
213
|
+
|
|
214
|
+
try {
|
|
215
|
+
const home = homedir();
|
|
216
|
+
const settingsPath = join(home, '.claude', 'settings.json');
|
|
217
|
+
if (!existsSync(settingsPath)) return;
|
|
218
|
+
|
|
219
|
+
const settings = JSON.parse(readFileSync(settingsPath, 'utf-8')) as Record<string, unknown>;
|
|
220
|
+
const hooks = settings.hooks as Record<string, unknown[]> | undefined;
|
|
221
|
+
if (!hooks) return;
|
|
222
|
+
|
|
223
|
+
// Filter out entries with the cleo-hook marker
|
|
224
|
+
let changed = false;
|
|
225
|
+
for (const [event, entries] of Object.entries(hooks)) {
|
|
226
|
+
if (!Array.isArray(entries)) continue;
|
|
227
|
+
const filtered = entries.filter(
|
|
228
|
+
(e) =>
|
|
229
|
+
!(
|
|
230
|
+
typeof e === 'object' &&
|
|
231
|
+
e !== null &&
|
|
232
|
+
Array.isArray((e as Record<string, unknown>).hooks) &&
|
|
233
|
+
((e as Record<string, unknown>).hooks as Array<Record<string, string>>).some(
|
|
234
|
+
(h) => typeof h.command === 'string' && h.command.includes('# cleo-hook'),
|
|
235
|
+
)
|
|
236
|
+
),
|
|
237
|
+
);
|
|
238
|
+
if (filtered.length !== entries.length) {
|
|
239
|
+
hooks[event] = filtered;
|
|
240
|
+
changed = true;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (changed) {
|
|
245
|
+
settings.hooks = hooks;
|
|
246
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
|
|
247
|
+
}
|
|
248
|
+
} catch {
|
|
249
|
+
// Cleanup failure is non-fatal
|
|
250
|
+
}
|
|
137
251
|
}
|
|
138
252
|
|
|
139
253
|
/**
|
|
@@ -143,6 +257,15 @@ export class ClaudeCodeHookProvider implements AdapterHookProvider {
|
|
|
143
257
|
return this.registered;
|
|
144
258
|
}
|
|
145
259
|
|
|
260
|
+
/**
|
|
261
|
+
* Get the project directory this hook provider was registered for.
|
|
262
|
+
*
|
|
263
|
+
* Returns null if hooks have not been registered yet.
|
|
264
|
+
*/
|
|
265
|
+
getProjectDir(): string | null {
|
|
266
|
+
return this.projectDir;
|
|
267
|
+
}
|
|
268
|
+
|
|
146
269
|
/**
|
|
147
270
|
* Get the native→canonical event mapping for introspection and debugging.
|
|
148
271
|
*
|