@zaly/agent 0.1.0 → 0.2.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 (87) hide show
  1. package/dist/{agent-D5NrjvG5.mjs → agent-DlhEEMPU.mjs} +103 -33
  2. package/dist/agent-DlhEEMPU.mjs.map +1 -0
  3. package/dist/{agent-B7cQOuMZ.mjs → agent-sHtwQDAk.mjs} +2 -3
  4. package/dist/{agent-B7cQOuMZ.mjs.map → agent-sHtwQDAk.mjs.map} +1 -1
  5. package/dist/{bash-9x8PPg0A.mjs → bash-DSy03sAj.mjs} +3 -4
  6. package/dist/{bash-9x8PPg0A.mjs.map → bash-DSy03sAj.mjs.map} +1 -1
  7. package/dist/compactions-BpvQk4CG.mjs +160 -0
  8. package/dist/compactions-BpvQk4CG.mjs.map +1 -0
  9. package/dist/{edit-D4yaBK1K.mjs → edit-DT672zIy.mjs} +2 -3
  10. package/dist/edit-DT672zIy.mjs.map +1 -0
  11. package/dist/{env-UUFv5Mye.mjs → env-C8p8i1E0.mjs} +2 -3
  12. package/dist/{env-UUFv5Mye.mjs.map → env-C8p8i1E0.mjs.map} +1 -1
  13. package/dist/{fetch-D0IeDN6H.mjs → fetch-BrtIqrid.mjs} +5 -6
  14. package/dist/{fetch-D0IeDN6H.mjs.map → fetch-BrtIqrid.mjs.map} +1 -1
  15. package/dist/{find-D1Z2ac_b.mjs → find-B-vvdlHu.mjs} +3 -4
  16. package/dist/{find-D1Z2ac_b.mjs.map → find-B-vvdlHu.mjs.map} +1 -1
  17. package/dist/{grep-By4wLRDk.mjs → grep-rvZ5S319.mjs} +3 -4
  18. package/dist/{grep-By4wLRDk.mjs.map → grep-rvZ5S319.mjs.map} +1 -1
  19. package/dist/{html-J629LNIm.mjs → html-VrAsoGBK.mjs} +277 -552
  20. package/dist/{html-J629LNIm.mjs.map → html-VrAsoGBK.mjs.map} +1 -1
  21. package/dist/{index-node-esm-CJsN8G51.mjs → index-node-esm-BwaOzhXB.mjs} +2 -3
  22. package/dist/{index-node-esm-CJsN8G51.mjs.map → index-node-esm-BwaOzhXB.mjs.map} +1 -1
  23. package/dist/index.d.mts +43 -103
  24. package/dist/index.d.mts.map +1 -1
  25. package/dist/index.mjs +3 -3
  26. package/dist/{jsonl-CvgEOakL.mjs → jsonl-BGt7eqPK.mjs} +2 -3
  27. package/dist/{jsonl-CvgEOakL.mjs.map → jsonl-BGt7eqPK.mjs.map} +1 -1
  28. package/dist/{manager-BJLjayBz.mjs → manager-1zEE5WiA.mjs} +4 -6
  29. package/dist/{manager-BJLjayBz.mjs.map → manager-1zEE5WiA.mjs.map} +1 -1
  30. package/dist/{markdown-Bv4J8cg3.mjs → markdown-8ICz5aFw.mjs} +2 -3
  31. package/dist/{markdown-Bv4J8cg3.mjs.map → markdown-8ICz5aFw.mjs.map} +1 -1
  32. package/dist/{masker-jgSUXzjY.mjs → masker-B97uwYXG.mjs} +4 -6
  33. package/dist/{masker-jgSUXzjY.mjs.map → masker-B97uwYXG.mjs.map} +1 -1
  34. package/dist/{model-_3ZA2xqm.mjs → model-DqGqxfAc.mjs} +2 -3
  35. package/dist/{model-_3ZA2xqm.mjs.map → model-DqGqxfAc.mjs.map} +1 -1
  36. package/dist/{notify-DpG_m9iP.mjs → notify-Ds0-4BeI.mjs} +2 -3
  37. package/dist/{notify-DpG_m9iP.mjs.map → notify-Ds0-4BeI.mjs.map} +1 -1
  38. package/dist/{read-B-hwcc2Q.mjs → read-C5keKntU.mjs} +4 -44
  39. package/dist/read-C5keKntU.mjs.map +1 -0
  40. package/dist/{registry-Zo0QmKdR.mjs → registry-CntkeXlo.mjs} +34 -32
  41. package/dist/registry-CntkeXlo.mjs.map +1 -0
  42. package/dist/{rolldown-runtime-DktXgydw.mjs → rolldown-runtime-DYf_mQCB.mjs} +1 -2
  43. package/dist/{search-CH0D5CkV.mjs → search-B-89W3SM.mjs} +2 -3
  44. package/dist/{search-CH0D5CkV.mjs.map → search-B-89W3SM.mjs.map} +1 -1
  45. package/dist/session/claude.d.mts +0 -2
  46. package/dist/session/claude.d.mts.map +1 -1
  47. package/dist/session/claude.mjs +4 -6
  48. package/dist/session/claude.mjs.map +1 -1
  49. package/dist/{session-CACkHyDR.mjs → session-CUE48QWX.mjs} +84 -51
  50. package/dist/session-CUE48QWX.mjs.map +1 -0
  51. package/dist/{session-Ds5nJz5A.d.mts → session-DY9mF9Vb.d.mts} +18 -19
  52. package/dist/session-DY9mF9Vb.d.mts.map +1 -0
  53. package/dist/session.d.mts +1 -3
  54. package/dist/session.d.mts.map +1 -1
  55. package/dist/session.mjs +4 -5
  56. package/dist/{src-DoXC_gDY.mjs → src-DJoqT9yP.mjs} +35 -40
  57. package/dist/{src-DoXC_gDY.mjs.map → src-DJoqT9yP.mjs.map} +1 -1
  58. package/dist/{subagent-BMQMbANL.mjs → subagent-D-TYaX38.mjs} +4 -5
  59. package/dist/{subagent-BMQMbANL.mjs.map → subagent-D-TYaX38.mjs.map} +1 -1
  60. package/dist/{swarm-BJ3gQA1Z.mjs → swarm-B_s9Qpbt.mjs} +2 -3
  61. package/dist/{swarm-BJ3gQA1Z.mjs.map → swarm-B_s9Qpbt.mjs.map} +1 -1
  62. package/dist/{swarm-BuFx_xeY.mjs → swarm-D823Yumk.mjs} +2 -3
  63. package/dist/{swarm-BuFx_xeY.mjs.map → swarm-D823Yumk.mjs.map} +1 -1
  64. package/dist/{tasks-WdRAHsOL.mjs → tasks-D76WXWr2.mjs} +3 -4
  65. package/dist/{tasks-WdRAHsOL.mjs.map → tasks-D76WXWr2.mjs.map} +1 -1
  66. package/dist/{tasks-BA-PCeGa.mjs → tasks-Dgsiuh0Q.mjs} +3 -4
  67. package/dist/{tasks-BA-PCeGa.mjs.map → tasks-Dgsiuh0Q.mjs.map} +1 -1
  68. package/dist/{tools-CJ2x45EZ.mjs → tools-DmoUYORG.mjs} +6 -10
  69. package/dist/{tools-CJ2x45EZ.mjs.map → tools-DmoUYORG.mjs.map} +1 -1
  70. package/dist/{truncate-BSMXgiXj.mjs → truncate-CChlZ113.mjs} +2 -3
  71. package/dist/{truncate-BSMXgiXj.mjs.map → truncate-CChlZ113.mjs.map} +1 -1
  72. package/dist/{uuid-CAdJg4l8.mjs → uuid-rfbQ9ad2.mjs} +2 -3
  73. package/dist/{uuid-CAdJg4l8.mjs.map → uuid-rfbQ9ad2.mjs.map} +1 -1
  74. package/dist/{wakeup-BYqTnfSp.mjs → wakeup-CFr1nu_L.mjs} +2 -3
  75. package/dist/{wakeup-BYqTnfSp.mjs.map → wakeup-CFr1nu_L.mjs.map} +1 -1
  76. package/dist/{write-DwGiDNeG.mjs → write-BRQFfWAn.mjs} +2 -3
  77. package/dist/write-BRQFfWAn.mjs.map +1 -0
  78. package/package.json +6 -6
  79. package/dist/agent-D5NrjvG5.mjs.map +0 -1
  80. package/dist/compactions-D9XlwQGO.mjs +0 -191
  81. package/dist/compactions-D9XlwQGO.mjs.map +0 -1
  82. package/dist/edit-D4yaBK1K.mjs.map +0 -1
  83. package/dist/read-B-hwcc2Q.mjs.map +0 -1
  84. package/dist/registry-Zo0QmKdR.mjs.map +0 -1
  85. package/dist/session-CACkHyDR.mjs.map +0 -1
  86. package/dist/session-Ds5nJz5A.d.mts.map +0 -1
  87. package/dist/write-DwGiDNeG.mjs.map +0 -1
