@claudexor/cli 1.0.1 → 2.1.2

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 (213) hide show
  1. package/dist/acp-surface-runner.d.ts +17 -0
  2. package/dist/acp-surface-runner.d.ts.map +1 -0
  3. package/dist/acp-surface-runner.js +187 -0
  4. package/dist/acp-surface-runner.js.map +1 -0
  5. package/dist/args.d.ts.map +1 -1
  6. package/dist/args.js.map +1 -1
  7. package/dist/bridge-serve.d.ts +3 -0
  8. package/dist/bridge-serve.d.ts.map +1 -0
  9. package/dist/bridge-serve.js +39 -0
  10. package/dist/bridge-serve.js.map +1 -0
  11. package/dist/capabilities.d.ts.map +1 -1
  12. package/dist/capabilities.js +12 -3
  13. package/dist/capabilities.js.map +1 -1
  14. package/dist/claude-oauth-usage.d.ts +33 -0
  15. package/dist/claude-oauth-usage.d.ts.map +1 -0
  16. package/dist/claude-oauth-usage.js +190 -0
  17. package/dist/claude-oauth-usage.js.map +1 -0
  18. package/dist/claude-statusline.d.ts +25 -0
  19. package/dist/claude-statusline.d.ts.map +1 -0
  20. package/dist/claude-statusline.js +259 -0
  21. package/dist/claude-statusline.js.map +1 -0
  22. package/dist/claudexord.js +346 -543
  23. package/dist/claudexord.js.map +1 -1
  24. package/dist/cli-io.d.ts +8 -9
  25. package/dist/cli-io.d.ts.map +1 -1
  26. package/dist/cli-io.js +11 -7
  27. package/dist/cli-io.js.map +1 -1
  28. package/dist/cli.js +475 -516
  29. package/dist/cli.js.map +1 -1
  30. package/dist/codex-quota-source.d.ts +11 -0
  31. package/dist/codex-quota-source.d.ts.map +1 -0
  32. package/dist/codex-quota-source.js +181 -0
  33. package/dist/codex-quota-source.js.map +1 -0
  34. package/dist/command-flags.d.ts +18 -0
  35. package/dist/command-flags.d.ts.map +1 -0
  36. package/dist/command-flags.js +124 -0
  37. package/dist/command-flags.js.map +1 -0
  38. package/dist/command-registry.d.ts +2 -40
  39. package/dist/command-registry.d.ts.map +1 -1
  40. package/dist/command-registry.js +74 -164
  41. package/dist/command-registry.js.map +1 -1
  42. package/dist/control-services.d.ts +2483 -0
  43. package/dist/control-services.d.ts.map +1 -0
  44. package/dist/control-services.js +437 -0
  45. package/dist/control-services.js.map +1 -0
  46. package/dist/credential-commands.d.ts +9 -0
  47. package/dist/credential-commands.d.ts.map +1 -0
  48. package/dist/credential-commands.js +224 -0
  49. package/dist/credential-commands.js.map +1 -0
  50. package/dist/daemon-lifecycle.d.ts +7 -3
  51. package/dist/daemon-lifecycle.d.ts.map +1 -1
  52. package/dist/daemon-lifecycle.js +40 -12
  53. package/dist/daemon-lifecycle.js.map +1 -1
  54. package/dist/daemon-run.d.ts +2 -0
  55. package/dist/daemon-run.d.ts.map +1 -1
  56. package/dist/daemon-run.js +62 -14
  57. package/dist/daemon-run.js.map +1 -1
  58. package/dist/daemon-runtime-shutdown.d.ts +58 -0
  59. package/dist/daemon-runtime-shutdown.d.ts.map +1 -0
  60. package/dist/daemon-runtime-shutdown.js +142 -0
  61. package/dist/daemon-runtime-shutdown.js.map +1 -0
  62. package/dist/decision.d.ts.map +1 -1
  63. package/dist/decision.js +12 -3
  64. package/dist/decision.js.map +1 -1
  65. package/dist/live.d.ts +29 -0
  66. package/dist/live.d.ts.map +1 -1
  67. package/dist/live.js +117 -6
  68. package/dist/live.js.map +1 -1
  69. package/dist/local-attachment.d.ts +14 -0
  70. package/dist/local-attachment.d.ts.map +1 -0
  71. package/dist/local-attachment.js +67 -0
  72. package/dist/local-attachment.js.map +1 -0
  73. package/dist/mcp-runner.d.ts +4 -15
  74. package/dist/mcp-runner.d.ts.map +1 -1
  75. package/dist/mcp-runner.js +273 -145
  76. package/dist/mcp-runner.js.map +1 -1
  77. package/dist/native-login.d.ts +21 -0
  78. package/dist/native-login.d.ts.map +1 -0
  79. package/dist/native-login.js +111 -0
  80. package/dist/native-login.js.map +1 -0
  81. package/dist/ops-commands.d.ts +8 -6
  82. package/dist/ops-commands.d.ts.map +1 -1
  83. package/dist/ops-commands.js +250 -168
  84. package/dist/ops-commands.js.map +1 -1
  85. package/dist/orchestrate-options.d.ts.map +1 -1
  86. package/dist/orchestrate-options.js +1 -1
  87. package/dist/orchestrate-options.js.map +1 -1
  88. package/dist/orphan-reaper.d.ts +4 -5
  89. package/dist/orphan-reaper.d.ts.map +1 -1
  90. package/dist/orphan-reaper.js +29 -56
  91. package/dist/orphan-reaper.js.map +1 -1
  92. package/dist/orphan-sweeper.d.ts +1 -2
  93. package/dist/orphan-sweeper.d.ts.map +1 -1
  94. package/dist/orphan-sweeper.js +29 -48
  95. package/dist/orphan-sweeper.js.map +1 -1
  96. package/dist/plugins.d.ts.map +1 -1
  97. package/dist/plugins.js +196 -64
  98. package/dist/plugins.js.map +1 -1
  99. package/dist/primary-output.d.ts.map +1 -1
  100. package/dist/primary-output.js.map +1 -1
  101. package/dist/profile-registration.d.ts +15 -0
  102. package/dist/profile-registration.d.ts.map +1 -0
  103. package/dist/profile-registration.js +68 -0
  104. package/dist/profile-registration.js.map +1 -0
  105. package/dist/project-command.d.ts +3 -0
  106. package/dist/project-command.d.ts.map +1 -0
  107. package/dist/project-command.js +87 -0
  108. package/dist/project-command.js.map +1 -0
  109. package/dist/quota-command.d.ts +3 -0
  110. package/dist/quota-command.d.ts.map +1 -0
  111. package/dist/quota-command.js +59 -0
  112. package/dist/quota-command.js.map +1 -0
  113. package/dist/registry.d.ts +1 -1
  114. package/dist/registry.d.ts.map +1 -1
  115. package/dist/registry.js +16 -4
  116. package/dist/registry.js.map +1 -1
  117. package/dist/release.d.ts.map +1 -1
  118. package/dist/release.js +15 -3
  119. package/dist/release.js.map +1 -1
  120. package/dist/repl.d.ts +3 -8
  121. package/dist/repl.d.ts.map +1 -1
  122. package/dist/repl.js +23 -122
  123. package/dist/repl.js.map +1 -1
  124. package/dist/request-preflight.d.ts +13 -0
  125. package/dist/request-preflight.d.ts.map +1 -0
  126. package/dist/request-preflight.js +81 -0
  127. package/dist/request-preflight.js.map +1 -0
  128. package/dist/retention-service.d.ts +24 -0
  129. package/dist/retention-service.d.ts.map +1 -0
  130. package/dist/retention-service.js +100 -0
  131. package/dist/retention-service.js.map +1 -0
  132. package/dist/retry-command-specs.d.ts +3 -0
  133. package/dist/retry-command-specs.d.ts.map +1 -0
  134. package/dist/retry-command-specs.js +21 -0
  135. package/dist/retry-command-specs.js.map +1 -0
  136. package/dist/retry-command.d.ts +4 -0
  137. package/dist/retry-command.d.ts.map +1 -0
  138. package/dist/retry-command.js +57 -0
  139. package/dist/retry-command.js.map +1 -0
  140. package/dist/review-command.d.ts.map +1 -1
  141. package/dist/review-command.js +47 -12
  142. package/dist/review-command.js.map +1 -1
  143. package/dist/run-options.d.ts +2 -2
  144. package/dist/run-options.d.ts.map +1 -1
  145. package/dist/run-options.js +27 -5
  146. package/dist/run-options.js.map +1 -1
  147. package/dist/settings-command.d.ts.map +1 -1
  148. package/dist/settings-command.js +143 -188
  149. package/dist/settings-command.js.map +1 -1
  150. package/dist/settings-service.d.ts +50 -0
  151. package/dist/settings-service.d.ts.map +1 -1
  152. package/dist/settings-service.js +67 -1
  153. package/dist/settings-service.js.map +1 -1
  154. package/dist/setup-job-reducer.d.ts +9 -0
  155. package/dist/setup-job-reducer.d.ts.map +1 -0
  156. package/dist/setup-job-reducer.js +290 -0
  157. package/dist/setup-job-reducer.js.map +1 -0
  158. package/dist/setup-job-store.d.ts +250 -0
  159. package/dist/setup-job-store.d.ts.map +1 -0
  160. package/dist/setup-job-store.js +359 -0
  161. package/dist/setup-job-store.js.map +1 -0
  162. package/dist/setup-job-support.d.ts +27 -0
  163. package/dist/setup-job-support.d.ts.map +1 -0
  164. package/dist/setup-job-support.js +141 -0
  165. package/dist/setup-job-support.js.map +1 -0
  166. package/dist/setup-jobs.d.ts +437 -22
  167. package/dist/setup-jobs.d.ts.map +1 -1
  168. package/dist/setup-jobs.js +813 -423
  169. package/dist/setup-jobs.js.map +1 -1
  170. package/dist/setup-lifecycle-binding.d.ts +40 -0
  171. package/dist/setup-lifecycle-binding.d.ts.map +1 -0
  172. package/dist/setup-lifecycle-binding.js +159 -0
  173. package/dist/setup-lifecycle-binding.js.map +1 -0
  174. package/dist/setup-login-protocol.d.ts +13 -0
  175. package/dist/setup-login-protocol.d.ts.map +1 -0
  176. package/dist/setup-login-protocol.js +179 -0
  177. package/dist/setup-login-protocol.js.map +1 -0
  178. package/dist/setup-login-runner.d.ts +20 -0
  179. package/dist/setup-login-runner.d.ts.map +1 -0
  180. package/dist/setup-login-runner.js +225 -0
  181. package/dist/setup-login-runner.js.map +1 -0
  182. package/dist/setup-supervisor.d.ts +53 -0
  183. package/dist/setup-supervisor.d.ts.map +1 -0
  184. package/dist/setup-supervisor.js +177 -0
  185. package/dist/setup-supervisor.js.map +1 -0
  186. package/dist/spec.d.ts +9 -20
  187. package/dist/spec.d.ts.map +1 -1
  188. package/dist/spec.js +49 -21
  189. package/dist/spec.js.map +1 -1
  190. package/dist/thread-delivery.d.ts +18 -0
  191. package/dist/thread-delivery.d.ts.map +1 -0
  192. package/dist/thread-delivery.js +67 -0
  193. package/dist/thread-delivery.js.map +1 -0
  194. package/dist/thread-select.d.ts +9 -0
  195. package/dist/thread-select.d.ts.map +1 -0
  196. package/dist/thread-select.js +12 -0
  197. package/dist/thread-select.js.map +1 -0
  198. package/dist/trust-command.d.ts.map +1 -1
  199. package/dist/trust-command.js +69 -61
  200. package/dist/trust-command.js.map +1 -1
  201. package/dist/trust-services.d.ts +5 -6
  202. package/dist/trust-services.d.ts.map +1 -1
  203. package/dist/trust-services.js +42 -13
  204. package/dist/trust-services.js.map +1 -1
  205. package/package.json +24 -22
  206. package/dist/attachment-resolver.d.ts +0 -11
  207. package/dist/attachment-resolver.d.ts.map +0 -1
  208. package/dist/attachment-resolver.js +0 -61
  209. package/dist/attachment-resolver.js.map +0 -1
  210. package/dist/settings-display.d.ts +0 -3
  211. package/dist/settings-display.d.ts.map +0 -1
  212. package/dist/settings-display.js +0 -33
  213. package/dist/settings-display.js.map +0 -1
