@claudexor/cli 3.1.2 → 3.2.0

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 (235) hide show
  1. package/dist/about-command.d.ts.map +1 -1
  2. package/dist/accounts-projection.d.ts +8 -1
  3. package/dist/accounts-projection.d.ts.map +1 -1
  4. package/dist/accounts-projection.js +33 -20
  5. package/dist/accounts-projection.js.map +1 -1
  6. package/dist/accounts-services.d.ts +206 -0
  7. package/dist/accounts-services.d.ts.map +1 -0
  8. package/dist/accounts-services.js +71 -0
  9. package/dist/accounts-services.js.map +1 -0
  10. package/dist/acp-surface-runner.d.ts +39 -0
  11. package/dist/acp-surface-runner.d.ts.map +1 -1
  12. package/dist/acp-surface-runner.js +104 -30
  13. package/dist/acp-surface-runner.js.map +1 -1
  14. package/dist/attachment-upload.d.ts +5 -0
  15. package/dist/attachment-upload.d.ts.map +1 -0
  16. package/dist/attachment-upload.js +64 -0
  17. package/dist/attachment-upload.js.map +1 -0
  18. package/dist/capabilities.d.ts.map +1 -1
  19. package/dist/capabilities.js +6 -1
  20. package/dist/capabilities.js.map +1 -1
  21. package/dist/choice-input.d.ts +7 -0
  22. package/dist/choice-input.d.ts.map +1 -0
  23. package/dist/choice-input.js +17 -0
  24. package/dist/choice-input.js.map +1 -0
  25. package/dist/claude-oauth-usage.js.map +1 -1
  26. package/dist/claudexord-entry.js.map +1 -1
  27. package/dist/claudexord.d.ts +1 -13
  28. package/dist/claudexord.d.ts.map +1 -1
  29. package/dist/claudexord.js +45 -69
  30. package/dist/claudexord.js.map +1 -1
  31. package/dist/cli-error.d.ts.map +1 -1
  32. package/dist/cli-error.js +21 -11
  33. package/dist/cli-error.js.map +1 -1
  34. package/dist/cli.js +143 -163
  35. package/dist/cli.js.map +1 -1
  36. package/dist/codex-device-login.js.map +1 -1
  37. package/dist/codex-quota-source.js.map +1 -1
  38. package/dist/command-flags.d.ts +16 -1
  39. package/dist/command-flags.d.ts.map +1 -1
  40. package/dist/command-flags.js +41 -19
  41. package/dist/command-flags.js.map +1 -1
  42. package/dist/command-registry.d.ts +21 -8
  43. package/dist/command-registry.d.ts.map +1 -1
  44. package/dist/command-registry.js +59 -116
  45. package/dist/command-registry.js.map +1 -1
  46. package/dist/command-scope.d.ts +13 -0
  47. package/dist/command-scope.d.ts.map +1 -0
  48. package/dist/command-scope.js +61 -0
  49. package/dist/command-scope.js.map +1 -0
  50. package/dist/control-services.d.ts +1631 -1003
  51. package/dist/control-services.d.ts.map +1 -1
  52. package/dist/control-services.js +38 -65
  53. package/dist/control-services.js.map +1 -1
  54. package/dist/credential-commands.d.ts.map +1 -1
  55. package/dist/credential-commands.js +13 -3
  56. package/dist/credential-commands.js.map +1 -1
  57. package/dist/daemon-lifecycle.d.ts.map +1 -1
  58. package/dist/daemon-outcome.d.ts +3 -5
  59. package/dist/daemon-outcome.d.ts.map +1 -1
  60. package/dist/daemon-outcome.js +7 -19
  61. package/dist/daemon-outcome.js.map +1 -1
  62. package/dist/daemon-run.d.ts +21 -12
  63. package/dist/daemon-run.d.ts.map +1 -1
  64. package/dist/daemon-run.js +59 -40
  65. package/dist/daemon-run.js.map +1 -1
  66. package/dist/daemon-runtime-shutdown.d.ts +7 -0
  67. package/dist/daemon-runtime-shutdown.d.ts.map +1 -1
  68. package/dist/daemon-runtime-shutdown.js +29 -0
  69. package/dist/daemon-runtime-shutdown.js.map +1 -1
  70. package/dist/delegation-belt-descriptor.js.map +1 -1
  71. package/dist/delegation-output.d.ts +2 -0
  72. package/dist/delegation-output.d.ts.map +1 -1
  73. package/dist/delegation-output.js +3 -1
  74. package/dist/delegation-output.js.map +1 -1
  75. package/dist/harness-command.d.ts +13 -0
  76. package/dist/harness-command.d.ts.map +1 -0
  77. package/dist/harness-command.js +35 -0
  78. package/dist/harness-command.js.map +1 -0
  79. package/dist/harness-installer.d.ts +79 -0
  80. package/dist/harness-installer.d.ts.map +1 -0
  81. package/dist/harness-installer.js +256 -0
  82. package/dist/harness-installer.js.map +1 -0
  83. package/dist/interaction-prompt.d.ts +19 -0
  84. package/dist/interaction-prompt.d.ts.map +1 -0
  85. package/dist/interaction-prompt.js +114 -0
  86. package/dist/interaction-prompt.js.map +1 -0
  87. package/dist/live.d.ts +2 -6
  88. package/dist/live.d.ts.map +1 -1
  89. package/dist/live.js +88 -75
  90. package/dist/live.js.map +1 -1
  91. package/dist/mcp-daemon-unavailable.d.ts +6 -0
  92. package/dist/mcp-daemon-unavailable.d.ts.map +1 -0
  93. package/dist/mcp-daemon-unavailable.js +16 -0
  94. package/dist/mcp-daemon-unavailable.js.map +1 -0
  95. package/dist/mcp-run-projections.d.ts +29 -0
  96. package/dist/mcp-run-projections.d.ts.map +1 -1
  97. package/dist/mcp-run-projections.js +17 -17
  98. package/dist/mcp-run-projections.js.map +1 -1
  99. package/dist/mcp-runner.d.ts.map +1 -1
  100. package/dist/mcp-runner.js +81 -39
  101. package/dist/mcp-runner.js.map +1 -1
  102. package/dist/native-login.js.map +1 -1
  103. package/dist/ops-command-specs.d.ts +64 -0
  104. package/dist/ops-command-specs.d.ts.map +1 -0
  105. package/dist/ops-command-specs.js +146 -0
  106. package/dist/ops-command-specs.js.map +1 -0
  107. package/dist/ops-commands.d.ts.map +1 -1
  108. package/dist/ops-commands.js +23 -5
  109. package/dist/ops-commands.js.map +1 -1
  110. package/dist/orphan-reaper.js.map +1 -1
  111. package/dist/output-mode.d.ts +11 -0
  112. package/dist/output-mode.d.ts.map +1 -0
  113. package/dist/output-mode.js +28 -0
  114. package/dist/output-mode.js.map +1 -0
  115. package/dist/plan-question-loop.d.ts.map +1 -1
  116. package/dist/plan-question-loop.js +16 -13
  117. package/dist/plan-question-loop.js.map +1 -1
  118. package/dist/plugins.js +1 -1
  119. package/dist/plugins.js.map +1 -1
  120. package/dist/primary-output.d.ts +9 -4
  121. package/dist/primary-output.d.ts.map +1 -1
  122. package/dist/primary-output.js +50 -2
  123. package/dist/primary-output.js.map +1 -1
  124. package/dist/quota-subject-universe.d.ts +6 -0
  125. package/dist/quota-subject-universe.d.ts.map +1 -0
  126. package/dist/quota-subject-universe.js +31 -0
  127. package/dist/quota-subject-universe.js.map +1 -0
  128. package/dist/registry.js.map +1 -1
  129. package/dist/release-command.d.ts +1 -1
  130. package/dist/release-command.js +2 -2
  131. package/dist/remote-command-specs.d.ts +45 -0
  132. package/dist/remote-command-specs.d.ts.map +1 -0
  133. package/dist/remote-command-specs.js +29 -0
  134. package/dist/remote-command-specs.js.map +1 -0
  135. package/dist/remote-command.d.ts +11 -0
  136. package/dist/remote-command.d.ts.map +1 -0
  137. package/dist/remote-command.js +262 -0
  138. package/dist/remote-command.js.map +1 -0
  139. package/dist/remote-filesystem.d.ts +33 -0
  140. package/dist/remote-filesystem.d.ts.map +1 -0
  141. package/dist/remote-filesystem.js +280 -0
  142. package/dist/remote-filesystem.js.map +1 -0
  143. package/dist/repo-asset-authority.js.map +1 -1
  144. package/dist/request-preflight.d.ts +11 -2
  145. package/dist/request-preflight.d.ts.map +1 -1
  146. package/dist/request-preflight.js +36 -13
  147. package/dist/request-preflight.js.map +1 -1
  148. package/dist/retry-command-specs.d.ts.map +1 -1
  149. package/dist/retry-command-specs.js +2 -0
  150. package/dist/retry-command-specs.js.map +1 -1
  151. package/dist/run-applicability.d.ts +74 -0
  152. package/dist/run-applicability.d.ts.map +1 -0
  153. package/dist/run-applicability.js +72 -0
  154. package/dist/run-applicability.js.map +1 -0
  155. package/dist/run-detail-projections.d.ts +23 -0
  156. package/dist/run-detail-projections.d.ts.map +1 -1
  157. package/dist/run-detail-projections.js +32 -1
  158. package/dist/run-detail-projections.js.map +1 -1
  159. package/dist/run-detail-response.d.ts +7 -0
  160. package/dist/run-detail-response.d.ts.map +1 -0
  161. package/dist/run-detail-response.js +23 -0
  162. package/dist/run-detail-response.js.map +1 -0
  163. package/dist/run-facts-projection.d.ts +22 -0
  164. package/dist/run-facts-projection.d.ts.map +1 -0
  165. package/dist/run-facts-projection.js +86 -0
  166. package/dist/run-facts-projection.js.map +1 -0
  167. package/dist/runtime-replacement-stop.d.ts +25 -0
  168. package/dist/runtime-replacement-stop.d.ts.map +1 -0
  169. package/dist/runtime-replacement-stop.js +145 -0
  170. package/dist/runtime-replacement-stop.js.map +1 -0
  171. package/dist/settings-command.d.ts +1 -0
  172. package/dist/settings-command.d.ts.map +1 -1
  173. package/dist/settings-command.js +27 -21
  174. package/dist/settings-command.js.map +1 -1
  175. package/dist/settings-service.d.ts +7 -7
  176. package/dist/settings-service.d.ts.map +1 -1
  177. package/dist/settings-service.js +3 -3
  178. package/dist/settings-service.js.map +1 -1
  179. package/dist/setup-client-pty.d.ts +14 -0
  180. package/dist/setup-client-pty.d.ts.map +1 -0
  181. package/dist/setup-client-pty.js +61 -0
  182. package/dist/setup-client-pty.js.map +1 -0
  183. package/dist/setup-device-code-disclosure.d.ts +15 -0
  184. package/dist/setup-device-code-disclosure.d.ts.map +1 -0
  185. package/dist/setup-device-code-disclosure.js +52 -0
  186. package/dist/setup-device-code-disclosure.js.map +1 -0
  187. package/dist/setup-job-reducer.d.ts.map +1 -1
  188. package/dist/setup-job-reducer.js +1 -0
  189. package/dist/setup-job-reducer.js.map +1 -1
  190. package/dist/setup-job-store.d.ts +275 -75
  191. package/dist/setup-job-store.d.ts.map +1 -1
  192. package/dist/setup-job-store.js.map +1 -1
  193. package/dist/setup-job-support.js.map +1 -1
  194. package/dist/setup-jobs.d.ts +517 -137
  195. package/dist/setup-jobs.d.ts.map +1 -1
  196. package/dist/setup-jobs.js +68 -118
  197. package/dist/setup-jobs.js.map +1 -1
  198. package/dist/setup-lifecycle-binding.d.ts +7 -0
  199. package/dist/setup-lifecycle-binding.d.ts.map +1 -1
  200. package/dist/setup-lifecycle-binding.js +6 -0
  201. package/dist/setup-lifecycle-binding.js.map +1 -1
  202. package/dist/setup-login-child-lifecycle.d.ts +13 -0
  203. package/dist/setup-login-child-lifecycle.d.ts.map +1 -0
  204. package/dist/setup-login-child-lifecycle.js +45 -0
  205. package/dist/setup-login-child-lifecycle.js.map +1 -0
  206. package/dist/setup-login-inline.d.ts +11 -12
  207. package/dist/setup-login-inline.d.ts.map +1 -1
  208. package/dist/setup-login-inline.js +26 -15
  209. package/dist/setup-login-inline.js.map +1 -1
  210. package/dist/setup-login-permit.d.ts +10 -0
  211. package/dist/setup-login-permit.d.ts.map +1 -0
  212. package/dist/setup-login-permit.js +52 -0
  213. package/dist/setup-login-permit.js.map +1 -0
  214. package/dist/setup-login-protocol.d.ts.map +1 -1
  215. package/dist/setup-login-protocol.js +9 -2
  216. package/dist/setup-login-protocol.js.map +1 -1
  217. package/dist/setup-login-runner.d.ts +1 -0
  218. package/dist/setup-login-runner.d.ts.map +1 -1
  219. package/dist/setup-login-runner.js +20 -31
  220. package/dist/setup-login-runner.js.map +1 -1
  221. package/dist/setup-supervisor.d.ts.map +1 -1
  222. package/dist/setup-supervisor.js.map +1 -1
  223. package/dist/terminal-run-output.d.ts +12 -0
  224. package/dist/terminal-run-output.d.ts.map +1 -0
  225. package/dist/terminal-run-output.js +33 -0
  226. package/dist/terminal-run-output.js.map +1 -0
  227. package/dist/thread-execution-workspace.d.ts +15 -0
  228. package/dist/thread-execution-workspace.d.ts.map +1 -1
  229. package/dist/thread-execution-workspace.js +39 -5
  230. package/dist/thread-execution-workspace.js.map +1 -1
  231. package/dist/thread-turn-services.d.ts +104 -0
  232. package/dist/thread-turn-services.d.ts.map +1 -0
  233. package/dist/thread-turn-services.js +27 -0
  234. package/dist/thread-turn-services.js.map +1 -0
  235. package/package.json +23 -23