@@ -1,11 +1,11 @@
1
- import { n as __exportAll } from "./rolldown-runtime-DktXgydw.mjs";
2
- import { r as uuidv7 } from "./uuid-CAdJg4l8.mjs";
3
- import { n as JsonlStore } from "./jsonl-CvgEOakL.mjs";
1
+ import { n as __exportAll } from "./rolldown-runtime-DYf_mQCB.mjs";
2
+ import { r as uuidv7 } from "./uuid-rfbQ9ad2.mjs";
3
+ import { n as JsonlStore } from "./jsonl-BGt7eqPK.mjs";
4
4
  import { Emitter, normPath } from "@zaly/shared";
5
5
  import { join } from "pathe";
6
6
  import { isDeepStrictEqual } from "node:util";
7
7
  import { zalyPaths } from "@zaly/shared/paths";
8
- //#region src/session/memory.ts
8
+ // src/session/memory.ts
9
9
  /**
10
10
  * In-memory `SessionStore` — a `Map<uuid, SessionNode>` plus a `root`
11
11
  * pointer. No persistence. Construction takes optional initial nodes
@@ -35,8 +35,7 @@ var MemoryStore = class {
35
35
  yield* this.#nodes.values();
36
36
  }
37
37
  };
38
- //#endregion
39
- //#region src/session/session.ts
38
+ // src/session/session.ts
40
39
  var session_exports = /* @__PURE__ */ __exportAll({ Session: () => Session });
41
40
  const VERSION = 2;
42
41
  /**
@@ -82,6 +81,7 @@ var Session = class Session extends Emitter {
82
81
  #started = false;
83
82
  #path;
84
83
  #head;
84
+ #mutations;
85
85
  constructor(opts) {
86
86
  super();
87
87
  this.#opts = opts;
@@ -155,28 +155,37 @@ var Session = class Session extends Emitter {
155
155
  };
156
156
  }
157
157
  async update(settings, opts) {
158
- return this.#commit({
158
+ return this.#mutate(() => this.#commit({
159
159
  settings,
160
160
  type: "session-settings"
161
- }, opts);
161
+ }, opts));
162
162
  }
163
163
  /** Lazily emits `session-start` on a fresh session or `session-resume`
164
164
  * on a hydrated one. Called from `#commit` before the first non-marker
165
165
  * node lands so the start/resume marker always heads the chain. */
166
166
  async #autostart() {
167
- if (!this.#started) await this.start();
167
+ if (!this.#started) await this.#start();
168
168
  }
169
169
  /** Explicitly mark the session as started — writes a `session-start`
170
170
  * marker on a fresh session, `session-resume` on a hydrated one.
171
171
  * Idempotent; subsequent calls are no-ops. Optional `meta` is
172
172
  * applied via `update()` after the marker lands. */
173
173
  async start(settings) {
174
- if (this.#started) return settings ? this.update(settings) : this.#store.root?.uuid;
174
+ return this.#mutate(() => this.#start(settings));
175
+ }
176
+ async #start(settings) {
177
+ if (this.#started) return settings ? this.#commit({
178
+ settings,
179
+ type: "session-settings"
180
+ }) : this.#store.root?.uuid;
175
181
  this.#started = true;
176
182
  const type = this.messages.length > 0 ? "session-resume" : "session-start";
177
183
  await this.#commit({ type });
178
184
  this.emit(type);
179
- await this.update(settings ?? {});
185
+ await this.#commit({
186
+ settings: settings ?? {},
187
+ type: "session-settings"
188
+ });
180
189
  return this.#store.root?.uuid;
181
190
  }
182
191
  /** Look up the decorated view for a node id — raw node plus the
@@ -219,46 +228,61 @@ var Session = class Session extends Emitter {
219
228
  id: uuid,
220
229
  ts
221
230
  };
222
- return this.#commit({
231
+ return this.#mutate(() => this.#commit({
223
232
  message: m,
224
233
  type: "message"
225
- });
234
+ }));
226
235
  }
227
- /** Mark a compaction boundary. Subsequent `add()` calls land after
228
- * this node; their messages form the new active conversation. The
229
- * pre-compact chain stays in the store but is no longer part of
230
- * `messages`. Also commits a fresh `session-meta` snapshot right
231
- * after the compact so post-compact lazy walks always have a nearby
232
- * meta anchor. */
236
+ /** Summarize an active prefix through a message ID, preserving everything
237
+ * appended after it. Boundary validation and tail calculation share the
238
+ * serialized commit with the new summary. Legacy tail-only calls remain
239
+ * supported. Original history stays in the store; a fresh settings anchor
240
+ * follows the compact node for reconstruction. */
233
241
  async compact(opts) {
234
- const node = {
235
- durationMs: opts.durationMs,
236
- parentUuid: this.#store.root?.uuid,
237
- preTokens: opts.preTokens,
238
- summary: opts.summary,
239
- tail: opts.tail,
240
- trigger: opts.trigger ?? "manual",
241
- ts: Date.now(),
242
- type: "compact",
243
- uuid: uuidv7()
244
- };
245
- const compactUuid = await this.#commit(node);
246
- await this.update({}, { force: true });
247
- await this.#rebuild();
248
- this.emit("compact", { node });
249
- return compactUuid;
242
+ return this.#mutate(async () => {
243
+ opts.signal?.throwIfAborted();
244
+ let tail = opts.tail;
245
+ if (opts.to !== void 0) {
246
+ const index = this.messages.findIndex((m) => m.id === opts.to);
247
+ if (index === -1 || opts.from !== void 0 && this.messages[0]?.id !== opts.from) throw new Error("Compaction snapshot is no longer part of the active history");
248
+ tail = this.messages.length - index - 1;
249
+ }
250
+ if (tail === void 0 || !Number.isInteger(tail) || tail < 0) throw new Error("Compaction requires a message boundary or a non-negative integer tail");
251
+ const compactUuid = await this.#commit({
252
+ durationMs: opts.durationMs,
253
+ from: opts.from,
254
+ preTokens: opts.preTokens,
255
+ summary: opts.summary,
256
+ tail,
257
+ to: opts.to,
258
+ trigger: opts.trigger ?? "manual",
259
+ type: "compact"
260
+ });
261
+ await this.#commit({
262
+ settings: {},
263
+ type: "session-settings"
264
+ }, { force: true });
265
+ await this.#rebuild();
266
+ const node = this.#view.compact;
267
+ this.emit("compact", { node });
268
+ return compactUuid;
269
+ });
250
270
  }
251
271
  async addMaskCheckpoint(opts) {
252
- this.#view.maskCheckpoint = opts;
253
- return this.#commit({
254
- ...opts,
255
- type: "mask-checkpoint"
272
+ return this.#mutate(async () => {
273
+ this.#view.maskCheckpoint = opts;
274
+ return this.#commit({
275
+ ...opts,
276
+ type: "mask-checkpoint"
277
+ });
256
278
  });
257
279
  }
