@cleocode/adapters 2026.10.18 → 2026.10.19-rc.ci.689

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 +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"}
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,CA6C1B;AAED,+EAA+E;AAC/E,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,wBAAwB,EACjC,QAAQ,EAAE,WAAW,EAAE,GACtB,uBAAuB,CA4CzB"}
@@ -45,11 +45,19 @@ function normalizeNativeProjectHook(argv, body, cwd) {
45
45
  };
46
46
  const payload = JSON.parse(body || "{}");
47
47
  if (!object(payload)) throw new Error("HOOK_AGENT_INPUT_INVALID");
48
+ const sessionId = payload.session_id;
49
+ const nativeSession = typeof sessionId === "string" && sessionId.length > 0 && sessionId.length <= 256 && /^[a-z][a-z0-9-]{0,63}$/.test(provider) ? { sessionId, harness: provider } : void 0;
48
50
  return {
49
51
  cwd: typeof payload.cwd === "string" ? payload.cwd : cwd,
50
52
  provider,
51
53
  nativeEvent: typeof payload.hook_event_name === "string" ? payload.hook_event_name : event,
52
- input: { schemaVersion: 1, source, event, toolInput: payload.tool_input ?? {} }
54
+ input: {
55
+ schemaVersion: 1,
56
+ source,
57
+ event,
58
+ toolInput: payload.tool_input ?? {},
59
+ ...nativeSession ? { nativeSession } : {}
60
+ }
53
61
  };
54
62
  }
55
63
  function renderNativeProjectHook(request, outcomes) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/project-hook-native.ts"],
4
- "mappings": "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",
4
+ "mappings": "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",
5
5
  "names": ["line"]
6
6
  }
