@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/cli.js CHANGED
@@ -5398,7 +5398,7 @@ var program = new Command();
5398
5398
  // package.json
5399
5399
  var package_default = {
5400
5400
  name: "@moxt-ai/mobius",
5401
- version: "0.0.294",
5401
+ version: "0.0.296",
5402
5402
  description: "Mobius CLI for pairing and running local AI agent services.",
5403
5403
  type: "module",
5404
5404
  bin: {
@@ -5547,6 +5547,7 @@ import { mkdir as CL, readdir as snt, readFile as sne, rm as int, writeFile as i
5547
5547
  import { createRequire as ant } from "module";
5548
5548
  import { homedir as kL, tmpdir as cnt } from "os";
5549
5549
  import { dirname as RL, isAbsolute as ane, join as vn, relative as cne, resolve as Vh, sep as IL } from "path";
5550
+ import { createInterface as lnt } from "readline";
5550
5551
  import { fileURLToPath as unt } from "url";
5551
5552
  import { setMaxListeners as bae } from "events";
5552
5553
  import { spawn as BFe } from "child_process";
@@ -37000,6 +37001,78 @@ function mZ(e, t, n, r) {
37000
37001
  if (!p) p = `${r() || "Forked session"} (fork)`;
37001
37002
  return u.push({ type: "custom-title", sessionId: c, customTitle: p, uuid: zS(), timestamp: l }), { entries: u, forkedSessionId: c };
37002
37003
  }
37004
+ function BS(e) {
37005
+ return ["subagents", ...e.agentRelPath ?? [], e.kind === "agent" ? `agent-${e.agentId}` : "journal"].join("/");
37006
+ }
37007
+ async function KP(e, t, n, r, o, s = PKe) {
37008
+ let i = [], a = 0, c, l = false;
37009
+ for (let u = 0; u < s; u++) {
37010
+ let p = await e.readRecords(t, { order: "forward", maxBytes: OKe, ...c !== void 0 && { fromSeq: c } });
37011
+ if (!p.ok) throw new Ze(`importSessionToStore: transcript read failed (${p.error.code})`, "importSessionToStore: transcript read failed");
37012
+ for (let f of p.value.items) {
37013
+ let m = Buffer.from(f.data.buffer, f.data.byteOffset, f.data.byteLength).toString("utf8").replace(/\r?\n$/, "");
37014
+ if (!m) continue;
37015
+ try {
37016
+ i.push(lt(m));
37017
+ } catch (h) {
37018
+ ce(`importSessionToStore: skipping unparseable record ${f.seq}: ${h}`);
37019
+ continue;
37020
+ }
37021
+ if (a += m.length, i.length >= o || a >= Ou) await r.append(n, i), i = [], a = 0;
37022
+ }
37023
+ if (c = p.value.nextSeq, c === void 0) {
37024
+ l = true;
37025
+ break;
37026
+ }
37027
+ }
37028
+ if (!l) throw new Ze("importSessionToStore: transcript read did not end (page cap reached)", "importSessionToStore: transcript read did not end");
37029
+ if (i.length > 0) await r.append(n, i);
37030
+ }
37031
+ var OKe = 67108864;
37032
+ var PKe = 1e5;
37033
+ var IKe = 1e4;
37034
+ async function AZ(e, t, n, r = IKe) {
37035
+ let o = [], s = [{ namespace: "transcript", projectKey: t, sessionId: n }], i = /* @__PURE__ */ new Set([""]), a = /* @__PURE__ */ new Set(), c = 0;
37036
+ while (s.length > 0) {
37037
+ if (++c > r) throw Error("importSessionToStore: subagent listing did not end (scope cap reached)");
37038
+ let l = s.shift(), u = [];
37039
+ if ((await Ao((f) => e.listEntries(l, { skipKeyStats: true, skipScopeStats: true, ...f !== void 0 && { cursor: f } }), (f) => {
37040
+ for (let m of f) if (m.kind === "key" && m.key.namespace === "transcript") {
37041
+ let h = m.key.agentRelPath;
37042
+ if (h !== void 0 && !sr(h)) continue;
37043
+ 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);
37044
+ if (y && _ !== void 0 && !a.has(_)) a.add(_), o.push(y);
37045
+ } 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 });
37046
+ })).status !== "done") throw Error("importSessionToStore: subagent listing failed");
37047
+ s.unshift(...u);
37048
+ }
37049
+ return o;
37050
+ }
37051
+ function DKe(e, t, n) {
37052
+ return tn.sidecar(e, t, ["subagents", ...n.agentRelPath ?? [], n.kind === "agent" ? `agent-${n.agentId}.meta.json` : "journal.meta.json"]);
37053
+ }
37054
+ async function TZ(e, t, n, r) {
37055
+ let o = r.map((a) => ({ subpath: BS(a), key: DKe(t, n, a) })).filter(({ key: a }) => Ms(a) === void 0), s = /* @__PURE__ */ new Map();
37056
+ if (o.length === 0) return s;
37057
+ let i = await e.readText(o.map(({ key: a }) => a));
37058
+ if (i.ok) return i.value.items.forEach((a, c) => {
37059
+ if (a.found) s.set(o[c].subpath, a.value);
37060
+ }), s;
37061
+ if (!vZ(i.error)) throw wZ(i.error.code);
37062
+ for (let { subpath: a, key: c } of o) {
37063
+ let l = await e.readText([c]);
37064
+ if (l.ok) {
37065
+ if (l.value.items[0].found) s.set(a, l.value.items[0].value);
37066
+ } else if (!vZ(l.error)) throw wZ(l.error.code);
37067
+ }
37068
+ return s;
37069
+ }
37070
+ function vZ(e) {
37071
+ return e.code === "Failed" && (e.telemetryCode === "ELOOP" || e.telemetryCode === "ENXIO");
37072
+ }
37073
+ function wZ(e) {
37074
+ return new Ze(`importSessionToStore: sidecar read failed (${e})`, "importSessionToStore: sidecar read failed");
37075
+ }
37003
37076
  function OZ(e) {
37004
37077
  return { globalConfig: GP(e || CZ(), ".claude.json"), userSettings: GP(e || GP(CZ(), ".claude"), "settings.json") };
37005
37078
  }