258
280
  async checkout(uuid) {
259
- if (this.#closed) throw new Error("Session is closed");
260
- this.#head = uuid;
261
- await this.#rebuild();
281
+ return this.#mutate(async () => {
282
+ if (this.#closed) throw new Error("Session is closed");
283
+ this.#head = uuid;
284
+ await this.#rebuild();
285
+ });
262
286
  }
263
287
  /** Pre-active history of the current chain — messages from before
264
288
  * the most recent compact (and earlier compacts), in chronological
@@ -275,9 +299,20 @@ var Session = class Session extends Emitter {
275
299
  }
276
300
  /** Flush + close the underlying store. Subsequent writes throw. */
277
301
  async close() {
278
- if (this.#closed) return;
279
- this.#closed = true;
280
- await this.#store.close?.();
302
+ return this.#mutate(async () => {
303
+ if (this.#closed) return;
304
+ this.#closed = true;
305
+ await this.#store.close?.();
306
+ });
307
+ }
308
+ #mutate(fn) {
309
+ const pending = this.#mutations ? this.#mutations.then(fn) : fn();
310
+ const settled = pending.then(() => {}, () => {});
311
+ this.#mutations = settled;
312
+ settled.then(() => {
313
+ if (this.#mutations === settled) this.#mutations = void 0;
314
+ });
315
+ return pending;
281
316
  }
282
317
  /** Atomically commit a node: register it in the store, update active
283
318
  * messages, persist, and emit. Single chokepoint for all mutations. */
