@super-one/cli 0.75.1 → 0.75.2

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/MANIFEST.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@super-one/cli",
3
- "version": "0.75.1",
3
+ "version": "0.75.2",
4
4
  "kind": "npm",
5
5
  "minNodeMajor": 20,
6
- "builtAt": "2026-10-19T10:32:17.176Z"
6
+ "builtAt": "2026-10-19T19:21:56.991Z"
7
7
  }
package/lib/cli.mjs CHANGED
@@ -137,8 +137,8 @@ import { fileURLToPath } from "node:url";
137
137
  function resolveCliReleaseVersion() {
138
138
  const fromEnv = process.env.SUPERONE_CLI_VERSION?.trim();
139
139
  if (fromEnv) return fromEnv;
140
- if ("0.75.1".trim()) {
141
- return "0.75.1".trim();
140
+ if ("0.75.2".trim()) {
141
+ return "0.75.2".trim();
142
142
  }
143
143
  const fromDist = readDistManifestVersion();
144
144
  if (fromDist) return fromDist;
@@ -5325,6 +5325,20 @@ var init_session_messages = __esm({
5325
5325
  }
5326
5326
  });
5327
5327
 
5328
+ // ../../packages/shared/src/environment/transcript-window.ts
5329
+ function desktopShowsSession(holders) {
5330
+ return holders.some((holder) => holder.startsWith(DESKTOP_WINDOW_HOLDER_PREFIX));
5331
+ }
5332
+ var TRANSCRIPT_WINDOW_SCHEMA, TRANSCRIPT_WINDOW_METHOD, DESKTOP_WINDOW_HOLDER_PREFIX;
5333
+ var init_transcript_window = __esm({
5334
+ "../../packages/shared/src/environment/transcript-window.ts"() {
5335
+ "use strict";
5336
+ TRANSCRIPT_WINDOW_SCHEMA = 1;
5337
+ TRANSCRIPT_WINDOW_METHOD = "session.transcriptWindow";
5338
+ DESKTOP_WINDOW_HOLDER_PREFIX = "desktop:";
5339
+ }
5340
+ });
5341
+
5328
5342
  // ../../packages/shared/src/environment/provider-resume.ts
5329
5343
  function providerSessionIdFromResume(providerResume) {
5330
5344
  const raw = typeof providerResume === "string" ? providerResume.trim() : "";
@@ -5502,6 +5516,7 @@ var init_environment = __esm({
5502
5516
  init_events();
5503
5517
  init_session_events();
5504
5518
  init_session_messages();
5519
+ init_transcript_window();
5505
5520
  init_provider_resume();
5506
5521
  init_lease();
5507
5522
  init_gateway();
@@ -11637,6 +11652,66 @@ var init_session_message_range = __esm({
11637
11652
  }
11638
11653
  });
11639
11654
 
11655
+ // ../../packages/runtime/src/stream/delivery/transcript-access.ts
11656
+ function missingRow() {
11657
+ return Object.assign(new Error("transcript index out of range"), { code: "not_found" });
11658
+ }
11659
+ function arrayTranscript(messages) {
11660
+ let ids;
11661
+ return {
11662
+ count: messages.length,
11663
+ messageAt(index) {
11664
+ const message = messages[index];
11665
+ if (!message) throw missingRow();
11666
+ return message;
11667
+ },
11668
+ indexOf: (messageId) => (ids ??= new Map(messages.map((message, index) => [message.id, index]))).get(messageId) ?? -1
11669
+ };
11670
+ }
11671
+ function sqliteTranscript(db, input) {
11672
+ const { table: table2, idColumn, columns, sessionId } = input;
11673
+ const total = db.prepare(`SELECT COUNT(*) AS count FROM ${table2} WHERE session_id = ?`).get(sessionId).count;
11674
+ const rowBefore = db.prepare(`SELECT ${columns} FROM ${table2} WHERE session_id = ? AND sort_order < ? ORDER BY sort_order DESC LIMIT 1`);
11675
+ const rowAfter = db.prepare(`SELECT ${columns} FROM ${table2} WHERE session_id = ? AND sort_order > ? ORDER BY sort_order ASC LIMIT 1`);
11676
+ const rowAtOffset = db.prepare(`SELECT ${columns} FROM ${table2} WHERE session_id = ? ORDER BY sort_order ASC LIMIT 1 OFFSET ?`);
11677
+ const sortOfId = db.prepare(`SELECT sort_order FROM ${table2} WHERE session_id = ? AND ${idColumn} = ?`);
11678
+ const countBefore = db.prepare(`SELECT COUNT(*) AS count FROM ${table2} WHERE session_id = ? AND sort_order < ?`);
11679
+ const byIndex = /* @__PURE__ */ new Map();
11680
+ const idIndex = /* @__PURE__ */ new Map();
11681
+ return {
11682
+ count: total,
11683
+ parsed: () => byIndex.size,
11684
+ messageAt(index) {
11685
+ const cached5 = byIndex.get(index);
11686
+ if (cached5) return cached5.message;
11687
+ if (index < 0 || index >= total) throw missingRow();
11688
+ const newer = byIndex.get(index + 1);
11689
+ const older = byIndex.get(index - 1);
11690
+ const row2 = newer ? rowBefore.get(sessionId, newer.sortOrder) : older ? rowAfter.get(sessionId, older.sortOrder) : rowAtOffset.get(sessionId, index);
11691
+ if (!row2) throw missingRow();
11692
+ const entry3 = { message: input.parse(row2), sortOrder: row2.sort_order };
11693
+ byIndex.set(index, entry3);
11694
+ idIndex.set(entry3.message.id, index);
11695
+ return entry3.message;
11696
+ },
11697
+ indexOf(messageId) {
11698
+ const cached5 = idIndex.get(messageId);
11699
+ if (cached5 !== void 0) return cached5;
11700
+ const row2 = sortOfId.get(sessionId, messageId);
11701
+ if (!row2) return -1;
11702
+ const index = countBefore.get(sessionId, row2.sort_order).count;
11703
+ if (index >= total) return -1;
11704
+ idIndex.set(messageId, index);
11705
+ return index;
11706
+ }
11707
+ };
11708
+ }
11709
+ var init_transcript_access = __esm({
11710
+ "../../packages/runtime/src/stream/delivery/transcript-access.ts"() {
11711
+ "use strict";
11712
+ }
11713
+ });
11714
+
11640
11715
  // ../../packages/shared/src/launch-options.ts
11641
11716
  var HARNESS_LAUNCH_OPTIONS;
11642
11717
  var init_launch_options = __esm({
@@ -17301,6 +17376,25 @@ var init_session_runtime = __esm({
17301
17376
  const snapshot = this.requireReadModel().snapshot(sessionId, input);
17302
17377
  return snapshot.after == null ? { ...snapshot, messages: this.withProviderResume(sessionId, snapshot.messages) } : snapshot;
17303
17378
  }
17379
+ /**
17380
+ * Bounded `session.transcriptWindow` read. `read` runs in this turn.
17381
+ * A cold checkpoint stays out of the read-model cache.
17382
+ */
17383
+ readTranscriptWindow(input) {
17384
+ const sessionId = this.requireSessionId(input.sessionId);
17385
+ const opened = this.requireReadModel().openWindow(sessionId, input.includeState);
17386
+ const resume = this.live.get(sessionId)?.providerResume;
17387
+ const last = opened.transcript.count - 1;
17388
+ const transcript = !resume ? opened.transcript : {
17389
+ ...opened.transcript,
17390
+ messageAt: (index) => {
17391
+ const message = opened.transcript.messageAt(index);
17392
+ if (index !== last || message.role !== "assistant" || message.resumePointId) return message;
17393
+ return { ...message, resumePointId: resume };
17394
+ }
17395
+ };
17396
+ return Promise.resolve(input.read({ transcript, state: opened.state, cursor: opened.cursor }));
17397
+ }
17304
17398
  /** The session's reduced transcript now; a host without a read model keeps none. */
17305
17399
  messages(sessionId) {
17306
17400
  sessionId = this.requireSessionId(sessionId);
@@ -22121,6 +22215,10 @@ var init_node_session_messages = __esm({
22121
22215
 
22122
22216
  // ../../packages/runtime/src/session/read-model.ts
22123
22217
  import { randomUUID as randomUUID4 } from "node:crypto";
22218
+ function coreState(core) {
22219
+ const { messages: _messages, ...state } = core;
22220
+ return state;
22221
+ }
22124
22222
  function sessionReadModel(db, log2) {
22125
22223
  return (records2) => {
22126
22224
  const readModel = new SessionReadModel(db, log2, records2);
@@ -22138,6 +22236,7 @@ var init_read_model = __esm({
22138
22236
  init_node_session_event_map();
22139
22237
  init_node_message_catalog();
22140
22238
  init_node_session_messages();
22239
+ init_transcript_access();
22141
22240
  init_message_catalog();
22142
22241
  MAX_IDLE_SESSIONS = 64;
22143
22242
  SessionReadModel = class {
@@ -22202,6 +22301,37 @@ var init_read_model = __esm({
22202
22301
  }
22203
22302
  session.applied = envelope.sessionVersion ?? session.applied;
22204
22303
  }
22304
+ /**
22305
+ * A transcript window. A cold session whose checkpoint is current is read by
22306
+ * index: nothing is reduced, so its rows equal a full load's, and they are
22307
+ * neither cached nor checkpointed. A session in memory, one with no
22308
+ * checkpoint, or one with events after its checkpoint (a turn that did not
22309
+ * finish) uses the complete session.
22310
+ */
22311
+ openWindow(sessionId, includeState) {
22312
+ const checkpoint = this.sessions.has(sessionId) ? void 0 : this.db.prepare(`SELECT applied_version, state_json FROM session_read_models WHERE session_id = ?`).get(sessionId);
22313
+ const current = checkpoint && !this.log.listForSession(sessionId, Number.MAX_SAFE_INTEGER, checkpoint.applied_version).length;
22314
+ if (!checkpoint || !current) {
22315
+ const session = this.load(sessionId);
22316
+ return {
22317
+ transcript: arrayTranscript(session.core.messages),
22318
+ state: includeState ? coreState(session.core) : {},
22319
+ cursor: { sequence: this.log.headSequence(), epoch: this.log.epoch, version: session.applied }
22320
+ };
22321
+ }
22322
+ const core = { ...createDefaultChatCoreSession(), ...JSON.parse(checkpoint.state_json), messages: [] };
22323
+ return {
22324
+ transcript: sqliteTranscript(this.db, {
22325
+ table: "session_messages",
22326
+ idColumn: "message_id",
22327
+ columns: "message_json, sort_order",
22328
+ sessionId,
22329
+ parse: (row2) => JSON.parse(row2.message_json)
22330
+ }),
22331
+ state: includeState ? coreState(core) : {},
22332
+ cursor: { sequence: this.log.headSequence(), epoch: this.log.epoch, version: checkpoint.applied_version }
22333
+ };
22334
+ }
22205
22335
  load(sessionId) {
22206
22336
  const loaded2 = this.sessions.get(sessionId);
22207
22337
  if (loaded2) {
@@ -102006,6 +102136,7 @@ function lightLiveMetadata(metadata) {
102006
102136
  }
102007
102137
 
102008
102138
  // ../../packages/runtime/src/stream/delivery/window-views.ts
102139
+ init_transcript_access();
102009
102140
  var LIVE_MESSAGE_BUDGET = { maxBytes: 64 * 1024, maxFragments: 24, targetChars: Number.MAX_SAFE_INTEGER };
102010
102141
  var LIVE_PATCH_BYTES = 256 * 1024;
102011
102142
  var MAX_HELD = 64;
@@ -102020,12 +102151,11 @@ var SessionFragments = class {
102020
102151
  }
102021
102152
  return fragments;
102022
102153
  }
102023
- source(messages) {
102024
- let ids;
102154
+ source(transcript) {
102025
102155
  return {
102026
- count: messages.length,
102027
- at: (index) => this.of(messages[index]),
102028
- indexOf: (messageId) => (ids ??= new Map(messages.map((message, index) => [message.id, index]))).get(messageId) ?? -1
102156
+ count: transcript.count,
102157
+ at: (index) => this.of(transcript.messageAt(index)),
102158
+ indexOf: (messageId) => transcript.indexOf(messageId)
102029
102159
  };
102030
102160
  }
102031
102161
  retain(messages) {
@@ -102034,24 +102164,37 @@ var SessionFragments = class {
102034
102164
  };
102035
102165
  var WindowViews = class {
102036
102166
  sessions = /* @__PURE__ */ new Map();
102167
+ /** Holders the 64-window cap dropped since the last drain. Switching a holder off a session is not an eviction. */
102168
+ evicted = [];
102037
102169
  has(sessionId) {
102038
102170
  return (this.sessions.get(sessionId)?.holders.size ?? 0) > 0;
102039
102171
  }
102172
+ /** Holder ids following `sessionId`, oldest serve first. */
102173
+ holderIds(sessionId) {
102174
+ return [...this.sessions.get(sessionId)?.holders.keys() ?? []];
102175
+ }
102176
+ /** Holders dropped by the cap. Each call takes them, so a frame reports an eviction once. */
102177
+ drainEvicted() {
102178
+ return this.evicted.splice(0);
102179
+ }
102040
102180
  serve(input) {
102181
+ const transcript = input.transcript ?? (input.messages ? arrayTranscript(input.messages) : null);
102182
+ if (!transcript) throw new Error("transcript window needs messages");
102041
102183
  const session = this.session(input.sessionId);
102042
- const selected = selectTranscriptWindow(session.fragments.source(input.messages), input.request, input.budget);
102184
+ const selected = selectTranscriptWindow(session.fragments.source(transcript), input.request, input.budget);
102043
102185
  const extend2 = input.request.anchor && input.request.direction !== "around" ? input.request.direction ?? "before" : null;
102044
102186
  const previous = session.holders.get(input.holder);
102045
102187
  const held = extend2 && previous ? previous : { messages: /* @__PURE__ */ new Map(), order: [], atTail: false, total: 0, seen: /* @__PURE__ */ new Map() };
102046
102188
  for (const message of selected.messages) {
102047
- const fragments = session.fragments.of(input.messages[message.index]);
102048
- if (!held.messages.has(message.id)) held.seen.set(message.id, input.messages[message.index]);
102189
+ const source = transcript.messageAt(message.index);
102190
+ const fragments = session.fragments.of(source);
102191
+ if (!held.messages.has(message.id)) held.seen.set(message.id, source);
102049
102192
  recordMessage(held, message, fragments, extend2 === "before" ? "before" : extend2 === "after" ? "after" : null);
102050
102193
  }
102051
102194
  const ids = selected.messages.map((message) => message.id);
102052
102195
  held.order = extend2 === "before" ? [...ids, ...held.order.filter((id) => !ids.includes(id))] : extend2 === "after" ? [...held.order.filter((id) => !ids.includes(id)), ...ids] : ids;
102053
102196
  if (!extend2 || extend2 === "after") held.atTail = selected.newer === null;
102054
- held.total = input.messages.length;
102197
+ held.total = transcript.count;
102055
102198
  session.holders.delete(input.holder);
102056
102199
  session.holders.set(input.holder, held);
102057
102200
  for (const [id, other] of this.sessions) {
@@ -102062,7 +102205,7 @@ var WindowViews = class {
102062
102205
  this.touch(input.sessionId);
102063
102206
  this.evict();
102064
102207
  session.fragments.retain(this.heldIds(input.sessionId));
102065
- return { ...selected, total: input.messages.length };
102208
+ return { ...selected, total: transcript.count };
102066
102209
  }
102067
102210
  /** Patches for every holder of a session whose window `messages` changed. */
102068
102211
  patches(sessionId, messages) {
@@ -102116,6 +102259,7 @@ var WindowViews = class {
102116
102259
  for (const holder of session.holders.keys()) {
102117
102260
  if (count <= MAX_HELD) break;
102118
102261
  session.holders.delete(holder);
102262
+ this.evicted.push({ sessionId, holder });
102119
102263
  count--;
102120
102264
  }
102121
102265
  if (!session.holders.size) this.sessions.delete(sessionId);
@@ -106616,6 +106760,7 @@ function coalesceAgentEventBatch(events) {
106616
106760
  }
106617
106761
 
106618
106762
  // ../../packages/runtime/src/server/session-delivery.ts
106763
+ init_transcript_window();
106619
106764
  var detailMessages = (sessions, sessionId) => sessions.detailMessages?.(sessionId) ?? sessions.messages(sessionId);
106620
106765
  function deliverLoad(result3, delivery) {
106621
106766
  if (!delivery) return result3;
@@ -106646,7 +106791,6 @@ function deliverLoad(result3, delivery) {
106646
106791
  function deliverFrame(frame, delivery, sessions) {
106647
106792
  const changed = /* @__PURE__ */ new Set();
106648
106793
  const windowed = /* @__PURE__ */ new Map();
106649
- const withholds = delivery.policy.surface === "phone";
106650
106794
  const events = frame.events.flatMap((envelope) => {
106651
106795
  const event = agentEventOf(envelope, sessions);
106652
106796
  if (!event) return [envelope];
@@ -106656,7 +106800,7 @@ function deliverFrame(frame, delivery, sessions) {
106656
106800
  const holdsWindow = delivery.windows.has(sessionId);
106657
106801
  if (holdsWindow) windowed.set(sessionId, envelope);
106658
106802
  const shaped = delivery.event(event, sessionId, summarized ? sessions.messages(sessionId) : []);
106659
- const live = holdsWindow && withholds ? shaped.flatMap((next) => windowLiveEvent(next) ?? []) : shaped;
106803
+ const live = holdsWindow && !desktopShowsSession(delivery.windows.holderIds(sessionId)) ? shaped.flatMap((next) => windowLiveEvent(next) ?? []) : shaped;
106660
106804
  return live.map((next) => ({
106661
106805
  ...envelope,
106662
106806
  eventType: SESSION_DURABLE_EVENT.agentEvent,
@@ -106670,7 +106814,9 @@ function deliverFrame(frame, delivery, sessions) {
106670
106814
  }
106671
106815
  }
106672
106816
  const details = [...changed].flatMap((sessionId) => delivery.views.hasDetails(sessionId) ? delivery.details(sessionId, detailMessages(sessions, sessionId)).flatMap((event) => event.type === "remote_detail" ? [{ sessionId, update: { subscriptionId: event.subscriptionId, revision: event.revision, offset: event.offset, text: event.text } }] : []) : []);
106673
- return { frame: { ...frame, events: foldDeltas(events) }, details };
106817
+ const dropped = delivery.windows.drainEvicted().map((item) => item.sessionId);
106818
+ const resnapshot = dropped.length ? [.../* @__PURE__ */ new Set([...frame.resnapshot ?? [], ...dropped])] : frame.resnapshot;
106819
+ return { frame: { ...frame, events: foldDeltas(events), ...resnapshot?.length ? { resnapshot } : {} }, details };
106674
106820
  }
106675
106821
  function foldDeltas(envelopes) {
106676
106822
  const out = [];
@@ -106697,7 +106843,7 @@ function subscribeDetail(delivery, sessions, input) {
106697
106843
  } catch (err) {
106698
106844
  throw Object.assign(err, { code: "invalid_argument" });
106699
106845
  }
106700
- const message = detailMessages(sessions, input.sessionId).find((candidate) => candidate.id === messageId);
106846
+ const message = sessions.detailMessage ? sessions.detailMessage(input.sessionId, messageId) : detailMessages(sessions, input.sessionId).find((candidate) => candidate.id === messageId);
106701
106847
  if (!message) throw Object.assign(new Error("Detail not found"), { code: "not_found" });
106702
106848
  try {
106703
106849
  return delivery.views.subscribe(input.sessionId, input.subscriptionId, input.detailRef, message);
@@ -107132,12 +107278,8 @@ function handleSessionUnsubscribeDetail(payload, ctx) {
107132
107278
 
107133
107279
  // ../../packages/runtime/src/server/rpc-session-window.ts
107134
107280
  init_environment();
107135
-
107136
- // ../../packages/shared/src/environment/transcript-window.ts
107137
- var TRANSCRIPT_WINDOW_SCHEMA = 1;
107138
- var TRANSCRIPT_WINDOW_METHOD = "session.transcriptWindow";
107139
-
107140
- // ../../packages/runtime/src/server/rpc-session-window.ts
107281
+ init_transcript_window();
107282
+ init_transcript_access();
107141
107283
  var MAX_HOLDER_LENGTH = 128;
107142
107284
  var invalid5 = (message) => ({ error: { code: "invalid_argument", message } });
107143
107285
  async function handleSessionTranscriptWindow(payload, ctx) {
@@ -107152,33 +107294,57 @@ async function handleSessionTranscriptWindow(payload, ctx) {
107152
107294
  if ("error" in parsed) return parsed;
107153
107295
  const { anchor, direction, viewport, budget, have, holder } = parsed;
107154
107296
  const includeState = parsed.includeState ?? !anchor;
107297
+ const request = { anchor, direction, have };
107298
+ const limits = windowBudget({ budget, viewport });
107155
107299
  try {
107300
+ if (sessions.readTranscriptWindow) {
107301
+ return await sessions.readTranscriptWindow({
107302
+ sessionId: target2.sessionId,
107303
+ includeState,
107304
+ read: (view) => windowResult(ctx, target2.sessionId, holder, request, limits, view, includeState)
107305
+ });
107306
+ }
107156
107307
  const loaded2 = await sessions.load({ sessionId: target2.sessionId, includeState, full: true });
107157
- const delivery = ctx.streams?.delivery;
107158
- const selected = (delivery?.windows ?? new WindowViews()).serve({
107159
- sessionId: target2.sessionId,
107160
- holder,
107161
- messages: loaded2.messages,
107162
- request: { anchor, direction, have },
107163
- budget: windowBudget({ budget, viewport })
107164
- });
107165
- const shaped = deliverLoad({ ...loaded2, messages: [], activeTurn: void 0 }, delivery);
107166
- const result3 = {
107167
- sessionId: target2.sessionId,
107168
- schema: TRANSCRIPT_WINDOW_SCHEMA,
107169
- messages: selected.messages,
107170
- older: selected.older,
107171
- newer: selected.newer,
107172
- total: selected.total,
107173
- ...includeState ? { state: shaped.state, ...shaped.restore ? { restore: shaped.restore } : {} } : {},
107174
- cursor: loaded2.cursor,
107175
- ...shaped.summarized ? { summarized: true } : {}
107176
- };
107177
- return { result: result3 };
107308
+ return windowResult(ctx, target2.sessionId, holder, request, limits, {
107309
+ transcript: arrayTranscript(loaded2.messages),
107310
+ state: loaded2.state,
107311
+ restore: loaded2.restore,
107312
+ cursor: loaded2.cursor
107313
+ }, includeState);
107178
107314
  } catch (err) {
107179
107315
  return mapThrown(err);
107180
107316
  }
107181
107317
  }
107318
+ function windowResult(ctx, sessionId, holder, request, budget, view, includeState) {
107319
+ const delivery = ctx.streams?.delivery;
107320
+ const selected = (delivery?.windows ?? new WindowViews()).serve({
107321
+ sessionId,
107322
+ holder,
107323
+ transcript: view.transcript,
107324
+ request,
107325
+ budget
107326
+ });
107327
+ const shaped = deliverLoad({
107328
+ sessionId,
107329
+ state: view.state,
107330
+ messages: [],
107331
+ ...view.restore ? { restore: view.restore } : {},
107332
+ cursor: view.cursor,
107333
+ before: null
107334
+ }, delivery);
107335
+ const result3 = {
107336
+ sessionId,
107337
+ schema: TRANSCRIPT_WINDOW_SCHEMA,
107338
+ messages: selected.messages,
107339
+ older: selected.older,
107340
+ newer: selected.newer,
107341
+ total: selected.total,
107342
+ ...includeState ? { state: shaped.state, ...shaped.restore ? { restore: shaped.restore } : {} } : {},
107343
+ cursor: view.cursor,
107344
+ ...shaped.summarized ? { summarized: true } : {}
107345
+ };
107346
+ return { result: result3 };
107347
+ }
107182
107348
  function parseWindowRequest(p3) {
107183
107349
  let anchor;
107184
107350
  if (p3.anchor !== void 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@super-one/cli",
3
- "version": "0.75.1",
3
+ "version": "0.75.2",
4
4
  "description": "SuperOne headless node CLI — remote execution environment (RPC, workspaces, sessions).",
5
5
  "type": "module",
6
6
  "license": "BUSL-1.1",