@platless/axom-cli 0.3.13 → 0.5.9

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/axom-patch/cli/README.md +30 -8
  2. package/dist/axom-patch/cli/account-limits/README.md +27 -0
  3. package/dist/axom-patch/cli/account-limits/antigravity-proxy.mjs +47 -0
  4. package/dist/axom-patch/cli/account-limits/antigravity-read.mjs +90 -0
  5. package/dist/axom-patch/cli/account-limits/antigravity.mjs +46 -0
  6. package/dist/axom-patch/cli/account-limits/generate.py +120 -0
  7. package/dist/axom-patch/cli/account-limits/kimi-proxy.mjs +64 -0
  8. package/dist/axom-patch/cli/account-limits/normalize.mjs +151 -0
  9. package/dist/axom-patch/cli/claude-account-limits.json +37 -0
  10. package/dist/axom-patch/cli/codex-account-limits.json +37 -0
  11. package/dist/axom-patch/cli/commandcode-account-limits.json +30 -0
  12. package/dist/axom-patch/cli/nightly-task.md +152 -0
  13. package/dist/axom-patch/cli/pi-subagent-subwork.json +23 -0
  14. package/dist/axom-patch/cli/probes/claude-late-async-terminal.mjs +5 -1
  15. package/dist/axom-patch/cli/probes/pi-subagent-subwork.mjs +211 -0
  16. package/dist/axom-patch/cli/probes/qoder-steering.mjs +1 -1
  17. package/dist/axom-patch/cli/probes/qoder-subagent-origin.mjs +20 -8
  18. package/dist/axom-patch/cli/probes/zcode-subagent-subwork.mjs +257 -0
  19. package/dist/axom-patch/cli/qoder-background-terminal.md +2 -1
  20. package/dist/axom-patch/cli/qoder-foreground-output.md +4 -3
  21. package/dist/axom-patch/cli/qoder-steering.json +15 -15
  22. package/dist/axom-patch/cli/qoder-subagent-origin.json +21 -21
  23. package/dist/axom-patch/cli/runtime.json +34 -8
  24. package/dist/axom-patch/cli/zcode-account-limits.json +31 -0
  25. package/dist/axom-patch/cli/zcode-models.json +38 -0
  26. package/dist/axom-patch/cli/zcode-subagent-subwork.json +73 -0
  27. package/dist/cli.js +33 -6
  28. package/dist/keepers/acp/keeper.mjs +3083 -0
  29. package/dist/keepers/acp/manifest.json +9 -0
  30. package/dist/keepers/terminal/keeper.mjs +8469 -0
  31. package/dist/keepers/terminal/manifest.json +9 -0
  32. package/dist/keepers/terminal/node_modules/node-pty/lib/conpty_console_list_agent.js +25 -0
  33. package/dist/keepers/terminal/node_modules/node-pty/lib/eventEmitter2.js +47 -0
  34. package/dist/keepers/terminal/node_modules/node-pty/lib/index.js +52 -0
  35. package/dist/keepers/terminal/node_modules/node-pty/lib/interfaces.js +7 -0
  36. package/dist/keepers/terminal/node_modules/node-pty/lib/shared/conout.js +10 -0
  37. package/dist/keepers/terminal/node_modules/node-pty/lib/terminal.js +190 -0
  38. package/dist/keepers/terminal/node_modules/node-pty/lib/types.js +7 -0
  39. package/dist/keepers/terminal/node_modules/node-pty/lib/unixTerminal.js +351 -0
  40. package/dist/keepers/terminal/node_modules/node-pty/lib/utils.js +38 -0
  41. package/dist/keepers/terminal/node_modules/node-pty/lib/windowsConoutConnection.js +131 -0
  42. package/dist/keepers/terminal/node_modules/node-pty/lib/windowsPtyAgent.js +344 -0
  43. package/dist/keepers/terminal/node_modules/node-pty/lib/windowsTerminal.js +209 -0
  44. package/dist/keepers/terminal/node_modules/node-pty/lib/worker/conoutSocketWorker.js +22 -0
  45. package/dist/keepers/terminal/node_modules/node-pty/package.json +66 -0
  46. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/darwin-arm64/pty.node +0 -0
  47. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/darwin-arm64/spawn-helper +0 -0
  48. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/darwin-x64/pty.node +0 -0
  49. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/darwin-x64/spawn-helper +0 -0
  50. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/linux-arm64/pty.node +0 -0
  51. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/linux-x64/pty.node +0 -0
  52. package/dist/runtime-deps/qoder-sdk/package-lock.json +1189 -0
  53. package/dist/runtime-deps/qoder-sdk/package.json +8 -0
  54. package/dist/test/keeperKit.js +67 -0
  55. package/dist/workstation/acp/acpAgents.js +2163 -611
  56. package/dist/workstation/acp/acpClient.js +60 -497
  57. package/dist/workstation/acp/adoption.js +10 -396
  58. package/dist/workstation/acp/binaryInstall.js +100 -27
  59. package/dist/workstation/acp/builds/gc.js +245 -0
  60. package/dist/workstation/acp/builds/install/binary.js +28 -0
  61. package/dist/workstation/acp/builds/install/npm.js +235 -0
  62. package/dist/workstation/acp/builds/install/uv.js +254 -0
  63. package/dist/workstation/acp/builds/migrate.js +195 -0
  64. package/dist/workstation/acp/builds/model.js +128 -0
  65. package/dist/workstation/acp/builds/nodeGate.js +100 -0
  66. package/dist/workstation/acp/builds/store.js +352 -0
  67. package/dist/workstation/acp/commandTableProbe.js +68 -0
  68. package/dist/workstation/acp/configOptions.js +103 -1
  69. package/dist/workstation/acp/envSecrets.js +27 -0
  70. package/dist/workstation/acp/initializeResponse.js +285 -0
  71. package/dist/workstation/acp/installErrors.js +12 -2
  72. package/dist/workstation/acp/installProbe.js +1 -1
  73. package/dist/workstation/acp/managedPatches.js +76 -160
  74. package/dist/workstation/acp/outbox.js +330 -0
  75. package/dist/workstation/acp/patchAssets.js +20 -3
  76. package/dist/workstation/acp/permission.js +42 -10
  77. package/dist/workstation/acp/processor/checkpoint.js +87 -0
  78. package/dist/workstation/acp/processor/commands.js +35 -0
  79. package/dist/workstation/acp/processor/control.js +355 -0
  80. package/dist/workstation/acp/processor/emit.js +26 -0
  81. package/dist/workstation/acp/processor/jsonrpc.js +172 -0
  82. package/dist/workstation/acp/processor/memoryLog.js +49 -0
  83. package/dist/workstation/acp/processor/origins.js +48 -0
  84. package/dist/workstation/acp/processor/output.js +67 -0
  85. package/dist/workstation/acp/processor/projection.js +42 -0
  86. package/dist/workstation/acp/processor/record.js +128 -0
  87. package/dist/workstation/acp/processor/runtime.js +181 -0
  88. package/dist/workstation/acp/processor/sdkSchemas.js +61 -0
  89. package/dist/workstation/acp/processor/session.js +525 -0
  90. package/dist/workstation/acp/processor/sideChannel.js +80 -0
  91. package/dist/workstation/acp/processor/state.js +74 -0
  92. package/dist/workstation/acp/processor/step.js +459 -0
  93. package/dist/workstation/acp/processor/test/fixtureLog.js +65 -0
  94. package/dist/workstation/acp/processor/test/harness.js +120 -0
  95. package/dist/workstation/acp/processor/test/largeIdEcho.js +50 -0
  96. package/dist/workstation/acp/processor/test/rawAgent.js +70 -0
  97. package/dist/workstation/acp/processor/transport/generations.js +76 -0
  98. package/dist/workstation/acp/processor/transport/keeper.js +130 -0
  99. package/dist/workstation/acp/processor/transport/local.js +269 -0
  100. package/dist/workstation/acp/processor/transport/types.js +78 -0
  101. package/dist/workstation/acp/processor/updates.js +364 -0
  102. package/dist/workstation/acp/processorSession.js +1512 -0
  103. package/dist/workstation/acp/qoderStartup.js +1 -1
  104. package/dist/workstation/acp/registry/catalog.js +154 -32
  105. package/dist/workstation/acp/registry/launch.js +61 -119
  106. package/dist/workstation/acp/sessionUpdateMapper.js +18 -7
  107. package/dist/workstation/acp/steering.js +58 -0
  108. package/dist/workstation/acp/switching.js +114 -0
  109. package/dist/workstation/acp/terminalLogin.js +16 -42
  110. package/dist/workstation/acp/terminalLoginSpec.js +41 -0
  111. package/dist/workstation/acp/test/adapterFixtures.js +256 -0
  112. package/dist/workstation/acp/test/daemonLife.js +106 -0
  113. package/dist/workstation/acp/test/keeperWorld.js +267 -0
  114. package/dist/workstation/acp/test/memoryOutbox.js +55 -0
  115. package/dist/workstation/acp/test/raw/fixtures.js +196 -0
  116. package/dist/workstation/acp/test/raw/qoderCaptures.js +125 -0
  117. package/dist/workstation/acp/test/raw/sanitize.js +344 -0
  118. package/dist/workstation/acp/test/raw/sources.js +249 -0
  119. package/dist/workstation/acp/test/realAdapter.js +377 -0
  120. package/dist/workstation/acp/test/scriptAgent.js +206 -0
  121. package/dist/workstation/acp/test/sessionFrames.js +42 -0
  122. package/dist/workstation/acp/timedCommand.js +4 -2
  123. package/dist/workstation/acp/uvxInstall.js +72 -122
  124. package/dist/workstation/agentFlow.js +103 -0
  125. package/dist/workstation/agentSessions.js +1324 -474
  126. package/dist/workstation/channels/agent.js +7 -5
  127. package/dist/workstation/channels/computer.js +69 -21
  128. package/dist/workstation/channels/computerExecs.js +200 -0
  129. package/dist/workstation/channels/management.js +84 -4
  130. package/dist/workstation/daemon.js +288 -7
  131. package/dist/workstation/daemonctl.js +28 -2
  132. package/dist/workstation/exec/attach.js +126 -0
  133. package/dist/workstation/exec/command.js +40 -0
  134. package/dist/workstation/exec/durable.js +517 -0
  135. package/dist/workstation/exec/fallback.js +106 -0
  136. package/dist/workstation/exec/policy.js +837 -0
  137. package/dist/workstation/exec/shaping.js +211 -0
  138. package/dist/workstation/exec.js +3 -112
  139. package/dist/workstation/files/adapters/computerFileFrames.js +51 -0
  140. package/dist/workstation/files/adapters/toolRequests.js +121 -0
  141. package/dist/workstation/files/client.js +455 -0
  142. package/dist/workstation/files/errors.js +28 -0
  143. package/dist/workstation/files/fence.js +350 -0
  144. package/dist/workstation/files/find/fileIndex.js +153 -0
  145. package/dist/workstation/files/find/fuzzy.js +155 -0
  146. package/dist/workstation/files/host.js +122 -0
  147. package/dist/workstation/files/hostProtocol.js +2 -0
  148. package/dist/workstation/files/media/cache.js +620 -0
  149. package/dist/workstation/files/media/encoding.js +308 -0
  150. package/dist/workstation/files/media/estimator.js +100 -0
  151. package/dist/workstation/files/media/media.js +325 -0
  152. package/dist/workstation/files/media/packedAudio.js +23 -0
  153. package/dist/workstation/files/media/scheduler.js +551 -0
  154. package/dist/workstation/files/media/types.js +5 -0
  155. package/dist/workstation/files/scope.js +45 -0
  156. package/dist/workstation/files/structured.js +284 -0
  157. package/dist/workstation/{fileOps.js → files/text.js} +117 -38
  158. package/dist/workstation/files/uploads.js +351 -0
  159. package/dist/workstation/journal.js +65 -236
  160. package/dist/workstation/keepers/acp/client.js +101 -0
  161. package/dist/workstation/keepers/acp/envelope.js +62 -0
  162. package/dist/workstation/keepers/acp/host.js +419 -0
  163. package/dist/workstation/keepers/acp/main.js +18 -0
  164. package/dist/workstation/keepers/acp/memoryStream.js +121 -0
  165. package/dist/workstation/keepers/acp/params.js +137 -0
  166. package/dist/workstation/keepers/acp/protocol.js +66 -0
  167. package/dist/workstation/keepers/acp/recover.js +120 -0
  168. package/dist/workstation/keepers/acp/session.js +584 -0
  169. package/dist/workstation/keepers/acp/stderr.js +154 -0
  170. package/dist/workstation/keepers/kit/activity.js +103 -0
  171. package/dist/workstation/keepers/kit/bootstrap.js +164 -0
  172. package/dist/workstation/keepers/kit/buildVersion.js +51 -0
  173. package/dist/workstation/keepers/kit/bundle.js +120 -0
  174. package/dist/workstation/keepers/kit/client.js +432 -0
  175. package/dist/workstation/keepers/kit/identity.js +21 -0
  176. package/dist/workstation/keepers/kit/ipc.js +112 -0
  177. package/dist/workstation/keepers/kit/launchConfig.js +8 -0
  178. package/dist/workstation/keepers/kit/launcher.js +249 -0
  179. package/dist/workstation/keepers/kit/lock.js +123 -0
  180. package/dist/workstation/keepers/kit/orphanSweep.js +86 -0
  181. package/dist/workstation/keepers/kit/paths.js +75 -0
  182. package/dist/workstation/keepers/kit/protocol.js +43 -0
  183. package/dist/workstation/keepers/kit/server.js +518 -0
  184. package/dist/workstation/keepers/kit/streamLog.js +697 -0
  185. package/dist/workstation/keepers/legacy.js +296 -0
  186. package/dist/workstation/keepers/policy.js +576 -0
  187. package/dist/workstation/keepers/stop.js +34 -0
  188. package/dist/workstation/keepers/terminal/client.js +213 -0
  189. package/dist/workstation/keepers/terminal/exec.js +981 -0
  190. package/dist/workstation/keepers/terminal/generations.js +129 -0
  191. package/dist/workstation/keepers/terminal/keeper.js +62 -0
  192. package/dist/workstation/keepers/terminal/main.js +43 -0
  193. package/dist/workstation/keepers/terminal/orphanSweep.js +3 -0
  194. package/dist/workstation/keepers/terminal/params.js +27 -0
  195. package/dist/workstation/keepers/terminal/protocol.js +56 -0
  196. package/dist/workstation/keepers/terminal/pty.js +330 -0
  197. package/dist/workstation/protocol/accountLimits.js +47 -0
  198. package/dist/workstation/protocol/agent.js +48 -4
  199. package/dist/workstation/protocol/common.js +30 -0
  200. package/dist/workstation/protocol/computer.js +15 -4
  201. package/dist/workstation/protocol/management.js +50 -2
  202. package/dist/workstation/qoderAdapter/backgroundProcess.js +18 -6
  203. package/dist/workstation/qoderAdapter/backgroundTerminal.js +78 -147
  204. package/dist/workstation/qoderAdapter/backgroundTerminalFold.js +372 -0
  205. package/dist/workstation/qoderAdapter/callbackContext.js +76 -0
  206. package/dist/workstation/qoderAdapter/foregroundOutput.js +15 -9
  207. package/dist/workstation/qoderAdapter/history.js +1 -3
  208. package/dist/workstation/qoderAdapter/main.js +4 -2
  209. package/dist/workstation/qoderAdapter/sdkDriver.js +1 -2
  210. package/dist/workstation/qoderAdapter/sdkRuntime.js +93 -0
  211. package/dist/workstation/qoderAdapter/sdkRuntimeInstall.js +145 -0
  212. package/dist/workstation/qoderAdapter/session.js +1 -1
  213. package/dist/workstation/qoderAdapter/subwork.js +15 -7
  214. package/dist/workstation/systemMetrics.js +110 -1
  215. package/dist/workstation/tools/client.js +9 -1
  216. package/dist/workstation/tools/info.js +50 -0
  217. package/dist/workstation/tools/keeperProcess.js +15 -5
  218. package/dist/workstation/tools/router.js +55 -0
  219. package/dist/workstation/tools/terminalRouter.js +222 -0
  220. package/dist/workstation/tools/validation.js +37 -1
  221. package/dist/workstation/update/coordinator.js +3 -0
  222. package/dist/workstation/update/ptyPreflight.js +21 -0
  223. package/dist/workstation/update/taskRegistry.js +105 -11
  224. package/package.json +10 -7
  225. package/dist/workstation/acp/acpSession.js +0 -1475
  226. package/dist/workstation/acp/contract.js +0 -499
  227. package/dist/workstation/acp/draftInterceptor.js +0 -163
  228. package/dist/workstation/acp/sessionScope.js +0 -19
  229. package/dist/workstation/filePaths.js +0 -174
  230. package/dist/workstation/fileWorker.js +0 -81
  231. package/dist/workstation/fileWorkerClient.js +0 -121
  232. package/dist/workstation/qoderAdapter/taskEvent.js +0 -26
  233. package/dist/workstation/tools/core.js +0 -50
  234. package/dist/workstation/tools/files.js +0 -525
  235. package/dist/workstation/tools/terminal.js +0 -214