@@ -285,8 +320,8 @@ var Session = class Session extends Emitter {
285
320
  let node = {
286
321
  ...n,
287
322
  parentUuid: this.head,
288
- ts: Date.now(),
289
- uuid: uuidv7()
323
+ ts: n.type === "message" ? n.message.ts ?? Date.now() : Date.now(),
324
+ uuid: n.type === "message" ? n.message.id ?? uuidv7() : uuidv7()
290
325
  };
291
326
  if (!this.#started && node.type !== "session-start" && node.type !== "session-resume") await this.#autostart();
292
327
  if (this.#closed) throw new Error("Session is closed");
@@ -364,8 +399,7 @@ var Session = class Session extends Emitter {
364
399
  if (node.type === "mask-checkpoint" && !compact && !maskCheckpoint) maskCheckpoint = node;
365
400
  if (node.type === "message") messageNodes.push(node);
366
401
  if (node.type === "compact" && (opts.active ?? true)) {
367
- if (compact) break;
368
- compact = node;
402
+ compact ??= node;
369
403
  limit = Math.min(limit, messageNodes.length + node.tail);
370
404
  }
371
405
  if (opts.stop?.(node)) break;
@@ -444,7 +478,6 @@ var Session = class Session extends Emitter {
444
478
  }
445
479
  }
446
480
  };
447
- //#endregion
448
481
  export { session_exports as n, MemoryStore as r, Session as t };
449
482
 
450
- //# sourceMappingURL=session-CACkHyDR.mjs.map
483
+ //# sourceMappingURL=session-CUE48QWX.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-CUE48QWX.mjs","names":[],"sources":["../src/session/memory.ts","../src/session/session.ts"],"sourcesContent":["import type { SessionStore } from \"./store.ts\"\nimport type { SessionNode } from \"./types.ts\"\n\n/**\n * In-memory `SessionStore` — a `Map<uuid, SessionNode>` plus a `root`\n * pointer. No persistence. Construction takes optional initial nodes\n * for tests, replay tools, and the Claude session importer.\n */\nexport class MemoryStore implements SessionStore {\n readonly #nodes: Map<string, SessionNode>\n #root?: SessionNode\n\n constructor(nodes?: Iterable<SessionNode>) {\n this.#nodes = new Map()\n if (nodes) {\n for (const node of nodes) {\n this.#nodes.set(node.uuid, node)\n this.#root = node\n }\n }\n }\n\n get root(): SessionNode | undefined {\n return this.#root\n }\n\n async get(id: string): Promise<SessionNode | undefined> {\n return this.#nodes.get(id)\n }\n\n async write(node: SessionNode): Promise<void> {\n this.#nodes.set(node.uuid, node)\n this.#root = node\n }\n\n *all(): Iterable<SessionNode> {\n yield* this.#nodes.values()\n }\n}\n","import type { Message } from \"@zaly/ai\"\nimport type { SessionStore } from \"./store.ts\"\nimport type {\n MaskCheckpoint,\n PartialNode,\n SessionEvents,\n SessionInit,\n SessionMessage,\n SessionNode,\n SessionNodeView,\n SessionOptions,\n SessionSettings,\n SessionUpdate,\n SessionView,\n} from \"./types.ts\"\n\nimport { Emitter, normPath } from \"@zaly/shared\"\nimport { zalyPaths } from \"@zaly/shared/paths\"\nimport { isDeepStrictEqual } from \"node:util\"\nimport { join } from \"pathe\"\nimport { uuidv7 } from \"../utils/uuid.ts\"\nimport { JsonlStore } from \"./jsonl.ts\"\nimport { MemoryStore } from \"./memory.ts\"\n\nconst VERSION = 2\n\n/**\n * Conversation primitive. Owns a DAG of message + compaction + meta\n * nodes via a `SessionStore` backend; the *active* message list is\n * whatever you get by walking `parentUuid` backwards from the store's\n * root until you hit a `compact` node (or the start).\n *\n * **Meta is snapshot-based.** `session-meta` nodes carry the full\n * cumulative meta as of their commit time. Other node types (start,\n * resume, message, compact) don't carry meta — `Session` reconstructs\n * the cumulative meta at any point by finding the most recent\n * `session-meta` ancestor in a forward pass over the chain. Public\n * APIs return `SessionNodeView` (raw node + decorated `meta`).\n *\n * Designed so the loop, the persistor, the TUI, and any replay tool\n * all read from one source of truth and never mutate the DAG behind\n * each other's backs:\n *\n * - **Run loop** (`Agent`) calls `add()` on each new message and\n * `compact()` on overflow.\n * - **TUI** subscribes to the `node` event for streaming render.\n * - **Persistor** is the `SessionStore` — `MemoryStore` for ephemeral\n * sessions, `JsonlStore` for file-backed.\n *\n * Construction:\n * - Use `await Session.load(opts)` for the recommended path — picks\n * the right store (Memory if no path, JSONL if path).\n * - For tests / direct embedding, `new Session({ store })` works with\n * any pre-built store.\n */\nexport class Session<T extends SessionStore = SessionStore> extends Emitter<SessionEvents> {\n readonly #store: T\n #opts: SessionInit<T>\n #id: string\n #dir: string\n #settings: SessionSettings = {}\n #view: SessionView = { messages: [], nodes: new Map() }\n #closed = false\n #started = false\n #path?: string\n #head?: string\n #mutations?: Promise<void>\n\n protected constructor(opts: SessionInit<T>) {\n super()\n this.#opts = opts\n this.#path = opts.path\n this.#store = opts.store\n this.#id = opts.defaults?.sessionId ?? uuidv7()\n this.#dir = normPath(opts.dir ?? join(zalyPaths.env.tmp, \"sessions\", this.#id))\n }\n\n /** Recommended one-step path: pick the right store backend, hydrate\n * if applicable, return a ready-to-use session.\n *\n * - `path` provided → `JsonlStore` (file-backed, hydrates from disk\n * if the file exists, opens for append either way).\n * - No `path` → `MemoryStore` (ephemeral, no persistence). */\n static async load<T extends SessionStore = SessionStore>(\n opts: SessionOptions<T> & { store: T }\n ): Promise<Session<T>>\n static async load(opts: SessionOptions & { path: string }): Promise<Session<JsonlStore>>\n static async load(opts?: SessionOptions & {}): Promise<Session<MemoryStore>>\n static async load(opts: SessionOptions = {}): Promise<Session> {\n const session = await Session.create(opts)\n await session.#rebuild()\n return session\n }\n\n private static async create(opts: SessionOptions = {}): Promise<Session> {\n const path = opts.path ? normPath(opts.path) : undefined\n const store: SessionStore =\n opts.store ?? (path ? await JsonlStore.load(path) : new MemoryStore())\n const init: SessionInit = { ...opts, path, store }\n return new Session(init)\n }\n\n /** Efficiently fetch the most recent user message by walking backward until we hit\n * a user message, without reconstructing the full chain. Useful for a session picker. */\n static async lastMessage(opts: SessionOptions = {}): Promise<Message<\"user\"> | undefined> {\n const session = await Session.create(opts)\n let ret: Message<\"user\"> | undefined\n await session.#chain({\n stop: (node) => {\n if (node.type === \"message\" && node.message.role === \"user\") {\n ret = node.message\n return true\n }\n return false\n },\n })\n void session.close()\n return ret\n }\n\n async #rebuild(): Promise<void> {\n const chain = await this.#chain()\n this.#view = chain\n this.#settings = chain.settings\n this.#id = chain.settings.sessionId ?? this.#id\n }\n\n // ── Read ──────────────────────────────────────────────────────────────\n\n /** Active conversation — chain from current head back to the most\n * recent compact (exclusive), in chronological order. This is what\n * the agent sees on the next request. */\n get messages(): readonly Message[] {\n return this.#view.messages\n }\n\n get maskCheckpoint(): MaskCheckpoint | undefined {\n return this.#view.maskCheckpoint\n }\n\n get id(): string {\n return this.#id\n }\n\n get dir(): string {\n return this.#dir\n }\n\n get path(): string | undefined {\n return this.#path\n }\n\n get started(): boolean {\n return this.#started\n }\n\n /** Current session settings, merged with defaults. */\n get settings(): SessionSettings {\n return { ...this.#opts.defaults, ...this.#settings }\n }\n\n async update(settings: SessionUpdate, opts?: { force?: boolean }): Promise<string> {\n return this.#mutate(() => this.#commit({ settings, type: \"session-settings\" }, opts))\n }\n\n /** Lazily emits `session-start` on a fresh session or `session-resume`\n * on a hydrated one. Called from `#commit` before the first non-marker\n * node lands so the start/resume marker always heads the chain. */\n async #autostart(): Promise<void> {\n if (!this.#started) await this.#start()\n }\n\n /** Explicitly mark the session as started — writes a `session-start`\n * marker on a fresh session, `session-resume` on a hydrated one.\n * Idempotent; subsequent calls are no-ops. Optional `meta` is\n * applied via `update()` after the marker lands. */\n async start(settings?: SessionUpdate): Promise<string | undefined> {\n return this.#mutate(() => this.#start(settings))\n }\n\n async #start(settings?: SessionUpdate): Promise<string | undefined> {\n if (this.#started)\n return settings\n ? this.#commit({ settings, type: \"session-settings\" })\n : this.#store.root?.uuid\n this.#started = true\n const type = this.messages.length > 0 ? (\"session-resume\" as const) : (\"session-start\" as const)\n await this.#commit({ type })\n void this.emit(type)\n await this.#commit({ settings: settings ?? {}, type: \"session-settings\" })\n return this.#store.root?.uuid\n }\n\n /** Look up the decorated view for a node id — raw node plus the\n * cumulative meta as of that node's position. Returns the\n * message-typed view, or `undefined` if the id doesn't refer to a\n * message in this session. */\n async node(id?: string | Message): Promise<(SessionNodeView & { type: \"message\" }) | undefined> {\n const m = typeof id === \"string\" ? { id } : id\n if (!m?.id) return undefined\n const ret = this.#view.nodes.get(m.id)\n return ret?.type === \"message\" ? ret : undefined\n }\n\n /** Current head uuid — the root of the store, which is the most\n * recently appended node. */\n get head(): string | undefined {\n return this.#head ?? this.#store.root?.uuid\n }\n\n /** Full DAG iterator — backed by `store.all()`. Yields raw nodes\n * (no meta decoration). */\n nodes(): Iterable<SessionNode> | AsyncIterable<SessionNode> {\n return this.#store.all?.() ?? []\n }\n\n get root(): SessionNode | undefined {\n return this.#store.root\n }\n\n // ── Mutate ────────────────────────────────────────────────────────────\n\n /** Append a message. The new node is parented to the current head,\n * head advances, and a `node` event fires. Optional `meta` carries\n * usage / model / finish info — populate it for assistant turns\n * the agent commits after a step. Returns the assigned uuid.\n *\n * If `message.id` / `message.ts` are set (e.g. round-tripped from a\n * prior load), they're used as the node's uuid / timestamp; otherwise\n * fresh values are generated. The committed message always carries\n * both — `m.id === node.uuid` and `m.ts === node.ts`. */\n async add(message: Message): Promise<string> {\n const uuid = message.id ?? uuidv7()\n const ts = message.ts ?? Date.now()\n const m = { ...message, id: uuid, ts }\n return this.#mutate(() => this.#commit({ message: m, type: \"message\" }))\n }\n\n /** Summarize an active prefix through a message ID, preserving everything\n * appended after it. Boundary validation and tail calculation share the\n * serialized commit with the new summary. Legacy tail-only calls remain\n * supported. Original history stays in the store; a fresh settings anchor\n * follows the compact node for reconstruction. */\n async compact(opts: {\n trigger?: \"manual\" | \"auto\"\n preTokens?: number\n durationMs?: number\n /** Cancel a queued compaction before its commit begins. */\n signal?: AbortSignal\n /** Prefer an explicit boundary; tail-only calls remain supported. */\n to?: string\n /** Expected first message of the snapshot, including a prior summary if present. */\n from?: string\n tail?: number\n summary: Message<\"system\">\n }): Promise<string> {\n return this.#mutate(async () => {\n opts.signal?.throwIfAborted()\n let tail = opts.tail\n if (opts.to !== undefined) {\n const index = this.messages.findIndex((m) => m.id === opts.to)\n if (index === -1 || (opts.from !== undefined && this.messages[0]?.id !== opts.from)) {\n throw new Error(\"Compaction snapshot is no longer part of the active history\")\n }\n tail = this.messages.length - index - 1\n }\n if (tail === undefined || !Number.isInteger(tail) || tail < 0) {\n throw new Error(\"Compaction requires a message boundary or a non-negative integer tail\")\n }\n const compactUuid = await this.#commit({\n durationMs: opts.durationMs,\n from: opts.from,\n preTokens: opts.preTokens,\n summary: opts.summary,\n tail,\n to: opts.to,\n trigger: opts.trigger ?? \"manual\",\n type: \"compact\",\n })\n await this.#commit({ settings: {}, type: \"session-settings\" }, { force: true })\n await this.#rebuild()\n const node = this.#view.compact!\n void this.emit(\"compact\", { node })\n return compactUuid\n })\n }\n\n async addMaskCheckpoint(opts: MaskCheckpoint): Promise<string> {\n return this.#mutate(async () => {\n this.#view.maskCheckpoint = opts\n return this.#commit({ ...opts, type: \"mask-checkpoint\" })\n })\n }\n\n async checkout(uuid: string): Promise<void> {\n return this.#mutate(async () => {\n if (this.#closed) throw new Error(\"Session is closed\")\n this.#head = uuid\n await this.#rebuild()\n })\n }\n\n /** Pre-active history of the current chain — messages from before\n * the most recent compact (and earlier compacts), in chronological\n * order. Useful for TUI scrollback that wants to render context the\n * agent itself no longer sees.\n *\n * `limit` truncates from the front (oldest), so the most recent\n * history messages always make it through. */\n async history(limit?: number): Promise<readonly Message[]> {\n const chain = await this.#chain({ active: false, limit })\n return chain.messages\n }\n\n /** Flush + close the underlying store. Subsequent writes throw. */\n async close(): Promise<void> {\n return this.#mutate(async () => {\n if (this.#closed) return\n this.#closed = true\n await this.#store.close?.()\n })\n }\n\n // ── Internals ────────────────────────────────────────────────────────\n\n // Keep commits and view rebuilds together so appends cannot race a compaction.\n #mutate<R>(fn: () => Promise<R>): Promise<R> {\n const pending = this.#mutations ? this.#mutations.then(fn) : fn()\n const settled = pending.then(\n () => {},\n () => {}\n )\n this.#mutations = settled\n void settled.then(() => {\n if (this.#mutations === settled) this.#mutations = undefined\n })\n return pending\n }\n\n /** Atomically commit a node: register it in the store, update active\n * messages, persist, and emit. Single chokepoint for all mutations. */\n async #commit(n: PartialNode, opts: { force?: boolean } = {}): Promise<string> {\n let node: SessionNode = {\n ...n,\n parentUuid: this.head,\n ts: n.type === \"message\" ? (n.message.ts ?? Date.now()) : Date.now(),\n uuid: n.type === \"message\" ? (n.message.id ?? uuidv7()) : uuidv7(),\n }\n\n if (!this.#started && node.type !== \"session-start\" && node.type !== \"session-resume\") {\n await this.#autostart()\n }\n if (this.#closed) throw new Error(\"Session is closed\")\n\n const next: SessionSettings = {\n ...this.#opts.defaults,\n ...this.#settings,\n ...(node.type === \"session-settings\" ? node.settings : {}),\n sessionId: this.#id,\n version: VERSION,\n }\n if (next.cwd) next.cwd = normPath(next.cwd)\n if (next.workspace) next.workspace = normPath(next.workspace)\n\n if (node.type === \"session-settings\") {\n if (!opts.force && isDeepStrictEqual(this.#settings, next)) return this.#store.root!.uuid\n node = { ...node, settings: next }\n }\n\n node = { ...node, parentUuid: this.head }\n await this.#store.write(node)\n this.#head = undefined // invalidate head cache so it reflects the store's root on next read\n\n // Decorate the new node with cumulative meta and append to the\n // active chain view\n this.#view.nodes.set(node.uuid, { ...node, settings: next })\n if (node.type === \"message\") this.#view.messages.push(node.message)\n\n // cwd / meta event signaling\n if (node.type === \"session-settings\") {\n const prev = this.#settings\n this.#settings = next\n this.#emitChanges(prev)\n }\n\n void this.emit(\"node\", { node })\n return node.uuid\n }\n\n #emitChanges(prev: SessionSettings): void {\n const next = this.#settings\n if (next.cwd && next.cwd !== prev.cwd) void this.emit(\"cwd\", { cwd: next.cwd, prev: prev.cwd })\n if (next.modelId && next.modelId !== prev.modelId)\n void this.emit(\"model\", { model: next.modelId, prev: prev.modelId })\n if (next.reasoning && next.reasoning !== prev.reasoning)\n void this.emit(\"reasoning\", { effort: next.reasoning, prev: prev.reasoning })\n }\n\n /** Walk `parentUuid` from the given node back toward the root,\n * returning the chain as decorated views (each with cumulative meta).\n * The `active` flag controls what counts:\n * - `true` — only the active chain (stops at first compact /\n * session-start, with the kept tail spliced in via\n * the compact's `tail` field, summary substituted\n * in place of the compact node).\n * - `false` — includes everything back to the root\n * Returns chronological order. */\n async #chain(\n opts: {\n active?: boolean\n limit?: number\n uuid?: string\n stop?: (node: SessionNode) => boolean\n } = {}\n ): Promise<SessionView & { settings: SessionSettings }> {\n // Backward pass: collect raw nodes (new to old)\n const reverse: SessionNode[] = []\n let cursor = opts.uuid ?? this.head\n let limit = opts.limit ?? Infinity\n let compact: SessionNode<\"compact\"> | undefined\n const messageNodes: SessionNode<\"message\">[] = []\n let maskCheckpoint: SessionNode<\"mask-checkpoint\"> | undefined\n\n // Walk backward from the head until we hit a compact or the start, collecting nodes.\n while (cursor) {\n // eslint-disable-next-line no-await-in-loop\n const node = await this.#store.get(cursor)\n if (!node || (node.type === \"message\" && messageNodes.length + 1 > limit)) break\n cursor = node.parentUuid\n reverse.push(node)\n // Keep track if the last mask-checkpoint, until we hit a compaction.\n if (node.type === \"mask-checkpoint\" && !compact && !maskCheckpoint) maskCheckpoint = node\n if (node.type === \"message\") messageNodes.push(node)\n if (node.type === \"compact\" && (opts.active ?? true)) {\n compact ??= node\n // Earlier compactions may contain part of the kept tail. Walk through\n // their preserved messages, but never resurrect their summarized history.\n limit = Math.min(limit, messageNodes.length + node.tail)\n }\n if (opts.stop?.(node)) break\n }\n\n // Forward pass: decorate with cumulative meta. session-meta nodes\n // redefine the meta; everything else inherits the running snapshot.\n const nodes = new Map<string, SessionNodeView>()\n let settings: SessionSettings = {}\n for (const n of reverse.toReversed()) {\n if (n.type === \"session-settings\") settings = n.settings\n nodes.set(n.uuid, { ...n, settings })\n }\n\n this.#migrate(nodes)\n\n const messages: SessionMessage[] = []\n for (const n of messageNodes) {\n // add `id`, `ts` and `modelId` (if assistant turn) to the message\n const m = { ...n.message, id: n.uuid, ts: n.ts }\n if (m.role === \"assistant\") {\n // Add missing modelId to assistant messages if not present\n const s = nodes.get(n.uuid)?.settings ?? {}\n m.meta = { ...m.meta, modelId: m.meta?.modelId ?? s.modelId }\n }\n n.message = m\n messages.push(m)\n }\n\n // Add compaction summary as the first message\n if (compact) {\n messages.push({ ...compact.summary, id: compact.uuid, ts: compact.ts })\n nodes.set(compact.uuid, {\n message: compact.summary,\n parentUuid: compact.parentUuid,\n settings: nodes.get(compact.uuid)?.settings ?? {},\n ts: compact.ts,\n type: \"message\",\n uuid: compact.uuid,\n })\n }\n\n return {\n compact,\n maskCheckpoint,\n messages: messages.toReversed(),\n nodes,\n settings,\n }\n }\n\n #migrate(nodes: Map<string, SessionNodeView>) {\n for (const n of nodes.values()) {\n const version = n.settings.version ?? 0\n if (version === VERSION) continue\n n.settings = { ...n.settings, version: VERSION }\n\n if (n.type === \"compact\") {\n n.summary.meta = { kind: \"compaction-summary\", ...n.summary.meta }\n continue\n }\n\n if (n.type !== \"message\") continue\n const m = n.message\n\n if (\n m.role === \"system\" &&\n Array.isArray(m.content) &&\n m.content[0].type === \"meta\" &&\n m.content[0].tag === \"task\"\n ) {\n // Missing task meta data kind\n m.meta = { kind: \"task\", ...m.meta }\n }\n\n n.message = m\n }\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import { Emitter } from "@zaly/shared";
2
2
  import { Message, ReasoningEffort } from "@zaly/ai";
3
- //#region src/session/types.d.ts
4
3
  /** A single node in the session DAG. Same shape on disk (JSONL) as in
5
4
  * memory — what we persist *is* what we navigate. Session settings live ONLY on
6
5
  * `session-settings` nodes as a full snapshot of the cumulative session
@@ -36,7 +35,11 @@ type SessionN = {
36
35
  preTokens?: number;
37
36
  /** How long the compactor took, ms. */
38
37
  durationMs?: number;
39
- /** Number of message from before compaction that will be preserved */
38
+ /** Last active message covered by the summary. Absent on legacy entries. */
39
+ to?: string;
40
+ /** First active message in the summarized snapshot, used to reject stale summaries. */
41
+ from?: string;
42
+ /** Number of messages after the summary boundary at commit time. */
40
43
  tail: number;
41
44
  /** Frozen summary message that becomes the head of the active
42
45
  * chain reconstruction. The full Message (not just text) so the
@@ -128,8 +131,6 @@ type SessionInit<T extends SessionStore = SessionStore> = SessionOptions & {
128
131
  * store based on options; direct construction passes one explicitly. */
129
132
  store: T;
130
133
  };
131
- //#endregion
132
- //#region src/session/store.d.ts
133
134
  /**
134
135
  * Storage backend for a `Session`'s DAG.
135
136
  *
@@ -170,8 +171,6 @@ interface SessionStore {
170
171
  * override with a more efficient bulk-scan implementation. */
171
172
  all?: () => Iterable<SessionNode> | AsyncIterable<SessionNode>;
172
173
  }
