@ken-jo/agent-connector 0.4.1 → 0.4.7
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/README.md +2 -2
- package/dist/{action-WT7GVRCC.js → action-YCU53FNE.js} +8 -8
- package/dist/{amazon-q-COAL3764.js → amazon-q-W574ZX35.js} +2 -2
- package/dist/amp-JPBQJJVM.js +666 -0
- package/dist/amp-JPBQJJVM.js.map +1 -0
- package/dist/{antigravity-AMKKKHS4.js → antigravity-VK2Y3FGV.js} +3 -3
- package/dist/{antigravity-cli-XERXEH5W.js → antigravity-cli-D4PCCUG2.js} +3 -3
- package/dist/{chunk-DCKFYWGM.js → chunk-2F5QH3D4.js} +36 -36
- package/dist/{chunk-RIMVWCZY.js → chunk-6RYPUR6O.js} +5 -5
- package/dist/{chunk-QREL7LZJ.js → chunk-7ECYDK5T.js} +2 -2
- package/dist/{chunk-O5TWCIJN.js → chunk-CYOAH23F.js} +18 -18
- package/dist/{chunk-URHQMFB3.js → chunk-DT6Y7XBI.js} +62 -16
- package/dist/chunk-DT6Y7XBI.js.map +1 -0
- package/dist/{chunk-2AVLX7GH.js → chunk-HAIMYUEY.js} +3 -3
- package/dist/{chunk-4ENJK5S2.js → chunk-MDNX7HTN.js} +2 -2
- package/dist/{chunk-EXLS7BSI.js → chunk-NLFPH4S2.js} +10 -2
- package/dist/chunk-NLFPH4S2.js.map +1 -0
- package/dist/{chunk-CPLK7GTE.js → chunk-PFDUGDOA.js} +351 -34
- package/dist/chunk-PFDUGDOA.js.map +1 -0
- package/dist/{chunk-EGCBZ2DC.js → chunk-SDPIT4HW.js} +2 -2
- package/dist/{chunk-5OWS5CMA.js → chunk-SPWFUHHK.js} +5 -5
- package/dist/{chunk-LQRAPXS4.js → chunk-TZQBASI7.js} +4 -2
- package/dist/chunk-TZQBASI7.js.map +1 -0
- package/dist/{chunk-XJ4S47CT.js → chunk-WFXWJITA.js} +2 -2
- package/dist/{chunk-24IDL5RW.js → chunk-YQLQJZ7S.js} +2 -2
- package/dist/{claude-code-W4PUFZL5.js → claude-code-ROSIILTM.js} +36 -100
- package/dist/claude-code-ROSIILTM.js.map +1 -0
- package/dist/cli/sdk.js +4 -4
- package/dist/cli.js +1 -1
- package/dist/{cline-WRYMNS7Z.js → cline-JUTO4V27.js} +2 -2
- package/dist/{codebuff-DH5Y7GAT.js → codebuff-2QUHL6HO.js} +127 -6
- package/dist/codebuff-2QUHL6HO.js.map +1 -0
- package/dist/{codex-DDHIV767.js → codex-YBBTIDD4.js} +109 -114
- package/dist/codex-YBBTIDD4.js.map +1 -0
- package/dist/{continue-K43SUHLQ.js → continue-W4TU4JSB.js} +5 -3
- package/dist/continue-W4TU4JSB.js.map +1 -0
- package/dist/{copilot-cli-Q3SSPT4V.js → copilot-cli-Y74SOP5G.js} +4 -2
- package/dist/copilot-cli-Y74SOP5G.js.map +1 -0
- package/dist/{crush-MBEH2R3I.js → crush-GMEWLXK5.js} +4 -2
- package/dist/{crush-MBEH2R3I.js.map → crush-GMEWLXK5.js.map} +1 -1
- package/dist/{cursor-TMBXDYR4.js → cursor-JBS4B3Q4.js} +50 -134
- package/dist/cursor-JBS4B3Q4.js.map +1 -0
- package/dist/{detect-KG5FG3EV.js → detect-2NIXILMZ.js} +4 -4
- package/dist/{doctor-FLZF34Y3.js → doctor-QWJBWALA.js} +8 -8
- package/dist/{droid-JC2NT6S4.js → droid-TJMTNCQE.js} +48 -106
- package/dist/droid-TJMTNCQE.js.map +1 -0
- package/dist/{gemini-cli-ILR7M5X3.js → gemini-cli-RAONGZRG.js} +7 -2
- package/dist/gemini-cli-RAONGZRG.js.map +1 -0
- package/dist/{goose-SFO5BBGW.js → goose-G4KKM6YU.js} +91 -131
- package/dist/goose-G4KKM6YU.js.map +1 -0
- package/dist/{hermes-3N7WN4WS.js → hermes-PJDTJE6F.js} +29 -33
- package/dist/hermes-PJDTJE6F.js.map +1 -0
- package/dist/{hook-XR3Z45FB.js → hook-FDGIQPRC.js} +8 -8
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/{install-BSR62UHJ.js → install-TLG3QVP3.js} +8 -8
- package/dist/{introspect-Nw8hTReX.d.ts → introspect-Cn3MSA4_.d.ts} +1 -1
- package/dist/{jetbrains-copilot-NRZHI5PC.js → jetbrains-copilot-DNXSLQE5.js} +4 -2
- package/dist/jetbrains-copilot-DNXSLQE5.js.map +1 -0
- package/dist/{kilo-5NWOXVSD.js → kilo-FERJ3X46.js} +101 -5
- package/dist/kilo-FERJ3X46.js.map +1 -0
- package/dist/{kilo-cli-UZ7R5UOP.js → kilo-cli-TDCONH5G.js} +108 -12
- package/dist/kilo-cli-TDCONH5G.js.map +1 -0
- package/dist/{kimi-2YFK2GBA.js → kimi-RIRD4J5J.js} +12 -2
- package/dist/kimi-RIRD4J5J.js.map +1 -0
- package/dist/{kiro-YL6AWUYG.js → kiro-X7JVLAN7.js} +4 -2
- package/dist/kiro-X7JVLAN7.js.map +1 -0
- package/dist/{leaderboard-MJG24O35.js → leaderboard-MXGENYXN.js} +2 -2
- package/dist/{mimo-code-FTMGSKMQ.js → mimo-code-RFLQ727H.js} +2 -2
- package/dist/{mux-5XZFB44C.js → mux-D77HBSBU.js} +3 -17
- package/dist/mux-D77HBSBU.js.map +1 -0
- package/dist/{nemoclaw-W5KEJ3WX.js → nemoclaw-LXUTMR56.js} +3 -3
- package/dist/{omp-2QMEY6HD.js → omp-CO7IXURG.js} +2 -2
- package/dist/{openclaw-EXJEFNZI.js → openclaw-XWJLEW35.js} +3 -3
- package/dist/{opencode-WNXYJR4X.js → opencode-QKZ5EIYU.js} +5 -2
- package/dist/opencode-QKZ5EIYU.js.map +1 -0
- package/dist/{package-ACZXJHWB.js → package-IA56LSC3.js} +6 -6
- package/dist/{pi-PVVPVWKG.js → pi-YGBXYWY5.js} +2 -2
- package/dist/{qwen-code-G4CXKUHR.js → qwen-code-E2MSEZK6.js} +55 -123
- package/dist/qwen-code-E2MSEZK6.js.map +1 -0
- package/dist/{roo-code-67TYJIQR.js → roo-code-AGGJ473T.js} +2 -2
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +6 -6
- package/dist/sdk/index.d.ts +3 -3
- package/dist/sdk/index.js +3 -3
- package/dist/sdk/test.d.ts +2 -2
- package/dist/sdk/test.js +5 -5
- package/dist/{serve-GER7URPR.js → serve-RNUCK5F7.js} +8 -8
- package/dist/{status-LAJE3BM5.js → status-JOX6RLJU.js} +6 -6
- package/dist/{statusline-L376ZPZU.js → statusline-ZVFI5DRT.js} +7 -7
- package/dist/{telemetry-B3DX3PWU.js → telemetry-3FN6HDVU.js} +5 -5
- package/dist/{trae-7CZZGOGI.js → trae-6L226ZDU.js} +2 -2
- package/dist/{types-CRVrFWeU.d.ts → types-_6arHbX9.d.ts} +5 -4
- package/dist/{uninstall-ZYTW7YMZ.js → uninstall-SCKZYB4J.js} +8 -8
- package/dist/{upgrade-4LUEEOZW.js → upgrade-WU3KZWR4.js} +8 -8
- package/dist/{usage-ZFBVQF3H.js → usage-G72SF7JG.js} +2 -2
- package/dist/{usage-event-GZ32AGEB.js → usage-event-DHSEBO5T.js} +7 -7
- package/dist/{vscode-copilot-MF2CDNMT.js → vscode-copilot-6EOZDLXC.js} +4 -2
- package/dist/vscode-copilot-6EOZDLXC.js.map +1 -0
- package/dist/{warp-VKG55TAT.js → warp-N5YYN5BF.js} +2 -2
- package/dist/{windsurf-FU5G4SHF.js → windsurf-4TGSJIVV.js} +2 -2
- package/dist/{zed-SFUHL3GS.js → zed-6P2UFWXU.js} +2 -2
- package/package.json +1 -1
- package/dist/amp-4U33CU7E.js +0 -300
- package/dist/amp-4U33CU7E.js.map +0 -1
- package/dist/chunk-CPLK7GTE.js.map +0 -1
- package/dist/chunk-EXLS7BSI.js.map +0 -1
- package/dist/chunk-LQRAPXS4.js.map +0 -1
- package/dist/chunk-URHQMFB3.js.map +0 -1
- package/dist/claude-code-W4PUFZL5.js.map +0 -1
- package/dist/codebuff-DH5Y7GAT.js.map +0 -1
- package/dist/codex-DDHIV767.js.map +0 -1
- package/dist/continue-K43SUHLQ.js.map +0 -1
- package/dist/copilot-cli-Q3SSPT4V.js.map +0 -1
- package/dist/cursor-TMBXDYR4.js.map +0 -1
- package/dist/droid-JC2NT6S4.js.map +0 -1
- package/dist/gemini-cli-ILR7M5X3.js.map +0 -1
- package/dist/goose-SFO5BBGW.js.map +0 -1
- package/dist/hermes-3N7WN4WS.js.map +0 -1
- package/dist/jetbrains-copilot-NRZHI5PC.js.map +0 -1
- package/dist/kilo-5NWOXVSD.js.map +0 -1
- package/dist/kilo-cli-UZ7R5UOP.js.map +0 -1
- package/dist/kimi-2YFK2GBA.js.map +0 -1
- package/dist/kiro-YL6AWUYG.js.map +0 -1
- package/dist/mux-5XZFB44C.js.map +0 -1
- package/dist/opencode-WNXYJR4X.js.map +0 -1
- package/dist/qwen-code-G4CXKUHR.js.map +0 -1
- package/dist/vscode-copilot-MF2CDNMT.js.map +0 -1
- /package/dist/{action-WT7GVRCC.js.map → action-YCU53FNE.js.map} +0 -0
- /package/dist/{amazon-q-COAL3764.js.map → amazon-q-W574ZX35.js.map} +0 -0
- /package/dist/{antigravity-AMKKKHS4.js.map → antigravity-VK2Y3FGV.js.map} +0 -0
- /package/dist/{antigravity-cli-XERXEH5W.js.map → antigravity-cli-D4PCCUG2.js.map} +0 -0
- /package/dist/{chunk-DCKFYWGM.js.map → chunk-2F5QH3D4.js.map} +0 -0
- /package/dist/{chunk-RIMVWCZY.js.map → chunk-6RYPUR6O.js.map} +0 -0
- /package/dist/{chunk-QREL7LZJ.js.map → chunk-7ECYDK5T.js.map} +0 -0
- /package/dist/{chunk-O5TWCIJN.js.map → chunk-CYOAH23F.js.map} +0 -0
- /package/dist/{chunk-2AVLX7GH.js.map → chunk-HAIMYUEY.js.map} +0 -0
- /package/dist/{chunk-4ENJK5S2.js.map → chunk-MDNX7HTN.js.map} +0 -0
- /package/dist/{chunk-EGCBZ2DC.js.map → chunk-SDPIT4HW.js.map} +0 -0
- /package/dist/{chunk-5OWS5CMA.js.map → chunk-SPWFUHHK.js.map} +0 -0
- /package/dist/{chunk-XJ4S47CT.js.map → chunk-WFXWJITA.js.map} +0 -0
- /package/dist/{chunk-24IDL5RW.js.map → chunk-YQLQJZ7S.js.map} +0 -0
- /package/dist/{cline-WRYMNS7Z.js.map → cline-JUTO4V27.js.map} +0 -0
- /package/dist/{detect-KG5FG3EV.js.map → detect-2NIXILMZ.js.map} +0 -0
- /package/dist/{doctor-FLZF34Y3.js.map → doctor-QWJBWALA.js.map} +0 -0
- /package/dist/{hook-XR3Z45FB.js.map → hook-FDGIQPRC.js.map} +0 -0
- /package/dist/{install-BSR62UHJ.js.map → install-TLG3QVP3.js.map} +0 -0
- /package/dist/{leaderboard-MJG24O35.js.map → leaderboard-MXGENYXN.js.map} +0 -0
- /package/dist/{mimo-code-FTMGSKMQ.js.map → mimo-code-RFLQ727H.js.map} +0 -0
- /package/dist/{nemoclaw-W5KEJ3WX.js.map → nemoclaw-LXUTMR56.js.map} +0 -0
- /package/dist/{omp-2QMEY6HD.js.map → omp-CO7IXURG.js.map} +0 -0
- /package/dist/{openclaw-EXJEFNZI.js.map → openclaw-XWJLEW35.js.map} +0 -0
- /package/dist/{package-ACZXJHWB.js.map → package-IA56LSC3.js.map} +0 -0
- /package/dist/{pi-PVVPVWKG.js.map → pi-YGBXYWY5.js.map} +0 -0
- /package/dist/{roo-code-67TYJIQR.js.map → roo-code-AGGJ473T.js.map} +0 -0
- /package/dist/{serve-GER7URPR.js.map → serve-RNUCK5F7.js.map} +0 -0
- /package/dist/{status-LAJE3BM5.js.map → status-JOX6RLJU.js.map} +0 -0
- /package/dist/{statusline-L376ZPZU.js.map → statusline-ZVFI5DRT.js.map} +0 -0
- /package/dist/{telemetry-B3DX3PWU.js.map → telemetry-3FN6HDVU.js.map} +0 -0
- /package/dist/{trae-7CZZGOGI.js.map → trae-6L226ZDU.js.map} +0 -0
- /package/dist/{uninstall-ZYTW7YMZ.js.map → uninstall-SCKZYB4J.js.map} +0 -0
- /package/dist/{upgrade-4LUEEOZW.js.map → upgrade-WU3KZWR4.js.map} +0 -0
- /package/dist/{usage-ZFBVQF3H.js.map → usage-G72SF7JG.js.map} +0 -0
- /package/dist/{usage-event-GZ32AGEB.js.map → usage-event-DHSEBO5T.js.map} +0 -0
- /package/dist/{warp-VKG55TAT.js.map → warp-N5YYN5BF.js.map} +0 -0
- /package/dist/{windsurf-FU5G4SHF.js.map → windsurf-4TGSJIVV.js.map} +0 -0
- /package/dist/{zed-SFUHL3GS.js.map → zed-6P2UFWXU.js.map} +0 -0
|
@@ -6,8 +6,10 @@ import {
|
|
|
6
6
|
resolveEnvRefsDeep
|
|
7
7
|
} from "./chunk-DBQMX75U.js";
|
|
8
8
|
import {
|
|
9
|
-
BaseAdapter
|
|
10
|
-
|
|
9
|
+
BaseAdapter,
|
|
10
|
+
removeFromObjectMap,
|
|
11
|
+
upsertInObjectMap
|
|
12
|
+
} from "./chunk-PFDUGDOA.js";
|
|
11
13
|
import "./chunk-7L6ITC4T.js";
|
|
12
14
|
import {
|
|
13
15
|
buildHomeBinHookCommand,
|
|
@@ -163,6 +165,17 @@ var CodexAdapter = class extends BaseAdapter {
|
|
|
163
165
|
ensureDir(dirname(path));
|
|
164
166
|
writeFileSync(path, TOML.stringify(data), "utf8");
|
|
165
167
|
}
|
|
168
|
+
/** An ObjectMapCodec over config.toml for the core/object-map engine.
|
|
169
|
+
* `isPresentButUnparseable` is `() => false`: readToml fail-softs to {} and the
|
|
170
|
+
* server path has historically coerced/overwritten rather than warn-skip on an
|
|
171
|
+
* unparseable file — preserved here for byte-identical behavior. */
|
|
172
|
+
tomlObjectMapCodec() {
|
|
173
|
+
return {
|
|
174
|
+
parse: (path) => this.readToml(path),
|
|
175
|
+
serialize: (path, data, dryRun) => this.writeToml(path, data, dryRun),
|
|
176
|
+
isPresentButUnparseable: () => false
|
|
177
|
+
};
|
|
178
|
+
}
|
|
166
179
|
// ── Install server (config.toml → [mcp_servers.<id>]) ───────────────────
|
|
167
180
|
installServer(ctx) {
|
|
168
181
|
const { connector, dryRun } = ctx;
|
|
@@ -171,113 +184,103 @@ var CodexAdapter = class extends BaseAdapter {
|
|
|
171
184
|
if (!server) {
|
|
172
185
|
return [{ platform: this.id, action: "skip", path, detail: "no server declared" }];
|
|
173
186
|
}
|
|
174
|
-
|
|
187
|
+
const isStdio = server.transport === "stdio" && !!server.command;
|
|
188
|
+
const isHttp = server.transport === "http" && !!server.url;
|
|
189
|
+
if (!isStdio && !isHttp) {
|
|
175
190
|
return [
|
|
176
191
|
{
|
|
177
192
|
platform: this.id,
|
|
178
193
|
action: "skip",
|
|
179
194
|
path,
|
|
180
|
-
detail: `transport "${server.transport}" not registrable in config.toml (stdio only)`
|
|
195
|
+
detail: `transport "${server.transport}" not registrable in config.toml (stdio + streamable-http only)`
|
|
181
196
|
}
|
|
182
197
|
];
|
|
183
198
|
}
|
|
184
199
|
const entry = this.renderMcpEntry(ctx, server);
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
return [{ platform: this.id, action, path, detail: `mcp_servers.${connector.id}` }];
|
|
200
|
+
return [
|
|
201
|
+
upsertInObjectMap({
|
|
202
|
+
codec: this.tomlObjectMapCodec(),
|
|
203
|
+
rootKey: "mcp_servers",
|
|
204
|
+
policy: "coerce",
|
|
205
|
+
platform: this.id,
|
|
206
|
+
configPath: path,
|
|
207
|
+
entryId: connector.id,
|
|
208
|
+
entry,
|
|
209
|
+
dryRun
|
|
210
|
+
})
|
|
211
|
+
];
|
|
198
212
|
}
|
|
199
213
|
uninstallServer(ctx) {
|
|
200
214
|
const { connector, dryRun } = ctx;
|
|
201
215
|
const path = this.getServerConfigPath(ctx);
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
-
delete bucket[connector.id];
|
|
215
|
-
this.writeToml(path, cfg, dryRun);
|
|
216
|
-
return [{ platform: this.id, action: "remove", path, detail: `mcp_servers.${connector.id}` }];
|
|
216
|
+
return [
|
|
217
|
+
removeFromObjectMap({
|
|
218
|
+
codec: this.tomlObjectMapCodec(),
|
|
219
|
+
rootKey: "mcp_servers",
|
|
220
|
+
policy: "coerce",
|
|
221
|
+
platform: this.id,
|
|
222
|
+
configPath: path,
|
|
223
|
+
entryId: connector.id,
|
|
224
|
+
dryRun
|
|
225
|
+
})
|
|
226
|
+
];
|
|
217
227
|
}
|
|
218
228
|
// ── Install hooks (hooks.json) ──────────────────────────────────────────
|
|
219
229
|
installHooks(ctx) {
|
|
220
|
-
const { dryRun } = ctx;
|
|
221
230
|
const path = this.getHookConfigPath(ctx);
|
|
222
231
|
const events = this.effectiveHookEvents(ctx);
|
|
223
232
|
const dropped = this.warnSkipHookEvents(ctx);
|
|
224
233
|
if (events.length === 0 && dropped.length === 0) {
|
|
225
234
|
return [{ platform: this.id, action: "skip", path, detail: "no hooks declared" }];
|
|
226
235
|
}
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
platform: this.id,
|
|
233
|
-
action: "warn",
|
|
234
|
-
path,
|
|
235
|
-
detail: `${event} has no Codex hook equivalent \u2014 skipped`
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
for (const event of events) {
|
|
239
|
-
const desired = this.renderHookEntry(ctx, event);
|
|
240
|
-
const list = Array.isArray(hooks[event]) ? hooks[event] : hooks[event] = [];
|
|
241
|
-
const idx = list.findIndex((e) => this.isOurEntry(ctx, event, e));
|
|
242
|
-
if (idx < 0) {
|
|
243
|
-
list.push(desired);
|
|
244
|
-
changes.push({ platform: this.id, action: "create", path, detail: `hooks.${event}` });
|
|
245
|
-
} else if (JSON.stringify(list[idx]) !== JSON.stringify(desired)) {
|
|
246
|
-
list[idx] = desired;
|
|
247
|
-
changes.push({ platform: this.id, action: "update", path, detail: `hooks.${event}` });
|
|
248
|
-
} else {
|
|
249
|
-
changes.push({ platform: this.id, action: "skip", path, detail: `hooks.${event}` });
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
if (changes.some((c) => c.action === "create" || c.action === "update")) {
|
|
253
|
-
this.writeJson(path, file, dryRun);
|
|
254
|
-
}
|
|
255
|
-
return changes;
|
|
236
|
+
const pending = [
|
|
237
|
+
...dropped.map((event) => ({ event, matcher: "" })),
|
|
238
|
+
...events.map((event) => ({ event, matcher: "" }))
|
|
239
|
+
];
|
|
240
|
+
return this.upsertHookEntries(ctx, path, pending, this.hookDescriptor(ctx));
|
|
256
241
|
}
|
|
257
242
|
uninstallHooks(ctx) {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
243
|
+
return this.removeHookEntries(ctx, this.getHookConfigPath(ctx), this.hookDescriptor(ctx));
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Codex hook-merge policy for the shared object-map engine. EVENT-SPECIFIC by
|
|
247
|
+
* construction: every observable (coerce root + bucket, the path-normalized
|
|
248
|
+
* per-event ownership find, the event-derived matcher with `hooks`-then-
|
|
249
|
+
* `matcher` key order, the BARE `hooks.<event>` skip/remove details with NO
|
|
250
|
+
* count, the warn wording, and the absent/no-match skips) is carried here so
|
|
251
|
+
* the engine reproduces the prior in-adapter loop byte-for-byte.
|
|
252
|
+
*/
|
|
253
|
+
hookDescriptor(ctx) {
|
|
254
|
+
return {
|
|
255
|
+
// Codex's server path coerces a malformed root; the hook path matches it.
|
|
256
|
+
malformedPolicy: "coerce",
|
|
257
|
+
// Supported event → identity; a WARN_SKIP event (PostToolUseFailure, which
|
|
258
|
+
// is the only thing `dropped` ever contains) → undefined → warn.
|
|
259
|
+
mapEvent: (e) => CODEX_HOOK_EVENTS.includes(e) ? e : void 0,
|
|
260
|
+
unmappedWarnDetail: (e) => `${e} has no Codex hook equivalent \u2014 skipped`,
|
|
261
|
+
renderEntry: (event, _matcher, command) => {
|
|
262
|
+
const entry = { hooks: [{ type: "command", command }] };
|
|
263
|
+
entry.matcher = event === "PreToolUse" || event === "PermissionRequest" ? PRE_TOOL_USE_MATCHER : "";
|
|
264
|
+
return entry;
|
|
265
|
+
},
|
|
266
|
+
// Idempotency find for the CANONICAL event the engine built `command` from —
|
|
267
|
+
// path-normalized, exact-command, the body of isOurEntry's command check.
|
|
268
|
+
entryOwnsCommand: (entry, command) => Array.isArray(entry.hooks) && entry.hooks.some(
|
|
269
|
+
(h) => (h.command ?? "").replace(/\\/g, "/") === command.replace(/\\/g, "/")
|
|
270
|
+
),
|
|
271
|
+
// FLAT whole-entry removal, EVENT-SPECIFIC: isOurEntry rebuilds our command
|
|
272
|
+
// from the event key being stripped, so a SubagentStop entry is never matched
|
|
273
|
+
// while iterating the PreToolUse bucket.
|
|
274
|
+
ownsEntryForRemove: (c, event) => (entry) => this.isOurEntry(c, event, entry),
|
|
275
|
+
skipDetail: (e) => `hooks.${e}`,
|
|
276
|
+
removeDetail: (e, _n) => `hooks.${e}`,
|
|
277
|
+
absentDetail: "no hooks.json",
|
|
278
|
+
noMatchDetail: "no agent-connector hooks present",
|
|
279
|
+
// Uninstall scans EXACTLY codex's fixed event set (not Object.keys), so a
|
|
280
|
+
// home-bin command hand-placed under a foreign event key is left untouched —
|
|
281
|
+
// byte-identical to the prior `for (const event of CODEX_HOOK_EVENTS)` loop.
|
|
282
|
+
removeEventKeys: CODEX_HOOK_EVENTS
|
|
283
|
+
};
|
|
281
284
|
}
|
|
282
285
|
// ── Health checks (default doctor renders these) ────────────────────────
|
|
283
286
|
getHealthChecks(ctx) {
|
|
@@ -689,6 +692,20 @@ var CodexAdapter = class extends BaseAdapter {
|
|
|
689
692
|
* plain string→string map. Honors the telemetry serve-wrapper.
|
|
690
693
|
*/
|
|
691
694
|
renderMcpEntry(ctx, server) {
|
|
695
|
+
if (server.transport === "http") {
|
|
696
|
+
const remote = { url: resolveEnvRefsDeep(server.url ?? "") };
|
|
697
|
+
if (server.auth?.type === "bearerEnv" && server.auth.bearerEnvVar) {
|
|
698
|
+
remote.bearer_token_env_var = server.auth.bearerEnvVar;
|
|
699
|
+
}
|
|
700
|
+
if (server.headers && Object.keys(server.headers).length > 0) {
|
|
701
|
+
const headers = {};
|
|
702
|
+
for (const [k, v] of Object.entries(resolveEnvRefsDeep(server.headers))) {
|
|
703
|
+
headers[k] = String(v);
|
|
704
|
+
}
|
|
705
|
+
remote.http_headers = headers;
|
|
706
|
+
}
|
|
707
|
+
return remote;
|
|
708
|
+
}
|
|
692
709
|
let command = server.command;
|
|
693
710
|
let args = [...server.args ?? []];
|
|
694
711
|
if (shouldWrapForTelemetry(server, ctx.connector.telemetry)) {
|
|
@@ -709,40 +726,18 @@ var CodexAdapter = class extends BaseAdapter {
|
|
|
709
726
|
}
|
|
710
727
|
return entry;
|
|
711
728
|
}
|
|
712
|
-
/**
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
ctx.connector.id
|
|
719
|
-
);
|
|
720
|
-
const entry = { hooks: [{ type: "command", command }] };
|
|
721
|
-
if (event === "PreToolUse" || event === "PermissionRequest") {
|
|
722
|
-
entry.matcher = PRE_TOOL_USE_MATCHER;
|
|
723
|
-
} else entry.matcher = "";
|
|
724
|
-
return entry;
|
|
725
|
-
}
|
|
726
|
-
/** Does this hooks.json entry belong to this connector (by home-bin command)? */
|
|
729
|
+
/**
|
|
730
|
+
* Does this hooks.json entry belong to this connector for `event`? EVENT-
|
|
731
|
+
* SPECIFIC + path-normalized exact-command match. The engine binds this per
|
|
732
|
+
* event in the uninstall (whole-entry FLAT removal) and the install idempotency
|
|
733
|
+
* find reuses its command body via the descriptor's entryOwnsCommand.
|
|
734
|
+
*/
|
|
727
735
|
isOurEntry(ctx, event, entry) {
|
|
728
736
|
if (!entry || typeof entry !== "object" || !Array.isArray(entry.hooks)) return false;
|
|
729
737
|
const ours = buildHomeBinHookCommand(ctx.homeBinPath, "codex", event, ctx.connector.id);
|
|
730
738
|
const needle = ours.replace(/\\/g, "/");
|
|
731
739
|
return entry.hooks.some((h) => (h.command ?? "").replace(/\\/g, "/") === needle);
|
|
732
740
|
}
|
|
733
|
-
readHooksFile(path) {
|
|
734
|
-
return this.readJson(path) ?? {};
|
|
735
|
-
}
|
|
736
|
-
/** Get-or-create a nested table inside a parsed TOML object. */
|
|
737
|
-
tomlBucket(cfg, key) {
|
|
738
|
-
const existing = cfg[key];
|
|
739
|
-
if (existing && typeof existing === "object" && !Array.isArray(existing)) {
|
|
740
|
-
return existing;
|
|
741
|
-
}
|
|
742
|
-
const fresh = {};
|
|
743
|
-
cfg[key] = fresh;
|
|
744
|
-
return fresh;
|
|
745
|
-
}
|
|
746
741
|
normalizeSource(raw) {
|
|
747
742
|
switch (raw) {
|
|
748
743
|
case "compact":
|
|
@@ -763,4 +758,4 @@ export {
|
|
|
763
758
|
adapter,
|
|
764
759
|
codex_default as default
|
|
765
760
|
};
|
|
766
|
-
//# sourceMappingURL=codex-
|
|
761
|
+
//# sourceMappingURL=codex-YBBTIDD4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters/codex/index.ts"],"sourcesContent":["/**\n * adapters/codex — Codex CLI platform adapter for agent-connector.\n *\n * Codex CLI hook paradigm is \"json-stdio\": the host pipes a JSON payload to a\n * command on stdin and reads JSON/exit-code back — the same wire protocol as\n * Claude Code (PascalCase fields, `hookSpecificOutput` reply wrapper).\n *\n * Two native config files live under the Codex config dir\n * (`$CODEX_HOME` || `~/.codex`, mirrored to `<projectDir>/.codex` for project\n * scope):\n * - config.toml → `[mcp_servers.<id>]` MCP registration (TOML, NO native\n * interpolation, so env-refs are resolved to literals at install time).\n * - hooks.json → Claude-compatible hook registration ({ matcher, hooks }).\n *\n * Grounded in context-mode's proven Codex adapter (configs/codex/{config.toml,\n * hooks.json}, src/adapters/codex/*) — exact TOML MCP shape + hook JSON schema.\n *\n * Known Codex limitations (upstream): PreToolUse deny works but updatedInput is\n * not yet honored (openai/codex#18491); PostToolUse updatedMCPToolOutput is\n * parsed-but-unsupported — hence canModifyArgs / canModifyOutput are false.\n *\n * E1 extension events (verified against developers.openai.com/codex/hooks):\n * - PermissionRequest — native, decision-capable via the nested\n * hookSpecificOutput.decision{behavior:\"allow\"|\"deny\", message?} envelope.\n * Codex docs: updatedInput / updatedPermissions / interrupt FAIL CLOSED on\n * this event, so they are never emitted here.\n * - SubagentStart — native; hookSpecificOutput.additionalContext is injected\n * as developer context for the subagent (not blockable).\n * - SubagentStop — native; the documented continuation shape is the TOP-LEVEL\n * {\"decision\":\"block\",\"reason\"} (Stop semantics: keeps the subagent going).\n * - PostToolUseFailure — NO Codex analog (PostToolUse only); declared hooks\n * for it warn-skip at install and the capability flag stays unset.\n * - PostCompact — native (Codex's hook system fires both PreCompact and\n * PostCompact); observe-only, normalizing the `trigger` (manual|auto)\n * exactly like PreCompact, with a passthrough formatReply.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport TOML from \"@iarna/toml\";\n\nimport type {\n ChangeRecord,\n CommandDef,\n DetectedPlatform,\n HealthCheck,\n HookEventName,\n HookParadigm,\n HookResponse,\n PlatformCapabilities,\n PlatformId,\n ServerDef,\n SkillDef,\n SubagentDef,\n} from \"../../core/types.js\";\nimport { ensureDir } from \"../../core/paths.js\";\nimport { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\nimport {\n removeFromObjectMap,\n upsertInObjectMap,\n type ObjectMapCodec,\n} from \"../../core/object-map.js\";\nimport { writeTomlString } from \"../../core/toml.js\";\nimport {\n buildHomeBinHookCommand,\n buildServeWrapperCommand,\n shouldWrapForTelemetry,\n} from \"../../core/spawn.js\";\nimport { BaseAdapter, type HookMergeDescriptor } from \"../base.js\";\nimport type {\n HookReply,\n InstallContext,\n MemoryTarget,\n NormalizedEvent,\n} from \"../spi.js\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Native shapes\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Raw Codex hook payload (PascalCase event, snake_case fields — Claude-style). */\ninterface CodexHookInput {\n tool_name?: string;\n tool_input?: Record<string, unknown>;\n tool_response?: string;\n session_id?: string;\n cwd?: string;\n hook_event_name?: string;\n source?: string;\n prompt?: string;\n is_error?: boolean;\n stop_hook_active?: boolean;\n trigger?: string;\n message?: string;\n // PostToolUseFailure-style failure field. Codex has NO failure event today;\n // parsed defensively only (the Claude-compatible wire would carry it).\n error?: string;\n // SubagentStart / SubagentStop (agent_type is the matcher subject).\n agent_id?: string;\n agent_type?: string;\n // SubagentStop only — the subagent's own transcript + final message.\n agent_transcript_path?: string;\n last_assistant_message?: string;\n}\n\n/** One hook entry inside hooks.json (Claude-compatible). */\ninterface CodexHookEntry {\n matcher?: string;\n hooks: Array<{ type: \"command\"; command: string }>;\n}\n\n/** Rendered `[mcp_servers.<id>]` table — string env table, no interpolation. */\ninterface CodexMcpEntry {\n // stdio transport\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n // streamable HTTP transport (remote): codex infers the transport from `url`\n // (no explicit transport key). Verified against codex-cli 0.139.0.\n url?: string;\n bearer_token_env_var?: string;\n http_headers?: Record<string, string>;\n}\n\n/**\n * Codex hook events agent-connector registers, in the canonical → native order.\n * Codex uses the same PascalCase event names as Claude Code; the home-binary\n * hook command receives the lowercased event token.\n */\nconst CODEX_HOOK_EVENTS = [\n \"SessionStart\",\n \"PreToolUse\",\n \"PostToolUse\",\n \"PreCompact\",\n \"UserPromptSubmit\",\n \"Stop\",\n \"PermissionRequest\",\n \"SubagentStart\",\n \"SubagentStop\",\n \"PostCompact\",\n] as const;\n\ntype CodexHookEventName = (typeof CODEX_HOOK_EVENTS)[number];\n\n/**\n * Newer canonical events with NO Codex analog: Codex ships PostToolUse only —\n * there is no failure event on the live hooks page. Declared hooks for these\n * warn-skip at install so the degradation is reported, never silent. (The\n * legacy SessionEnd / Notification silent filter predates this convention and\n * is deliberately left untouched.)\n */\nconst WARN_SKIP_EVENTS: ReadonlySet<HookEventName> = new Set([\"PostToolUseFailure\"]);\n\n/**\n * PreToolUse matcher — canonical Codex tool names + bare MCP tool names +\n * external MCP catch-all literal. Charset-clean ([A-Za-z0-9_|] only) so Codex's\n * Rust `regex` exact-matcher short-circuits (no look-around, which Codex\n * rejects at boot). Copied from context-mode's proven matcher.\n */\nconst PRE_TOOL_USE_MATCHER =\n \"local_shell|shell|shell_command|exec_command|Bash|Shell|apply_patch|Edit|Write|grep_files|mcp__\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Adapter\n// ─────────────────────────────────────────────────────────────────────────\n\nexport class CodexAdapter extends BaseAdapter {\n readonly id: PlatformId = \"codex\";\n readonly name = \"Codex CLI\";\n readonly paradigm: HookParadigm = \"json-stdio\";\n\n readonly capabilities: PlatformCapabilities = {\n // Memory surface: AGENTS.md-first managed block. memoryTargets below probes\n // AGENTS.override.md first (it shadows AGENTS.md per directory on codex).\n supportsMemory: true,\n preToolUse: true,\n postToolUse: true,\n preCompact: true,\n sessionStart: true,\n sessionEnd: false,\n userPromptSubmit: true,\n stop: true,\n notification: false,\n // E1 events: PermissionRequest (decision-capable) + SubagentStart/Stop are\n // Codex-native. postToolUseFailure stays unset — Codex has no failure event,\n // so a declared hook for it warn-skips at install.\n permissionRequest: true,\n subagentStart: true,\n subagentStop: true,\n // PostCompact: Codex's hook system fires both PreCompact and PostCompact\n // (developers.openai.com/codex/hooks). Observational only — the reply\n // contract mirrors PreCompact (cannot block/modify a completed compaction).\n postCompact: true,\n canModifyArgs: false,\n canModifyOutput: false,\n canInjectSessionContext: true,\n transports: [\"stdio\", \"http\"],\n // Content surfaces: Codex implements all three.\n // command → ~/.codex/prompts/<name>.md (md+frontmatter, USER SCOPE ONLY)\n // skill → project: .codex/skills/<name>/SKILL.md · user: ~/.agents/skills/<name>/SKILL.md\n // subagent → <codexDir>/agents/<name>.toml (TOML)\n supportsCommands: true,\n supportsSkills: true,\n supportsSubagents: true,\n };\n\n // ── Detection ──────────────────────────────────────────────────────────\n\n detectInstalled(projectDir: string): DetectedPlatform {\n const userDir = this.userConfigDir();\n const projDir = join(projectDir, \".codex\");\n const userCfg = join(userDir, \"config.toml\");\n const projCfg = join(projDir, \"config.toml\");\n\n const userInstalled = existsSync(userDir) || existsSync(userCfg);\n const projInstalled = existsSync(projDir) || existsSync(projCfg);\n const installed = userInstalled || projInstalled;\n const scope = projInstalled && !userInstalled ? \"project\" : \"user\";\n const configPath = scope === \"project\" ? projCfg : userCfg;\n\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n configPath,\n scope,\n reason: installed\n ? `Found Codex config dir (${scope})`\n : `No .codex config dir at ${userDir} or ${projDir}`,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── Native paths ───────────────────────────────────────────────────────\n\n override getConfigDir(ctx: InstallContext): string {\n if (ctx.scope === \"project\") return join(ctx.projectDir, \".codex\");\n return this.userConfigDir();\n }\n\n override getServerConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"config.toml\");\n }\n\n override getHookConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"hooks.json\");\n }\n\n // ── Memory surface: AGENTS.override.md probe + 32 KiB doc-cap budget ─────\n // Codex reads AGENTS.override.md > AGENTS.md per directory (one file per\n // directory), so when the override file exists OUR block must live there or\n // it is never loaded. Combined project docs are capped at 32 KiB\n // (`project_doc_max_bytes`), hence the ~28 KiB per-file budget warn.\n protected override memoryTargets(ctx: InstallContext): MemoryTarget[] {\n // An explicit path override keeps the base resolution (escape hatch wins).\n if (this.memoryOverride(ctx)?.path) return super.memoryTargets(ctx);\n if (ctx.scope !== \"project\" && ctx.scope !== \"user\") return [];\n const budgetBytes = 28 * 1024;\n const dir = ctx.scope === \"project\" ? ctx.projectDir : this.userConfigDir();\n const overrideMd = join(dir, \"AGENTS.override.md\");\n if (existsSync(overrideMd)) {\n return [\n {\n path: overrideMd,\n reason: \"AGENTS.override.md shadows AGENTS.md on codex (one doc per directory)\",\n budgetBytes,\n },\n ];\n }\n return [\n {\n path: join(dir, \"AGENTS.md\"),\n reason:\n ctx.scope === \"project\"\n ? \"AGENTS.md standard (project root; codex is the format's originator)\"\n : \"codex global guidance ($CODEX_HOME/AGENTS.md)\",\n budgetBytes,\n },\n ];\n }\n\n /** `$CODEX_HOME` || `~/.codex` for user scope. */\n private userConfigDir(): string {\n const env = process.env.CODEX_HOME;\n if (env && env.trim() !== \"\") {\n if (env.startsWith(\"~\")) {\n return join(homedir(), env.replace(/^~[/\\\\]?/, \"\"));\n }\n return env;\n }\n return join(homedir(), \".codex\");\n }\n\n // ── TOML config IO (override JSON helpers — config.toml is TOML) ─────────\n\n private readToml(path: string): Record<string, unknown> {\n if (!existsSync(path)) return {};\n try {\n return TOML.parse(readFileSync(path, \"utf8\")) as Record<string, unknown>;\n } catch {\n return {};\n }\n }\n\n private writeToml(path: string, data: Record<string, unknown>, dryRun: boolean): void {\n if (dryRun) return;\n ensureDir(dirname(path));\n // @iarna/toml's stringify type wants its JsonMap; our object is structurally compatible.\n writeFileSync(path, TOML.stringify(data as never), \"utf8\");\n }\n\n /** An ObjectMapCodec over config.toml for the core/object-map engine.\n * `isPresentButUnparseable` is `() => false`: readToml fail-softs to {} and the\n * server path has historically coerced/overwritten rather than warn-skip on an\n * unparseable file — preserved here for byte-identical behavior. */\n private tomlObjectMapCodec(): ObjectMapCodec {\n return {\n parse: (path) => this.readToml(path),\n serialize: (path, data, dryRun) => this.writeToml(path, data, dryRun),\n isPresentButUnparseable: () => false,\n };\n }\n\n // ── Install server (config.toml → [mcp_servers.<id>]) ───────────────────\n\n override installServer(ctx: InstallContext): ChangeRecord[] {\n const { connector, dryRun } = ctx;\n const server = this.effectiveServer(ctx);\n const path = this.getServerConfigPath(ctx);\n\n if (!server) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no server declared\" }];\n }\n const isStdio = server.transport === \"stdio\" && !!server.command;\n const isHttp = server.transport === \"http\" && !!server.url;\n if (!isStdio && !isHttp) {\n // Codex config.toml [mcp_servers] supports stdio (command) + streamable\n // HTTP (url). Other remote transports (sse/ws) have no codex analog.\n return [\n {\n platform: this.id,\n action: \"skip\",\n path,\n detail: `transport \"${server.transport}\" not registrable in config.toml (stdio + streamable-http only)`,\n },\n ];\n }\n\n const entry = this.renderMcpEntry(ctx, server);\n\n return [\n upsertInObjectMap({\n codec: this.tomlObjectMapCodec(),\n rootKey: \"mcp_servers\",\n policy: \"coerce\",\n platform: this.id,\n configPath: path,\n entryId: connector.id,\n entry,\n dryRun,\n }),\n ];\n }\n\n override uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const { connector, dryRun } = ctx;\n const path = this.getServerConfigPath(ctx);\n return [\n removeFromObjectMap({\n codec: this.tomlObjectMapCodec(),\n rootKey: \"mcp_servers\",\n policy: \"coerce\",\n platform: this.id,\n configPath: path,\n entryId: connector.id,\n dryRun,\n }),\n ];\n }\n\n // ── Install hooks (hooks.json) ──────────────────────────────────────────\n\n override installHooks(ctx: InstallContext): ChangeRecord[] {\n const path = this.getHookConfigPath(ctx);\n const events = this.effectiveHookEvents(ctx);\n const dropped = this.warnSkipHookEvents(ctx);\n\n if (events.length === 0 && dropped.length === 0) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no hooks declared\" }];\n }\n\n // HOST-ORDERED pending: warn-skip events (mapEvent → undefined → warn) FIRST,\n // then the supported events in CODEX_HOOK_EVENTS order. Events neither\n // supported nor in WARN_SKIP_EVENTS are never enqueued → silently dropped, as\n // before. matcher is \"\" for every item; renderEntry derives the real matcher\n // from the event (PreToolUse/PermissionRequest), never from this field.\n const pending = [\n ...dropped.map((event) => ({ event: event as string, matcher: \"\" })),\n ...events.map((event) => ({ event: event as string, matcher: \"\" })),\n ];\n return this.upsertHookEntries(ctx, path, pending, this.hookDescriptor(ctx));\n }\n\n override uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n return this.removeHookEntries(ctx, this.getHookConfigPath(ctx), this.hookDescriptor(ctx));\n }\n\n /**\n * Codex hook-merge policy for the shared object-map engine. EVENT-SPECIFIC by\n * construction: every observable (coerce root + bucket, the path-normalized\n * per-event ownership find, the event-derived matcher with `hooks`-then-\n * `matcher` key order, the BARE `hooks.<event>` skip/remove details with NO\n * count, the warn wording, and the absent/no-match skips) is carried here so\n * the engine reproduces the prior in-adapter loop byte-for-byte.\n */\n private hookDescriptor(ctx: InstallContext): HookMergeDescriptor<CodexHookEntry> {\n return {\n // Codex's server path coerces a malformed root; the hook path matches it.\n malformedPolicy: \"coerce\",\n // Supported event → identity; a WARN_SKIP event (PostToolUseFailure, which\n // is the only thing `dropped` ever contains) → undefined → warn.\n mapEvent: (e) =>\n (CODEX_HOOK_EVENTS as readonly string[]).includes(e) ? e : undefined,\n unmappedWarnDetail: (e) => `${e} has no Codex hook equivalent — skipped`,\n renderEntry: (event, _matcher, command) => {\n const entry: CodexHookEntry = { hooks: [{ type: \"command\", command }] };\n // KEY ORDER: hooks THEN matcher. Matcher is EVENT-derived, not from the\n // connector's declared matcher: PermissionRequest matches tool names like\n // PreToolUse (charset-clean), everything else registers \"\" (all).\n entry.matcher =\n event === \"PreToolUse\" || event === \"PermissionRequest\" ? PRE_TOOL_USE_MATCHER : \"\";\n return entry;\n },\n // Idempotency find for the CANONICAL event the engine built `command` from —\n // path-normalized, exact-command, the body of isOurEntry's command check.\n entryOwnsCommand: (entry, command) =>\n Array.isArray(entry.hooks) &&\n entry.hooks.some(\n (h) => (h.command ?? \"\").replace(/\\\\/g, \"/\") === command.replace(/\\\\/g, \"/\"),\n ),\n // FLAT whole-entry removal, EVENT-SPECIFIC: isOurEntry rebuilds our command\n // from the event key being stripped, so a SubagentStop entry is never matched\n // while iterating the PreToolUse bucket.\n ownsEntryForRemove: (c, event) => (entry) =>\n this.isOurEntry(c, event as CodexHookEventName, entry),\n skipDetail: (e) => `hooks.${e}`,\n removeDetail: (e, _n) => `hooks.${e}`,\n absentDetail: \"no hooks.json\",\n noMatchDetail: \"no agent-connector hooks present\",\n // Uninstall scans EXACTLY codex's fixed event set (not Object.keys), so a\n // home-bin command hand-placed under a foreign event key is left untouched —\n // byte-identical to the prior `for (const event of CODEX_HOOK_EVENTS)` loop.\n removeEventKeys: CODEX_HOOK_EVENTS,\n };\n }\n\n // ── Health checks (default doctor renders these) ────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const path = this.getServerConfigPath(ctx);\n const id = ctx.connector.id;\n const checks: HealthCheck[] = [\n {\n name: `${this.name}: config.toml exists`,\n check: () =>\n existsSync(path)\n ? { status: \"OK\", detail: path }\n : { status: \"FAIL\", detail: `not found: ${path}` },\n },\n {\n name: `${this.name}: mcp_servers.${id} registered`,\n check: () => {\n // Only assert what the connector declares (same rule as the\n // content-surface checks below): a server-less connector — e.g. a\n // catalog-only bundle of agents/skills/commands — never writes an\n // [mcp_servers.<id>] table, so its absence is healthy.\n if (!ctx.connector.server) {\n return { status: \"OK\", detail: \"no MCP server declared\" };\n }\n const cfg = this.readToml(path);\n const bucket = cfg[\"mcp_servers\"];\n const present =\n typeof bucket === \"object\" &&\n bucket !== null &&\n id in (bucket as Record<string, unknown>);\n return present\n ? { status: \"OK\", detail: `mcp_servers.${id}` }\n : { status: \"FAIL\", detail: `mcp_servers.${id} not found in ${path}` };\n },\n },\n ];\n\n // Content-surface checks: assert presence only for surfaces this connector\n // declares. Codex commands are user-scope only, so a project-scope install\n // won't have written them — only check command files in user scope.\n if (ctx.scope !== \"project\") {\n for (const cmd of ctx.connector.commands) {\n const p = this.commandPath(cmd.name);\n checks.push({\n name: `${this.name}: command ${cmd.name} present`,\n check: () =>\n existsSync(p) ? { status: \"OK\", detail: p } : { status: \"FAIL\", detail: `not found: ${p}` },\n });\n }\n }\n for (const skill of ctx.connector.skills) {\n const p = join(this.skillDir(ctx, skill.name), \"SKILL.md\");\n checks.push({\n name: `${this.name}: skill ${skill.name} present`,\n check: () =>\n existsSync(p) ? { status: \"OK\", detail: p } : { status: \"FAIL\", detail: `not found: ${p}` },\n });\n }\n for (const agent of ctx.connector.subagents) {\n const p = this.subagentPath(ctx, agent.name);\n checks.push({\n name: `${this.name}: subagent ${agent.name} present`,\n check: () =>\n existsSync(p) ? { status: \"OK\", detail: p } : { status: \"FAIL\", detail: `not found: ${p}` },\n });\n }\n return checks;\n }\n\n // ── Content surfaces: commands / skills / subagents ──────────────────────\n // CONTENT-ONLY: pure native-file writers. No runtime dispatch, no home-bin\n // pointer, no telemetry wrap. Each method is idempotent (byte-identical →\n // skip) via writeContentFile and reversible via removeContentFile. Honors\n // platforms[\"codex\"] per-surface false to skip.\n //\n // Native locations:\n // command → ~/.codex/prompts/<name>.md md+frontmatter(description,argument-hint)\n // USER SCOPE ONLY — project scope yields a single \"warn\".\n // skill → project: <projectDir>/.codex/skills/<name>/SKILL.md (+ resources)\n // user: ~/.agents/skills/<name>/SKILL.md (~/.codex/skills is deprecated)\n // subagent → <codexDir>/agents/<name>.toml TOML via writeTomlString\n\n /** Command files always live under the USER codex dir: ~/.codex/prompts. */\n private commandPath(name: string): string {\n return join(this.userConfigDir(), \"prompts\", `${name}.md`);\n }\n private skillDir(ctx: InstallContext, name: string): string {\n // Project scope: <projectDir>/.codex/skills/<name> — the Project config-layer\n // skills root (codex-rs/core-skills/src/loader.rs, ConfigLayerSource::Project),\n // NOT deprecated. User scope: $HOME/.agents/skills/<name> — codex's CURRENT\n // user skills root. The older $CODEX_HOME/skills (~/.codex/skills) is still\n // read but the loader labels it a \"Deprecated user skills location, kept for\n // backward compatibility\". .agents is anchored to the OS home (home_dir), NOT\n // $CODEX_HOME — so use homedir() here, never userConfigDir() (which honors\n // CODEX_HOME).\n if (ctx.scope === \"project\") return join(this.getConfigDir(ctx), \"skills\", name);\n return join(homedir(), \".agents\", \"skills\", name);\n }\n private subagentPath(ctx: InstallContext, name: string): string {\n return join(this.getConfigDir(ctx), \"agents\", `${name}.toml`);\n }\n\n // ── Commands (USER SCOPE ONLY) ───────────────────────────────────────────\n\n override installCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[this.id]?.commands === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"commands disabled for codex\" }];\n }\n if (ctx.scope === \"project\") {\n return [{ platform: this.id, action: \"warn\", detail: \"codex commands are user-scope only\" }];\n }\n if (connector.commands.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no commands\" }];\n }\n return connector.commands.map((cmd) =>\n this.writeContentFile(this.commandPath(cmd.name), this.renderCommand(cmd), ctx.dryRun),\n );\n }\n\n override uninstallCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (ctx.scope === \"project\") {\n return [{ platform: this.id, action: \"warn\", detail: \"codex commands are user-scope only\" }];\n }\n if (connector.commands.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no commands\" }];\n }\n return connector.commands.map((cmd) =>\n this.removeContentFile(this.commandPath(cmd.name), ctx.dryRun),\n );\n }\n\n /** Render a command to md+frontmatter (description, argument-hint). */\n private renderCommand(cmd: CommandDef): string {\n const frontmatter: Record<string, unknown> = {};\n if (cmd.description !== undefined) frontmatter.description = cmd.description;\n if (cmd.argumentHint !== undefined) frontmatter[\"argument-hint\"] = cmd.argumentHint;\n if (cmd.extra) Object.assign(frontmatter, cmd.extra);\n return this.renderFrontmatterMd(frontmatter, cmd.prompt);\n }\n\n // ── Skills ───────────────────────────────────────────────────────────────\n\n override installSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[this.id]?.skills === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"skills disabled for codex\" }];\n }\n if (connector.skills.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\n }\n const changes: ChangeRecord[] = [];\n for (const skill of connector.skills) {\n const dir = this.skillDir(ctx, skill.name);\n const rendered = this.renderSkill(skill);\n changes.push(this.writeContentFile(join(dir, \"SKILL.md\"), rendered, ctx.dryRun));\n // Bundle any resource files beside SKILL.md (relative path → contents).\n // Defense-in-depth: skip+warn on any key that escapes the skill dir\n // (config-time validation already rejects these, but never trust input).\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) {\n changes.push({\n platform: this.id,\n action: \"warn\",\n detail: `skill resource \"${rel}\" escapes the skill dir; skipped`,\n });\n continue;\n }\n changes.push(this.writeContentFile(target, contents, ctx.dryRun));\n }\n // Migrate away an AC-owned copy at the deprecated user skills root so the\n // skill is not double-registered after the move to ~/.agents/skills.\n changes.push(...this.migrateDeprecatedUserSkill(ctx, skill, rendered));\n }\n return changes;\n }\n\n /**\n * One-time, opt-out-safe migration: prior AC versions wrote user-scope skills\n * to the now-deprecated $CODEX_HOME/skills/<name> root, which codex STILL reads\n * (kept for backward compatibility). Once we write the same skill to the current\n * ~/.agents/skills root, codex would register it TWICE (same frontmatter name,\n * two User-scope roots). If a SKILL.md exists at the deprecated path AND is\n * byte-identical to what we render — i.e. AC-owned, not hand-authored — remove\n * it (and its now-empty dir). The content-equality guard guarantees we never\n * delete a skill a user placed there by hand. No-op for project scope (where\n * .codex/skills is the valid, non-deprecated Project config-layer path) and when\n * a custom CODEX_HOME would make the deprecated path coincide with the new one.\n */\n private migrateDeprecatedUserSkill(\n ctx: InstallContext,\n skill: SkillDef,\n rendered: string,\n ): ChangeRecord[] {\n if (ctx.scope === \"project\") return [];\n const deprecated = join(this.userConfigDir(), \"skills\", skill.name, \"SKILL.md\");\n // Never touch the file we just wrote (pathological CODEX_HOME === ~/.agents).\n if (deprecated === join(this.skillDir(ctx, skill.name), \"SKILL.md\")) return [];\n if (!existsSync(deprecated)) return [];\n if (readFileSync(deprecated, \"utf8\") !== rendered) return []; // hand-authored — leave it\n return [\n this.removeContentFile(deprecated, ctx.dryRun),\n this.removeDirIfEmpty(dirname(deprecated), ctx.dryRun),\n ];\n }\n\n override uninstallSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.skills.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\n }\n const changes: ChangeRecord[] = [];\n for (const skill of connector.skills) {\n const dir = this.skillDir(ctx, skill.name);\n // Remove only the files we wrote (SKILL.md + declared resources), then the\n // skill dir itself when we own its full contents.\n changes.push(this.removeContentFile(join(dir, \"SKILL.md\"), ctx.dryRun));\n for (const rel of Object.keys(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) continue; // never delete outside the skill dir\n changes.push(this.removeContentFile(target, ctx.dryRun));\n }\n // Only remove the skill dir when WE own its full contents — never rm -rf a\n // dir that still holds user-added / sibling-tool / shared files.\n changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));\n }\n return changes;\n }\n\n /**\n * Render a skill's SKILL.md: frontmatter (name, description + optional model,\n * allowed-tools, disable-model-invocation) + body. UNIFORM with every other\n * skill-supporting platform — only the parent dir differs.\n */\n private renderSkill(skill: SkillDef): string {\n const frontmatter: Record<string, unknown> = {\n name: skill.name,\n description: skill.description,\n };\n if (skill.model !== undefined) frontmatter.model = skill.model;\n const allow = skill.tools?.allow;\n if (allow && allow.length > 0) frontmatter[\"allowed-tools\"] = allow.join(\", \");\n if (skill.disableModelInvocation !== undefined) {\n frontmatter[\"disable-model-invocation\"] = skill.disableModelInvocation;\n }\n if (skill.extra) Object.assign(frontmatter, skill.extra);\n return this.renderFrontmatterMd(frontmatter, skill.body);\n }\n\n // ── Subagents (TOML) ─────────────────────────────────────────────────────\n\n override installSubagents(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[this.id]?.subagents === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"subagents disabled for codex\" }];\n }\n if (connector.subagents.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no subagents\" }];\n }\n return connector.subagents.map((agent) =>\n this.writeContentFile(this.subagentPath(ctx, agent.name), this.renderSubagent(agent), ctx.dryRun),\n );\n }\n\n override uninstallSubagents(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.subagents.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no subagents\" }];\n }\n return connector.subagents.map((agent) =>\n this.removeContentFile(this.subagentPath(ctx, agent.name), ctx.dryRun),\n );\n }\n\n /**\n * Render a subagent to a Codex agent TOML file:\n * { name, description, developer_instructions: prompt, model }.\n * model is omitted when undefined so Codex applies its default.\n */\n private renderSubagent(agent: SubagentDef): string {\n const table: Record<string, unknown> = {\n name: agent.name,\n description: agent.description,\n developer_instructions: agent.prompt,\n };\n if (agent.model !== undefined) table.model = agent.model;\n if (agent.extra) Object.assign(table, agent.extra);\n return writeTomlString(table);\n }\n\n // ── Runtime dispatch ────────────────────────────────────────────────────\n\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\n const input = (raw ?? {}) as CodexHookInput;\n const base = {\n hostPlatform: this.id,\n connectorId: \"\",\n sessionId: input.session_id ?? `pid-${process.ppid}`,\n projectDir: input.cwd ?? process.env.CODEX_PROJECT_DIR ?? process.cwd(),\n raw,\n };\n\n switch (event) {\n case \"PreToolUse\":\n return {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n };\n case \"PostToolUse\":\n return {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n toolOutput: input.tool_response,\n isError: input.is_error ?? false,\n };\n case \"SessionStart\":\n return { ...base, source: this.normalizeSource(input.source) };\n case \"SessionEnd\":\n return { ...base, reason: input.message };\n case \"UserPromptSubmit\":\n return { ...base, prompt: input.prompt ?? \"\" };\n case \"PreCompact\":\n return { ...base, trigger: input.trigger === \"manual\" ? \"manual\" : \"auto\" };\n case \"PostCompact\":\n // Post-compaction sibling of PreCompact — same `trigger` normalization\n // (manual|auto), observe-only. Codex's PostCompact payload mirrors\n // PreCompact's; everything else rides on `raw`.\n return { ...base, trigger: input.trigger === \"manual\" ? \"manual\" : \"auto\" };\n case \"Stop\":\n return { ...base, stopHookActive: input.stop_hook_active ?? false };\n case \"Notification\":\n return { ...base, message: input.message ?? \"\" };\n case \"PermissionRequest\":\n // Codex documents tool_name/tool_input (+tool_input.description); it has\n // no permission_suggestions field, so the normalized optional stays unset.\n return {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n };\n case \"PostToolUseFailure\":\n // No Codex analog — never fired natively. Parsed defensively (Claude-\n // compatible wire) so a manual `hook codex PostToolUseFailure` invocation\n // still normalizes instead of throwing.\n return {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n error: input.error ?? \"\",\n };\n case \"SubagentStart\":\n return {\n ...base,\n ...(typeof input.agent_id === \"string\" ? { agentId: input.agent_id } : {}),\n ...(typeof input.agent_type === \"string\" ? { agentType: input.agent_type } : {}),\n };\n case \"SubagentStop\":\n // agent_id/agent_type stay optional — never depend on hosts populating\n // them on stop (the Claude-family SDK quirk).\n return {\n ...base,\n ...(typeof input.agent_id === \"string\" ? { agentId: input.agent_id } : {}),\n ...(typeof input.agent_type === \"string\" ? { agentType: input.agent_type } : {}),\n ...(typeof input.agent_transcript_path === \"string\"\n ? { agentTranscriptPath: input.agent_transcript_path }\n : {}),\n ...(typeof input.last_assistant_message === \"string\"\n ? { lastAssistantMessage: input.last_assistant_message }\n : {}),\n ...(typeof input.stop_hook_active === \"boolean\"\n ? { stopHookActive: input.stop_hook_active }\n : {}),\n };\n }\n }\n\n formatReply(event: HookEventName, response: HookResponse): HookReply {\n // Codex (like Claude Code) reads a `hookSpecificOutput` JSON wrapper from\n // stdout; exit code 0 = allow. Fields the host cannot honor are dropped.\n\n // PermissionRequest uses Codex's nested decision{behavior} envelope and is\n // the ONE event where an EXPLICIT \"allow\" is an ACTIVE grant (suppresses the\n // approval prompt). ask/context/void → NO decision output: fall through to\n // the normal approval flow (the prompt IS the ask). Codex docs: updatedInput\n // / updatedPermissions / interrupt FAIL CLOSED on this event, so \"modify\"\n // also falls through — emitting a bare allow would grant the ORIGINAL input\n // the handler wanted rewritten.\n if (event === \"PermissionRequest\") {\n if (response.decision === \"deny\") {\n return {\n exitCode: 0,\n stdout: JSON.stringify({\n hookSpecificOutput: {\n hookEventName: \"PermissionRequest\",\n decision: {\n behavior: \"deny\",\n message: response.reason ?? \"Blocked by hook\",\n },\n },\n }),\n };\n }\n if (response.decision === \"allow\") {\n return {\n exitCode: 0,\n stdout: JSON.stringify({\n hookSpecificOutput: {\n hookEventName: \"PermissionRequest\",\n decision: { behavior: \"allow\" },\n },\n }),\n };\n }\n return { exitCode: 0 };\n }\n\n // SubagentStart is observe/context-only on Codex (continue:false is parsed\n // but does not stop the subagent): \"context\" injects additionalContext as\n // developer context for the SUBAGENT, and a \"deny\" DEGRADES to the same\n // shape carrying the reason.\n if (event === \"SubagentStart\") {\n const context =\n response.decision === \"context\"\n ? response.additionalContext\n : response.decision === \"deny\"\n ? response.reason ?? response.additionalContext\n : undefined;\n if (context) {\n return {\n exitCode: 0,\n stdout: JSON.stringify({\n hookSpecificOutput: {\n hookEventName: \"SubagentStart\",\n additionalContext: context,\n },\n }),\n };\n }\n return { exitCode: 0 };\n }\n\n if (response.decision === \"deny\") {\n // PreToolUse deny is honored; other events fail-open to allow.\n if (event === \"PreToolUse\") {\n return {\n exitCode: 0,\n stdout: JSON.stringify({\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n permissionDecision: \"deny\",\n permissionDecisionReason: response.reason ?? \"Blocked by hook\",\n },\n }),\n };\n }\n // SubagentStop deny = Stop semantics: the documented continuation shape is\n // the TOP-LEVEL {\"decision\":\"block\",\"reason\"} (keeps the subagent going\n // with `reason` as its next instruction).\n if (event === \"SubagentStop\") {\n return {\n exitCode: 0,\n stdout: JSON.stringify({\n decision: \"block\",\n reason: response.reason ?? \"Blocked by hook\",\n }),\n };\n }\n return { exitCode: 0 };\n }\n\n // Context injection: honored on SessionStart and PostToolUse (additionalContext).\n // (SubagentStop accepts only the common output fields — no additionalContext.)\n if (response.additionalContext && (event === \"SessionStart\" || event === \"PostToolUse\")) {\n return {\n exitCode: 0,\n stdout: JSON.stringify({\n hookSpecificOutput: {\n hookEventName: event,\n additionalContext: response.additionalContext,\n },\n }),\n };\n }\n\n // \"allow\" / unsupported-on-Codex (modify, ask) → passthrough.\n return { exitCode: 0 };\n }\n\n // ── Internal helpers ────────────────────────────────────────────────────\n\n /** Resolve the per-platform server override into an effective ServerDef. */\n private effectiveServer(ctx: InstallContext): ServerDef | undefined {\n const override = ctx.connector.platforms[this.id]?.server;\n if (override === false) return undefined;\n const base = ctx.connector.server;\n if (!base) return undefined;\n return override ? { ...base, ...override } : base;\n }\n\n /** Which canonical hook events to register for Codex, honoring overrides. */\n private effectiveHookEvents(ctx: InstallContext): CodexHookEventName[] {\n const override = ctx.connector.platforms[this.id]?.hooks;\n if (override === false) return [];\n return CODEX_HOOK_EVENTS.filter((e) => ctx.connector.hookEvents.includes(e));\n }\n\n /** Declared events Codex has no analog for — install reports a warn-skip. */\n private warnSkipHookEvents(ctx: InstallContext): HookEventName[] {\n const override = ctx.connector.platforms[this.id]?.hooks;\n if (override === false) return [];\n return ctx.connector.hookEvents.filter((e) => WARN_SKIP_EVENTS.has(e));\n }\n\n /**\n * Render the `[mcp_servers.<id>]` table. TOML has NO interpolation, so every\n * `${env:VAR}` is resolved to a literal at install time. The env table is a\n * plain string→string map. Honors the telemetry serve-wrapper.\n */\n private renderMcpEntry(ctx: InstallContext, server: ServerDef): CodexMcpEntry {\n // Streamable HTTP server: codex infers the transport from `url` (no explicit\n // transport key). VERIFIED against codex-cli 0.139.0 — `codex mcp add <id>\n // --url <U> --bearer-token-env-var <E>` writes:\n // [mcp_servers.<id>]\n // url = \"…\"\n // bearer_token_env_var = \"…\" (only with bearerEnv auth)\n // Telemetry serve-wrapping is stdio-only (remote cannot be intercepted).\n // installServer's guard only lets stdio+command or http+url reach here, so\n // this branch is exactly the streamable-HTTP case (lock-step with the guard).\n if (server.transport === \"http\") {\n const remote: CodexMcpEntry = { url: resolveEnvRefsDeep(server.url ?? \"\") };\n if (server.auth?.type === \"bearerEnv\" && server.auth.bearerEnvVar) {\n remote.bearer_token_env_var = server.auth.bearerEnvVar;\n }\n if (server.headers && Object.keys(server.headers).length > 0) {\n const headers: Record<string, string> = {};\n for (const [k, v] of Object.entries(resolveEnvRefsDeep(server.headers))) {\n headers[k] = String(v);\n }\n remote.http_headers = headers;\n }\n return remote;\n }\n let command = server.command as string;\n let args = [...(server.args ?? [])];\n\n if (shouldWrapForTelemetry(server, ctx.connector.telemetry)) {\n const wrapped = buildServeWrapperCommand(ctx.homeBinPath, ctx.connector.id, command, args, ctx.scope, this.id);\n command = wrapped.command;\n args = wrapped.args;\n }\n\n // Resolve env-refs to literals (TOML cannot interpolate).\n command = resolveEnvRefsDeep(command);\n args = resolveEnvRefsDeep(args);\n\n const entry: CodexMcpEntry = { command };\n if (args.length > 0) entry.args = args;\n\n if (server.env && Object.keys(server.env).length > 0) {\n const env: Record<string, string> = {};\n for (const [k, v] of Object.entries(resolveEnvRefsDeep(server.env))) {\n env[k] = String(v);\n }\n entry.env = env;\n }\n return entry;\n }\n\n /**\n * Does this hooks.json entry belong to this connector for `event`? EVENT-\n * SPECIFIC + path-normalized exact-command match. The engine binds this per\n * event in the uninstall (whole-entry FLAT removal) and the install idempotency\n * find reuses its command body via the descriptor's entryOwnsCommand.\n */\n private isOurEntry(ctx: InstallContext, event: CodexHookEventName, entry: CodexHookEntry): boolean {\n if (!entry || typeof entry !== \"object\" || !Array.isArray(entry.hooks)) return false;\n const ours = buildHomeBinHookCommand(ctx.homeBinPath, \"codex\", event, ctx.connector.id);\n const needle = ours.replace(/\\\\/g, \"/\");\n return entry.hooks.some((h) => (h.command ?? \"\").replace(/\\\\/g, \"/\") === needle);\n }\n\n private normalizeSource(raw: string | undefined): \"startup\" | \"compact\" | \"resume\" | \"clear\" {\n switch (raw) {\n case \"compact\":\n return \"compact\";\n case \"resume\":\n return \"resume\";\n case \"clear\":\n return \"clear\";\n default:\n return \"startup\";\n }\n }\n}\n\nexport const adapter = new CodexAdapter();\nexport default adapter;\n"],"mappings":"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","names":[]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
readYaml,
|
|
4
4
|
writeYaml
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-NLFPH4S2.js";
|
|
6
6
|
import {
|
|
7
7
|
extractSessionId,
|
|
8
8
|
toolResponseToString
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from "./chunk-DBQMX75U.js";
|
|
13
13
|
import {
|
|
14
14
|
BaseAdapter
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-PFDUGDOA.js";
|
|
16
16
|
import "./chunk-7L6ITC4T.js";
|
|
17
17
|
import {
|
|
18
18
|
buildHomeBinHookCommand,
|
|
@@ -371,6 +371,8 @@ var ContinueAdapter = class extends BaseAdapter {
|
|
|
371
371
|
}
|
|
372
372
|
const hookPath = this.getHookConfigPath(ctx);
|
|
373
373
|
const file = this.readJson(hookPath) ?? {};
|
|
374
|
+
const __skip = this.malformedHookRootSkip(hookPath, file.hooks);
|
|
375
|
+
if (__skip) return [__skip];
|
|
374
376
|
const hooks = file.hooks ??= {};
|
|
375
377
|
const changes = [];
|
|
376
378
|
let mutated = false;
|
|
@@ -787,4 +789,4 @@ export {
|
|
|
787
789
|
adapter,
|
|
788
790
|
continue_default as default
|
|
789
791
|
};
|
|
790
|
-
//# sourceMappingURL=continue-
|
|
792
|
+
//# sourceMappingURL=continue-W4TU4JSB.js.map
|