@narumitw/pi-sync 0.51.1 → 0.52.1

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 (181) hide show
  1. package/README.md +30 -5
  2. package/dist/chunks/{chunk-7KHKWL3Q.ts → chunk-2CBF6SMT.ts} +8 -7
  3. package/dist/chunks/chunk-2CBF6SMT.ts.map +7 -0
  4. package/dist/chunks/{chunk-YFADF5ZQ.ts → chunk-2DI6PDZV.ts} +5 -1
  5. package/dist/chunks/chunk-2DI6PDZV.ts.map +7 -0
  6. package/dist/chunks/{chunk-4MPIH46N.ts → chunk-3B4Z2SKV.ts} +40 -6
  7. package/dist/chunks/chunk-3B4Z2SKV.ts.map +7 -0
  8. package/dist/chunks/{chunk-YPXGU5OR.ts → chunk-4QVPTIZB.ts} +16 -6
  9. package/dist/chunks/{chunk-YPXGU5OR.ts.map → chunk-4QVPTIZB.ts.map} +2 -2
  10. package/dist/chunks/{chunk-UA7RXOIT.ts → chunk-4SBTAVFL.ts} +6 -6
  11. package/dist/chunks/{chunk-6546TS54.ts → chunk-5RZPINUQ.ts} +7 -4
  12. package/dist/chunks/{chunk-6546TS54.ts.map → chunk-5RZPINUQ.ts.map} +2 -2
  13. package/dist/chunks/chunk-76NB4R7U.ts +107 -0
  14. package/dist/chunks/chunk-76NB4R7U.ts.map +7 -0
  15. package/dist/chunks/{chunk-DM4X4FIA.ts → chunk-7D6RDCVC.ts} +8 -10
  16. package/dist/chunks/{chunk-DM4X4FIA.ts.map → chunk-7D6RDCVC.ts.map} +2 -2
  17. package/dist/chunks/chunk-A6HU4ERM.ts +124 -0
  18. package/dist/chunks/chunk-A6HU4ERM.ts.map +7 -0
  19. package/dist/chunks/chunk-AMJRUXFT.ts +17 -0
  20. package/dist/chunks/chunk-AMJRUXFT.ts.map +7 -0
  21. package/dist/chunks/chunk-ANWNQIR7.ts +1013 -0
  22. package/dist/chunks/chunk-ANWNQIR7.ts.map +7 -0
  23. package/dist/chunks/{chunk-T56RNRZJ.ts → chunk-BDB4IDM3.ts} +19 -10
  24. package/dist/chunks/chunk-BDB4IDM3.ts.map +7 -0
  25. package/dist/chunks/{chunk-2RZSQWBH.ts → chunk-CHSIAC4N.ts} +5 -5
  26. package/dist/chunks/{chunk-2RZSQWBH.ts.map → chunk-CHSIAC4N.ts.map} +2 -2
  27. package/dist/chunks/chunk-HUZ5CR4W.ts +110 -0
  28. package/dist/chunks/chunk-HUZ5CR4W.ts.map +7 -0
  29. package/dist/chunks/{chunk-QLSN7AGX.ts → chunk-IJ6VV6FN.ts} +81 -19
  30. package/dist/chunks/chunk-IJ6VV6FN.ts.map +7 -0
  31. package/dist/chunks/chunk-NLS2NV3K.ts +1746 -0
  32. package/dist/chunks/chunk-NLS2NV3K.ts.map +7 -0
  33. package/dist/chunks/chunk-ORQRHEEO.ts +362 -0
  34. package/dist/chunks/chunk-ORQRHEEO.ts.map +7 -0
  35. package/dist/chunks/chunk-QE7NZZWT.ts +380 -0
  36. package/dist/chunks/chunk-QE7NZZWT.ts.map +7 -0
  37. package/dist/chunks/{chunk-HGJH56KR.ts → chunk-QHSQCK7L.ts} +4 -4
  38. package/dist/chunks/chunk-QOFMXPM5.ts +735 -0
  39. package/dist/chunks/chunk-QOFMXPM5.ts.map +7 -0
  40. package/dist/chunks/{chunk-DZUSTGQV.ts → chunk-UQ3ALBIB.ts} +4 -4
  41. package/dist/chunks/{chunk-Q32CQWPM.ts → chunk-V6VZ5TLG.ts} +13 -6
  42. package/dist/chunks/chunk-V6VZ5TLG.ts.map +7 -0
  43. package/dist/chunks/{chunk-E42GXD6D.ts → chunk-WKPX2SIC.ts} +4 -4
  44. package/dist/chunks/chunk-ZW5ZLGBI.ts +154 -0
  45. package/dist/chunks/chunk-ZW5ZLGBI.ts.map +7 -0
  46. package/dist/chunks/{chunk-6NT3YFGY.ts → chunk-ZX2Q6THB.ts} +8 -3
  47. package/dist/chunks/{chunk-6NT3YFGY.ts.map → chunk-ZX2Q6THB.ts.map} +2 -2
  48. package/dist/chunks/conflict-artifacts-BB2FZMIE.ts +27 -0
  49. package/dist/chunks/conflict-review-4WPGCXFB.ts +175 -0
  50. package/dist/chunks/conflict-review-4WPGCXFB.ts.map +7 -0
  51. package/dist/chunks/{file-selection-RAVHRYFG.ts → file-selection-WZX7HAY2.ts} +8 -7
  52. package/dist/chunks/{file-selection-RAVHRYFG.ts.map → file-selection-WZX7HAY2.ts.map} +1 -1
  53. package/dist/chunks/{git-backend-IAANDL3K.ts → git-backend-HLGKUQJT.ts} +19 -7
  54. package/dist/chunks/git-backend-HLGKUQJT.ts.map +7 -0
  55. package/dist/chunks/local-fields-6DGYOOIK.ts +22 -0
  56. package/dist/chunks/manager-result-dispatcher-VIDT3QBU.ts +23 -0
  57. package/dist/chunks/{manager-ui-763NEKJY.ts → manager-ui-HSMHS3OK.ts} +236 -57
  58. package/dist/chunks/manager-ui-HSMHS3OK.ts.map +7 -0
  59. package/dist/chunks/merge-baseline-store-EVQAAML6.ts +22 -0
  60. package/dist/chunks/remote-selection-ui-SMF5CLFO.ts +22 -0
  61. package/dist/chunks/{s3-backend-XGXUOPUN.ts → s3-backend-DJ2NT3SZ.ts} +16 -9
  62. package/dist/chunks/s3-backend-DJ2NT3SZ.ts.map +7 -0
  63. package/dist/chunks/{setup-switch-5G2VNJHL.ts → setup-switch-KTUWL6DE.ts} +9 -6
  64. package/dist/chunks/{setup-wizard-YIEWGX32.ts → setup-wizard-GSDPDFC4.ts} +10 -7
  65. package/dist/chunks/{setup-wizard-YIEWGX32.ts.map → setup-wizard-GSDPDFC4.ts.map} +1 -1
  66. package/dist/chunks/{snapshot-JL5DFSXI.ts → snapshot-THS5EY2L.ts} +6 -9
  67. package/dist/chunks/snapshot-THS5EY2L.ts.map +7 -0
  68. package/dist/chunks/{sync-inspection-P3ENJLNF.ts → sync-inspection-VBJF2FWC.ts} +10 -10
  69. package/dist/chunks/sync-inspection-VBJF2FWC.ts.map +7 -0
  70. package/dist/chunks/{sync-operations-AR76EB6C.ts → sync-operations-RHNECOOG.ts} +309 -508
  71. package/dist/chunks/sync-operations-RHNECOOG.ts.map +7 -0
  72. package/dist/chunks/{sync-state-VHJUZ4YG.ts → sync-state-CFL4RRRB.ts} +6 -6
  73. package/dist/chunks/sync-state-CFL4RRRB.ts.map +7 -0
  74. package/dist/chunks/{webdav-backend-3EGUONAT.ts → webdav-backend-ETQGSI6I.ts} +13 -7
  75. package/dist/chunks/webdav-backend-ETQGSI6I.ts.map +7 -0
  76. package/dist/index.ts +142 -43
  77. package/dist/index.ts.map +2 -2
  78. package/docs/content-merge-audit.md +156 -0
  79. package/docs/merge-implementation-audit.md +312 -0
  80. package/docs/settings-merge-audit.md +153 -0
  81. package/docs/settings.md +36 -0
  82. package/package.json +5 -5
  83. package/src/backends/git/git-backend.ts +2 -0
  84. package/src/backends/git/git-storage.ts +8 -3
  85. package/src/backends/s3/s3-backend.ts +2 -1
  86. package/src/backends/webdav/webdav-backend.ts +2 -1
  87. package/src/commands/command-execution.ts +10 -0
  88. package/src/commands/command.ts +4 -0
  89. package/src/settings/config.ts +12 -0
  90. package/src/settings/settings-management.ts +2 -2
  91. package/src/settings/settings-types.ts +14 -1
  92. package/src/settings/settings-validation.ts +24 -3
  93. package/src/snapshot/session-paths.ts +34 -7
  94. package/src/snapshot/snapshot-apply.ts +81 -32
  95. package/src/snapshot/snapshot-case-replacement.ts +80 -0
  96. package/src/snapshot/snapshot-codec.ts +6 -1
  97. package/src/snapshot/snapshot-root-transition.ts +154 -0
  98. package/src/snapshot/snapshot-transaction-plan.ts +72 -0
  99. package/src/snapshot/snapshot-transaction.ts +844 -102
  100. package/src/snapshot/snapshot-types.ts +5 -0
  101. package/src/state/json-file.ts +32 -5
  102. package/src/state/merge-baseline-store.ts +182 -0
  103. package/src/state/mutation-directory-sync.ts +34 -0
  104. package/src/state/state-types.ts +4 -0
  105. package/src/state/sync-state-store.ts +14 -1
  106. package/src/sync/automatic-sync.ts +11 -3
  107. package/src/sync/conflict-artifact-ownership.ts +63 -0
  108. package/src/sync/conflict-artifacts.ts +195 -0
  109. package/src/sync/conflict-groups.ts +68 -0
  110. package/src/sync/conflict-preview.ts +56 -0
  111. package/src/sync/conflict-resolution.ts +93 -0
  112. package/src/sync/conflict-retention.ts +72 -0
  113. package/src/sync/conflict-review.ts +95 -0
  114. package/src/sync/content-conflicts.ts +73 -0
  115. package/src/sync/field-migration.ts +39 -0
  116. package/src/sync/file-merge-planner.ts +143 -0
  117. package/src/sync/json-document.ts +184 -0
  118. package/src/sync/local-fields.ts +134 -0
  119. package/src/sync/merge-apply.ts +428 -0
  120. package/src/sync/merge-journal.ts +219 -0
  121. package/src/sync/merged-sync.ts +723 -0
  122. package/src/sync/partial-progress.ts +54 -0
  123. package/src/sync/remote-snapshot.ts +6 -0
  124. package/src/sync/session-merge.ts +194 -0
  125. package/src/sync/settings-conflicts.ts +52 -0
  126. package/src/sync/settings-merge.ts +57 -0
  127. package/src/sync/startup-check.ts +90 -5
  128. package/src/sync/sync-inspection.ts +1 -0
  129. package/src/sync/sync-local.ts +61 -0
  130. package/src/sync/sync-mutations.ts +256 -114
  131. package/src/sync/sync-queries.ts +6 -2
  132. package/src/sync/sync-state.ts +14 -5
  133. package/src/sync/text-merge.ts +133 -0
  134. package/src/sync-extension.ts +8 -0
  135. package/src/ui/manager-state.ts +12 -1
  136. package/src/ui/manager-ui.ts +10 -0
  137. package/src/ui/merge-review.ts +28 -0
  138. package/src/ui/remote-selection-ui.ts +1 -0
  139. package/src/ui/settings-ui.ts +183 -2
  140. package/src/ui/setup/setup-actions.ts +2 -2
  141. package/src/ui/setup/setup-switcher.ts +2 -1
  142. package/src/ui/storage-connections-ui.ts +11 -7
  143. package/src/ui/sync-attention.ts +3 -0
  144. package/src/ui/sync-format.ts +16 -12
  145. package/src/ui/sync-setups-ui.ts +1 -0
  146. package/src/ui/terminal-text.ts +9 -2
  147. package/dist/chunks/chunk-4AIHXRKE.ts +0 -197
  148. package/dist/chunks/chunk-4AIHXRKE.ts.map +0 -7
  149. package/dist/chunks/chunk-4MPIH46N.ts.map +0 -7
  150. package/dist/chunks/chunk-7KHKWL3Q.ts.map +0 -7
  151. package/dist/chunks/chunk-EEJPYTWE.ts +0 -348
  152. package/dist/chunks/chunk-EEJPYTWE.ts.map +0 -7
  153. package/dist/chunks/chunk-IVXEDPAD.ts +0 -370
  154. package/dist/chunks/chunk-IVXEDPAD.ts.map +0 -7
  155. package/dist/chunks/chunk-MSSW6F3R.ts +0 -12
  156. package/dist/chunks/chunk-MSSW6F3R.ts.map +0 -7
  157. package/dist/chunks/chunk-OVDTF5CH.ts +0 -90
  158. package/dist/chunks/chunk-OVDTF5CH.ts.map +0 -7
  159. package/dist/chunks/chunk-Q32CQWPM.ts.map +0 -7
  160. package/dist/chunks/chunk-QLSN7AGX.ts.map +0 -7
  161. package/dist/chunks/chunk-SWUXA3MH.ts +0 -18
  162. package/dist/chunks/chunk-SWUXA3MH.ts.map +0 -7
  163. package/dist/chunks/chunk-T56RNRZJ.ts.map +0 -7
  164. package/dist/chunks/chunk-YFADF5ZQ.ts.map +0 -7
  165. package/dist/chunks/git-backend-IAANDL3K.ts.map +0 -7
  166. package/dist/chunks/manager-result-dispatcher-OTUMQM26.ts +0 -23
  167. package/dist/chunks/manager-ui-763NEKJY.ts.map +0 -7
  168. package/dist/chunks/remote-selection-ui-TZTJF32Y.ts +0 -22
  169. package/dist/chunks/s3-backend-XGXUOPUN.ts.map +0 -7
  170. package/dist/chunks/sync-operations-AR76EB6C.ts.map +0 -7
  171. package/dist/chunks/webdav-backend-3EGUONAT.ts.map +0 -7
  172. /package/dist/chunks/{chunk-UA7RXOIT.ts.map → chunk-4SBTAVFL.ts.map} +0 -0
  173. /package/dist/chunks/{chunk-HGJH56KR.ts.map → chunk-QHSQCK7L.ts.map} +0 -0
  174. /package/dist/chunks/{chunk-DZUSTGQV.ts.map → chunk-UQ3ALBIB.ts.map} +0 -0
  175. /package/dist/chunks/{chunk-E42GXD6D.ts.map → chunk-WKPX2SIC.ts.map} +0 -0
  176. /package/dist/chunks/{manager-result-dispatcher-OTUMQM26.ts.map → conflict-artifacts-BB2FZMIE.ts.map} +0 -0
  177. /package/dist/chunks/{remote-selection-ui-TZTJF32Y.ts.map → local-fields-6DGYOOIK.ts.map} +0 -0
  178. /package/dist/chunks/{setup-switch-5G2VNJHL.ts.map → manager-result-dispatcher-VIDT3QBU.ts.map} +0 -0
  179. /package/dist/chunks/{snapshot-JL5DFSXI.ts.map → merge-baseline-store-EVQAAML6.ts.map} +0 -0
  180. /package/dist/chunks/{sync-inspection-P3ENJLNF.ts.map → remote-selection-ui-SMF5CLFO.ts.map} +0 -0
  181. /package/dist/chunks/{sync-state-VHJUZ4YG.ts.map → setup-switch-KTUWL6DE.ts.map} +0 -0