173
- //#endregion
174
- //#region src/session/jsonl.d.ts
175
174
  /**
176
175
  * JSONL-backed `SessionStore` — append-only file, one record per line.
177
176
  *
@@ -206,8 +205,6 @@ declare class JsonlReader<T> {
206
205
  next(): Promise<T | undefined>;
207
206
  close(): Promise<void>;
208
207
  }
209
- //#endregion
210
- //#region src/session/memory.d.ts
211
208
  /**
212
209
  * In-memory `SessionStore` — a `Map<uuid, SessionNode>` plus a `root`
213
210
  * pointer. No persistence. Construction takes optional initial nodes
@@ -221,8 +218,6 @@ declare class MemoryStore implements SessionStore {
221
218
  write(node: SessionNode): Promise<void>;
222
219
  all(): Iterable<SessionNode>;
223
220
  }
224
- //#endregion
225
- //#region src/session/session.d.ts
226
221
  /**
227
222
  * Conversation primitive. Owns a DAG of message + compaction + meta
228
223
  * nodes via a `SessionStore` backend; the *active* message list is
@@ -315,17 +310,22 @@ declare class Session<T extends SessionStore = SessionStore> extends Emitter<Ses
315
310
  * fresh values are generated. The committed message always carries
316
311
  * both — `m.id === node.uuid` and `m.ts === node.ts`. */
