arborkit 1.0.0 → 1.1.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 (121) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +8 -0
  3. package/dist/addressing.js +4 -52
  4. package/dist/addressing.js.map +1 -1
  5. package/dist/ag-ui.js +6 -44
  6. package/dist/ag-ui.js.map +1 -1
  7. package/dist/arbor.js +25 -1537
  8. package/dist/arbor.js.map +1 -1
  9. package/dist/artifact-tree.js +5 -281
  10. package/dist/artifact-tree.js.map +1 -1
  11. package/dist/chunk-2UY5KJ5P.js +72 -0
  12. package/dist/chunk-2UY5KJ5P.js.map +1 -0
  13. package/dist/chunk-32FKMLEA.js +117 -0
  14. package/dist/chunk-32FKMLEA.js.map +1 -0
  15. package/dist/chunk-3BWK5SLN.js +22 -0
  16. package/dist/chunk-3BWK5SLN.js.map +1 -0
  17. package/dist/chunk-53XPRLFF.js +213 -0
  18. package/dist/chunk-53XPRLFF.js.map +1 -0
  19. package/dist/chunk-55J6XMHW.js +1 -0
  20. package/dist/chunk-55J6XMHW.js.map +1 -0
  21. package/dist/chunk-6DOI4FNX.js +18 -0
  22. package/dist/chunk-6DOI4FNX.js.map +1 -0
  23. package/dist/chunk-AGPH62II.js +78 -0
  24. package/dist/chunk-AGPH62II.js.map +1 -0
  25. package/dist/chunk-BYXJ5B5F.js +40 -0
  26. package/dist/chunk-BYXJ5B5F.js.map +1 -0
  27. package/dist/chunk-DQW5EEWU.js +20 -0
  28. package/dist/chunk-DQW5EEWU.js.map +1 -0
  29. package/dist/chunk-I4NLMLE2.js +43 -0
  30. package/dist/chunk-I4NLMLE2.js.map +1 -0
  31. package/dist/chunk-KRJCSJL4.js +208 -0
  32. package/dist/chunk-KRJCSJL4.js.map +1 -0
  33. package/dist/chunk-L4HFSLBD.js +112 -0
  34. package/dist/chunk-L4HFSLBD.js.map +1 -0
  35. package/dist/chunk-M72UOSPG.js +43 -0
  36. package/dist/chunk-M72UOSPG.js.map +1 -0
  37. package/dist/chunk-OZCCBVUV.js +50 -0
  38. package/dist/chunk-OZCCBVUV.js.map +1 -0
  39. package/dist/chunk-QRGDUGY6.js +143 -0
  40. package/dist/chunk-QRGDUGY6.js.map +1 -0
  41. package/dist/chunk-QWYVTW2C.js +70 -0
  42. package/dist/chunk-QWYVTW2C.js.map +1 -0
  43. package/dist/chunk-TEJZF3IR.js +24 -0
  44. package/dist/chunk-TEJZF3IR.js.map +1 -0
  45. package/dist/chunk-U3NXJNUY.js +23 -0
  46. package/dist/chunk-U3NXJNUY.js.map +1 -0
  47. package/dist/chunk-UTJZYWK3.js +272 -0
  48. package/dist/chunk-UTJZYWK3.js.map +1 -0
  49. package/dist/chunk-V3HDDWER.js +60 -0
  50. package/dist/chunk-V3HDDWER.js.map +1 -0
  51. package/dist/chunk-VG5BEOBI.js +34 -0
  52. package/dist/chunk-VG5BEOBI.js.map +1 -0
  53. package/dist/chunk-VGHBPFCV.js +18 -0
  54. package/dist/chunk-VGHBPFCV.js.map +1 -0
  55. package/dist/chunk-WEO5KBRI.js +148 -0
  56. package/dist/chunk-WEO5KBRI.js.map +1 -0
  57. package/dist/chunk-XT7WR7OF.js +23 -0
  58. package/dist/chunk-XT7WR7OF.js.map +1 -0
  59. package/dist/chunk-XWCA5XHZ.js +12 -0
  60. package/dist/chunk-XWCA5XHZ.js.map +1 -0
  61. package/dist/chunk-YCDDDYGG.js +22 -0
  62. package/dist/chunk-YCDDDYGG.js.map +1 -0
  63. package/dist/chunk-YWY2EK2Q.js +40 -0
  64. package/dist/chunk-YWY2EK2Q.js.map +1 -0
  65. package/dist/chunk-ZBBMJMLG.js +33 -0
  66. package/dist/chunk-ZBBMJMLG.js.map +1 -0
  67. package/dist/chunk-ZDANDXJ6.js +148 -0
  68. package/dist/chunk-ZDANDXJ6.js.map +1 -0
  69. package/dist/clock.js +4 -18
  70. package/dist/clock.js.map +1 -1
  71. package/dist/decompose.js +5 -16
  72. package/dist/decompose.js.map +1 -1
  73. package/dist/delta-storage.js +5 -101
  74. package/dist/delta-storage.js.map +1 -1
  75. package/dist/delta.js +15 -732
  76. package/dist/delta.js.map +1 -1
  77. package/dist/embedding-port.js +3 -17
  78. package/dist/embedding-port.js.map +1 -1
  79. package/dist/embedding-text.js +4 -16
  80. package/dist/embedding-text.js.map +1 -1
  81. package/dist/errors.js +8 -50
  82. package/dist/errors.js.map +1 -1
  83. package/dist/event-log.js +4 -78
  84. package/dist/event-log.js.map +1 -1
  85. package/dist/file-storage.js +3 -38
  86. package/dist/file-storage.js.map +1 -1
  87. package/dist/ids.js +4 -17
  88. package/dist/ids.js.map +1 -1
  89. package/dist/index.js +117 -1763
  90. package/dist/index.js.map +1 -1
  91. package/dist/json-edit.js +10 -75
  92. package/dist/json-edit.js.map +1 -1
  93. package/dist/jsonpointer.js +8 -24
  94. package/dist/jsonpointer.js.map +1 -1
  95. package/dist/mutator.js +5 -240
  96. package/dist/mutator.js.map +1 -1
  97. package/dist/navigator.js +7 -188
  98. package/dist/navigator.js.map +1 -1
  99. package/dist/path-glob.js +5 -35
  100. package/dist/path-glob.js.map +1 -1
  101. package/dist/registry-validator.js +3 -7
  102. package/dist/registry-validator.js.map +1 -1
  103. package/dist/replay.js +6 -179
  104. package/dist/replay.js.map +1 -1
  105. package/dist/semantic-index.js +5 -222
  106. package/dist/semantic-index.js.map +1 -1
  107. package/dist/storage.js +9 -372
  108. package/dist/storage.js.map +1 -1
  109. package/dist/toolset.d.ts +10 -0
  110. package/dist/toolset.js +8 -302
  111. package/dist/toolset.js.map +1 -1
  112. package/dist/type-aware-decision.js +3 -13
  113. package/dist/type-aware-decision.js.map +1 -1
  114. package/dist/type-registry.js +3 -13
  115. package/dist/type-registry.js.map +1 -1
  116. package/dist/types.js +1 -0
  117. package/dist/vector-index-port.js +3 -45
  118. package/dist/vector-index-port.js.map +1 -1
  119. package/dist/zod-adapter.js +4 -30
  120. package/dist/zod-adapter.js.map +1 -1
  121. package/package.json +128 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.0 — 2026-07-05
