@claudexor/cli 3.1.2 → 3.3.7-rc.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 (244) 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 +208 -0
  7. package/dist/accounts-services.d.ts.map +1 -0
  8. package/dist/accounts-services.js +88 -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.d.ts.map +1 -1
  26. package/dist/claude-oauth-usage.js +13 -1
  27. package/dist/claude-oauth-usage.js.map +1 -1
  28. package/dist/claudexord-entry.js.map +1 -1
  29. package/dist/claudexord.d.ts +1 -13
  30. package/dist/claudexord.d.ts.map +1 -1
  31. package/dist/claudexord.js +57 -94
  32. package/dist/claudexord.js.map +1 -1
  33. package/dist/cli-error.d.ts.map +1 -1
  34. package/dist/cli-error.js +21 -11
  35. package/dist/cli-error.js.map +1 -1
  36. package/dist/cli.js +143 -163
  37. package/dist/cli.js.map +1 -1
  38. package/dist/codex-device-login.js.map +1 -1
  39. package/dist/codex-quota-source.js.map +1 -1
  40. package/dist/command-flags.d.ts +16 -1
  41. package/dist/command-flags.d.ts.map +1 -1
  42. package/dist/command-flags.js +41 -19
  43. package/dist/command-flags.js.map +1 -1
  44. package/dist/command-registry.d.ts +21 -8
  45. package/dist/command-registry.d.ts.map +1 -1
  46. package/dist/command-registry.js +59 -116
  47. package/dist/command-registry.js.map +1 -1
  48. package/dist/command-scope.d.ts +13 -0
  49. package/dist/command-scope.d.ts.map +1 -0
  50. package/dist/command-scope.js +61 -0
  51. package/dist/command-scope.js.map +1 -0
  52. package/dist/control-services.d.ts +1638 -1003
  53. package/dist/control-services.d.ts.map +1 -1
  54. package/dist/control-services.js +49 -67
  55. package/dist/control-services.js.map +1 -1
  56. package/dist/credential-commands.d.ts.map +1 -1
  57. package/dist/credential-commands.js +13 -3
  58. package/dist/credential-commands.js.map +1 -1
  59. package/dist/daemon-lifecycle.d.ts.map +1 -1
  60. package/dist/daemon-outcome.d.ts +3 -5
  61. package/dist/daemon-outcome.d.ts.map +1 -1
  62. package/dist/daemon-outcome.js +7 -19
  63. package/dist/daemon-outcome.js.map +1 -1
  64. package/dist/daemon-run.d.ts +21 -12
  65. package/dist/daemon-run.d.ts.map +1 -1
  66. package/dist/daemon-run.js +59 -40
  67. package/dist/daemon-run.js.map +1 -1
  68. package/dist/daemon-runtime-shutdown.d.ts +7 -0
  69. package/dist/daemon-runtime-shutdown.d.ts.map +1 -1
  70. package/dist/daemon-runtime-shutdown.js +29 -0
  71. package/dist/daemon-runtime-shutdown.js.map +1 -1
  72. package/dist/delegation-belt-descriptor.js.map +1 -1
  73. package/dist/delegation-output.d.ts +2 -0
  74. package/dist/delegation-output.d.ts.map +1 -1
  75. package/dist/delegation-output.js +3 -1
  76. package/dist/delegation-output.js.map +1 -1
  77. package/dist/harness-command.d.ts +13 -0
  78. package/dist/harness-command.d.ts.map +1 -0
  79. package/dist/harness-command.js +35 -0
  80. package/dist/harness-command.js.map +1 -0
  81. package/dist/harness-installer.d.ts +79 -0
  82. package/dist/harness-installer.d.ts.map +1 -0
  83. package/dist/harness-installer.js +256 -0
  84. package/dist/harness-installer.js.map +1 -0
  85. package/dist/interaction-prompt.d.ts +19 -0
  86. package/dist/interaction-prompt.d.ts.map +1 -0
  87. package/dist/interaction-prompt.js +114 -0
  88. package/dist/interaction-prompt.js.map +1 -0
  89. package/dist/live.d.ts +2 -6
  90. package/dist/live.d.ts.map +1 -1
  91. package/dist/live.js +88 -75
  92. package/dist/live.js.map +1 -1
  93. package/dist/mcp-daemon-unavailable.d.ts +6 -0
  94. package/dist/mcp-daemon-unavailable.d.ts.map +1 -0
  95. package/dist/mcp-daemon-unavailable.js +16 -0
  96. package/dist/mcp-daemon-unavailable.js.map +1 -0
  97. package/dist/mcp-run-projections.d.ts +30 -0
  98. package/dist/mcp-run-projections.d.ts.map +1 -1
  99. package/dist/mcp-run-projections.js +17 -17
  100. package/dist/mcp-run-projections.js.map +1 -1
  101. package/dist/mcp-runner.d.ts.map +1 -1
  102. package/dist/mcp-runner.js +81 -39
  103. package/dist/mcp-runner.js.map +1 -1
  104. package/dist/native-login.js.map +1 -1
  105. package/dist/ops-command-specs.d.ts +64 -0
  106. package/dist/ops-command-specs.d.ts.map +1 -0
  107. package/dist/ops-command-specs.js +146 -0
  108. package/dist/ops-command-specs.js.map +1 -0
  109. package/dist/ops-commands.d.ts.map +1 -1
  110. package/dist/ops-commands.js +23 -5
  111. package/dist/ops-commands.js.map +1 -1
  112. package/dist/orphan-reaper.js.map +1 -1
  113. package/dist/output-mode.d.ts +11 -0
  114. package/dist/output-mode.d.ts.map +1 -0
  115. package/dist/output-mode.js +28 -0
  116. package/dist/output-mode.js.map +1 -0
  117. package/dist/plan-question-loop.d.ts.map +1 -1
  118. package/dist/plan-question-loop.js +17 -13
  119. package/dist/plan-question-loop.js.map +1 -1
  120. package/dist/plugins.js +1 -1
  121. package/dist/plugins.js.map +1 -1
  122. package/dist/primary-output.d.ts +9 -4
  123. package/dist/primary-output.d.ts.map +1 -1
  124. package/dist/primary-output.js +50 -2
  125. package/dist/primary-output.js.map +1 -1
  126. package/dist/quota-subject-universe.d.ts +6 -0
  127. package/dist/quota-subject-universe.d.ts.map +1 -0
  128. package/dist/quota-subject-universe.js +31 -0
  129. package/dist/quota-subject-universe.js.map +1 -0
  130. package/dist/registry.js.map +1 -1
  131. package/dist/release-command.d.ts +1 -1
  132. package/dist/release-command.js +2 -2
  133. package/dist/remote-command-specs.d.ts +45 -0
  134. package/dist/remote-command-specs.d.ts.map +1 -0
  135. package/dist/remote-command-specs.js +29 -0
  136. package/dist/remote-command-specs.js.map +1 -0
  137. package/dist/remote-command.d.ts +11 -0
  138. package/dist/remote-command.d.ts.map +1 -0
  139. package/dist/remote-command.js +262 -0
  140. package/dist/remote-command.js.map +1 -0
  141. package/dist/remote-filesystem.d.ts +33 -0
  142. package/dist/remote-filesystem.d.ts.map +1 -0
  143. package/dist/remote-filesystem.js +280 -0
  144. package/dist/remote-filesystem.js.map +1 -0
  145. package/dist/repo-asset-authority.js.map +1 -1
  146. package/dist/request-preflight.d.ts +11 -2
  147. package/dist/request-preflight.d.ts.map +1 -1
  148. package/dist/request-preflight.js +36 -13
  149. package/dist/request-preflight.js.map +1 -1
  150. package/dist/retention-service.d.ts.map +1 -1
  151. package/dist/retention-service.js +6 -1
  152. package/dist/retention-service.js.map +1 -1
  153. package/dist/retry-command-specs.d.ts.map +1 -1
  154. package/dist/retry-command-specs.js +2 -0
  155. package/dist/retry-command-specs.js.map +1 -1
  156. package/dist/run-applicability.d.ts +74 -0
  157. package/dist/run-applicability.d.ts.map +1 -0
  158. package/dist/run-applicability.js +80 -0
  159. package/dist/run-applicability.js.map +1 -0
  160. package/dist/run-detail-projections.d.ts +23 -0
  161. package/dist/run-detail-projections.d.ts.map +1 -1
  162. package/dist/run-detail-projections.js +32 -1
  163. package/dist/run-detail-projections.js.map +1 -1
  164. package/dist/run-detail-response.d.ts +7 -0
  165. package/dist/run-detail-response.d.ts.map +1 -0
  166. package/dist/run-detail-response.js +23 -0
  167. package/dist/run-detail-response.js.map +1 -0
  168. package/dist/run-facts-projection.d.ts +22 -0
  169. package/dist/run-facts-projection.d.ts.map +1 -0
  170. package/dist/run-facts-projection.js +86 -0
  171. package/dist/run-facts-projection.js.map +1 -0
  172. package/dist/runtime-replacement-stop.d.ts +25 -0
  173. package/dist/runtime-replacement-stop.d.ts.map +1 -0
  174. package/dist/runtime-replacement-stop.js +145 -0
  175. package/dist/runtime-replacement-stop.js.map +1 -0
  176. package/dist/settings-command.d.ts +1 -0
  177. package/dist/settings-command.d.ts.map +1 -1
  178. package/dist/settings-command.js +27 -21
  179. package/dist/settings-command.js.map +1 -1
  180. package/dist/settings-service.d.ts +7 -7
  181. package/dist/settings-service.d.ts.map +1 -1
  182. package/dist/settings-service.js +3 -3
  183. package/dist/settings-service.js.map +1 -1
  184. package/dist/setup-client-pty.d.ts +14 -0
  185. package/dist/setup-client-pty.d.ts.map +1 -0
  186. package/dist/setup-client-pty.js +61 -0
  187. package/dist/setup-client-pty.js.map +1 -0
  188. package/dist/setup-device-code-disclosure.d.ts +15 -0
  189. package/dist/setup-device-code-disclosure.d.ts.map +1 -0
  190. package/dist/setup-device-code-disclosure.js +52 -0
  191. package/dist/setup-device-code-disclosure.js.map +1 -0
  192. package/dist/setup-job-reducer.d.ts.map +1 -1
  193. package/dist/setup-job-reducer.js +1 -0
  194. package/dist/setup-job-reducer.js.map +1 -1
  195. package/dist/setup-job-store.d.ts +275 -75
  196. package/dist/setup-job-store.d.ts.map +1 -1
  197. package/dist/setup-job-store.js.map +1 -1
  198. package/dist/setup-job-support.js.map +1 -1
  199. package/dist/setup-jobs.d.ts +517 -137
  200. package/dist/setup-jobs.d.ts.map +1 -1
  201. package/dist/setup-jobs.js +68 -118
  202. package/dist/setup-jobs.js.map +1 -1
  203. package/dist/setup-lifecycle-binding.d.ts +7 -0
  204. package/dist/setup-lifecycle-binding.d.ts.map +1 -1
  205. package/dist/setup-lifecycle-binding.js +6 -0
  206. package/dist/setup-lifecycle-binding.js.map +1 -1
  207. package/dist/setup-login-child-lifecycle.d.ts +13 -0
  208. package/dist/setup-login-child-lifecycle.d.ts.map +1 -0
  209. package/dist/setup-login-child-lifecycle.js +45 -0
  210. package/dist/setup-login-child-lifecycle.js.map +1 -0
  211. package/dist/setup-login-inline.d.ts +11 -12
  212. package/dist/setup-login-inline.d.ts.map +1 -1
  213. package/dist/setup-login-inline.js +26 -15
  214. package/dist/setup-login-inline.js.map +1 -1
  215. package/dist/setup-login-permit.d.ts +10 -0
  216. package/dist/setup-login-permit.d.ts.map +1 -0
  217. package/dist/setup-login-permit.js +52 -0
  218. package/dist/setup-login-permit.js.map +1 -0
  219. package/dist/setup-login-protocol.d.ts.map +1 -1
  220. package/dist/setup-login-protocol.js +9 -2
  221. package/dist/setup-login-protocol.js.map +1 -1
  222. package/dist/setup-login-runner.d.ts +1 -0
  223. package/dist/setup-login-runner.d.ts.map +1 -1
  224. package/dist/setup-login-runner.js +20 -31
  225. package/dist/setup-login-runner.js.map +1 -1
  226. package/dist/setup-supervisor.d.ts.map +1 -1
  227. package/dist/setup-supervisor.js.map +1 -1
  228. package/dist/terminal-run-output.d.ts +12 -0
  229. package/dist/terminal-run-output.d.ts.map +1 -0
  230. package/dist/terminal-run-output.js +33 -0
  231. package/dist/terminal-run-output.js.map +1 -0
  232. package/dist/thread-continuity-context.d.ts +36 -0
  233. package/dist/thread-continuity-context.d.ts.map +1 -0
  234. package/dist/thread-continuity-context.js +33 -0
  235. package/dist/thread-continuity-context.js.map +1 -0
  236. package/dist/thread-execution-workspace.d.ts +15 -0
  237. package/dist/thread-execution-workspace.d.ts.map +1 -1
  238. package/dist/thread-execution-workspace.js +39 -5
  239. package/dist/thread-execution-workspace.js.map +1 -1
  240. package/dist/thread-turn-services.d.ts +107 -0
  241. package/dist/thread-turn-services.d.ts.map +1 -0
  242. package/dist/thread-turn-services.js +28 -0
  243. package/dist/thread-turn-services.js.map +1 -0
  244. package/package.json +23 -23