317
312
  add(message: Message): Promise<string>;
318
- /** Mark a compaction boundary. Subsequent `add()` calls land after
319
- * this node; their messages form the new active conversation. The
320
- * pre-compact chain stays in the store but is no longer part of
321
- * `messages`. Also commits a fresh `session-meta` snapshot right
322
- * after the compact so post-compact lazy walks always have a nearby
323
- * meta anchor. */
313
+ /** Summarize an active prefix through a message ID, preserving everything
314
+ * appended after it. Boundary validation and tail calculation share the
315
+ * serialized commit with the new summary. Legacy tail-only calls remain
316
+ * supported. Original history stays in the store; a fresh settings anchor
317
+ * follows the compact node for reconstruction. */
324
318
  compact(opts: {
325
319
  trigger?: "manual" | "auto";
326
320
  preTokens?: number;
327
321
  durationMs?: number;
328
- tail: number;
322
+ /** Cancel a queued compaction before its commit begins. */
323
+ signal?: AbortSignal;
324
+ /** Prefer an explicit boundary; tail-only calls remain supported. */
325
+ to?: string;
326
+ /** Expected first message of the snapshot, including a prior summary if present. */
327
+ from?: string;
328
+ tail?: number;
329
329
  summary: Message<"system">;
330
330
  }): Promise<string>;
331
331
  addMaskCheckpoint(opts: MaskCheckpoint): Promise<string>;
@@ -341,6 +341,5 @@ declare class Session<T extends SessionStore = SessionStore> extends Emitter<Ses
341
341
  /** Flush + close the underlying store. Subsequent writes throw. */
342
342
  close(): Promise<void>;
343
343
  }
344
- //#endregion
345
344
  export { SessionStore as a, SessionEvents as c, SessionNode as d, SessionNodeView as f, SessionView as g, SessionUpdate as h, JsonlStore as i, SessionInit as l, SessionSettings as m, MemoryStore as n, MaskCheckpoint as o, SessionOptions as p, JsonlReader as r, PartialNode as s, Session as t, SessionMessage as u };
346
- //# sourceMappingURL=session-Ds5nJz5A.d.mts.map
345
+ //# sourceMappingURL=session-DY9mF9Vb.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-DY9mF9Vb.d.mts","names":[],"sources":["../src/session/types.ts","../src/session/store.ts","../src/session/jsonl.ts","../src/session/memory.ts","../src/session/session.ts"],"mappings":";;;;;;;;;KAYK;EACH;;EAEA;;EAEA;;EAEI;;EACA;;EACA;EAA0B,UAAU;;EACpC;EAAiB,SAAS;;EAC1B;EAAyB;EAAmB;;EAE5C;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;;;;EAKA,SAAS;;KAGV,kBAAkB;KAEX;EAAmB;EAAmB;;KAEtC,iBAAiB;EAAY;EAAY;;KAEzC,YAAY,UAAU,kBAAkB,mBAAmB,QACrE;EACE,MAAM;;;;;KAME,kBAAkB;EAAgB,UAAU;;KAE5C;EACV,UAAU;EACV,OAAO,YAAY;EACnB,UAAU;EACV,iBAAiB;;KAGP;EACV;EACA;EACA;EACA;EACA;EACA,YAAY;;KAGF,gBAAgB,KAAK;KAE5B,iBAAiB,GAAG,UAAU,eAAe,oBAAoB,KAAK,GAAG;KAElE,cAAc,iBAAiB;;;KAM/B;EACV;IAAQ,MAAM;;EACd;IAAY;IAA0B,mBAAmB;;EACzD;IAAW,MAAM;;EAEjB;IAAO;IAAa;;EACpB;IAAS;IAAe;;EACxB;IAAa,QAAQ;IAAiB,OAAO;;EAE7C;EACA;;KAKU,eAAe,UAAU,eAAe;EAClD,QAAQ;;;;;EAKR;;;;;EAKA;;;EAGA,WAAW,KAAK;;KAGN,YAAY,UAAU,eAAe,gBAAgB;;;EAG/D,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;UCjGQ;;;WAGN,MAAM;;EAGf,MAAM,eAAe,QAAQ;;;;EAK7B,QAAQ,MAAM,gBAAgB;;EAG9B,cAAc;;;;EAKd,YAAY,SAAS,eAAe,cAAc;;;;;;;;;;;;;;cCvBvC,sBAAsB;;WACxB;EAKT,YAAY;;;;SAQC,KAAK,eAAe,QAAQ;MAmBrC,QAAQ;EAIN,IAAI,aAAa,QAAQ;EAIzB,MAAM,MAAM,cAAc;EAS1B,SAAS;EAIR,OAAO,cAAc;;cAMjB,YAAY;;WAMF;EAArB,YAAqB;UAsBN;EAgCT,QAAQ,QAAQ;EAMhB,SAAK;;;;;;;cC3IA,uBAAuB;;EAIlC,YAAY,QAAQ,SAAS;MAUzB,QAAQ;EAIN,IAAI,aAAa,QAAQ;EAIzB,MAAM,MAAM,cAAc;EAK/B,OAAO,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cCoBN,QAAQ,UAAU,eAAe,sBAAsB,QAAQ;;YAajE,YAAa,MAAM,YAAY;;;;;;;SAe3B,KAAK,UAAU,eAAe,cACzC,MAAM,eAAe;IAAO,OAAO;MAClC,QAAQ,QAAQ;SACN,KAAK,MAAM;IAAmB;MAAiB,QAAQ,QAAQ;SAC/D,KAAK,OAAO,sBAAsB,QAAQ,QAAQ;iBAO1C;;;SAUR,YAAY,OAAM,iBAAsB,QAAQ;;;;MA4BzD,qBAAqB;MAIrB,kBAAkB;MAIlB;MAIA;MAIA;MAIA;;MAKA,YAAY;EAIV,OAAO,UAAU,eAAe;IAAS;MAAoB;;;;;EAe7D,MAAM,WAAW,gBAAgB;;;;;EAqBjC,KAAK,cAAc,UAAU,SAAS;IAAoB;;;;MAS5D;;;EAMJ,SAAS,SAAS,eAAe,cAAc;MAI3C,QAAQ;;;;;;;;;;EAeN,IAAI,SAAS,UAAU;;;;;;EAYvB,QAAQ;IACZ;IACA;IACA;;IAEA,SAAS;;IAET;;IAEA;IACA;IACA,SAAS;MACP;EAgCE,kBAAkB,MAAM,iBAAiB;EAOzC,SAAS,eAAe;;;;;;;;EAexB,QAAQ,iBAAiB,iBAAiB;;EAM1C,SAAS"}
@@ -1,6 +1,5 @@
1
- import { a as SessionStore, c as SessionEvents, d as SessionNode, f as SessionNodeView, g as SessionView, h as SessionUpdate, i as JsonlStore, l as SessionInit, m as SessionSettings, n as MemoryStore, o as MaskCheckpoint, p as SessionOptions, r as JsonlReader, s as PartialNode, t as Session, u as SessionMessage } from "./session-Ds5nJz5A.mjs";
1
+ import { a as SessionStore, c as SessionEvents, d as SessionNode, f as SessionNodeView, g as SessionView, h as SessionUpdate, i as JsonlStore, l as SessionInit, m as SessionSettings, n as MemoryStore, o as MaskCheckpoint, p as SessionOptions, r as JsonlReader, s as PartialNode, t as Session, u as SessionMessage } from "./session-DY9mF9Vb.mjs";
2
2
  import { Stats } from "node:fs";