4
+
5
+ - **New patch op: `edit`** — exact-substring surgery on string-valued nodes:
6
+ `patch(ref, { op: "edit", old, new, replaceAll?, ifVersion? })`. `old` must occur
7
+ exactly once in the node's string value (or set `replaceAll`); on a miss or an
8
+ ambiguous match the op fails with a structured `INVALID_OP` that reports the
9
+ occurrence count, so an agent can re-quote a larger fragment and retry.
10
+ Replacement is literal (no `$&`-style pattern expansion). Scope and `ifVersion`
11
+ are enforced *before* any content inspection — out-of-scope probes get an
12
+ identical `SCOPE_VIOLATION` whether or not `old` matches, leaking nothing.
13
+ - Under the hood `edit` is pure sugar over `set`: the event log records an ordinary
14
+ `set` with full before/after, so replay, revert, delta persistence, and the AG-UI
15
+ adapter need no changes.
16
+ - Motivation: output tokens are ~5× input price on current Claude models. An agent
17
+ quoting `old`/`new` fragments (~100 output tokens) instead of regenerating a whole
18
+ block (~1500) is the dominant cost lever for agent-driven editing. Pattern: `get`
19
+ the node first, quote `old` from the live value — the Claude Code `Edit`-tool
20
+ semantics.
21
+
22
+ ## 1.0.1 — 2026-07-03
23
+
24
+ - **Fix: cross-entry `instanceof` breakage.** 1.0.0 was built without code splitting, so every
25
+ subpath entry (`arborkit/errors`, `arborkit/toolset`, …) bundled its own copies of shared
26
+ classes — mixing root and subpath imports broke `instanceof` (e.g. the toolset degraded
27
+ `SCOPE_VIOLATION` results to generic `ERROR` against a `Mutator` imported from another entry).
28
+ Splitting is now enabled; shared chunks give one class identity across all entries.
29
+ - Chunk files stay private: the `"./*"` wildcard export is replaced by an explicit per-module
30
+ exports map, so hash-named chunks are not importable. All documented entry points are unchanged.
31
+
3
32
  ## 1.0.0 — 2026-07-03