@@ -0,0 +1,213 @@
1
+ // Daemon-side: a typed `pty.*` client for keeper-terminal (launch through KeeperLauncher, one long-lived KeeperClient per
2
+ // generation). Exempt from the keeper-side import guard.
3
+ import { promises as fs } from 'node:fs';
4
+ import path from 'node:path';
5
+ import { readKeeperManifest } from '../kit/bundle.js';
6
+ import { KeeperClient } from '../kit/client.js';
7
+ import { keeperGen } from '../kit/identity.js';
8
+ import { defaultDistDir } from '../kit/launcher.js';
9
+ import { protocolWindow } from '../kit/protocol.js';
10
+ import { PTY_CAPABILITY, PTY_UNAVAILABLE_ERROR, TERMINAL_PROTOCOL_VERSION, execStream, } from './protocol.js';
11
+ /** keeper-terminal could not be reached (launch, connect or hello failed): the request was never sent. */
12
+ export class KeeperLaunchError extends Error {
13
+ cause;
14
+ code = 'launch_failed';
15
+ // The cause's message unchanged: terminal.* callers surface it as before.
16
+ constructor(cause) {
17
+ super(cause instanceof Error ? cause.message : String(cause));
18
+ this.cause = cause;
19
+ this.name = 'KeeperLaunchError';
20
+ }
21
+ }
22
+ /** The terminal fields a keeper-terminal hello implies: `pty` capability, or today's unavailable wording. */
23
+ export function terminalStatusOf(hello) {
24
+ return hello.capabilities.includes(PTY_CAPABILITY) ? { terminal: true } : { terminal: false, terminalError: PTY_UNAVAILABLE_ERROR };
25
+ }
26
+ /** Records how long a "nothing is running" answer stays valid, so a high-frequency probe does not knock on a missing socket each time. */
27
+ const NOT_RUNNING_TTL_MS = 5000;
28
+ /** The default bound of {@link TerminalKeeperClient.probe}: a real connect and hello, not a quick peek. */
29
+ export const KEEPER_PROBE_TIMEOUT_MS = 3000;
30
+ const errnoOf = (error) => typeof error === 'object' && error !== null && typeof error.code === 'string' ? error.code : undefined;
31
+ /** Connect errors that prove nothing listens: the socket file is gone, or a stale one with no listener behind it. */
32
+ const ABSENT_ERRNOS = new Set(['ENOENT', 'ECONNREFUSED']);
33
+ const messageOf = (error) => (error instanceof Error ? error.message : String(error));
34
+ export class TerminalKeeperClient {
35
+ options;
36
+ client;
37
+ clientGen;
38
+ /** The generation of the build the launcher last ensured (the daemon's current keeper-terminal build). */
39
+ currentGen;
40
+ /** Until when a proven absence is remembered (only `absent` is cached for this long). */
41
+ notRunningUntil = 0;
42
+ /** Until when `runningHello` answers null after an undecided probe without probing again (never used by `probe`). */
43
+ undecidedUntil = 0;
44
+ /** Probes in flight, by bound: a caller joins one with its own bound (a 300 ms peek never answers a 3 s probe). */
45
+ probing = new Map();
46
+ constructor(options) {
47
+ this.options = options;
48
+ }
49
+ get daemonProtocol() { return this.options.daemonProtocol ?? protocolWindow(TERMINAL_PROTOCOL_VERSION); }
50
+ clientFor(paths) {
51
+ if (this.client && this.clientGen === paths.gen)
52
+ return this.client;
53
+ this.client?.close();
54
+ this.client = new KeeperClient({
55
+ kind: 'terminal', socket: paths.socket, tokenFile: paths.tokenFile, gen: paths.gen, daemonProtocol: this.daemonProtocol,
56
+ requestTimeoutMs: this.options.requestTimeoutMs, connectTimeoutMs: this.options.connectTimeoutMs,
57
+ });
58
+ this.client.on('error', () => { }); // state changes are observed through `state`; never crash the daemon on an emitter error
59
+ this.clientGen = paths.gen;
60
+ return this.client;
61
+ }
62
+ /** The hello of the connected keeper, if this client currently holds a ready connection. Never does IO. */
63
+ get hello() { return this.client?.state === 'ready' ? this.client.hello : undefined; }
64
+ /** The generation this client is bound to (`gen`), or `undefined` for the current build's. */
65
+ get gen() { return this.options.gen; }
66
+ /**
67
+ * The connected client of the current build, launching it only when needed. A ready connection to the current build's
68
+ * generation is returned as is (no manifest read, no probe), so per-request calls such as `pty.poll` cost one round trip.
69
+ * Anything else (no client yet, reconnecting, keeper gone, another generation) goes through the launcher, which starts at
70
+ * most one keeper per kind at a time. A `gen`-bound client only connects to its generation.
71
+ */
72
+ async ensure() {
73
+ const current = this.client;
74
+ if (this.options.gen !== undefined) {
75
+ if (current && current.state === 'ready')
76
+ return current;
77
+ const client = this.clientFor(this.options.launcher.pathsFor('terminal', this.options.gen));
78
+ await client.connect();
79
+ return client;
80
+ }
81
+ if (current && current.state === 'ready' && this.clientGen !== undefined && this.clientGen === this.currentGen)
82
+ return current;
83
+ const handle = await this.options.launcher.launch('terminal');
84
+ this.currentGen = handle.paths.gen;
85
+ const client = this.clientFor(handle.paths);
86
+ await client.connect();
87
+ this.notRunningUntil = 0;
88
+ this.undecidedUntil = 0;
89
+ return client;
90
+ }
91
+ /**
92
+ * The hello of keeper-terminal (current build) if it is already running, else null. Connects to a running keeper but
93
+ * NEVER starts one (spec §7: answering tools.info starts no keeper). A "not running" answer is remembered briefly. Null also when
94
+ * the keeper could not be told within `timeoutMs` (see {@link probe} for callers that must not read that as "not running").
95
+ */
96
+ async runningHello(timeoutMs = 300) {
97
+ const ready = this.hello;
98
+ if (ready)
99
+ return ready;
100
+ const now = Date.now();
101
+ if (now < this.notRunningUntil || now < this.undecidedUntil)
102
+ return null;
103
+ const presence = await this.probe(timeoutMs);
104
+ if (presence.state === 'unknown')
105
+ this.undecidedUntil = Date.now() + NOT_RUNNING_TTL_MS;
106
+ return presence.state === 'running' ? presence.hello : null;
107
+ }
108
+ /**
109
+ * Whether keeper-terminal (this client's generation) runs — `absent` only when that is proven (see {@link KeeperPresence}). Never
110
+ * starts one. Waits for a real connect and hello up to `timeoutMs`; an answer it could not get in time is `unknown`.
111
+ */
112
+ probe(timeoutMs = KEEPER_PROBE_TIMEOUT_MS) {
113
+ const ready = this.hello;
114
+ if (ready)
115
+ return Promise.resolve({ state: 'running', hello: ready });
116
+ if (Date.now() < this.notRunningUntil)
117
+ return Promise.resolve({ state: 'absent' });
118
+ let probing = this.probing.get(timeoutMs);
119
+ if (!probing) {
120
+ probing = this.probeOnce(timeoutMs).finally(() => { this.probing.delete(timeoutMs); });
121
+ this.probing.set(timeoutMs, probing);
122
+ }
123
+ return probing;
124
+ }
125
+ async probeOnce(timeoutMs) {
126
+ const absent = () => { this.notRunningUntil = Date.now() + NOT_RUNNING_TTL_MS; return { state: 'absent' }; };
127
+ let gen;
128
+ try {
129
+ gen = this.options.gen
130
+ ?? keeperGen((await readKeeperManifest(path.join(this.options.distDir ?? defaultDistDir(), 'terminal'))).buildVersion);
131
+ }
132
+ catch {
133
+ return absent();
134
+ } // no build of the current generation: nothing of it can run
135
+ const paths = this.options.launcher.pathsFor('terminal', gen);
136
+ if (this.options.gen === undefined)
137
+ this.currentGen = paths.gen;
138
+ try {
139
+ await fs.access(paths.tokenFile);
140
+ await fs.access(paths.socket);
141
+ }
142
+ catch (error) {
143
+ return ABSENT_ERRNOS.has(errnoOf(error) ?? '') ? absent() : { state: 'unknown', reason: messageOf(error) };
144
+ }
145
+ const client = this.clientFor(paths);
146
+ let timer;
147
+ try {
148
+ const result = await Promise.race([
149
+ client.connect(),
150
+ new Promise((resolve) => { timer = setTimeout(() => resolve(null), timeoutMs); timer.unref(); }),
151
+ ]);
152
+ if (result === null)
153
+ return { state: 'unknown', reason: `no answer within ${timeoutMs} ms` };
154
+ if (result.status === 'ready') {
155
+ this.notRunningUntil = 0;
156
+ this.undecidedUntil = 0;
157
+ return { state: 'running', hello: result.hello };
158
+ }
159
+ return { state: 'unknown', reason: `protocol ${result.hello.protocolVersion} is outside the daemon's window` };
160
+ }
161
+ catch (error) {
162
+ // The token or the socket went away meanwhile, or nothing listens behind a stale socket file: the keeper is gone.
163
+ return ABSENT_ERRNOS.has(errnoOf(error) ?? '') ? absent() : { state: 'unknown', reason: messageOf(error) };
164
+ }
165
+ finally {
166
+ clearTimeout(timer);
167
+ }
168
+ }
169
+ /** `tools.info` terminal fields from a running keeper's hello, else from `fallback` (a cached node-pty check). Starts nothing. */
170
+ async terminalStatus(fallback) {
171
+ const hello = await this.runningHello();
172
+ return hello ? terminalStatusOf(hello) : fallback();
173
+ }
174
+ /** A failure to reach the keeper (launch, connect, hello) surfaces as {@link KeeperLaunchError}: nothing was sent. */
175
+ async call(method, params, options = {}) {
176
+ let client;
177
+ try {
178
+ client = await this.ensure();
179
+ }
180
+ catch (error) {
181
+ throw new KeeperLaunchError(error);
182
+ }
183
+ return client.request(method, params, options);
184
+ }
185
+ create(params) { return this.call('pty.create', params); }
186
+ attach(params) { return this.call('pty.attach', params); }
187
+ poll(params) { return this.call('pty.poll', params); }
188
+ write(params) { return this.call('pty.write', params); }
189
+ resize(params) { return this.call('pty.resize', params); }
190
+ takeover(params) { return this.call('pty.takeover', params); }
191
+ detach(params) { return this.call('pty.detach', params); }
192
+ close(params) { return this.call('pty.close', params); }
193
+ list() { return this.call('pty.list', {}); }
194
+ activity() { return this.call('keeper.activity', {}); }
195
+ // exec.* (spec §4.2). The daemon decides argv/env/deadline/quotas; the keeper only executes them.
196
+ execStart(params, options = {}) { return this.call('exec.start', params, options); }
197
+ execList() { return this.call('exec.list', {}); }
198
+ /** Descriptor plus the latest checkpoint (blob as given to `execCheckpoint`). */
199
+ execStatus(execId, options = {}) { return this.call('exec.status', { execId }, options); }
200
+ execRead(params) { return this.call('exec.read', params); }
201
+ execKill(params) { return this.call('exec.kill', params); }
202
+ execCommit(params) { return this.call('exec.commit', params); }
203
+ execCheckpoint(params) { return this.call('exec.checkpoint', params); }
204
+ /**
205
+ * Streams an exec's records from `from` with credit backpressure (kit stream `exec/<execId>`); after a reconnect the kit client
206
+ * resumes after the last record delivered.
207
+ */
208
+ async execSubscribe(execId, handler, options) {
209
+ return (await this.ensure()).subscribe(execStream(execId), handler, options);
210
+ }
211
+ /** Drops the connection (the keeper and its PTYs keep running). */
212
+ disconnect() { this.client?.close(); this.client = undefined; this.clientGen = undefined; }
213
+ }