@moxt-ai/mobius 0.0.294 → 0.0.296

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.
package/dist/runtime.js CHANGED
@@ -22582,7 +22582,7 @@ import { fetch as fetch3 } from "undici";
22582
22582
  // package.json
22583
22583
  var package_default = {
22584
22584
  name: "@moxt-ai/mobius",
22585
- version: "0.0.294",
22585
+ version: "0.0.296",
22586
22586
  description: "Mobius CLI for pairing and running local AI agent services.",
22587
22587
  type: "module",
22588
22588
  bin: {
@@ -22731,6 +22731,7 @@ import { mkdir as CL, readdir as snt, readFile as sne, rm as int2, writeFile as
22731
22731
  import { createRequire as ant } from "module";
22732
22732
  import { homedir as kL, tmpdir as cnt } from "os";
22733
22733
  import { dirname as RL, isAbsolute as ane, join as vn, relative as cne, resolve as Vh, sep as IL } from "path";
22734
+ import { createInterface as lnt } from "readline";
22734
22735
  import { fileURLToPath as unt } from "url";
22735
22736
  import { setMaxListeners as bae } from "events";
22736
22737
  import { spawn as BFe } from "child_process";
@@ -54184,6 +54185,78 @@ function mZ(e, t, n, r) {
54184
54185
  if (!p) p = `${r() || "Forked session"} (fork)`;
54185
54186
  return u.push({ type: "custom-title", sessionId: c, customTitle: p, uuid: zS(), timestamp: l }), { entries: u, forkedSessionId: c };
54186
54187
  }
54188
+ function BS(e) {
54189
+ return ["subagents", ...e.agentRelPath ?? [], e.kind === "agent" ? `agent-${e.agentId}` : "journal"].join("/");
54190
+ }
54191
+ async function KP(e, t, n, r, o, s = PKe) {
54192
+ let i = [], a = 0, c, l = false;
54193
+ for (let u = 0; u < s; u++) {
54194
+ let p = await e.readRecords(t, { order: "forward", maxBytes: OKe, ...c !== void 0 && { fromSeq: c } });
54195
+ if (!p.ok) throw new Ze(`importSessionToStore: transcript read failed (${p.error.code})`, "importSessionToStore: transcript read failed");
54196
+ for (let f of p.value.items) {
54197
+ let m = Buffer.from(f.data.buffer, f.data.byteOffset, f.data.byteLength).toString("utf8").replace(/\r?\n$/, "");
54198
+ if (!m) continue;
54199
+ try {
54200
+ i.push(lt(m));
54201
+ } catch (h) {
54202
+ ce(`importSessionToStore: skipping unparseable record ${f.seq}: ${h}`);
54203
+ continue;
54204
+ }
54205
+ if (a += m.length, i.length >= o || a >= Ou) await r.append(n, i), i = [], a = 0;
54206
+ }
54207
+ if (c = p.value.nextSeq, c === void 0) {
54208
+ l = true;
54209
+ break;
54210
+ }
54211
+ }
54212
+ if (!l) throw new Ze("importSessionToStore: transcript read did not end (page cap reached)", "importSessionToStore: transcript read did not end");
54213
+ if (i.length > 0) await r.append(n, i);
54214
+ }
54215
+ var OKe = 67108864;
54216
+ var PKe = 1e5;
54217
+ var IKe = 1e4;
54218
+ async function AZ(e, t, n, r = IKe) {
54219
+ let o = [], s = [{ namespace: "transcript", projectKey: t, sessionId: n }], i = /* @__PURE__ */ new Set([""]), a = /* @__PURE__ */ new Set(), c = 0;
54220
+ while (s.length > 0) {
54221
+ if (++c > r) throw Error("importSessionToStore: subagent listing did not end (scope cap reached)");
54222
+ let l = s.shift(), u = [];
54223
+ if ((await Ao((f) => e.listEntries(l, { skipKeyStats: true, skipScopeStats: true, ...f !== void 0 && { cursor: f } }), (f) => {
54224
+ for (let m of f) if (m.kind === "key" && m.key.namespace === "transcript") {
54225
+ let h = m.key.agentRelPath;
54226
+ if (h !== void 0 && !sr(h)) continue;
54227
+ let y = m.key.agentId !== void 0 ? pn(m.key.agentId) ? { kind: "agent", agentId: m.key.agentId, ...h && { agentRelPath: h } } : void 0 : m.key.journal === true && h !== void 0 ? { kind: "journal", agentRelPath: h } : void 0, _ = y && BS(y);
54228
+ if (y && _ !== void 0 && !a.has(_)) a.add(_), o.push(y);
54229
+ } else if (m.kind === "scope" && m.scope.namespace === "transcript" && m.scope.agentRelPath !== void 0 && sr(m.scope.agentRelPath) && !i.has(m.scope.agentRelPath.join("/"))) i.add(m.scope.agentRelPath.join("/")), u.push({ namespace: "transcript", projectKey: t, sessionId: n, agentRelPath: m.scope.agentRelPath });
54230
+ })).status !== "done") throw Error("importSessionToStore: subagent listing failed");
54231
+ s.unshift(...u);
54232
+ }
54233
+ return o;
54234
+ }
54235
+ function DKe(e, t, n) {
54236
+ return tn.sidecar(e, t, ["subagents", ...n.agentRelPath ?? [], n.kind === "agent" ? `agent-${n.agentId}.meta.json` : "journal.meta.json"]);
54237
+ }
54238
+ async function TZ(e, t, n, r) {
54239
+ let o = r.map((a) => ({ subpath: BS(a), key: DKe(t, n, a) })).filter(({ key: a }) => Ms(a) === void 0), s = /* @__PURE__ */ new Map();
54240
+ if (o.length === 0) return s;
54241
+ let i = await e.readText(o.map(({ key: a }) => a));
54242
+ if (i.ok) return i.value.items.forEach((a, c) => {
54243
+ if (a.found) s.set(o[c].subpath, a.value);
54244
+ }), s;
54245
+ if (!vZ(i.error)) throw wZ(i.error.code);
54246
+ for (let { subpath: a, key: c } of o) {
54247
+ let l = await e.readText([c]);
54248
+ if (l.ok) {
54249
+ if (l.value.items[0].found) s.set(a, l.value.items[0].value);
54250
+ } else if (!vZ(l.error)) throw wZ(l.error.code);
54251
+ }
54252
+ return s;
54253
+ }
54254
+ function vZ(e) {
54255
+ return e.code === "Failed" && (e.telemetryCode === "ELOOP" || e.telemetryCode === "ENXIO");
54256
+ }
54257
+ function wZ(e) {
54258
+ return new Ze(`importSessionToStore: sidecar read failed (${e})`, "importSessionToStore: sidecar read failed");
54259
+ }
54187
54260
  function OZ(e) {
54188
54261
  return { globalConfig: GP(e || CZ(), ".claude.json"), userSettings: GP(e || GP(CZ(), ".claude"), "settings.json") };
54189
54262
  }
@@ -58824,6 +58897,75 @@ async function KZt(e, t) {
58824
58897
  if (t?.sessionStore) return Tnt(t.sessionStore, e, t);
58825
58898
  return pZ(e, t);
58826
58899
  }
58900
+ async function GZt(e, t, n, r) {
58901
+ if (!Je(e)) throw new Ze(`Invalid sessionId: ${e}`, "importSessionToStore: invalid sessionId (must be a UUID)");
58902
+ let o = ye(), s = o ? r : void 0, i = await Ni(e, n?.dir, ir(s), o);
58903
+ if (!i) throw Error(`Session ${e} not found`);
58904
+ let a = no(n?.dir), c = n?.batchSize && n.batchSize > 0 ? n.batchSize : Wy, l = s === void 0 ? void 0 : ac(RL(i.filePath), pn), u = s !== void 0 && l !== void 0 ? { backend: s, projectKey: l } : void 0;
58905
+ if (u !== void 0) await KP(u.backend, tn.transcript(u.projectKey, e), { projectKey: a, sessionId: e }, t, c);
58906
+ else await rne(i.filePath, { projectKey: a, sessionId: e }, t, c);
58907
+ if (n?.includeSubagents === false) return;
58908
+ if (u !== void 0) {
58909
+ let m = await AZ(u.backend, u.projectKey, e), h = await TZ(u.backend, u.projectKey, e, m);
58910
+ for (let y of m) {
58911
+ let _ = { projectKey: a, sessionId: e, subpath: BS(y) };
58912
+ await KP(u.backend, y.kind === "agent" ? tn.transcript(u.projectKey, e, y.agentId, y.agentRelPath) : tn.journal(u.projectKey, e, y.agentRelPath), _, t, c);
58913
+ let E = h.get(_.subpath), S;
58914
+ if (E !== void 0) try {
58915
+ S = lt(E);
58916
+ } catch (x) {
58917
+ ce(`importSessionToStore: skipping unreadable sidecar for ${_.subpath}: ${x}`);
58918
+ }
58919
+ if (S !== void 0) await t.append(_, [{ type: "agent_metadata", ...S }]);
58920
+ }
58921
+ return;
58922
+ }
58923
+ let p = i.filePath.replace(/\.jsonl$/, ""), f = vn(p, "subagents");
58924
+ for (let m of await ynt(f)) {
58925
+ let h = cne(p, m).split(IL);
58926
+ h[h.length - 1] = h.at(-1).replace(/\.jsonl$/, "");
58927
+ let y = { projectKey: a, sessionId: e, subpath: h.join("/") };
58928
+ await rne(m, y, t, c);
58929
+ let _ = m.replace(/\.jsonl$/, ".meta.json"), E;
58930
+ try {
58931
+ E = lt(await sne(_, "utf8"));
58932
+ } catch (S) {
58933
+ if (!wr(S)) ce(`importSessionToStore: skipping unreadable sidecar ${_}: ${S}`);
58934
+ }
58935
+ if (E !== void 0) await t.append(y, [{ type: "agent_metadata", ...E }]);
58936
+ }
58937
+ }
58938
+ async function rne(e, t, n, r) {
58939
+ let o = lnt({ input: rnt(e, { encoding: "utf8" }), crlfDelay: 1 / 0 }), s = [], i = 0;
58940
+ for await (let a of o) {
58941
+ if (!a) continue;
58942
+ try {
58943
+ s.push(lt(a));
58944
+ } catch (c) {
58945
+ ce(`importSessionToStore: skipping unparseable line in ${e}: ${c}`);
58946
+ continue;
58947
+ }
58948
+ if (i += a.length, s.length >= r || i >= Ou) await n.append(t, s), s = [], i = 0;
58949
+ }
58950
+ if (s.length > 0) await n.append(t, s);
58951
+ }
58952
+ async function ynt(e) {
58953
+ let t = [];
58954
+ async function n(r) {
58955
+ let o;
58956
+ try {
58957
+ o = await snt(r, { withFileTypes: true });
58958
+ } catch {
58959
+ return;
58960
+ }
58961
+ for (let s of o) {
58962
+ let i = vn(r, s.name);
58963
+ if (s.isDirectory()) await n(i);
58964
+ else if (s.isFile() && s.name.endsWith(".jsonl")) t.push(i);
58965
+ }
58966
+ }
58967
+ return await n(e), t;
58968
+ }
58827
58969
  function une(e) {
58828
58970
  let t = Vh(e ?? "."), n;
58829
58971
  try {
@@ -59237,7 +59379,26 @@ function listEnvironmentSessions(environment, cwd, signal) {
59237
59379
  // src/acp/harness/claude/upstream/dist/environment-session-messages.js
59238
59380
  var SESSION_MESSAGES_TIMEOUT_MILLISECONDS = 3e4;
59239
59381
  function getEnvironmentSessionMessages(environment, sessionId, signal) {
59240
- return withEnvironment(environment, () => withDeadline(signal, SESSION_MESSAGES_TIMEOUT_MILLISECONDS, () => FZt(sessionId)));
59382
+ return withEnvironment(environment, () => withDeadline(signal, SESSION_MESSAGES_TIMEOUT_MILLISECONDS, async () => {
59383
+ const messages = await FZt(sessionId);
59384
+ if (!messages.some(({ type, message }) => type === "assistant" && typeof message === "object" && message !== null && "model" in message && message.model === "<synthetic>")) {
59385
+ return messages;
59386
+ }
59387
+ const authenticationFailures = /* @__PURE__ */ new Set();
59388
+ await GZt(sessionId, {
59389
+ append: async (_key, entries) => {
59390
+ signal.throwIfAborted();
59391
+ for (const entry of entries) {
59392
+ if (entry.type === "assistant" && entry["error"] === "authentication_failed" && typeof entry.uuid === "string") {
59393
+ authenticationFailures.add(entry.uuid);
59394
+ }
59395
+ }
59396
+ },
59397
+ load: async () => null
59398
+ }, { includeSubagents: false });
59399
+ signal.throwIfAborted();
59400
+ return messages.filter((message) => !authenticationFailures.has(message.uuid));
59401
+ }));
59241
59402
  }
59242
59403
 
59243
59404
  // src/acp/harness/claude/upstream/dist/session-config-ids.js
@@ -62064,17 +62225,6 @@ function stripLocalCommandMetadata(content) {
62064
62225
  }
62065
62226
  return kept;
62066
62227
  }
62067
- function isSyntheticLoginMessage(apiMessage) {
62068
- if (!apiMessage || typeof apiMessage !== "object") {
62069
- return false;
62070
- }
62071
- const { model, content } = apiMessage;
62072
- if (model !== "<synthetic>" || !Array.isArray(content) || content.length !== 1) {
62073
- return false;
62074
- }
62075
- const block = content[0];
62076
- return !!block && block.type === "text" && typeof block.text === "string" && block.text.includes("Please run /login");
62077
- }
62078
62228
  var ClientConnection = class {
62079
62229
  ctx;
62080
62230
  onSessionUpdate;
@@ -63573,10 +63723,6 @@ ${message.api_refusal_explanation}` : "";
63573
63723
  }
63574
63724
  switch (message.subtype) {
63575
63725
  case "success": {
63576
- if (message.result.includes("Please run /login")) {
63577
- failActive(RequestError3.authRequired());
63578
- break;
63579
- }
63580
63726
  if (message.stop_reason === "max_tokens") {
63581
63727
  stopReason = "max_tokens";
63582
63728
  break;
@@ -63800,8 +63946,8 @@ ${message.api_refusal_explanation}` : "";
63800
63946
  if (message.message.role === "system") {
63801
63947
  break;
63802
63948
  }
63803
- if (message.type === "assistant" && isSyntheticLoginMessage(message.message)) {
63804
- failActive(RequestError3.authRequired());
63949
+ if (message.type === "assistant" && message.error === "authentication_failed") {
63950
+ failActive(RequestError3.authRequired(errorKindData(message.error)));
63805
63951
  break;
63806
63952
  }
63807
63953
  let content;
@@ -64184,9 +64330,6 @@ ${message.api_refusal_explanation}` : "";
64184
64330
  if (replaySession && replayMessageId && message.uuid) {
64185
64331
  replaySession.messageIdToUuid.set(replayMessageId, message.uuid);
64186
64332
  }
64187
- if (message.type === "assistant" && isSyntheticLoginMessage(message.message)) {
64188
- continue;
64189
- }
64190
64333
  const parentToolUseId = parentToolUseIdOf(message);
64191
64334
  if (parentToolUseId !== null && !forwardSubagentText) {
64192
64335
  continue;
@@ -90088,37 +90231,44 @@ async function runRelayConnection({
90088
90231
  // src/runtime/relay/session-event-publisher.ts
90089
90232
  import { WebSocket as WebSocket8 } from "undici";
90090
90233
  var MAX_BUFFERED_BYTES = 32 * 1024 * 1024;
90234
+ var MAX_PENDING_BYTES2 = 32 * 1024 * 1024;
90091
90235
  var MAX_EVENT_BATCH_BYTES = 1024 * 1024;
90092
90236
  var MAX_FRAME_BYTES = 8 * 1024 * 1024;
90093
90237
  var LOCAL_BACKPRESSURE_CLOSE_CODE = 4009;
90094
90238
  var EMPTY_ENVELOPE_BYTES = Buffer.byteLength(JSON.stringify({ events: [], kind: SESSION_EVENT_KIND }));
90095
90239
  var SESSION_EVENT_BATCH_WINDOW_MILLISECONDS = 100;
90096
90240
  var RuntimeSessionEventPublisher = class {
90097
- #pendingEvents = [];
90098
- #pendingBytes = EMPTY_ENVELOPE_BYTES;
90241
+ #pending = [];
90242
+ #pendingBytes = 0;
90243
+ #overflowReported = false;
90099
90244
  #pendingTask = null;
90100
- #socket = null;
90245
+ #connection = { kind: "disconnected" };
90101
90246
  #timer;
90102
90247
  constructor(timer) {
90103
90248
  this.#timer = timer;
90104
90249
  }
90105
90250
  connect = (socket) => {
90106
- this.dropPendingEvents();
90107
- this.#socket = socket;
90251
+ if (this.#connection.kind === "closed") {
90252
+ return;
90253
+ }
90254
+ this.#connection = { kind: "connected", socket };
90255
+ this.flushEvents(socket);
90108
90256
  };
90109
90257
  disconnect = (socket) => {
90110
- if (this.#socket === socket) {
90111
- this.#socket = null;
90112
- this.dropPendingEvents();
90258
+ if (this.#connection.kind === "connected" && this.#connection.socket === socket) {
90259
+ this.#connection = { kind: "disconnected" };
90260
+ this.cancelFlush();
90113
90261
  }
90114
90262
  };
90115
90263
  close = () => {
90116
- this.#socket = null;
90117
- this.dropPendingEvents();
90264
+ this.#connection = { kind: "closed" };
90265
+ this.cancelFlush();
90266
+ this.#pending.length = 0;
90267
+ this.#pendingBytes = 0;
90118
90268
  };
90119
90269
  flush = () => {
90120
- if (this.#socket !== null) {
90121
- this.flushEvents(this.#socket);
90270
+ if (this.#connection.kind === "connected") {
90271
+ this.flushEvents(this.#connection.socket);
90122
90272
  }
90123
90273
  };
90124
90274
  publishOperationFailure = (sessionId, requestId, code, message) => {
@@ -90128,10 +90278,11 @@ var RuntimeSessionEventPublisher = class {
90128
90278
  publishInfo = (event) => this.#send(event);
90129
90279
  publishClosed = (event) => this.#send(event);
90130
90280
  #send = (message) => {
90131
- const socket = this.#socket;
90132
- if (socket === null || socket.readyState !== WebSocket8.OPEN) {
90281
+ const connection = this.#connection;
90282
+ if (connection.kind !== "connected" || connection.socket.readyState !== WebSocket8.OPEN) {
90133
90283
  return;
90134
90284
  }
90285
+ const socket = connection.socket;
90135
90286
  const encoded = encodeDaemonToServiceMessage(message);
90136
90287
  if (socket.bufferedAmount + Buffer.byteLength(encoded, "utf8") > MAX_BUFFERED_BYTES) {
90137
90288
  socket.close(LOCAL_BACKPRESSURE_CLOSE_CODE, "Live event transport overloaded");
@@ -90143,8 +90294,7 @@ var RuntimeSessionEventPublisher = class {
90143
90294
  }
90144
90295
  };
90145
90296
  publish = (event) => {
90146
- const socket = this.#socket;
90147
- if (socket === null || socket.readyState !== WebSocket8.OPEN) {
90297
+ if (this.#connection.kind === "closed") {
90148
90298
  return;
90149
90299
  }
90150
90300
  const bytes = Buffer.byteLength(JSON.stringify(event), "utf8") + 1;
@@ -90157,15 +90307,34 @@ var RuntimeSessionEventPublisher = class {
90157
90307
  });
90158
90308
  return;
90159
90309
  }
90160
- if (this.#pendingEvents.length > 0 && this.#pendingBytes + bytes > MAX_EVENT_BATCH_BYTES) {
90161
- this.flushEvents(socket);
90162
- if (socket.readyState !== WebSocket8.OPEN) {
90163
- return;
90310
+ let batch = this.#pending.at(-1);
90311
+ const newBatch = batch === void 0 || batch.events.length >= SESSION_EVENT_BATCH_MAX_SIZE || batch.bytes + bytes > MAX_EVENT_BATCH_BYTES;
90312
+ const additionalBytes = bytes + (newBatch ? EMPTY_ENVELOPE_BYTES : 0);
90313
+ if (this.#pendingBytes + additionalBytes > MAX_PENDING_BYTES2) {
90314
+ if (!this.#overflowReported) {
90315
+ this.#overflowReported = true;
90316
+ console.warn("Live Session output exceeded the pending buffer limit", {
90317
+ code: "live_event_buffer_full",
90318
+ sessionId: event.sessionId,
90319
+ eventId: event.eventId,
90320
+ maximumBytes: MAX_PENDING_BYTES2
90321
+ });
90164
90322
  }
90323
+ return;
90165
90324
  }
90166
- this.#pendingEvents.push(event);
90167
- this.#pendingBytes += bytes;
90168
- if (this.#pendingEvents.length >= SESSION_EVENT_BATCH_MAX_SIZE || this.#pendingBytes >= MAX_EVENT_BATCH_BYTES) {
90325
+ if (batch === void 0 || newBatch) {
90326
+ batch = { events: [], bytes: EMPTY_ENVELOPE_BYTES };
90327
+ this.#pending.push(batch);
90328
+ }
90329
+ batch.events.push(event);
90330
+ batch.bytes += bytes;
90331
+ this.#pendingBytes += additionalBytes;
90332
+ const connection = this.#connection;
90333
+ if (connection.kind !== "connected" || connection.socket.readyState !== WebSocket8.OPEN) {
90334
+ return;
90335
+ }
90336
+ const socket = connection.socket;
90337
+ if (this.#pending.length > 1 || batch.events.length >= SESSION_EVENT_BATCH_MAX_SIZE || batch.bytes >= MAX_EVENT_BATCH_BYTES) {
90169
90338
  this.flushEvents(socket);
90170
90339
  return;
90171
90340
  }
@@ -90174,29 +90343,35 @@ var RuntimeSessionEventPublisher = class {
90174
90343
  SESSION_EVENT_BATCH_WINDOW_MILLISECONDS
90175
90344
  );
90176
90345
  };
90177
- dropPendingEvents = () => {
90346
+ cancelFlush = () => {
90178
90347
  this.#pendingTask?.cancel();
90179
90348
  this.#pendingTask = null;
90180
- this.#pendingEvents = [];
90181
- this.#pendingBytes = EMPTY_ENVELOPE_BYTES;
90182
90349
  };
90183
90350
  flushEvents = (socket) => {
90184
- this.#pendingTask?.cancel();
90185
- this.#pendingTask = null;
90186
- const events = this.#pendingEvents;
90187
- this.#pendingEvents = [];
90188
- this.#pendingBytes = EMPTY_ENVELOPE_BYTES;
90189
- if (events.length === 0 || this.#socket !== socket || socket.readyState !== WebSocket8.OPEN) {
90351
+ this.cancelFlush();
90352
+ const connection = this.#connection;
90353
+ if (connection.kind !== "connected" || connection.socket !== socket || socket.readyState !== WebSocket8.OPEN) {
90190
90354
  return;
90191
90355
  }
90192
- const encoded = encodeDaemonToServiceMessage({ events, kind: SESSION_EVENT_KIND });
90193
- if (socket.bufferedAmount + Buffer.byteLength(encoded, "utf8") > MAX_BUFFERED_BYTES) {
90194
- socket.close(LOCAL_BACKPRESSURE_CLOSE_CODE, "Live event transport overloaded");
90195
- return;
90356
+ let attempted = 0;
90357
+ for (const batch of this.#pending) {
90358
+ const encoded = encodeDaemonToServiceMessage({ events: batch.events, kind: SESSION_EVENT_KIND });
90359
+ if (socket.bufferedAmount + Buffer.byteLength(encoded, "utf8") > MAX_BUFFERED_BYTES) {
90360
+ socket.close(LOCAL_BACKPRESSURE_CLOSE_CODE, "Live event transport overloaded");
90361
+ break;
90362
+ }
90363
+ attempted += 1;
90364
+ this.#pendingBytes -= batch.bytes;
90365
+ try {
90366
+ socket.send(encoded);
90367
+ } catch {
90368
+ console.warn("Live Session output could not be sent", { code: "live_event_send_failed" });
90369
+ break;
90370
+ }
90196
90371
  }
90197
- try {
90198
- socket.send(encoded);
90199
- } catch {
90372
+ this.#pending.splice(0, attempted);
90373
+ if (this.#pending.length === 0) {
90374
+ this.#overflowReported = false;
90200
90375
  }
90201
90376
  };
90202
90377
  };