@@ -41640,6 +41713,75 @@ async function KZt(e, t) {
41640
41713
  if (t?.sessionStore) return Tnt(t.sessionStore, e, t);
41641
41714
  return pZ(e, t);
41642
41715
  }
41716
+ async function GZt(e, t, n, r) {
41717
+ if (!Je(e)) throw new Ze(`Invalid sessionId: ${e}`, "importSessionToStore: invalid sessionId (must be a UUID)");
41718
+ let o = ye(), s = o ? r : void 0, i = await Ni(e, n?.dir, ir(s), o);
41719
+ if (!i) throw Error(`Session ${e} not found`);
41720
+ 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;
41721
+ if (u !== void 0) await KP(u.backend, tn.transcript(u.projectKey, e), { projectKey: a, sessionId: e }, t, c);
41722
+ else await rne(i.filePath, { projectKey: a, sessionId: e }, t, c);
41723
+ if (n?.includeSubagents === false) return;
41724
+ if (u !== void 0) {
41725
+ let m = await AZ(u.backend, u.projectKey, e), h = await TZ(u.backend, u.projectKey, e, m);
41726
+ for (let y of m) {
41727
+ let _ = { projectKey: a, sessionId: e, subpath: BS(y) };
41728
+ 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);
41729
+ let E = h.get(_.subpath), S;
41730
+ if (E !== void 0) try {
41731
+ S = lt(E);
41732
+ } catch (x) {
41733
+ ce(`importSessionToStore: skipping unreadable sidecar for ${_.subpath}: ${x}`);
41734
+ }
41735
+ if (S !== void 0) await t.append(_, [{ type: "agent_metadata", ...S }]);
41736
+ }
41737
+ return;
41738
+ }
41739
+ let p = i.filePath.replace(/\.jsonl$/, ""), f = vn(p, "subagents");
41740
+ for (let m of await ynt(f)) {
41741
+ let h = cne(p, m).split(IL);
41742
+ h[h.length - 1] = h.at(-1).replace(/\.jsonl$/, "");
41743
+ let y = { projectKey: a, sessionId: e, subpath: h.join("/") };
41744
+ await rne(m, y, t, c);
41745
+ let _ = m.replace(/\.jsonl$/, ".meta.json"), E;
41746
+ try {
41747
+ E = lt(await sne(_, "utf8"));
41748
+ } catch (S) {
41749
+ if (!wr(S)) ce(`importSessionToStore: skipping unreadable sidecar ${_}: ${S}`);
41750
+ }
41751
+ if (E !== void 0) await t.append(y, [{ type: "agent_metadata", ...E }]);
41752
+ }
41753
+ }
41754
+ async function rne(e, t, n, r) {
41755
+ let o = lnt({ input: rnt(e, { encoding: "utf8" }), crlfDelay: 1 / 0 }), s = [], i = 0;
41756
+ for await (let a of o) {
41757
+ if (!a) continue;
41758
+ try {
41759
+ s.push(lt(a));
41760
+ } catch (c) {
41761
+ ce(`importSessionToStore: skipping unparseable line in ${e}: ${c}`);
41762
+ continue;
41763
+ }
41764
+ if (i += a.length, s.length >= r || i >= Ou) await n.append(t, s), s = [], i = 0;
41765
+ }
41766
+ if (s.length > 0) await n.append(t, s);
41767
+ }
41768
+ async function ynt(e) {
41769
+ let t = [];
41770
+ async function n(r) {
41771
+ let o;
41772
+ try {
41773
+ o = await snt(r, { withFileTypes: true });
41774
+ } catch {
41775
+ return;
41776
+ }
41777
+ for (let s of o) {
41778
+ let i = vn(r, s.name);
41779
+ if (s.isDirectory()) await n(i);
41780
+ else if (s.isFile() && s.name.endsWith(".jsonl")) t.push(i);
41781
+ }
41782
+ }
41783
+ return await n(e), t;
41784
+ }
41643
41785
  function une(e) {
41644
41786
  let t = Vh(e ?? "."), n;
41645
41787
  try {
@@ -42053,7 +42195,26 @@ function listEnvironmentSessions(environment, cwd, signal) {
42053
42195
  // src/acp/harness/claude/upstream/dist/environment-session-messages.js
42054
42196
  var SESSION_MESSAGES_TIMEOUT_MILLISECONDS = 3e4;
42055
42197
  function getEnvironmentSessionMessages(environment, sessionId, signal) {
42056
- return withEnvironment(environment, () => withDeadline(signal, SESSION_MESSAGES_TIMEOUT_MILLISECONDS, () => FZt(sessionId)));
42198
+ return withEnvironment(environment, () => withDeadline(signal, SESSION_MESSAGES_TIMEOUT_MILLISECONDS, async () => {
42199
+ const messages = await FZt(sessionId);
42200
+ if (!messages.some(({ type, message }) => type === "assistant" && typeof message === "object" && message !== null && "model" in message && message.model === "<synthetic>")) {
42201
+ return messages;
42202
+ }
42203
+ const authenticationFailures = /* @__PURE__ */ new Set();
42204
+ await GZt(sessionId, {
42205
+ append: async (_key, entries) => {
42206
+ signal.throwIfAborted();
42207
+ for (const entry of entries) {
42208
+ if (entry.type === "assistant" && entry["error"] === "authentication_failed" && typeof entry.uuid === "string") {
42209
+ authenticationFailures.add(entry.uuid);
42210
+ }
42211
+ }
42212
+ },
42213
+ load: async () => null
42214
+ }, { includeSubagents: false });
42215
+ signal.throwIfAborted();
42216
+ return messages.filter((message) => !authenticationFailures.has(message.uuid));
42217
+ }));
42057
42218
  }
42058
42219
 
42059
42220
  // src/acp/harness/claude/upstream/dist/session-config-ids.js
@@ -64550,17 +64711,6 @@ function stripLocalCommandMetadata(content) {
64550
64711
  }
64551
64712
  return kept;
64552
64713
  }
64553
- function isSyntheticLoginMessage(apiMessage) {
64554
- if (!apiMessage || typeof apiMessage !== "object") {
64555
- return false;
64556
- }
64557
- const { model, content } = apiMessage;
64558
- if (model !== "<synthetic>" || !Array.isArray(content) || content.length !== 1) {
64559
- return false;
64560
- }
64561
- const block = content[0];
64562
- return !!block && block.type === "text" && typeof block.text === "string" && block.text.includes("Please run /login");
64563
- }
64564
64714
  var ClientConnection = class {
64565
64715
  ctx;
64566
64716
  onSessionUpdate;
@@ -66059,10 +66209,6 @@ ${message.api_refusal_explanation}` : "";
66059
66209
  }
66060
66210
  switch (message.subtype) {
66061
66211
  case "success": {
66062
- if (message.result.includes("Please run /login")) {
66063
- failActive(RequestError3.authRequired());
66064
- break;
66065
- }
66066
66212
  if (message.stop_reason === "max_tokens") {
66067
66213
  stopReason = "max_tokens";
66068
66214
  break;
@@ -66286,8 +66432,8 @@ ${message.api_refusal_explanation}` : "";
66286
66432
  if (message.message.role === "system") {
66287
66433
  break;
66288
66434
  }
66289
- if (message.type === "assistant" && isSyntheticLoginMessage(message.message)) {
66290
- failActive(RequestError3.authRequired());
66435
+ if (message.type === "assistant" && message.error === "authentication_failed") {
66436
+ failActive(RequestError3.authRequired(errorKindData(message.error)));
66291
66437
  break;
66292
66438
  }
66293
66439
  let content;
@@ -66670,9 +66816,6 @@ ${message.api_refusal_explanation}` : "";
66670
66816
  if (replaySession && replayMessageId && message.uuid) {
66671
66817
  replaySession.messageIdToUuid.set(replayMessageId, message.uuid);
66672
66818
  }
66673
- if (message.type === "assistant" && isSyntheticLoginMessage(message.message)) {
66674
- continue;
66675
- }
66676
66819
  const parentToolUseId = parentToolUseIdOf(message);
66677
66820
  if (parentToolUseId !== null && !forwardSubagentText) {
66678
66821
  continue;
@@ -96703,37 +96846,44 @@ async function runRelayConnection({
96703
96846
  // src/runtime/relay/session-event-publisher.ts
96704
96847
  import { WebSocket as WebSocket8 } from "undici";
96705
96848
  var MAX_BUFFERED_BYTES = 32 * 1024 * 1024;
96849
+ var MAX_PENDING_BYTES2 = 32 * 1024 * 1024;
96706
96850
  var MAX_EVENT_BATCH_BYTES = 1024 * 1024;
96707
96851
  var MAX_FRAME_BYTES = 8 * 1024 * 1024;
96708
96852
  var LOCAL_BACKPRESSURE_CLOSE_CODE = 4009;
96709
96853
  var EMPTY_ENVELOPE_BYTES = Buffer.byteLength(JSON.stringify({ events: [], kind: SESSION_EVENT_KIND }));
96710
96854
  var SESSION_EVENT_BATCH_WINDOW_MILLISECONDS = 100;
96711
96855
  var RuntimeSessionEventPublisher = class {
96712
- #pendingEvents = [];
96713
- #pendingBytes = EMPTY_ENVELOPE_BYTES;
96856
+ #pending = [];
96857
+ #pendingBytes = 0;
96858
+ #overflowReported = false;
96714
96859
  #pendingTask = null;
96715
- #socket = null;
96860
+ #connection = { kind: "disconnected" };
96716
96861
  #timer;
96717
96862
  constructor(timer) {
96718
96863
  this.#timer = timer;
96719
96864
  }
96720
96865
  connect = (socket) => {
96721
- this.dropPendingEvents();
96722
- this.#socket = socket;
96866
+ if (this.#connection.kind === "closed") {
96867
+ return;
96868
+ }
96869
+ this.#connection = { kind: "connected", socket };
96870
+ this.flushEvents(socket);
96723
96871
  };
96724
96872
  disconnect = (socket) => {
96725
- if (this.#socket === socket) {
96726
- this.#socket = null;
96727
- this.dropPendingEvents();
96873
+ if (this.#connection.kind === "connected" && this.#connection.socket === socket) {
96874
+ this.#connection = { kind: "disconnected" };
96875
+ this.cancelFlush();
96728
96876
  }
96729
96877
  };
96730
96878
  close = () => {
96731
- this.#socket = null;
96732
- this.dropPendingEvents();
96879
+ this.#connection = { kind: "closed" };
96880
+ this.cancelFlush();
96881
+ this.#pending.length = 0;
96882
+ this.#pendingBytes = 0;
96733
96883
  };
96734
96884
  flush = () => {
96735
- if (this.#socket !== null) {
96736
- this.flushEvents(this.#socket);
96885
+ if (this.#connection.kind === "connected") {
96886
+ this.flushEvents(this.#connection.socket);
96737
96887
  }
96738
96888
  };
96739
96889
  publishOperationFailure = (sessionId, requestId, code, message) => {
@@ -96743,10 +96893,11 @@ var RuntimeSessionEventPublisher = class {
96743
96893
  publishInfo = (event) => this.#send(event);
96744
96894
  publishClosed = (event) => this.#send(event);
96745
96895
  #send = (message) => {
96746
- const socket = this.#socket;
96747
- if (socket === null || socket.readyState !== WebSocket8.OPEN) {
96896
+ const connection = this.#connection;
96897
+ if (connection.kind !== "connected" || connection.socket.readyState !== WebSocket8.OPEN) {
96748
96898
  return;
96749
96899
  }
96900
+ const socket = connection.socket;
96750
96901
  const encoded = encodeDaemonToServiceMessage(message);
96751
96902
  if (socket.bufferedAmount + Buffer.byteLength(encoded, "utf8") > MAX_BUFFERED_BYTES) {
96752
96903
  socket.close(LOCAL_BACKPRESSURE_CLOSE_CODE, "Live event transport overloaded");
@@ -96758,8 +96909,7 @@ var RuntimeSessionEventPublisher = class {
96758
96909
  }
96759
96910
  };
96760
96911
  publish = (event) => {
96761
- const socket = this.#socket;
96762
- if (socket === null || socket.readyState !== WebSocket8.OPEN) {
96912
+ if (this.#connection.kind === "closed") {
96763
96913
  return;
96764
96914
  }
96765
96915
  const bytes = Buffer.byteLength(JSON.stringify(event), "utf8") + 1;
@@ -96772,15 +96922,34 @@ var RuntimeSessionEventPublisher = class {
96772
96922
  });
96773
96923
  return;
96774
96924
  }
96775
- if (this.#pendingEvents.length > 0 && this.#pendingBytes + bytes > MAX_EVENT_BATCH_BYTES) {
96776
- this.flushEvents(socket);
96777
- if (socket.readyState !== WebSocket8.OPEN) {
96778
- return;
96925
+ let batch = this.#pending.at(-1);
96926
+ const newBatch = batch === void 0 || batch.events.length >= SESSION_EVENT_BATCH_MAX_SIZE || batch.bytes + bytes > MAX_EVENT_BATCH_BYTES;
96927
+ const additionalBytes = bytes + (newBatch ? EMPTY_ENVELOPE_BYTES : 0);
96928
+ if (this.#pendingBytes + additionalBytes > MAX_PENDING_BYTES2) {
96929
+ if (!this.#overflowReported) {
96930
+ this.#overflowReported = true;
96931
+ console.warn("Live Session output exceeded the pending buffer limit", {
96932
+ code: "live_event_buffer_full",
96933
+ sessionId: event.sessionId,
96934
+ eventId: event.eventId,
96935
+ maximumBytes: MAX_PENDING_BYTES2
96936
+ });
96779
96937
  }
96938
+ return;
96780
96939
  }
96781
- this.#pendingEvents.push(event);
96782
- this.#pendingBytes += bytes;
96783
- if (this.#pendingEvents.length >= SESSION_EVENT_BATCH_MAX_SIZE || this.#pendingBytes >= MAX_EVENT_BATCH_BYTES) {
96940
+ if (batch === void 0 || newBatch) {
96941
+ batch = { events: [], bytes: EMPTY_ENVELOPE_BYTES };
96942
+ this.#pending.push(batch);
96943
+ }
96944
+ batch.events.push(event);
96945
+ batch.bytes += bytes;
96946
+ this.#pendingBytes += additionalBytes;
96947
+ const connection = this.#connection;
96948
+ if (connection.kind !== "connected" || connection.socket.readyState !== WebSocket8.OPEN) {
96949
+ return;
96950
+ }
96951
+ const socket = connection.socket;
96952
+ if (this.#pending.length > 1 || batch.events.length >= SESSION_EVENT_BATCH_MAX_SIZE || batch.bytes >= MAX_EVENT_BATCH_BYTES) {
96784
96953
  this.flushEvents(socket);
96785
96954
  return;
96786
96955
  }
@@ -96789,29 +96958,35 @@ var RuntimeSessionEventPublisher = class {
96789
96958
  SESSION_EVENT_BATCH_WINDOW_MILLISECONDS
96790
96959
  );
96791
96960
  };
96792
- dropPendingEvents = () => {
96961
+ cancelFlush = () => {
96793
96962
  this.#pendingTask?.cancel();
96794
96963
  this.#pendingTask = null;
96795
- this.#pendingEvents = [];
96796
- this.#pendingBytes = EMPTY_ENVELOPE_BYTES;
96797
96964
  };
96798
96965
  flushEvents = (socket) => {
96799
- this.#pendingTask?.cancel();
96800
- this.#pendingTask = null;
96801
- const events = this.#pendingEvents;
96802
- this.#pendingEvents = [];
96803
- this.#pendingBytes = EMPTY_ENVELOPE_BYTES;
96804
- if (events.length === 0 || this.#socket !== socket || socket.readyState !== WebSocket8.OPEN) {
96966
+ this.cancelFlush();
96967
+ const connection = this.#connection;
96968
+ if (connection.kind !== "connected" || connection.socket !== socket || socket.readyState !== WebSocket8.OPEN) {
96805
96969
  return;
96806
96970
  }
96807
- const encoded = encodeDaemonToServiceMessage({ events, kind: SESSION_EVENT_KIND });
96808
- if (socket.bufferedAmount + Buffer.byteLength(encoded, "utf8") > MAX_BUFFERED_BYTES) {
96809
- socket.close(LOCAL_BACKPRESSURE_CLOSE_CODE, "Live event transport overloaded");
96810
- return;
96971
+ let attempted = 0;
96972
+ for (const batch of this.#pending) {
96973
+ const encoded = encodeDaemonToServiceMessage({ events: batch.events, kind: SESSION_EVENT_KIND });
96974
+ if (socket.bufferedAmount + Buffer.byteLength(encoded, "utf8") > MAX_BUFFERED_BYTES) {
96975
+ socket.close(LOCAL_BACKPRESSURE_CLOSE_CODE, "Live event transport overloaded");
96976
+ break;
96977
+ }
96978
+ attempted += 1;
96979
+ this.#pendingBytes -= batch.bytes;
96980
+ try {
96981
+ socket.send(encoded);
96982
+ } catch {
96983
+ console.warn("Live Session output could not be sent", { code: "live_event_send_failed" });
96984
+ break;
96985
+ }
96811
96986
  }
96812
- try {
96813
- socket.send(encoded);
96814
- } catch {
96987
+ this.#pending.splice(0, attempted);
96988
+ if (this.#pending.length === 0) {
96989
+ this.#overflowReported = false;
96815
96990
  }
96816
96991
  };
96817
96992
  };