4
33
 
5
34
  First public release of Arbor as `arborkit`. The milestone arc:
package/README.md CHANGED
@@ -44,6 +44,14 @@ const home = await tools.get({ path: "/pages/home" }); // home.value.content ===
44
44
  const refused = await tools.patch({ path: "/plan" }, { op: "set", value: "hacked" });
45
45
  // refused.ok === false — out of scope; violations are returned, never thrown
46
46
 
47
+ // Agent edits — surgical substring replacement instead of regenerating a block:
48
+ // get the node first, quote `old` from the live value (Claude Code Edit semantics).
49
+ await tools.patch({ path: "/pages/home" }, { op: "set", value: { title: "Home", html: "<p>Bonus: 100% do 2000 PLN</p>" } });
50
+ const edited = await tools.patch(
51
+ { path: "/pages/home/html" },
52
+ { op: "edit", old: "100% do 2000 PLN", new: "150% do 3000 PLN" },
53
+ ); // unique-or-fail: an ambiguous `old` returns INVALID_OP with the occurrence count
54
+
47
55
  // Semantic search — mutations only mark nodes stale; reindex() embeds:
48
56
  await arbor.index!.reindex();
49
57
  const found = await arbor.index!.search("home page"); // { results, staleCount }
@@ -1,55 +1,7 @@
1
- // src/jsonpointer.ts
2
- function encodeSegment(s) {
3
- return s.replace(/~/g, "~0").replace(/\//g, "~1");
4
- }
5
- function decodeSegment(s) {
6
- return s.replace(/~1/g, "/").replace(/~0/g, "~");
7
- }
8
- function buildPointer(segments) {
9
- if (segments.length === 0) return "";
10
- return "/" + segments.map((s) => encodeSegment(String(s))).join("/");
11
- }
12
- function parsePointer(pointer) {
13
- if (pointer === "") return [];
14
- if (!pointer.startsWith("/")) {
15
- throw new Error(`Invalid JSON Pointer (must be "" or start with "/"): ${pointer}`);
16
- }
17
- return pointer.slice(1).split("/").map(decodeSegment);
18
- }
19
-
20
- // src/addressing.ts
21
- var Addressing = class {
22
- constructor(tree) {
23
- this.tree = tree;
24
- }
25
- tree;
26
- byId(id) {
27
- return this.tree.get(id);
28
- }
29
- /** Compute the JSON Pointer for a node by walking parent links to the root. */
30
- pathOf(id) {
31
- const cur0 = this.tree.get(id);
32
- if (!cur0) throw new Error(`Unknown node: ${id}`);
33
- const segments = [];
34
- let cur = cur0;
35
- while (cur && cur.parentId !== null) {
36
- segments.unshift(cur.key);
37
- cur = this.tree.get(cur.parentId);
38
- }
39
- return buildPointer(segments);
40
- }
41
- /** Resolve a JSON Pointer to a node, or undefined if any segment is missing. */
42
- byPath(pointer) {
43
- const segments = parsePointer(pointer);
44
- let cur = this.tree.root();
45
- for (const seg of segments) {
46
- if (!cur) return void 0;
47
- cur = this.tree.childByKey(cur.id, seg);
48
- if (!cur) return void 0;
49
- }
50
- return cur;
51
- }
52
- };
1
+ import {
2
+ Addressing
3
+ } from "./chunk-M72UOSPG.js";
4
+ import "./chunk-VG5BEOBI.js";
53
5
  export {
54
6
  Addressing
55
7
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/jsonpointer.ts","../src/addressing.ts"],"sourcesContent":["/** Escape a single reference token per RFC 6901: ~ -> ~0, / -> ~1. */\r\nexport function encodeSegment(s: string): string {\r\n return s.replace(/~/g, \"~0\").replace(/\\//g, \"~1\");\r\n}\r\n\r\n/** Unescape a single reference token per RFC 6901: ~1 -> /, then ~0 -> ~. */\r\nexport function decodeSegment(s: string): string {\r\n return s.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\r\n}\r\n\r\n/** Build a JSON Pointer string. Empty segment list => \"\" (root). */\r\nexport function buildPointer(segments: ReadonlyArray<string | number>): string {\r\n if (segments.length === 0) return \"\";\r\n return \"/\" + segments.map((s) => encodeSegment(String(s))).join(\"/\");\r\n}\r\n\r\n/** Append one child key to a parent pointer, escaping the key exactly as `buildPointer` does. */\r\nexport function appendPointer(parent: string, key: string | number): string {\r\n return parent + \"/\" + encodeSegment(String(key));\r\n}\r\n\r\n/** True when `path` is at or under `scope` (JSON Pointer prefix). Undefined scope = everywhere. */\r\nexport function isWithin(path: string, scope: string | undefined): boolean {\r\n return scope === undefined || path === scope || path.startsWith(scope + \"/\");\r\n}\r\n\r\n/** Parse a JSON Pointer into decoded segments. \"\" => [] (root). */\r\nexport function parsePointer(pointer: string): string[] {\r\n if (pointer === \"\") return [];\r\n if (!pointer.startsWith(\"/\")) {\r\n throw new Error(`Invalid JSON Pointer (must be \"\" or start with \"/\"): ${pointer}`);\r\n }\r\n return pointer.slice(1).split(\"/\").map(decodeSegment);\r\n}\r\n","import type { ArbNode, NodeId } from \"./types\";\r\nimport type { ArtifactTree } from \"./artifact-tree\";\r\nimport { buildPointer, parsePointer } from \"./jsonpointer\";\r\n\r\n/**\r\n * Resolves nodes by stable id and by JSON Pointer path.\r\n * `path` is DERIVED from the current structure (not stored), so it stays\r\n * consistent automatically — id is identity, path is current location.\r\n */\r\nexport class Addressing {\r\n constructor(private readonly tree: ArtifactTree) {}\r\n\r\n byId(id: NodeId): ArbNode | undefined {\r\n return this.tree.get(id);\r\n }\r\n\r\n /** Compute the JSON Pointer for a node by walking parent links to the root. */\r\n pathOf(id: NodeId): string {\r\n const cur0 = this.tree.get(id);\r\n if (!cur0) throw new Error(`Unknown node: ${id}`);\r\n const segments: (string | number)[] = [];\r\n let cur: ArbNode | undefined = cur0;\r\n while (cur && cur.parentId !== null) {\r\n segments.unshift(cur.key as string | number);\r\n cur = this.tree.get(cur.parentId);\r\n }\r\n return buildPointer(segments);\r\n }\r\n\r\n /** Resolve a JSON Pointer to a node, or undefined if any segment is missing. */\r\n byPath(pointer: string): ArbNode | undefined {\r\n const segments = parsePointer(pointer);\r\n let cur: ArbNode | undefined = this.tree.root();\r\n for (const seg of segments) {\r\n if (!cur) return undefined;\r\n // parsePointer yields UNescaped segments and node keys are raw strings —\r\n // they match childByKey's String(key) map keys directly.\r\n cur = this.tree.childByKey(cur.id, seg);\r\n if (!cur) return undefined;\r\n }\r\n return cur;\r\n }\r\n}\r\n"],"mappings":";AACO,SAAS,cAAc,GAAmB;AAC/C,SAAO,EAAE,QAAQ,MAAM,IAAI,EAAE,QAAQ,OAAO,IAAI;AAClD;AAGO,SAAS,cAAc,GAAmB;AAC/C,SAAO,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG;AACjD;AAGO,SAAS,aAAa,UAAkD;AAC7E,MAAI,SAAS,WAAW,EAAG,QAAO;AAClC,SAAO,MAAM,SAAS,IAAI,CAAC,MAAM,cAAc,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG;AACrE;AAaO,SAAS,aAAa,SAA2B;AACtD,MAAI,YAAY,GAAI,QAAO,CAAC;AAC5B,MAAI,CAAC,QAAQ,WAAW,GAAG,GAAG;AAC5B,UAAM,IAAI,MAAM,wDAAwD,OAAO,EAAE;AAAA,EACnF;AACA,SAAO,QAAQ,MAAM,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,aAAa;AACtD;;;ACxBO,IAAM,aAAN,MAAiB;AAAA,EACtB,YAA6B,MAAoB;AAApB;AAAA,EAAqB;AAAA,EAArB;AAAA,EAE7B,KAAK,IAAiC;AACpC,WAAO,KAAK,KAAK,IAAI,EAAE;AAAA,EACzB;AAAA;AAAA,EAGA,OAAO,IAAoB;AACzB,UAAM,OAAO,KAAK,KAAK,IAAI,EAAE;AAC7B,QAAI,CAAC,KAAM,OAAM,IAAI,MAAM,iBAAiB,EAAE,EAAE;AAChD,UAAM,WAAgC,CAAC;AACvC,QAAI,MAA2B;AAC/B,WAAO,OAAO,IAAI,aAAa,MAAM;AACnC,eAAS,QAAQ,IAAI,GAAsB;AAC3C,YAAM,KAAK,KAAK,IAAI,IAAI,QAAQ;AAAA,IAClC;AACA,WAAO,aAAa,QAAQ;AAAA,EAC9B;AAAA;AAAA,EAGA,OAAO,SAAsC;AAC3C,UAAM,WAAW,aAAa,OAAO;AACrC,QAAI,MAA2B,KAAK,KAAK,KAAK;AAC9C,eAAW,OAAO,UAAU;AAC1B,UAAI,CAAC,IAAK,QAAO;AAGjB,YAAM,KAAK,KAAK,WAAW,IAAI,IAAI,GAAG;AACtC,UAAI,CAAC,IAAK,QAAO;AAAA,IACnB;AACA,WAAO;AAAA,EACT;AACF;","names":[]}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/dist/ag-ui.js CHANGED
@@ -1,47 +1,9 @@
1
- // src/errors.ts
2
- var ArborError = class extends Error {
3
- constructor(code, message) {
4
- super(message);
5
- this.code = code;
6
- this.name = new.target.name;
7
- }
8
- code;
9
- };
10
- var InvalidOpError = class extends ArborError {
11
- constructor(message) {
12
- super("INVALID_OP", message);
13
- }
14
- };
15
-
16
- // src/ag-ui.ts
17
- function toJsonPatch(e) {
18
- switch (e.kind) {
19
- case "set":
20
- return e.path === void 0 ? null : { op: "replace", path: e.path, value: e.after ?? null };
21
- case "insert":
22
- return e.path === void 0 ? null : { op: "add", path: e.path, value: e.after ?? null };
23
- case "remove":
24
- return e.path === void 0 ? null : { op: "remove", path: e.path };
25
- case "move":
26
- return e.fromPath === void 0 || e.toPath === void 0 ? null : { op: "move", from: e.fromPath, path: e.toPath };
27
- }
28
- }
29
- function snapshotEvent(tree) {
30
- return { type: "STATE_SNAPSHOT", snapshot: tree.toJson() };
31
- }
32
- function deltaSince(log, sinceSeq) {
33
- if (sinceSeq < log.baseSeqValue()) {
34
- throw new InvalidOpError(
35
- `deltaSince: events [${sinceSeq}, ${log.baseSeqValue()}) were compacted away \u2014 send a fresh STATE_SNAPSHOT instead`
36
- );
37
- }
38
- const delta = [];
39
- for (const e of log.since(sinceSeq)) {
40
- const op = toJsonPatch(e);
41
- if (op) delta.push(op);
42
- }
43
- return { event: { type: "STATE_DELTA", delta }, nextSeq: log.length() };
44
- }
1
+ import {
2
+ deltaSince,
3
+ snapshotEvent,
4
+ toJsonPatch
5
+ } from "./chunk-BYXJ5B5F.js";
6
+ import "./chunk-V3HDDWER.js";
45
7
  export {
46
8
  deltaSince,
47
9
  snapshotEvent,
package/dist/ag-ui.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/ag-ui.ts"],"sourcesContent":["import type { NodeId } from \"./types\";\r\n\r\n/** A reference to a node: by stable id or by JSON Pointer path. */\r\nexport type Ref = { id: NodeId } | { path: string };\r\n\r\nexport class ArborError extends Error {\r\n constructor(\r\n public readonly code: string,\r\n message: string,\r\n ) {\r\n super(message);\r\n this.name = new.target.name;\r\n }\r\n}\r\n\r\nexport class NodeNotFoundError extends ArborError {\r\n constructor(public readonly ref: Ref) {\r\n super(\"NODE_NOT_FOUND\", `Node not found: ${JSON.stringify(ref)}`);\r\n }\r\n}\r\n\r\nexport class ScopeViolationError extends ArborError {\r\n constructor(\r\n public readonly targetPath: string,\r\n public readonly scope: string,\r\n ) {\r\n super(\"SCOPE_VIOLATION\", `Access outside scope: ${targetPath} (scope: ${scope})`);\r\n }\r\n}\r\n\r\nexport class StaleVersionError extends ArborError {\r\n constructor(\r\n public readonly id: NodeId,\r\n public readonly expected: number,\r\n public readonly actual: number,\r\n ) {\r\n super(\"STALE_VERSION\", `Stale version for ${id}: expected ${expected}, actual ${actual}`);\r\n }\r\n}\r\n\r\nexport class InvalidOpError extends ArborError {\r\n constructor(message: string) {\r\n super(\"INVALID_OP\", message);\r\n }\r\n}\r\n\r\nexport class ValidationError extends ArborError {\r\n constructor(\r\n public readonly type: string | undefined,\r\n public readonly details: string,\r\n ) {\r\n super(\"VALIDATION_ERROR\", `Validation failed${type ? ` for type ${type}` : \"\"}: ${details}`);\r\n }\r\n}\r\n","// AG-UI adapter — expose the artifact tree + event log as AG-UI shared-state\r\n// events (STATE_SNAPSHOT / STATE_DELTA with RFC 6902 JSON Patch ops). Zero-dep:\r\n// these are plain objects shaped like AG-UI events, no AG-UI SDK required.\r\nimport type { Json } from \"./types\";\r\nimport type { ArtifactTree } from \"./artifact-tree\";\r\nimport type { EventLog, MutationEvent } from \"./event-log\";\r\nimport { InvalidOpError } from \"./errors\";\r\n\r\n/** RFC 6902 operation (the subset Arbor emits). */\r\nexport type JsonPatchOp =\r\n | { op: \"replace\" | \"add\"; path: string; value: Json }\r\n | { op: \"remove\"; path: string }\r\n | { op: \"move\"; from: string; path: string };\r\n\r\nexport interface AgUiStateSnapshot {\r\n type: \"STATE_SNAPSHOT\";\r\n snapshot: Json;\r\n}\r\n\r\nexport interface AgUiStateDelta {\r\n type: \"STATE_DELTA\";\r\n delta: JsonPatchOp[];\r\n}\r\n\r\n/** One mutation event as an RFC 6902 op, or null for pre-M7 events without paths. */\r\nexport function toJsonPatch(e: MutationEvent): JsonPatchOp | null {\r\n switch (e.kind) {\r\n case \"set\":\r\n return e.path === undefined ? null : { op: \"replace\", path: e.path, value: e.after ?? null };\r\n case \"insert\":\r\n return e.path === undefined ? null : { op: \"add\", path: e.path, value: e.after ?? null };\r\n case \"remove\":\r\n return e.path === undefined ? null : { op: \"remove\", path: e.path };\r\n case \"move\":\r\n return e.fromPath === undefined || e.toPath === undefined\r\n ? null\r\n : { op: \"move\", from: e.fromPath, path: e.toPath };\r\n }\r\n}\r\n\r\n/** The full current state as an AG-UI STATE_SNAPSHOT event. */\r\nexport function snapshotEvent(tree: ArtifactTree): AgUiStateSnapshot {\r\n return { type: \"STATE_SNAPSHOT\", snapshot: tree.toJson() };\r\n}\r\n\r\n/** Retained events with seq >= sinceSeq as ONE AG-UI STATE_DELTA event (pathless\r\n * pre-M7 events are skipped). Returns the delta plus the next since-cursor.\r\n *\r\n * Throws InvalidOpError when `sinceSeq` is below the log's compaction floor:\r\n * the events in [sinceSeq, baseSeq) are gone, and applying a gapped delta would\r\n * silently diverge the client. On this error the caller must re-send a fresh\r\n * `snapshotEvent` (and resume deltas from the current version) instead. */\r\nexport function deltaSince(log: EventLog, sinceSeq: number): { event: AgUiStateDelta; nextSeq: number } {\r\n if (sinceSeq < log.baseSeqValue()) {\r\n throw new InvalidOpError(\r\n `deltaSince: events [${sinceSeq}, ${log.baseSeqValue()}) were compacted away — send a fresh STATE_SNAPSHOT instead`,\r\n );\r\n }\r\n const delta: JsonPatchOp[] = [];\r\n for (const e of log.since(sinceSeq)) {\r\n const op = toJsonPatch(e);\r\n if (op) delta.push(op);\r\n }\r\n return { event: { type: \"STATE_DELTA\", delta }, nextSeq: log.length() };\r\n}\r\n"],"mappings":";AAKO,IAAM,aAAN,cAAyB,MAAM;AAAA,EACpC,YACkB,MAChB,SACA;AACA,UAAM,OAAO;AAHG;AAIhB,SAAK,OAAO,WAAW;AAAA,EACzB;AAAA,EALkB;AAMpB;AA2BO,IAAM,iBAAN,cAA6B,WAAW;AAAA,EAC7C,YAAY,SAAiB;AAC3B,UAAM,cAAc,OAAO;AAAA,EAC7B;AACF;;;ACnBO,SAAS,YAAY,GAAsC;AAChE,UAAQ,EAAE,MAAM;AAAA,IACd,KAAK;AACH,aAAO,EAAE,SAAS,SAAY,OAAO,EAAE,IAAI,WAAW,MAAM,EAAE,MAAM,OAAO,EAAE,SAAS,KAAK;AAAA,IAC7F,KAAK;AACH,aAAO,EAAE,SAAS,SAAY,OAAO,EAAE,IAAI,OAAO,MAAM,EAAE,MAAM,OAAO,EAAE,SAAS,KAAK;AAAA,IACzF,KAAK;AACH,aAAO,EAAE,SAAS,SAAY,OAAO,EAAE,IAAI,UAAU,MAAM,EAAE,KAAK;AAAA,IACpE,KAAK;AACH,aAAO,EAAE,aAAa,UAAa,EAAE,WAAW,SAC5C,OACA,EAAE,IAAI,QAAQ,MAAM,EAAE,UAAU,MAAM,EAAE,OAAO;AAAA,EACvD;AACF;AAGO,SAAS,cAAc,MAAuC;AACnE,SAAO,EAAE,MAAM,kBAAkB,UAAU,KAAK,OAAO,EAAE;AAC3D;AASO,SAAS,WAAW,KAAe,UAA8D;AACtG,MAAI,WAAW,IAAI,aAAa,GAAG;AACjC,UAAM,IAAI;AAAA,MACR,uBAAuB,QAAQ,KAAK,IAAI,aAAa,CAAC;AAAA,IACxD;AAAA,EACF;AACA,QAAM,QAAuB,CAAC;AAC9B,aAAW,KAAK,IAAI,MAAM,QAAQ,GAAG;AACnC,UAAM,KAAK,YAAY,CAAC;AACxB,QAAI,GAAI,OAAM,KAAK,EAAE;AAAA,EACvB;AACA,SAAO,EAAE,OAAO,EAAE,MAAM,eAAe,MAAM,GAAG,SAAS,IAAI,OAAO,EAAE;AACxE;","names":[]}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}