@agentdocumentformat/cli 0.7.8 → 0.8.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 (100) hide show
  1. package/README.md +1 -1
  2. package/dist/adf.mjs +59 -8
  3. package/dist/chunks/{APEv2Parser-2CNNHMXV.mjs → APEv2Parser-WIXRJLHB.mjs} +2 -2
  4. package/dist/chunks/{AiffParser-7BR4RL6G.mjs → AiffParser-ZC4QFOVJ.mjs} +5 -5
  5. package/dist/chunks/{App-7RIIOHJJ.mjs → App-A5GUFCFJ.mjs} +279 -293
  6. package/dist/chunks/{DsdiffParser-CMD4AX7A.mjs → DsdiffParser-UAPAJHFX.mjs} +5 -5
  7. package/dist/chunks/{DsfParser-UOGZDS2M.mjs → DsfParser-NNYZK2QX.mjs} +6 -6
  8. package/dist/chunks/{FlacParser-HB3T3CD4.mjs → FlacParser-MW2W4LO3.mjs} +6 -6
  9. package/dist/chunks/{MP4Parser-66HBRUSX.mjs → MP4Parser-Z57SYOOQ.mjs} +4 -4
  10. package/dist/chunks/{MpegParser-YW6LIUEW.mjs → MpegParser-XIIPAZVM.mjs} +7 -7
  11. package/dist/chunks/{MusepackParser-PAUSXP7D.mjs → MusepackParser-QWNDEYHJ.mjs} +6 -6
  12. package/dist/chunks/{OggParser-NUBV3GWC.mjs → OggParser-WRX53F77.mjs} +9 -9
  13. package/dist/chunks/{WavPackParser-WQAGT7TC.mjs → WavPackParser-MJ7WCSJ5.mjs} +2 -2
  14. package/dist/chunks/{WaveParser-EWLQVDX4.mjs → WaveParser-RAVLHZ5S.mjs} +7 -7
  15. package/dist/chunks/{adf-schema-US4NFHMR.mjs → adf-schema-YJSGLMA4.mjs} +2 -2
  16. package/dist/chunks/auth-manager-AJ32FZWS.mjs +19 -0
  17. package/dist/chunks/auth-manager-C5OBEQK2.mjs +18 -0
  18. package/dist/chunks/auth-manager-TBNKCJ45.mjs +17 -0
  19. package/dist/chunks/{chatgpt-subscription-E4MXTIAT.mjs → chatgpt-subscription-MMGNW5KJ.mjs} +5 -2
  20. package/dist/chunks/chunk-3UGZFWIF.mjs +26 -0
  21. package/dist/chunks/{chunk-5PO5PKRV.mjs → chunk-4OGZFUKA.mjs} +126 -67
  22. package/dist/chunks/{chunk-VN7UH7I5.mjs → chunk-6XQZGYMK.mjs} +246 -67
  23. package/dist/chunks/{chunk-XNPZBLYL.mjs → chunk-75DC5EWN.mjs} +13 -2
  24. package/dist/chunks/chunk-AZYOXXVL.mjs +865 -0
  25. package/dist/chunks/{chunk-6VQEXLE2.mjs → chunk-BHY7QDCM.mjs} +41 -3
  26. package/dist/chunks/chunk-C2S64Y6F.mjs +203 -0
  27. package/dist/chunks/chunk-C4GA5SI4.mjs +12799 -0
  28. package/dist/chunks/chunk-DDTTSKGG.mjs +2443 -0
  29. package/dist/chunks/{chunk-VAUOM3IN.mjs → chunk-DLWCKKIO.mjs} +1 -1
  30. package/dist/chunks/{chunk-QPLEAE6V.mjs → chunk-G6NBFYG5.mjs} +152 -824
  31. package/dist/chunks/{chunk-KXEF4F4E.mjs → chunk-GAZO6UMI.mjs} +1 -1
  32. package/dist/chunks/{chunk-XYTWGHFS.mjs → chunk-H3XLRWVE.mjs} +1 -1
  33. package/dist/chunks/{chunk-7T2YMTWL.mjs → chunk-H4C65MTP.mjs} +4 -4
  34. package/dist/chunks/chunk-HBOFZRUS.mjs +738 -0
  35. package/dist/chunks/chunk-JVPZIMXW.mjs +976 -0
  36. package/dist/chunks/{chunk-XYV3VCIX.mjs → chunk-JZFONJSL.mjs} +79 -20
  37. package/dist/chunks/chunk-KDDVQKCG.mjs +65 -0
  38. package/dist/chunks/chunk-KRPKWOMB.mjs +290 -0
  39. package/dist/chunks/{chunk-G6PH7RPW.mjs → chunk-LCMANRYY.mjs} +3 -3
  40. package/dist/chunks/{chunk-ZESQMP66.mjs → chunk-LGL6ML37.mjs} +3 -3
  41. package/dist/chunks/chunk-LKFHERRV.mjs +145 -0
  42. package/dist/chunks/chunk-LTX74NU6.mjs +29 -0
  43. package/dist/chunks/chunk-M2F7C2UJ.mjs +425 -0
  44. package/dist/chunks/{chunk-62NE4LG4.mjs → chunk-MQAMI5BF.mjs} +5 -5
  45. package/dist/chunks/chunk-MZRXFWPQ.mjs +278 -0
  46. package/dist/chunks/{chunk-PRMGZZM5.mjs → chunk-NZLEPJ5M.mjs} +2 -0
  47. package/dist/chunks/{chunk-CD3ATSXE.mjs → chunk-NZO5O4VN.mjs} +1 -1
  48. package/dist/chunks/{chunk-I3UYSITV.mjs → chunk-O7XKQ6CH.mjs} +1 -1
  49. package/dist/chunks/chunk-P3RG5LQA.mjs +244 -0
  50. package/dist/chunks/chunk-PAK5JCO2.mjs +48 -0
  51. package/dist/chunks/chunk-PC63YFB7.mjs +34 -0
  52. package/dist/chunks/{daemon-control-HKFVSQTQ.mjs → chunk-PRPTKMQW.mjs} +67 -26
  53. package/dist/chunks/{chunk-LFMB4PAA.mjs → chunk-TKXIH27X.mjs} +974 -113
  54. package/dist/chunks/{chunk-5W7KES6P.mjs → chunk-UZPDETEU.mjs} +1 -1
  55. package/dist/chunks/chunk-V2T6NZX2.mjs +517 -0
  56. package/dist/chunks/chunk-V3MM6PCH.mjs +366 -0
  57. package/dist/chunks/chunk-WJGPNHGX.mjs +67 -0
  58. package/dist/chunks/chunk-WVTPPOKK.mjs +290 -0
  59. package/dist/chunks/{chunk-J74STFKE.mjs → chunk-WX6QCUWI.mjs} +272 -51
  60. package/dist/chunks/{chunk-Y5ZLKFLE.mjs → chunk-XNNJQCZP.mjs} +196 -165
  61. package/dist/chunks/{chunk-HDBPBORT.mjs → chunk-XT2BJUFC.mjs} +15 -6
  62. package/dist/chunks/{chunk-HSBV6YFU.mjs → chunk-YRMKSHW3.mjs} +614 -92
  63. package/dist/chunks/{chunk-BNXUAOO4.mjs → chunk-ZGXUOAWZ.mjs} +3186 -959
  64. package/dist/chunks/chunk-ZPB3HYM7.mjs +45 -0
  65. package/dist/chunks/claude-subscription-33BMZB6I.mjs +29 -0
  66. package/dist/chunks/{cli-NMFIAR7Z.mjs → cli-I47IFDHJ.mjs} +797 -56
  67. package/dist/chunks/{commands-KPJWFRUE.mjs → commands-E4EQUHE5.mjs} +4 -3
  68. package/dist/chunks/{daemon-YDIK3AAM.mjs → daemon-FQ5BV3AP.mjs} +82058 -63958
  69. package/dist/chunks/daemon-control-L3CLG63P.mjs +59 -0
  70. package/dist/chunks/{daemon-token-WRSULP7G.mjs → daemon-token-L5QKTHU5.mjs} +3 -1
  71. package/dist/chunks/{discord-DSP4HUWI.mjs → discord-IR62565M.mjs} +3 -52
  72. package/dist/chunks/{email-BRG7KUO2.mjs → email-KHHTJBDW.mjs} +4 -2
  73. package/dist/chunks/{grok-subscription-4PYX7TBF.mjs → grok-subscription-E74FS5EG.mjs} +5 -2
  74. package/dist/chunks/{lib-N7FCZWKH.mjs → lib-L27L5PXM.mjs} +22 -22
  75. package/dist/chunks/{open-VAU7PXT6.mjs → open-TLGS2Z3Q.mjs} +4 -4
  76. package/dist/chunks/{parser-JVY2PWSM.mjs → parser-7GARNT5L.mjs} +1 -1
  77. package/dist/chunks/{pipeline-executor-O77NTGLP.mjs → pipeline-executor-FD4FBWQA.mjs} +6 -5
  78. package/dist/chunks/prompt-RRHZX4YT.mjs +13 -0
  79. package/dist/chunks/remote-access-cli-XXAPQWH6.mjs +268 -0
  80. package/dist/chunks/remote-hello-UFWUBDQI.mjs +37 -0
  81. package/dist/chunks/sdk-5FD2ZP7N.mjs +28422 -0
  82. package/dist/chunks/{slack-OCNNF4DX.mjs → slack-IYC5RAB5.mjs} +3 -4
  83. package/dist/chunks/{store-HUVDJPYN.mjs → store-ZRN2WCFB.mjs} +6 -3
  84. package/dist/chunks/tailscale-WLJATFMB.mjs +25 -0
  85. package/dist/chunks/{theme-SFE3JMA2.mjs → theme-HLBDTF6F.mjs} +1 -1
  86. package/dist/chunks/{themes-YLXLOIJF.mjs → themes-BQ72P446.mjs} +2 -2
  87. package/dist/chunks/{token-6G3HCMNX.mjs → token-6D22WECM.mjs} +20 -16
  88. package/dist/chunks/{token-util-UXYSDQIW.mjs → token-util-YF3ZWBZ4.mjs} +1 -2
  89. package/dist/chunks/{tui-UQJLK7XI.mjs → tui-SPSPDADM.mjs} +17 -14
  90. package/dist/chunks/{welcome-XHXFV7SH.mjs → welcome-J5JZZAM5.mjs} +1 -1
  91. package/dist/chunks/{whatsapp-AJMRQBT7.mjs → whatsapp-YJFFVN4Q.mjs} +9 -9
  92. package/package.json +1 -1
  93. package/dist/chunks/chunk-GKKCMXIZ.mjs +0 -94
  94. package/dist/chunks/chunk-IHDDCZBS.mjs +0 -112
  95. package/dist/chunks/chunk-KWFOS5WC.mjs +0 -41
  96. package/dist/chunks/chunk-UEZR2CNS.mjs +0 -65
  97. package/dist/chunks/chunk-VMHTYDH4.mjs +0 -172
  98. package/dist/chunks/chunk-Y2QA53AN.mjs +0 -259
  99. package/dist/chunks/{chunk-NBTUWMGP.mjs → chunk-2MTE22CR.mjs} +3 -3
  100. package/dist/chunks/{telegram-2EFGKIVK.mjs → telegram-JYY2VDTI.mjs} +5 -5