@@ -0,0 +1,256 @@
1
+ /**
2
+ * `claudexor harness install` — the disclosed, pinned remote vendor installer
3
+ * (issue #89; restored from the PR #82 cut with the security objections
4
+ * fixed).
5
+ *
6
+ * Contract:
7
+ * - npm-distributed harnesses (claude/codex/opencode) install ONE exact
8
+ * version — the per-package vendor-version SSOT — never `@latest`. npm
9
+ * verifies the registry integrity checksum for an exact version, so the
10
+ * pin is a real guarantee. For claude/codex that SSOT is the value the
11
+ * model/effort freshness gates verified; the opencode pin is a
12
+ * deterministic install target, NOT a verification claim (no recorded
13
+ * fixture yet — see packages/harness-opencode vendor-cli-version.ts).
14
+ * - cursor has no npm artifact and CANNOT be pinned. Instead of pretending,
15
+ * the HUMAN is the verifier: the complete vendor script is downloaded first
16
+ * (never piped to a shell), its size and sha256 are printed, and it runs in
17
+ * the visible PTY the operator is watching — the same principle as
18
+ * interactive SSH auth.
19
+ * - NOTHING executes without disclosure: the exact command and install
20
+ * destination print first, and execution needs a TTY confirmation or an
21
+ * explicit `--yes` (the macOS flow confirms against this module's own
22
+ * `--dry-run --json` disclosure before passing `--yes`).
23
+ * - failures are typed and loud; a failed download or non-zero installer exit
24
+ * never reads as success, and the temp download dir is removed on every
25
+ * path.
26
+ * - `--json` keeps stdout pure: exactly ONE JSON object. In json mode every
27
+ * human progress line goes to stderr and child processes (npm/curl/the
28
+ * vendor script) run with their stdout routed onto stderr, so vendor
29
+ * output stays visible without corrupting the machine envelope.
30
+ */
31
+ import { spawnSync } from "node:child_process";
32
+ import { createHash } from "node:crypto";
33
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, readSync, rmSync } from "node:fs";
34
+ import { homedir, tmpdir } from "node:os";
35
+ import { dirname, join, resolve } from "node:path";
36
+ import { CLAUDE_VENDOR_CLI_VERSION } from "@claudexor/harness-claude";
37
+ import { CODEX_VENDOR_CLI_VERSION } from "@claudexor/harness-codex";
38
+ import { OPENCODE_VENDOR_CLI_VERSION } from "@claudexor/harness-opencode";
39
+ import { composeBaseEnv } from "@claudexor/core";
40
+ import { flagBool } from "./args.js";
41
+ import { print, printJson, printUsageError } from "./cli-io.js";
42
+ export const INSTALLABLE_HARNESSES = ["claude", "codex", "cursor", "opencode"];
43
+ export function isInstallableHarness(value) {
44
+ return INSTALLABLE_HARNESSES.includes(value);
45
+ }
46
+ const NPM_PINS = {
47
+ claude: {
48
+ npmPackage: "@anthropic-ai/claude-code",
49
+ version: CLAUDE_VENDOR_CLI_VERSION,
50
+ verification: "release_verified",
51
+ },
52
+ codex: {
53
+ npmPackage: "@openai/codex",
54
+ version: CODEX_VENDOR_CLI_VERSION,
55
+ verification: "release_verified",
56
+ },
57
+ opencode: {
58
+ npmPackage: "opencode-ai",
59
+ version: OPENCODE_VENDOR_CLI_VERSION,
60
+ verification: "deterministic_only",
61
+ },
62
+ };
63
+ export const CURSOR_INSTALL_URL = "https://cursor.com/install";
64
+ export function harnessInstallerDisclosure(harness) {
65
+ const pin = NPM_PINS[harness];
66
+ if (pin) {
67
+ return {
68
+ harness,
69
+ command: `npm install --global --prefix ~/.claudexor/remote/vendor ${pin.npmPackage}@${pin.version}`,
70
+ installLocation: "~/.claudexor/remote/vendor/bin",
71
+ pinnedVersion: pin.version,
72
+ verification: pin.verification,
73
+ };
74
+ }
75
+ return {
76
+ harness,
77
+ command: `curl --fail --silent --show-error --location ${CURSOR_INSTALL_URL} ` +
78
+ "--output <private-tmpdir>/install.sh && /bin/sh <private-tmpdir>/install.sh",
79
+ installLocation: "~/.local/bin (or ~/.cursor/bin, as selected by Cursor's installer)",
80
+ pinnedVersion: null,
81
+ verification: "human_observed",
82
+ };
83
+ }
84
+ export function runHarnessInstaller(harness, options = {}) {
85
+ const home = resolve(options.home ?? homedir());
86
+ const spawn = options.spawn ?? spawnSync;
87
+ const json = options.json === true;
88
+ // stdin inherited; child stdout -> OUR stderr (fd 2) in json mode so
89
+ // vendor/npm output stays visible but never pollutes the JSON envelope.
90
+ const childStdio = json ? [0, 2, 2] : "inherit";
91
+ const note = (line) => {
92
+ if (json)
93
+ process.stderr.write(line + "\n");
94
+ else
95
+ print(line);
96
+ };
97
+ // Vendor-controlled npm/curl/shell children receive the shared minimal
98
+ // runtime env, never the parent process's provider credentials.
99
+ const environment = { ...composeBaseEnv("clean"), HOME: home };
100
+ const pin = NPM_PINS[harness];
101
+ if (pin) {
102
+ const vendorRoot = join(home, ".claudexor", "remote", "vendor");
103
+ (options.mkdir ?? mkdirSync)(vendorRoot, { recursive: true, mode: 0o700 });
104
+ const nodePath = resolve(options.nodePath ?? process.execPath);
105
+ const npmCLI = resolve(dirname(nodePath), "..", "lib", "node_modules", "npm", "bin", "npm-cli.js");
106
+ if (!(options.exists ?? existsSync)(npmCLI)) {
107
+ return {
108
+ exitCode: 1,
109
+ refusal: `the bundled npm entrypoint is missing at ${npmCLI} ` +
110
+ "(expected inside the pinned Node runtime next to this CLI); nothing was executed",
111
+ };
112
+ }
113
+ const result = spawn(nodePath, [npmCLI, "install", "--global", "--prefix", vendorRoot, `${pin.npmPackage}@${pin.version}`], { stdio: childStdio, env: environment });
114
+ return { exitCode: result.status ?? 1 };
115
+ }
116
+ // Cursor: download the COMPLETE vendor script before execution (`--fail`
117
+ // rejects HTTP error bodies), read it back and print its size + sha256 so
118
+ // the watching human sees exactly which bytes are about to run, and remove
119
+ // the private temp dir on every success/failure path.
120
+ const temporaryDirectory = mkdtempSync(join(tmpdir(), "claudexor-cursor-install-"));
121
+ const installerPath = join(temporaryDirectory, "install.sh");
122
+ try {
123
+ const downloaded = spawn("curl", [
124
+ "--fail",
125
+ "--silent",
126
+ "--show-error",
127
+ "--location",
128
+ CURSOR_INSTALL_URL,
129
+ "--output",
130
+ installerPath,
131
+ ], { stdio: childStdio, env: environment });
132
+ if (downloaded.status !== 0) {
133
+ return {
134
+ exitCode: downloaded.status ?? 1,
135
+ refusal: `the download of ${CURSOR_INSTALL_URL} failed (curl exit ${downloaded.status ?? "unknown"}); nothing was executed`,
136
+ };
137
+ }
138
+ let script;
139
+ try {
140
+ script = readFileSync(installerPath);
141
+ }
142
+ catch {
143
+ return {
144
+ exitCode: 1,
145
+ refusal: "the downloaded installer script could not be read back; nothing was executed",
146
+ };
147
+ }
148
+ note(`cursor installer downloaded: ${script.length} bytes, ` +
149
+ `sha256 ${createHash("sha256").update(script).digest("hex")}`);
150
+ note(`running: /bin/sh ${installerPath}`);
151
+ const executed = spawn("/bin/sh", [installerPath], { stdio: childStdio, env: environment });
152
+ return { exitCode: executed.status ?? 1 };
153
+ }
154
+ finally {
155
+ rmSync(temporaryDirectory, { recursive: true, force: true });
156
+ }
157
+ }
158
+ const INSTALL_USAGE = "usage: claudexor harness install <claude|codex|cursor|opencode> [--dry-run] [--yes]";
159
+ function pinDisclosureLine(disclosure) {
160
+ if (disclosure.pinnedVersion === null) {
161
+ return "Version pin: none — Cursor ships no pinnable npm artifact; the vendor script is downloaded in full, its size and sha256 print, and it runs in this terminal where you watch it";
162
+ }
163
+ if (disclosure.verification === "deterministic_only") {
164
+ return `Version pin: ${disclosure.pinnedVersion} (exact; deterministic install target — not covered by recorded verification fixtures; npm verifies its registry integrity checksum)`;
165
+ }
166
+ return `Version pin: ${disclosure.pinnedVersion} (exact; the version this release was verified against — npm verifies its registry integrity checksum)`;
167
+ }
168
+ function printHumanDisclosure(disclosure) {
169
+ print(`Harness: ${disclosure.harness}`);
170
+ print(`Command: ${disclosure.command}`);
171
+ print(`Install location: ${disclosure.installLocation}`);
172
+ print(pinDisclosureLine(disclosure));
173
+ }
174
+ /** Blocking y/N read on the controlling TTY (fd 0). Anything but an explicit
175
+ * yes declines — closing stdin or an unreadable terminal never installs. */
176
+ function confirmOnTty(question) {
177
+ process.stdout.write(question);
178
+ const buffer = Buffer.alloc(1024);
179
+ let input = "";
180
+ while (!input.includes("\n")) {
181
+ let bytesRead = 0;
182
+ try {
183
+ bytesRead = readSync(0, buffer, 0, buffer.length, null);
184
+ }
185
+ catch {
186
+ return false;
187
+ }
188
+ if (bytesRead === 0)
189
+ break;
190
+ input += buffer.toString("utf8", 0, bytesRead);
191
+ }
192
+ return /^y(es)?$/i.test(input.trim());
193
+ }
194
+ export function harnessInstallCommand(args, json,
195
+ /** Test seam: forwarded to `runHarnessInstaller` (spawn/home/... fakes). */
196
+ runnerOptions = {}) {
197
+ const harness = args._[2] ?? "";
198
+ if (!isInstallableHarness(harness) || args._.length !== 3) {
199
+ return printUsageError(json, INSTALL_USAGE);
200
+ }
201
+ const disclosure = harnessInstallerDisclosure(harness);
202
+ if (flagBool(args, "dry-run")) {
203
+ if (json)
204
+ printJson({ ok: true, dryRun: true, ...disclosure });
205
+ else
206
+ printHumanDisclosure(disclosure);
207
+ return 0;
208
+ }
209
+ // Disclosure precedes EVERY execution path; --json without --yes refuses
210
+ // (machine callers must have shown the dry-run disclosure themselves).
211
+ if (!json)
212
+ printHumanDisclosure(disclosure);
213
+ if (!flagBool(args, "yes")) {
214
+ if (json || !process.stdin.isTTY) {
215
+ if (json) {
216
+ printJson({
217
+ ok: false,
218
+ exitCode: 1,
219
+ code: "confirmation_required",
220
+ message: "pass --yes after showing the --dry-run disclosure, or run on a TTY",
221
+ ...disclosure,
222
+ });
223
+ }
224
+ else {
225
+ print("Not installing: confirm with --yes, or run on an interactive terminal to be asked.");
226
+ }
227
+ return 1;
228
+ }
229
+ if (!confirmOnTty(`Run this installer for ${harness}? [y/N] `)) {
230
+ print("Cancelled; nothing was installed.");
231
+ return 1;
232
+ }
233
+ }
234
+ const result = runHarnessInstaller(harness, { ...runnerOptions, json });
235
+ const ok = result.exitCode === 0 && result.refusal === undefined;
236
+ if (json) {
237
+ printJson({
238
+ ok,
239
+ dryRun: false,
240
+ exitCode: result.exitCode,
241
+ ...(result.refusal === undefined ? {} : { refusal: result.refusal }),
242
+ ...disclosure,
243
+ });
244
+ }
245
+ else if (result.refusal !== undefined) {
246
+ print(`Install refused: ${result.refusal}`);
247
+ }
248
+ else if (!ok) {
249
+ print(`Installer exited with code ${result.exitCode}; ${harness} was NOT installed cleanly.`);
250
+ }
251
+ else {
252
+ print(`Installer finished. Run \`claudexor doctor\` to verify ${harness}.`);
253
+ }
254
+ return ok ? 0 : result.exitCode === 0 ? 1 : result.exitCode;
255
+ }
256
+ //# sourceMappingURL=harness-installer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness-installer.js","sourceRoot":"","sources":["../src/harness-installer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { InteractionAnswerSet, InteractionQuestion } from "@claudexor/schema";
2
+ /** Prompt questions on the controlling TTY. A non-TTY or expired deadline
3
+ * declines benignly so the engine can continue with explicit assumptions. */
4
+ export declare function promptQuestionsOnTty(interactionId: string, questions: InteractionQuestion[], timeoutAt?: string, signal?: AbortSignal): Promise<InteractionAnswerSet | null>;
5
+ export interface InteractionQuestionReader {
6
+ question(prompt: string, options?: {
7
+ signal?: AbortSignal;
8
+ }): Promise<string>;
9
+ close(): void;
10
+ }
11
+ export interface InteractionPromptOptions {
12
+ timeoutAt?: string;
13
+ signal?: AbortSignal;
14
+ reader: InteractionQuestionReader;
15
+ }
16
+ /** Testable core of the TTY prompt. The caller supplies the reader and a run-
17
+ * lifetime signal, so a disabled deadline can still close on cancel/terminal. */
18
+ export declare function collectInteractionAnswers(interactionId: string, questions: InteractionQuestion[], options: InteractionPromptOptions): Promise<InteractionAnswerSet | null>;
19
+ //# sourceMappingURL=interaction-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interaction-prompt.d.ts","sourceRoot":"","sources":["../src/interaction-prompt.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAOnF;6EAC6E;AAC7E,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,mBAAmB,EAAE,EAChC,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAUtC;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9E,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,yBAAyB,CAAC;CACnC;AAgCD;iFACiF;AACjF,wBAAsB,yBAAyB,CAC7C,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,mBAAmB,EAAE,EAChC,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAsEtC"}
@@ -0,0 +1,114 @@
1
+ import { createInterface } from "node:readline/promises";
2
+ import { parseChoiceIndexes } from "./choice-input.js";
3
+ const print = (line) => {
4
+ process.stdout.write(line + "\n");
5
+ };
6
+ /** Prompt questions on the controlling TTY. A non-TTY or expired deadline
7
+ * declines benignly so the engine can continue with explicit assumptions. */
8
+ export async function promptQuestionsOnTty(interactionId, questions, timeoutAt, signal) {
9
+ if (!process.stdin.isTTY) {
10
+ print("(question received, but stdin is not a TTY — the run continues with assumptions)");
11
+ return null;
12
+ }
13
+ return collectInteractionAnswers(interactionId, questions, {
14
+ timeoutAt,
15
+ signal,
16
+ reader: createInterface({ input: process.stdin, output: process.stdout }),
17
+ });
18
+ }
19
+ const MAX_TIMER_DELAY_MS = 2_147_483_647;
20
+ /** Node coerces a timeout above 2^31-1 ms to 1 ms. Build a cancellable
21
+ * deadline signal from bounded timer chunks so a large finite interaction
22
+ * policy does not close the CLI prompt immediately. */
23
+ function finiteDeadlineSignal(delayMs) {
24
+ const controller = new AbortController();
25
+ const deadline = Date.now() + delayMs;
26
+ let timer;
27
+ let cancelled = false;
28
+ const arm = () => {
29
+ if (cancelled)
30
+ return;
31
+ const remaining = deadline - Date.now();
32
+ if (remaining <= 0) {
33
+ controller.abort();
34
+ return;
35
+ }
36
+ timer = setTimeout(arm, Math.min(remaining, MAX_TIMER_DELAY_MS));
37
+ timer.unref?.();
38
+ };
39
+ arm();
40
+ return {
41
+ signal: controller.signal,
42
+ cancel: () => {
43
+ cancelled = true;
44
+ if (timer)
45
+ clearTimeout(timer);
46
+ },
47
+ };
48
+ }
49
+ /** Testable core of the TTY prompt. The caller supplies the reader and a run-
50
+ * lifetime signal, so a disabled deadline can still close on cancel/terminal. */
51
+ export async function collectInteractionAnswers(interactionId, questions, options) {
52
+ const { reader, timeoutAt, signal: runSignal } = options;
53
+ const deadlineMs = timeoutAt ? Date.parse(timeoutAt) - Date.now() : null;
54
+ if (deadlineMs !== null && (!Number.isFinite(deadlineMs) || deadlineMs <= 0)) {
55
+ // An already-expired deadline must decline immediately — prompting with
56
+ // no signal would hang the TTY forever on a question the engine already
57
+ // timed out (e.g. a historical event replayed by `follow`).
58
+ print("(question already timed out — the run continues with assumptions)");
59
+ reader.close();
60
+ return null;
61
+ }
62
+ const deadline = deadlineMs === null ? undefined : finiteDeadlineSignal(deadlineMs);
63
+ const signals = [runSignal, deadline?.signal].filter((value) => value !== undefined);
64
+ const signal = signals.length === 0 ? undefined : signals.length === 1 ? signals[0] : AbortSignal.any(signals);
65
+ try {
66
+ if (signal?.aborted)
67
+ return null;
68
+ const answers = [];
69
+ for (const q of questions) {
70
+ print("");
71
+ print(`? ${q.header ? `[${q.header}] ` : ""}${q.question}`);
72
+ q.options.forEach((option, index) => print(` ${index + 1}) ${option.label}${option.description ? ` — ${option.description}` : ""}`));
73
+ const hint = q.options.length > 0
74
+ ? q.multi_select
75
+ ? "numbers separated by commas, or free text"
76
+ : "a number, or free text"
77
+ : "free text";
78
+ const raw = (signal
79
+ ? await reader.question(` answer (${hint}): `, { signal })
80
+ : await reader.question(` answer (${hint}): `)).trim();
81
+ if (!raw)
82
+ continue;
83
+ const picks = parseChoiceIndexes(raw, q.options.length, q.multi_select);
84
+ if (picks) {
85
+ answers.push({
86
+ question_id: q.id,
87
+ selected_labels: picks.map((index) => q.options[index]?.label ?? "").filter(Boolean),
88
+ free_text: null,
89
+ });
90
+ }
91
+ else {
92
+ answers.push({ question_id: q.id, selected_labels: [], free_text: raw });
93
+ }
94
+ }
95
+ return answers.length > 0 ? { interaction_id: interactionId, answers } : null;
96
+ }
97
+ catch {
98
+ const resolvedElsewhere = runSignal?.aborted &&
99
+ runSignal.reason &&
100
+ typeof runSignal.reason === "object" &&
101
+ runSignal.reason.kind === "interaction_resolved";
102
+ print(resolvedElsewhere
103
+ ? "(question resolved — answer prompt closed)"
104
+ : runSignal?.aborted
105
+ ? "(run ended — answer prompt closed)"
106
+ : "(answer window closed — the run continues with assumptions)");
107
+ return null;
108
+ }
109
+ finally {
110
+ deadline?.cancel();
111
+ reader.close();
112
+ }
113
+ }
114
+ //# sourceMappingURL=interaction-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interaction-prompt.js","sourceRoot":"","sources":["../src/interaction-prompt.ts"],"names":[],"mappings":"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"}
package/dist/live.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { InteractionAnswerSet, InteractionQuestion } from "@claudexor/schema";
1
+ export { collectInteractionAnswers } from "./interaction-prompt.js";
2
2
  /** One CLI process-status policy for direct runs and streamed terminals — a
3
3
  * thin re-export of the ONE projection owner (D8): the lifecycle IS the exit
4
4
  * code (succeeded => 0; a "Done · needs review" run also exits 0). */
