@cleocode/adapters 2026.3.72 → 2026.3.73

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.
Files changed (96) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +1227 -101
  4. package/dist/index.js.map +4 -4
  5. package/dist/providers/claude-code/adapter.d.ts.map +1 -1
  6. package/dist/providers/claude-code/adapter.js +16 -5
  7. package/dist/providers/claude-code/adapter.js.map +1 -1
  8. package/dist/providers/claude-code/hooks.d.ts +89 -25
  9. package/dist/providers/claude-code/hooks.d.ts.map +1 -1
  10. package/dist/providers/claude-code/hooks.js +230 -28
  11. package/dist/providers/claude-code/hooks.js.map +1 -1
  12. package/dist/providers/codex/adapter.d.ts +70 -0
  13. package/dist/providers/codex/adapter.d.ts.map +1 -0
  14. package/dist/providers/codex/adapter.js +134 -0
  15. package/dist/providers/codex/adapter.js.map +1 -0
  16. package/dist/providers/codex/hooks.d.ts +85 -0
  17. package/dist/providers/codex/hooks.d.ts.map +1 -0
  18. package/dist/providers/codex/hooks.js +155 -0
  19. package/dist/providers/codex/hooks.js.map +1 -0
  20. package/dist/providers/codex/index.d.ts +22 -0
  21. package/dist/providers/codex/index.d.ts.map +1 -0
  22. package/dist/providers/codex/index.js +24 -0
  23. package/dist/providers/codex/index.js.map +1 -0
  24. package/dist/providers/codex/install.d.ts +74 -0
  25. package/dist/providers/codex/install.d.ts.map +1 -0
  26. package/dist/providers/codex/install.js +183 -0
  27. package/dist/providers/codex/install.js.map +1 -0
  28. package/dist/providers/cursor/adapter.d.ts.map +1 -1
  29. package/dist/providers/cursor/adapter.js +16 -2
  30. package/dist/providers/cursor/adapter.js.map +1 -1
  31. package/dist/providers/cursor/hooks.d.ts +102 -17
  32. package/dist/providers/cursor/hooks.d.ts.map +1 -1
  33. package/dist/providers/cursor/hooks.js +164 -18
  34. package/dist/providers/cursor/hooks.js.map +1 -1
  35. package/dist/providers/gemini-cli/adapter.d.ts +70 -0
  36. package/dist/providers/gemini-cli/adapter.d.ts.map +1 -0
  37. package/dist/providers/gemini-cli/adapter.js +145 -0
  38. package/dist/providers/gemini-cli/adapter.js.map +1 -0
  39. package/dist/providers/gemini-cli/hooks.d.ts +92 -0
  40. package/dist/providers/gemini-cli/hooks.d.ts.map +1 -0
  41. package/dist/providers/gemini-cli/hooks.js +169 -0
  42. package/dist/providers/gemini-cli/hooks.js.map +1 -0
  43. package/dist/providers/gemini-cli/index.d.ts +22 -0
  44. package/dist/providers/gemini-cli/index.d.ts.map +1 -0
  45. package/dist/providers/gemini-cli/index.js +24 -0
  46. package/dist/providers/gemini-cli/index.js.map +1 -0
  47. package/dist/providers/gemini-cli/install.d.ts +74 -0
  48. package/dist/providers/gemini-cli/install.d.ts.map +1 -0
  49. package/dist/providers/gemini-cli/install.js +183 -0
  50. package/dist/providers/gemini-cli/install.js.map +1 -0
  51. package/dist/providers/kimi/adapter.d.ts +72 -0
  52. package/dist/providers/kimi/adapter.d.ts.map +1 -0
  53. package/dist/providers/kimi/adapter.js +133 -0
  54. package/dist/providers/kimi/adapter.js.map +1 -0
  55. package/dist/providers/kimi/hooks.d.ts +64 -0
  56. package/dist/providers/kimi/hooks.d.ts.map +1 -0
  57. package/dist/providers/kimi/hooks.js +73 -0
  58. package/dist/providers/kimi/hooks.js.map +1 -0
  59. package/dist/providers/kimi/index.d.ts +22 -0
  60. package/dist/providers/kimi/index.d.ts.map +1 -0
  61. package/dist/providers/kimi/index.js +24 -0
  62. package/dist/providers/kimi/index.js.map +1 -0
  63. package/dist/providers/kimi/install.d.ts +80 -0
  64. package/dist/providers/kimi/install.d.ts.map +1 -0
  65. package/dist/providers/kimi/install.js +189 -0
  66. package/dist/providers/kimi/install.js.map +1 -0
  67. package/dist/providers/opencode/adapter.d.ts.map +1 -1
  68. package/dist/providers/opencode/adapter.js +13 -6
  69. package/dist/providers/opencode/adapter.js.map +1 -1
  70. package/dist/providers/opencode/hooks.d.ts +89 -28
  71. package/dist/providers/opencode/hooks.d.ts.map +1 -1
  72. package/dist/providers/opencode/hooks.js +145 -37
  73. package/dist/providers/opencode/hooks.js.map +1 -1
  74. package/package.json +3 -2
  75. package/src/index.ts +18 -0
  76. package/src/providers/claude-code/adapter.ts +16 -5
  77. package/src/providers/claude-code/hooks.ts +154 -30
  78. package/src/providers/codex/adapter.ts +154 -0
  79. package/src/providers/codex/hooks.ts +163 -0
  80. package/src/providers/codex/index.ts +27 -0
  81. package/src/providers/codex/install.ts +203 -0
  82. package/src/providers/codex/manifest.json +28 -0
  83. package/src/providers/cursor/adapter.ts +16 -2
  84. package/src/providers/cursor/hooks.ts +167 -18
  85. package/src/providers/gemini-cli/adapter.ts +165 -0
  86. package/src/providers/gemini-cli/hooks.ts +177 -0
  87. package/src/providers/gemini-cli/index.ts +27 -0
  88. package/src/providers/gemini-cli/install.ts +203 -0
  89. package/src/providers/gemini-cli/manifest.json +35 -0
  90. package/src/providers/kimi/adapter.ts +153 -0
  91. package/src/providers/kimi/hooks.ts +80 -0
  92. package/src/providers/kimi/index.ts +27 -0
  93. package/src/providers/kimi/install.ts +209 -0
  94. package/src/providers/kimi/manifest.json +24 -0
  95. package/src/providers/opencode/adapter.ts +13 -6
  96. package/src/providers/opencode/hooks.ts +146 -37
package/dist/index.js CHANGED
@@ -1099,14 +1099,14 @@ var init_hooks2 = __esm({
1099
1099
  });
1100
1100
 
1101
1101
  // packages/adapters/src/providers/cursor/install.js