@@ -55,6 +55,20 @@ export interface HeavyHookDetection {
55
55
  * @returns whether it is in use, and why.
56
56
  */
57
57
  export declare function detectHeavyHookProvider(provider: HeavyCommandHookProvider, projectDir: string, env?: Env): HeavyHookDetection;
58
+ /**
59
+ * Install only CLEO's Stop dispatcher (`cleo hook stop`, T13796) for one
60
+ * provider in the project, whatever the heavy-command mode, and nothing
61
+ * else (no `PreToolUse` hook). `cleo goal install --harness claude|codex`
62
+ * uses it so the dispatcher runs the CLEO Goal tick (T13820). Project-level
63
+ * only: a project that is the home directory, a target in the user-global
64
+ * Claude config, or a shared `.codex/hooks.json` is refused unwritten.
65
+ * Never throws.
66
+ *
67
+ * @param projectDir - the project root.
68
+ * @param provider - `claude-code` or `codex`.
69
+ * @returns the outcome for that provider.
70
+ */
71
+ export declare function syncProjectStopDispatch(projectDir: string, provider: 'claude-code' | 'codex'): Promise<HeavyHookDeliveryOutcome>;
58
72
  /**
59
73
  * Install, refresh or (mode `off`) remove CLEO's heavy-command hook for every
60
74
  * provider in use in `projectDir`, each independently: one provider's failure
@@ -1 +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;AA2B7B,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;AAqFD;;;;;;;;;;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,CA6CnB;AAED,+DAA+D;AAC/D,eAAO,MAAM,oBAAoB,EAAE,oBAIjC,CAAC"}
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;AA8B7B,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;AA2BD;;;;;;;;;;;;GAYG;AACH,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,aAAa,GAAG,OAAO,GAChC,OAAO,CAAC,wBAAwB,CAAC,CA6BnC;AA4DD;;;;;;;;;;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,CA6CnB;AAED,+DAA+D;AAC/D,eAAO,MAAM,oBAAoB,EAAE,oBAKjC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cleocode/adapters",
3
- "version": "2026.10.18",
3
+ "version": "2026.10.19-rc.ci.689",
4
4
  "description": "Unified provider adapters for CLEO (Claude Code, OpenCode, Cursor)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -27,9 +27,9 @@
27
27
  "@ai-sdk/anthropic": "^3.0.69",
28
28
  "@ai-sdk/openai": "^2.0.53",
29
29
  "ai": "^6.0.168",
30
- "@cleocode/caamp": "2026.10.18",
31
- "@cleocode/contracts": "2026.10.18",
32
- "@cleocode/paths": "2026.10.18"
30
+ "@cleocode/caamp": "2026.10.19-rc.ci.689",
31
+ "@cleocode/contracts": "2026.10.19-rc.ci.689",
32
+ "@cleocode/paths": "2026.10.19-rc.ci.689"
33
33
  },
34
34
  "license": "MIT",
35
35
  "engines": {
@@ -42,8 +42,8 @@
42
42
  "devDependencies": {
43
43
  "@types/node": "^24.3.0",
44
44
  "vitest": "^4.1.4",
45
- "@cleocode/playbooks": "2026.10.18",
46
- "@cleocode/core": "2026.10.18"
45
+ "@cleocode/core": "2026.10.19-rc.ci.689",
46
+ "@cleocode/playbooks": "2026.10.19-rc.ci.689"
47
47
  },
48
48
  "repository": {
49
49
  "type": "git",
@@ -133,10 +133,23 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
133
133
  * `@cleocode/core`. Loading the SQL directly keeps the test hermetic without
134
134
  * re-implementing the schema inline.
135
135
  */
136
- const MIGRATION_SQL = resolve(
137
- __dirname,
138
- '../../../core/migrations/drizzle-tasks/20260417220000_t889-playbook-tables/migration.sql',
139
- );
136
+ const PROJECT_MIGRATIONS = resolve(__dirname, '../../../core/migrations/drizzle-cleo-project');
137
+
138
+ /** The playbook twins the state layer writes, as a project store creates them (T12535). */
139
+ function playbookTwinSql(): string {
140
+ const consolidation = readFileSync(
141
+ resolve(PROJECT_MIGRATIONS, '20260531000001_t11363-consolidation-cleo-project/migration.sql'),
142
+ 'utf8',
143
+ );
144
+ const tables = ['tasks_playbook_runs', 'tasks_playbook_approvals'].map(
145
+ (t) => consolidation.match(new RegExp(`CREATE TABLE \`${t}\` \\([\\s\\S]*?\\n\\);`))?.[0] ?? '',
146
+ );
147
+ const uids = readFileSync(
148
+ resolve(PROJECT_MIGRATIONS, '20261016120000_t12535-playbook-row-uids/migration.sql'),
149
+ 'utf8',
150
+ );
151
+ return [...tables, uids].join('\n--> statement-breakpoint\n');
152
+ }
140
153
 
141
154
  /** Absolute path to the rcasd.cantbook starter playbook (T934). */
142
155
  const RCASD_CANTBOOK = resolve(__dirname, '../../../playbooks/starter/rcasd.cantbook');
@@ -263,7 +276,7 @@ describe('T937 — harness interop: playbook runtime across provider adapters',
263
276
  beforeEach(() => {
264
277
  db = new DatabaseSync(':memory:');
265
278
  db.exec('PRAGMA foreign_keys=ON');
266
- applyMigration(db, readFileSync(MIGRATION_SQL, 'utf8'));
279
+ applyMigration(db, playbookTwinSql());
267
280
 
268
281
  anthropicCalls.length = 0;
269
282
  openaiCalls.length = 0;
@@ -393,7 +406,7 @@ describe('T937 — harness interop: playbook runtime across provider adapters',
393
406
  // Reset per-provider state so DB rows don't collide.
394
407
  const freshDb = new DatabaseSync(':memory:');
395
408
  freshDb.exec('PRAGMA foreign_keys=ON');
396
- applyMigration(freshDb, readFileSync(MIGRATION_SQL, 'utf8'));
409
+ applyMigration(freshDb, playbookTwinSql());
397
410
 
398
411
  const result = await executePlaybook({
399
412
  db: freshDb,
@@ -69,11 +69,25 @@ export function normalizeNativeProjectHook(
69
69
  };
70
70
  const payload = JSON.parse(body || '{}') as HookJsonValue;
71
71
  if (!object(payload)) throw new Error('HOOK_AGENT_INPUT_INVALID');
72
+ const sessionId = payload.session_id;
73
+ const nativeSession =
74
+ typeof sessionId === 'string' &&
75
+ sessionId.length > 0 &&
76
+ sessionId.length <= 256 &&
77
+ /^[a-z][a-z0-9-]{0,63}$/.test(provider)
78
+ ? { sessionId, harness: provider }
79
+ : undefined;
72
80
  return {
73
81
  cwd: typeof payload.cwd === 'string' ? payload.cwd : cwd,
74
82
  provider,
75
83
  nativeEvent: typeof payload.hook_event_name === 'string' ? payload.hook_event_name : event,
76
- input: { schemaVersion: 1, source, event, toolInput: payload.tool_input ?? {} },
84
+ input: {
85
+ schemaVersion: 1,
86
+ source,
87
+ event,
88
+ toolInput: payload.tool_input ?? {},
89
+ ...(nativeSession ? { nativeSession } : {}),
90
+ },
77
91
  };
78
92
  }
79
93
 
@@ -37,12 +37,15 @@ import type {
37
37
  HeavyHookInspection,
38
38
  } from '@cleocode/contracts';
39
39
  import { findOnPath } from '@cleocode/paths';
40
+ import { projectClaudeSettingsPath } from '../claude-code/paths.js';
40
41
  import {
41
42
  CLAUDE_LOCAL_SETTINGS,
42
43
  CODEX_HOOKS_FILE,
43
44
  codexHookSnippet,
44
45
  codexHooksSharedReason,
45
46
  excludedByCleo,
47
+ excludeHookFileFromGit,
48
+ excludeLocalSettingsFromGit,
46
49
  HEAVY_COMMAND_HOOK_ID,
47
50
  HeavyHookPathBlockedError,
48
51
  HeavyHookSharedConfigError,
@@ -212,6 +215,53 @@ async function syncStopDispatch(
212
215
  }
213
216
  }
214
217
 
218
+ /**
219
+ * Install only CLEO's Stop dispatcher (`cleo hook stop`, T13796) for one
220
+ * provider in the project, whatever the heavy-command mode, and nothing
221
+ * else (no `PreToolUse` hook). `cleo goal install --harness claude|codex`
222
+ * uses it so the dispatcher runs the CLEO Goal tick (T13820). Project-level
223
+ * only: a project that is the home directory, a target in the user-global
224
+ * Claude config, or a shared `.codex/hooks.json` is refused unwritten.
225
+ * Never throws.
226
+ *
227
+ * @param projectDir - the project root.
228
+ * @param provider - `claude-code` or `codex`.
229
+ * @returns the outcome for that provider.
230
+ */
231
+ export async function syncProjectStopDispatch(
232
+ projectDir: string,
233
+ provider: 'claude-code' | 'codex',
234
+ ): Promise<HeavyHookDeliveryOutcome> {
235
+ let target = heavyHookTarget(provider, projectDir);
236
+ if (isUserHomeDir(projectDir)) {
237
+ return {
238
+ provider,
239
+ status: 'skipped',
240
+ target,
241
+ reason: 'the project is the home directory, whose .claude/ and .codex/ are user-global',
242
+ remedy: 'run it from a project directory',
243
+ };
244
+ }
245
+ try {
246
+ if (provider === 'claude-code') target = projectClaudeSettingsPath(projectDir);
247
+ else {
248
+ const shared = codexHooksSharedReason(projectDir);
249
+ if (shared !== null) throw new HeavyHookSharedConfigError(target, shared);
250
+ }
251
+ const status = await syncJsonStopDispatchHook(target, provider, true);
252
+ if (provider === 'claude-code') excludeLocalSettingsFromGit(projectDir);
253
+ else excludeHookFileFromGit(projectDir, CODEX_HOOKS_FILE);
254
+ return { provider, status, target };
255
+ } catch (err) {
256
+ return {
257
+ provider,
258
+ status: err instanceof HeavyHookSharedConfigError ? 'needs-consent' : 'failed',
259
+ target,
260
+ reason: errorText(err),
261
+ };
262
+ }
263
+ }
264
+
215
265
  async function syncProvider(
216
266
  provider: HeavyCommandHookProvider,
217
267
  projectDir: string,
@@ -645,6 +695,7 @@ export function probeHeavyHookCli(
645
695
  /** The delivery surface `@cleocode/core` loads at run time. */
646
696
  export const heavyHookDeliveryApi: HeavyHookDeliveryApi = Object.freeze({
647
697
  syncProjectHeavyCommandHooks,
698
+ syncProjectStopDispatch,
648
699
  inspectProjectHeavyCommandHooks,
649
700
  probeHeavyHookCli,
650
701
  });