@narumitw/pi-sync 0.49.15 → 0.50.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 (209) hide show
  1. package/README.md +49 -16
  2. package/dist/chunks/chunk-2B2ELUF5.ts +29 -0
  3. package/dist/chunks/chunk-2B2ELUF5.ts.map +7 -0
  4. package/dist/chunks/chunk-6LP3MCR2.ts +115 -0
  5. package/dist/chunks/chunk-6LP3MCR2.ts.map +7 -0
  6. package/dist/chunks/chunk-6UHKGALE.ts +134 -0
  7. package/dist/chunks/chunk-6UHKGALE.ts.map +7 -0
  8. package/dist/chunks/{chunk-JF6MZCT4.ts → chunk-AUSDLD6F.ts} +4 -4
  9. package/dist/chunks/chunk-AUSDLD6F.ts.map +7 -0
  10. package/dist/chunks/{chunk-X7SQ2EQM.ts → chunk-AXXS2BPA.ts} +9 -9
  11. package/dist/chunks/chunk-AXXS2BPA.ts.map +7 -0
  12. package/dist/chunks/{chunk-5T442OP3.ts → chunk-C7XY5NF5.ts} +210 -373
  13. package/dist/chunks/chunk-C7XY5NF5.ts.map +7 -0
  14. package/dist/chunks/{chunk-4U6AFLJB.ts → chunk-CHH26D4F.ts} +3 -2
  15. package/dist/chunks/chunk-CHH26D4F.ts.map +7 -0
  16. package/dist/chunks/chunk-CPEHGXJV.ts +50 -0
  17. package/dist/chunks/chunk-CPEHGXJV.ts.map +7 -0
  18. package/dist/chunks/{chunk-5MQ76BK5.ts → chunk-D5X27LCA.ts} +2 -2
  19. package/dist/chunks/chunk-D5X27LCA.ts.map +7 -0
  20. package/dist/chunks/{chunk-WSOBYHIZ.ts → chunk-GWMHAQG4.ts} +4 -4
  21. package/dist/chunks/chunk-GWMHAQG4.ts.map +7 -0
  22. package/dist/chunks/{chunk-5LZALPCD.ts → chunk-HUDQATCL.ts} +25 -25
  23. package/dist/chunks/chunk-HUDQATCL.ts.map +7 -0
  24. package/dist/chunks/{chunk-YQ6UW7IF.ts → chunk-JAAKLL6M.ts} +2 -2
  25. package/dist/chunks/chunk-JAAKLL6M.ts.map +7 -0
  26. package/dist/chunks/chunk-JSYMGJQQ.ts +51 -0
  27. package/dist/chunks/chunk-JSYMGJQQ.ts.map +7 -0
  28. package/dist/chunks/chunk-L7TBO32M.ts +25 -0
  29. package/dist/chunks/chunk-L7TBO32M.ts.map +7 -0
  30. package/dist/chunks/{chunk-DFXBKHGN.ts → chunk-LCRI3ABW.ts} +21 -8
  31. package/dist/chunks/chunk-LCRI3ABW.ts.map +7 -0
  32. package/dist/chunks/chunk-LTBWGSBV.ts +12 -0
  33. package/dist/chunks/chunk-LTBWGSBV.ts.map +7 -0
  34. package/dist/chunks/chunk-NJFUIVYL.ts +17 -0
  35. package/dist/chunks/chunk-NJFUIVYL.ts.map +7 -0
  36. package/dist/chunks/{chunk-HVUSHMVL.ts → chunk-OEX4ABY6.ts} +39 -37
  37. package/dist/chunks/chunk-OEX4ABY6.ts.map +7 -0
  38. package/dist/chunks/chunk-OUHGBFYF.ts +1255 -0
  39. package/dist/chunks/chunk-OUHGBFYF.ts.map +7 -0
  40. package/dist/chunks/{chunk-HGV24P4T.ts → chunk-Q2TUM5X6.ts} +3 -3
  41. package/dist/chunks/chunk-Q2TUM5X6.ts.map +7 -0
  42. package/dist/chunks/{chunk-GLQLN5GV.ts → chunk-SL64RLXR.ts} +8 -6
  43. package/dist/chunks/chunk-SL64RLXR.ts.map +7 -0
  44. package/dist/chunks/chunk-T3HH3UEJ.ts +96 -0
  45. package/dist/chunks/chunk-T3HH3UEJ.ts.map +7 -0
  46. package/dist/chunks/chunk-TEN2ZBJV.ts +101 -0
  47. package/dist/chunks/chunk-TEN2ZBJV.ts.map +7 -0
  48. package/dist/chunks/chunk-THMF4BVL.ts +18 -0
  49. package/dist/chunks/chunk-THMF4BVL.ts.map +7 -0
  50. package/dist/chunks/{chunk-44LPGQTI.ts → chunk-X5OM6GXT.ts} +9 -7
  51. package/dist/chunks/chunk-X5OM6GXT.ts.map +7 -0
  52. package/dist/chunks/chunk-XBX4HBLG.ts +57 -0
  53. package/dist/chunks/chunk-XBX4HBLG.ts.map +7 -0
  54. package/dist/chunks/{chunk-ARN2672F.ts → chunk-YKJHPTGO.ts} +23 -55
  55. package/dist/chunks/chunk-YKJHPTGO.ts.map +7 -0
  56. package/dist/chunks/chunk-Z4DQF6L3.ts +12 -0
  57. package/dist/chunks/chunk-Z4DQF6L3.ts.map +7 -0
  58. package/dist/chunks/{chunk-F5QL2GPY.ts → chunk-ZI5MXMEX.ts} +5 -99
  59. package/dist/chunks/chunk-ZI5MXMEX.ts.map +7 -0
  60. package/dist/chunks/{file-selection-RKEHALNQ.ts → file-selection-FTTKAOYX.ts} +10 -7
  61. package/dist/chunks/file-selection-FTTKAOYX.ts.map +7 -0
  62. package/dist/chunks/{git-backend-E3UOUUOM.ts → git-backend-OQW46G2X.ts} +42 -17
  63. package/dist/chunks/git-backend-OQW46G2X.ts.map +7 -0
  64. package/dist/chunks/manager-result-dispatcher-U23ODD32.ts +22 -0
  65. package/dist/chunks/manager-ui-ABATHC36.ts +1680 -0
  66. package/dist/chunks/manager-ui-ABATHC36.ts.map +7 -0
  67. package/dist/chunks/remote-selection-ui-ZE3TY67S.ts +21 -0
  68. package/dist/chunks/{s3-backend-552LXHE4.ts → s3-backend-3P33LQHU.ts} +96 -18
  69. package/dist/chunks/s3-backend-3P33LQHU.ts.map +7 -0
  70. package/dist/chunks/{setup-switch-5YDG5YGJ.ts → setup-switch-IS2PEZ3J.ts} +9 -9
  71. package/dist/chunks/setup-wizard-VB3VDOV5.ts +89 -0
  72. package/dist/chunks/setup-wizard-VB3VDOV5.ts.map +7 -0
  73. package/dist/chunks/{snapshot-2RYBUDRA.ts → snapshot-HKEWCVK6.ts} +7 -6
  74. package/dist/chunks/sync-inspection-FEP4L5TR.ts +20 -0
  75. package/dist/chunks/{sync-operations-3LLIHWZO.ts → sync-operations-ONJ27QRL.ts} +374 -294
  76. package/dist/chunks/sync-operations-ONJ27QRL.ts.map +7 -0
  77. package/dist/chunks/{sync-state-SRN6YRBK.ts → sync-state-Q2FTXTW6.ts} +6 -6
  78. package/dist/chunks/sync-state-Q2FTXTW6.ts.map +7 -0
  79. package/dist/chunks/{webdav-backend-ZD5RHRIU.ts → webdav-backend-ECIKD7SO.ts} +26 -13
  80. package/dist/chunks/webdav-backend-ECIKD7SO.ts.map +7 -0
  81. package/dist/index.ts +477 -342
  82. package/dist/index.ts.map +4 -4
  83. package/docs/settings.md +30 -6
  84. package/package.json +1 -1
  85. package/src/{backend-factory.ts → backends/backend-factory.ts} +4 -4
  86. package/src/backends/backend-identity.ts +40 -0
  87. package/src/backends/backend-types.ts +81 -0
  88. package/src/{git-backend.ts → backends/git/git-backend.ts} +43 -19
  89. package/src/{git-config.ts → backends/git/git-config.ts} +1 -0
  90. package/src/{git-storage.ts → backends/git/git-storage.ts} +2 -2
  91. package/src/{s3-backend.ts → backends/s3/s3-backend.ts} +45 -9
  92. package/src/{s3-client.ts → backends/s3/s3-client.ts} +56 -8
  93. package/src/{sync-backend.ts → backends/sync-backend.ts} +1 -1
  94. package/src/{webdav-backend.ts → backends/webdav/webdav-backend.ts} +22 -10
  95. package/src/{webdav-client.ts → backends/webdav/webdav-client.ts} +1 -1
  96. package/src/{webdav-config.ts → backends/webdav/webdav-config.ts} +1 -0
  97. package/src/commands/command-execution.ts +330 -0
  98. package/src/commands/command-handler.ts +201 -0
  99. package/src/commands/command-types.ts +18 -0
  100. package/src/{command.ts → commands/command.ts} +2 -1
  101. package/src/commands/setup-completions.ts +6 -0
  102. package/src/settings/config.ts +238 -0
  103. package/src/{settings-management.ts → settings/settings-management.ts} +39 -14
  104. package/src/settings/settings-store.ts +109 -0
  105. package/src/settings/settings-types.ts +128 -0
  106. package/src/settings/settings-validation.ts +443 -0
  107. package/src/snapshot/session-paths.ts +84 -0
  108. package/src/{snapshot-apply.ts → snapshot/snapshot-apply.ts} +3 -3
  109. package/src/{snapshot-codec.ts → snapshot/snapshot-codec.ts} +2 -2
  110. package/src/{snapshot-transaction.ts → snapshot/snapshot-transaction.ts} +5 -4
  111. package/src/snapshot/snapshot-types.ts +38 -0
  112. package/src/{snapshot.ts → snapshot/snapshot.ts} +39 -20
  113. package/src/state/json-file.ts +20 -0
  114. package/src/{lock.ts → state/lock.ts} +3 -2
  115. package/src/{operation-availability.ts → state/operation-availability.ts} +2 -2
  116. package/src/state/state-types.ts +20 -0
  117. package/src/state/sync-state-store.ts +62 -0
  118. package/src/sync/automatic-sync.ts +103 -0
  119. package/src/{remote-snapshot.ts → sync/remote-snapshot.ts} +27 -4
  120. package/src/{setup-switch.ts → sync/setup-switch.ts} +6 -7
  121. package/src/sync/signals.ts +10 -0
  122. package/src/sync/startup-check.ts +128 -0
  123. package/src/{sync-decision.ts → sync/sync-decision.ts} +6 -3
  124. package/src/sync/sync-error-guidance.ts +53 -0
  125. package/src/sync/sync-inspection.ts +51 -0
  126. package/src/sync/sync-loaders.ts +54 -0
  127. package/src/{sync-operations.ts → sync/sync-mutations.ts} +34 -325
  128. package/src/sync/sync-operations.ts +12 -0
  129. package/src/{sync-policy.ts → sync/sync-policy.ts} +2 -2
  130. package/src/sync/sync-queries.ts +235 -0
  131. package/src/{sync-state.ts → sync/sync-state.ts} +5 -4
  132. package/src/sync-extension.ts +64 -708
  133. package/src/sync.ts +8 -8
  134. package/src/types.ts +47 -286
  135. package/src/ui/automatic-sync-summary.ts +6 -0
  136. package/src/{cancellable-operation.ts → ui/cancellable-operation.ts} +4 -4
  137. package/src/{file-selection.ts → ui/file-selection.ts} +5 -3
  138. package/src/{manager-attention.ts → ui/manager-attention.ts} +5 -1
  139. package/src/{manager-recovery.ts → ui/manager-recovery.ts} +6 -2
  140. package/src/{manager-state.ts → ui/manager-state.ts} +35 -14
  141. package/src/ui/manager-ui.ts +386 -0
  142. package/src/{remote-selection-ui.ts → ui/remote-selection-ui.ts} +21 -13
  143. package/src/{secret-input.ts → ui/secret-input.ts} +22 -4
  144. package/src/{settings-ui.ts → ui/settings-ui.ts} +17 -13
  145. package/src/ui/setup/git-ui.ts +293 -0
  146. package/src/{s3-credentials-ui.ts → ui/setup/s3-credentials-ui.ts} +13 -21
  147. package/src/ui/setup/s3-ui.ts +217 -0
  148. package/src/ui/setup/setup-actions.ts +127 -0
  149. package/src/ui/setup/setup-location-ui.ts +167 -0
  150. package/src/ui/setup/setup-name-ui.ts +34 -0
  151. package/src/ui/setup/setup-prompts.ts +92 -0
  152. package/src/ui/setup/setup-review.ts +70 -0
  153. package/src/ui/setup/setup-switcher.ts +181 -0
  154. package/src/ui/setup/setup-wizard.ts +39 -0
  155. package/src/ui/setup/text-input.ts +78 -0
  156. package/src/ui/setup/webdav-ui.ts +330 -0
  157. package/src/{storage-connections-ui.ts → ui/storage-connections-ui.ts} +99 -69
  158. package/src/{sync-attention.ts → ui/sync-attention.ts} +75 -6
  159. package/src/{sync-format.ts → ui/sync-format.ts} +7 -13
  160. package/src/{sync-resolution-ui.ts → ui/sync-resolution-ui.ts} +4 -3
  161. package/src/{sync-setups-ui.ts → ui/sync-setups-ui.ts} +23 -10
  162. package/src/ui/terminal-text.ts +4 -0
  163. package/dist/chunks/chunk-44LPGQTI.ts.map +0 -7
  164. package/dist/chunks/chunk-4U6AFLJB.ts.map +0 -7
  165. package/dist/chunks/chunk-5LZALPCD.ts.map +0 -7
  166. package/dist/chunks/chunk-5MQ76BK5.ts.map +0 -7
  167. package/dist/chunks/chunk-5T442OP3.ts.map +0 -7
  168. package/dist/chunks/chunk-ARN2672F.ts.map +0 -7
  169. package/dist/chunks/chunk-C7LXZ3UH.ts +0 -167
  170. package/dist/chunks/chunk-C7LXZ3UH.ts.map +0 -7
  171. package/dist/chunks/chunk-DFXBKHGN.ts.map +0 -7
  172. package/dist/chunks/chunk-E4COSV32.ts +0 -82
  173. package/dist/chunks/chunk-E4COSV32.ts.map +0 -7
  174. package/dist/chunks/chunk-F5QL2GPY.ts.map +0 -7
  175. package/dist/chunks/chunk-GLQLN5GV.ts.map +0 -7
  176. package/dist/chunks/chunk-HGV24P4T.ts.map +0 -7
  177. package/dist/chunks/chunk-HVUSHMVL.ts.map +0 -7
  178. package/dist/chunks/chunk-JF6MZCT4.ts.map +0 -7
  179. package/dist/chunks/chunk-WSOBYHIZ.ts.map +0 -7
  180. package/dist/chunks/chunk-X7SQ2EQM.ts.map +0 -7
  181. package/dist/chunks/chunk-YQ6UW7IF.ts.map +0 -7
  182. package/dist/chunks/file-selection-RKEHALNQ.ts.map +0 -7
  183. package/dist/chunks/git-backend-E3UOUUOM.ts.map +0 -7
  184. package/dist/chunks/manager-result-dispatcher-LWPYJAD5.ts +0 -18
  185. package/dist/chunks/manager-ui-NF4RUHBY.ts +0 -2785
  186. package/dist/chunks/manager-ui-NF4RUHBY.ts.map +0 -7
  187. package/dist/chunks/remote-selection-ui-NUF5P4ZJ.ts +0 -17
  188. package/dist/chunks/s3-backend-552LXHE4.ts.map +0 -7
  189. package/dist/chunks/sync-operations-3LLIHWZO.ts.map +0 -7
  190. package/dist/chunks/webdav-backend-ZD5RHRIU.ts.map +0 -7
  191. package/src/config.ts +0 -923
  192. package/src/git-ui.ts +0 -307
  193. package/src/manager-helpers.ts +0 -64
  194. package/src/manager-ui.ts +0 -997
  195. package/src/webdav-ui.ts +0 -421
  196. /package/dist/chunks/{manager-result-dispatcher-LWPYJAD5.ts.map → manager-result-dispatcher-U23ODD32.ts.map} +0 -0
  197. /package/dist/chunks/{remote-selection-ui-NUF5P4ZJ.ts.map → remote-selection-ui-ZE3TY67S.ts.map} +0 -0
  198. /package/dist/chunks/{setup-switch-5YDG5YGJ.ts.map → setup-switch-IS2PEZ3J.ts.map} +0 -0
  199. /package/dist/chunks/{snapshot-2RYBUDRA.ts.map → snapshot-HKEWCVK6.ts.map} +0 -0
  200. /package/dist/chunks/{sync-state-SRN6YRBK.ts.map → sync-inspection-FEP4L5TR.ts.map} +0 -0
  201. /package/src/{git-runner.ts → backends/git/git-runner.ts} +0 -0
  202. /package/src/{config-errors.ts → settings/config-errors.ts} +0 -0
  203. /package/src/{config-file.ts → settings/config-file.ts} +0 -0
  204. /package/src/{snapshot-paths.ts → snapshot/snapshot-paths.ts} +0 -0
  205. /package/src/{lock-policy.ts → state/lock-policy.ts} +0 -0
  206. /package/src/{lockfile-fs.ts → state/lockfile-fs.ts} +0 -0
  207. /package/src/{state-directory.ts → state/state-directory.ts} +0 -0
  208. /package/src/{sync-errors.ts → sync/sync-errors.ts} +0 -0
  209. /package/src/{manager-result-dispatcher.ts → ui/manager-result-dispatcher.ts} +0 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/ui/file-selection.ts"],