1102
- import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
1103
- import { join as join7 } from "node:path";
1104
- var INSTRUCTION_REFERENCES2, MCP_SERVER_KEY2, CursorInstallProvider;
1102
+ import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
1103
+ import { join as join10 } from "node:path";
1104
+ var INSTRUCTION_REFERENCES3, MCP_SERVER_KEY3, CursorInstallProvider;
1105
1105
  var init_install2 = __esm({
1106
1106
  "packages/adapters/src/providers/cursor/install.js"() {
1107
1107
  "use strict";
1108
- INSTRUCTION_REFERENCES2 = ["@~/.cleo/templates/CLEO-INJECTION.md", "@.cleo/memory-bridge.md"];
1109
- MCP_SERVER_KEY2 = "cleo";
1108
+ INSTRUCTION_REFERENCES3 = ["@~/.cleo/templates/CLEO-INJECTION.md", "@.cleo/memory-bridge.md"];
1109
+ MCP_SERVER_KEY3 = "cleo";
1110
1110
  CursorInstallProvider = class {
1111
1111
  installedProjectDir = null;
1112
1112
  /**
@@ -1124,7 +1124,7 @@ var init_install2 = __esm({
1124
1124
  if (mcpServerPath) {
1125
1125
  mcpRegistered = this.registerMcpServer(projectDir, mcpServerPath);
1126
1126
  if (mcpRegistered) {
1127
- details.mcpConfigPath = join7(projectDir, ".cursor", "mcp.json");
1127
+ details.mcpConfigPath = join10(projectDir, ".cursor", "mcp.json");
1128
1128
  }
1129
1129
  }
1130
1130
  instructionFileUpdated = this.updateInstructionFiles(projectDir);
@@ -1149,15 +1149,15 @@ var init_install2 = __esm({
1149
1149
  async uninstall() {
1150
1150
  if (!this.installedProjectDir)
1151
1151
  return;
1152
- const mcpPath = join7(this.installedProjectDir, ".cursor", "mcp.json");
1153
- if (existsSync5(mcpPath)) {
1152
+ const mcpPath = join10(this.installedProjectDir, ".cursor", "mcp.json");
1153
+ if (existsSync7(mcpPath)) {
1154
1154
  try {
1155
- const raw = readFileSync4(mcpPath, "utf-8");
1155
+ const raw = readFileSync5(mcpPath, "utf-8");
1156
1156
  const config = JSON.parse(raw);
1157
1157
  const mcpServers = config.mcpServers;
1158
- if (mcpServers && MCP_SERVER_KEY2 in mcpServers) {
1159
- delete mcpServers[MCP_SERVER_KEY2];
1160
- writeFileSync3(mcpPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
1158
+ if (mcpServers && MCP_SERVER_KEY3 in mcpServers) {
1159
+ delete mcpServers[MCP_SERVER_KEY3];
1160
+ writeFileSync4(mcpPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
1161
1161
  }
1162
1162
  } catch {
1163
1163
  }
@@ -1170,12 +1170,12 @@ var init_install2 = __esm({
1170
1170
  * Checks for MCP server registered in .cursor/mcp.json.
1171
1171
  */
1172
1172
  async isInstalled() {
1173
- const mcpPath = join7(process.cwd(), ".cursor", "mcp.json");
1174
- if (existsSync5(mcpPath)) {
1173
+ const mcpPath = join10(process.cwd(), ".cursor", "mcp.json");
1174
+ if (existsSync7(mcpPath)) {
1175
1175
  try {
1176
- const config = JSON.parse(readFileSync4(mcpPath, "utf-8"));
1176
+ const config = JSON.parse(readFileSync5(mcpPath, "utf-8"));
1177
1177
  const mcpServers = config.mcpServers;
1178
- if (mcpServers && MCP_SERVER_KEY2 in mcpServers) {
1178
+ if (mcpServers && MCP_SERVER_KEY3 in mcpServers) {
1179
1179
  return true;
1180
1180
  }
1181
1181
  } catch {
@@ -1202,13 +1202,13 @@ var init_install2 = __esm({
1202
1202
  * @returns true if registration was performed or updated
1203
1203
  */
1204
1204
  registerMcpServer(projectDir, mcpServerPath) {
1205
- const cursorDir = join7(projectDir, ".cursor");
1206
- const mcpPath = join7(cursorDir, "mcp.json");
1205
+ const cursorDir = join10(projectDir, ".cursor");
1206
+ const mcpPath = join10(cursorDir, "mcp.json");
1207
1207
  let config = {};
1208
- mkdirSync2(cursorDir, { recursive: true });
1209
- if (existsSync5(mcpPath)) {
1208
+ mkdirSync3(cursorDir, { recursive: true });
1209
+ if (existsSync7(mcpPath)) {
1210
1210
  try {
1211
- config = JSON.parse(readFileSync4(mcpPath, "utf-8"));
1211
+ config = JSON.parse(readFileSync5(mcpPath, "utf-8"));
1212
1212
  } catch {
1213
1213
  }
1214
1214
  }
@@ -1216,11 +1216,11 @@ var init_install2 = __esm({
1216
1216
  config.mcpServers = {};
1217
1217
  }
1218
1218
  const mcpServers = config.mcpServers;
1219
- mcpServers[MCP_SERVER_KEY2] = {
1219
+ mcpServers[MCP_SERVER_KEY3] = {
1220
1220
  command: "node",
1221
1221
  args: [mcpServerPath]
1222
1222
  };
1223
- writeFileSync3(mcpPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
1223
+ writeFileSync4(mcpPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
1224
1224
  return true;
1225
1225
  }
1226
1226
  /**
@@ -1247,18 +1247,18 @@ var init_install2 = __esm({
1247
1247
  * @returns true if the file was modified
1248
1248
  */
1249
1249
  updateLegacyRules(projectDir) {
1250
- const rulesPath = join7(projectDir, ".cursorrules");
1251
- if (!existsSync5(rulesPath)) {
1250
+ const rulesPath = join10(projectDir, ".cursorrules");
1251
+ if (!existsSync7(rulesPath)) {
1252
1252
  return false;
1253
1253
  }
1254
- let content = readFileSync4(rulesPath, "utf-8");
1255
- const missingRefs = INSTRUCTION_REFERENCES2.filter((ref) => !content.includes(ref));
1254
+ let content = readFileSync5(rulesPath, "utf-8");
1255
+ const missingRefs = INSTRUCTION_REFERENCES3.filter((ref) => !content.includes(ref));
1256
1256
  if (missingRefs.length === 0) {
1257
1257
  return false;
1258
1258
  }
1259
1259
  const separator = content.endsWith("\n") ? "" : "\n";
1260
1260
  content = content + separator + missingRefs.join("\n") + "\n";
1261
- writeFileSync3(rulesPath, content, "utf-8");
1261
+ writeFileSync4(rulesPath, content, "utf-8");
1262
1262
  return true;
1263
1263
  }
1264
1264
  /**
@@ -1270,8 +1270,8 @@ var init_install2 = __esm({
1270
1270
  * @returns true if the file was created or modified
1271
1271
  */
1272
1272
  updateModernRules(projectDir) {
1273
- const rulesDir = join7(projectDir, ".cursor", "rules");
1274
- const mdcPath = join7(rulesDir, "cleo.mdc");
1273
+ const rulesDir = join10(projectDir, ".cursor", "rules");
1274
+ const mdcPath = join10(rulesDir, "cleo.mdc");
1275
1275
  const expectedContent = [
1276
1276
  "---",
1277
1277
  "description: CLEO task management protocol references",
@@ -1279,17 +1279,17 @@ var init_install2 = __esm({
1279
1279
  "alwaysApply: true",
1280
1280
  "---",
1281
1281
  "",
1282
- ...INSTRUCTION_REFERENCES2,
1282
+ ...INSTRUCTION_REFERENCES3,
1283
1283
  ""
1284
1284
  ].join("\n");
1285
- if (existsSync5(mdcPath)) {
1286
- const existing = readFileSync4(mdcPath, "utf-8");
1285
+ if (existsSync7(mdcPath)) {
1286
+ const existing = readFileSync5(mdcPath, "utf-8");
1287
1287
  if (existing === expectedContent) {
1288
1288
  return false;
1289
1289
  }
1290
1290
  }
1291
- mkdirSync2(rulesDir, { recursive: true });
1292
- writeFileSync3(mdcPath, expectedContent, "utf-8");
1291
+ mkdirSync3(rulesDir, { recursive: true });
1292
+ writeFileSync4(mdcPath, expectedContent, "utf-8");
1293
1293
  return true;
1294
1294
  }
1295
1295
  /**
@@ -1297,10 +1297,10 @@ var init_install2 = __esm({
1297
1297
  */
1298
1298
  getUpdatedFileList(projectDir) {
1299
1299
  const files = [];
1300
- if (existsSync5(join7(projectDir, ".cursorrules"))) {
1301
- files.push(join7(projectDir, ".cursorrules"));
1300
+ if (existsSync7(join10(projectDir, ".cursorrules"))) {
1301
+ files.push(join10(projectDir, ".cursorrules"));
1302
1302
  }
1303
- files.push(join7(projectDir, ".cursor", "rules", "cleo.mdc"));
1303
+ files.push(join10(projectDir, ".cursor", "rules", "cleo.mdc"));
1304
1304
  return files;
1305
1305
  }
1306
1306
  };
@@ -1308,8 +1308,8 @@ var init_install2 = __esm({
1308
1308
  });
1309
1309
 
1310
1310
  // packages/adapters/src/providers/cursor/adapter.js
1311
- import { existsSync as existsSync6 } from "node:fs";
1312
- import { join as join8 } from "node:path";
1311
+ import { existsSync as existsSync8 } from "node:fs";
1312
+ import { join as join11 } from "node:path";
1313
1313
  var CursorAdapter;
1314
1314
  var init_adapter2 = __esm({
1315
1315
  "packages/adapters/src/providers/cursor/adapter.js"() {
@@ -1382,14 +1382,14 @@ var init_adapter2 = __esm({
1382
1382
  }
1383
1383
  let configExists = false;
1384
1384
  if (this.projectDir) {
1385
- const cursorConfigDir = join8(this.projectDir, ".cursor");
1386
- configExists = existsSync6(cursorConfigDir);
1385
+ const cursorConfigDir = join11(this.projectDir, ".cursor");
1386
+ configExists = existsSync8(cursorConfigDir);
1387
1387
  details.configDirExists = configExists;
1388
1388
  }
1389
1389
  const editorEnvSet = process.env.CURSOR_EDITOR !== void 0;
1390
1390
  details.editorEnvSet = editorEnvSet;
1391
1391
  if (this.projectDir) {
1392
- const legacyRulesExist = existsSync6(join8(this.projectDir, ".cursorrules"));
1392
+ const legacyRulesExist = existsSync8(join11(this.projectDir, ".cursorrules"));
1393
1393
  details.legacyRulesExist = legacyRulesExist;
1394
1394
  }
1395
1395
  const healthy = configExists || editorEnvSet;
@@ -1422,10 +1422,10 @@ __export(cursor_exports, {
1422
1422
  CursorAdapter: () => CursorAdapter,
1423
1423
  CursorHookProvider: () => CursorHookProvider,
1424
1424
  CursorInstallProvider: () => CursorInstallProvider,
1425
- createAdapter: () => createAdapter2,
1425
+ createAdapter: () => createAdapter3,
1426
1426
  default: () => cursor_default
1427
1427
  });
1428
- function createAdapter2() {
1428
+ function createAdapter3() {
1429
1429
  return new CursorAdapter();
1430
1430
  }
1431
1431
  var cursor_default;
@@ -1504,14 +1504,14 @@ var init_hooks3 = __esm({
1504
1504
  });
1505
1505
 
1506
1506
  // packages/adapters/src/providers/opencode/install.js
1507
- import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
1508
- import { join as join9 } from "node:path";
1509
- var INSTRUCTION_REFERENCES3, MCP_SERVER_KEY3, OpenCodeInstallProvider;
1507
+ import { existsSync as existsSync13, mkdirSync as mkdirSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "node:fs";
1508
+ import { join as join17 } from "node:path";
1509
+ var INSTRUCTION_REFERENCES6, MCP_SERVER_KEY6, OpenCodeInstallProvider;
1510
1510
  var init_install3 = __esm({
1511
1511
  "packages/adapters/src/providers/opencode/install.js"() {
1512
1512
  "use strict";
1513
- INSTRUCTION_REFERENCES3 = ["@~/.cleo/templates/CLEO-INJECTION.md", "@.cleo/memory-bridge.md"];
1514
- MCP_SERVER_KEY3 = "cleo";
1513
+ INSTRUCTION_REFERENCES6 = ["@~/.cleo/templates/CLEO-INJECTION.md", "@.cleo/memory-bridge.md"];
1514
+ MCP_SERVER_KEY6 = "cleo";
1515
1515
  OpenCodeInstallProvider = class {
1516
1516
  installedProjectDir = null;
1517
1517
  /**
@@ -1529,12 +1529,12 @@ var init_install3 = __esm({
1529
1529
  if (mcpServerPath) {
1530
1530
  mcpRegistered = this.registerMcpServer(projectDir, mcpServerPath);
1531
1531
  if (mcpRegistered) {
1532
- details.mcpConfigPath = join9(projectDir, ".opencode", "config.json");
1532
+ details.mcpConfigPath = join17(projectDir, ".opencode", "config.json");
1533
1533
  }
1534
1534
  }
1535
1535
  instructionFileUpdated = this.updateInstructionFile(projectDir);
1536
1536
  if (instructionFileUpdated) {
1537
- details.instructionFile = join9(projectDir, "AGENTS.md");
1537
+ details.instructionFile = join17(projectDir, "AGENTS.md");
1538
1538
  }
1539
1539
  this.installedProjectDir = projectDir;
1540
1540
  return {
@@ -1554,15 +1554,15 @@ var init_install3 = __esm({
1554
1554
  async uninstall() {
1555
1555
  if (!this.installedProjectDir)
1556
1556
  return;
1557
- const configPath = join9(this.installedProjectDir, ".opencode", "config.json");
1558
- if (existsSync7(configPath)) {
1557
+ const configPath = join17(this.installedProjectDir, ".opencode", "config.json");
1558
+ if (existsSync13(configPath)) {
1559
1559
  try {
1560
- const raw = readFileSync5(configPath, "utf-8");
1560
+ const raw = readFileSync8(configPath, "utf-8");
1561
1561
  const config = JSON.parse(raw);
1562
1562
  const mcpServers = config.mcpServers;
1563
- if (mcpServers && MCP_SERVER_KEY3 in mcpServers) {
1564
- delete mcpServers[MCP_SERVER_KEY3];
1565
- writeFileSync4(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
1563
+ if (mcpServers && MCP_SERVER_KEY6 in mcpServers) {
1564
+ delete mcpServers[MCP_SERVER_KEY6];
1565
+ writeFileSync7(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
1566
1566
  }
1567
1567
  } catch {
1568
1568
  }
@@ -1576,12 +1576,12 @@ var init_install3 = __esm({
1576
1576
  * Returns true if the CLEO MCP server entry is found.
1577
1577
  */
1578
1578
  async isInstalled() {
1579
- const configPath = join9(process.cwd(), ".opencode", "config.json");
1580
- if (existsSync7(configPath)) {
1579
+ const configPath = join17(process.cwd(), ".opencode", "config.json");
1580
+ if (existsSync13(configPath)) {
1581
1581
  try {
1582
- const config = JSON.parse(readFileSync5(configPath, "utf-8"));
1582
+ const config = JSON.parse(readFileSync8(configPath, "utf-8"));
1583
1583
  const mcpServers = config.mcpServers;
1584
- if (mcpServers && MCP_SERVER_KEY3 in mcpServers) {
1584
+ if (mcpServers && MCP_SERVER_KEY6 in mcpServers) {
1585
1585
  return true;
1586
1586
  }
1587
1587
  } catch {
@@ -1608,13 +1608,13 @@ var init_install3 = __esm({
1608
1608
  * @returns true if registration was performed or updated
1609
1609
  */
1610
1610
  registerMcpServer(projectDir, mcpServerPath) {
1611
- const openCodeDir = join9(projectDir, ".opencode");
1612
- const configPath = join9(openCodeDir, "config.json");
1611
+ const openCodeDir = join17(projectDir, ".opencode");
1612
+ const configPath = join17(openCodeDir, "config.json");
1613
1613
  let config = {};
1614
- mkdirSync3(openCodeDir, { recursive: true });
1615
- if (existsSync7(configPath)) {
1614
+ mkdirSync6(openCodeDir, { recursive: true });
1615
+ if (existsSync13(configPath)) {
1616
1616
  try {
1617
- config = JSON.parse(readFileSync5(configPath, "utf-8"));
1617
+ config = JSON.parse(readFileSync8(configPath, "utf-8"));
1618
1618
  } catch {
1619
1619
  }
1620
1620
  }
@@ -1622,11 +1622,11 @@ var init_install3 = __esm({
1622
1622
  config.mcpServers = {};
1623
1623
  }
1624
1624
  const mcpServers = config.mcpServers;
1625
- mcpServers[MCP_SERVER_KEY3] = {
1625
+ mcpServers[MCP_SERVER_KEY6] = {
1626
1626
  command: "node",
1627
1627
  args: [mcpServerPath]
1628
1628
  };
1629
- writeFileSync4(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
1629
+ writeFileSync7(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
1630
1630
  return true;
1631
1631
  }
1632
1632
  /**
@@ -1635,14 +1635,14 @@ var init_install3 = __esm({
1635
1635
  * @returns true if the file was created or modified
1636
1636
  */
1637
1637
  updateInstructionFile(projectDir) {
1638
- const agentsMdPath = join9(projectDir, "AGENTS.md");
1638
+ const agentsMdPath = join17(projectDir, "AGENTS.md");
1639
1639
  let content = "";
1640
1640
  let existed = false;
1641
- if (existsSync7(agentsMdPath)) {
1642
- content = readFileSync5(agentsMdPath, "utf-8");
1641
+ if (existsSync13(agentsMdPath)) {
1642
+ content = readFileSync8(agentsMdPath, "utf-8");
1643
1643
  existed = true;
1644
1644
  }
1645
- const missingRefs = INSTRUCTION_REFERENCES3.filter((ref) => !content.includes(ref));
1645
+ const missingRefs = INSTRUCTION_REFERENCES6.filter((ref) => !content.includes(ref));
1646
1646
  if (missingRefs.length === 0) {
1647
1647
  return false;
1648
1648
  }
@@ -1653,7 +1653,7 @@ var init_install3 = __esm({
1653
1653
  } else {
1654
1654
  content = refsBlock + "\n";
1655
1655
  }
1656
- writeFileSync4(agentsMdPath, content, "utf-8");
1656
+ writeFileSync7(agentsMdPath, content, "utf-8");
1657
1657
  return true;
1658
1658
  }
1659
1659
  };
@@ -1661,10 +1661,10 @@ var init_install3 = __esm({
1661
1661
  });
1662
1662
 
1663
1663
  // packages/adapters/src/providers/opencode/spawn.js
1664
- import { exec as exec3, spawn as nodeSpawn2 } from "node:child_process";
1665
- import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
1666
- import { join as join10 } from "node:path";
1667
- import { promisify as promisify3 } from "node:util";
1664
+ import { exec as exec6, spawn as nodeSpawn2 } from "node:child_process";
1665
+ import { mkdir as mkdir2, readFile as readFile4, writeFile as writeFile2 } from "node:fs/promises";
1666
+ import { join as join18 } from "node:path";
1667
+ import { promisify as promisify6 } from "node:util";
1668
1668
  function buildOpenCodeAgentMarkdown(description, instructions) {
1669
1669
  const normalizedDesc = description.replace(/\s+/g, " ").trim();
1670
1670
  return [
@@ -1679,8 +1679,8 @@ function buildOpenCodeAgentMarkdown(description, instructions) {
1679
1679
  ].join("\n");
1680
1680
  }
1681
1681
  async function ensureSubagentDefinition(workingDirectory) {
1682
- const agentDir = join10(workingDirectory, ".opencode", "agent");
1683
- const agentPath = join10(agentDir, `${OPENCODE_SUBAGENT_NAME}.md`);
1682
+ const agentDir = join18(workingDirectory, ".opencode", "agent");
1683
+ const agentPath = join18(agentDir, `${OPENCODE_SUBAGENT_NAME}.md`);
1684
1684
  const description = "CLEO task executor with protocol compliance.";
1685
1685
  const instructions = [
1686
1686
  "# CLEO Subagent",
@@ -1694,7 +1694,7 @@ async function ensureSubagentDefinition(workingDirectory) {
1694
1694
  await mkdir2(agentDir, { recursive: true });
1695
1695
  let existing = null;
1696
1696
  try {
1697
- existing = await readFile2(agentPath, "utf-8");
1697
+ existing = await readFile4(agentPath, "utf-8");
1698
1698
  } catch {
1699
1699
  existing = null;
1700
1700
  }
@@ -1703,11 +1703,11 @@ async function ensureSubagentDefinition(workingDirectory) {
1703
1703
  }
1704
1704
  return OPENCODE_SUBAGENT_NAME;
1705
1705
  }
1706
- var execAsync3, OPENCODE_SUBAGENT_NAME, OPENCODE_FALLBACK_AGENT, OpenCodeSpawnProvider;
1706
+ var execAsync6, OPENCODE_SUBAGENT_NAME, OPENCODE_FALLBACK_AGENT, OpenCodeSpawnProvider;
1707
1707
  var init_spawn2 = __esm({
1708
1708
  "packages/adapters/src/providers/opencode/spawn.js"() {
1709
1709
  "use strict";
1710
- execAsync3 = promisify3(exec3);
1710
+ execAsync6 = promisify6(exec6);
1711
1711
  OPENCODE_SUBAGENT_NAME = "cleo-subagent";
1712
1712
  OPENCODE_FALLBACK_AGENT = "general";
1713
1713
  OpenCodeSpawnProvider = class {
@@ -1720,7 +1720,7 @@ var init_spawn2 = __esm({
1720
1720
  */
1721
1721
  async canSpawn() {
1722
1722
  try {
1723
- await execAsync3("which opencode");
1723
+ await execAsync6("which opencode");
1724
1724
  return true;
1725
1725
  } catch {
1726
1726
  return false;
@@ -1839,18 +1839,18 @@ var init_spawn2 = __esm({
1839
1839
  });
1840
1840
 
1841
1841
  // packages/adapters/src/providers/opencode/adapter.js
1842
- import { exec as exec4 } from "node:child_process";
1843
- import { existsSync as existsSync8 } from "node:fs";
1844
- import { join as join11 } from "node:path";
1845
- import { promisify as promisify4 } from "node:util";
1846
- var execAsync4, OpenCodeAdapter;
1842
+ import { exec as exec7 } from "node:child_process";
1843
+ import { existsSync as existsSync14 } from "node:fs";
1844
+ import { join as join19 } from "node:path";
1845
+ import { promisify as promisify7 } from "node:util";
1846
+ var execAsync7, OpenCodeAdapter;
1847
1847
  var init_adapter3 = __esm({
1848
1848
  "packages/adapters/src/providers/opencode/adapter.js"() {
1849
1849
  "use strict";
1850
1850
  init_hooks3();
1851
1851
  init_install3();
1852
1852
  init_spawn2();
1853
- execAsync4 = promisify4(exec4);
1853
+ execAsync7 = promisify7(exec7);
1854
1854
  OpenCodeAdapter = class {
1855
1855
  id = "opencode";
1856
1856
  name = "OpenCode";
@@ -1931,15 +1931,15 @@ var init_adapter3 = __esm({
1931
1931
  }
1932
1932
  let cliAvailable = false;
1933
1933
  try {
1934
- const { stdout } = await execAsync4("which opencode");
1934
+ const { stdout } = await execAsync7("which opencode");
1935
1935
  cliAvailable = stdout.trim().length > 0;
1936
1936
  details.cliPath = stdout.trim();
1937
1937
  } catch {
1938
1938
  details.cliAvailable = false;
1939
1939
  }
1940
1940
  if (this.projectDir) {
1941
- const openCodeConfigDir = join11(this.projectDir, ".opencode");
1942
- const configExists = existsSync8(openCodeConfigDir);
1941
+ const openCodeConfigDir = join19(this.projectDir, ".opencode");
1942
+ const configExists = existsSync14(openCodeConfigDir);
1943
1943
  details.configDirExists = configExists;
1944
1944
  }
1945
1945
  const versionEnvSet = process.env.OPENCODE_VERSION !== void 0;
@@ -1975,10 +1975,10 @@ __export(opencode_exports, {
1975
1975
  OpenCodeHookProvider: () => OpenCodeHookProvider,
1976
1976
  OpenCodeInstallProvider: () => OpenCodeInstallProvider,
1977
1977
  OpenCodeSpawnProvider: () => OpenCodeSpawnProvider,
1978
- createAdapter: () => createAdapter3,
1978
+ createAdapter: () => createAdapter6,
1979
1979
  default: () => opencode_default
1980
1980
  });
1981
- function createAdapter3() {
1981
+ function createAdapter6() {
1982
1982
  return new OpenCodeAdapter();
1983
1983
  }
1984
1984
  var opencode_default;
@@ -1996,12 +1996,1126 @@ var init_opencode = __esm({
1996
1996
 
1997
1997
  // packages/adapters/src/index.ts
1998
1998
  init_claude_code();
1999
+
2000
+ // packages/adapters/src/providers/codex/adapter.ts
2001
+ import { exec as exec3 } from "node:child_process";
2002
+ import { existsSync as existsSync6 } from "node:fs";
2003
+ import { homedir as homedir7 } from "node:os";
2004
+ import { join as join9 } from "node:path";
2005
+ import { promisify as promisify3 } from "node:util";
2006
+
2007
+ // packages/adapters/src/providers/codex/hooks.ts
2008
+ import { readdir, readFile as readFile2 } from "node:fs/promises";
2009
+ import { join as join7 } from "node:path";
2010
+ var CODEX_EVENT_MAP = {
2011
+ SessionStart: "SessionStart",
2012
+ PromptSubmit: "UserPromptSubmit",
2013
+ ResponseComplete: "Stop"
2014
+ };
2015
+ var CodexHookProvider = class {
2016
+ registered = false;
2017
+ /**
2018
+ * Map a Codex CLI native event name to a CAAMP hook event name.
2019
+ *
2020
+ * @param providerEvent - Codex CLI event name (e.g. "SessionStart", "PromptSubmit")
2021
+ * @returns CAAMP event name or null if unmapped
2022
+ * @task T162
2023
+ */
2024
+ mapProviderEvent(providerEvent) {
2025
+ return CODEX_EVENT_MAP[providerEvent] ?? null;
2026
+ }
2027
+ /**
2028
+ * Register native hooks for a project.
2029
+ *
2030
+ * For Codex CLI, hooks are registered via the config system
2031
+ * (~/.codex/), which is handled by the install provider.
2032
+ * This method marks hooks as registered without performing
2033
+ * filesystem operations.
2034
+ *
2035
+ * @param _projectDir - Project directory (unused; hooks are global)
2036
+ * @task T162
2037
+ */
2038
+ async registerNativeHooks(_projectDir) {
2039
+ this.registered = true;
2040
+ }
2041
+ /**
2042
+ * Unregister native hooks.
2043
+ *
2044
+ * For Codex CLI, this is a no-op since hooks are managed through
2045
+ * the config system. Unregistration happens via the install
2046
+ * provider's uninstall method.
2047
+ * @task T162
2048
+ */
2049
+ async unregisterNativeHooks() {
2050
+ this.registered = false;
2051
+ }
2052
+ /**
2053
+ * Check whether hooks have been registered via registerNativeHooks.
2054
+ * @task T162
2055
+ */
2056
+ isRegistered() {
2057
+ return this.registered;
2058
+ }
2059
+ /**
2060
+ * Get the full event mapping for introspection/debugging.
2061
+ * @task T162
2062
+ */
2063
+ getEventMap() {
2064
+ return { ...CODEX_EVENT_MAP };
2065
+ }
2066
+ /**
2067
+ * Extract a plain-text transcript from Codex CLI session data.
2068
+ *
2069
+ * Reads the most recent session file under ~/.codex/ and extracts
2070
+ * turn text into a flat string for brain observation extraction.
2071
+ *
2072
+ * Returns null when no session data is found or on any read error.
2073
+ *
2074
+ * @param _sessionId - CLEO session ID (unused; reads the most recent file)
2075
+ * @param _projectDir - Project directory (unused; Codex CLI uses global paths)
2076
+ * @task T162 @epic T134
2077
+ */
2078
+ async getTranscript(_sessionId, _projectDir) {
2079
+ try {
2080
+ const homeDir = process.env.HOME ?? process.env.USERPROFILE ?? "/root";
2081
+ const codexDir = join7(homeDir, ".codex");
2082
+ let allFiles = [];
2083
+ try {
2084
+ const entries = await readdir(codexDir, { withFileTypes: true });
2085
+ for (const entry of entries) {
2086
+ if (!entry.isFile()) continue;
2087
+ const name = entry.name;
2088
+ if (name.endsWith(".json") || name.endsWith(".jsonl")) {
2089
+ allFiles.push(join7(codexDir, name));
2090
+ }
2091
+ }
2092
+ } catch {
2093
+ return null;
2094
+ }
2095
+ if (allFiles.length === 0) return null;
2096
+ allFiles = allFiles.sort((a, b) => b.localeCompare(a));
2097
+ const mostRecent = allFiles[0];
2098
+ if (!mostRecent) return null;
2099
+ const raw = await readFile2(mostRecent, "utf-8");
2100
+ const turns = [];
2101
+ const lines = raw.split("\n").filter((l) => l.trim());
2102
+ for (const line of lines) {
2103
+ try {
2104
+ const entry = JSON.parse(line);
2105
+ const role = entry.role;
2106
+ const content = entry.content;
2107
+ if (role === "assistant" && typeof content === "string") {
2108
+ turns.push(`assistant: ${content}`);
2109
+ } else if (role === "user" && typeof content === "string") {
2110
+ turns.push(`user: ${content}`);
2111
+ }
2112
+ } catch {
2113
+ }
2114
+ }
2115
+ return turns.length > 0 ? turns.join("\n") : null;
2116
+ } catch {
2117
+ return null;
2118
+ }
2119
+ }
2120
+ };
2121
+
2122
+ // packages/adapters/src/providers/codex/install.ts
2123
+ import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
2124
+ import { homedir as homedir6 } from "node:os";
2125
+ import { join as join8 } from "node:path";
2126
+ var INSTRUCTION_REFERENCES2 = ["@~/.cleo/templates/CLEO-INJECTION.md", "@.cleo/memory-bridge.md"];
2127
+ var MCP_SERVER_KEY2 = "cleo";
2128
+ var CodexInstallProvider = class {
2129
+ /**
2130
+ * Install CLEO into a Codex CLI environment.
2131
+ *
2132
+ * @param options - Installation options including project directory and MCP server path
2133
+ * @returns Result describing what was installed
2134
+ * @task T162
2135
+ */
2136
+ async install(options) {
2137
+ const { projectDir, mcpServerPath } = options;
2138
+ const installedAt = (/* @__PURE__ */ new Date()).toISOString();
2139
+ let instructionFileUpdated = false;
2140
+ let mcpRegistered = false;
2141
+ const details = {};
2142
+ if (mcpServerPath) {
2143
+ mcpRegistered = this.registerMcpServer(mcpServerPath);
2144
+ if (mcpRegistered) {
2145
+ details.mcpConfigPath = join8(homedir6(), ".codex", "config.json");
2146
+ }
2147
+ }
2148
+ instructionFileUpdated = this.updateInstructionFile(projectDir);
2149
+ if (instructionFileUpdated) {
2150
+ details.instructionFile = join8(projectDir, "AGENTS.md");
2151
+ }
2152
+ return {
2153
+ success: true,
2154
+ installedAt,
2155
+ instructionFileUpdated,
2156
+ mcpRegistered,
2157
+ details
2158
+ };
2159
+ }
2160
+ /**
2161
+ * Uninstall CLEO from the Codex CLI environment.
2162
+ *
2163
+ * Removes the MCP server registration from ~/.codex/config.json.
2164
+ * Does not remove AGENTS.md references (they are harmless if CLEO is not present).
2165
+ * @task T162
2166
+ */
2167
+ async uninstall() {
2168
+ const configPath = join8(homedir6(), ".codex", "config.json");
2169
+ if (existsSync5(configPath)) {
2170
+ try {
2171
+ const raw = readFileSync4(configPath, "utf-8");
2172
+ const config = JSON.parse(raw);
2173
+ const mcpServers = config.mcpServers;
2174
+ if (mcpServers && MCP_SERVER_KEY2 in mcpServers) {
2175
+ delete mcpServers[MCP_SERVER_KEY2];
2176
+ writeFileSync3(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
2177
+ }
2178
+ } catch {
2179
+ }
2180
+ }
2181
+ }
2182
+ /**
2183
+ * Check whether CLEO is installed in the Codex CLI environment.
2184
+ *
2185
+ * Checks for MCP server registered in ~/.codex/config.json.
2186
+ * Returns true if the CLEO MCP server entry is found.
2187
+ * @task T162
2188
+ */
2189
+ async isInstalled() {
2190
+ const configPath = join8(homedir6(), ".codex", "config.json");
2191
+ if (existsSync5(configPath)) {
2192
+ try {
2193
+ const config = JSON.parse(readFileSync4(configPath, "utf-8"));
2194
+ const mcpServers = config.mcpServers;
2195
+ if (mcpServers && MCP_SERVER_KEY2 in mcpServers) {
2196
+ return true;
2197
+ }
2198
+ } catch {
2199
+ }
2200
+ }
2201
+ return false;
2202
+ }
2203
+ /**
2204
+ * Ensure AGENTS.md contains @-references to CLEO instruction files.
2205
+ *
2206
+ * Creates AGENTS.md if it does not exist. Appends any missing references.
2207
+ *
2208
+ * @param projectDir - Project root directory
2209
+ * @task T162
2210
+ */
2211
+ async ensureInstructionReferences(projectDir) {
2212
+ this.updateInstructionFile(projectDir);
2213
+ }
2214
+ /**
2215
+ * Register the CLEO MCP server in ~/.codex/config.json.
2216
+ *
2217
+ * Codex CLI stores its MCP server configuration in ~/.codex/config.json
2218
+ * under the mcpServers key.
2219
+ *
2220
+ * @param mcpServerPath - Absolute path to the MCP server entry point
2221
+ * @returns true if registration was performed or updated
2222
+ */
2223
+ registerMcpServer(mcpServerPath) {
2224
+ const codexDir = join8(homedir6(), ".codex");
2225
+ const configPath = join8(codexDir, "config.json");
2226
+ let config = {};
2227
+ mkdirSync2(codexDir, { recursive: true });
2228
+ if (existsSync5(configPath)) {
2229
+ try {
2230
+ config = JSON.parse(readFileSync4(configPath, "utf-8"));
2231
+ } catch {
2232
+ }
2233
+ }
2234
+ if (!config.mcpServers || typeof config.mcpServers !== "object") {
2235
+ config.mcpServers = {};
2236
+ }
2237
+ const mcpServers = config.mcpServers;
2238
+ mcpServers[MCP_SERVER_KEY2] = {
2239
+ command: "node",
2240
+ args: [mcpServerPath]
2241
+ };
2242
+ writeFileSync3(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
2243
+ return true;
2244
+ }
2245
+ /**
2246
+ * Update AGENTS.md with CLEO @-references.
2247
+ *
2248
+ * @param projectDir - Project root directory
2249
+ * @returns true if the file was created or modified
2250
+ */
2251
+ updateInstructionFile(projectDir) {
2252
+ const agentsMdPath = join8(projectDir, "AGENTS.md");
2253
+ let content = "";
2254
+ let existed = false;
2255
+ if (existsSync5(agentsMdPath)) {
2256
+ content = readFileSync4(agentsMdPath, "utf-8");
2257
+ existed = true;
2258
+ }
2259
+ const missingRefs = INSTRUCTION_REFERENCES2.filter((ref) => !content.includes(ref));
2260
+ if (missingRefs.length === 0) {
2261
+ return false;
2262
+ }
2263
+ const refsBlock = missingRefs.join("\n");
2264
+ if (existed) {
2265
+ const separator = content.endsWith("\n") ? "" : "\n";
2266
+ content = content + separator + refsBlock + "\n";
2267
+ } else {
2268
+ content = refsBlock + "\n";
2269
+ }
2270
+ writeFileSync3(agentsMdPath, content, "utf-8");
2271
+ return true;
2272
+ }
2273
+ };
2274
+
2275
+ // packages/adapters/src/providers/codex/adapter.ts
2276
+ var execAsync3 = promisify3(exec3);
2277
+ var CodexAdapter = class {
2278
+ id = "codex";
2279
+ name = "Codex";
2280
+ version = "1.0.0";
2281
+ capabilities = {
2282
+ supportsHooks: true,
2283
+ supportedHookEvents: ["SessionStart", "UserPromptSubmit", "Stop"],
2284
+ supportsSpawn: false,
2285
+ supportsInstall: true,
2286
+ supportsMcp: true,
2287
+ supportsInstructionFiles: false,
2288
+ supportsContextMonitor: false,
2289
+ supportsStatusline: false,
2290
+ supportsProviderPaths: false,
2291
+ supportsTransport: false,
2292
+ supportsTaskSync: false
2293
+ };
2294
+ hooks;
2295
+ install;
2296
+ projectDir = null;
2297
+ initialized = false;
2298
+ constructor() {
2299
+ this.hooks = new CodexHookProvider();
2300
+ this.install = new CodexInstallProvider();
2301
+ }
2302
+ /**
2303
+ * Initialize the adapter for a given project directory.
2304
+ *
2305
+ * @param projectDir - Root directory of the project
2306
+ * @task T162
2307
+ */
2308
+ async initialize(projectDir) {
2309
+ this.projectDir = projectDir;
2310
+ this.initialized = true;
2311
+ }
2312
+ /**
2313
+ * Dispose the adapter and clean up resources.
2314
+ *
2315
+ * Unregisters hooks and releases any tracked state.
2316
+ * @task T162
2317
+ */
2318
+ async dispose() {
2319
+ if (this.hooks.isRegistered()) {
2320
+ await this.hooks.unregisterNativeHooks();
2321
+ }
2322
+ this.initialized = false;
2323
+ this.projectDir = null;
2324
+ }
2325
+ /**
2326
+ * Run a health check to verify Codex CLI is accessible.
2327
+ *
2328
+ * Checks:
2329
+ * 1. Adapter has been initialized
2330
+ * 2. Codex CLI binary is available in PATH
2331
+ * 3. ~/.codex/ configuration directory exists
2332
+ *
2333
+ * @returns Health status with details about each check
2334
+ * @task T162
2335
+ */
2336
+ async healthCheck() {
2337
+ const details = {};
2338
+ if (!this.initialized) {
2339
+ return {
2340
+ healthy: false,
2341
+ provider: this.id,
2342
+ details: { error: "Adapter not initialized" }
2343
+ };
2344
+ }
2345
+ let cliAvailable = false;
2346
+ try {
2347
+ const { stdout } = await execAsync3("which codex");
2348
+ cliAvailable = stdout.trim().length > 0;
2349
+ details.cliPath = stdout.trim();
2350
+ } catch {
2351
+ details.cliAvailable = false;
2352
+ }
2353
+ const codexConfigDir = join9(homedir7(), ".codex");
2354
+ const configExists = existsSync6(codexConfigDir);
2355
+ details.configDirExists = configExists;
2356
+ const healthy = cliAvailable;
2357
+ details.cliAvailable = cliAvailable;
2358
+ return {
2359
+ healthy,
2360
+ provider: this.id,
2361
+ details
2362
+ };
2363
+ }
2364
+ /**
2365
+ * Check whether the adapter has been initialized.
2366
+ * @task T162
2367
+ */
2368
+ isInitialized() {
2369
+ return this.initialized;
2370
+ }
2371
+ /**
2372
+ * Get the project directory this adapter was initialized with.
2373
+ * @task T162
2374
+ */
2375
+ getProjectDir() {
2376
+ return this.projectDir;
2377
+ }
2378
+ };
2379
+
2380
+ // packages/adapters/src/providers/codex/index.ts
2381
+ function createAdapter2() {
2382
+ return new CodexAdapter();
2383
+ }
2384
+
2385
+ // packages/adapters/src/index.ts
1999
2386
  init_cursor();
2387
+
2388
+ // packages/adapters/src/providers/gemini-cli/adapter.ts
2389
+ import { exec as exec4 } from "node:child_process";
2390
+ import { existsSync as existsSync10 } from "node:fs";
2391
+ import { homedir as homedir9 } from "node:os";
2392
+ import { join as join14 } from "node:path";
2393
+ import { promisify as promisify4 } from "node:util";
2394
+
2395
+ // packages/adapters/src/providers/gemini-cli/hooks.ts
2396
+ import { readdir as readdir2, readFile as readFile3 } from "node:fs/promises";
2397
+ import { join as join12 } from "node:path";
2398
+ var GEMINI_CLI_EVENT_MAP = {
2399
+ SessionStart: "SessionStart",
2400
+ SessionEnd: "SessionEnd",
2401
+ PromptSubmit: "BeforeAgent",
2402
+ ResponseComplete: "AfterAgent",
2403
+ PreToolUse: "BeforeTool",
2404
+ PostToolUse: "AfterTool",
2405
+ PreModel: "BeforeModel",
2406
+ PostModel: "AfterModel",
2407
+ PreCompact: "PreCompress",
2408
+ Notification: "Notification"
2409
+ };
2410
+ var GeminiCliHookProvider = class {
2411
+ registered = false;
2412
+ /**
2413
+ * Map a Gemini CLI native event name to a CAAMP hook event name.
2414
+ *
2415
+ * @param providerEvent - Gemini CLI event name (e.g. "SessionStart", "PreToolUse")
2416
+ * @returns CAAMP event name or null if unmapped
2417
+ * @task T161
2418
+ */
2419
+ mapProviderEvent(providerEvent) {
2420
+ return GEMINI_CLI_EVENT_MAP[providerEvent] ?? null;
2421
+ }
2422
+ /**
2423
+ * Register native hooks for a project.
2424
+ *
2425
+ * For Gemini CLI, hooks are registered via the config system
2426
+ * (~/.gemini/), which is handled by the install provider.
2427
+ * This method marks hooks as registered without performing
2428
+ * filesystem operations.
2429
+ *
2430
+ * @param _projectDir - Project directory (unused; hooks are global)
2431
+ * @task T161
2432
+ */
2433
+ async registerNativeHooks(_projectDir) {
2434
+ this.registered = true;
2435
+ }
2436
+ /**
2437
+ * Unregister native hooks.
2438
+ *
2439
+ * For Gemini CLI, this is a no-op since hooks are managed through
2440
+ * the config system. Unregistration happens via the install
2441
+ * provider's uninstall method.
2442
+ * @task T161
2443
+ */
2444
+ async unregisterNativeHooks() {
2445
+ this.registered = false;
2446
+ }
2447
+ /**
2448
+ * Check whether hooks have been registered via registerNativeHooks.
2449
+ * @task T161
2450
+ */
2451
+ isRegistered() {
2452
+ return this.registered;
2453
+ }
2454
+ /**
2455
+ * Get the full event mapping for introspection/debugging.
2456
+ * @task T161
2457
+ */
2458
+ getEventMap() {
2459
+ return { ...GEMINI_CLI_EVENT_MAP };
2460
+ }
2461
+ /**
2462
+ * Extract a plain-text transcript from Gemini CLI session data.
2463
+ *
2464
+ * Reads the most recent session file under ~/.gemini/ and extracts
2465
+ * turn text into a flat string for brain observation extraction.
2466
+ *
2467
+ * Returns null when no session data is found or on any read error.
2468
+ *
2469
+ * @param _sessionId - CLEO session ID (unused; reads the most recent file)
2470
+ * @param _projectDir - Project directory (unused; Gemini CLI uses global paths)
2471
+ * @task T161 @epic T134
2472
+ */
2473
+ async getTranscript(_sessionId, _projectDir) {
2474
+ try {
2475
+ const homeDir = process.env.HOME ?? process.env.USERPROFILE ?? "/root";
2476
+ const geminiDir = join12(homeDir, ".gemini");
2477
+ let allFiles = [];
2478
+ try {
2479
+ const entries = await readdir2(geminiDir, { withFileTypes: true });
2480
+ for (const entry of entries) {
2481
+ if (!entry.isFile()) continue;
2482
+ const name = entry.name;
2483
+ if (name.endsWith(".json") || name.endsWith(".jsonl")) {
2484
+ allFiles.push(join12(geminiDir, name));
2485
+ }
2486
+ }
2487
+ } catch {
2488
+ return null;
2489
+ }
2490
+ if (allFiles.length === 0) return null;
2491
+ allFiles = allFiles.sort((a, b) => b.localeCompare(a));
2492
+ const mostRecent = allFiles[0];
2493
+ if (!mostRecent) return null;
2494
+ const raw = await readFile3(mostRecent, "utf-8");
2495
+ const turns = [];
2496
+ const lines = raw.split("\n").filter((l) => l.trim());
2497
+ for (const line of lines) {
2498
+ try {
2499
+ const entry = JSON.parse(line);
2500
+ const role = entry.role;
2501
+ const content = entry.content;
2502
+ if (role === "assistant" && typeof content === "string") {
2503
+ turns.push(`assistant: ${content}`);
2504
+ } else if (role === "user" && typeof content === "string") {
2505
+ turns.push(`user: ${content}`);
2506
+ }
2507
+ } catch {
2508
+ }
2509
+ }
2510
+ return turns.length > 0 ? turns.join("\n") : null;
2511
+ } catch {
2512
+ return null;
2513
+ }
2514
+ }
2515
+ };
2516
+
2517
+ // packages/adapters/src/providers/gemini-cli/install.ts
2518
+ import { existsSync as existsSync9, mkdirSync as mkdirSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "node:fs";
2519
+ import { homedir as homedir8 } from "node:os";
2520
+ import { join as join13 } from "node:path";
2521
+ var INSTRUCTION_REFERENCES4 = ["@~/.cleo/templates/CLEO-INJECTION.md", "@.cleo/memory-bridge.md"];
2522
+ var MCP_SERVER_KEY4 = "cleo";
2523
+ var GeminiCliInstallProvider = class {
2524
+ /**
2525
+ * Install CLEO into a Gemini CLI environment.
2526
+ *
2527
+ * @param options - Installation options including project directory and MCP server path
2528
+ * @returns Result describing what was installed
2529
+ * @task T161
2530
+ */
2531
+ async install(options) {
2532
+ const { projectDir, mcpServerPath } = options;
2533
+ const installedAt = (/* @__PURE__ */ new Date()).toISOString();
2534
+ let instructionFileUpdated = false;
2535
+ let mcpRegistered = false;
2536
+ const details = {};
2537
+ if (mcpServerPath) {
2538
+ mcpRegistered = this.registerMcpServer(mcpServerPath);
2539
+ if (mcpRegistered) {
2540
+ details.mcpConfigPath = join13(homedir8(), ".gemini", "settings.json");
2541
+ }
2542
+ }
2543
+ instructionFileUpdated = this.updateInstructionFile(projectDir);
2544
+ if (instructionFileUpdated) {
2545
+ details.instructionFile = join13(projectDir, "AGENTS.md");
2546
+ }
2547
+ return {
2548
+ success: true,
2549
+ installedAt,
2550
+ instructionFileUpdated,
2551
+ mcpRegistered,
2552
+ details
2553
+ };
2554
+ }
2555
+ /**
2556
+ * Uninstall CLEO from the Gemini CLI environment.
2557
+ *
2558
+ * Removes the MCP server registration from ~/.gemini/settings.json.
2559
+ * Does not remove AGENTS.md references (they are harmless if CLEO is not present).
2560
+ * @task T161
2561
+ */
2562
+ async uninstall() {
2563
+ const settingsPath = join13(homedir8(), ".gemini", "settings.json");
2564
+ if (existsSync9(settingsPath)) {
2565
+ try {
2566
+ const raw = readFileSync6(settingsPath, "utf-8");
2567
+ const config = JSON.parse(raw);
2568
+ const mcpServers = config.mcpServers;
2569
+ if (mcpServers && MCP_SERVER_KEY4 in mcpServers) {
2570
+ delete mcpServers[MCP_SERVER_KEY4];
2571
+ writeFileSync5(settingsPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
2572
+ }
2573
+ } catch {
2574
+ }
2575
+ }
2576
+ }
2577
+ /**
2578
+ * Check whether CLEO is installed in the Gemini CLI environment.
2579
+ *
2580
+ * Checks for MCP server registered in ~/.gemini/settings.json.
2581
+ * Returns true if the CLEO MCP server entry is found.
2582
+ * @task T161
2583
+ */
2584
+ async isInstalled() {
2585
+ const settingsPath = join13(homedir8(), ".gemini", "settings.json");
2586
+ if (existsSync9(settingsPath)) {
2587
+ try {
2588
+ const config = JSON.parse(readFileSync6(settingsPath, "utf-8"));
2589
+ const mcpServers = config.mcpServers;
2590
+ if (mcpServers && MCP_SERVER_KEY4 in mcpServers) {
2591
+ return true;
2592
+ }
2593
+ } catch {
2594
+ }
2595
+ }
2596
+ return false;
2597
+ }
2598
+ /**
2599
+ * Ensure AGENTS.md contains @-references to CLEO instruction files.
2600
+ *
2601
+ * Creates AGENTS.md if it does not exist. Appends any missing references.
2602
+ *
2603
+ * @param projectDir - Project root directory
2604
+ * @task T161
2605
+ */
2606
+ async ensureInstructionReferences(projectDir) {
2607
+ this.updateInstructionFile(projectDir);
2608
+ }
2609
+ /**
2610
+ * Register the CLEO MCP server in ~/.gemini/settings.json.
2611
+ *
2612
+ * Gemini CLI stores its MCP server configuration in ~/.gemini/settings.json
2613
+ * under the mcpServers key.
2614
+ *
2615
+ * @param mcpServerPath - Absolute path to the MCP server entry point
2616
+ * @returns true if registration was performed or updated
2617
+ */
2618
+ registerMcpServer(mcpServerPath) {
2619
+ const geminiDir = join13(homedir8(), ".gemini");
2620
+ const settingsPath = join13(geminiDir, "settings.json");
2621
+ let config = {};
2622
+ mkdirSync4(geminiDir, { recursive: true });
2623
+ if (existsSync9(settingsPath)) {
2624
+ try {
2625
+ config = JSON.parse(readFileSync6(settingsPath, "utf-8"));
2626
+ } catch {
2627
+ }
2628
+ }
2629
+ if (!config.mcpServers || typeof config.mcpServers !== "object") {
2630
+ config.mcpServers = {};
2631
+ }
2632
+ const mcpServers = config.mcpServers;
2633
+ mcpServers[MCP_SERVER_KEY4] = {
2634
+ command: "node",
2635
+ args: [mcpServerPath]
2636
+ };
2637
+ writeFileSync5(settingsPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
2638
+ return true;
2639
+ }
2640
+ /**
2641
+ * Update AGENTS.md with CLEO @-references.
2642
+ *
2643
+ * @param projectDir - Project root directory
2644
+ * @returns true if the file was created or modified
2645
+ */
2646
+ updateInstructionFile(projectDir) {
2647
+ const agentsMdPath = join13(projectDir, "AGENTS.md");
2648
+ let content = "";
2649
+ let existed = false;
2650
+ if (existsSync9(agentsMdPath)) {
2651
+ content = readFileSync6(agentsMdPath, "utf-8");
2652
+ existed = true;
2653
+ }
2654
+ const missingRefs = INSTRUCTION_REFERENCES4.filter((ref) => !content.includes(ref));
2655
+ if (missingRefs.length === 0) {
2656
+ return false;
2657
+ }
2658
+ const refsBlock = missingRefs.join("\n");
2659
+ if (existed) {
2660
+ const separator = content.endsWith("\n") ? "" : "\n";
2661
+ content = content + separator + refsBlock + "\n";
2662
+ } else {
2663
+ content = refsBlock + "\n";
2664
+ }
2665
+ writeFileSync5(agentsMdPath, content, "utf-8");
2666
+ return true;
2667
+ }
2668
+ };
2669
+
2670
+ // packages/adapters/src/providers/gemini-cli/adapter.ts
2671
+ var execAsync4 = promisify4(exec4);
2672
+ var GeminiCliAdapter = class {
2673
+ id = "gemini-cli";
2674
+ name = "Gemini CLI";
2675
+ version = "1.0.0";
2676
+ capabilities = {
2677
+ supportsHooks: true,
2678
+ supportedHookEvents: [
2679
+ "SessionStart",
2680
+ "SessionEnd",
2681
+ "BeforeAgent",
2682
+ "AfterAgent",
2683
+ "BeforeTool",
2684
+ "AfterTool",
2685
+ "BeforeModel",
2686
+ "AfterModel",
2687
+ "PreCompress",
2688
+ "Notification"
2689
+ ],
2690
+ supportsSpawn: false,
2691
+ supportsInstall: true,
2692
+ supportsMcp: true,
2693
+ supportsInstructionFiles: false,
2694
+ supportsContextMonitor: false,
2695
+ supportsStatusline: false,
2696
+ supportsProviderPaths: false,
2697
+ supportsTransport: false,
2698
+ supportsTaskSync: false
2699
+ };
2700
+ hooks;
2701
+ install;
2702
+ projectDir = null;
2703
+ initialized = false;
2704
+ constructor() {
2705
+ this.hooks = new GeminiCliHookProvider();
2706
+ this.install = new GeminiCliInstallProvider();
2707
+ }
2708
+ /**
2709
+ * Initialize the adapter for a given project directory.
2710
+ *
2711
+ * @param projectDir - Root directory of the project
2712
+ * @task T161
2713
+ */
2714
+ async initialize(projectDir) {
2715
+ this.projectDir = projectDir;
2716
+ this.initialized = true;
2717
+ }
2718
+ /**
2719
+ * Dispose the adapter and clean up resources.
2720
+ *
2721
+ * Unregisters hooks and releases any tracked state.
2722
+ * @task T161
2723
+ */
2724
+ async dispose() {
2725
+ if (this.hooks.isRegistered()) {
2726
+ await this.hooks.unregisterNativeHooks();
2727
+ }
2728
+ this.initialized = false;
2729
+ this.projectDir = null;
2730
+ }
2731
+ /**
2732
+ * Run a health check to verify Gemini CLI is accessible.
2733
+ *
2734
+ * Checks:
2735
+ * 1. Adapter has been initialized
2736
+ * 2. Gemini CLI binary is available in PATH
2737
+ * 3. ~/.gemini/ configuration directory exists
2738
+ *
2739
+ * @returns Health status with details about each check
2740
+ * @task T161
2741
+ */
2742
+ async healthCheck() {
2743
+ const details = {};
2744
+ if (!this.initialized) {
2745
+ return {
2746
+ healthy: false,
2747
+ provider: this.id,
2748
+ details: { error: "Adapter not initialized" }
2749
+ };
2750
+ }
2751
+ let cliAvailable = false;
2752
+ try {
2753
+ const { stdout } = await execAsync4("which gemini");
2754
+ cliAvailable = stdout.trim().length > 0;
2755
+ details.cliPath = stdout.trim();
2756
+ } catch {
2757
+ details.cliAvailable = false;
2758
+ }
2759
+ const geminiConfigDir = join14(homedir9(), ".gemini");
2760
+ const configExists = existsSync10(geminiConfigDir);
2761
+ details.configDirExists = configExists;
2762
+ const healthy = cliAvailable;
2763
+ details.cliAvailable = cliAvailable;
2764
+ return {
2765
+ healthy,
2766
+ provider: this.id,
2767
+ details
2768
+ };
2769
+ }
2770
+ /**
2771
+ * Check whether the adapter has been initialized.
2772
+ * @task T161
2773
+ */
2774
+ isInitialized() {
2775
+ return this.initialized;
2776
+ }
2777
+ /**
2778
+ * Get the project directory this adapter was initialized with.
2779
+ * @task T161
2780
+ */
2781
+ getProjectDir() {
2782
+ return this.projectDir;
2783
+ }
2784
+ };
2785
+
2786
+ // packages/adapters/src/providers/gemini-cli/index.ts
2787
+ function createAdapter4() {
2788
+ return new GeminiCliAdapter();
2789
+ }
2790
+
2791
+ // packages/adapters/src/providers/kimi/adapter.ts
2792
+ import { exec as exec5 } from "node:child_process";
2793
+ import { existsSync as existsSync12 } from "node:fs";
2794
+ import { homedir as homedir11 } from "node:os";
2795
+ import { join as join16 } from "node:path";
2796
+ import { promisify as promisify5 } from "node:util";
2797
+
2798
+ // packages/adapters/src/providers/kimi/hooks.ts
2799
+ var KimiHookProvider = class {
2800
+ registered = false;
2801
+ /**
2802
+ * Map a Kimi native event name to a CAAMP hook event name.
2803
+ *
2804
+ * Kimi has no hook system, so this always returns null.
2805
+ *
2806
+ * @param _providerEvent - Unused; Kimi emits no hookable events
2807
+ * @returns Always null
2808
+ * @task T163
2809
+ */
2810
+ mapProviderEvent(_providerEvent) {
2811
+ return null;
2812
+ }
2813
+ /**
2814
+ * Register native hooks for a project.
2815
+ *
2816
+ * Kimi has no hook system. This method is a no-op and only
2817
+ * tracks registration state for interface compliance.
2818
+ *
2819
+ * @param _projectDir - Project directory (unused)
2820
+ * @task T163
2821
+ */
2822
+ async registerNativeHooks(_projectDir) {
2823
+ this.registered = true;
2824
+ }
2825
+ /**
2826
+ * Unregister native hooks.
2827
+ *
2828
+ * Kimi has no hook system. This method is a no-op.
2829
+ * @task T163
2830
+ */
2831
+ async unregisterNativeHooks() {
2832
+ this.registered = false;
2833
+ }
2834
+ /**
2835
+ * Check whether hooks have been registered via registerNativeHooks.
2836
+ * @task T163
2837
+ */
2838
+ isRegistered() {
2839
+ return this.registered;
2840
+ }
2841
+ /**
2842
+ * Get the full event mapping for introspection/debugging.
2843
+ *
2844
+ * Returns an empty map since Kimi has no hookable events.
2845
+ * @task T163
2846
+ */
2847
+ getEventMap() {
2848
+ return {};
2849
+ }
2850
+ };
2851
+
2852
+ // packages/adapters/src/providers/kimi/install.ts
2853
+ import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "node:fs";
2854
+ import { homedir as homedir10 } from "node:os";
2855
+ import { join as join15 } from "node:path";
2856
+ var INSTRUCTION_REFERENCES5 = ["@~/.cleo/templates/CLEO-INJECTION.md", "@.cleo/memory-bridge.md"];
2857
+ var MCP_SERVER_KEY5 = "cleo";
2858
+ var KimiInstallProvider = class {
2859
+ /**
2860
+ * Install CLEO into a Kimi environment.
2861
+ *
2862
+ * @param options - Installation options including project directory and MCP server path
2863
+ * @returns Result describing what was installed
2864
+ * @task T163
2865
+ */
2866
+ async install(options) {
2867
+ const { projectDir, mcpServerPath } = options;
2868
+ const installedAt = (/* @__PURE__ */ new Date()).toISOString();
2869
+ let instructionFileUpdated = false;
2870
+ let mcpRegistered = false;
2871
+ const details = {};
2872
+ if (mcpServerPath) {
2873
+ mcpRegistered = this.registerMcpServer(mcpServerPath);
2874
+ if (mcpRegistered) {
2875
+ details.mcpConfigPath = join15(homedir10(), ".kimi", "mcp.json");
2876
+ }
2877
+ }
2878
+ instructionFileUpdated = this.updateInstructionFile(projectDir);
2879
+ if (instructionFileUpdated) {
2880
+ details.instructionFile = join15(projectDir, "AGENTS.md");
2881
+ }
2882
+ return {
2883
+ success: true,
2884
+ installedAt,
2885
+ instructionFileUpdated,
2886
+ mcpRegistered,
2887
+ details
2888
+ };
2889
+ }
2890
+ /**
2891
+ * Uninstall CLEO from the Kimi environment.
2892
+ *
2893
+ * Removes the MCP server registration from ~/.kimi/mcp.json.
2894
+ * Does not remove AGENTS.md references (they are harmless if CLEO is not present).
2895
+ * @task T163
2896
+ */
2897
+ async uninstall() {
2898
+ const mcpPath = join15(homedir10(), ".kimi", "mcp.json");
2899
+ if (existsSync11(mcpPath)) {
2900
+ try {
2901
+ const raw = readFileSync7(mcpPath, "utf-8");
2902
+ const config = JSON.parse(raw);
2903
+ const mcpServers = config.mcpServers;
2904
+ if (mcpServers && MCP_SERVER_KEY5 in mcpServers) {
2905
+ delete mcpServers[MCP_SERVER_KEY5];
2906
+ writeFileSync6(mcpPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
2907
+ }
2908
+ } catch {
2909
+ }
2910
+ }
2911
+ }
2912
+ /**
2913
+ * Check whether CLEO is installed in the Kimi environment.
2914
+ *
2915
+ * Checks for MCP server registered in ~/.kimi/mcp.json.
2916
+ * Returns true if the CLEO MCP server entry is found.
2917
+ * @task T163
2918
+ */
2919
+ async isInstalled() {
2920
+ const mcpPath = join15(homedir10(), ".kimi", "mcp.json");
2921
+ if (existsSync11(mcpPath)) {
2922
+ try {
2923
+ const config = JSON.parse(readFileSync7(mcpPath, "utf-8"));
2924
+ const mcpServers = config.mcpServers;
2925
+ if (mcpServers && MCP_SERVER_KEY5 in mcpServers) {
2926
+ return true;
2927
+ }
2928
+ } catch {
2929
+ }
2930
+ }
2931
+ return false;
2932
+ }
2933
+ /**
2934
+ * Ensure AGENTS.md contains @-references to CLEO instruction files.
2935
+ *
2936
+ * Creates AGENTS.md if it does not exist. Appends any missing references.
2937
+ *
2938
+ * @param projectDir - Project root directory
2939
+ * @task T163
2940
+ */
2941
+ async ensureInstructionReferences(projectDir) {
2942
+ this.updateInstructionFile(projectDir);
2943
+ }
2944
+ /**
2945
+ * Register the CLEO MCP server in ~/.kimi/mcp.json.
2946
+ *
2947
+ * Kimi stores its MCP server configuration in ~/.kimi/mcp.json
2948
+ * under the mcpServers key.
2949
+ *
2950
+ * @param mcpServerPath - Absolute path to the MCP server entry point
2951
+ * @returns true if registration was performed or updated
2952
+ */
2953
+ registerMcpServer(mcpServerPath) {
2954
+ const kimiDir = join15(homedir10(), ".kimi");
2955
+ const mcpPath = join15(kimiDir, "mcp.json");
2956
+ let config = {};
2957
+ mkdirSync5(kimiDir, { recursive: true });
2958
+ if (existsSync11(mcpPath)) {
2959
+ try {
2960
+ config = JSON.parse(readFileSync7(mcpPath, "utf-8"));
2961
+ } catch {
2962
+ }
2963
+ }
2964
+ if (!config.mcpServers || typeof config.mcpServers !== "object") {
2965
+ config.mcpServers = {};
2966
+ }
2967
+ const mcpServers = config.mcpServers;
2968
+ mcpServers[MCP_SERVER_KEY5] = {
2969
+ command: "node",
2970
+ args: [mcpServerPath]
2971
+ };
2972
+ writeFileSync6(mcpPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
2973
+ return true;
2974
+ }
2975
+ /**
2976
+ * Update AGENTS.md with CLEO @-references.
2977
+ *
2978
+ * @param projectDir - Project root directory
2979
+ * @returns true if the file was created or modified
2980
+ */
2981
+ updateInstructionFile(projectDir) {
2982
+ const agentsMdPath = join15(projectDir, "AGENTS.md");
2983
+ let content = "";
2984
+ let existed = false;
2985
+ if (existsSync11(agentsMdPath)) {
2986
+ content = readFileSync7(agentsMdPath, "utf-8");
2987
+ existed = true;
2988
+ }
2989
+ const missingRefs = INSTRUCTION_REFERENCES5.filter((ref) => !content.includes(ref));
2990
+ if (missingRefs.length === 0) {
2991
+ return false;
2992
+ }
2993
+ const refsBlock = missingRefs.join("\n");
2994
+ if (existed) {
2995
+ const separator = content.endsWith("\n") ? "" : "\n";
2996
+ content = content + separator + refsBlock + "\n";
2997
+ } else {
2998
+ content = refsBlock + "\n";
2999
+ }
3000
+ writeFileSync6(agentsMdPath, content, "utf-8");
3001
+ return true;
3002
+ }
3003
+ };
3004
+
3005
+ // packages/adapters/src/providers/kimi/adapter.ts
3006
+ var execAsync5 = promisify5(exec5);
3007
+ var KimiAdapter = class {
3008
+ id = "kimi";
3009
+ name = "Kimi";
3010
+ version = "1.0.0";
3011
+ capabilities = {
3012
+ supportsHooks: false,
3013
+ supportedHookEvents: [],
3014
+ supportsSpawn: false,
3015
+ supportsInstall: true,
3016
+ supportsMcp: true,
3017
+ supportsInstructionFiles: false,
3018
+ supportsContextMonitor: false,
3019
+ supportsStatusline: false,
3020
+ supportsProviderPaths: false,
3021
+ supportsTransport: false,
3022
+ supportsTaskSync: false
3023
+ };
3024
+ hooks;
3025
+ install;
3026
+ projectDir = null;
3027
+ initialized = false;
3028
+ constructor() {
3029
+ this.hooks = new KimiHookProvider();
3030
+ this.install = new KimiInstallProvider();
3031
+ }
3032
+ /**
3033
+ * Initialize the adapter for a given project directory.
3034
+ *
3035
+ * @param projectDir - Root directory of the project
3036
+ * @task T163
3037
+ */
3038
+ async initialize(projectDir) {
3039
+ this.projectDir = projectDir;
3040
+ this.initialized = true;
3041
+ }
3042
+ /**
3043
+ * Dispose the adapter and clean up resources.
3044
+ *
3045
+ * Releases tracked state. No hooks to unregister since Kimi
3046
+ * has no native hook system.
3047
+ * @task T163
3048
+ */
3049
+ async dispose() {
3050
+ this.initialized = false;
3051
+ this.projectDir = null;
3052
+ }
3053
+ /**
3054
+ * Run a health check to verify Kimi is accessible.
3055
+ *
3056
+ * Checks:
3057
+ * 1. Adapter has been initialized
3058
+ * 2. Kimi CLI binary is available in PATH
3059
+ * 3. ~/.kimi/ configuration directory exists
3060
+ *
3061
+ * @returns Health status with details about each check
3062
+ * @task T163
3063
+ */
3064
+ async healthCheck() {
3065
+ const details = {};
3066
+ if (!this.initialized) {
3067
+ return {
3068
+ healthy: false,
3069
+ provider: this.id,
3070
+ details: { error: "Adapter not initialized" }
3071
+ };
3072
+ }
3073
+ let cliAvailable = false;
3074
+ try {
3075
+ const { stdout } = await execAsync5("which kimi");
3076
+ cliAvailable = stdout.trim().length > 0;
3077
+ details.cliPath = stdout.trim();
3078
+ } catch {
3079
+ details.cliAvailable = false;
3080
+ }
3081
+ const kimiConfigDir = join16(homedir11(), ".kimi");
3082
+ const configExists = existsSync12(kimiConfigDir);
3083
+ details.configDirExists = configExists;
3084
+ const healthy = cliAvailable;
3085
+ details.cliAvailable = cliAvailable;
3086
+ return {
3087
+ healthy,
3088
+ provider: this.id,
3089
+ details
3090
+ };
3091
+ }
3092
+ /**
3093
+ * Check whether the adapter has been initialized.
3094
+ * @task T163
3095
+ */
3096
+ isInitialized() {
3097
+ return this.initialized;
3098
+ }
3099
+ /**
3100
+ * Get the project directory this adapter was initialized with.
3101
+ * @task T163
3102
+ */
3103
+ getProjectDir() {
3104
+ return this.projectDir;
3105
+ }
3106
+ };
3107
+
3108
+ // packages/adapters/src/providers/kimi/index.ts
3109
+ function createAdapter5() {
3110
+ return new KimiAdapter();
3111
+ }
3112
+
3113
+ // packages/adapters/src/index.ts
2000
3114
  init_opencode();
2001
3115
 
2002
3116
  // packages/adapters/src/registry.js
2003
- import { readFileSync as readFileSync6 } from "node:fs";
2004
- import { dirname as dirname2, join as join12, resolve } from "node:path";
3117
+ import { readFileSync as readFileSync9 } from "node:fs";
3118
+ import { dirname as dirname2, join as join20, resolve } from "node:path";
2005
3119
  import { fileURLToPath } from "node:url";
2006
3120
  var PROVIDER_IDS = ["claude-code", "opencode", "cursor"];
2007
3121
  function getProviderManifests() {
@@ -2009,8 +3123,8 @@ function getProviderManifests() {
2009
3123
  const baseDir = resolve(dirname2(fileURLToPath(import.meta.url)), "providers");
2010
3124
  for (const providerId of PROVIDER_IDS) {
2011
3125
  try {
2012
- const manifestPath = join12(baseDir, providerId, "manifest.json");
2013
- const raw = readFileSync6(manifestPath, "utf-8");
3126
+ const manifestPath = join20(baseDir, providerId, "manifest.json");
3127
+ const raw = readFileSync9(manifestPath, "utf-8");
2014
3128
  manifests.push(JSON.parse(raw));
2015
3129
  } catch {
2016
3130
  }
@@ -2041,17 +3155,29 @@ export {
2041
3155
  ClaudeCodePathProvider,
2042
3156
  ClaudeCodeSpawnProvider,
2043
3157
  ClaudeCodeTransportProvider,
3158
+ CodexAdapter,
3159
+ CodexHookProvider,
3160
+ CodexInstallProvider,
2044
3161
  CursorAdapter,
2045
3162
  CursorHookProvider,
2046
3163
  CursorInstallProvider,
3164
+ GeminiCliAdapter,
3165
+ GeminiCliHookProvider,
3166
+ GeminiCliInstallProvider,
3167
+ KimiAdapter,
3168
+ KimiHookProvider,
3169
+ KimiInstallProvider,
2047
3170
  OpenCodeAdapter,
2048
3171
  OpenCodeHookProvider,
2049
3172
  OpenCodeInstallProvider,
2050
3173
  OpenCodeSpawnProvider,
2051
3174
  checkStatuslineIntegration,
2052
3175
  createAdapter as createClaudeCodeAdapter,
2053
- createAdapter2 as createCursorAdapter,
2054
- createAdapter3 as createOpenCodeAdapter,
3176
+ createAdapter2 as createCodexAdapter,
3177
+ createAdapter3 as createCursorAdapter,
3178
+ createAdapter4 as createGeminiCliAdapter,
3179
+ createAdapter5 as createKimiAdapter,
3180
+ createAdapter6 as createOpenCodeAdapter,
2055
3181
  discoverProviders,
2056
3182
  getProviderManifests,
2057
3183
  getSetupInstructions,