@@ -0,0 +1,380 @@
1
+ // @generated by scripts/build-runtime.mjs; do not edit.
2
+ // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
+ import {
4
+ collidingPaths,
5
+ planFileMerge
6
+ } from "./chunk-76NB4R7U.ts";
7
+ import {
8
+ statePathForConfig,
9
+ syncStateFingerprint
10
+ } from "./chunk-4QVPTIZB.ts";
11
+ import {
12
+ backendIdentityCoordinates
13
+ } from "./chunk-2JZFHNLM.ts";
14
+ import {
15
+ parseJsonObjectDocument,
16
+ parseSettingsDocument
17
+ } from "./chunk-ZW5ZLGBI.ts";
18
+ import {
19
+ syncDirectory,
20
+ writeJson
21
+ } from "./chunk-HUZ5CR4W.ts";
22
+
23
+ // src/state/merge-baseline-store.ts
24
+ import { createHash } from "node:crypto";
25
+ import fs from "node:fs/promises";
26
+ import path2 from "node:path";
27
+
28
+ // src/sync/session-merge.ts
29
+ import { CURRENT_SESSION_VERSION } from "@earendil-works/pi-coding-agent";
30
+
31
+ // src/sync/text-merge.ts
32
+ import path from "node:path";
33
+ var TEXT_LIMIT = 1024 * 1024;
34
+ var TEXT_MERGE_WORK_LIMIT = 8e6;
35
+ function charge(budget, work) {
36
+ if (work > budget.remaining) throw new Error("Text merge operation complexity bound exceeded.");
37
+ budget.remaining -= work;
38
+ }
39
+ function isMergeTextPath(filePath) {
40
+ return filePath === "AGENTS.md" || /\.(?:md|txt)$/u.test(filePath) && ["prompts", "skills"].includes(filePath.split("/")[0] ?? "") && path.posix.basename(filePath) !== "keybindings.json";
41
+ }
42
+ function text(bytes) {
43
+ if (bytes.length > TEXT_LIMIT) throw new Error("Text merge bound exceeded.");
44
+ const decoded = bytes.toString("utf8");
45
+ if (!Buffer.from(decoded).equals(bytes) || bytes.some((byte) => byte < 32 && byte !== 9 && byte !== 10 && byte !== 13 || byte === 127))
46
+ throw new Error("Unsupported text encoding.");
47
+ return decoded;
48
+ }
49
+ function lines(value) {
50
+ return value.match(/[^\n]*\n|[^\n]+$/gu) ?? [];
51
+ }
52
+ function edits(base, next, signal) {
53
+ const width = next.length + 1;
54
+ if ((base.length + 1) * width > 4e6) throw new Error("Text merge complexity bound exceeded.");
55
+ const ids = /* @__PURE__ */ new Map();
56
+ const intern = (line) => {
57
+ let id2 = ids.get(line);
58
+ if (id2 === void 0) {
59
+ id2 = ids.size;
60
+ ids.set(line, id2);
61
+ }
62
+ return id2;
63
+ };
64
+ const baseIds = base.map(intern);
65
+ const nextIds = next.map(intern);
66
+ const grid = new Uint32Array((base.length + 1) * width);
67
+ for (let i2 = base.length - 1; i2 >= 0; i2--) {
68
+ signal?.throwIfAborted();
69
+ for (let j2 = next.length - 1; j2 >= 0; j2--)
70
+ grid[i2 * width + j2] = baseIds[i2] === nextIds[j2] ? 1 + (grid[(i2 + 1) * width + j2 + 1] ?? 0) : Math.max(grid[(i2 + 1) * width + j2] ?? 0, grid[i2 * width + j2 + 1] ?? 0);
71
+ }
72
+ const result = [];
73
+ let i = 0;
74
+ let j = 0;
75
+ let active;
76
+ while (i < base.length || j < next.length) {
77
+ if (i < base.length && j < next.length && baseIds[i] === nextIds[j]) {
78
+ if (active) {
79
+ result.push(active);
80
+ active = void 0;
81
+ }
82
+ i++;
83
+ j++;
84
+ continue;
85
+ }
86
+ active ??= { start: i, end: i, lines: [] };
87
+ if (j < next.length && (i === base.length || (grid[i * width + j + 1] ?? 0) >= (grid[(i + 1) * width + j] ?? 0)))
88
+ active.lines.push(next[j++] ?? "");
89
+ else active.end = ++i;
90
+ }
91
+ if (active) result.push(active);
92
+ return result;
93
+ }
94
+ function mergeText(baseBytes, localBytes, remoteBytes, options = {}) {
95
+ const budget = options.budget ?? { remaining: TEXT_MERGE_WORK_LIMIT };
96
+ try {
97
+ options.signal?.throwIfAborted();
98
+ const base = lines(text(baseBytes));
99
+ const ours = lines(text(localBytes));
100
+ const theirs = lines(text(remoteBytes));
101
+ const cells = [ours, theirs].map((next) => (base.length + 1) * (next.length + 1));
102
+ if (cells.some((count) => count > 4e6)) return;
103
+ charge(budget, (cells[0] ?? 0) + (cells[1] ?? 0));
104
+ const local = edits(base, ours, options.signal);
105
+ const remote = edits(base, theirs, options.signal);
106
+ const combined = [...local];
107
+ for (const right of remote) {
108
+ let same = false;
109
+ for (const left of local) {
110
+ options.signal?.throwIfAborted();
111
+ charge(budget, 1);
112
+ if (left.start === right.start && left.end === right.end && left.lines.join("") === right.lines.join("")) {
113
+ same = true;
114
+ continue;
115
+ }
116
+ const overlap = left.start === left.end || right.start === right.end ? left.start <= right.end && right.start <= left.end : left.start < right.end && right.start < left.end;
117
+ if (overlap) return;
118
+ }
119
+ if (!same) combined.push(right);
120
+ }
121
+ combined.sort((left, right) => left.start - right.start || left.end - right.end);
122
+ let cursor = 0;
123
+ const output = [];
124
+ for (const edit of combined) {
125
+ output.push(...base.slice(cursor, edit.start), ...edit.lines);
126
+ cursor = edit.end;
127
+ }
128
+ output.push(...base.slice(cursor));
129
+ const result = Buffer.from(output.join(""));
130
+ text(result);
131
+ return result;
132
+ } catch {
133
+ options.signal?.throwIfAborted();
134
+ return;
135
+ }
136
+ }
137
+
138
+ // src/sync/session-merge.ts
139
+ var sessionId = (value) => typeof value === "string" && /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/u.test(value);
140
+ var id = (value) => typeof value === "string" && /^[a-zA-Z0-9_-]{1,128}$/u.test(value);
141
+ var content = (value, types = ["text", "image", "thinking", "toolCall"]) => typeof value === "string" || Array.isArray(value) && value.every(
142
+ (block) => object(block) && types.includes(String(block.type)) && (block.type === "text" && typeof block.text === "string" || block.type === "image" && typeof block.data === "string" && typeof block.mimeType === "string" || block.type === "thinking" && typeof block.thinking === "string" || block.type === "toolCall" && typeof block.id === "string" && typeof block.name === "string" && object(block.arguments))
143
+ );
144
+ var message = (value) => {
145
+ if (!object(value) || typeof value.timestamp !== "number" || !Number.isFinite(value.timestamp)) return false;
146
+ switch (value.role) {
147
+ case "system":
148
+ return content(value.content, ["text"]) && (value.sections === void 0 || object(value.sections) && Object.values(value.sections).every((section) => section === null || typeof section === "string")) && (value.toolsAdded === void 0 || Array.isArray(value.toolsAdded) && value.toolsAdded.every(
149
+ (tool) => object(tool) && typeof tool.name === "string" && typeof tool.description === "string" && object(tool.parameters)
150
+ )) && (value.toolsRemoved === void 0 || Array.isArray(value.toolsRemoved) && value.toolsRemoved.every((tool) => object(tool) && typeof tool.name === "string"));
151
+ case "user":
152
+ return content(value.content, ["text", "image"]);
153
+ case "assistant":
154
+ return Array.isArray(value.content) && content(value.content, ["text", "thinking", "toolCall"]) && typeof value.api === "string" && typeof value.provider === "string" && typeof value.model === "string" && object(value.usage) && ["pending", "stop", "length", "toolUse", "error", "aborted", "deferred"].includes(String(value.stopReason));
155
+ case "toolResult":
156
+ return typeof value.toolCallId === "string" && typeof value.toolName === "string" && Array.isArray(value.content) && content(value.content, ["text", "image"]) && typeof value.isError === "boolean";
157
+ case "custom":
158
+ return typeof value.customType === "string" && content(value.content, ["text", "image"]) && typeof value.display === "boolean";
159
+ case "bashExecution":
160
+ return typeof value.command === "string" && typeof value.output === "string" && typeof value.cancelled === "boolean" && typeof value.truncated === "boolean";
161
+ case "branchSummary":
162
+ return typeof value.summary === "string" && (value.fromId === null || typeof value.fromId === "string");
163
+ case "compactionSummary":
164
+ return typeof value.summary === "string" && typeof value.tokensBefore === "number" && Number.isFinite(value.tokensBefore) && value.tokensBefore >= 0;
165
+ default:
166
+ return false;
167
+ }
168
+ };
169
+ var object = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
170
+ function validateSession(bytes) {
171
+ if (CURRENT_SESSION_VERSION !== 3) throw new Error("Unaudited Pi session format; require review.");
172
+ const raw = text(bytes);
173
+ if (!raw.endsWith("\n")) throw new Error("Incomplete session tail.");
174
+ const rows = raw.slice(0, -1).split("\n").map((line) => {
175
+ if (line.startsWith("\uFEFF")) throw new Error("Unexpected session-record BOM; require review.");
176
+ return parseJsonObjectDocument(Buffer.from(line)).root.value;
177
+ });
178
+ if (rows.length > 16384) throw new Error("Session entry bound exceeded.");
179
+ const header = rows[0];
180
+ if (!object(header) || header.type !== "session" || header.version !== CURRENT_SESSION_VERSION || !sessionId(header.id) || typeof header.cwd !== "string" || typeof header.timestamp !== "string" || !Number.isFinite(Date.parse(header.timestamp)) || header.parentSession !== void 0 && typeof header.parentSession !== "string")
181
+ throw new Error("Unsupported session header.");
182
+ const ids = /* @__PURE__ */ new Set();
183
+ const known = (value) => id(value) && ids.has(value);
184
+ for (const row of rows.slice(1)) {
185
+ if (!object(row) || !id(row.id) || ids.has(row.id) || typeof row.timestamp !== "string" || !Number.isFinite(Date.parse(row.timestamp)) || row.parentId !== null && !known(row.parentId))
186
+ throw new Error("Invalid session graph.");
187
+ const strings = (...keys) => keys.every((key) => typeof row[key] === "string");
188
+ let valid = false;
189
+ switch (row.type) {
190
+ case "message":
191
+ valid = message(row.message);
192
+ break;
193
+ case "thinking_level_change":
194
+ valid = strings("thinkingLevel");
195
+ break;
196
+ case "model_change":
197
+ valid = strings("provider", "modelId");
198
+ break;
199
+ case "usage":
200
+ valid = strings("kind", "provider", "model") && object(row.usage);
201
+ break;
202
+ case "compaction":
203
+ valid = strings("summary") && (known(row.firstKeptEntryId) || row.firstKeptEntryId === row.id) && (row.systemMessage === void 0 || object(row.systemMessage) && row.systemMessage.role === "system" && message(row.systemMessage)) && typeof row.tokensBefore === "number" && Number.isFinite(row.tokensBefore) && row.tokensBefore >= 0;
204
+ break;
205
+ case "branch_summary":
206
+ valid = strings("summary") && (known(row.fromId) || row.fromId === "root");
207
+ break;
208
+ case "custom":
209
+ valid = strings("customType");
210
+ break;
211
+ case "custom_message":
212
+ valid = strings("customType") && typeof row.display === "boolean" && content(row.content, ["text", "image"]);
213
+ break;
214
+ case "context_edit":
215
+ valid = known(row.targetId) && (row.replacement === null || object(row.replacement) && content(row.replacement.content));
216
+ break;
217
+ case "label":
218
+ valid = known(row.targetId) && (row.label === void 0 || typeof row.label === "string");
219
+ break;
220
+ case "session_info":
221
+ valid = row.name === void 0 || typeof row.name === "string";
222
+ break;
223
+ }
224
+ if (!valid) throw new Error("Unsupported session entry.");
225
+ ids.add(row.id);
226
+ }
227
+ return header.id;
228
+ }
229
+ function mergeSession(base, local, remote) {
230
+ try {
231
+ const identity2 = validateSession(base);
232
+ if (validateSession(local) !== identity2 || validateSession(remote) !== identity2) return;
233
+ const prefix = (left, right) => right.length >= left.length && right.subarray(0, left.length).equals(left);
234
+ if (!prefix(base, local) || !prefix(base, remote)) return;
235
+ if (prefix(local, remote)) return remote;
236
+ if (prefix(remote, local)) return local;
237
+ } catch {
238
+ return;
239
+ }
240
+ }
241
+
242
+ // src/state/merge-baseline-store.ts
243
+ var MAX_BYTES = 192 * 1024 * 1024;
244
+ function eligible(file) {
245
+ try {
246
+ const bytes = Buffer.from(file.contentBase64, "base64");
247
+ if (file.path === "settings.json") parseSettingsDocument(bytes);
248
+ else if (isMergeTextPath(file.path)) text(bytes);
249
+ else if (file.path.startsWith("sessions/") && file.path.endsWith(".jsonl")) validateSession(bytes);
250
+ else return false;
251
+ return true;
252
+ } catch {
253
+ return false;
254
+ }
255
+ }
256
+ function identity(config) {
257
+ return JSON.stringify([
258
+ config.setupName,
259
+ backendIdentityCoordinates(config),
260
+ config.include,
261
+ config.localFields ?? []
262
+ ]);
263
+ }
264
+ function directory(config) {
265
+ return `${statePathForConfig(config)}.ancestors`;
266
+ }
267
+ async function checkDirectory(config, create = false) {
268
+ const target = directory(config);
269
+ if (create) await fs.mkdir(target, { recursive: true, mode: 448 });
270
+ const stat = await fs.lstat(target);
271
+ if (!stat.isDirectory() || stat.isSymbolicLink() || process.platform !== "win32" && (stat.mode & 63) !== 0)
272
+ throw new Error("Unsafe private ancestor directory; preserve evidence.");
273
+ }
274
+ function baselinePath(config, state) {
275
+ return path2.join(directory(config), `${syncStateFingerprint(state)}.json`);
276
+ }
277
+ async function stageMergeBaseline(config, snapshot, accepted, previous) {
278
+ const collisions = collidingPaths(snapshot.files.map((file) => file.path));
279
+ const files = snapshot.files.filter((file) => {
280
+ return !collisions.has(file.path) && accepted.lastFileHashes[file.path] === file.sha256 && (file.path === "settings.json" || config.mergeContent) && eligible(file);
281
+ });
282
+ if (previous) {
283
+ const stagedPaths = new Set(files.map((file) => file.path));
284
+ let ancestors = [];
285
+ try {
286
+ ancestors = await readMergeAncestors(config, previous) ?? [];
287
+ } catch {
288
+ }
289
+ for (const ancestor of ancestors)
290
+ if (!collisions.has(ancestor.path) && accepted.lastFileHashes[ancestor.path] === ancestor.sha256 && !stagedPaths.has(ancestor.path)) {
291
+ files.push(ancestor);
292
+ stagedPaths.add(ancestor.path);
293
+ }
294
+ }
295
+ const plan = planFileMerge({ baseline: {}, local: files, remote: [], selectionCompatible: true });
296
+ if (plan.kind !== "planned" || plan.conflicts.length)
297
+ throw new Error("Cannot stage unverified merge ancestor bytes.");
298
+ const record = {
299
+ version: 1,
300
+ identity: identity(config),
301
+ acceptedState: syncStateFingerprint(accepted),
302
+ files
303
+ };
304
+ await checkDirectory(config, true);
305
+ await writeJson(baselinePath(config, accepted), record, { maxBytes: MAX_BYTES });
306
+ }
307
+ async function readBaselineRecord(config, target, acceptedState, validate = () => {
308
+ }) {
309
+ const stat = await fs.lstat(target);
310
+ validate();
311
+ if (!stat.isFile() || stat.size > MAX_BYTES || process.platform !== "win32" && (stat.mode & 63) !== 0)
312
+ throw new Error("Unsafe cache.");
313
+ const record = JSON.parse(await fs.readFile(target, "utf8"));
314
+ validate();
315
+ if (record.version !== 1 || record.identity !== identity(config) || record.acceptedState !== acceptedState || !Array.isArray(record.files) || record.files.length > 16384 || record.files.some((file) => !eligible(file)))
316
+ throw new Error("Invalid cache identity.");
317
+ const plan = planFileMerge({ baseline: {}, local: record.files, remote: [], selectionCompatible: true });
318
+ if (plan.kind !== "planned" || plan.conflicts.length) throw new Error("Invalid cache bytes.");
319
+ return record;
320
+ }
321
+ async function readMergeAncestors(config, state) {
322
+ let record;
323
+ try {
324
+ await checkDirectory(config);
325
+ record = await readBaselineRecord(config, baselinePath(config, state), syncStateFingerprint(state));
326
+ for (const file of record.files) {
327
+ if (state.lastFileHashes[file.path] !== file.sha256 || createHash("sha256").update(Buffer.from(file.contentBase64, "base64")).digest("hex") !== file.sha256)
328
+ throw new Error("Cache hash mismatch.");
329
+ }
330
+ } catch (error) {
331
+ if (error.code === "ENOENT") return;
332
+ throw new Error("Merge ancestor is invalid; preserve its private cache and review the conflict.");
333
+ }
334
+ return record.files;
335
+ }
336
+ async function readMergeAncestor(config, state, filePath) {
337
+ const file = (await readMergeAncestors(config, state))?.find((file2) => file2.path === filePath);
338
+ return file ? Buffer.from(file.contentBase64, "base64") : void 0;
339
+ }
340
+ async function pruneMergeBaselines(config, state, validate) {
341
+ validate();
342
+ const keep = path2.basename(baselinePath(config, state));
343
+ let names;
344
+ try {
345
+ await checkDirectory(config);
346
+ validate();
347
+ names = await fs.readdir(directory(config));
348
+ } catch (error) {
349
+ if (error.code === "ENOENT") return;
350
+ throw error;
351
+ }
352
+ for (const name of names) {
353
+ validate();
354
+ if (name === keep || !/^[a-f0-9]{64}\.json$/u.test(name)) continue;
355
+ const target = path2.join(directory(config), name);
356
+ try {
357
+ await readBaselineRecord(config, target, name.slice(0, -5), validate);
358
+ } catch {
359
+ validate();
360
+ continue;
361
+ }
362
+ validate();
363
+ await fs.rm(target);
364
+ validate();
365
+ }
366
+ await syncDirectory(directory(config));
367
+ validate();
368
+ }
369
+
370
+ export {
371
+ TEXT_MERGE_WORK_LIMIT,
372
+ isMergeTextPath,
373
+ mergeText,
374
+ mergeSession,
375
+ stageMergeBaseline,
376
+ readMergeAncestors,
377
+ readMergeAncestor,
378
+ pruneMergeBaselines
379
+ };
380
+ //# sourceMappingURL=chunk-QE7NZZWT.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/state/merge-baseline-store.ts", "../../src/sync/session-merge.ts", "../../src/sync/text-merge.ts"],
4
+ "sourcesContent": ["import { createHash } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { backendIdentityCoordinates } from \"../backends/backend-identity.js\";\nimport type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport type { Snapshot, SnapshotFile } from \"../snapshot/snapshot-types.js\";\nimport { collidingPaths, planFileMerge } from \"../sync/file-merge-planner.js\";\nimport { parseSettingsDocument } from \"../sync/json-document.js\";\nimport { validateSession } from \"../sync/session-merge.js\";\nimport { isMergeTextPath, text } from \"../sync/text-merge.js\";\nimport { syncDirectory, writeJson } from \"./json-file.js\";\nimport type { SyncState } from \"./state-types.js\";\nimport { statePathForConfig, syncStateFingerprint } from \"./sync-state-store.js\";\n\ninterface MergeBaseline {\n version: 1;\n identity: string;\n acceptedState: string;\n files: SnapshotFile[];\n}\nconst MAX_BYTES = 192 * 1024 * 1024;\nfunction eligible(file: SnapshotFile) {\n try {\n const bytes = Buffer.from(file.contentBase64, \"base64\");\n if (file.path === \"settings.json\") parseSettingsDocument(bytes);\n else if (isMergeTextPath(file.path)) text(bytes);\n else if (file.path.startsWith(\"sessions/\") && file.path.endsWith(\".jsonl\")) validateSession(bytes);\n else return false;\n return true;\n } catch {\n return false;\n }\n}\n\nfunction identity(config: AnySyncConfig) {\n return JSON.stringify([\n config.setupName,\n backendIdentityCoordinates(config),\n config.include,\n config.localFields ?? [],\n ]);\n}\nfunction directory(config: AnySyncConfig) {\n return `${statePathForConfig(config)}.ancestors`;\n}\nasync function checkDirectory(config: AnySyncConfig, create = false) {\n const target = directory(config);\n if (create) await fs.mkdir(target, { recursive: true, mode: 0o700 });\n const stat = await fs.lstat(target);\n if (!stat.isDirectory() || stat.isSymbolicLink() || (process.platform !== \"win32\" && (stat.mode & 0o077) !== 0))\n throw new Error(\"Unsafe private ancestor directory; preserve evidence.\");\n}\nfunction baselinePath(config: AnySyncConfig, state: SyncState) {\n return path.join(directory(config), `${syncStateFingerprint(state)}.json`);\n}\n\n/** Stage before accepted state, retain its previous ancestor until journal retirement. Never bootstrap from current edits. */\nexport async function stageMergeBaseline(\n config: AnySyncConfig,\n snapshot: Snapshot,\n accepted: SyncState,\n previous?: SyncState,\n) {\n const collisions = collidingPaths(snapshot.files.map((file) => file.path));\n const files = snapshot.files.filter((file) => {\n return (\n !collisions.has(file.path) &&\n accepted.lastFileHashes[file.path] === file.sha256 &&\n (file.path === \"settings.json\" || config.mergeContent) &&\n eligible(file)\n );\n });\n if (previous) {\n const stagedPaths = new Set(files.map((file) => file.path));\n let ancestors: SnapshotFile[] = [];\n try {\n ancestors = (await readMergeAncestors(config, previous)) ?? [];\n } catch {\n /* Keep unknown evidence; missing bytes are never invented. */\n }\n for (const ancestor of ancestors)\n if (\n !collisions.has(ancestor.path) &&\n accepted.lastFileHashes[ancestor.path] === ancestor.sha256 &&\n !stagedPaths.has(ancestor.path)\n ) {\n files.push(ancestor);\n stagedPaths.add(ancestor.path);\n }\n }\n const plan = planFileMerge({ baseline: {}, local: files, remote: [], selectionCompatible: true });\n if (plan.kind !== \"planned\" || plan.conflicts.length)\n throw new Error(\"Cannot stage unverified merge ancestor bytes.\");\n const record: MergeBaseline = {\n version: 1,\n identity: identity(config),\n acceptedState: syncStateFingerprint(accepted),\n files,\n };\n await checkDirectory(config, true);\n await writeJson(baselinePath(config, accepted), record, { maxBytes: MAX_BYTES });\n}\n\nasync function readBaselineRecord(\n config: AnySyncConfig,\n target: string,\n acceptedState: string,\n validate: () => void = () => {},\n): Promise<MergeBaseline> {\n const stat = await fs.lstat(target);\n validate();\n if (!stat.isFile() || stat.size > MAX_BYTES || (process.platform !== \"win32\" && (stat.mode & 0o077) !== 0))\n throw new Error(\"Unsafe cache.\");\n const record = JSON.parse(await fs.readFile(target, \"utf8\")) as MergeBaseline;\n validate();\n if (\n record.version !== 1 ||\n record.identity !== identity(config) ||\n record.acceptedState !== acceptedState ||\n !Array.isArray(record.files) ||\n record.files.length > 16_384 ||\n record.files.some((file) => !eligible(file))\n )\n throw new Error(\"Invalid cache identity.\");\n const plan = planFileMerge({ baseline: {}, local: record.files, remote: [], selectionCompatible: true });\n if (plan.kind !== \"planned\" || plan.conflicts.length) throw new Error(\"Invalid cache bytes.\");\n return record;\n}\n\nexport async function readMergeAncestors(config: AnySyncConfig, state: SyncState): Promise<SnapshotFile[] | undefined> {\n let record: MergeBaseline;\n try {\n await checkDirectory(config);\n record = await readBaselineRecord(config, baselinePath(config, state), syncStateFingerprint(state));\n for (const file of record.files) {\n if (\n state.lastFileHashes[file.path] !== file.sha256 ||\n createHash(\"sha256\").update(Buffer.from(file.contentBase64, \"base64\")).digest(\"hex\") !== file.sha256\n )\n throw new Error(\"Cache hash mismatch.\");\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw new Error(\"Merge ancestor is invalid; preserve its private cache and review the conflict.\");\n }\n return record.files;\n}\nexport async function readMergeAncestor(config: AnySyncConfig, state: SyncState, filePath: string) {\n const file = (await readMergeAncestors(config, state))?.find((file) => file.path === filePath);\n return file ? Buffer.from(file.contentBase64, \"base64\") : undefined;\n}\n\n/** Caller must hold the sync operation lock and retire the commit journal before pruning. */\nexport async function pruneMergeBaselines(config: AnySyncConfig, state: SyncState, validate: () => void) {\n validate();\n const keep = path.basename(baselinePath(config, state));\n let names: string[];\n try {\n await checkDirectory(config);\n validate();\n names = await fs.readdir(directory(config));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw error;\n }\n for (const name of names) {\n validate();\n if (name === keep || !/^[a-f0-9]{64}\\.json$/u.test(name)) continue;\n const target = path.join(directory(config), name);\n try {\n await readBaselineRecord(config, target, name.slice(0, -5), validate);\n } catch {\n validate();\n continue; // Unknown/corrupted evidence is not an owned pruning candidate.\n }\n validate();\n await fs.rm(target);\n validate();\n }\n await syncDirectory(directory(config));\n validate();\n}\n", "import { CURRENT_SESSION_VERSION } from \"@earendil-works/pi-coding-agent\";\nimport { parseJsonObjectDocument } from \"./json-document.js\";\nimport { text } from \"./text-merge.js\";\n\n// Public header IDs use Pi assertValidSessionId; generated entry IDs have a separate grammar.\nconst sessionId = (value: unknown): value is string =>\n typeof value === \"string\" && /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/u.test(value);\nconst id = (value: unknown): value is string => typeof value === \"string\" && /^[a-zA-Z0-9_-]{1,128}$/u.test(value);\nconst content = (value: unknown, types = [\"text\", \"image\", \"thinking\", \"toolCall\"]): boolean =>\n typeof value === \"string\" ||\n (Array.isArray(value) &&\n value.every(\n (block) =>\n object(block) &&\n types.includes(String(block.type)) &&\n ((block.type === \"text\" && typeof block.text === \"string\") ||\n (block.type === \"image\" && typeof block.data === \"string\" && typeof block.mimeType === \"string\") ||\n (block.type === \"thinking\" && typeof block.thinking === \"string\") ||\n (block.type === \"toolCall\" &&\n typeof block.id === \"string\" &&\n typeof block.name === \"string\" &&\n object(block.arguments))),\n ));\nconst message = (value: unknown) => {\n if (!object(value) || typeof value.timestamp !== \"number\" || !Number.isFinite(value.timestamp)) return false;\n switch (value.role) {\n case \"system\":\n return (\n content(value.content, [\"text\"]) &&\n (value.sections === undefined ||\n (object(value.sections) &&\n Object.values(value.sections).every((section) => section === null || typeof section === \"string\"))) &&\n (value.toolsAdded === undefined ||\n (Array.isArray(value.toolsAdded) &&\n value.toolsAdded.every(\n (tool) =>\n object(tool) &&\n typeof tool.name === \"string\" &&\n typeof tool.description === \"string\" &&\n object(tool.parameters),\n ))) &&\n (value.toolsRemoved === undefined ||\n (Array.isArray(value.toolsRemoved) &&\n value.toolsRemoved.every((tool) => object(tool) && typeof tool.name === \"string\")))\n );\n case \"user\":\n return content(value.content, [\"text\", \"image\"]);\n case \"assistant\":\n return (\n Array.isArray(value.content) &&\n content(value.content, [\"text\", \"thinking\", \"toolCall\"]) &&\n typeof value.api === \"string\" &&\n typeof value.provider === \"string\" &&\n typeof value.model === \"string\" &&\n object(value.usage) &&\n [\"pending\", \"stop\", \"length\", \"toolUse\", \"error\", \"aborted\", \"deferred\"].includes(String(value.stopReason))\n );\n case \"toolResult\":\n return (\n typeof value.toolCallId === \"string\" &&\n typeof value.toolName === \"string\" &&\n Array.isArray(value.content) &&\n content(value.content, [\"text\", \"image\"]) &&\n typeof value.isError === \"boolean\"\n );\n case \"custom\":\n return (\n typeof value.customType === \"string\" &&\n content(value.content, [\"text\", \"image\"]) &&\n typeof value.display === \"boolean\"\n );\n case \"bashExecution\":\n return (\n typeof value.command === \"string\" &&\n typeof value.output === \"string\" &&\n typeof value.cancelled === \"boolean\" &&\n typeof value.truncated === \"boolean\"\n );\n case \"branchSummary\":\n return typeof value.summary === \"string\" && (value.fromId === null || typeof value.fromId === \"string\");\n case \"compactionSummary\":\n return (\n typeof value.summary === \"string\" &&\n typeof value.tokensBefore === \"number\" &&\n Number.isFinite(value.tokensBefore) &&\n value.tokensBefore >= 0\n );\n default:\n return false;\n }\n};\nconst object = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n/** Stricter than Pi's repair-tolerant reader: never skip malformed lines or migrate a log. */\nexport function validateSession(bytes: Buffer) {\n if (CURRENT_SESSION_VERSION !== 3) throw new Error(\"Unaudited Pi session format; require review.\");\n const raw = text(bytes);\n if (!raw.endsWith(\"\\n\")) throw new Error(\"Incomplete session tail.\");\n const rows: unknown[] = raw\n .slice(0, -1)\n .split(\"\\n\")\n .map((line) => {\n if (line.startsWith(\"\\uFEFF\")) throw new Error(\"Unexpected session-record BOM; require review.\");\n return parseJsonObjectDocument(Buffer.from(line)).root.value;\n });\n if (rows.length > 16_384) throw new Error(\"Session entry bound exceeded.\");\n const header = rows[0];\n if (\n !object(header) ||\n header.type !== \"session\" ||\n header.version !== CURRENT_SESSION_VERSION ||\n !sessionId(header.id) ||\n typeof header.cwd !== \"string\" ||\n typeof header.timestamp !== \"string\" ||\n !Number.isFinite(Date.parse(header.timestamp)) ||\n (header.parentSession !== undefined && typeof header.parentSession !== \"string\")\n )\n throw new Error(\"Unsupported session header.\");\n const ids = new Set<string>();\n const known = (value: unknown) => id(value) && ids.has(value);\n for (const row of rows.slice(1)) {\n if (\n !object(row) ||\n !id(row.id) ||\n ids.has(row.id) ||\n typeof row.timestamp !== \"string\" ||\n !Number.isFinite(Date.parse(row.timestamp)) ||\n (row.parentId !== null && !known(row.parentId))\n )\n throw new Error(\"Invalid session graph.\");\n const strings = (...keys: string[]) => keys.every((key) => typeof row[key] === \"string\");\n let valid = false;\n switch (row.type) {\n case \"message\":\n valid = message(row.message);\n break;\n case \"thinking_level_change\":\n valid = strings(\"thinkingLevel\");\n break;\n case \"model_change\":\n valid = strings(\"provider\", \"modelId\");\n break;\n case \"usage\":\n valid = strings(\"kind\", \"provider\", \"model\") && object(row.usage);\n break;\n case \"compaction\":\n valid =\n strings(\"summary\") &&\n (known(row.firstKeptEntryId) || row.firstKeptEntryId === row.id) &&\n (row.systemMessage === undefined ||\n (object(row.systemMessage) && row.systemMessage.role === \"system\" && message(row.systemMessage))) &&\n typeof row.tokensBefore === \"number\" &&\n Number.isFinite(row.tokensBefore) &&\n row.tokensBefore >= 0;\n break;\n case \"branch_summary\":\n valid = strings(\"summary\") && (known(row.fromId) || row.fromId === \"root\");\n break;\n case \"custom\":\n valid = strings(\"customType\");\n break;\n case \"custom_message\":\n valid = strings(\"customType\") && typeof row.display === \"boolean\" && content(row.content, [\"text\", \"image\"]);\n break;\n case \"context_edit\":\n valid =\n known(row.targetId) &&\n (row.replacement === null || (object(row.replacement) && content(row.replacement.content)));\n break;\n case \"label\":\n valid = known(row.targetId) && (row.label === undefined || typeof row.label === \"string\");\n break;\n case \"session_info\":\n valid = row.name === undefined || typeof row.name === \"string\";\n break;\n }\n if (!valid) throw new Error(\"Unsupported session entry.\");\n ids.add(row.id);\n }\n return header.id;\n}\nexport function mergeSession(base: Buffer, local: Buffer, remote: Buffer): Buffer | undefined {\n try {\n const identity = validateSession(base);\n if (validateSession(local) !== identity || validateSession(remote) !== identity) return;\n const prefix = (left: Buffer, right: Buffer) =>\n right.length >= left.length && right.subarray(0, left.length).equals(left);\n if (!prefix(base, local) || !prefix(base, remote)) return;\n if (prefix(local, remote)) return remote;\n if (prefix(remote, local)) return local;\n } catch {\n return;\n }\n}\n", "import path from \"node:path\";\nexport const TEXT_LIMIT = 1024 * 1024;\nexport const TEXT_MERGE_WORK_LIMIT = 8_000_000;\nexport interface TextMergeBudget {\n remaining: number;\n}\nexport interface TextMergeOptions {\n budget?: TextMergeBudget;\n signal?: AbortSignal;\n}\nfunction charge(budget: TextMergeBudget, work: number) {\n if (work > budget.remaining) throw new Error(\"Text merge operation complexity bound exceeded.\");\n budget.remaining -= work;\n}\nexport function isMergeTextPath(filePath: string) {\n return (\n filePath === \"AGENTS.md\" ||\n (/\\.(?:md|txt)$/u.test(filePath) &&\n [\"prompts\", \"skills\"].includes(filePath.split(\"/\")[0] ?? \"\") &&\n path.posix.basename(filePath) !== \"keybindings.json\")\n );\n}\nexport function text(bytes: Buffer) {\n if (bytes.length > TEXT_LIMIT) throw new Error(\"Text merge bound exceeded.\");\n const decoded = bytes.toString(\"utf8\");\n if (\n !Buffer.from(decoded).equals(bytes) ||\n bytes.some((byte) => (byte < 32 && byte !== 9 && byte !== 10 && byte !== 13) || byte === 127)\n )\n throw new Error(\"Unsupported text encoding.\");\n return decoded;\n}\ntype Hunk = { start: number; end: number; lines: string[] };\nfunction lines(value: string) {\n return value.match(/[^\\n]*\\n|[^\\n]+$/gu) ?? [];\n}\nfunction edits(base: string[], next: string[], signal?: AbortSignal): Hunk[] {\n const width = next.length + 1;\n if ((base.length + 1) * width > 4_000_000) throw new Error(\"Text merge complexity bound exceeded.\");\n // Intern once so each charged DP cell compares fixed-size IDs, not long line strings.\n const ids = new Map<string, number>();\n const intern = (line: string) => {\n let id = ids.get(line);\n if (id === undefined) {\n id = ids.size;\n ids.set(line, id);\n }\n return id;\n };\n const baseIds = base.map(intern);\n const nextIds = next.map(intern);\n const grid = new Uint32Array((base.length + 1) * width);\n for (let i = base.length - 1; i >= 0; i--) {\n signal?.throwIfAborted();\n for (let j = next.length - 1; j >= 0; j--)\n grid[i * width + j] =\n baseIds[i] === nextIds[j]\n ? 1 + (grid[(i + 1) * width + j + 1] ?? 0)\n : Math.max(grid[(i + 1) * width + j] ?? 0, grid[i * width + j + 1] ?? 0);\n }\n const result: Hunk[] = [];\n let i = 0;\n let j = 0;\n let active: Hunk | undefined;\n while (i < base.length || j < next.length) {\n if (i < base.length && j < next.length && baseIds[i] === nextIds[j]) {\n if (active) {\n result.push(active);\n active = undefined;\n }\n i++;\n j++;\n continue;\n }\n active ??= { start: i, end: i, lines: [] };\n if (j < next.length && (i === base.length || (grid[i * width + j + 1] ?? 0) >= (grid[(i + 1) * width + j] ?? 0)))\n active.lines.push(next[j++] ?? \"\");\n else active.end = ++i;\n }\n if (active) result.push(active);\n return result;\n}\nexport function mergeText(\n baseBytes: Buffer,\n localBytes: Buffer,\n remoteBytes: Buffer,\n options: TextMergeOptions = {},\n): Buffer | undefined {\n const budget = options.budget ?? { remaining: TEXT_MERGE_WORK_LIMIT };\n try {\n options.signal?.throwIfAborted();\n const base = lines(text(baseBytes));\n const ours = lines(text(localBytes));\n const theirs = lines(text(remoteBytes));\n const cells = [ours, theirs].map((next) => (base.length + 1) * (next.length + 1));\n if (cells.some((count) => count > 4_000_000)) return;\n charge(budget, (cells[0] ?? 0) + (cells[1] ?? 0));\n const local = edits(base, ours, options.signal);\n const remote = edits(base, theirs, options.signal);\n const combined = [...local];\n for (const right of remote) {\n let same = false;\n for (const left of local) {\n options.signal?.throwIfAborted();\n charge(budget, 1);\n if (left.start === right.start && left.end === right.end && left.lines.join(\"\") === right.lines.join(\"\")) {\n same = true;\n continue;\n }\n const overlap =\n left.start === left.end || right.start === right.end\n ? left.start <= right.end && right.start <= left.end\n : left.start < right.end && right.start < left.end;\n if (overlap) return;\n }\n if (!same) combined.push(right);\n }\n combined.sort((left, right) => left.start - right.start || left.end - right.end);\n let cursor = 0;\n const output: string[] = [];\n for (const edit of combined) {\n output.push(...base.slice(cursor, edit.start), ...edit.lines);\n cursor = edit.end;\n }\n output.push(...base.slice(cursor));\n const result = Buffer.from(output.join(\"\"));\n text(result);\n return result;\n } catch {\n options.signal?.throwIfAborted();\n return;\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["path", "id", "i", "j", "identity", "path", "file"]
7
+ }
@@ -5,15 +5,15 @@
5
5
  var createSyncBackend = async (config) => {
6
6
  switch (config.backend.type) {
7
7
  case "s3": {
8
- const { S3SyncBackend } = await import("./s3-backend-XGXUOPUN.ts");
8
+ const { S3SyncBackend } = await import("./s3-backend-DJ2NT3SZ.ts");
9
9
  return new S3SyncBackend(config.backend);
10
10
  }
11
11
  case "webdav": {
12
- const { WebDavSyncBackend } = await import("./webdav-backend-3EGUONAT.ts");
12
+ const { WebDavSyncBackend } = await import("./webdav-backend-ETQGSI6I.ts");
13
13
  return new WebDavSyncBackend(config.backend);
14
14
  }
15
15
  case "git": {
16
- const { GitSyncBackend } = await import("./git-backend-IAANDL3K.ts");
16
+ const { GitSyncBackend } = await import("./git-backend-HLGKUQJT.ts");
17
17
  return new GitSyncBackend(config.backend);
18
18
  }
19
19
  }
@@ -22,4 +22,4 @@ var createSyncBackend = async (config) => {
22
22
  export {
23
23
  createSyncBackend
24
24
  };
25
- //# sourceMappingURL=chunk-HGJH56KR.ts.map
25
+ //# sourceMappingURL=chunk-QHSQCK7L.ts.map