package/dist/plugins.js CHANGED
@@ -3,6 +3,7 @@ import { copyFileSync, existsSync, lstatSync, readFileSync, readdirSync, realpat
3
3
  import { dirname, isAbsolute, join, relative, resolve } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { hostFallbackExamples, recoveryVerbs } from "./command-registry.js";
6
+ import { manageClaudeStatusline } from "./claude-statusline.js";
6
7
  import { CLAUDEXOR_VERSION, ensureDir, sha256, userConfigDir, userHomeDir, writeJson, } from "@claudexor/util";
7
8
  export const PLUGIN_HOSTS = ["cursor", "claude", "codex", "opencode"];
8
9
  export const PLUGIN_TARGETS = [...PLUGIN_HOSTS, "all"];
@@ -21,10 +22,6 @@ function jsonText(value) {
21
22
  function generatedMcpEnv(runtime) {
22
23
  return {
23
24
  CLAUDEXOR_CONFIG_DIR: runtime.configDir,
24
- // MANAGED is drift-detection CONTENT (versions the generated artifact
25
- // text for status/doctor). PLUGIN_VERSION is ALSO read at runtime:
26
- // `mcp serve` compares it with the CLI version and warns on stderr when
27
- // the installed artifacts are stale (repair + host reload fixes it).
28
25
  CLAUDEXOR_MANAGED: MARKER,
29
26
  CLAUDEXOR_PLUGIN_VERSION: CLAUDEXOR_VERSION,
30
27
  };
@@ -46,19 +43,16 @@ function opencodeMcpEntry(runtime) {
46
43
  command: [runtime.nodePath, runtime.cliPath, "mcp", "serve"],
47
44
  environment: generatedMcpEnv(runtime),
48
45
  enabled: true,
49
- // Tool-DISCOVERY timeout only (OpenCode semantics). Tool EXECUTION time
50
- // is governed by OpenCode's global MCP execution timeout — long verbs
51
- // (agent/best-of) can exceed it; the generated README and INTEGRATIONS.md
52
- // carry the guidance (raise experimental.mcp_timeout, or prefer the CLI
53
- // for long runs). The runId trailer keeps abandoned calls recoverable.
54
46
  timeout: 5000,
55
47
  };
56
48
  }
57
49
  /** `claudexor inspect <runId>`, `follow <runId>`, ... — from the registry's recovery verbs. */
58
50
  function recoveryVerbLine() {
59
51
  const verbs = recoveryVerbs();
60
- const parts = verbs.map((verb, i) => (i === 0 ? `\`claudexor ${verb} <runId>\`` : `\`${verb} <runId>\``));
61
- return parts.length > 1 ? `${parts.slice(0, -1).join(", ")}, or ${parts[parts.length - 1]}` : (parts[0] ?? "");
52
+ const parts = verbs.map((verb, i) => i === 0 ? `\`claudexor ${verb} <runId>\`` : `\`${verb} <runId>\``);
53
+ return parts.length > 1
54
+ ? `${parts.slice(0, -1).join(", ")}, or ${parts[parts.length - 1]}`
55
+ : (parts[0] ?? "");
62
56
  }
63
57
  function skillText(host) {
64
58
  const namespace = host === "claude" ? "claudexor@skills-dir" : "claudexor";
@@ -110,9 +104,9 @@ function skillText(host) {
110
104
  ].join("\n");
111
105
  }
112
106
  function commandText(host) {
113
- const frontmatter = (host === "claude" || host === "cursor" || host === "opencode"
107
+ const frontmatter = host === "claude" || host === "cursor" || host === "opencode"
114
108
  ? ["---", "description: Use Claudexor CLI/MCP for harness-agnostic coding workflows", "---"]
115
- : []);
109
+ : [];
116
110
  return [
117
111
  ...frontmatter,
118
112
  managedComment().trimEnd(),
@@ -124,7 +118,9 @@ function commandText(host) {
124
118
  "",
125
119
  "Do not claim live thread parity through MCP. Ask for an explicit repo path if the target project is ambiguous.",
126
120
  "",
127
- ].filter((line, i, all) => line !== "" || all[i - 1] !== "").join("\n");
121
+ ]
122
+ .filter((line, i, all) => line !== "" || all[i - 1] !== "")
123
+ .join("\n");
128
124
  }
129
125
  function readmeText(host) {
130
126
  return [
@@ -210,11 +206,31 @@ const HOST_DEFINITIONS = {
210
206
  artifacts: (home, runtime) => {
211
207
  const root = join(home, ".claude", "skills", "claudexor");
212
208
  return [
213
- { path: join(root, ".claude-plugin", "plugin.json"), content: manifest("claude"), description: "Claude plugin manifest" },
214
- { path: join(root, "skills", "claudexor", "SKILL.md"), content: skillText("claude"), description: "Claude skill" },
215
- { path: join(root, "commands", "claudexor.md"), content: commandText("claude"), description: "Claude command" },
216
- { path: join(root, ".mcp.json"), content: jsonText(mcpServers(runtime)), description: "Claude MCP config" },
217
- { path: join(root, "README.md"), content: readmeText("claude"), description: "Claude integration README" },
209
+ {
210
+ path: join(root, ".claude-plugin", "plugin.json"),
211
+ content: manifest("claude"),
212
+ description: "Claude plugin manifest",
213
+ },
214
+ {
215
+ path: join(root, "skills", "claudexor", "SKILL.md"),
216
+ content: skillText("claude"),
217
+ description: "Claude skill",
218
+ },
219
+ {
220
+ path: join(root, "commands", "claudexor.md"),
221
+ content: commandText("claude"),
222
+ description: "Claude command",
223
+ },
224
+ {
225
+ path: join(root, ".mcp.json"),
226
+ content: jsonText(mcpServers(runtime)),
227
+ description: "Claude MCP config",
228
+ },
229
+ {
230
+ path: join(root, "README.md"),
231
+ content: readmeText("claude"),
232
+ description: "Claude integration README",
233
+ },
218
234
  ];
219
235
  },
220
236
  legacy: (home) => [
@@ -235,10 +251,26 @@ const HOST_DEFINITIONS = {
235
251
  artifacts: (home, runtime) => {
236
252
  const root = join(home, ".codex", "plugins", "claudexor");
237
253
  return [
238
- { path: join(root, ".codex-plugin", "plugin.json"), content: manifest("codex"), description: "Codex plugin manifest" },
239
- { path: join(root, "skills", "claudexor", "SKILL.md"), content: skillText("codex"), description: "Codex skill" },
240
- { path: join(root, ".mcp.json"), content: jsonText(mcpServers(runtime)), description: "Codex MCP config" },
241
- { path: join(root, "README.md"), content: readmeText("codex"), description: "Codex integration README" },
254
+ {
255
+ path: join(root, ".codex-plugin", "plugin.json"),
256
+ content: manifest("codex"),
257
+ description: "Codex plugin manifest",
258
+ },
259
+ {
260
+ path: join(root, "skills", "claudexor", "SKILL.md"),
261
+ content: skillText("codex"),
262
+ description: "Codex skill",
263
+ },
264
+ {
265
+ path: join(root, ".mcp.json"),
266
+ content: jsonText(mcpServers(runtime)),
267
+ description: "Codex MCP config",
268
+ },
269
+ {
270
+ path: join(root, "README.md"),
271
+ content: readmeText("codex"),
272
+ description: "Codex integration README",
273
+ },
242
274
  ];
243
275
  },
244
276
  config: "codex-marketplace",
@@ -260,11 +292,31 @@ const HOST_DEFINITIONS = {
260
292
  artifacts: (home, runtime) => {
261
293
  const root = join(home, ".cursor", "plugins", "local", "claudexor");
262
294
  return [
263
- { path: join(root, ".cursor-plugin", "plugin.json"), content: manifest("cursor"), description: "Cursor plugin manifest" },
264
- { path: join(root, "skills", "claudexor", "SKILL.md"), content: skillText("cursor"), description: "Cursor skill" },
265
- { path: join(root, "commands", "claudexor.md"), content: commandText("cursor"), description: "Cursor command" },
266
- { path: join(root, "mcp.json"), content: jsonText(mcpServers(runtime)), description: "Cursor MCP config" },
267
- { path: join(root, "README.md"), content: readmeText("cursor"), description: "Cursor integration README" },
295
+ {
296
+ path: join(root, ".cursor-plugin", "plugin.json"),
297
+ content: manifest("cursor"),
298
+ description: "Cursor plugin manifest",
299
+ },
300
+ {
301
+ path: join(root, "skills", "claudexor", "SKILL.md"),
302
+ content: skillText("cursor"),
303
+ description: "Cursor skill",
304
+ },
305
+ {
306
+ path: join(root, "commands", "claudexor.md"),
307
+ content: commandText("cursor"),
308
+ description: "Cursor command",
309
+ },
310
+ {
311
+ path: join(root, "mcp.json"),
312
+ content: jsonText(mcpServers(runtime)),
313
+ description: "Cursor MCP config",
314
+ },
315
+ {
316
+ path: join(root, "README.md"),
317
+ content: readmeText("cursor"),
318
+ description: "Cursor integration README",
319
+ },
268
320
  ];
269
321
  },
270
322
  legacy: (home) => [
@@ -285,9 +337,21 @@ const HOST_DEFINITIONS = {
285
337
  artifacts: (home, runtime) => {
286
338
  const root = join(home, ".config", "opencode");
287
339
  return [
288
- { path: join(root, "skills", "claudexor", "SKILL.md"), content: skillText("opencode"), description: "OpenCode skill" },
289
- { path: join(root, "commands", "claudexor.md"), content: commandText("opencode"), description: "OpenCode command" },
290
- { path: join(root, "plugins", "claudexor.js"), content: opencodePluginText(runtime), description: "OpenCode JS plugin" },
340
+ {
341
+ path: join(root, "skills", "claudexor", "SKILL.md"),
342
+ content: skillText("opencode"),
343
+ description: "OpenCode skill",
344
+ },
345
+ {
346
+ path: join(root, "commands", "claudexor.md"),
347
+ content: commandText("opencode"),
348
+ description: "OpenCode command",
349
+ },
350
+ {
351
+ path: join(root, "plugins", "claudexor.js"),
352
+ content: opencodePluginText(runtime),
353
+ description: "OpenCode JS plugin",
354
+ },
291
355
  ];
292
356
  },
293
357
  config: "opencode-mcp",
@@ -346,7 +410,9 @@ function loadState(configDir = userConfigDir()) {
346
410
  catch (err) {
347
411
  throw new Error(`plugin state is not valid JSON: ${path}: ${err instanceof Error ? err.message : String(err)}`);
348
412
  }
349
- if (!parsed || typeof parsed !== "object" || parsed.version !== STATE_VERSION) {
413
+ if (!parsed ||
414
+ typeof parsed !== "object" ||
415
+ parsed.version !== STATE_VERSION) {
350
416
  throw new Error(`plugin state has unsupported shape: ${path}`);
351
417
  }
352
418
  const state = parsed;
@@ -376,7 +442,10 @@ function readText(path) {
376
442
  return readFileSync(path, "utf8");
377
443
  }
378
444
  catch (err) {
379
- if (err && typeof err === "object" && "code" in err && err.code === "ENOENT")
445
+ if (err &&
446
+ typeof err === "object" &&
447
+ "code" in err &&
448
+ err.code === "ENOENT")
380
449
  return null;
381
450
  throw new Error(`unable to read ${path}: ${err instanceof Error ? err.message : String(err)}`);
382
451
  }
@@ -451,7 +520,10 @@ function assertReadableLeaf(path) {
451
520
  lstatSync(path);
452
521
  }
453
522
  catch (err) {
454
- if (err && typeof err === "object" && "code" in err && err.code === "ENOENT")
523
+ if (err &&
524
+ typeof err === "object" &&
525
+ "code" in err &&
526
+ err.code === "ENOENT")
455
527
  return;
456
528
  throw err;
457
529
  }
@@ -475,7 +547,10 @@ function rejectSymlinkPath(path) {
475
547
  st = lstatSync(path);
476
548
  }
477
549
  catch (err) {
478
- if (err && typeof err === "object" && "code" in err && err.code === "ENOENT")
550
+ if (err &&
551
+ typeof err === "object" &&
552
+ "code" in err &&
553
+ err.code === "ENOENT")
479
554
  return;
480
555
  throw err;
481
556
  }
@@ -496,7 +571,10 @@ function assertSafeLeaf(path) {
496
571
  throw new Error(`${path} is not a regular file`);
497
572
  }
498
573
  catch (err) {
499
- if (err && typeof err === "object" && "code" in err && err.code === "ENOENT")
574
+ if (err &&
575
+ typeof err === "object" &&
576
+ "code" in err &&
577
+ err.code === "ENOENT")
500
578
  return;
501
579
  throw err;
502
580
  }
@@ -582,7 +660,7 @@ cross-family review, and budget balancing. Prefer it for multi-harness work.
582
660
  - \`claudexor race "<task>" --n 4\` Best-of-N tournament + cross-family review
583
661
  - \`claudexor plan "<task>"\` read-only plan
584
662
  - \`claudexor create "<task>"\` create a new project
585
- - \`claudexor inspect <run_id>\` inspect artifacts under .claudexor/runs
663
+ - \`claudexor inspect <run_id>\` inspect artifacts in the external runtime store
586
664
 
587
665
  These plugins are thin shims: they call the local CLI; all orchestration lives in claudexor.`;
588
666
  const OLD_LEGACY_CLAUDE_COMMAND = `---
@@ -603,7 +681,8 @@ function legacyThinShimVerifier(file, text) {
603
681
  if (file.endsWith("plugin.json"))
604
682
  return isOldThinShimManifest(text);
605
683
  if (file === "commands/claudexor.md") {
606
- return exactLegacyText(text, OLD_LEGACY_CLAUDE_COMMAND) || exactLegacyText(text, OLD_LEGACY_CURSOR_COMMAND);
684
+ return (exactLegacyText(text, OLD_LEGACY_CLAUDE_COMMAND) ||
685
+ exactLegacyText(text, OLD_LEGACY_CURSOR_COMMAND));
607
686
  }
608
687
  return false;
609
688
  }
@@ -653,11 +732,14 @@ function backupFile(def, runtime, path) {
653
732
  return dest;
654
733
  }
655
734
  function hasManagedMarker(text) {
656
- return text.includes(MARKER) || text.includes('"marker": "claudexor:managed host-plugin-lifecycle"');
735
+ return (text.includes(MARKER) || text.includes('"marker": "claudexor:managed host-plugin-lifecycle"'));
657
736
  }
658
737
  function artifactOwned(state, host, artifact, current, force) {
659
738
  const entry = state.hosts[host]?.artifacts[artifact.path];
660
- return entry?.hash === hashText(current) || (entry !== undefined && hasManagedMarker(current)) || current === artifact.content || (force && hasManagedMarker(current));
739
+ return (entry?.hash === hashText(current) ||
740
+ (entry !== undefined && hasManagedMarker(current)) ||
741
+ current === artifact.content ||
742
+ (force && hasManagedMarker(current)));
661
743
  }
662
744
  function isPathInside(root, path) {
663
745
  const rel = relative(root, path);
@@ -712,7 +794,10 @@ function configEntryOwned(stateEntry, current, desired, force, requireState = fa
712
794
  const currentText = JSON.stringify(current);
713
795
  const hasMarker = currentText.includes(MARKER);
714
796
  const exactMarkedDesired = !requireState && hasMarker && jsonText(current) === jsonText(desired);
715
- return stateEntry?.hash === hashText(jsonText(current)) || exactMarkedDesired || (stateEntry !== undefined && hasMarker) || (force && hasMarker);
797
+ return (stateEntry?.hash === hashText(jsonText(current)) ||
798
+ exactMarkedDesired ||
799
+ (stateEntry !== undefined && hasMarker) ||
800
+ (force && hasMarker));
716
801
  }
717
802
  function codexMarketplaceEntries(plugins) {
718
803
  return plugins
@@ -723,8 +808,12 @@ function mergeCodexMarketplace(state, dryRun, force, def, runtime, res) {
723
808
  const path = join(userHomeDir(), ".agents", "plugins", "marketplace.json");
724
809
  const desired = desiredCodexMarketplaceEntry();
725
810
  const parsed = readJsonFile(path);
726
- const base = parsed === undefined ? { name: "personal", interface: { displayName: "Personal" }, plugins: [] } : parsed;
727
- if (!base || typeof base !== "object" || !Array.isArray(base.plugins)) {
811
+ const base = parsed === undefined
812
+ ? { name: "personal", interface: { displayName: "Personal" }, plugins: [] }
813
+ : parsed;
814
+ if (!base ||
815
+ typeof base !== "object" ||
816
+ !Array.isArray(base.plugins)) {
728
817
  res.errors.push(`${path} is not a Codex marketplace JSON object with plugins[]`);
729
818
  return false;
730
819
  }
@@ -831,7 +920,10 @@ function checkConfig(host, state, res, runtime) {
831
920
  return false;
832
921
  }
833
922
  const desired = desiredCodexMarketplaceEntry();
834
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || !Array.isArray(parsed.plugins)) {
923
+ if (!parsed ||
924
+ typeof parsed !== "object" ||
925
+ Array.isArray(parsed) ||
926
+ !Array.isArray(parsed.plugins)) {
835
927
  res.errors.push(`${path} is not a Codex marketplace JSON object with plugins[]`);
836
928
  return false;
837
929
  }
@@ -848,7 +940,9 @@ function checkConfig(host, state, res, runtime) {
848
940
  res.errors.push(`${path} has an unowned claudexor marketplace entry`);
849
941
  return false;
850
942
  }
851
- res.notes.push(matches.length > 0 ? "Codex marketplace entry is drifted" : "Codex marketplace entry is missing");
943
+ res.notes.push(matches.length > 0
944
+ ? "Codex marketplace entry is drifted"
945
+ : "Codex marketplace entry is missing");
852
946
  return false;
853
947
  }
854
948
  if (host === "opencode") {
@@ -900,7 +994,9 @@ function removeConfig(host, state, dryRun, force, def, runtime, res) {
900
994
  const parsed = readJsonFile(path);
901
995
  if (parsed === undefined)
902
996
  return true;
903
- if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.plugins)) {
997
+ if (!parsed ||
998
+ typeof parsed !== "object" ||
999
+ !Array.isArray(parsed.plugins)) {
904
1000
  res.errors.push(`${path} is not a Codex marketplace JSON object with plugins[]`);
905
1001
  return false;
906
1002
  }
@@ -1012,13 +1108,22 @@ function applyArtifacts(def, artifacts, state, dryRun, force, runtime, res) {
1012
1108
  function obsoleteArtifactRoots(host, home) {
1013
1109
  switch (host) {
1014
1110
  case "claude":
1015
- return [join(home, ".claude", "skills", "claudexor"), join(home, ".claude", "plugins", "claudexor")];
1111
+ return [
1112
+ join(home, ".claude", "skills", "claudexor"),
1113
+ join(home, ".claude", "plugins", "claudexor"),
1114
+ ];
1016
1115
  case "codex":
1017
- return [join(home, ".codex", "plugins", "claudexor"), join(home, ".agents", "skills", "claudexor")];
1116
+ return [
1117
+ join(home, ".codex", "plugins", "claudexor"),
1118
+ join(home, ".agents", "skills", "claudexor"),
1119
+ ];
1018
1120
  case "cursor":
1019
1121
  return [join(home, ".cursor", "plugins", "local", "claudexor")];
1020
1122
  case "opencode":
1021
- return [join(home, ".config", "opencode", "skills", "claudexor"), join(home, ".config", "opencode", "claudexor")];
1123
+ return [
1124
+ join(home, ".config", "opencode", "skills", "claudexor"),
1125
+ join(home, ".config", "opencode", "claudexor"),
1126
+ ];
1022
1127
  }
1023
1128
  }
1024
1129
  function artifactStatePathAllowed(def, artifacts, path) {
@@ -1030,7 +1135,9 @@ function removeObsoleteStateArtifacts(def, artifacts, state, dryRun, _force, res
1030
1135
  const hs = hostState(state, def.host);
1031
1136
  const allowed = new Set(artifacts.map((a) => a.path));
1032
1137
  for (const [path, entry] of Object.entries(hs.artifacts)) {
1033
- if (entry.host !== def.host || entry.path !== path || !artifactStatePathAllowed(def, artifacts, path)) {
1138
+ if (entry.host !== def.host ||
1139
+ entry.path !== path ||
1140
+ !artifactStatePathAllowed(def, artifacts, path)) {
1034
1141
  res.errors.push(`${stateFilePath()} contains out-of-scope ${def.host} artifact state for ${path}; remove that state entry or clean it manually`);
1035
1142
  return false;
1036
1143
  }
@@ -1067,7 +1174,9 @@ function removeArtifacts(def, artifacts, state, dryRun, force, res) {
1067
1174
  continue;
1068
1175
  }
1069
1176
  const desired = artifacts.find((a) => a.path === path);
1070
- const owned = hs.artifacts[path]?.hash === hashText(current) || current === desired?.content || (force && hasManagedMarker(current));
1177
+ const owned = hs.artifacts[path]?.hash === hashText(current) ||
1178
+ current === desired?.content ||
1179
+ (force && hasManagedMarker(current));
1071
1180
  if (!owned) {
1072
1181
  res.errors.push(`${path} exists but no longer matches Claudexor ownership state`);
1073
1182
  return false;
@@ -1082,10 +1191,7 @@ function removeArtifacts(def, artifacts, state, dryRun, force, res) {
1082
1191
  pruneEmptyDirs(def.root(userHomeDir()));
1083
1192
  return true;
1084
1193
  }
1085
- function pruneEmptyDirs(_root) {
1086
- // Deliberately conservative: removing files is enough for uninstall; avoid
1087
- // recursive directory cleanup in user config roots.
1088
- }
1194
+ function pruneEmptyDirs(_root) { }
1089
1195
  function removeVerifiedLegacy(def, dryRun, res) {
1090
1196
  for (const legacy of def.legacy(userHomeDir())) {
1091
1197
  if (!existsSync(legacy.path))
@@ -1142,7 +1248,8 @@ async function mcpSelfTest(runtime) {
1142
1248
  const init = lines.find((line) => line && typeof line === "object" && line.id === 1);
1143
1249
  if (init?.result?.serverInfo?.name && !sentToolsList) {
1144
1250
  sentToolsList = true;
1145
- child.stdin.write(JSON.stringify({ jsonrpc: "2.0", method: "notifications/initialized", params: {} }) + "\n");
1251
+ child.stdin.write(JSON.stringify({ jsonrpc: "2.0", method: "notifications/initialized", params: {} }) +
1252
+ "\n");
1146
1253
  child.stdin.write(JSON.stringify({ jsonrpc: "2.0", id: 2, method: "tools/list", params: {} }) + "\n");
1147
1254
  }
1148
1255
  const tools = lines.find((line) => line && typeof line === "object" && line.id === 2);
@@ -1151,7 +1258,8 @@ async function mcpSelfTest(runtime) {
1151
1258
  const listed = tools.result?.tools;
1152
1259
  clearTimeout(timer);
1153
1260
  child.kill("SIGTERM");
1154
- if (Array.isArray(listed) && listed.some((t) => t.name === "claudexor_status")) {
1261
+ if (Array.isArray(listed) &&
1262
+ listed.some((t) => t.name === "claudexor_status")) {
1155
1263
  resolve(null);
1156
1264
  }
1157
1265
  else {
@@ -1168,7 +1276,9 @@ async function mcpSelfTest(runtime) {
1168
1276
  }
1169
1277
  }
1170
1278
  });
1171
- child.stderr.on("data", (d) => { stderr += String(d); });
1279
+ child.stderr.on("data", (d) => {
1280
+ stderr += String(d);
1281
+ });
1172
1282
  child.on("error", (err) => {
1173
1283
  if (settled)
1174
1284
  return;
@@ -1200,7 +1310,16 @@ async function mcpSelfTest(runtime) {
1200
1310
  }
1201
1311
  function mcpSelfTestEnv(runtime) {
1202
1312
  const env = {};
1203
- for (const key of ["HOME", "PATH", "CLAUDEXOR_CONFIG_DIR", "TMPDIR", "TMP", "TEMP", "LANG", "LC_ALL"]) {
1313
+ for (const key of [
1314
+ "HOME",
1315
+ "PATH",
1316
+ "CLAUDEXOR_CONFIG_DIR",
1317
+ "TMPDIR",
1318
+ "TMP",
1319
+ "TEMP",
1320
+ "LANG",
1321
+ "LC_ALL",
1322
+ ]) {
1204
1323
  const value = process.env[key];
1205
1324
  if (value)
1206
1325
  env[key] = value;
@@ -1234,8 +1353,9 @@ async function runHost(def, verb, options, state, runtime) {
1234
1353
  try {
1235
1354
  if (verb === "status" || verb === "doctor") {
1236
1355
  const art = checkArtifacts(def, artifacts, state, res);
1237
- const configOk = checkConfig(def.host, state, res, runtime);
1238
- const hasConfig = def.config !== undefined;
1356
+ const configOk = checkConfig(def.host, state, res, runtime) &&
1357
+ (def.host !== "claude" || manageClaudeStatusline(verb, { ...runtime, dryRun }, res));
1358
+ const hasConfig = def.config !== undefined || def.host === "claude";
1239
1359
  if (res.errors.length > 0 || art.blocked)
1240
1360
  res.state = "blocked";
1241
1361
  else if (art.all && configOk)
@@ -1246,7 +1366,9 @@ async function runHost(def, verb, options, state, runtime) {
1246
1366
  res.state = "partial";
1247
1367
  else
1248
1368
  res.state = "missing";
1249
- if (verb === "doctor" && dryRun && (res.state === "installed" || res.state === "registered")) {
1369
+ if (verb === "doctor" &&
1370
+ dryRun &&
1371
+ (res.state === "installed" || res.state === "registered")) {
1250
1372
  res.actions.push("would run MCP initialize/initialized/tools-list self-test");
1251
1373
  }
1252
1374
  else if (verb === "doctor" && (res.state === "installed" || res.state === "registered")) {
@@ -1263,6 +1385,10 @@ async function runHost(def, verb, options, state, runtime) {
1263
1385
  return res;
1264
1386
  }
1265
1387
  if (verb === "uninstall") {
1388
+ if (def.host === "claude" && !manageClaudeStatusline(verb, { ...runtime, dryRun }, res)) {
1389
+ res.state = "blocked";
1390
+ return res;
1391
+ }
1266
1392
  if (!removeVerifiedLegacy(def, dryRun, res)) {
1267
1393
  res.state = "blocked";
1268
1394
  return res;
@@ -1291,11 +1417,17 @@ async function runHost(def, verb, options, state, runtime) {
1291
1417
  res.state = "blocked";
1292
1418
  return res;
1293
1419
  }
1294
- if (def.config === "codex-marketplace" && !mergeCodexMarketplace(state, dryRun, force, def, runtime, res)) {
1420
+ if (def.config === "codex-marketplace" &&
1421
+ !mergeCodexMarketplace(state, dryRun, force, def, runtime, res)) {
1422
+ res.state = "blocked";
1423
+ return res;
1424
+ }
1425
+ if (def.config === "opencode-mcp" &&
1426
+ !mergeOpenCodeMcp(state, dryRun, force, def, runtime, res)) {
1295
1427
  res.state = "blocked";
1296
1428
  return res;
1297
1429
  }
1298
- if (def.config === "opencode-mcp" && !mergeOpenCodeMcp(state, dryRun, force, def, runtime, res)) {
1430
+ if (def.host === "claude" && !manageClaudeStatusline(verb, { ...runtime, dryRun }, res)) {
1299
1431
  res.state = "blocked";
1300
1432
  return res;
1301
1433
  }