@@ -1,3 +1,11 @@
1
+ import { type ControlPrimaryOutput as ControlPrimaryOutputType, type RunFailure as RunFailureType } from "@claudexor/schema";
2
+ export type PrimaryOutputPresentation = Pick<ControlPrimaryOutputType, "kind" | "path" | "text"> & {
3
+ truncated?: boolean;
4
+ };
5
+ /** Schema-validate the Control API's single primary-output owner. */
6
+ export declare function projectRunPrimaryOutput(detail: Record<string, unknown> | null): ControlPrimaryOutputType | null;
7
+ /** Inline non-patch output with an honest bounded-preview disclosure. */
8
+ export declare function presentRunPrimaryOutput(output: PrimaryOutputPresentation | null): string | null;
1
9
  export type ApplyEligibilityProjection = {
2
10
  eligible: boolean;
3
11
  state: string | null;
@@ -7,10 +15,25 @@ export type ApplyEligibilityProjection = {
7
15
  export declare function projectApplyEligibility(detail: Record<string, unknown> | null): ApplyEligibilityProjection | null;
8
16
  export declare function projectRunSpendUsd(detail: Record<string, unknown> | null): number | null;
9
17
  export declare function projectRunCouncil(detail: Record<string, unknown> | null): unknown;
18
+ /** Preserve only the schema-owned typed terminal failure. Every surface uses
19
+ * this projection instead of forwarding an arbitrary failure-shaped object. */
20
+ export declare function projectRunFailure(detail: Record<string, unknown> | null): RunFailureType | null;
10
21
  export declare function projectRunLineage(detail: Record<string, unknown> | null): {
11
22
  parentRunId: string | null;
12
23
  delegatedFromRunId: string | null;
13
24
  delegation: Record<string, unknown> | null;
14
25
  };
15
26
  export declare function projectOutcomeBanner(detail: Record<string, unknown> | null): string | null;
27
+ /** Typed description of a raised post-terminal run-detail problem for surfaces
28
+ * that must DEGRADE instead of failing the caller (MCP results, ACP turn
29
+ * results, --json outcome projections): the finished run's result survives with
30
+ * its runId, and this field discloses WHY its detail projections are absent.
31
+ * The CLI's own terminal path keeps the raise (renderCliFailure, non-zero
32
+ * exit) — there the run result IS the process outcome. */
33
+ export interface RunDetailProblem {
34
+ code: string | null;
35
+ message: string;
36
+ retryable: boolean | null;
37
+ }
38
+ export declare function describeRunDetailProblem(error: unknown): RunDetailProblem;
16
39
  //# sourceMappingURL=run-detail-projections.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"run-detail-projections.d.ts","sourceRoot":"","sources":["../src/run-detail-projections.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GACrC,0BAA0B,GAAG,IAAI,CAGnC;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAOxF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,OAAO,CAGjF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG;IACzE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC5C,CAcA;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAG1F"}
1
+ {"version":3,"file":"run-detail-projections.d.ts","sourceRoot":"","sources":["../src/run-detail-projections.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,oBAAoB,IAAI,wBAAwB,EACrD,KAAK,UAAU,IAAI,cAAc,EAClC,MAAM,mBAAmB,CAAC;AAG3B,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAAC,wBAAwB,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG;IACjG,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,qEAAqE;AACrE,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GACrC,wBAAwB,GAAG,IAAI,CAGjC;AAED,yEAAyE;AACzE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,yBAAyB,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAO/F;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GACrC,0BAA0B,GAAG,IAAI,CAGnC;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAOxF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,OAAO,CAGjF;AAED;+EAC+E;AAC/E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,cAAc,GAAG,IAAI,CAG/F;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG;IACzE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC5C,CAcA;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAG1F;AAED;;;;;0DAK0D;AAC1D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAOzE"}
@@ -1,4 +1,21 @@
1
- import { CouncilProjection } from "@claudexor/schema";
1
+ import { ControlPrimaryOutput, CouncilProjection, RunFailure, } from "@claudexor/schema";
2
+ import { redactSecrets } from "@claudexor/util";
3
+ /** Schema-validate the Control API's single primary-output owner. */
4
+ export function projectRunPrimaryOutput(detail) {
5
+ const parsed = ControlPrimaryOutput.safeParse(detail?.["primaryOutput"]);
6
+ return parsed.success ? parsed.data : null;
7
+ }
8
+ /** Inline non-patch output with an honest bounded-preview disclosure. */
9
+ export function presentRunPrimaryOutput(output) {
10
+ if (!output || output.kind === "patch" || typeof output.text !== "string")
11
+ return null;
12
+ const text = output.text.trim();
13
+ if (!text)
14
+ return null;
15
+ return output.truncated === true
16
+ ? `${text}\n\n[Inline preview bounded; full artifact: ${output.path}]`
17
+ : text;
18
+ }
2
19
  export function projectApplyEligibility(detail) {
3
20
  const value = detail?.["applyEligibility"];
4
21
  return value && typeof value === "object" ? value : null;
@@ -14,6 +31,12 @@ export function projectRunCouncil(detail) {
14
31
  const parsed = CouncilProjection.safeParse(detail?.["council"]);
15
32
  return parsed.success ? parsed.data : null;
16
33
  }
34
+ /** Preserve only the schema-owned typed terminal failure. Every surface uses
35
+ * this projection instead of forwarding an arbitrary failure-shaped object. */
36
+ export function projectRunFailure(detail) {
37
+ const parsed = RunFailure.safeParse(detail?.["failure"]);
38
+ return parsed.success ? parsed.data : null;
39
+ }
17
40
  export function projectRunLineage(detail) {
18
41
  const summary = detail?.["summary"] && typeof detail["summary"] === "object"
19
42
  ? detail["summary"]
@@ -30,4 +53,12 @@ export function projectOutcomeBanner(detail) {
30
53
  const banner = detail?.["outcomeBanner"];
31
54
  return typeof banner === "string" && banner.length > 0 ? banner : null;
32
55
  }
56
+ export function describeRunDetailProblem(error) {
57
+ const record = error && typeof error === "object" ? error : {};
58
+ return {
59
+ code: typeof record["code"] === "string" && record["code"] ? record["code"] : null,
60
+ message: redactSecrets(error instanceof Error ? error.message : String(error)),
61
+ retryable: typeof record["retryable"] === "boolean" ? record["retryable"] : null,
62
+ };
63
+ }
33
64
  //# sourceMappingURL=run-detail-projections.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"run-detail-projections.js","sourceRoot":"","sources":["../src/run-detail-projections.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAStD,MAAM,UAAU,uBAAuB,CACrC,MAAsC;IAEtC,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,kBAAkB,CAAC,CAAC;IAC3C,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAE,KAAoC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3F,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAsC;IACvE,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC;IACpC,MAAM,KAAK,GACT,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ;QACpC,CAAC,CAAE,OAAkC,CAAC,QAAQ;QAC9C,CAAC,CAAC,SAAS,CAAC;IAChB,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAsC;IACtE,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAChE,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAsC;IAKtE,MAAM,OAAO,GACX,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,QAAQ;QAC1D,CAAC,CAAE,MAAM,CAAC,SAAS,CAA6B;QAChD,CAAC,CAAC,IAAI,CAAC;IACX,OAAO;QACL,WAAW,EAAE,OAAO,OAAO,EAAE,CAAC,aAAa,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI;QACzF,kBAAkB,EAChB,OAAO,OAAO,EAAE,CAAC,oBAAoB,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,IAAI;QAC5F,UAAU,EACR,OAAO,EAAE,CAAC,YAAY,CAAC,IAAI,OAAO,OAAO,CAAC,YAAY,CAAC,KAAK,QAAQ;YAClE,CAAC,CAAE,OAAO,CAAC,YAAY,CAA6B;YACpD,CAAC,CAAC,IAAI;KACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAsC;IACzE,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,eAAe,CAAC,CAAC;IACzC,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACzE,CAAC"}
1
+ {"version":3,"file":"run-detail-projections.js","sourceRoot":"","sources":["../src/run-detail-projections.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ type JsonResponse = {
2
+ json(): Promise<unknown>;
3
+ };
4
+ /** Decode and schema-check a successful Control API run-detail response. */
5
+ export declare function readRunDetailResponse(response: JsonResponse): Promise<Record<string, unknown>>;
6
+ export {};
7
+ //# sourceMappingURL=run-detail-response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-detail-response.d.ts","sourceRoot":"","sources":["../src/run-detail-response.ts"],"names":[],"mappings":"AAGA,KAAK,YAAY,GAAG;IAAE,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,CAAC;AAEjD,4EAA4E;AAC5E,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,YAAY,GACrB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAWlC"}
@@ -0,0 +1,23 @@
1
+ import { ControlRunDetail } from "@claudexor/schema";
2
+ import { CliError } from "./cli-error.js";
3
+ /** Decode and schema-check a successful Control API run-detail response. */
4
+ export async function readRunDetailResponse(response) {
5
+ let body;
6
+ try {
7
+ body = await response.json();
8
+ }
9
+ catch {
10
+ throw invalidRunDetailResponse("run detail endpoint returned malformed JSON");
11
+ }
12
+ if (!ControlRunDetail.safeParse(body).success) {
13
+ throw invalidRunDetailResponse("run detail endpoint returned an invalid response");
14
+ }
15
+ return body;
16
+ }
17
+ function invalidRunDetailResponse(message) {
18
+ return new CliError("operational", message, {
19
+ code: "invalid_service_response",
20
+ retryable: true,
21
+ });
22
+ }
23
+ //# sourceMappingURL=run-detail-response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-detail-response.js","sourceRoot":"","sources":["../src/run-detail-response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAI1C,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,QAAsB;IAEtB,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,wBAAwB,CAAC,6CAA6C,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QAC9C,MAAM,wBAAwB,CAAC,kDAAkD,CAAC,CAAC;IACrF,CAAC;IACD,OAAO,IAA+B,CAAC;AACzC,CAAC;AAED,SAAS,wBAAwB,CAAC,OAAe;IAC/C,OAAO,IAAI,QAAQ,CAAC,aAAa,EAAE,OAAO,EAAE;QAC1C,IAAI,EAAE,0BAA0B;QAChC,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { type ExpectedRunFactsIdentity, type RunFacts as RunFactsType } from "@claudexor/schema";
2
+ import { type ApplyEligibilityProjection } from "./run-detail-projections.js";
3
+ type RunDetail = Record<string, unknown> | null;
4
+ export type { ExpectedRunFactsIdentity } from "@claudexor/schema";
5
+ /** Exact validated terminal receipt from an already-fetched run detail. */
6
+ export declare function projectRunFacts(detail: RunDetail, expected?: ExpectedRunFactsIdentity): RunFactsType | null;
7
+ /**
8
+ * Shared fields appended to both terminal machine surfaces. RunFacts is
9
+ * intentionally always present; only a genuinely missing legacy receipt
10
+ * projects to null, while present malformed data fails loudly.
11
+ */
12
+ export declare function projectTerminalDetailFields(detail: RunDetail, expected?: ExpectedRunFactsIdentity): {
13
+ outcomeBanner?: string;
14
+ applyEligibility?: ApplyEligibilityProjection;
15
+ runFacts: RunFactsType | null;
16
+ };
17
+ type YamlArtifactReader = {
18
+ readYaml(path: string): unknown;
19
+ };
20
+ /** Read the canonical immutable RunFacts artifact without reconstructing it. */
21
+ export declare function readRunFactsArtifact(reader: YamlArtifactReader, finalDir: string, expected?: ExpectedRunFactsIdentity): RunFactsType | null;
22
+ //# sourceMappingURL=run-facts-projection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-facts-projection.d.ts","sourceRoot":"","sources":["../src/run-facts-projection.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,IAAI,YAAY,EAC9B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAGL,KAAK,0BAA0B,EAChC,MAAM,6BAA6B,CAAC;AAErC,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;AAKhD,YAAY,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAElE,2EAA2E;AAC3E,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,wBAA6B,GACtC,YAAY,GAAG,IAAI,CAKrB;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,wBAA6B,GACtC;IACD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,0BAA0B,CAAC;IAC9C,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;CAC/B,CAQA;AAED,KAAK,kBAAkB,GAAG;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC,CAAC;AAEF,gFAAgF;AAChF,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,wBAA6B,GACtC,YAAY,GAAG,IAAI,CAmBrB"}
@@ -0,0 +1,86 @@
1
+ import { lstatSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { RunFactsInvalidError, validateRunFactsReceipt, } from "@claudexor/schema";
4
+ import { projectApplyEligibility, projectOutcomeBanner, } from "./run-detail-projections.js";
5
+ /** Exact validated terminal receipt from an already-fetched run detail. */
6
+ export function projectRunFacts(detail, expected = {}) {
7
+ if (!detail)
8
+ return null;
9
+ const value = detail["runFacts"];
10
+ if (value === null || value === undefined)
11
+ return null;
12
+ return validateRunFactsReceipt(value, expectedIdentityFromDetail(detail, expected));
13
+ }
14
+ /**
15
+ * Shared fields appended to both terminal machine surfaces. RunFacts is
16
+ * intentionally always present; only a genuinely missing legacy receipt
17
+ * projects to null, while present malformed data fails loudly.
18
+ */
19
+ export function projectTerminalDetailFields(detail, expected = {}) {
20
+ const outcomeBanner = projectOutcomeBanner(detail);
21
+ const applyEligibility = projectApplyEligibility(detail);
22
+ return {
23
+ ...(outcomeBanner ? { outcomeBanner } : {}),
24
+ ...(applyEligibility ? { applyEligibility } : {}),
25
+ runFacts: projectRunFacts(detail, expected),
26
+ };
27
+ }
28
+ /** Read the canonical immutable RunFacts artifact without reconstructing it. */
29
+ export function readRunFactsArtifact(reader, finalDir, expected = {}) {
30
+ const path = join(finalDir, "run_facts.yaml");
31
+ const finalDirStat = lstatOrNull(finalDir);
32
+ if (finalDirStat === null)
33
+ return null;
34
+ if (!finalDirStat.isDirectory() || finalDirStat.isSymbolicLink()) {
35
+ throw new RunFactsInvalidError();
36
+ }
37
+ const artifactStat = lstatOrNull(path);
38
+ if (artifactStat === null)
39
+ return null;
40
+ if (!artifactStat.isFile() || artifactStat.isSymbolicLink())
41
+ throw new RunFactsInvalidError();
42
+ let raw;
43
+ try {
44
+ raw = reader.readYaml(path);
45
+ }
46
+ catch {
47
+ throw new RunFactsInvalidError();
48
+ }
49
+ return validateRunFactsReceipt(raw, expected);
50
+ }
51
+ function expectedIdentityFromDetail(detail, expected) {
52
+ const summary = detail["summary"];
53
+ if (!summary || typeof summary !== "object")
54
+ return expected;
55
+ const record = summary;
56
+ const summaryRunId = typeof record["runId"] === "string" ? record["runId"] : undefined;
57
+ const summaryTaskId = typeof record["taskId"] === "string" ? record["taskId"] : undefined;
58
+ if ((expected.runId !== undefined &&
59
+ summaryRunId !== undefined &&
60
+ expected.runId !== summaryRunId) ||
61
+ (expected.taskId !== undefined &&
62
+ summaryTaskId !== undefined &&
63
+ expected.taskId !== summaryTaskId)) {
64
+ throw new RunFactsInvalidError();
65
+ }
66
+ return {
67
+ runId: expected.runId ?? summaryRunId,
68
+ taskId: expected.taskId ?? summaryTaskId,
69
+ ...(expected.lifecycle !== undefined ? { lifecycle: expected.lifecycle } : {}),
70
+ };
71
+ }
72
+ function lstatOrNull(path) {
73
+ try {
74
+ return lstatSync(path);
75
+ }
76
+ catch (error) {
77
+ if (error &&
78
+ typeof error === "object" &&
79
+ "code" in error &&
80
+ error.code === "ENOENT") {
81
+ return null;
82
+ }
83
+ throw new RunFactsInvalidError();
84
+ }
85
+ }
86
+ //# sourceMappingURL=run-facts-projection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-facts-projection.js","sourceRoot":"","sources":["../src/run-facts-projection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { type AwaitDaemonTerminationOptions, type DaemonTerminationOutcome, type DaemonLeaseOwner, DaemonClient, awaitDaemonTermination } from "@claudexor/daemon";
2
+ interface RuntimeReplacementStopDeps {
3
+ socketPath(): string;
4
+ readToken(): string | null;
5
+ socketAlive(path: string): Promise<boolean>;
6
+ leaseOwner(path: string): DaemonLeaseOwner | null;
7
+ client(path: string, token: string): Pick<DaemonClient, "shutdownForRuntimeReplacement">;
8
+ awaitTermination(path: string, options: AwaitDaemonTerminationOptions): ReturnType<typeof awaitDaemonTermination>;
9
+ write(line: string): void;
10
+ }
11
+ /** One owner for the admission/termination uncertainty boundary used by both
12
+ * local and remote runtime replacement. Only a proven
13
+ * `{ok:true,fenced:true,targetBound:true}` receipt grants
14
+ * signal authority for the pre-RPC writer-lease owner.
15
+ * A lost, legacy, or untyped response may passively prove that the pinned
16
+ * daemon exited, but can never turn into a kill. */
17
+ export declare function admitAndAwaitRuntimeReplacementStop(requestAdmission: () => Promise<unknown>, awaitTermination: (options: AwaitDaemonTerminationOptions) => Promise<DaemonTerminationOutcome>, expectedOwner: DaemonLeaseOwner): Promise<DaemonTerminationOutcome>;
18
+ /** Handle `claudexord --stop`: the identity-proven, admission-safe shutdown the
19
+ * macOS installer runs before an atomic pointer swap. Unlike explicit operator
20
+ * shutdown, this asks the daemon to atomically prove idle and fence every ingress
21
+ * before stopping. The pinned termination proof remains authoritative when the
22
+ * accepted RPC response is lost as the socket closes. */
23
+ export declare function runStopIfRequested(argv: readonly string[], deps?: RuntimeReplacementStopDeps): Promise<boolean>;
24
+ export {};
25
+ //# sourceMappingURL=runtime-replacement-stop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-replacement-stop.d.ts","sourceRoot":"","sources":["../src/runtime-replacement-stop.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,6BAA6B,EAClC,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,EACrB,YAAY,EAGZ,sBAAsB,EAIvB,MAAM,mBAAmB,CAAC;AAE3B,UAAU,0BAA0B;IAClC,UAAU,IAAI,MAAM,CAAC;IACrB,SAAS,IAAI,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAAC;IAClD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,+BAA+B,CAAC,CAAC;IACzF,gBAAgB,CACd,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,6BAA6B,GACrC,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;IAC7C,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAoED;;;;;oDAKoD;AACpD,wBAAsB,mCAAmC,CACvD,gBAAgB,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EACxC,gBAAgB,EAAE,CAAC,OAAO,EAAE,6BAA6B,KAAK,OAAO,CAAC,wBAAwB,CAAC,EAC/F,aAAa,EAAE,gBAAgB,GAC9B,OAAO,CAAC,wBAAwB,CAAC,CAgCnC;AAED;;;;yDAIyD;AACzD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,IAAI,GAAE,0BAA2C,GAChD,OAAO,CAAC,OAAO,CAAC,CAwElB"}
@@ -0,0 +1,145 @@
1
+ import { DaemonClient, daemonLeaseOwner, awaitDaemonTermination, defaultSocketPath, readToken, socketAlive, } from "@claudexor/daemon";
2
+ const productionDeps = {
3
+ socketPath: defaultSocketPath,
4
+ readToken,
5
+ socketAlive,
6
+ leaseOwner: daemonLeaseOwner,
7
+ client: (path, token) => new DaemonClient(path, token),
8
+ awaitTermination: awaitDaemonTermination,
9
+ write: (line) => process.stdout.write(line),
10
+ };
11
+ function refusalCode(error) {
12
+ if (!error || typeof error !== "object" || !("code" in error))
13
+ return null;
14
+ const code = error.code;
15
+ return code === "runtime_replacement_busy" || code === "runtime_activity_unknown" ? code : null;
16
+ }
17
+ function activityUnknown(message, cause) {
18
+ return Object.assign(new Error(message), {
19
+ code: "runtime_activity_unknown",
20
+ status: 503,
21
+ retryable: true,
22
+ ...(cause === undefined ? {} : { cause }),
23
+ });
24
+ }
25
+ function isTargetBoundAdmissionReceipt(value) {
26
+ return (!!value &&
27
+ typeof value === "object" &&
28
+ value.ok === true &&
29
+ value.fenced === true &&
30
+ value.targetBound === true);
31
+ }
32
+ function stopIdentity(argv) {
33
+ const stop = argv.indexOf("--stop");
34
+ if (stop < 0 || argv.length !== stop + 3)
35
+ return null;
36
+ const version = argv[stop + 1];
37
+ const buildSha = argv[stop + 2];
38
+ if (typeof version !== "string" ||
39
+ version.length === 0 ||
40
+ typeof buildSha !== "string" ||
41
+ !/^[0-9a-f]{40}$/.test(buildSha)) {
42
+ return null;
43
+ }
44
+ return { version, buildSha };
45
+ }
46
+ function writeRefusal(deps, code, detail) {
47
+ deps.write(`${JSON.stringify({ stopped: false, code, retryable: true, detail })}\n`);
48
+ process.exitCode = 1;
49
+ }
50
+ /** One owner for the admission/termination uncertainty boundary used by both
51
+ * local and remote runtime replacement. Only a proven
52
+ * `{ok:true,fenced:true,targetBound:true}` receipt grants
53
+ * signal authority for the pre-RPC writer-lease owner.
54
+ * A lost, legacy, or untyped response may passively prove that the pinned
55
+ * daemon exited, but can never turn into a kill. */
56
+ export async function admitAndAwaitRuntimeReplacementStop(requestAdmission, awaitTermination, expectedOwner) {
57
+ let admitted = false;
58
+ let admissionFailure;
59
+ try {
60
+ const receipt = await requestAdmission();
61
+ if (isTargetBoundAdmissionReceipt(receipt)) {
62
+ admitted = true;
63
+ }
64
+ else {
65
+ // A pre-v3.2 daemon can accept the same method while ignoring its new
66
+ // identity parameters and return the legacy fenced receipt. It may still
67
+ // exit naturally, but it never grants signal authority to the caller.
68
+ admissionFailure = activityUnknown("runtime replacement returned no identity-bound admission receipt");
69
+ }
70
+ }
71
+ catch (error) {
72
+ if (refusalCode(error))
73
+ throw error;
74
+ admissionFailure = error;
75
+ }
76
+ const termination = await awaitTermination({
77
+ allowSigkill: admitted,
78
+ expectedOwner,
79
+ requireNoSuccessor: true,
80
+ });
81
+ if (!admitted && termination.outcome !== "exited") {
82
+ throw activityUnknown(`runtime replacement admission is uncertain and the daemon remains alive: ${termination.detail}`, admissionFailure);
83
+ }
84
+ return termination;
85
+ }
86
+ /** Handle `claudexord --stop`: the identity-proven, admission-safe shutdown the
87
+ * macOS installer runs before an atomic pointer swap. Unlike explicit operator
88
+ * shutdown, this asks the daemon to atomically prove idle and fence every ingress
89
+ * before stopping. The pinned termination proof remains authoritative when the
90
+ * accepted RPC response is lost as the socket closes. */
91
+ export async function runStopIfRequested(argv, deps = productionDeps) {
92
+ if (!argv.includes("--stop"))
93
+ return false;
94
+ const expectedIdentity = stopIdentity(argv);
95
+ if (!expectedIdentity) {
96
+ writeRefusal(deps, "runtime_activity_unknown", "runtime replacement requires an exact expected version and build SHA");
97
+ return true;
98
+ }
99
+ const socketPath = deps.socketPath();
100
+ const alive = await deps.socketAlive(socketPath);
101
+ if (!alive) {
102
+ // A daemon claims the writer lease before it binds the socket. Treating the
103
+ // boot window as absence would let the installer move the runtime pointer
104
+ // beneath that live process. Idempotent success therefore requires both
105
+ // surfaces to prove absence, matching the remote replacement path.
106
+ if (deps.leaseOwner(socketPath)) {
107
+ writeRefusal(deps, "runtime_activity_unknown", "runtime replacement found a writer lease but no reachable daemon socket");
108
+ return true;
109
+ }
110
+ deps.write(`${JSON.stringify({ stopped: true, alreadyStopped: true })}\n`);
111
+ return true;
112
+ }
113
+ const token = deps.readToken();
114
+ if (!token) {
115
+ writeRefusal(deps, "runtime_activity_unknown", "runtime replacement cannot authenticate to the live daemon");
116
+ return true;
117
+ }
118
+ const expectedOwner = deps.leaseOwner(socketPath);
119
+ if (!expectedOwner) {
120
+ writeRefusal(deps, "runtime_activity_unknown", "runtime replacement cannot bind the live daemon to its writer lease");
121
+ return true;
122
+ }
123
+ const expectedTarget = {
124
+ ...expectedIdentity,
125
+ leaseOwner: { pid: expectedOwner.pid, token: expectedOwner.token },
126
+ };
127
+ let termination;
128
+ try {
129
+ termination = await admitAndAwaitRuntimeReplacementStop(() => deps.client(socketPath, token).shutdownForRuntimeReplacement(expectedTarget), (options) => deps.awaitTermination(socketPath, options), expectedOwner);
130
+ }
131
+ catch (error) {
132
+ const code = refusalCode(error);
133
+ if (code) {
134
+ writeRefusal(deps, code, error.message);
135
+ return true;
136
+ }
137
+ throw error;
138
+ }
139
+ const stopped = termination.outcome !== "still_alive";
140
+ deps.write(`${JSON.stringify({ stopped, outcome: termination.outcome, detail: termination.detail })}\n`);
141
+ if (!stopped)
142
+ process.exitCode = 1;
143
+ return true;
144
+ }
145
+ //# sourceMappingURL=runtime-replacement-stop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-replacement-stop.js","sourceRoot":"","sources":["../src/runtime-replacement-stop.ts"],"names":[],"mappings":"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"}
@@ -38,4 +38,5 @@ export declare const HARNESS_SETTING_FIELDS: {
38
38
  };
39
39
  export declare function settingsCommand(args: ParsedArgs, json: boolean): Promise<number>;
40
40
  export declare function settingPatch(key: string, value: string): SettingsPatch;
41
+ export declare function formatInteractionTimeoutSetting(value: number | null): string;
41
42
  //# sourceMappingURL=settings-command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"settings-command.d.ts","sourceRoot":"","sources":["../src/settings-command.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,OAAO,EAGL,KAAK,4BAA4B,IAAI,aAAa,EACnD,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAM5C;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;CAUxB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;CAazB,CAAC;AAWX,wBAAsB,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAsBtF;AAsFD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,CA2DtE"}
1
+ {"version":3,"file":"settings-command.d.ts","sourceRoot":"","sources":["../src/settings-command.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,OAAO,EAGL,KAAK,4BAA4B,IAAI,aAAa,EACnD,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAM5C;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB;aAChC,YAAY,EAAE,aAAa;aAC3B,aAAa,EAAE,cAAc;aAC7B,aAAa,EAAE,cAAc;aAC7B,sBAAsB,EAAE,sBAAsB;aAC9C,eAAe,EAAE,gBAAgB;aACjC,kBAAkB,EAAE,mBAAmB;aACvC,eAAe,EAAE,gBAAgB;aACjC,mBAAmB,EAAE,kBAAkB;aACvC,eAAe,EAAE,gBAAgB;CACzB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,sBAAsB;aACjC,OAAO,EAAE,SAAS;aAClB,0BAA0B,EAAE,0BAA0B;aACtD,aAAa,EAAE,cAAc;aAC7B,cAAc,EAAE,eAAe;aAC/B,MAAM,EAAE,QAAQ;aAChB,SAAS,EAAE,UAAU;aACrB,UAAU,EAAE,WAAW;aACvB,WAAW,EAAE,YAAY;aACzB,UAAU,EAAE,WAAW;aACvB,GAAG,EAAE,KAAK;aACV,eAAe,EAAE,gBAAgB;aACjC,oBAAoB,EAAE,oBAAoB;CAClC,CAAC;AAYX,wBAAsB,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BtF;AAmFD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,CA8DtE;AAkCD,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE5E"}
@@ -1,7 +1,7 @@
1
1
  /** `claudexor settings` is a thin projection of the daemon-owned /v2/settings surface. */
2
2
  import { ControlSettingsSnapshot, ControlSettingsUpdateRequest, } from "@claudexor/schema";
3
3
  import { print, printJson, printUsageError } from "./cli-io.js";
4
- import { renderCliFailure } from "./cli-error.js";
4
+ import { controlProblemError, renderCliFailure, usageError } from "./cli-error.js";
5
5
  import { ensureDaemon } from "./daemon-run.js";
6
6
  import { controlApiFetch } from "./live.js";
7
7
  /**
@@ -42,12 +42,21 @@ export const HARNESS_SETTING_FIELDS = {
42
42
  const HARNESS_KEY_RE = new RegExp(`^harness\\.([^.]+)\\.(${Object.keys(HARNESS_SETTING_FIELDS).join("|")})$`);
43
43
  const USAGE = "usage: claudexor settings set <key> <value>\n" +
44
44
  ` global keys: ${Object.keys(GLOBAL_SETTING_FIELDS).join(", ")}\n` +
45
+ " interaction_timeout_ms: positive milliseconds or disabled\n" +
45
46
  ` harness keys: harness.<id>.{${Object.keys(HARNESS_SETTING_FIELDS).join(",")}}`;
46
47
  export async function settingsCommand(args, json) {
47
48
  const sub = args._[1] ?? "show";
48
49
  if (sub !== "show" && sub !== "set")
49
50
  return printUsageError(json, "usage: claudexor settings show|set");
51
+ const key = args._[2];
52
+ const value = args._[3];
53
+ if (sub === "set" && (!key || value === undefined))
54
+ return printUsageError(json, USAGE);
50
55
  try {
56
+ // Validate caller-owned input before daemon bootstrap. A bad key/value is a
57
+ // usage failure even when the engine is offline; starting the daemon cannot
58
+ // make malformed input valid.
59
+ const patch = sub === "set" ? settingPatch(key, value) : undefined;
51
60
  const { addr } = await ensureDaemon();
52
61
  if (sub === "show") {
53
62
  const snapshot = await settingsRequest(addr, "GET");
@@ -57,11 +66,7 @@ export async function settingsCommand(args, json) {
57
66
  printSettings(snapshot);
58
67
  return 0;
59
68
  }
60
- const key = args._[2];
61
- const value = args._[3];
62
- if (!key || value === undefined)
63
- return printUsageError(json, USAGE);
64
- const snapshot = await settingsRequest(addr, "POST", settingPatch(key, value));
69
+ const snapshot = await settingsRequest(addr, "POST", patch);
65
70
  if (json)
66
71
  printJson(snapshot);
67
72
  else
@@ -90,12 +95,7 @@ async function settingsRequest(addr, method, body) {
90
95
  throw new Error(`settings endpoint returned invalid JSON (HTTP ${response.status})`);
91
96
  }
92
97
  if (!response.ok) {
93
- const detail = value;
94
- throw new Error(typeof detail["message"] === "string"
95
- ? detail["message"]
96
- : typeof detail["error"] === "string"
97
- ? detail["error"]
98
- : `settings request failed (HTTP ${response.status})`);
98
+ throw controlProblemError(response.status, value, `settings request failed (HTTP ${response.status})`);
99
99
  }
100
100
  return ControlSettingsSnapshot.parse(value);
101
101
  }
@@ -107,12 +107,12 @@ function harnessFieldPatch(field, value) {
107
107
  switch (field) {
108
108
  case "enabled": {
109
109
  if (value !== "true" && value !== "false")
110
- throw new Error("harness enabled must be true or false");
110
+ throw usageError("harness enabled must be true or false");
111
111
  return { enabled: value === "true" };
112
112
  }
113
113
  case "native_credentials_enabled": {
114
114
  if (value !== "true" && value !== "false")
115
- throw new Error("harness native_credentials_enabled must be true or false");
115
+ throw usageError("harness native_credentials_enabled must be true or false");
116
116
  return { nativeCredentialsEnabled: value === "true" };
117
117
  }
118
118
  case "default_model":
@@ -128,7 +128,7 @@ function harnessFieldPatch(field, value) {
128
128
  return { [patchKey]: null };
129
129
  const n = Number(value.trim());
130
130
  if (!Number.isInteger(n) || n <= 0)
131
- throw new Error(`harness ${field} must be a positive integer or none`);
131
+ throw usageError(`harness ${field} must be a positive integer or none`);
132
132
  return { [patchKey]: n };
133
133
  }
134
134
  case "tools_allow":
@@ -152,7 +152,7 @@ function harnessFieldPatch(field, value) {
152
152
  }
153
153
  export function settingPatch(key, value) {
154
154
  if (key === "default_model") {
155
- throw new Error("the global default_model setting was removed (model choice is harness-scoped, INV-103); use `claudexor settings set harness.<id>.default_model <model>`");
155
+ throw usageError("the global default_model setting was removed (model choice is harness-scoped, INV-103); use `claudexor settings set harness.<id>.default_model <model>`");
156
156
  }
157
157
  const harness = HARNESS_KEY_RE.exec(key);
158
158
  if (harness) {
@@ -163,7 +163,7 @@ export function settingPatch(key, value) {
163
163
  });
164
164
  }
165
165
  if (key === "default_portfolio") {
166
- throw new Error("default_portfolio was removed in v2; use routing_goal");
166
+ throw usageError("default_portfolio was removed in v2; use routing_goal");
167
167
  }
168
168
  if (key === "routing_goal")
169
169
  return ControlSettingsUpdateRequest.parse({ routingGoal: value });
@@ -177,7 +177,7 @@ export function settingPatch(key, value) {
177
177
  qualityTiers = JSON.parse(value);
178
178
  }
179
179
  catch {
180
- throw new Error("quality_tiers must be a JSON object of per-intent ordered tiers");
180
+ throw usageError("quality_tiers must be a JSON object of per-intent ordered tiers");
181
181
  }
182
182
  return ControlSettingsUpdateRequest.parse({ qualityTiers });
183
183
  }
@@ -199,16 +199,19 @@ export function settingPatch(key, value) {
199
199
  return ControlSettingsUpdateRequest.parse({ paidBudgetPerRun: { kind: "unlimited" } });
200
200
  const maxUsd = Number(value.trim());
201
201
  if (!Number.isFinite(maxUsd) || maxUsd < 0 || value.trim() === "")
202
- throw new Error(`${key} must be a non-negative number or unlimited`);
202
+ throw usageError(`${key} must be a non-negative number or unlimited`);
203
203
  return ControlSettingsUpdateRequest.parse({
204
204
  paidBudgetPerRun: { kind: "finite", maxUsd },
205
205
  });
206
206
  }
207
207
  if (key === "interaction_timeout_ms") {
208
+ if (value.trim() === "disabled") {
209
+ return ControlSettingsUpdateRequest.parse({ interactionTimeoutMs: null });
210
+ }
208
211
  const interactionTimeoutMs = Number(value.trim());
209
212
  return ControlSettingsUpdateRequest.parse({ interactionTimeoutMs });
210
213
  }
211
- throw new Error(`unknown setting: ${key}`);
214
+ throw usageError(`unknown setting: ${key}`);
212
215
  }
213
216
  function printSettings(settings) {
214
217
  print(`sources: ${settings.sources.length ? settings.sources.join(", ") : "(defaults)"}`);
@@ -219,7 +222,7 @@ function printSettings(settings) {
219
222
  print(`routing.env_inheritance: ${settings.routing.envInheritance}`);
220
223
  print(`routing.auth_preference: ${settings.routing.authPreference}`);
221
224
  print(`budget.paid_budget_per_run: ${settings.budget.paidBudgetPerRun.kind === "unlimited" ? "unlimited" : settings.budget.paidBudgetPerRun.maxUsd}`);
222
- print(`interaction_timeout_ms: ${settings.interactionTimeoutMs}`);
225
+ print(`interaction_timeout_ms: ${formatInteractionTimeoutSetting(settings.interactionTimeoutMs)}`);
223
226
  print(`runtime.reviewer_timeout_ms: ${settings.runtime.reviewerTimeoutMs}`);
224
227
  print(`runtime.transient_retry.max_retries: ${settings.runtime.transientRetry.maxRetries}`);
225
228
  print(`runtime.transient_retry.initial_delay_ms: ${settings.runtime.transientRetry.initialDelayMs}`);
@@ -232,4 +235,7 @@ function printSettings(settings) {
232
235
  print(` ${id}: enabled=${harness.enabled} cli_login=${harness.nativeCredentialsEnabled ? "on" : "off"} model=${harness.defaultModel ?? "(native)"} fallback=${harness.fallbackModel ?? "(none)"} effort=${harness.effort ?? "(native)"} web=${harness.web} max_turns=${harness.maxTurns ?? "(none)"} max_rounds=${harness.maxRounds ?? "(default)"} auth=${harness.authPreference} limit_action=${harness.profileLimitAction}`);
233
236
  }
234
237
  }
238
+ export function formatInteractionTimeoutSetting(value) {
239
+ return value === null ? "disabled" : String(value);
240
+ }
235
241
  //# sourceMappingURL=settings-command.js.map