3
- //#region src/session/manager.d.ts
4
3
  export type SessionInfo = {
5
4
  /** uuidv7 session id. Absent for non-managed external paths until the
6
5
  * session is loaded — the file's session-start node carries the
@@ -32,6 +31,5 @@ export declare function listSessions(opts?: SessionListOpts): Promise<SessionInf
32
31
  export declare function resumeSession(filter: string | SessionFilter): Promise<Session | undefined>;
33
32
  export declare function loadSession(opts?: Partial<SessionInfo>): Promise<Session>;
34
33
  export declare function sessionInfo(opts?: Partial<SessionInfo>): SessionInfo;
35
- //#endregion
36
34
  export { JsonlReader, JsonlStore, type MaskCheckpoint, MemoryStore, type PartialNode, Session, type SessionEvents, type SessionInit, type SessionMessage, type SessionNode, type SessionNodeView, type SessionOptions, type SessionSettings, type SessionStore, type SessionUpdate, type SessionView };
37
35
  //# sourceMappingURL=session.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.mts","names":[],"sources":["../src/session/manager.ts"],"mappings":";;;YAUY;;;;EAIV;;EAEA;;EAEA;;EAEA;;EAEA;EACA,OAAO;;YAGG;;EAEV;;EAEA;;EAEA;;YAGU;EACV,kBAAkB;EAClB;;wBAcoB,aAAa,OAAM,kBAAoB,QAAA;wBAyCvC,cAAc,iBAAiB,gBAAgB,QAAQ;wBAKvD,YAAY,OAAM,QAAQ,eAAoB,QAAQ;wBAc5D,YAAY,OAAM,QAAQ,eAAoB"}
1
+ {"version":3,"file":"session.d.mts","names":[],"sources":["../src/session/manager.ts"],"mappings":";;YAUY;;;;EAIV;;EAEA;;EAEA;;EAEA;;EAEA;EACA,OAAO;;YAGG;;EAEV;;EAEA;;EAEA;;YAGU;EACV,kBAAkB;EAClB;;wBAcoB,aAAa,OAAM,kBAAoB,QAAA;wBAyCvC,cAAc,iBAAiB,gBAAgB,QAAQ;wBAKvD,YAAY,OAAM,QAAQ,eAAoB,QAAQ;wBAc5D,YAAY,OAAM,QAAQ,eAAoB"}
package/dist/session.mjs CHANGED
@@ -1,12 +1,12 @@
1
- import { n as isUuidv7Like, r as uuidv7 } from "./uuid-CAdJg4l8.mjs";
2
- import { n as JsonlStore, t as JsonlReader } from "./jsonl-CvgEOakL.mjs";
3
- import { r as MemoryStore, t as Session } from "./session-CACkHyDR.mjs";
1
+ import { n as isUuidv7Like, r as uuidv7 } from "./uuid-rfbQ9ad2.mjs";
2
+ import { n as JsonlStore, t as JsonlReader } from "./jsonl-BGt7eqPK.mjs";
3
+ import { r as MemoryStore, t as Session } from "./session-CUE48QWX.mjs";
4
4
  import { decodePath, encodePath, normPath, safeStatAsync } from "@zaly/shared";
5
5
  import { basename, dirname, join, relative } from "pathe";
6
6
  import { glob } from "@zaly/shared/glob";
7
7
  import { mkdir, stat } from "node:fs/promises";
8
8
  import { zalyPaths } from "@zaly/shared/paths";
9
- //#region src/session/manager.ts
9
+ // src/session/manager.ts
10
10
  async function toFilter(filter) {
11
11
  if (isUuidv7Like(filter)) return { id: filter };
12
12
  if ((await safeStatAsync(filter))?.isDirectory()) return { workspace: filter };
@@ -100,7 +100,6 @@ function sessionInfo(opts = {}) {
100
100
  workspace
101
101
  };
102
102
  }
103
- //#endregion
104
103
  export { JsonlReader, JsonlStore, MemoryStore, Session, listSessions, loadSession, resumeSession, sessionInfo };
105
104
 
106
105
  //# sourceMappingURL=session.mjs.map
@@ -1,6 +1,6 @@
1
- import { n as __exportAll } from "./rolldown-runtime-DktXgydw.mjs";
2
- import { n as parseBash, t as TOOLS } from "./tools-CJ2x45EZ.mjs";
3
- import "./registry-Zo0QmKdR.mjs";
1
+ import { n as __exportAll } from "./rolldown-runtime-DYf_mQCB.mjs";
2
+ import { n as parseBash, t as TOOLS } from "./tools-DmoUYORG.mjs";
3
+ import "./registry-CntkeXlo.mjs";
4
4
  import { Emitter, formatDuration, isInstance, normPath, prettyPath, safeReadFile, safeStatAsync, safeStringify, toError } from "@zaly/shared";
5
5
  import { LazyCache } from "@zaly/shared/cache";
6
6
  import { BaseCollection } from "@zaly/shared/collection";
@@ -11,7 +11,7 @@ import { glob } from "@zaly/shared/glob";
11
11
  import { readFile } from "node:fs/promises";
12
12
  import { isDeepStrictEqual } from "node:util";
13
13
  import { Type } from "typebox";
14
- //#region src/ctx.ts
14
+ // src/ctx.ts
15
15
  var ctx_exports = /* @__PURE__ */ __exportAll({
16
16
  AgentContext: () => AgentContext,
17
17
  createAgent: () => createAgent,
@@ -161,7 +161,7 @@ var AgentContext = class extends Emitter {
161
161
  }
162
162
  async swarm() {
163
163
  return this.#cache.need("swarm", async () => {
164
- const { Swarm } = await import("./swarm-BJ3gQA1Z.mjs");
164
+ const { Swarm } = await import("./swarm-B_s9Qpbt.mjs");
165
165
  return new Swarm();
166
166
  }, this.#opts.swarm);
167
167
  }
@@ -175,19 +175,19 @@ var AgentContext = class extends Emitter {
175
175
  }
176
176
  async notifier() {
177
177
  return this.#cache.want("notifier", async (opts) => {
178
- const { Notifier } = await import("./notify-DpG_m9iP.mjs");
178
+ const { Notifier } = await import("./notify-Ds0-4BeI.mjs");
179
179
  return new Notifier(opts);
180
180
  }, this.#opts.notify);
181
181
  }
182
182
  async masker() {
183
183
  return this.#cache.want("masker", async (opts) => {
184
- const { Masker } = await import("./masker-jgSUXzjY.mjs");
184
+ const { Masker } = await import("./masker-B97uwYXG.mjs");
185
185
  return new Masker(this.agent, opts);
186
186
  }, this.#opts.mask);
187
187
  }