@@ -36,11 +36,6 @@ export declare function formatRunEventLine(ev: Record<string, unknown>): string
36
36
  * Text mode only — `--json`/NDJSON stay verbatim machine surfaces.
37
37
  */
38
38
  export declare function createRunEventLineFormatter(): (ev: Record<string, unknown>) => string | null;
39
- /**
40
- * Prompt the questions on the controlling TTY. Returns null on a non-TTY
41
- * stdin or when the deadline passes (the engine then declines benignly).
42
- */
43
- export declare function promptQuestionsOnTty(interactionId: string, questions: InteractionQuestion[], timeoutAt?: string): Promise<InteractionAnswerSet | null>;
44
39
  export interface ControlApiAddress {
45
40
  baseUrl: string;
46
41
  token: string;
@@ -56,6 +51,7 @@ export declare function controlApiFetch(addr: ControlApiAddress, path: string, i
56
51
  * package constant. Null when the daemon did not report a well-formed version. */
57
52
  export interface EngineIdentity {
58
53
  engineVersion: string | null;
54
+ engineBuildSha: string | null;
59
55
  }
60
56
  export declare function handshakeControlApi(addr: ControlApiAddress, client?: string): Promise<EngineIdentity>;
61
57
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../src/live.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAenF;;sEAEsE;AACtE,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAElE;AAED;;;6EAG6E;AAC7E,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAInF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI,CA6H7E;AAcD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,2BAA2B,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,GAAG,IAAI,CAgB5F;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,mBAAmB,EAAE,EAChC,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAwDtC;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAID,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,CAAC;AAElC,wBAAgB,iBAAiB,IAAI,iBAAiB,CASrD;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,CAC7B,IAAI,EAAE,iBAAiB,EACvB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,QAAQ,CAAC,CA4BnB;AAED;;;kFAGkF;AAClF,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,iBAAiB,EACvB,MAAM,SAAkB,GACvB,OAAO,CAAC,cAAc,CAAC,CAmCzB;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAgH7E"}
1
+ {"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../src/live.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAMpE;;sEAEsE;AACtE,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAElE;AAED;;;6EAG6E;AAC7E,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAInF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI,CAqI7E;AAcD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,2BAA2B,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,GAAG,IAAI,CAgB5F;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAID,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,CAAC;AAElC,wBAAgB,iBAAiB,IAAI,iBAAiB,CASrD;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,CAC7B,IAAI,EAAE,iBAAiB,EACvB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,QAAQ,CAAC,CA4BnB;AAED;;;kFAGkF;AAClF,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,iBAAiB,EACvB,MAAM,SAAkB,GACvB,OAAO,CAAC,cAAc,CAAC,CAwCzB;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CA0J7E"}