4
+ "sourcesContent": ["import fs from \"node:fs/promises\";\nimport type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { defineMenu, runMenu } from \"@narumitw/pi-tui-kit\";\nimport { loadConfig } from \"../settings/config.js\";\nimport { localConfigPath } from \"../settings/config-file.js\";\nimport { updateSyncSetup } from \"../settings/settings-management.js\";\nimport { agentDir } from \"../snapshot/session-paths.js\";\nimport {\n\tBUILT_IN_SYNC_ROOTS,\n\tisSafeCustomIncludePath,\n\tnormalizeSyncInclude,\n\tsyncIncludeSelection,\n} from \"../sync/sync-policy.js\";\n\nconst BUILT_IN_PREFIX = \"builtin:\";\nconst CUSTOM_PREFIX = \"custom:\";\nconst SESSIONS_ID = \"sessions\";\nconst ADD_CUSTOM_ID = \"add-custom\";\n\ninterface SelectionDraft {\n\tbuiltIns: Set<string>;\n\tcustom: Set<string>;\n\tsessions: boolean;\n}\n\nexport async function showFileSelection(\n\tctx: ExtensionCommandContext,\n\tsetupName?: string,\n\tsignal?: AbortSignal,\n) {\n\tconst config = await loadConfig(setupName);\n\tif (signal?.aborted) return;\n\tconst selection = syncIncludeSelection(config.include);\n\tconst original: SelectionDraft = {\n\t\tbuiltIns: new Set(selection.builtIns),\n\t\tcustom: new Set(selection.custom),\n\t\tsessions: selection.sessions,\n\t};\n\tconst draft = cloneDraft(original);\n\tconst customCandidates = await listCustomCandidates(draft.custom);\n\n\tif (ctx.mode !== \"tui\") {\n\t\tctx.ui.notify(\n\t\t\t[\n\t\t\t\t`pi-sync included content for sync setup ${safeTerminalText(config.setupName)}:`,\n\t\t\t\t`include: ${config.include.map(safeTerminalText).join(\", \") || \"none\"}`,\n\t\t\t\t`Edit sync.include in ${safeTerminalText(localConfigPath())}.`,\n\t\t\t].join(\"\\n\"),\n\t\t\t\"info\",\n\t\t);\n\t\treturn;\n\t}\n\n\twhile (!signal?.aborted) {\n\t\tawait showDraftEditor(ctx, config.setupName, draft, customCandidates, signal);\n\t\tif (signal?.aborted || sameDraft(original, draft)) return;\n\t\tconst choice = await showDraftReview(ctx, original, draft, signal);\n\t\tif (signal?.aborted) return;\n\t\tif (choice === \"Continue editing\") continue;\n\t\tif (choice !== \"Save changes\") {\n\t\t\tctx.ui.notify(\"Included-content changes discarded.\", \"info\");\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tif (!original.sessions && draft.sessions) {\n\t\t\t\tconst acknowledged = await ctx.ui.confirm(\n\t\t\t\t\t\"Include session conversations?\",\n\t\t\t\t\t\"Session JSONL may contain prompts, tool output, file paths, images, and secrets. Continue only with storage you trust.\",\n\t\t\t\t\t{ signal },\n\t\t\t\t);\n\t\t\t\tif (signal?.aborted) return;\n\t\t\t\tif (!acknowledged) {\n\t\t\t\t\tctx.ui.notify(\"Session inclusion was not saved.\", \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst include = [\n\t\t\t\t...BUILT_IN_SYNC_ROOTS.filter((candidate) => draft.builtIns.has(candidate)),\n\t\t\t\t...draft.custom,\n\t\t\t\t...(draft.sessions ? [\"sessions\"] : []),\n\t\t\t];\n\t\t\tif (signal?.aborted) return;\n\t\t\tawait updateSyncSetup(\n\t\t\t\tconfig.setupName,\n\t\t\t\t(setup) => ({\n\t\t\t\t\t...setup,\n\t\t\t\t\tsync: { ...setup.sync, include },\n\t\t\t\t}),\n\t\t\t\t{ expectedInclude: config.include, signal },\n\t\t\t);\n\t\t\tif (signal?.aborted) return;\n\t\t\tctx.ui.notify(\n\t\t\t\t`Saved included content for sync setup \u201C${safeTerminalText(config.setupName)}\u201D. It applies to the next manual or automatic sync.`,\n\t\t\t\t\"info\",\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (signal?.aborted) return;\n\t\t\tctx.ui.notify(\n\t\t\t\t`Could not save pi-sync file selection: ${safeTerminalText(error instanceof Error ? error.message : String(error))}`,\n\t\t\t\t\"error\",\n\t\t\t);\n\t\t}\n\t\treturn;\n\t}\n}\n\nasync function showDraftEditor(\n\tctx: ExtensionCommandContext,\n\tsetupName: string,\n\tdraft: SelectionDraft,\n\tcustomCandidates: string[],\n\tsignal?: AbortSignal,\n) {\n\tconst menu = defineMenu<undefined, \"editor\", \"toggle\" | \"addCustom\", ExtensionCommandContext>({\n\t\tstart: \"editor\",\n\t\tscreens: {\n\t\t\teditor: () => ({\n\t\t\t\tkind: \"multiSelect\",\n\t\t\t\ttitle: `Included Content \u00B7 ${safeTerminalText(setupName)}`,\n\t\t\t\tlines: [\"Draft only \u00B7 leaving this screen opens Save, Discard, or Continue editing.\"],\n\t\t\t\tviewportSize: 12,\n\t\t\t\titems: [\n\t\t\t\t\t...BUILT_IN_SYNC_ROOTS.map((relativePath) => ({\n\t\t\t\t\t\tid: `${BUILT_IN_PREFIX}${relativePath}`,\n\t\t\t\t\t\tlabel: relativePath,\n\t\t\t\t\t\tdescription: relativePath.includes(\".\")\n\t\t\t\t\t\t\t? `Sync the top-level ${relativePath} file when present.`\n\t\t\t\t\t\t\t: `Recursively sync every safe file under ${relativePath}/.`,\n\t\t\t\t\t\tselected: draft.builtIns.has(relativePath),\n\t\t\t\t\t})),\n\t\t\t\t\t...customCandidates.map((relativePath) => ({\n\t\t\t\t\t\tid: `${CUSTOM_PREFIX}${relativePath}`,\n\t\t\t\t\t\tlabel: safeTerminalText(relativePath),\n\t\t\t\t\t\tdescription: \"Additional safe agent-relative file or directory.\",\n\t\t\t\t\t\tselected: draft.custom.has(relativePath),\n\t\t\t\t\t})),\n\t\t\t\t\t{\n\t\t\t\t\t\tid: SESSIONS_ID,\n\t\t\t\t\t\tlabel: \"sessions\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Session JSONL may contain prompts, tool output, paths, images, and secrets. Sync only to storage you trust.\",\n\t\t\t\t\t\tselected: draft.sessions,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\taction: \"toggle\",\n\t\t\t\tactions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: ADD_CUSTOM_ID,\n\t\t\t\t\t\tlabel: \"Add custom path\u2026\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Include an agent-relative file or directory even when it exists only remotely.\",\n\t\t\t\t\t\taction: \"addCustom\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\thint: \"close\",\n\t\t\t\tdoneLabel: \"Review changes\",\n\t\t\t}),\n\t\t},\n\t\tactions: {\n\t\t\ttoggle: async ({ itemId, selected }) => {\n\t\t\t\tupdateDraft(draft, itemId, selected === true);\n\t\t\t\treturn { kind: \"stay\" };\n\t\t\t},\n\t\t\taddCustom: async ({ ctx: actionCtx, signal: actionSignal }) => {\n\t\t\t\tconst entered = await actionCtx.ui.input(\n\t\t\t\t\t\"Add included content\",\n\t\t\t\t\t\"Agent-relative path, for example custom.toml or snippets\",\n\t\t\t\t\t{ signal: actionSignal },\n\t\t\t\t);\n\t\t\t\tif (actionSignal.aborted) return { kind: \"stay\" };\n\t\t\t\tconst requested = entered?.trim();\n\t\t\t\tif (!requested) return { kind: \"stay\" };\n\t\t\t\tconst existing = customCandidates.find(\n\t\t\t\t\t(candidate) => candidate.toLowerCase() === requested.toLowerCase(),\n\t\t\t\t);\n\t\t\t\tconst relativePath = existing ?? requested;\n\t\t\t\tif (draft.custom.has(relativePath)) return { kind: \"stay\" };\n\t\t\t\ttry {\n\t\t\t\t\tif (!isSafeCustomIncludePath(relativePath)) {\n\t\t\t\t\t\tthrow new Error(\"Enter a safe agent-relative file or directory path.\");\n\t\t\t\t\t}\n\t\t\t\t\tnormalizeSyncInclude([\n\t\t\t\t\t\t...draft.builtIns,\n\t\t\t\t\t\t...draft.custom,\n\t\t\t\t\t\t...(draft.sessions ? [\"sessions\"] : []),\n\t\t\t\t\t\trelativePath,\n\t\t\t\t\t]);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (actionSignal.aborted) return { kind: \"stay\" };\n\t\t\t\t\tactionCtx.ui.notify(\n\t\t\t\t\t\t`Could not add included content: ${safeTerminalText(error instanceof Error ? error.message : String(error))}`,\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t);\n\t\t\t\t\treturn { kind: \"stay\" };\n\t\t\t\t}\n\t\t\t\tif (!existing) {\n\t\t\t\t\tcustomCandidates.push(relativePath);\n\t\t\t\t\tcustomCandidates.sort((left, right) => left.localeCompare(right));\n\t\t\t\t}\n\t\t\t\tdraft.custom.add(relativePath);\n\t\t\t\treturn { kind: \"stay\" };\n\t\t\t},\n\t\t},\n\t});\n\tawait runMenu(ctx, menu, {\n\t\tgetState: () => undefined,\n\t\tsignal,\n\t\tisCurrent: () => !signal?.aborted,\n\t});\n}\n\nasync function showDraftReview(\n\tctx: ExtensionCommandContext,\n\toriginal: SelectionDraft,\n\tdraft: SelectionDraft,\n\tsignal?: AbortSignal,\n) {\n\tlet choice: \"Save changes\" | \"Discard changes\" | \"Continue editing\" | undefined;\n\tconst menu = defineMenu<undefined, \"review\", \"choose\", ExtensionCommandContext>({\n\t\tstart: \"review\",\n\t\tscreens: {\n\t\t\treview: () => ({\n\t\t\t\tkind: \"actions\",\n\t\t\t\ttitle: \"Review included-content changes\",\n\t\t\t\tlines: formatDraftPreview(original, draft).split(\"\\n\").slice(2),\n\t\t\t\titems: [\n\t\t\t\t\t{ id: \"save\", label: \"Save changes\", action: \"choose\" },\n\t\t\t\t\t{ id: \"discard\", label: \"Discard changes\", action: \"choose\" },\n\t\t\t\t\t{ id: \"continue\", label: \"Continue editing\", action: \"choose\" },\n\t\t\t\t],\n\t\t\t\thint: \"close\",\n\t\t\t}),\n\t\t},\n\t\tactions: {\n\t\t\tchoose: async ({ itemId }) => {\n\t\t\t\tchoice =\n\t\t\t\t\titemId === \"save\"\n\t\t\t\t\t\t? \"Save changes\"\n\t\t\t\t\t\t: itemId === \"continue\"\n\t\t\t\t\t\t\t? \"Continue editing\"\n\t\t\t\t\t\t\t: \"Discard changes\";\n\t\t\t\treturn { kind: \"close\" };\n\t\t\t},\n\t\t},\n\t});\n\tawait runMenu(ctx, menu, {\n\t\tgetState: () => undefined,\n\t\tsignal,\n\t\tisCurrent: () => !signal?.aborted,\n\t});\n\treturn choice;\n}\n\nfunction updateDraft(draft: SelectionDraft, id: string, included: boolean) {\n\tif (id.startsWith(BUILT_IN_PREFIX))\n\t\treturn updateSet(draft.builtIns, id.slice(BUILT_IN_PREFIX.length), included);\n\tif (id.startsWith(CUSTOM_PREFIX))\n\t\treturn updateSet(draft.custom, id.slice(CUSTOM_PREFIX.length), included);\n\tif (id === SESSIONS_ID) {\n\t\tdraft.sessions = included;\n\t\treturn;\n\t}\n\tthrow new Error(`Unknown file selection: ${id}`);\n}\n\nfunction updateSet(set: Set<string>, value: string, included: boolean) {\n\tif (included) set.add(value);\n\telse set.delete(value);\n}\n\nfunction formatDraftPreview(original: SelectionDraft, draft: SelectionDraft) {\n\tconst lines = [\"Review included-content changes\", \"\"];\n\tfor (const item of new Set([\n\t\t...original.builtIns,\n\t\t...draft.builtIns,\n\t\t...original.custom,\n\t\t...draft.custom,\n\t])) {\n\t\tconst before = original.builtIns.has(item) || original.custom.has(item);\n\t\tconst after = draft.builtIns.has(item) || draft.custom.has(item);\n\t\tif (before !== after) lines.push(`${after ? \"Include\" : \"Exclude\"}: ${safeTerminalText(item)}`);\n\t}\n\tif (original.sessions !== draft.sessions)\n\t\tlines.push(`${draft.sessions ? \"Include\" : \"Exclude\"}: sessions`);\n\tlines.push(\"\", \"Saving does not start a network sync.\");\n\treturn lines.join(\"\\n\");\n}\n\nasync function listCustomCandidates(configured: Set<string>) {\n\tconst candidates = new Map([...configured].map((item) => [item.toLowerCase(), item]));\n\ttry {\n\t\tfor (const entry of await fs.readdir(agentDir(), { withFileTypes: true })) {\n\t\t\tif ((!entry.isFile() && !entry.isDirectory()) || !isSafeCustomIncludePath(entry.name))\n\t\t\t\tcontinue;\n\t\t\tif (!candidates.has(entry.name.toLowerCase()))\n\t\t\t\tcandidates.set(entry.name.toLowerCase(), entry.name);\n\t\t}\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n\t}\n\treturn [...candidates.values()].sort((left, right) => left.localeCompare(right));\n}\n\nfunction cloneDraft(value: SelectionDraft): SelectionDraft {\n\treturn {\n\t\tbuiltIns: new Set(value.builtIns),\n\t\tcustom: new Set(value.custom),\n\t\tsessions: value.sessions,\n\t};\n}\n\nfunction sameDraft(left: SelectionDraft, right: SelectionDraft) {\n\treturn (\n\t\tleft.sessions === right.sessions &&\n\t\tsameSet(left.builtIns, right.builtIns) &&\n\t\tsameSet(left.custom, right.custom)\n\t);\n}\n\nfunction sameSet(left: Set<string>, right: Set<string>) {\n\treturn left.size === right.size && [...left].every((item) => right.has(item));\n}\n\nfunction safeTerminalText(value: string) {\n\t// biome-ignore lint/suspicious/noControlCharactersInRegex: Escape untrusted terminal controls.\n\treturn value.replace(/[\\u0000-\\u001f\\u007f-\\u009f]/gu, \"?\");\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -1,29 +1,35 @@
1
1
  // @generated by scripts/build-runtime.mjs; do not edit.
2
2
  // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
+ import {
4
+ stateDir
5
+ } from "./chunk-ZI5MXMEX.ts";
6
+ import {
7
+ SyncBackendConflictError,
8
+ SyncBackendPublicationOutcomeUnknownError
9
+ } from "./chunk-D5X27LCA.ts";
10
+ import {
11
+ syncErrorGuidance
12
+ } from "./chunk-CPEHGXJV.ts";
3
13
  import {
4
14
  normalizeGitBranch,
5
15
  normalizeGitDirectory,
6
16
  normalizeGitRemote,
7
17
  normalizeGitRemoteIdentity,
8
- stateDir,
9
18
  validateGitNamespace
10
- } from "./chunk-F5QL2GPY.ts";
11
- import {
12
- SyncBackendConflictError,
13
- SyncBackendPublicationOutcomeUnknownError
14
- } from "./chunk-5MQ76BK5.ts";
19
+ } from "./chunk-TEN2ZBJV.ts";
20
+ import "./chunk-2B2ELUF5.ts";
15
21
  import {
16
22
  portableSnapshotSelection,
17
23
  posixJoin,
18
24
  snapshotSelectionInclude
19
- } from "./chunk-YQ6UW7IF.ts";
25
+ } from "./chunk-JAAKLL6M.ts";
20
26
 