188
188
  async permissions() {
189
189
  return this.#cache.need("permissions", async (opts) => {
190
- const { PermissionManager } = await import("./manager-BJLjayBz.mjs");
190
+ const { PermissionManager } = await import("./manager-1zEE5WiA.mjs");
191
191
  return new PermissionManager({
192
192
  ...opts,
193
193
  cwd: this.cwd
@@ -198,7 +198,7 @@ var AgentContext = class extends Emitter {
198
198
  async function loadSession(spec) {
199
199
  if (isInstance(spec)) return spec;
200
200
  else {
201
- const { Session } = await import("./session-CACkHyDR.mjs").then((n) => n.n);
201
+ const { Session } = await import("./session-CUE48QWX.mjs").then((n) => n.n);
202
202
  return await Session.load({ ...spec });
203
203
  }
204
204
  }
@@ -210,15 +210,15 @@ async function createAgentContext(opts) {
210
210
  });
211
211
  }
212
212
  async function createAgent(opts) {
213
- const [{ Agent }, ctx] = await Promise.all([import("./agent-D5NrjvG5.mjs"), createAgentContext(opts)]);
213
+ const [{ Agent }, ctx] = await Promise.all([import("./agent-DlhEEMPU.mjs"), createAgentContext(opts)]);
214
214
  return new Agent(ctx);
215
215
  }
216
216
  const promptRegistry = createRegistry("prompt").from({
217
- "AGENTS.md": (ctx) => import("./markdown-Bv4J8cg3.mjs").then((m) => m.agentsMdPrompt(ctx)),
218
- "MEMORY.md": (ctx) => import("./markdown-Bv4J8cg3.mjs").then((m) => m.memoryMdPrompt(ctx)),
219
- agent: () => import("./agent-B7cQOuMZ.mjs").then((m) => m.agentPrompt),
220
- env: (ctx) => import("./env-UUFv5Mye.mjs").then((m) => m.prompt(ctx)),
221
- model: (ctx) => import("./model-_3ZA2xqm.mjs").then((m) => m.prompt(ctx))
217
+ "AGENTS.md": (ctx) => import("./markdown-8ICz5aFw.mjs").then((m) => m.agentsMdPrompt(ctx)),
218
+ "MEMORY.md": (ctx) => import("./markdown-8ICz5aFw.mjs").then((m) => m.memoryMdPrompt(ctx)),
219
+ agent: () => import("./agent-sHtwQDAk.mjs").then((m) => m.agentPrompt),
220
+ env: (ctx) => import("./env-C8p8i1E0.mjs").then((m) => m.prompt(ctx)),
221
+ model: (ctx) => import("./model-DqGqxfAc.mjs").then((m) => m.prompt(ctx))
222
222
  });
223
223
  var PromptCollection = class extends BaseCollection {
224
224
  list() {
@@ -255,21 +255,21 @@ async function promptCollection() {
255
255
  ]);
256
256
  }
257
257
  const toolRegistry = createRegistry("tool").from({
258
- agent_send: () => import("./swarm-BuFx_xeY.mjs").then((m) => m.agentSendTool),
259
- agent_spawn: () => import("./swarm-BuFx_xeY.mjs").then((m) => m.agentSpawnTool),
260
- bash: () => import("./bash-9x8PPg0A.mjs").then((m) => m.bashTool),
261
- edit: () => import("./edit-D4yaBK1K.mjs").then((m) => m.editTool),
262
- fetch: () => import("./fetch-D0IeDN6H.mjs").then((m) => m.fetchTool),
263
- find: () => import("./find-D1Z2ac_b.mjs").then((m) => m.findTool),
264
- grep: () => import("./grep-By4wLRDk.mjs").then((m) => m.grepTool),
265
- read: () => import("./read-B-hwcc2Q.mjs").then((m) => m.readTool),
266
- search: () => import("./search-CH0D5CkV.mjs").then((m) => m.searchTool),
267
- subagent: () => import("./subagent-BMQMbANL.mjs").then((m) => m.subagentTool),
268
- task_list: () => import("./tasks-BA-PCeGa.mjs").then((m) => m.taskListTool),
269
- task_poll: () => import("./tasks-BA-PCeGa.mjs").then((m) => m.taskPollTool),
270
- task_stop: () => import("./tasks-BA-PCeGa.mjs").then((m) => m.taskStopTool),
271
- wakeup: () => import("./wakeup-BYqTnfSp.mjs").then((m) => m.wakeupTool),
272
- write: () => import("./write-DwGiDNeG.mjs").then((m) => m.writeTool)
258
+ agent_send: () => import("./swarm-D823Yumk.mjs").then((m) => m.agentSendTool),
259
+ agent_spawn: () => import("./swarm-D823Yumk.mjs").then((m) => m.agentSpawnTool),
260
+ bash: () => import("./bash-DSy03sAj.mjs").then((m) => m.bashTool),
261
+ edit: () => import("./edit-DT672zIy.mjs").then((m) => m.editTool),
262
+ fetch: () => import("./fetch-BrtIqrid.mjs").then((m) => m.fetchTool),
263
+ find: () => import("./find-B-vvdlHu.mjs").then((m) => m.findTool),
264
+ grep: () => import("./grep-rvZ5S319.mjs").then((m) => m.grepTool),
265
+ read: () => import("./read-C5keKntU.mjs").then((m) => m.readTool),
266
+ search: () => import("./search-B-89W3SM.mjs").then((m) => m.searchTool),
267
+ subagent: () => import("./subagent-D-TYaX38.mjs").then((m) => m.subagentTool),
268
+ task_list: () => import("./tasks-Dgsiuh0Q.mjs").then((m) => m.taskListTool),
269
+ task_poll: () => import("./tasks-Dgsiuh0Q.mjs").then((m) => m.taskPollTool),
270
+ task_stop: () => import("./tasks-Dgsiuh0Q.mjs").then((m) => m.taskStopTool),
271
+ wakeup: () => import("./wakeup-CFr1nu_L.mjs").then((m) => m.wakeupTool),
272
+ write: () => import("./write-BRQFfWAn.mjs").then((m) => m.writeTool)
273
273
  });
274
274
  var ToolCollection = class extends BaseCollection {
275
275
  list() {
@@ -285,8 +285,7 @@ var ToolCollection = class extends BaseCollection {
285
285
  async function toolCollection() {
286
286
  return new ToolCollection([]);
287
287
  }
288
- //#endregion
289
- //#region src/commands.ts
288
+ // src/commands.ts
290
289
  const BASH_RE = /^!`(.*)`$/;
291
290
  var Commands = class {
292
291
  #opts;
@@ -429,8 +428,7 @@ async function exec(script, opts = {}) {
429
428
  md.push("");
430
429
  return md.join("\n");
431
430
  }
432
- //#endregion
433
- //#region src/skills.ts
431
+ // src/skills.ts
434
432
  var Skills = class Skills {
435
433
  catalog = /* @__PURE__ */ new Map();
436
434
  #tool;
@@ -586,8 +584,7 @@ async function listReferences(dir) {
586
584
  }
587
585
  return out.toSorted();
588
586
  }
589
- //#endregion
590
- //#region src/compaction/utils.ts
587
+ // src/compaction/utils.ts
591
588
  const LAMBDA = Math.LN2 / 60;
592
589
  const KIND_WEIGHTS = {
593
590
  edit: 2,
@@ -792,8 +789,7 @@ function formatFileUsage(files) {
792
789
  const text = lines.join("\n");
793
790
  return toXml(text, "files", { indent: false });
794
791
  }
795
- //#endregion
796
- //#region src/context/tokens.ts
792
+ // src/context/tokens.ts
797
793
  const CHARS_PER_TOKEN = 4;
798
794
  const ATTACHMENT_TOKENS = {
799
795
  audio: 3e3,
@@ -948,7 +944,6 @@ function formatTokenStats(s, indent = 0) {
948
944
  function fmt(n) {
949
945
  return n.toLocaleString("en-US").replace(/,/g, "_");
950
946
  }
951
- //#endregion
952
947
  export { ctx_exports as _, extractConversation as a, formatFileUsage as c, Commands as d, toolCollection as f, createAgent as g, promptRegistry as h, extractBashUsage as i, messageTail as l, promptCollection as m, formatTokenStats as n, extractFileUsage as o, toolRegistry as p, tokenStats as r, formatBashUsage as s, estimatePart as t, Skills as u };
953
948
 
954
- //# sourceMappingURL=src-DoXC_gDY.mjs.map
949
+ //# sourceMappingURL=src-DJoqT9yP.mjs.map