@@ -7,15 +7,25 @@ const __dirname = __adfDirname(__filename);
7
7
  import {
8
8
  DaemonError,
9
9
  MAIN_LOOP
10
- } from "./chunk-XNPZBLYL.mjs";
10
+ } from "./chunk-75DC5EWN.mjs";
11
11
  import {
12
12
  cjs
13
13
  } from "./chunk-SGUTYISF.mjs";
14
14
  import {
15
15
  daemon_url_exports
16
- } from "./chunk-GKKCMXIZ.mjs";
16
+ } from "./chunk-V2T6NZX2.mjs";
17
+ import {
18
+ __export
19
+ } from "./chunk-M2RX3S2T.mjs";
20
+
21
+ // src/shared/daemon-client/client.ts
22
+ var client_exports = {};
23
+ __export(client_exports, {
24
+ DaemonClient: () => DaemonClient,
25
+ staticCredentials: () => staticCredentials
26
+ });
17
27
 
18
- // src/main/tui/api/sse.ts
28
+ // src/shared/daemon-client/sse.ts
19
29
  var EventStream = class {
20
30
  options;
21
31
  fetchImpl;
@@ -31,6 +41,8 @@ var EventStream = class {
31
41
  resumePending = !1;
32
42
  seen = /* @__PURE__ */ new Set();
33
43
  seenOrder = [];
44
+ /** Remembered keys that a daemon restart invalidates (DedupeKey.cursorScoped). */
45
+ cursorScoped = /* @__PURE__ */ new Set();
34
46
  idleTimer = null;
35
47
  retryTimer = null;
36
48
  info = { state: "idle", attempt: 0 };
@@ -67,10 +79,12 @@ var EventStream = class {
67
79
  }
68
80
  }
69
81
  buildUrl() {
70
- let params = new URLSearchParams();
71
- this.options.agentId && params.set("agentId", this.options.agentId), this.lastCursor >= 0 ? (params.set("since", String(this.lastCursor)), this.epoch && params.set("epoch", this.epoch)) : this.options.replay || params.set("since", String(Number.MAX_SAFE_INTEGER));
82
+ let params = new URLSearchParams(), query = typeof this.options.query == "function" ? this.options.query() : this.options.query;
83
+ for (let [key, value] of Object.entries(query ?? {}))
84
+ value == null || value === "" || params.set(key, String(value));
85
+ this.options.agentId && params.set("agentId", this.options.agentId), this.lastCursor >= 0 ? (params.set("since", String(this.lastCursor)), this.epoch ? params.set("epoch", this.epoch) : params.delete("epoch")) : (this.options.replay ? params.delete("since") : params.set("since", String(Number.MAX_SAFE_INTEGER)), params.delete("epoch"));
72
86
  let qs = params.toString();
73
- return `${this.options.baseUrl}/events${qs ? `?${qs}` : ""}`;
87
+ return `${this.options.baseUrl}${this.options.path ?? "/events"}${qs ? `?${qs}` : ""}`;
74
88
  }
75
89
  async connect() {
76
90
  if (this.closed) return;
@@ -81,12 +95,17 @@ var EventStream = class {
81
95
  this.controller = controller;
82
96
  let failure;
83
97
  try {
84
- let response = await this.fetchImpl(this.buildUrl(), {
85
- headers: { Accept: "text/event-stream", ...typeof this.options.headers == "function" ? this.options.headers() : this.options.headers ?? {} },
86
- signal: controller.signal
98
+ let url = this.buildUrl();
99
+ if (await this.options.beforeConnect?.(url), this.closed) return;
100
+ let response = await this.fetchImpl(url, {
101
+ headers: { Accept: "text/event-stream", ...typeof this.options.headers == "function" ? this.options.headers(url) : this.options.headers ?? {} },
102
+ signal: controller.signal,
103
+ // A redirect would carry the headers (token) to wherever it points.
104
+ redirect: "manual"
87
105
  });
88
106
  if (!response.ok || !response.body)
89
- throw new Error(`HTTP ${response.status} ${response.statusText}`.trim());
107
+ throw response.body?.cancel().catch(() => {
108
+ }), isRedirect(response) ? new Error(redirectMessage(this.options.baseUrl, response)) : new Error(`HTTP ${response.status} ${response.statusText}`.trim());
90
109
  this.attempt = 0, this.resumePending = resumed, this.hasOpened = !0, this.setState({ state: "open", attempt: 0, resumed }), this.armIdle(), await this.read(response.body, controller), failure = "stream ended";
91
110
  } catch (err) {
92
111
  failure = controller.signal.aborted && this.closed ? void 0 : errorMessage(err);
@@ -94,6 +113,10 @@ var EventStream = class {
94
113
  this.clearIdle();
95
114
  }
96
115
  if (this.closed) return;
116
+ try {
117
+ this.options.onDrop?.();
118
+ } catch {
119
+ }
97
120
  this.attempt += 1;
98
121
  let delay = this.backoff();
99
122
  this.setState({ state: "reconnecting", attempt: this.attempt, error: failure, retryInMs: delay }), this.retryTimer = setTimeout(() => {
@@ -153,18 +176,19 @@ var EventStream = class {
153
176
  `));
154
177
  return;
155
178
  }
156
- let frame;
179
+ let parsed;
157
180
  try {
158
- frame = JSON.parse(data.join(`
181
+ parsed = JSON.parse(data.join(`
159
182
  `));
160
183
  } catch {
161
184
  return;
162
185
  }
163
- if (!frame || typeof frame != "object" || !frame.event) return;
186
+ if (!(this.options.isFrame ?? isEventFrame)(parsed)) return;
187
+ let frame = parsed;
164
188
  typeof frame.cursor == "number" && (frame.cursor < this.lastCursor && this.forgetCursorKeys(), this.lastCursor = frame.cursor);
165
- let key = dedupeKey(frame);
189
+ let key = this.options.dedupeKey ? this.options.dedupeKey(frame) : defaultDedupeKey(frame);
166
190
  if (key) {
167
- if (this.seen.has(key)) return;
191
+ if (this.seen.has(key.key)) return;
168
192
  this.remember(key);
169
193
  }
170
194
  try {
@@ -196,7 +220,14 @@ var EventStream = class {
196
220
  return;
197
221
  }
198
222
  let reason = data.reason === "epoch_changed" ? "epoch_changed" : "evicted";
199
- reason === "epoch_changed" && (this.forgetCursorKeys(), this.lastCursor = -1), this.reportResume({ exact: !1, reason, epoch });
223
+ reason === "epoch_changed" && (this.forgetCursorKeys(), this.lastCursor = -1);
224
+ let gap = { reason, epoch };
225
+ (typeof data.requestedCursor == "number" || data.requestedCursor === null) && (gap.requestedCursor = data.requestedCursor), (typeof data.oldestCursor == "number" || data.oldestCursor === null) && (gap.oldestCursor = data.oldestCursor), typeof data.latestCursor == "number" && (gap.latestCursor = data.latestCursor), typeof data.dropped == "number" && (gap.dropped = data.dropped);
226
+ try {
227
+ this.options.onGap?.(gap);
228
+ } catch {
229
+ }
230
+ this.reportResume({ exact: !1, reason, epoch });
200
231
  }
201
232
  reportResume(info) {
202
233
  if (this.resumePending) {
@@ -207,24 +238,42 @@ var EventStream = class {
207
238
  }
208
239
  }
209
240
  }
210
- remember(key) {
211
- this.seen.add(key), this.seenOrder.push(key);
241
+ remember({ key, cursorScoped }) {
242
+ this.seen.add(key), this.seenOrder.push(key), cursorScoped && this.cursorScoped.add(key);
212
243
  let cap = this.options.dedupeWindow ?? 5e3;
213
244
  for (; this.seenOrder.length > cap; ) {
214
245
  let old = this.seenOrder.shift();
215
- old && this.seen.delete(old);
246
+ old && (this.seen.delete(old), this.cursorScoped.delete(old));
216
247
  }
217
248
  }
249
+ /** The daemon restarted: keys built from its cursors no longer identify anything. */
218
250
  forgetCursorKeys() {
219
- for (let i = this.seenOrder.length - 1; i >= 0; i--) {
220
- let key = this.seenOrder[i];
221
- key.startsWith("c:") && (this.seen.delete(key), this.seenOrder.splice(i, 1));
251
+ if (this.cursorScoped.size !== 0) {
252
+ for (let i = this.seenOrder.length - 1; i >= 0; i--) {
253
+ let key = this.seenOrder[i];
254
+ this.cursorScoped.has(key) && (this.seen.delete(key), this.seenOrder.splice(i, 1));
255
+ }
256
+ this.cursorScoped.clear();
222
257
  }
223
258
  }
224
259
  };
225
260
  function dedupeKey(frame) {
226
261
  let { event } = frame;
227
- return event.agent_id && typeof event.seq == "number" && event.seq > 0 ? `a:${event.agent_id}:${event.seq}` : typeof frame.cursor == "number" ? `c:${frame.cursor}` : null;
262
+ return event?.agent_id && typeof event.seq == "number" && event.seq > 0 ? `a:${event.agent_id}:${event.seq}` : typeof frame.cursor == "number" ? `c:${frame.cursor}` : null;
263
+ }
264
+ function defaultDedupeKey(frame) {
265
+ let key = dedupeKey(frame);
266
+ return key ? { key, cursorScoped: key.startsWith("c:") } : null;
267
+ }
268
+ function isRedirect(response) {
269
+ return response.type === "opaqueredirect" || response.status >= 300 && response.status < 400 && response.status !== 304;
270
+ }
271
+ function redirectMessage(baseUrl, response) {
272
+ let location = response.headers.get("location");
273
+ return `Daemon at ${baseUrl} answered a redirect (HTTP ${response.status}${location ? ` to ${location}` : ""}); redirects are not followed, so the token stays with ${baseUrl}`;
274
+ }
275
+ function isEventFrame(value) {
276
+ return !!value && typeof value == "object" && !!value.event;
228
277
  }
229
278
  function errorMessage(err) {
230
279
  if (err instanceof Error) {
@@ -233,8 +282,16 @@ function errorMessage(err) {
233
282
  }
234
283
  return String(err);
235
284
  }
285
+ function isClientFrame(value) {
286
+ if (!value || typeof value != "object") return !1;
287
+ let { kind, cursor } = value;
288
+ return (kind === "executor" || kind === "host" || kind === "push" || kind === "umbilical" || kind === "turn") && typeof cursor == "number";
289
+ }
290
+ function clientFrameDedupeKey(frame) {
291
+ return typeof frame.cursor == "number" ? { key: `s:${frame.cursor}`, cursorScoped: !0 } : null;
292
+ }
236
293
 
237
- // src/main/tui/api/normalize.ts
294
+ // src/shared/daemon-client/normalize.ts
238
295
  var obj = (v) => v && typeof v == "object" && !Array.isArray(v) ? v : {}, arr = (v) => Array.isArray(v) ? v : [], num = (v) => typeof v == "number" && Number.isFinite(v) ? v : 0;
239
296
  function normalizeRuntime(raw) {
240
297
  let r = obj(raw), daemon = obj(r.daemon), providers = obj(r.providers), network = obj(r.network), mesh = obj(network.mesh), websocket = obj(network.websocket);
@@ -252,83 +309,119 @@ function normalizeRuntime(raw) {
252
309
  };
253
310
  }
254
311
 
255
- // src/main/tui/api/client.ts
256
- var { localDaemonToken, localProofHeaders, resolveDaemonToken, resolveDaemonUrl } = cjs(daemon_url_exports), enc = encodeURIComponent;
257
- function sameOrigin(a, b) {
312
+ // src/shared/daemon-client/client.ts
313
+ function staticCredentials(token) {
314
+ return { token: () => token };
315
+ }
316
+ var enc = encodeURIComponent;
317
+ function originOf(url) {
258
318
  try {
259
- return new URL(a).origin === new URL(b).origin;
319
+ let origin = new URL(url).origin;
320
+ return origin === "null" ? null : origin;
260
321
  } catch {
261
- return !1;
322
+ return null;
262
323
  }
263
324
  }
264
- var DaemonClient = class _DaemonClient {
325
+ var DaemonClient = class {
265
326
  baseUrl;
266
- token;
327
+ /** The one origin `credentials` are sent to. */
328
+ origin;
329
+ credentials;
267
330
  fetchImpl;
268
331
  timeoutMs;
269
332
  options;
270
- constructor(options = {}) {
271
- this.baseUrl = resolveDaemonUrl(options.baseUrl), this.token = resolveDaemonToken(options.token, options.env ?? process.env, options.localToken ? this.baseUrl : void 0), this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis), this.timeoutMs = options.timeoutMs ?? 15e3, this.options = options;
333
+ constructor(options) {
334
+ this.baseUrl = options.baseUrl.replace(/\/+$/, ""), this.origin = originOf(this.baseUrl), this.credentials = options.credentials, this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis), this.timeoutMs = options.timeoutMs ?? 15e3, this.options = options;
272
335
  }
273
336
  /**
274
- * Same transport (fetch, timeout) against another daemon. The current token
275
- * is carried over only to the same origin; another origin gets `token`, or
276
- * ADF_DAEMON_TOKEN, or none — never this daemon's bearer token.
337
+ * Same transport (fetch, timeout) against another daemon. The current
338
+ * credentials are carried over only to the same origin without a `token`;
339
+ * otherwise the client gets `credentialsFor(baseUrl, token)` (or just
340
+ * `token`), or none — never this daemon's.
277
341
  */
278
342
  withBaseUrl(baseUrl, token) {
279
- let carried = sameOrigin(this.baseUrl, resolveDaemonUrl(baseUrl)) ? this.token : void 0;
280
- return new _DaemonClient({ ...this.options, baseUrl, token: token ?? carried });
343
+ let next = baseUrl.replace(/\/+$/, ""), credentials = token ? this.options.credentialsFor?.(next, token) ?? staticCredentials(token) : this.origin !== null && originOf(next) === this.origin ? this.credentials : this.options.credentialsFor?.(next);
344
+ return this.derive({ ...this.options, baseUrl: next, credentials });
345
+ }
346
+ /** Same daemon and credentials, another default timeout for the calls made through it. */
347
+ withTimeout(timeoutMs) {
348
+ return this.derive({ ...this.options, timeoutMs });
349
+ }
350
+ /** Same daemon and credentials; every request names this client session (null: none). */
351
+ withClientSession(sessionId) {
352
+ return this.derive({ ...this.options, clientSession: sessionId ?? void 0 });
353
+ }
354
+ /**
355
+ * A client like this one with other options; `withBaseUrl` and
356
+ * `withTimeout` build through it. A subclass whose constructor takes other
357
+ * options overrides it so the derived client keeps the subclass.
358
+ */
359
+ derive(options) {
360
+ return new this.constructor(options);
281
361
  }
282
362
  /** Whether requests carry a bearer token. */
283
363
  get hasToken() {
284
- return !!this.token;
364
+ return !!this.credentials?.token();
285
365
  }
286
366
  // --- transport ------------------------------------------------------------
287
367
  url(path, query) {
288
368
  let qs = query ? buildQuery(query) : "";
289
369
  return `${this.baseUrl}${path}${qs}`;
290
370
  }
371
+ /** Headers for a request to `baseUrl` itself. */
291
372
  headers(extra = {}) {
373
+ return this.headersFor(this.baseUrl, extra);
374
+ }
375
+ /**
376
+ * Headers for a request to `url`: the bearer token (and `localProof` for
377
+ * `path`) only when `url` has the credentials' origin. A path that turns
378
+ * the URL into another host (`@host`, a full URL) gets no credentials.
379
+ */
380
+ headersFor(url, extra = {}, path) {
381
+ let own = this.ownsUrl(url), token = own ? this.credentials?.token() : void 0, session = own ? this.options.clientSession : void 0;
292
382
  return {
293
383
  Accept: "application/json",
294
- ...this.token ? { Authorization: `Bearer ${this.token}` } : {},
384
+ ...token ? { Authorization: `Bearer ${token}` } : {},
385
+ ...session ? { "X-ADF-Client-Session": session } : {},
386
+ ...own && path !== void 0 ? this.credentials?.localProof?.(path) ?? {} : {},
295
387
  ...extra
296
388
  };
297
389
  }
298
- /**
299
- * The daemon answered 401: with `localToken` and no explicit token, pick up
300
- * a token file that appeared or changed since (daemon first start). True
301
- * when the token changed, so the request is worth one retry.
302
- */
303
- refreshLocalToken() {
304
- if (!this.options.localToken || this.options.token) return !1;
305
- let env = this.options.env ?? process.env;
306
- if (env.ADF_DAEMON_TOKEN) return !1;
307
- let fresh = localDaemonToken(this.baseUrl, env);
308
- return !fresh || fresh === this.token ? !1 : (this.token = fresh, !0);
390
+ ownsUrl(url) {
391
+ return this.origin !== null && originOf(url) === this.origin;
309
392
  }
310
393
  async request(method, path, options = {}, retried = !1) {
311
394
  let controller = new AbortController(), timeoutMs = options.timeoutMs ?? this.timeoutMs, timer = setTimeout(() => controller.abort(new Error("timeout")), timeoutMs), onAbort = () => controller.abort(options.signal?.reason);
312
- options.signal?.addEventListener("abort", onAbort, { once: !0 });
313
- let response;
395
+ options.signal?.aborted ? onAbort() : options.signal?.addEventListener("abort", onAbort, { once: !0 });
396
+ let url = this.url(path, options.query), response, text, own = this.ownsUrl(url);
314
397
  try {
315
- response = await this.fetchImpl(this.url(path, options.query), {
398
+ if (controller.signal.throwIfAborted(), own && this.credentials?.ready)
399
+ try {
400
+ await this.credentials.ready();
401
+ } catch (err) {
402
+ throw new DaemonError(errorMessage2(err), null);
403
+ }
404
+ if (response = await this.fetchImpl(url, {
316
405
  method,
317
- headers: this.headers({
318
- ...options.body !== void 0 ? { "Content-Type": "application/json" } : {},
319
- // Proxy-mode daemons (ADF_DAEMON_BEHIND_PROXY) need this machine's proof on local-only routes.
320
- ...this.options.localToken ? localProofHeaders(this.baseUrl, path, this.options.env ?? process.env) : {}
321
- }),
406
+ // Proxy-mode daemons (ADF_DAEMON_BEHIND_PROXY) need this machine's proof on local-only routes.
407
+ headers: this.headersFor(url, options.body !== void 0 ? { "Content-Type": "application/json" } : {}, path),
322
408
  body: options.body !== void 0 ? JSON.stringify(options.body) : void 0,
323
- signal: controller.signal
324
- });
409
+ signal: controller.signal,
410
+ // Never followed: a 302 would forward the token / local proof, a 307 the body.
411
+ redirect: "manual"
412
+ }), isRedirect(response))
413
+ throw response.body?.cancel().catch(() => {
414
+ }), new DaemonError(redirectMessage(this.baseUrl, response), response.status);
415
+ text = await response.text();
325
416
  } catch (err) {
417
+ if (err instanceof DaemonError) throw err;
418
+ own && this.credentials?.dropped?.();
326
419
  let reason = controller.signal.aborted && !options.signal?.aborted ? `timed out after ${timeoutMs}ms` : errorMessage2(err);
327
420
  throw new DaemonError(`Cannot reach daemon at ${this.baseUrl}: ${reason}`, null);
328
421
  } finally {
329
422
  clearTimeout(timer), options.signal?.removeEventListener("abort", onAbort);
330
423
  }
331
- let text = await response.text(), body = null;
424
+ let body = null;
332
425
  if (text.trim())
333
426
  try {
334
427
  body = JSON.parse(text);
@@ -336,7 +429,7 @@ var DaemonClient = class _DaemonClient {
336
429
  body = text;
337
430
  }
338
431
  if (!response.ok) {
339
- if (response.status === 401 && !retried && this.refreshLocalToken()) return this.request(method, path, options, !0);
432
+ if (response.status === 401 && !retried && this.ownsUrl(url) && this.credentials?.refresh?.()) return this.request(method, path, options, !0);
340
433
  let message = isRecord(body) && typeof body.error == "string" ? body.error : `HTTP ${response.status} ${response.statusText}`;
341
434
  throw new DaemonError(message, response.status, body);
342
435
  }
@@ -357,11 +450,65 @@ var DaemonClient = class _DaemonClient {
357
450
  del(path, query) {
358
451
  return this.request("DELETE", path, { query });
359
452
  }
360
- /** Live umbilical events (SSE) with auto-reconnect. Call `.start()` on the result. */
453
+ /**
454
+ * Live events (SSE) with auto-reconnect: `GET /events` (umbilical frames)
455
+ * unless `path` names another stream. Call `.start()` on the result.
456
+ */
361
457
  events(options) {
362
- return new EventStream({ ...options, baseUrl: this.baseUrl, headers: () => this.headers({ Accept: "text/event-stream" }), fetch: this.fetchImpl });
458
+ return new EventStream({
459
+ ...options,
460
+ baseUrl: this.baseUrl,
461
+ headers: (url) => this.headersFor(url, { Accept: "text/event-stream" }),
462
+ fetch: this.fetchImpl,
463
+ beforeConnect: async (url) => {
464
+ this.ownsUrl(url) && await this.credentials?.ready?.();
465
+ },
466
+ onDrop: () => this.credentials?.dropped?.()
467
+ });
468
+ }
469
+ // --- client sessions (design D5; internal) ---------------------------------
470
+ /** POST /client/sessions: open a session. Its stream starts at the first frame after this call. */
471
+ createClientSession(input) {
472
+ return this.post("/client/sessions", input);
473
+ }
474
+ /**
475
+ * GET /client/sessions/:id/events: the session's frames (executor, host,
476
+ * push). Replays from the session's first frame unless `since` is given;
477
+ * reconnects resume with `?since=&epoch=`. `onGap` / `onResume` report lost
478
+ * frames (resync then, design D6). A 404 means the session is gone (it
479
+ * expired or the daemon restarted): close the stream and open a new
480
+ * session. Call `.start()` on the result.
481
+ */
482
+ clientSessionEvents(sessionId, options) {
483
+ return this.events({
484
+ replay: !0,
485
+ dedupeKey: clientFrameDedupeKey,
486
+ ...options,
487
+ path: `/client/sessions/${enc(sessionId)}/events`,
488
+ isFrame: (value) => isClientFrame(value)
489
+ });
490
+ }
491
+ /** PUT /client/sessions/:id/focus: the agent whose deltas and full tool results this session gets (null: none). */
492
+ setClientSessionFocus(sessionId, agentId) {
493
+ return this.put(`/client/sessions/${enc(sessionId)}/focus`, { agentId });
494
+ }
495
+ /** POST /client/sessions/:id/documents: hold an agent file open for this session. */
496
+ holdClientSessionDocument(sessionId, document) {
497
+ return this.post(`/client/sessions/${enc(sessionId)}/documents`, document);
498
+ }
499
+ /** DELETE /client/sessions/:id/documents/:agentId. */
500
+ releaseClientSessionDocument(sessionId, agentId) {
501
+ return this.del(`/client/sessions/${enc(sessionId)}/documents/${enc(agentId)}`);
502
+ }
503
+ /** DELETE /client/sessions/:id: end the session now; its documents are released. */
504
+ endClientSession(sessionId) {
505
+ return this.del(`/client/sessions/${enc(sessionId)}`);
363
506
  }
364
507
  // --- daemon ---------------------------------------------------------------
508
+ /** GET /version: build, client API version, settings file, pid, who started this run (§8.2). */
509
+ version() {
510
+ return this.get("/version");
511
+ }
365
512
  health() {
366
513
  return this.get("/health");
367
514
  }
@@ -433,7 +580,7 @@ var DaemonClient = class _DaemonClient {
433
580
  lanAddresses() {
434
581
  return this.get("/network/mesh/lan-addresses");
435
582
  }
436
- // --- subscription provider sign-in (ChatGPT, Grok) ------------------------
583
+ // --- subscription provider sign-in (ChatGPT, Grok, Claude) ----------------
437
584
  // Sign-in flows themselves (browser, callback server, polling) live in
438
585
  // cli/auth-flow.ts over `request`; these are the plain reads and sign-out.
439
586
  subscriptionStatus(provider) {
@@ -442,6 +589,14 @@ var DaemonClient = class _DaemonClient {
442
589
  logoutSubscription(provider) {
443
590
  return this.post(`/auth/${provider}/logout`);
444
591
  }
592
+ /** Hand the code Claude's sign-in page shows to the daemon's waiting Claude Code. */
593
+ submitClaudeCode(code) {
594
+ return this.post("/auth/claude/code", { code });
595
+ }
596
+ /** Stop a running Claude sign-in on the daemon host. */
597
+ cancelClaudeAuth() {
598
+ return this.post("/auth/claude/cancel");
599
+ }
445
600
  // --- owner identity + agent creation --------------------------------------
446
601
  // create / restore / unlock answer loopback callers only (403 loopback_only).
447
602
  // Nothing here logs or keeps a request or response body.
@@ -861,6 +1016,30 @@ function errorMessage2(err) {
861
1016
  return String(err);
862
1017
  }
863
1018
 
1019
+ // src/main/tui/api/client.ts
1020
+ var { daemonCredentials, resolveDaemonUrl } = cjs(daemon_url_exports), shared = cjs(client_exports), staticCredentials2 = shared.staticCredentials, DaemonClient2 = class _DaemonClient extends shared.DaemonClient {
1021
+ /** `resolved`: options already built for the shared client (derive); `options` is then ignored. */
1022
+ constructor(options = {}, resolved) {
1023
+ super(resolved ?? _DaemonClient.resolve(options));
1024
+ }
1025
+ static resolve(options) {
1026
+ let baseUrl = resolveDaemonUrl(options.baseUrl, options.env), lookup = { localToken: options.localToken, env: options.env, fetch: options.fetch };
1027
+ return {
1028
+ baseUrl,
1029
+ // `--token` belongs to this URL; another daemon (withBaseUrl) gets its
1030
+ // own `--token`, or ADF_DAEMON_TOKEN, or its own local token file (and
1031
+ // local proof, when it is this machine's daemon), never this one.
1032
+ credentials: daemonCredentials(baseUrl, { ...lookup, token: options.token }),
1033
+ credentialsFor: (url, token) => daemonCredentials(url, { ...lookup, token }),
1034
+ fetch: options.fetch,
1035
+ timeoutMs: options.timeoutMs
1036
+ };
1037
+ }
1038
+ derive(options) {
1039
+ return new _DaemonClient({}, options);
1040
+ }
1041
+ };
1042
+
864
1043
  export {
865
- DaemonClient
1044
+ DaemonClient2 as DaemonClient
866
1045
  };
@@ -4,8 +4,18 @@ import { dirname as __adfDirname } from 'node:path';
4
4
  const require = __adfCreateRequire(import.meta.url);
5
5
  const __filename = __adfFileURLToPath(import.meta.url);
6
6
  const __dirname = __adfDirname(__filename);
7
+ import {
8
+ __export
9
+ } from "./chunk-M2RX3S2T.mjs";
7
10
 
8
- // src/main/tui/api/types.ts
11
+ // src/shared/daemon-client/types.ts
12
+ var types_exports = {};
13
+ __export(types_exports, {
14
+ DaemonError: () => DaemonError,
15
+ MAIN_LOOP: () => MAIN_LOOP,
16
+ SUPPORTED_CLIENT_API_VERSION: () => SUPPORTED_CLIENT_API_VERSION,
17
+ isCredentialsLocked: () => isCredentialsLocked
18
+ });
9
19
  var MAIN_LOOP = "main", DaemonError = class extends Error {
10
20
  constructor(message, status, body = null) {
11
21
  super(message);
@@ -25,9 +35,10 @@ function isCredentialsLocked(err) {
25
35
  let body = err.body;
26
36
  return !!body && typeof body == "object" && body.code === "credentials_locked";
27
37
  }
38
+ var SUPPORTED_CLIENT_API_VERSION = 2;
28
39
 
29
40
  export {
30
41
  MAIN_LOOP,
31
42
  DaemonError,
32
- isCredentialsLocked
43
+ types_exports
33
44
  };