21
- // src/git-backend.ts
27
+ // src/backends/git/git-backend.ts
22
28
  import { createHash as createHash2, randomUUID } from "node:crypto";
23
29
  import fs from "node:fs/promises";
24
30
  import path from "node:path";
25
31
 
26
- // src/git-runner.ts
32
+ // src/backends/git/git-runner.ts
27
33
  import { spawn } from "node:child_process";
28
34
  import process2 from "node:process";
29
35
  var DEFAULT_TIMEOUT_MS = 3e4;
@@ -262,7 +268,7 @@ function throwIfAborted(signal) {
262
268
  throw signal.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted", "AbortError");
263
269
  }
264
270
 
265
- // src/git-storage.ts
271
+ // src/backends/git/git-storage.ts
266
272
  import { createHash } from "node:crypto";
267
273
  var GIT_MANIFEST_VERSION = 2;
268
274
  var MAX_GIT_MANIFEST_BYTES = 1024 * 1024;
@@ -428,7 +434,7 @@ function hasControlCharacter(value) {
428
434
  return /[\u0000-\u001f\u007f-\u009f]/u.test(value);
429
435
  }
430
436
 
431
- // src/git-backend.ts
437
+ // src/backends/git/git-backend.ts
432
438
  var COMMAND_TIMEOUT_MS = 3e4;
433
439
  var POST_COMMIT_TIMEOUT_MS = 45e3;
434
440
  var gitCacheMutationQueues = /* @__PURE__ */ new Map();
@@ -440,7 +446,7 @@ var GitSyncBackend = class {
440
446
  if (!this.allowLocalRemotes) assertProductionRemote(config.profile.remote);
441
447
  this.identity = gitBackendIdentity(config);
442
448
  this.destination = gitDestination(config);
443
- this.cacheRoot = options.cacheRoot ?? path.join(stateDir(), "git");
449
+ this.cacheRoot = path.resolve(options.cacheRoot ?? path.join(stateDir(), "git"));
444
450
  this.cacheDir = path.join(this.cacheRoot, this.identity.slice("git:".length), "repository.git");
445
451
  this.commandTimeoutMs = options.commandTimeoutMs ?? COMMAND_TIMEOUT_MS;
446
452
  this.postCommitTimeoutMs = options.postCommitTimeoutMs ?? POST_COMMIT_TIMEOUT_MS;
@@ -627,7 +633,13 @@ var GitSyncBackend = class {
627
633
  return entries;
628
634
  }
629
635
  async diagnose(signal) {
630
- const diagnostics = [];
636
+ const diagnostics = [
637
+ {
638
+ key: "git-scope",
639
+ level: "info",
640
+ message: "git check scope: read remote snapshots and inspect the local cache. Write access is not tested."
641
+ }
642
+ ];
631
643
  try {
632
644
  const version = await runGit(["--version"], {
633
645
  signal,
@@ -641,7 +653,13 @@ var GitSyncBackend = class {
641
653
  message: supported ? versionText : `${versionText || "unknown Git version"}; pi-sync requires Git 2.30 or newer`
642
654
  });
643
655
  } catch (error) {
644
- return [{ key: "git-version", level: "error", message: this.safeError(error) }];
656
+ return [
657
+ {
658
+ key: "git-version",
659
+ level: "error",
660
+ message: syncErrorGuidance(new Error(this.safeError(error)))
661
+ }
662
+ ];
645
663
  }
646
664
  try {
647
665
  const head = await this.readHead(signal);
@@ -660,7 +678,7 @@ var GitSyncBackend = class {
660
678
  diagnostics.push({
661
679
  key: "git-remote",
662
680
  level: "error",
663
- message: `git remote: ${this.safeError(error)}`
681
+ message: `git remote: ${syncErrorGuidance(new Error(this.safeError(error)))}`
664
682
  });
665
683
  }
666
684
  return diagnostics;
@@ -877,12 +895,14 @@ var GitSyncBackend = class {
877
895
  try {
878
896
  recreate = !await this.cacheUsesSha1(signal);
879
897
  } catch {
898
+ throwIfAborted2(signal);
880
899
  recreate = true;
881
900
  }
882
901
  }
883
902
  } catch (error) {
884
903
  if (error.code !== "ENOENT") throw error;
885
904
  }
905
+ throwIfAborted2(signal);
886
906
  if (recreate) await fs.rm(this.cacheDir, { recursive: true, force: true });
887
907
  try {
888
908
  await fs.access(this.cacheDir);
@@ -920,7 +940,7 @@ var GitSyncBackend = class {
920
940
  return `refs/heads/${this.config.destination.branch}`;
921
941
  }
922
942
  publicationPath() {
923
- return this.config.destination.directory;
943
+ return this.config.destination.directory === "./" ? "" : this.config.destination.directory;
924
944
  }
925
945
  manifestPath() {
926
946
  return posixJoin(this.publicationPath(), "manifest.json");
@@ -1049,8 +1069,10 @@ function assertProductionRemote(remote) {
1049
1069
  }
1050
1070
  async function withGitCacheMutation(cacheDir, run, signal) {
1051
1071
  const previous = gitCacheMutationQueues.get(cacheDir) ?? Promise.resolve();
1072
+ let started = false;
1052
1073
  const operation = previous.catch(() => void 0).then(() => {
1053
1074
  throwIfAborted2(signal);
1075
+ started = true;
1054
1076
  return run();
1055
1077
  });
1056
1078
  const tail = operation.then(
@@ -1072,6 +1094,9 @@ async function withGitCacheMutation(cacheDir, run, signal) {
1072
1094
  if (signal.aborted) onAbort();
1073
1095
  try {
1074
1096
  return await Promise.race([operation, aborted]);
1097
+ } catch (error) {
1098
+ if (started) await tail;
1099
+ throw error;
1075
1100
  } finally {
1076
1101
  signal.removeEventListener("abort", onAbort);
1077
1102
  }
@@ -1101,4 +1126,4 @@ export {
1101
1126
  gitBackendIdentity,
1102
1127
  isSupportedGitVersion
1103
1128
  };
1104
- //# sourceMappingURL=git-backend-E3UOUUOM.ts.map
1129
+ //# sourceMappingURL=git-backend-OQW46G2X.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/backends/git/git-backend.ts", "../../src/backends/git/git-runner.ts", "../../src/backends/git/git-storage.ts"],
4
+ "sourcesContent": ["import { createHash, randomUUID } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { posixJoin } from \"../../paths.js\";\nimport type { Snapshot, SnapshotFile } from \"../../snapshot/snapshot-types.js\";\nimport { stateDir } from \"../../state/state-directory.js\";\nimport { syncErrorGuidance } from \"../../sync/sync-error-guidance.js\";\nimport type { ResolvedGitBackend } from \"../backend-types.js\";\nimport {\n\ttype BackendDiagnostic,\n\ttype ExpectedRemoteHead,\n\ttype PublishSnapshotOptions,\n\ttype PublishSnapshotResult,\n\ttype RemoteHead,\n\ttype RemoteHistoryEntry,\n\ttype SyncBackend,\n\tSyncBackendConflictError,\n\tSyncBackendPublicationOutcomeUnknownError,\n} from \"../sync-backend.js\";\nimport {\n\tnormalizeGitBranch,\n\tnormalizeGitDirectory,\n\tnormalizeGitRemote,\n\tnormalizeGitRemoteIdentity,\n\tvalidateGitNamespace,\n} from \"./git-config.js\";\nimport { GitCommandError, readGitBlobs, runGit } from \"./git-runner.js\";\nimport {\n\tGIT_MANIFEST_VERSION,\n\ttype GitManifest,\n\tMAX_GIT_MANIFEST_BYTES,\n\tMAX_GIT_TREE_OUTPUT_BYTES,\n\ttype PreparedGitFile,\n\tparseGitTree,\n\tprepareGitSnapshot,\n\trequireGitManifest,\n\tvalidateGitPublicationTree,\n\tvalidateGitSnapshot,\n} from \"./git-storage.js\";\n\nconst COMMAND_TIMEOUT_MS = 30_000;\nconst POST_COMMIT_TIMEOUT_MS = 45_000;\nconst gitCacheMutationQueues = new Map<string, Promise<void>>();\n\nexport interface GitBackendOptions {\n\tcacheRoot?: string;\n\tallowLocalRemotes?: boolean;\n\tcommandTimeoutMs?: number;\n\tpostCommitTimeoutMs?: number;\n\t/** Deterministic fault injection used only by the local backend test suite. */\n\tafterPushForTest?: () => void | Promise<void>;\n\tafterLsRemoteForTest?: () => void | Promise<void>;\n\tafterPayloadWriteForTest?: () => void | Promise<void>;\n}\n\nexport class GitSyncBackend implements SyncBackend {\n\treadonly identity: string;\n\treadonly destination: string;\n\treadonly capability = \"lease-protected\" as const;\n\tprivate readonly cacheRoot: string;\n\tprivate readonly cacheDir: string;\n\tprivate readonly allowLocalRemotes: boolean;\n\tprivate readonly commandTimeoutMs: number;\n\tprivate readonly postCommitTimeoutMs: number;\n\tprivate readonly afterPushForTest?: () => void | Promise<void>;\n\tprivate readonly afterLsRemoteForTest?: () => void | Promise<void>;\n\tprivate readonly afterPayloadWriteForTest?: () => void | Promise<void>;\n\tprivate cacheReady?: Promise<void>;\n\n\tconstructor(\n\t\tprivate readonly config: ResolvedGitBackend,\n\t\toptions: GitBackendOptions = {},\n\t) {\n\t\tassertGitDestination(config);\n\t\tthis.allowLocalRemotes = options.allowLocalRemotes === true;\n\t\tif (!this.allowLocalRemotes) assertProductionRemote(config.profile.remote);\n\t\tthis.identity = gitBackendIdentity(config);\n\t\tthis.destination = gitDestination(config);\n\t\tthis.cacheRoot = path.resolve(options.cacheRoot ?? path.join(stateDir(), \"git\"));\n\t\tthis.cacheDir = path.join(this.cacheRoot, this.identity.slice(\"git:\".length), \"repository.git\");\n\t\tthis.commandTimeoutMs = options.commandTimeoutMs ?? COMMAND_TIMEOUT_MS;\n\t\tthis.postCommitTimeoutMs = options.postCommitTimeoutMs ?? POST_COMMIT_TIMEOUT_MS;\n\t\tthis.afterPushForTest = options.afterPushForTest;\n\t\tthis.afterLsRemoteForTest = options.afterLsRemoteForTest;\n\t\tthis.afterPayloadWriteForTest = options.afterPayloadWriteForTest;\n\t}\n\n\tsameRevision(left: string, right: string) {\n\t\treturn decodeRevision(left, this.identity) === decodeRevision(right, this.identity);\n\t}\n\n\tasync readHead(signal?: AbortSignal): Promise<RemoteHead | undefined> {\n\t\tconst sha = await this.fetchRemoteHead(signal);\n\t\tif (!sha) return undefined;\n\t\tconst { manifest } = await this.readPublication(sha, signal);\n\t\treturn remoteHead(sha, manifest, this.identity);\n\t}\n\n\tasync readSnapshot(reference: string, signal?: AbortSignal): Promise<Snapshot> {\n\t\tconst head = await this.fetchRemoteHead(signal);\n\t\tif (!head) throw new Error(`Git snapshot publication was not found: ${reference}`);\n\t\tconst commit = await this.resolveSnapshotReference(reference, head, signal);\n\t\ttry {\n\t\t\tawait this.git([\"cat-file\", \"-e\", `${commit}^{commit}`], { signal });\n\t\t\tawait this.git([\"merge-base\", \"--is-ancestor\", commit, head], { signal });\n\t\t} catch (error) {\n\t\t\tthrow new Error(`Git snapshot publication was not found: ${reference}`, { cause: error });\n\t\t}\n\t\tconst { manifest, payloadEntries } = await this.readPublication(commit, signal);\n\t\tlet blobs: Buffer[];\n\t\ttry {\n\t\t\tblobs = await readGitBlobs(\n\t\t\t\tpayloadEntries.map((entry) => entry.object),\n\t\t\t\t{\n\t\t\t\t\tgitDir: this.cacheDir,\n\t\t\t\t\tsignal,\n\t\t\t\t\ttimeoutMs: this.commandTimeoutMs,\n\t\t\t\t\tallowFileProtocol: this.allowLocalRemotes,\n\t\t\t\t\tmaxOutputBytes: manifest.files.reduce((total, file) => total + file.size, 0),\n\t\t\t\t},\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error && /exceeds/u.test(error.message)) {\n\t\t\t\tthrow new Error(\"Git snapshot file content exceeds its manifest size.\", { cause: error });\n\t\t\t}\n\t\t\tthrow this.redactedError(error);\n\t\t}\n\t\tthrowIfAborted(signal);\n\t\tconst files: SnapshotFile[] = manifest.files.map((file, index) => {\n\t\t\tconst content = blobs[index];\n\t\t\tif (!content || content.byteLength !== file.size || sha256(content) !== file.sha256) {\n\t\t\t\tthrow new Error(`Git snapshot file checksum or size mismatch: ${file.path}`);\n\t\t\t}\n\t\t\treturn { path: file.path, contentBase64: content.toString(\"base64\"), sha256: file.sha256 };\n\t\t});\n\t\tconst snapshot: Snapshot = {\n\t\t\tversion: manifest.snapshotVersion,\n\t\t\tid: manifest.snapshotId,\n\t\t\tcreatedAt: manifest.createdAt,\n\t\t\tmachine: manifest.machine,\n\t\t\tprofile: manifest.profile,\n\t\t\t...(manifest.snapshotSyncSessions === undefined\n\t\t\t\t? {}\n\t\t\t\t: { syncSessions: manifest.snapshotSyncSessions }),\n\t\t\t...(manifest.selection === undefined ? {} : { selection: manifest.selection }),\n\t\t\tfiles,\n\t\t};\n\t\tvalidateGitSnapshot(snapshot, manifest, this.config.destination.namespace);\n\t\treturn snapshot;\n\t}\n\n\tasync publishSnapshot(\n\t\tsnapshot: Snapshot,\n\t\texpected: ExpectedRemoteHead,\n\t\toptions: PublishSnapshotOptions = {},\n\t): Promise<PublishSnapshotResult> {\n\t\tthrowIfAborted(options.signal);\n\t\tconst files = prepareGitSnapshot(snapshot, this.config.destination.namespace);\n\t\tconst observed = await this.fetchRemoteHead(options.signal);\n\t\tif (!matchesExpected(observed, expected, this.identity)) {\n\t\t\tthrow new SyncBackendConflictError(\n\t\t\t\t\"Git remote changed while preparing publication. Run /sync status and retry.\",\n\t\t\t\t{ currentHead: observed ? await this.headForSha(observed, options.signal) : undefined },\n\t\t\t);\n\t\t}\n\t\tthrowIfAborted(options.signal);\n\t\tconst manifest: GitManifest = {\n\t\t\tversion: GIT_MANIFEST_VERSION,\n\t\t\tsnapshotVersion: snapshot.version,\n\t\t\tsnapshotId: snapshot.id,\n\t\t\tcreatedAt: snapshot.createdAt,\n\t\t\tmachine: snapshot.machine,\n\t\t\tprofile: snapshot.profile,\n\t\t\tsyncSessions:\n\t\t\t\tsnapshot.syncSessions === true ||\n\t\t\t\tsnapshot.files.some((file) => file.path.startsWith(\"sessions/\")),\n\t\t\t...(snapshot.syncSessions === undefined\n\t\t\t\t? {}\n\t\t\t\t: { snapshotSyncSessions: snapshot.syncSessions }),\n\t\t\t...(snapshot.selection === undefined ? {} : { selection: snapshot.selection }),\n\t\t\tfiles: files.map(({ path: filePath, sha256: fileSha, size }) => ({\n\t\t\t\tpath: filePath,\n\t\t\t\tsha256: fileSha,\n\t\t\t\tsize,\n\t\t\t})),\n\t\t};\n\t\tlet candidate: string;\n\t\ttry {\n\t\t\tcandidate = await this.createCommit(snapshot, files, manifest, observed, options.signal);\n\t\t} catch (error) {\n\t\t\tthrow this.redactedError(error);\n\t\t}\n\t\tthrowIfAborted(options.signal);\n\t\toptions.onCommit?.();\n\n\t\tconst ref = this.remoteRef();\n\t\tconst lease = `--force-with-lease=${ref}:${observed ?? \"\"}`;\n\t\tlet pushError: unknown;\n\t\ttry {\n\t\t\tawait this.git(\n\t\t\t\t[\n\t\t\t\t\t\"push\",\n\t\t\t\t\t\"--porcelain\",\n\t\t\t\t\t\"--no-verify\",\n\t\t\t\t\tlease,\n\t\t\t\t\tthis.config.profile.remote,\n\t\t\t\t\t`${candidate}:${ref}`,\n\t\t\t\t],\n\t\t\t\t{ timeoutMs: this.postCommitTimeoutMs },\n\t\t\t);\n\t\t\tawait this.afterPushForTest?.();\n\t\t} catch (error) {\n\t\t\tpushError = error;\n\t\t}\n\n\t\tlet current: string | undefined;\n\t\ttry {\n\t\t\tcurrent = await this.fetchRemoteHead(AbortSignal.timeout(this.postCommitTimeoutMs));\n\t\t} catch (error) {\n\t\t\tthrow new SyncBackendPublicationOutcomeUnknownError(\n\t\t\t\t`Git publication outcome is unknown: ${this.safeError(pushError ?? error)}`,\n\t\t\t\t{ cause: pushError ?? error },\n\t\t\t);\n\t\t}\n\t\tif (current !== candidate) {\n\t\t\tif (pushError && current === observed) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Git publication failed without updating the owned branch: ${this.safeError(pushError)}`,\n\t\t\t\t\t{\n\t\t\t\t\t\tcause: pushError,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new SyncBackendConflictError(\n\t\t\t\tpushError\n\t\t\t\t\t? `Git publication lease was rejected: ${this.safeError(pushError)}`\n\t\t\t\t\t: \"Git remote changed immediately after publication.\",\n\t\t\t\t{\n\t\t\t\t\tphase: \"after-commit\",\n\t\t\t\t\tcurrentHead: current ? await this.headForSha(current) : undefined,\n\t\t\t\t\tcandidateMayHaveBeenActive: true,\n\t\t\t\t\tcause: pushError instanceof Error ? pushError : undefined,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t\tconst head = await this.headForSha(candidate);\n\t\treturn { head, warnings: [] };\n\t}\n\n\tasync listHistory(signal?: AbortSignal): Promise<RemoteHistoryEntry[]> {\n\t\tconst sha = await this.fetchRemoteHead(signal);\n\t\tif (!sha) return [];\n\t\tconst result = await this.git(\n\t\t\t[\"rev-list\", \"--first-parent\", \"--reverse\", \"--max-count=100\", sha],\n\t\t\t{ signal },\n\t\t);\n\t\tconst commits = result.stdout.toString(\"utf8\").trim().split(\"\\n\").filter(Boolean);\n\t\tconst entries: RemoteHistoryEntry[] = [];\n\t\tfor (const commit of commits) {\n\t\t\tconst { manifest } = await this.readPublication(commit, signal);\n\t\t\tentries.push({\n\t\t\t\tsnapshotRef: commit,\n\t\t\t\tsnapshotId: manifest.snapshotId,\n\t\t\t\tcreatedAt: manifest.createdAt,\n\t\t\t\tmachine: manifest.machine,\n\t\t\t\tsyncSessions: manifest.syncSessions,\n\t\t\t});\n\t\t}\n\t\treturn entries;\n\t}\n\n\tasync diagnose(signal?: AbortSignal): Promise<BackendDiagnostic[]> {\n\t\tconst diagnostics: BackendDiagnostic[] = [\n\t\t\t{\n\t\t\t\tkey: \"git-scope\",\n\t\t\t\tlevel: \"info\",\n\t\t\t\tmessage:\n\t\t\t\t\t\"git check scope: read remote snapshots and inspect the local cache. Write access is not tested.\",\n\t\t\t},\n\t\t];\n\t\ttry {\n\t\t\tconst version = await runGit([\"--version\"], {\n\t\t\t\tsignal,\n\t\t\t\ttimeoutMs: this.commandTimeoutMs,\n\t\t\t});\n\t\t\tconst versionText = version.stdout.toString(\"utf8\").trim();\n\t\t\tconst supported = isSupportedGitVersion(versionText);\n\t\t\tdiagnostics.push({\n\t\t\t\tkey: \"git-version\",\n\t\t\t\tlevel: supported ? \"info\" : \"error\",\n\t\t\t\tmessage: supported\n\t\t\t\t\t? versionText\n\t\t\t\t\t: `${versionText || \"unknown Git version\"}; pi-sync requires Git 2.30 or newer`,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tkey: \"git-version\",\n\t\t\t\t\tlevel: \"error\",\n\t\t\t\t\tmessage: syncErrorGuidance(new Error(this.safeError(error))),\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\t\ttry {\n\t\t\tconst head = await this.readHead(signal);\n\t\t\tif (head) await this.readSnapshot(head.snapshotRef, signal);\n\t\t\tdiagnostics.push({\n\t\t\t\tkey: \"git-remote\",\n\t\t\t\tlevel: \"info\",\n\t\t\t\tmessage: head\n\t\t\t\t\t? `git remote: reachable; owned branch ${this.config.destination.branch} is valid`\n\t\t\t\t\t: `git remote: reachable; owned branch ${this.config.destination.branch} is not created yet`,\n\t\t\t});\n\t\t\tdiagnostics.push({\n\t\t\t\tkey: \"git-cache\",\n\t\t\t\tlevel: \"info\",\n\t\t\t\tmessage: \"git cache: private bare repository is healthy\",\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tdiagnostics.push({\n\t\t\t\tkey: \"git-remote\",\n\t\t\t\tlevel: \"error\",\n\t\t\t\tmessage: `git remote: ${syncErrorGuidance(new Error(this.safeError(error)))}`,\n\t\t\t});\n\t\t}\n\t\treturn diagnostics;\n\t}\n\n\tprivate async resolveSnapshotReference(reference: string, head: string, signal?: AbortSignal) {\n\t\tif (isCommitSha(reference) || /^[0-9a-f]{64}$/u.test(reference)) {\n\t\t\trequireCommitSha(reference);\n\t\t\treturn reference;\n\t\t}\n\t\tif (!reference || reference.length > 512 || !/^[A-Za-z0-9._-]+$/u.test(reference)) {\n\t\t\tthrow new Error(\"Invalid Git publication reference.\");\n\t\t}\n\t\tconst result = await this.git([\"rev-list\", \"--first-parent\", \"--max-count=100\", head], {\n\t\t\tsignal,\n\t\t});\n\t\tconst commits = result.stdout.toString(\"utf8\").trim().split(\"\\n\").filter(Boolean);\n\t\tconst matches: string[] = [];\n\t\tfor (const commit of commits) {\n\t\t\tconst { manifest } = await this.readPublication(commit, signal);\n\t\t\tif (manifest.snapshotId === reference) matches.push(commit);\n\t\t}\n\t\tif (matches.length === 0) {\n\t\t\tthrow new Error(`Git snapshot publication was not found: ${reference}`);\n\t\t}\n\t\tif (matches.length > 1) {\n\t\t\tthrow new Error(\n\t\t\t\t`Git snapshot id is ambiguous; use a commit reference from /sync history: ${reference}`,\n\t\t\t);\n\t\t}\n\t\treturn matches[0] as string;\n\t}\n\n\tprivate async headForSha(sha: string, signal?: AbortSignal) {\n\t\tconst { manifest } = await this.readPublication(sha, signal);\n\t\treturn remoteHead(sha, manifest, this.identity);\n\t}\n\n\tprivate async fetchRemoteHead(signal?: AbortSignal) {\n\t\tawait this.ensureCache(signal);\n\t\tconst result = await this.git(\n\t\t\t[\"ls-remote\", \"--refs\", this.config.profile.remote, this.remoteRef()],\n\t\t\t{ signal },\n\t\t);\n\t\tconst line = result.stdout.toString(\"utf8\").trim();\n\t\tif (!line) return undefined;\n\t\tconst [sha, ref, ...extra] = line.split(/\\s+/u);\n\t\tif (extra.length > 0 || ref !== this.remoteRef() || !sha) {\n\t\t\tthrow new Error(\"Git remote returned a malformed owned-ref response.\");\n\t\t}\n\t\trequireCommitSha(sha);\n\t\tawait this.afterLsRemoteForTest?.();\n\t\treturn withGitCacheMutation(\n\t\t\tthis.cacheDir,\n\t\t\tasync () => {\n\t\t\t\tconst localRef = `refs/pisync/fetch/${process.pid}-${randomUUID()}`;\n\t\t\t\ttry {\n\t\t\t\t\tawait this.git(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"fetch\",\n\t\t\t\t\t\t\t\"--no-tags\",\n\t\t\t\t\t\t\t\"--force\",\n\t\t\t\t\t\t\tthis.config.profile.remote,\n\t\t\t\t\t\t\t`${this.remoteRef()}:${localRef}`,\n\t\t\t\t\t\t],\n\t\t\t\t\t\t{ signal },\n\t\t\t\t\t);\n\t\t\t\t\tconst fetched = (await this.git([\"rev-parse\", \"--verify\", localRef], { signal })).stdout\n\t\t\t\t\t\t.toString(\"utf8\")\n\t\t\t\t\t\t.trim();\n\t\t\t\t\trequireCommitSha(fetched);\n\t\t\t\t\treturn fetched;\n\t\t\t\t} finally {\n\t\t\t\t\tawait this.git([\"update-ref\", \"-d\", localRef], { timeoutMs: 5_000 }).catch(\n\t\t\t\t\t\t() => undefined,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tprivate async readManifest(commit: string, signal?: AbortSignal): Promise<GitManifest> {\n\t\trequireCommitSha(commit);\n\t\tconst bytes = await this.showFile(commit, this.manifestPath(), signal, MAX_GIT_MANIFEST_BYTES);\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(bytes.toString(\"utf8\"));\n\t\t} catch (error) {\n\t\t\tthrow new Error(\"Git publication manifest is malformed.\", { cause: error });\n\t\t}\n\t\treturn requireGitManifest(parsed);\n\t}\n\n\tprivate showFile(\n\t\tcommit: string,\n\t\tfilePath: string,\n\t\tsignal?: AbortSignal,\n\t\tmaxOutputBytes?: number,\n\t) {\n\t\treturn this.git([\"show\", `${commit}:${filePath}`], { signal, maxOutputBytes }).then(\n\t\t\t(result) => result.stdout,\n\t\t);\n\t}\n\n\tprivate async createCommit(\n\t\tsnapshot: Snapshot,\n\t\tfiles: PreparedGitFile[],\n\t\tmanifest: GitManifest,\n\t\tparent: string | undefined,\n\t\tsignal?: AbortSignal,\n\t) {\n\t\tconst manifestBytes = Buffer.from(`${JSON.stringify(manifest)}\\n`, \"utf8\");\n\t\tif (manifestBytes.byteLength > MAX_GIT_MANIFEST_BYTES) {\n\t\t\tthrow new Error(`Git publication manifest exceeds the ${MAX_GIT_MANIFEST_BYTES}-byte limit.`);\n\t\t}\n\t\tawait this.ensureCache(signal);\n\t\tconst temporaryDirectory = await fs.mkdtemp(path.join(path.dirname(this.cacheDir), \".index-\"));\n\t\tconst indexPath = path.join(temporaryDirectory, \"index\");\n\t\tconst payloadDirectory = path.join(temporaryDirectory, \"payloads\");\n\t\tconst env = { GIT_INDEX_FILE: indexPath };\n\t\ttry {\n\t\t\tawait fs.mkdir(payloadDirectory, { mode: 0o700 });\n\t\t\tconst uniqueFiles = [...new Map(files.map((file) => [file.sha256, file])).values()].sort(\n\t\t\t\t(left, right) => left.sha256.localeCompare(right.sha256),\n\t\t\t);\n\t\t\tfor (const file of uniqueFiles) {\n\t\t\t\tthrowIfAborted(signal);\n\t\t\t\tawait fs.writeFile(path.join(payloadDirectory, file.sha256), file.content, {\n\t\t\t\t\tflag: \"wx\",\n\t\t\t\t\tmode: 0o600,\n\t\t\t\t});\n\t\t\t}\n\t\t\tawait this.afterPayloadWriteForTest?.();\n\t\t\tthrowIfAborted(signal);\n\t\t\tconst hashed = await this.git([\"hash-object\", \"-w\", \"--no-filters\", \"--stdin-paths\"], {\n\t\t\t\tcwd: payloadDirectory,\n\t\t\t\tinput: uniqueFiles.map((file) => file.sha256).join(\"\\n\") + (uniqueFiles.length ? \"\\n\" : \"\"),\n\t\t\t\tsignal,\n\t\t\t\tmaxOutputBytes: Math.max(1024, uniqueFiles.length * 64),\n\t\t\t});\n\t\t\tconst objectIds = hashed.stdout.toString(\"utf8\").trim().split(\"\\n\").filter(Boolean);\n\t\t\tif (objectIds.length !== uniqueFiles.length || objectIds.some((id) => !isCommitSha(id))) {\n\t\t\t\tthrow new Error(\"Git hash-object returned a malformed payload response.\");\n\t\t\t}\n\t\t\tconst objectsBySha256 = new Map(\n\t\t\t\tuniqueFiles.map((file, index) => [file.sha256, objectIds[index] as string]),\n\t\t\t);\n\t\t\tconst manifestBlob = (\n\t\t\t\tawait this.git([\"hash-object\", \"-w\", \"--stdin\"], { input: manifestBytes, signal })\n\t\t\t).stdout\n\t\t\t\t.toString(\"utf8\")\n\t\t\t\t.trim();\n\t\t\tif (!isCommitSha(manifestBlob)) throw new Error(\"Git returned an invalid manifest blob id.\");\n\t\t\tawait this.git([\"read-tree\", \"--empty\"], { env, signal });\n\t\t\tconst indexLines = [\n\t\t\t\t`100644 ${manifestBlob}\\t${this.manifestPath()}`,\n\t\t\t\t...files.map((file) => {\n\t\t\t\t\tconst object = objectsBySha256.get(file.sha256);\n\t\t\t\t\tif (!object) throw new Error(\"Git payload object is missing after hashing.\");\n\t\t\t\t\treturn `100644 ${object}\\t${this.filePath(file.path)}`;\n\t\t\t\t}),\n\t\t\t];\n\t\t\tawait this.git([\"update-index\", \"-z\", \"--index-info\"], {\n\t\t\t\tenv,\n\t\t\t\tsignal,\n\t\t\t\tinput: Buffer.from(`${indexLines.join(\"\\0\")}\\0`, \"utf8\"),\n\t\t\t});\n\t\t\tconst tree = (await this.git([\"write-tree\"], { env, signal })).stdout.toString(\"utf8\").trim();\n\t\t\tconst date = Number.isNaN(Date.parse(snapshot.createdAt))\n\t\t\t\t? new Date().toISOString()\n\t\t\t\t: snapshot.createdAt;\n\t\t\tconst commit = await this.git(\n\t\t\t\t[\"commit-tree\", tree, ...(parent ? [\"-p\", parent] : []), \"-F\", \"-\"],\n\t\t\t\t{\n\t\t\t\t\tsignal,\n\t\t\t\t\tinput: `pi-sync snapshot ${snapshot.id}\\n`,\n\t\t\t\t\tenv: {\n\t\t\t\t\t\tGIT_AUTHOR_NAME: \"pi-sync\",\n\t\t\t\t\t\tGIT_AUTHOR_EMAIL: \"pi-sync@localhost\",\n\t\t\t\t\t\tGIT_COMMITTER_NAME: \"pi-sync\",\n\t\t\t\t\t\tGIT_COMMITTER_EMAIL: \"pi-sync@localhost\",\n\t\t\t\t\t\tGIT_AUTHOR_DATE: date,\n\t\t\t\t\t\tGIT_COMMITTER_DATE: date,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t\tconst sha = commit.stdout.toString(\"utf8\").trim();\n\t\t\trequireCommitSha(sha);\n\t\t\treturn sha;\n\t\t} finally {\n\t\t\tawait fs.rm(temporaryDirectory, { recursive: true, force: true });\n\t\t}\n\t}\n\n\tprivate ensureCache(signal?: AbortSignal) {\n\t\tif (!this.cacheReady) {\n\t\t\tconst operation = withGitCacheMutation(\n\t\t\t\tthis.cacheDir,\n\t\t\t\t() => this.initializeCache(signal),\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tconst wrapped = operation.catch((error) => {\n\t\t\t\tif (this.cacheReady === wrapped) this.cacheReady = undefined;\n\t\t\t\tthrow this.redactedError(error);\n\t\t\t});\n\t\t\tthis.cacheReady = wrapped;\n\t\t}\n\t\treturn this.cacheReady;\n\t}\n\n\tprivate async initializeCache(signal?: AbortSignal) {\n\t\tconst version = await runGit([\"--version\"], {\n\t\t\tsignal,\n\t\t\ttimeoutMs: this.commandTimeoutMs,\n\t\t});\n\t\tconst versionText = version.stdout.toString(\"utf8\").trim();\n\t\tif (!isSupportedGitVersion(versionText)) {\n\t\t\tthrow new Error(\n\t\t\t\t`${versionText || \"Unknown Git version\"}; pi-sync requires Git 2.30 or newer.`,\n\t\t\t);\n\t\t}\n\t\tconst parent = path.dirname(this.cacheDir);\n\t\tconst cacheParent = path.dirname(this.cacheRoot);\n\t\tawait assertNotSymlink(cacheParent, \"Git cache parent\");\n\t\tawait assertNotSymlink(this.cacheRoot, \"Git cache root\");\n\t\tawait fs.mkdir(this.cacheRoot, { recursive: true, mode: 0o700 });\n\t\tawait assertNotSymlink(cacheParent, \"Git cache parent\");\n\t\tawait assertNotSymlink(this.cacheRoot, \"Git cache root\");\n\t\tawait assertNotSymlink(parent, \"Git cache identity directory\");\n\t\tawait fs.mkdir(parent, { recursive: true, mode: 0o700 });\n\t\tawait assertNotSymlink(parent, \"Git cache identity directory\");\n\t\tlet recreate = false;\n\t\ttry {\n\t\t\tconst stat = await fs.lstat(this.cacheDir);\n\t\t\tif (stat.isSymbolicLink()) throw new Error(\"Refusing symlinked Git cache.\");\n\t\t\tif (!stat.isDirectory()) recreate = true;\n\t\t\telse {\n\t\t\t\ttry {\n\t\t\t\t\trecreate = !(await this.cacheUsesSha1(signal));\n\t\t\t\t} catch {\n\t\t\t\t\tthrowIfAborted(signal);\n\t\t\t\t\trecreate = true;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n\t\t}\n\t\tthrowIfAborted(signal);\n\t\tif (recreate) await fs.rm(this.cacheDir, { recursive: true, force: true });\n\t\ttry {\n\t\t\tawait fs.access(this.cacheDir);\n\t\t} catch {\n\t\t\ttry {\n\t\t\t\tawait runGit([\"init\", \"--bare\", \"--object-format=sha1\", this.cacheDir], {\n\t\t\t\t\tsignal,\n\t\t\t\t\ttimeoutMs: this.commandTimeoutMs,\n\t\t\t\t\tallowFileProtocol: this.allowLocalRemotes,\n\t\t\t\t});\n\t\t\t} catch (initError) {\n\t\t\t\tconst concurrent = await this.cacheUsesSha1(signal).catch(() => false);\n\t\t\t\tif (!concurrent) throw initError;\n\t\t\t}\n\t\t}\n\t\tif (process.platform !== \"win32\") await fs.chmod(parent, 0o700);\n\t}\n\n\tprivate async cacheUsesSha1(signal?: AbortSignal) {\n\t\tconst result = await this.git([\"rev-parse\", \"--is-bare-repository\", \"--show-object-format\"], {\n\t\t\tsignal,\n\t\t});\n\t\treturn result.stdout.toString(\"utf8\").trim() === \"true\\nsha1\";\n\t}\n\n\tprivate git(\n\t\targs: string[],\n\t\toptions: {\n\t\t\tcwd?: string;\n\t\t\tinput?: Buffer | string;\n\t\t\tenv?: NodeJS.ProcessEnv;\n\t\t\tsignal?: AbortSignal;\n\t\t\ttimeoutMs?: number;\n\t\t\tmaxOutputBytes?: number;\n\t\t} = {},\n\t) {\n\t\treturn runGit(args, {\n\t\t\tgitDir: this.cacheDir,\n\t\t\tallowFileProtocol: this.allowLocalRemotes,\n\t\t\ttimeoutMs: options.timeoutMs ?? this.commandTimeoutMs,\n\t\t\t...options,\n\t\t}).catch((error) => {\n\t\t\tthrow this.redactedError(error);\n\t\t});\n\t}\n\n\tprivate remoteRef() {\n\t\treturn `refs/heads/${this.config.destination.branch}`;\n\t}\n\n\tprivate publicationPath() {\n\t\treturn this.config.destination.directory === \"./\" ? \"\" : this.config.destination.directory;\n\t}\n\n\tprivate manifestPath() {\n\t\treturn posixJoin(this.publicationPath(), \"manifest.json\");\n\t}\n\n\tprivate filePath(filePath: string) {\n\t\treturn posixJoin(this.publicationPath(), \"files\", filePath);\n\t}\n\n\tprivate async readPublication(commit: string, signal?: AbortSignal) {\n\t\tconst manifest = await this.readManifest(commit, signal);\n\t\tconst entries = await this.readPublicationTree(commit, signal);\n\t\tconst payloadEntries = validateGitPublicationTree(\n\t\t\tentries,\n\t\t\tmanifest,\n\t\t\tthis.manifestPath(),\n\t\t\t(filePath) => this.filePath(filePath),\n\t\t);\n\t\treturn { manifest, payloadEntries };\n\t}\n\n\tprivate async readPublicationTree(commit: string, signal?: AbortSignal) {\n\t\tconst result = await this.git([\"ls-tree\", \"-r\", \"-z\", commit], {\n\t\t\tsignal,\n\t\t\tmaxOutputBytes: MAX_GIT_TREE_OUTPUT_BYTES,\n\t\t});\n\t\treturn parseGitTree(result.stdout);\n\t}\n\n\tprivate redactedError(error: unknown) {\n\t\tif (error instanceof Error && error.name === \"AbortError\") return error;\n\t\treturn new Error(this.safeError(error));\n\t}\n\n\tprivate safeError(error: unknown) {\n\t\tconst raw =\n\t\t\terror instanceof GitCommandError\n\t\t\t\t? error.stderr || error.message\n\t\t\t\t: error instanceof Error\n\t\t\t\t\t? error.message\n\t\t\t\t\t: String(error);\n\t\treturn redactGitError(raw, this.config.profile.remote, this.cacheDir);\n\t}\n}\n\nexport function gitBackendIdentity(config: ResolvedGitBackend) {\n\tlet remoteIdentity: string;\n\ttry {\n\t\tremoteIdentity = normalizeGitRemoteIdentity(config.profile.remote);\n\t} catch {\n\t\tremoteIdentity = config.profile.remote;\n\t}\n\tconst canonical = JSON.stringify([\n\t\tremoteIdentity,\n\t\tconfig.destination.branch,\n\t\tconfig.destination.directory,\n\t]);\n\treturn `git:${sha256(Buffer.from(canonical))}`;\n}\n\nfunction gitDestination(config: ResolvedGitBackend) {\n\tlet host = \"Git remote\";\n\tconst remote = config.profile.remote;\n\tif (remote.includes(\"://\")) {\n\t\ttry {\n\t\t\thost = new URL(remote).host;\n\t\t} catch {\n\t\t\thost = \"Git remote\";\n\t\t}\n\t} else {\n\t\tconst match = /^(?:[^@]+@)?(?<host>\\[[^\\]]+\\]|[^:]+):/u.exec(remote);\n\t\tif (match?.groups?.host) host = match.groups.host;\n\t}\n\treturn `${host} \u00B7 ${config.destination.branch}:${config.destination.directory}`;\n}\n\nfunction remoteHead(sha: string, manifest: GitManifest, identity: string): RemoteHead {\n\treturn {\n\t\tsnapshotRef: sha,\n\t\tsnapshotId: manifest.snapshotId,\n\t\trevision: `${identity}:${sha}`,\n\t\tcreatedAt: manifest.createdAt,\n\t\tmachine: manifest.machine,\n\t\tsyncSessions: manifest.syncSessions,\n\t\t...(manifest.selection === undefined ? {} : { selection: manifest.selection }),\n\t};\n}\n\nfunction matchesExpected(\n\tcurrent: string | undefined,\n\texpected: ExpectedRemoteHead,\n\tidentity: string,\n) {\n\tif (expected.kind === \"missing\") return current === undefined;\n\ttry {\n\t\treturn current === decodeRevision(expected.revision, identity);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction decodeRevision(revision: string, identity: string) {\n\tconst prefix = `${identity}:`;\n\tconst sha = revision.startsWith(prefix) ? revision.slice(prefix.length) : \"\";\n\tif (!/^[0-9a-f]{40}$/u.test(sha)) throw new Error(\"Invalid Git remote revision.\");\n\treturn sha;\n}\n\nfunction isCommitSha(value: string) {\n\treturn /^[0-9a-f]{40}$/u.test(value);\n}\n\nfunction requireCommitSha(value: string) {\n\tif (/^[0-9a-f]{64}$/u.test(value)) {\n\t\tthrow new Error(\"Unsupported Git SHA-256 repository; pi-sync currently requires SHA-1 refs.\");\n\t}\n\tif (!/^[0-9a-f]{40}$/u.test(value)) throw new Error(\"Invalid Git publication reference.\");\n}\n\nexport function isSupportedGitVersion(value: string) {\n\tconst match = /git version (\\d+)\\.(\\d+)/u.exec(value);\n\tif (!match) return false;\n\tconst major = Number(match[1]);\n\tconst minor = Number(match[2]);\n\treturn major > 2 || (major === 2 && minor >= 30);\n}\n\nfunction assertGitDestination(config: ResolvedGitBackend) {\n\ttry {\n\t\tif (\n\t\t\tnormalizeGitBranch(config.destination.branch) !== config.destination.branch ||\n\t\t\tnormalizeGitDirectory(config.destination.directory) !== config.destination.directory\n\t\t) {\n\t\t\tthrow new Error(\"Git storage location is not normalized.\");\n\t\t}\n\t\tvalidateGitNamespace(config.destination.namespace);\n\t} catch (error) {\n\t\tthrow new Error(\"Invalid Git storage location.\", { cause: error });\n\t}\n}\n\nfunction assertProductionRemote(remote: string) {\n\tlet normalized: string | undefined;\n\ttry {\n\t\tnormalized = normalizeGitRemote(remote);\n\t} catch (error) {\n\t\tthrow new Error(error instanceof Error ? error.message : \"Invalid Git remote.\", {\n\t\t\tcause: error,\n\t\t});\n\t}\n\tif (!normalized || normalized !== remote)\n\t\tthrow new Error(\"Invalid or non-normalized Git remote.\");\n}\n\nasync function withGitCacheMutation<T>(\n\tcacheDir: string,\n\trun: () => Promise<T>,\n\tsignal?: AbortSignal,\n): Promise<T> {\n\tconst previous = gitCacheMutationQueues.get(cacheDir) ?? Promise.resolve();\n\tlet started = false;\n\tconst operation = previous\n\t\t.catch(() => undefined)\n\t\t.then(() => {\n\t\t\tthrowIfAborted(signal);\n\t\t\tstarted = true;\n\t\t\treturn run();\n\t\t});\n\tconst tail = operation.then(\n\t\t() => undefined,\n\t\t() => undefined,\n\t);\n\tgitCacheMutationQueues.set(cacheDir, tail);\n\tvoid tail.then(() => {\n\t\tif (gitCacheMutationQueues.get(cacheDir) === tail) gitCacheMutationQueues.delete(cacheDir);\n\t});\n\tif (!signal) return operation;\n\tthrowIfAborted(signal);\n\tlet rejectAbort: ((reason: unknown) => void) | undefined;\n\tconst aborted = new Promise<never>((_resolve, reject) => {\n\t\trejectAbort = reject;\n\t});\n\tconst onAbort = () => rejectAbort?.(abortReason(signal));\n\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\tif (signal.aborted) onAbort();\n\ttry {\n\t\treturn await Promise.race([operation, aborted]);\n\t} catch (error) {\n\t\t// A queued job can cancel immediately, but a running job owns a child/cache\n\t\t// mutation. Drain its bounded cleanup before releasing outer sync guards.\n\t\tif (started) await tail;\n\t\tthrow error;\n\t} finally {\n\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t}\n}\n\nasync function assertNotSymlink(target: string, label: string) {\n\ttry {\n\t\tconst stat = await fs.lstat(target);\n\t\tif (stat.isSymbolicLink()) throw new Error(`Refusing symlinked ${label}.`);\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n\t}\n}\n\nfunction redactGitError(value: string, remote: string, cacheDir: string) {\n\treturn (\n\t\tvalue\n\t\t\t.replaceAll(remote, \"<git-remote>\")\n\t\t\t.replaceAll(cacheDir, \"<git-cache>\")\n\t\t\t.replace(/https:\\/\\/[^/@\\s]+@/gu, \"https://<credentials>@\")\n\t\t\t.replace(/\\b(password|token|authorization)=\\S+/giu, \"$1=<redacted>\")\n\t\t\t.replace(/\\bBearer\\s+\\S+/giu, \"Bearer <redacted>\")\n\t\t\t// biome-ignore lint/suspicious/noControlCharactersInRegex: sanitize untrusted process output.\n\t\t\t.replace(/[\\u0000-\\u001f\\u007f-\\u009f]/gu, \" \")\n\t\t\t.trim()\n\t\t\t.slice(0, 4096)\n\t);\n}\n\nfunction sha256(value: Buffer) {\n\treturn createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\nfunction abortReason(signal: AbortSignal) {\n\treturn signal.reason instanceof Error\n\t\t? signal.reason\n\t\t: new DOMException(\"The operation was aborted\", \"AbortError\");\n}\n\nfunction throwIfAborted(signal?: AbortSignal) {\n\tif (signal?.aborted) throw abortReason(signal);\n}\n", "import { spawn } from \"node:child_process\";\nimport process from \"node:process\";\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_OUTPUT_LIMIT = 1024 * 1024;\n\nexport interface GitRunOptions {\n\tgitDir?: string;\n\tcwd?: string;\n\tinput?: Buffer | string;\n\tenv?: NodeJS.ProcessEnv;\n\tsignal?: AbortSignal;\n\ttimeoutMs?: number;\n\tmaxOutputBytes?: number;\n\tallowFileProtocol?: boolean;\n}\n\nexport interface GitRunResult {\n\tstdout: Buffer;\n\tstderr: Buffer;\n}\n\nexport class GitCommandError extends Error {\n\treadonly code = \"GIT_COMMAND_FAILED\";\n\tconstructor(\n\t\tmessage: string,\n\t\treadonly exitCode: number | null,\n\t\treadonly stderr: string,\n\t\toptions?: ErrorOptions,\n\t) {\n\t\tsuper(message, options);\n\t\tthis.name = \"GitCommandError\";\n\t}\n}\n\nexport async function runGit(args: string[], options: GitRunOptions = {}): Promise<GitRunResult> {\n\tthrowIfAborted(options.signal);\n\tconst hooksPath = process.platform === \"win32\" ? \"NUL\" : \"/dev/null\";\n\tconst protocolArgs = [\n\t\t\"-c\",\n\t\t`core.hooksPath=${hooksPath}`,\n\t\t\"-c\",\n\t\t\"gc.auto=0\",\n\t\t\"-c\",\n\t\t\"maintenance.auto=false\",\n\t\t\"-c\",\n\t\t\"protocol.allow=never\",\n\t\t\"-c\",\n\t\t\"protocol.https.allow=always\",\n\t\t\"-c\",\n\t\t\"protocol.ssh.allow=always\",\n\t];\n\tif (options.allowFileProtocol) protocolArgs.push(\"-c\", \"protocol.file.allow=always\");\n\tconst commandArgs = [\n\t\t...(options.gitDir ? [`--git-dir=${options.gitDir}`] : []),\n\t\t...protocolArgs,\n\t\t...args,\n\t];\n\tconst inheritedEnvironment = Object.fromEntries(\n\t\tObject.entries(process.env).filter(\n\t\t\t([key]) =>\n\t\t\t\t!key.startsWith(\"GIT_\") &&\n\t\t\t\tkey !== \"PAGER\" &&\n\t\t\t\tkey !== \"EDITOR\" &&\n\t\t\t\tkey !== \"VISUAL\" &&\n\t\t\t\tkey !== \"SSH_ASKPASS\" &&\n\t\t\t\tkey !== \"SSH_ASKPASS_REQUIRE\",\n\t\t),\n\t);\n\tconst allowedGitOverrides = new Set([\n\t\t\"GIT_INDEX_FILE\",\n\t\t\"GIT_AUTHOR_NAME\",\n\t\t\"GIT_AUTHOR_EMAIL\",\n\t\t\"GIT_AUTHOR_DATE\",\n\t\t\"GIT_COMMITTER_NAME\",\n\t\t\"GIT_COMMITTER_EMAIL\",\n\t\t\"GIT_COMMITTER_DATE\",\n\t]);\n\tconst suppliedEnvironment = Object.fromEntries(\n\t\tObject.entries(options.env ?? {}).filter(\n\t\t\t([key]) => !key.startsWith(\"GIT_\") || allowedGitOverrides.has(key),\n\t\t),\n\t);\n\tconst env: NodeJS.ProcessEnv = {\n\t\t...inheritedEnvironment,\n\t\t...suppliedEnvironment,\n\t\tLC_ALL: \"C\",\n\t\tLANG: \"C\",\n\t\tGIT_CONFIG_NOSYSTEM: \"1\",\n\t\tGIT_TERMINAL_PROMPT: \"0\",\n\t\tGCM_INTERACTIVE: \"Never\",\n\t\tGIT_PAGER: \"cat\",\n\t\tPAGER: \"cat\",\n\t\tGIT_EDITOR: \"true\",\n\t\tEDITOR: \"true\",\n\t\tVISUAL: \"true\",\n\t\tGIT_ASKPASS: \"\",\n\t\tSSH_ASKPASS: \"\",\n\t\tSSH_ASKPASS_REQUIRE: \"never\",\n\t\tGIT_SSH_COMMAND: \"ssh -oBatchMode=yes\",\n\t};\n\tconst child = spawn(\"git\", commandArgs, {\n\t\tcwd: options.cwd,\n\t\tenv,\n\t\tstdio: [\"pipe\", \"pipe\", \"pipe\"],\n\t\tdetached: process.platform !== \"win32\",\n\t\twindowsHide: true,\n\t});\n\tconst stdout: Buffer[] = [];\n\tconst stderr: Buffer[] = [];\n\tlet total = 0;\n\tlet settled = false;\n\tlet terminationError: Error | undefined;\n\tlet escalationTimer: NodeJS.Timeout | undefined;\n\tconst limit = options.maxOutputBytes ?? DEFAULT_OUTPUT_LIMIT;\n\n\tconst terminate = (error: Error) => {\n\t\tif (settled || terminationError) return;\n\t\tterminationError = error;\n\t\tif (child.pid && process.platform !== \"win32\") {\n\t\t\ttry {\n\t\t\t\tprocess.kill(-child.pid, \"SIGTERM\");\n\t\t\t} catch {\n\t\t\t\tchild.kill(\"SIGTERM\");\n\t\t\t}\n\t\t} else {\n\t\t\tchild.kill(\"SIGTERM\");\n\t\t\tif (child.pid && process.platform === \"win32\") {\n\t\t\t\tconst killer = spawn(\"taskkill\", [\"/pid\", String(child.pid), \"/t\", \"/f\"], {\n\t\t\t\t\tstdio: \"ignore\",\n\t\t\t\t\twindowsHide: true,\n\t\t\t\t});\n\t\t\t\tkiller.on(\"error\", () => undefined);\n\t\t\t\tkiller.unref();\n\t\t\t}\n\t\t}\n\t\tescalationTimer = setTimeout(() => {\n\t\t\tif (settled) return;\n\t\t\tif (child.pid && process.platform !== \"win32\") {\n\t\t\t\ttry {\n\t\t\t\t\tprocess.kill(-child.pid, \"SIGKILL\");\n\t\t\t\t} catch {\n\t\t\t\t\tchild.kill(\"SIGKILL\");\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tchild.kill(\"SIGKILL\");\n\t\t\t}\n\t\t}, 2_000);\n\t};\n\tconst collect = (target: Buffer[]) => (chunk: Buffer) => {\n\t\ttotal += chunk.byteLength;\n\t\tif (total > limit) {\n\t\t\tterminate(new Error(`Git output exceeds the ${limit}-byte limit.`));\n\t\t\treturn;\n\t\t}\n\t\ttarget.push(Buffer.from(chunk));\n\t};\n\tchild.stdout.on(\"data\", collect(stdout));\n\tchild.stderr.on(\"data\", collect(stderr));\n\tchild.stdin.on(\"error\", () => undefined);\n\tchild.stdin.end(options.input);\n\tconst onAbort = () =>\n\t\tterminate(\n\t\t\toptions.signal?.reason instanceof Error\n\t\t\t\t? options.signal.reason\n\t\t\t\t: new DOMException(\"The operation was aborted\", \"AbortError\"),\n\t\t);\n\toptions.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\tconst timer = setTimeout(\n\t\t() =>\n\t\t\tterminate(\n\t\t\t\tnew Error(`Git command timed out after ${options.timeoutMs ?? DEFAULT_TIMEOUT_MS}ms.`),\n\t\t\t),\n\t\toptions.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n\t);\n\n\tlet result: GitRunResult;\n\ttry {\n\t\tresult = await new Promise<GitRunResult>((resolve, reject) => {\n\t\t\tchild.once(\"error\", reject);\n\t\t\tchild.once(\"close\", (code) => {\n\t\t\t\tsettled = true;\n\t\t\t\tif (escalationTimer) clearTimeout(escalationTimer);\n\t\t\t\tconst stdoutBuffer = Buffer.concat(stdout);\n\t\t\t\tconst stderrBuffer = Buffer.concat(stderr);\n\t\t\t\tif (terminationError) {\n\t\t\t\t\treject(terminationError);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (code !== 0) {\n\t\t\t\t\tconst stderrText = stderrBuffer.toString(\"utf8\").trim();\n\t\t\t\t\treject(\n\t\t\t\t\t\tnew GitCommandError(\n\t\t\t\t\t\t\tstderrText || `Git exited with status ${code ?? \"unknown\"}.`,\n\t\t\t\t\t\t\tcode,\n\t\t\t\t\t\t\tstderrText,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tresolve({ stdout: stdoutBuffer, stderr: stderrBuffer });\n\t\t\t});\n\t\t});\n\t} finally {\n\t\tclearTimeout(timer);\n\t\tif (escalationTimer) clearTimeout(escalationTimer);\n\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t}\n\treturn result;\n}\n\nexport function parseGitBlobBatch(output: Buffer, expectedCount: number, maxContentBytes: number) {\n\tif (!Number.isSafeInteger(expectedCount) || expectedCount < 0) {\n\t\tthrow new Error(\"Invalid Git batch object count.\");\n\t}\n\tif (!Number.isSafeInteger(maxContentBytes) || maxContentBytes < 0) {\n\t\tthrow new Error(\"Invalid Git batch content limit.\");\n\t}\n\tconst blobs: Buffer[] = [];\n\tlet offset = 0;\n\tlet contentBytes = 0;\n\tfor (let index = 0; index < expectedCount; index += 1) {\n\t\tconst headerEnd = output.indexOf(0x0a, offset);\n\t\tif (headerEnd < 0) throw new Error(\"Git cat-file batch response is truncated.\");\n\t\tconst header = output.subarray(offset, headerEnd).toString(\"utf8\");\n\t\tif (header.endsWith(\" missing\")) throw new Error(\"Git cat-file batch object is missing.\");\n\t\tconst match = /^(?<object>[0-9a-f]{40}) blob (?<size>0|[1-9][0-9]*)$/u.exec(header);\n\t\tif (!match?.groups) throw new Error(\"Git cat-file batch response is malformed.\");\n\t\tconst size = Number(match.groups.size);\n\t\tif (!Number.isSafeInteger(size)) throw new Error(\"Git cat-file batch size is malformed.\");\n\t\tcontentBytes += size;\n\t\tif (contentBytes > maxContentBytes) {\n\t\t\tthrow new Error(`Git cat-file batch content exceeds the ${maxContentBytes}-byte limit.`);\n\t\t}\n\t\tconst contentStart = headerEnd + 1;\n\t\tconst contentEnd = contentStart + size;\n\t\tif (contentEnd >= output.length) throw new Error(\"Git cat-file batch response is truncated.\");\n\t\tif (output[contentEnd] !== 0x0a) {\n\t\t\tthrow new Error(\"Git cat-file batch response is malformed.\");\n\t\t}\n\t\tblobs.push(Buffer.from(output.subarray(contentStart, contentEnd)));\n\t\toffset = contentEnd + 1;\n\t}\n\tif (offset !== output.length) throw new Error(\"Git cat-file batch response has trailing data.\");\n\treturn blobs;\n}\n\nexport async function readGitBlobs(\n\tobjects: string[],\n\toptions: Omit<GitRunOptions, \"input\" | \"maxOutputBytes\"> & { maxOutputBytes: number },\n) {\n\tif (objects.length === 0) return [];\n\tif (!Number.isSafeInteger(options.maxOutputBytes) || options.maxOutputBytes < 0) {\n\t\tthrow new Error(\"Invalid Git batch output limit.\");\n\t}\n\tif (objects.some((object) => !/^[0-9a-f]{40}$/u.test(object))) {\n\t\tthrow new Error(\"Invalid Git blob object id.\");\n\t}\n\tconst protocolOverhead = objects.length * 96;\n\tif (!Number.isSafeInteger(protocolOverhead + options.maxOutputBytes)) {\n\t\tthrow new Error(\"Invalid Git batch output limit.\");\n\t}\n\tconst result = await runGit([\"cat-file\", \"--batch\"], {\n\t\t...options,\n\t\tinput: `${objects.join(\"\\n\")}\\n`,\n\t\tmaxOutputBytes: options.maxOutputBytes + protocolOverhead,\n\t});\n\treturn parseGitBlobBatch(result.stdout, objects.length, options.maxOutputBytes);\n}\n\nfunction throwIfAborted(signal?: AbortSignal) {\n\tif (!signal?.aborted) return;\n\tthrow signal.reason instanceof Error\n\t\t? signal.reason\n\t\t: new DOMException(\"The operation was aborted\", \"AbortError\");\n}\n", "import { createHash } from \"node:crypto\";\nimport type { Snapshot, SnapshotSelection } from \"../../snapshot/snapshot-types.js\";\nimport { portableSnapshotSelection, snapshotSelectionInclude } from \"../../sync/sync-policy.js\";\n\nexport const GIT_MANIFEST_VERSION = 2;\nexport const MAX_GIT_MANIFEST_BYTES = 1024 * 1024;\nexport const MAX_GIT_TREE_OUTPUT_BYTES = 16 * 1024 * 1024;\nexport const MAX_GIT_PAYLOAD_BYTES = 100 * 1024 * 1024;\nexport const MAX_GIT_SNAPSHOT_BYTES = 512 * 1024 * 1024;\nconst SNAPSHOT_VERSION = 1;\n\nexport interface GitManifestFile {\n\tpath: string;\n\tsha256: string;\n\tsize: number;\n}\n\nexport interface GitManifest {\n\tversion: number;\n\tsnapshotVersion: number;\n\tsnapshotId: string;\n\tcreatedAt: string;\n\tmachine: string;\n\tprofile: string;\n\tsyncSessions: boolean;\n\tsnapshotSyncSessions?: boolean;\n\tselection?: SnapshotSelection;\n\tfiles: GitManifestFile[];\n}\n\nexport interface PreparedGitFile extends GitManifestFile {\n\tcontent: Buffer;\n}\n\nexport interface GitTreeEntry {\n\tmode: string;\n\ttype: string;\n\tobject: string;\n\tpath: string;\n}\n\nexport function isGitPayloadSizeAllowed(size: number) {\n\treturn Number.isSafeInteger(size) && size >= 0 && size <= MAX_GIT_PAYLOAD_BYTES;\n}\n\nexport function requireGitManifest(value: unknown): GitManifest {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) {\n\t\tthrow new Error(\"Git publication manifest is malformed.\");\n\t}\n\tconst manifest = value as Partial<GitManifest>;\n\tif (manifest.version === 1) {\n\t\tthrow new Error(\n\t\t\t\"Git publication uses the unsupported pre-release gzip format; recreate this pi-sync-owned test branch.\",\n\t\t);\n\t}\n\tif (\n\t\tmanifest.version !== GIT_MANIFEST_VERSION ||\n\t\tmanifest.snapshotVersion !== SNAPSHOT_VERSION ||\n\t\ttypeof manifest.snapshotId !== \"string\" ||\n\t\tmanifest.snapshotId.length > 512 ||\n\t\t!/^[A-Za-z0-9._-]+$/u.test(manifest.snapshotId) ||\n\t\ttypeof manifest.createdAt !== \"string\" ||\n\t\tmanifest.createdAt.length > 64 ||\n\t\thasControlCharacter(manifest.createdAt) ||\n\t\tNumber.isNaN(Date.parse(manifest.createdAt)) ||\n\t\ttypeof manifest.machine !== \"string\" ||\n\t\tmanifest.machine.length > 256 ||\n\t\thasControlCharacter(manifest.machine) ||\n\t\ttypeof manifest.profile !== \"string\" ||\n\t\tmanifest.profile.length === 0 ||\n\t\tmanifest.profile.length > 256 ||\n\t\thasControlCharacter(manifest.profile) ||\n\t\ttypeof manifest.syncSessions !== \"boolean\" ||\n\t\t(manifest.snapshotSyncSessions !== undefined &&\n\t\t\ttypeof manifest.snapshotSyncSessions !== \"boolean\") ||\n\t\t!Array.isArray(manifest.files) ||\n\t\t!hasExactKeys(manifest as Record<string, unknown>, [\n\t\t\t\"version\",\n\t\t\t\"snapshotVersion\",\n\t\t\t\"snapshotId\",\n\t\t\t\"createdAt\",\n\t\t\t\"machine\",\n\t\t\t\"profile\",\n\t\t\t\"syncSessions\",\n\t\t\t...(manifest.snapshotSyncSessions === undefined ? [] : [\"snapshotSyncSessions\"]),\n\t\t\t...(manifest.selection === undefined ? [] : [\"selection\"]),\n\t\t\t\"files\",\n\t\t])\n\t) {\n\t\tthrow new Error(\"Git publication manifest is malformed.\");\n\t}\n\tif (manifest.selection !== undefined) portableSnapshotSelection(manifest.selection);\n\tlet total = 0;\n\tconst paths = new Set<string>();\n\tfor (const rawFile of manifest.files) {\n\t\tif (!rawFile || typeof rawFile !== \"object\" || Array.isArray(rawFile)) {\n\t\t\tthrow new Error(\"Git publication manifest file is malformed.\");\n\t\t}\n\t\tconst file = rawFile as Partial<GitManifestFile>;\n\t\tif (\n\t\t\t!hasExactKeys(file as Record<string, unknown>, [\"path\", \"sha256\", \"size\"]) ||\n\t\t\t!isSafeSnapshotPath(file.path) ||\n\t\t\ttypeof file.sha256 !== \"string\" ||\n\t\t\t!/^[0-9a-f]{64}$/u.test(file.sha256) ||\n\t\t\ttypeof file.size !== \"number\" ||\n\t\t\t!isGitPayloadSizeAllowed(file.size) ||\n\t\t\tpaths.has(file.path)\n\t\t) {\n\t\t\tthrow new Error(\"Git publication manifest file is malformed.\");\n\t\t}\n\t\ttotal += file.size;\n\t\tif (!Number.isSafeInteger(total) || total > MAX_GIT_SNAPSHOT_BYTES) {\n\t\t\tthrow new Error(`Git snapshot content exceeds the ${MAX_GIT_SNAPSHOT_BYTES}-byte limit.`);\n\t\t}\n\t\tpaths.add(file.path);\n\t}\n\tassertNoPathConflicts([...paths]);\n\treturn manifest as GitManifest;\n}\n\nexport function validateGitSnapshot(snapshot: Snapshot, manifest: GitManifest, namespace: string) {\n\tconst prepared = prepareGitSnapshot(snapshot, namespace);\n\tconst syncSessions =\n\t\tsnapshot.syncSessions === true ||\n\t\tsnapshot.files.some((file) => file.path.startsWith(\"sessions/\"));\n\tif (\n\t\tsnapshot.id !== manifest.snapshotId ||\n\t\tsnapshot.createdAt !== manifest.createdAt ||\n\t\tsnapshot.machine !== manifest.machine ||\n\t\tsnapshot.profile !== manifest.profile ||\n\t\tsnapshot.syncSessions !== manifest.snapshotSyncSessions ||\n\t\tsyncSessions !== manifest.syncSessions ||\n\t\t!sameOptionalInclude(\n\t\t\tsnapshotSelectionInclude(snapshot),\n\t\t\tmanifest.selection === undefined\n\t\t\t\t? undefined\n\t\t\t\t: portableSnapshotSelection(manifest.selection).include,\n\t\t) ||\n\t\tprepared.length !== manifest.files.length ||\n\t\tprepared.some((file, index) => {\n\t\t\tconst expected = manifest.files[index];\n\t\t\treturn (\n\t\t\t\t!expected ||\n\t\t\t\tfile.path !== expected.path ||\n\t\t\t\tfile.sha256 !== expected.sha256 ||\n\t\t\t\tfile.size !== expected.size\n\t\t\t);\n\t\t})\n\t) {\n\t\tthrow new Error(\"Git snapshot identity does not match its publication manifest.\");\n\t}\n}\n\nexport function prepareGitSnapshot(snapshot: Snapshot, namespace: string) {\n\tsnapshotSelectionInclude(snapshot);\n\tif (\n\t\tsnapshot.version !== SNAPSHOT_VERSION ||\n\t\ttypeof snapshot.id !== \"string\" ||\n\t\t!snapshot.id ||\n\t\tsnapshot.id.length > 512 ||\n\t\t!/^[A-Za-z0-9._-]+$/u.test(snapshot.id) ||\n\t\tsnapshot.profile !== namespace ||\n\t\t!Array.isArray(snapshot.files) ||\n\t\ttypeof snapshot.createdAt !== \"string\" ||\n\t\t!snapshot.createdAt ||\n\t\tsnapshot.createdAt.length > 64 ||\n\t\thasControlCharacter(snapshot.createdAt) ||\n\t\tNumber.isNaN(Date.parse(snapshot.createdAt)) ||\n\t\ttypeof snapshot.machine !== \"string\" ||\n\t\tsnapshot.machine.length > 256 ||\n\t\thasControlCharacter(snapshot.machine)\n\t) {\n\t\tthrow new Error(\"Invalid Git snapshot publication.\");\n\t}\n\tconst paths = new Set<string>();\n\tconst prepared: PreparedGitFile[] = [];\n\tlet total = 0;\n\tfor (const file of snapshot.files) {\n\t\tif (\n\t\t\t!isSafeSnapshotPath(file.path) ||\n\t\t\ttypeof file.contentBase64 !== \"string\" ||\n\t\t\ttypeof file.sha256 !== \"string\" ||\n\t\t\t!/^[0-9a-f]{64}$/u.test(file.sha256) ||\n\t\t\tpaths.has(file.path)\n\t\t) {\n\t\t\tthrow new Error(\"Invalid Git snapshot file.\");\n\t\t}\n\t\tconst content = Buffer.from(file.contentBase64, \"base64\");\n\t\tif (content.toString(\"base64\") !== file.contentBase64 || sha256(content) !== file.sha256) {\n\t\t\tthrow new Error(\"Git snapshot file checksum mismatch.\");\n\t\t}\n\t\tif (!isGitPayloadSizeAllowed(content.byteLength)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Git snapshot file exceeds GitHub's ${MAX_GIT_PAYLOAD_BYTES}-byte regular-Git limit: ${file.path}`,\n\t\t\t);\n\t\t}\n\t\ttotal += content.byteLength;\n\t\tif (!Number.isSafeInteger(total) || total > MAX_GIT_SNAPSHOT_BYTES) {\n\t\t\tthrow new Error(`Git snapshot content exceeds the ${MAX_GIT_SNAPSHOT_BYTES}-byte limit.`);\n\t\t}\n\t\tpaths.add(file.path);\n\t\tprepared.push({ path: file.path, sha256: file.sha256, size: content.byteLength, content });\n\t}\n\tassertNoPathConflicts([...paths]);\n\treturn prepared;\n}\n\nexport function parseGitTree(output: Buffer): GitTreeEntry[] {\n\tif (output.byteLength === 0) return [];\n\tif (output.at(-1) !== 0) throw new Error(\"Git publication tree response is malformed.\");\n\treturn output\n\t\t.subarray(0, -1)\n\t\t.toString(\"utf8\")\n\t\t.split(\"\\0\")\n\t\t.map((line) => {\n\t\t\tconst match =\n\t\t\t\t/^(?<mode>[0-9]{6}) (?<type>blob|tree|commit) (?<object>[0-9a-f]{40})\\t(?<path>.+)$/u.exec(\n\t\t\t\t\tline,\n\t\t\t\t);\n\t\t\tif (!match?.groups || hasControlCharacter(match.groups.path)) {\n\t\t\t\tthrow new Error(\"Git publication tree response is malformed.\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tmode: match.groups.mode,\n\t\t\t\ttype: match.groups.type,\n\t\t\t\tobject: match.groups.object,\n\t\t\t\tpath: match.groups.path,\n\t\t\t};\n\t\t});\n}\n\nexport function validateGitPublicationTree(\n\tentries: GitTreeEntry[],\n\tmanifest: GitManifest,\n\tmanifestPath: string,\n\tfilePath: (path: string) => string,\n) {\n\tconst byPath = new Map<string, GitTreeEntry>();\n\tfor (const entry of entries) {\n\t\tif (byPath.has(entry.path)) throw new Error(\"Git publication tree contains duplicate paths.\");\n\t\tbyPath.set(entry.path, entry);\n\t}\n\tconst expectedPaths = [manifestPath, ...manifest.files.map((file) => filePath(file.path))];\n\tif (entries.length !== expectedPaths.length || expectedPaths.some((path) => !byPath.has(path))) {\n\t\tthrow new Error(\"Git publication tree has missing or extra files.\");\n\t}\n\tfor (const expectedPath of expectedPaths) {\n\t\tconst entry = byPath.get(expectedPath);\n\t\tif (entry?.mode !== \"100644\" || entry.type !== \"blob\") {\n\t\t\tthrow new Error(`Git publication tree contains a non-regular file: ${expectedPath}`);\n\t\t}\n\t}\n\treturn manifest.files.map((file) => byPath.get(filePath(file.path)) as GitTreeEntry);\n}\n\nfunction sameOptionalInclude(left: string[] | undefined, right: string[] | undefined) {\n\tif (!left || !right) return left === right;\n\treturn left.length === right.length && left.every((item, index) => item === right[index]);\n}\n\nfunction isSafeSnapshotPath(value: unknown): value is string {\n\treturn (\n\t\ttypeof value === \"string\" &&\n\t\tvalue.length > 0 &&\n\t\tvalue.length <= 4096 &&\n\t\t!value.startsWith(\"/\") &&\n\t\t!value.includes(\"\\\\\") &&\n\t\t!hasControlCharacter(value) &&\n\t\tvalue\n\t\t\t.split(\"/\")\n\t\t\t.every(\n\t\t\t\t(segment) =>\n\t\t\t\t\tsegment && segment !== \".\" && segment !== \"..\" && segment.toLowerCase() !== \".git\",\n\t\t\t)\n\t);\n}\n\nfunction hasExactKeys(value: Record<string, unknown>, expected: string[]) {\n\tconst keys = Object.keys(value).sort();\n\tconst expectedKeys = [...expected].sort();\n\treturn (\n\t\tkeys.length === expectedKeys.length && keys.every((key, index) => key === expectedKeys[index])\n\t);\n}\n\nfunction assertNoPathConflicts(paths: string[]) {\n\tconst sorted = [...paths].sort();\n\tfor (let index = 1; index < sorted.length; index += 1) {\n\t\tconst parent = sorted[index - 1];\n\t\tconst child = sorted[index];\n\t\tif (parent && child?.startsWith(`${parent}/`)) {\n\t\t\tthrow new Error(`Git snapshot file path conflict: ${parent} and ${child}`);\n\t\t}\n\t}\n}\n\nfunction sha256(value: Buffer) {\n\treturn createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\nfunction hasControlCharacter(value: string) {\n\t// biome-ignore lint/suspicious/noControlCharactersInRegex: Reject untrusted terminal/ref controls.\n\treturn /[\\u0000-\\u001f\\u007f-\\u009f]/u.test(value);\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["createHash", "process", "path", "throwIfAborted", "sha256", "createHash"]
7
+ }
@@ -0,0 +1,22 @@
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
+ dispatchManagerResult
5
+ } from "./chunk-X5OM6GXT.ts";
6
+ import "./chunk-YKJHPTGO.ts";
7
+ import "./chunk-HUDQATCL.ts";
8
+ import "./chunk-L7TBO32M.ts";
9
+ import "./chunk-LTBWGSBV.ts";
10
+ import "./chunk-LCRI3ABW.ts";
11
+ import "./chunk-C7XY5NF5.ts";
12
+ import "./chunk-6LP3MCR2.ts";
13
+ import "./chunk-TEN2ZBJV.ts";
14
+ import "./chunk-2B2ELUF5.ts";
15
+ import "./chunk-OEX4ABY6.ts";
16
+ import "./chunk-THMF4BVL.ts";
17
+ import "./chunk-T3HH3UEJ.ts";
18
+ import "./chunk-JAAKLL6M.ts";
19
+ export {
20
+ dispatchManagerResult
21
+ };
22
+ //# sourceMappingURL=manager-result-dispatcher-U23ODD32.ts.map