@narumitw/pi-sync 0.54.3 → 0.56.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 (179) hide show
  1. package/README.md +21 -4
  2. package/dist/chunks/agent-candidate-3JN6DJKT.ts +26 -0
  3. package/dist/chunks/agent-plan-QCUJWBP4.ts +99 -0
  4. package/dist/chunks/agent-plan-QCUJWBP4.ts.map +7 -0
  5. package/dist/chunks/agent-runner-E2JU2VZ6.ts +182 -0
  6. package/dist/chunks/agent-runner-E2JU2VZ6.ts.map +7 -0
  7. package/dist/chunks/agent-store-A3F6IYWZ.ts +152 -0
  8. package/dist/chunks/agent-store-A3F6IYWZ.ts.map +7 -0
  9. package/dist/chunks/chunk-5Q5SSKNG.ts +128 -0
  10. package/dist/chunks/chunk-5Q5SSKNG.ts.map +7 -0
  11. package/dist/chunks/chunk-5XZOC7FD.ts +215 -0
  12. package/dist/chunks/chunk-5XZOC7FD.ts.map +7 -0
  13. package/dist/chunks/{chunk-GC3QOL6J.ts → chunk-AAEEHR7H.ts} +31 -87
  14. package/dist/chunks/chunk-AAEEHR7H.ts.map +7 -0
  15. package/dist/chunks/{chunk-R35N4CL3.ts → chunk-B4QZBDBT.ts} +2 -2
  16. package/dist/chunks/{chunk-KGE47GCZ.ts → chunk-CRKTAPSL.ts} +8 -8
  17. package/dist/chunks/chunk-DT7M4VQS.ts +69 -0
  18. package/dist/chunks/chunk-DT7M4VQS.ts.map +7 -0
  19. package/dist/chunks/chunk-ED3TYIVW.ts +229 -0
  20. package/dist/chunks/chunk-ED3TYIVW.ts.map +7 -0
  21. package/dist/chunks/{chunk-HMXUKU43.ts → chunk-EUMINX7L.ts} +6 -6
  22. package/dist/chunks/chunk-FQOSHGJ7.ts +215 -0
  23. package/dist/chunks/chunk-FQOSHGJ7.ts.map +7 -0
  24. package/dist/chunks/chunk-GNH73BJ5.ts +153 -0
  25. package/dist/chunks/chunk-GNH73BJ5.ts.map +7 -0
  26. package/dist/chunks/{chunk-YTHQEW35.ts → chunk-GP5DU62N.ts} +8 -9
  27. package/dist/chunks/chunk-GP5DU62N.ts.map +7 -0
  28. package/dist/chunks/{chunk-AAZDBIBJ.ts → chunk-GSNPASKB.ts} +2 -2
  29. package/dist/chunks/{chunk-E6ONFG57.ts → chunk-IWZH5KYS.ts} +11 -8
  30. package/dist/chunks/chunk-IWZH5KYS.ts.map +7 -0
  31. package/dist/chunks/{chunk-CAGJOKB7.ts → chunk-JJTARUSO.ts} +15 -14
  32. package/dist/chunks/chunk-JJTARUSO.ts.map +7 -0
  33. package/dist/chunks/{chunk-ITFR6NNQ.ts → chunk-NLWS55B6.ts} +2 -1
  34. package/dist/chunks/{chunk-ITFR6NNQ.ts.map → chunk-NLWS55B6.ts.map} +2 -2
  35. package/dist/chunks/{chunk-2FETCGGT.ts → chunk-OEWQVWLC.ts} +4 -4
  36. package/dist/chunks/{chunk-35GM6XKM.ts → chunk-OTZRCKYP.ts} +128 -382
  37. package/dist/chunks/chunk-OTZRCKYP.ts.map +7 -0
  38. package/dist/chunks/{chunk-XU2VXGQV.ts → chunk-OWBAZA6J.ts} +14 -8
  39. package/dist/chunks/chunk-OWBAZA6J.ts.map +7 -0
  40. package/dist/chunks/chunk-PRUEIIK7.ts +24 -0
  41. package/dist/chunks/chunk-PRUEIIK7.ts.map +7 -0
  42. package/dist/chunks/chunk-QGK445K7.ts +21 -0
  43. package/dist/chunks/chunk-QGK445K7.ts.map +7 -0
  44. package/dist/chunks/{chunk-KATKRR3D.ts → chunk-QO333NM4.ts} +32 -11
  45. package/dist/chunks/chunk-QO333NM4.ts.map +7 -0
  46. package/dist/chunks/{chunk-I4JYVFUS.ts → chunk-QSHMOL3I.ts} +21 -22
  47. package/dist/chunks/chunk-QSHMOL3I.ts.map +7 -0
  48. package/dist/chunks/chunk-S2FMH5FT.ts +97 -0
  49. package/dist/chunks/chunk-S2FMH5FT.ts.map +7 -0
  50. package/dist/chunks/{chunk-BVVP33U5.ts → chunk-SWRVXVFD.ts} +12 -9
  51. package/dist/chunks/chunk-SWRVXVFD.ts.map +7 -0
  52. package/dist/chunks/{chunk-ZX2Q6THB.ts → chunk-UBV24CG4.ts} +4 -5
  53. package/dist/chunks/chunk-UBV24CG4.ts.map +7 -0
  54. package/dist/chunks/chunk-UOHR7LRO.ts +70 -0
  55. package/dist/chunks/chunk-UOHR7LRO.ts.map +7 -0
  56. package/dist/chunks/{chunk-VCL7TZYW.ts → chunk-UPNVIUBN.ts} +3 -3
  57. package/dist/chunks/chunk-VJN7KU4J.ts +350 -0
  58. package/dist/chunks/chunk-VJN7KU4J.ts.map +7 -0
  59. package/dist/chunks/chunk-YHT4YTYG.ts +31 -0
  60. package/dist/chunks/chunk-YHT4YTYG.ts.map +7 -0
  61. package/dist/chunks/{chunk-A3TFXY4O.ts → chunk-YK52VDXG.ts} +6 -5
  62. package/dist/chunks/chunk-YK52VDXG.ts.map +7 -0
  63. package/dist/chunks/config-KGIYTTXQ.ts +37 -0
  64. package/dist/chunks/{conflict-artifacts-4CZFB7WI.ts → conflict-artifacts-FXFIIBCB.ts} +8 -7
  65. package/dist/chunks/{conflict-review-ZOTOHL2E.ts → conflict-review-6WIEQLXW.ts} +31 -25
  66. package/dist/chunks/{conflict-review-ZOTOHL2E.ts.map → conflict-review-6WIEQLXW.ts.map} +1 -1
  67. package/dist/chunks/continuous-record-LFRVXQBD.ts +30 -0
  68. package/dist/chunks/continuous-sync-AWAAOXK2.ts +545 -0
  69. package/dist/chunks/continuous-sync-AWAAOXK2.ts.map +7 -0
  70. package/dist/chunks/{file-selection-UNHBVVON.ts → file-selection-3JJYOVNR.ts} +5 -5
  71. package/dist/chunks/{git-backend-FD7AVSK6.ts → git-backend-KYDZ673X.ts} +28 -32
  72. package/dist/chunks/git-backend-KYDZ673X.ts.map +7 -0
  73. package/dist/chunks/{manager-result-dispatcher-HVRTPEVK.ts → manager-result-dispatcher-AGBBVDDS.ts} +10 -9
  74. package/dist/chunks/{manager-ui-ZIN4BUSF.ts → manager-ui-KRAW3NE2.ts} +184 -45
  75. package/dist/chunks/manager-ui-KRAW3NE2.ts.map +7 -0
  76. package/dist/chunks/{merge-baseline-store-ICXVTCML.ts → merge-baseline-store-RFCAH7KL.ts} +5 -5
  77. package/dist/chunks/{remote-selection-ui-H6AEVA3Q.ts → remote-selection-ui-5725JDNC.ts} +9 -8
  78. package/dist/chunks/remote-selection-ui-5725JDNC.ts.map +7 -0
  79. package/dist/chunks/{s3-backend-Y4P3O5B5.ts → s3-backend-Y7WSCLJI.ts} +38 -38
  80. package/dist/chunks/s3-backend-Y7WSCLJI.ts.map +7 -0
  81. package/dist/chunks/{setup-switch-ZMW5C4M7.ts → setup-switch-E7PHKI6J.ts} +7 -6
  82. package/dist/chunks/setup-switch-E7PHKI6J.ts.map +7 -0
  83. package/dist/chunks/{setup-wizard-VW7F3JN4.ts → setup-wizard-65DROCIJ.ts} +14 -13
  84. package/dist/chunks/setup-wizard-65DROCIJ.ts.map +7 -0
  85. package/dist/chunks/{sync-inspection-3EMS2J5B.ts → sync-inspection-XFJOAMJD.ts} +8 -8
  86. package/dist/chunks/sync-inspection-XFJOAMJD.ts.map +7 -0
  87. package/dist/chunks/{sync-operations-2CWST333.ts → sync-operations-HDUDT5PD.ts} +62 -63
  88. package/dist/chunks/sync-operations-HDUDT5PD.ts.map +7 -0
  89. package/dist/chunks/{webdav-backend-TBILVEQK.ts → webdav-backend-6K26F6LT.ts} +39 -48
  90. package/dist/chunks/webdav-backend-6K26F6LT.ts.map +7 -0
  91. package/dist/index.ts +165 -85
  92. package/dist/index.ts.map +3 -3
  93. package/docs/agent-mode-verification.md +99 -0
  94. package/docs/continuous-sync-verification.md +87 -0
  95. package/docs/settings.md +84 -1
  96. package/package.json +3 -2
  97. package/src/backends/git/git-backend.ts +1 -4
  98. package/src/backends/git/git-runner.ts +1 -5
  99. package/src/backends/s3/s3-backend.ts +3 -25
  100. package/src/backends/s3/s3-client.ts +14 -2
  101. package/src/backends/snapshot-pointer.ts +27 -0
  102. package/src/backends/webdav/webdav-backend.ts +3 -29
  103. package/src/backends/webdav/webdav-client.ts +11 -7
  104. package/src/commands/command-execution.ts +5 -2
  105. package/src/commands/command-handler.ts +15 -3
  106. package/src/commands/command-types.ts +6 -0
  107. package/src/commands/command.ts +1 -0
  108. package/src/settings/config.ts +7 -0
  109. package/src/settings/settings-store.ts +0 -34
  110. package/src/settings/settings-types.ts +8 -0
  111. package/src/settings/settings-validation.ts +1 -1
  112. package/src/snapshot/snapshot-codec.ts +1 -5
  113. package/src/state/lock.ts +13 -10
  114. package/src/state/merge-baseline-store.ts +2 -2
  115. package/src/state/state-directory.ts +8 -1
  116. package/src/sync/agent-candidate.ts +251 -0
  117. package/src/sync/agent-plan.ts +87 -0
  118. package/src/sync/agent-policy.ts +13 -0
  119. package/src/sync/agent-request.ts +17 -0
  120. package/src/sync/agent-runner.ts +188 -0
  121. package/src/sync/agent-store.ts +151 -0
  122. package/src/sync/agent-sync.ts +91 -0
  123. package/src/sync/automatic-sync.ts +2 -1
  124. package/src/sync/continuous-errors.ts +85 -0
  125. package/src/sync/continuous-lease.ts +221 -0
  126. package/src/sync/continuous-record.ts +179 -0
  127. package/src/sync/continuous-storage.ts +55 -0
  128. package/src/sync/continuous-sync.ts +516 -0
  129. package/src/sync/continuous-watch.ts +59 -0
  130. package/src/sync/merged-sync.ts +70 -12
  131. package/src/sync/remote-snapshot.ts +2 -3
  132. package/src/sync/settings-merge.ts +19 -3
  133. package/src/sync/setup-switch.ts +1 -5
  134. package/src/sync/startup-check.ts +15 -11
  135. package/src/sync/sync-inspection.ts +8 -1
  136. package/src/sync/sync-mutations.ts +6 -17
  137. package/src/sync/sync-queries.ts +5 -0
  138. package/src/sync/text-merge.ts +3 -3
  139. package/src/sync-extension.ts +75 -19
  140. package/src/ui/agent-mode-setting.ts +91 -0
  141. package/src/ui/manager-state.ts +2 -0
  142. package/src/ui/remote-selection-ui.ts +5 -5
  143. package/src/ui/settings-ui.ts +83 -1
  144. package/src/ui/setup/s3-credentials-ui.ts +1 -5
  145. package/src/ui/setup/setup-name-ui.ts +2 -5
  146. package/src/ui/setup/setup-switcher.ts +2 -0
  147. package/src/ui/sync-setups-ui.ts +3 -5
  148. package/dist/chunks/chunk-26PMXY7E.ts +0 -362
  149. package/dist/chunks/chunk-26PMXY7E.ts.map +0 -7
  150. package/dist/chunks/chunk-35GM6XKM.ts.map +0 -7
  151. package/dist/chunks/chunk-A3TFXY4O.ts.map +0 -7
  152. package/dist/chunks/chunk-BVVP33U5.ts.map +0 -7
  153. package/dist/chunks/chunk-CAGJOKB7.ts.map +0 -7
  154. package/dist/chunks/chunk-E6ONFG57.ts.map +0 -7
  155. package/dist/chunks/chunk-GC3QOL6J.ts.map +0 -7
  156. package/dist/chunks/chunk-I4JYVFUS.ts.map +0 -7
  157. package/dist/chunks/chunk-KATKRR3D.ts.map +0 -7
  158. package/dist/chunks/chunk-XU2VXGQV.ts.map +0 -7
  159. package/dist/chunks/chunk-YTHQEW35.ts.map +0 -7
  160. package/dist/chunks/chunk-ZX2Q6THB.ts.map +0 -7
  161. package/dist/chunks/git-backend-FD7AVSK6.ts.map +0 -7
  162. package/dist/chunks/manager-ui-ZIN4BUSF.ts.map +0 -7
  163. package/dist/chunks/s3-backend-Y4P3O5B5.ts.map +0 -7
  164. package/dist/chunks/setup-wizard-VW7F3JN4.ts.map +0 -7
  165. package/dist/chunks/sync-operations-2CWST333.ts.map +0 -7
  166. package/dist/chunks/webdav-backend-TBILVEQK.ts.map +0 -7
  167. /package/dist/chunks/{conflict-artifacts-4CZFB7WI.ts.map → agent-candidate-3JN6DJKT.ts.map} +0 -0
  168. /package/dist/chunks/{chunk-R35N4CL3.ts.map → chunk-B4QZBDBT.ts.map} +0 -0
  169. /package/dist/chunks/{chunk-KGE47GCZ.ts.map → chunk-CRKTAPSL.ts.map} +0 -0
  170. /package/dist/chunks/{chunk-HMXUKU43.ts.map → chunk-EUMINX7L.ts.map} +0 -0
  171. /package/dist/chunks/{chunk-AAZDBIBJ.ts.map → chunk-GSNPASKB.ts.map} +0 -0
  172. /package/dist/chunks/{chunk-2FETCGGT.ts.map → chunk-OEWQVWLC.ts.map} +0 -0
  173. /package/dist/chunks/{chunk-VCL7TZYW.ts.map → chunk-UPNVIUBN.ts.map} +0 -0
  174. /package/dist/chunks/{manager-result-dispatcher-HVRTPEVK.ts.map → config-KGIYTTXQ.ts.map} +0 -0
  175. /package/dist/chunks/{merge-baseline-store-ICXVTCML.ts.map → conflict-artifacts-FXFIIBCB.ts.map} +0 -0
  176. /package/dist/chunks/{remote-selection-ui-H6AEVA3Q.ts.map → continuous-record-LFRVXQBD.ts.map} +0 -0
  177. /package/dist/chunks/{file-selection-UNHBVVON.ts.map → file-selection-3JJYOVNR.ts.map} +0 -0
  178. /package/dist/chunks/{setup-switch-ZMW5C4M7.ts.map → manager-result-dispatcher-AGBBVDDS.ts.map} +0 -0
  179. /package/dist/chunks/{sync-inspection-3EMS2J5B.ts.map → merge-baseline-store-RFCAH7KL.ts.map} +0 -0
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/ui/remote-selection-ui.ts", "../../src/ui/cancellable-operation.ts"],
4
- "sourcesContent": ["import type { ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { defineMenu, runMenu } from \"@narumitw/pi-tui-kit\";\nimport { createSyncBackend, type SyncBackendFactory } from \"../backends/backend-factory.js\";\nimport type { RemoteHead, SyncBackend } from \"../backends/sync-backend.js\";\nimport {\n loadConfig,\n loadPartialConfig,\n type SyncSetupStorageReview,\n syncConfigReviewFingerprint,\n} from \"../settings/config.js\";\nimport { SyncSetupReviewChangedError, updateSyncSetup } from \"../settings/settings-management.js\";\nimport type { AnySyncConfig, PartialConfig } from \"../settings/settings-types.js\";\nimport { readSnapshotForHead } from \"../sync/remote-snapshot.js\";\nimport { errorMessage } from \"../sync/sync-errors.js\";\nimport {\n compareSyncInclude,\n inspectRemoteSelection,\n type RemoteSelectionDecision,\n type RemoteSelectionState,\n sameSyncInclude,\n} from \"../sync/sync-policy.js\";\nimport { type RunRoute, type RunRouteResult, runCancellableOperation } from \"./cancellable-operation.js\";\nimport { setSyncStatus } from \"./sync-status.js\";\nimport { safeTerminalText } from \"./terminal-text.js\";\n\nexport type RemoteSelectionOrigin = \"settings\" | \"sync\" | \"pull\" | \"push\";\n\nexport interface RemoteSelectionReviewOptions {\n decision?: RemoteSelectionDecision;\n origin?: RemoteSelectionOrigin;\n runRoute?: RunRoute;\n cancelLabel?: string;\n /** The explicit mismatch is resolved or superseded; this does not imply file equality. */\n onSelectionResolved?: () => void;\n withStateAccess?: <T>(task: () => Promise<T>) => Promise<T>;\n}\n\nexport type RemoteSelectionReviewResult =\n | { kind: \"back\" }\n | { kind: \"closed\" }\n | { kind: \"done\" }\n | { kind: \"stale\" }\n | { kind: \"route-result\"; result: RunRouteResult; route: \"sync\" | \"pull\" | \"push\" };\n\nexport async function showRemoteSelectionReview(\n ctx: ExtensionContext,\n setupName?: string,\n signal?: AbortSignal,\n factory: SyncBackendFactory = createSyncBackend,\n options: RemoteSelectionReviewOptions = {},\n): Promise<RemoteSelectionReviewResult> {\n try {\n let decision = options.decision;\n if (!decision) {\n const inspected = await inspectConfiguredRemoteSelection(ctx, setupName, signal, factory);\n if (!inspected || signal?.aborted) return { kind: \"stale\" };\n // A successful fresh read can supersede an old explicit mismatch without\n // changing local settings. This is not user cancellation or proof of file equality.\n if (inspected.kind === \"empty\" || inspected.state.kind !== \"different\") {\n options.onSelectionResolved?.();\n }\n if (inspected.kind === \"empty\") {\n ctx.ui.notify(\"Remote storage has no snapshot or synced-content list yet.\", \"info\");\n return { kind: \"back\" };\n }\n if (inspected.state.kind === \"same\") {\n ctx.ui.notify(\"Remote synced content already matches this sync setup.\", \"info\");\n return { kind: \"back\" };\n }\n if (inspected.state.kind === \"legacy\") {\n if (ctx.mode !== \"tui\") {\n ctx.ui.notify(formatLegacySummary(inspected.config, inspected.state.discovered), \"info\");\n return { kind: \"back\" };\n }\n await showLegacyDiscovery(ctx, inspected.config, inspected.state.discovered, signal);\n return signal?.aborted ? { kind: \"stale\" } : { kind: \"back\" };\n }\n decision = decisionFromState(inspected.config, inspected.state);\n }\n\n if (ctx.mode !== \"tui\") {\n ctx.ui.notify(formatRemoteSelectionSummary(decision), \"warning\");\n return { kind: \"back\" };\n }\n\n let currentDecision = decision;\n for (;;) {\n if (signal?.aborted) return { kind: \"stale\" };\n const result = await showSelectionDifference(\n ctx,\n currentDecision,\n options.origin ?? \"settings\",\n options.runRoute,\n signal,\n factory,\n options,\n );\n if (result.kind !== \"refresh\") return result;\n const refreshed = await runWithOptionalStateAccess(options, () =>\n inspectConfiguredRemoteSelection(ctx, currentDecision.setupName, signal, factory),\n );\n if (!refreshed || signal?.aborted) return { kind: \"stale\" };\n if (refreshed.kind === \"empty\") {\n options.onSelectionResolved?.();\n ctx.ui.notify(\"Remote storage no longer has a snapshot or synced-content list.\", \"warning\");\n return { kind: \"back\" };\n }\n if (refreshed.state.kind !== \"different\") {\n ctx.ui.notify(\n refreshed.state.kind === \"same\"\n ? \"Remote synced content now matches this sync setup.\"\n : \"The refreshed legacy snapshot has no authoritative synced-content list.\",\n \"info\",\n );\n options.onSelectionResolved?.();\n return { kind: \"done\" };\n }\n currentDecision = decisionFromState(refreshed.config, refreshed.state);\n }\n } catch (error) {\n if (signal?.aborted) return { kind: \"stale\" };\n ctx.ui.notify(`Could not review synced content: ${errorMessage(error)}`, \"error\");\n return { kind: \"back\" };\n } finally {\n setSyncStatus(ctx, undefined);\n }\n}\n\ntype DifferenceFlowResult = RemoteSelectionReviewResult | { kind: \"refresh\" };\n\nasync function showSelectionDifference(\n ctx: ExtensionContext,\n initialDecision: RemoteSelectionDecision,\n origin: RemoteSelectionOrigin,\n runRoute: RunRoute | undefined,\n sessionSignal: AbortSignal | undefined,\n factory: SyncBackendFactory,\n options: Pick<RemoteSelectionReviewOptions, \"cancelLabel\" | \"onSelectionResolved\" | \"withStateAccess\">,\n): Promise<DifferenceFlowResult> {\n type Screen = \"choice\" | \"review\" | \"saved\";\n type Action = \"adopt\" | \"keep\" | \"cancel\" | \"continue\" | \"done\";\n interface FlowState {\n decision: RemoteSelectionDecision;\n saved: boolean;\n }\n let flowState: FlowState = { decision: initialDecision, saved: false };\n let continuationReview: PartialConfig | undefined;\n let nextResult: RemoteSelectionReviewResult | undefined;\n let refreshRequested = false;\n const route = origin === \"settings\" ? \"sync\" : origin;\n const menu = defineMenu<FlowState, Screen, Action, ExtensionContext>({\n start: \"choice\",\n screens: {\n choice: ({ state }) => ({\n kind: \"actions\",\n title: \"Synced content differs\",\n lines: selectionSummaryLines(state.decision),\n items: [\n {\n id: \"review\",\n label: \"Review all paths (recommended)\",\n description: \"Compare exact remote-only, device-only, and ordered lists.\",\n to: \"review\",\n },\n {\n id: \"adopt\",\n label: \"Use remote content list\",\n description: \"Save the reviewed list on this device without pulling files.\",\n action: \"adopt\",\n },\n {\n id: \"keep\",\n label: \"Keep this device's content list and update remote\u2026\",\n description: \"Open the existing exact force-push preview without skipping confirmation.\",\n action: \"keep\",\n },\n { id: \"cancel\", label: options.cancelLabel ?? \"Cancel\", action: \"cancel\" },\n ],\n hint: \"back\",\n }),\n review: ({ state }) => ({\n kind: \"review\",\n title: `Review synced content \u00B7 ${safeTerminalText(state.decision.setupName)}`,\n content: formatSelectionDifference(state.decision),\n format: { kind: \"text\" },\n viewportSize: \"adaptive\",\n hint: \"back\",\n }),\n saved: ({ state }) => ({\n kind: \"actions\",\n title: \"Remote content list saved\",\n lines: [\n `Sync setup: ${safeTerminalText(state.decision.setupName)}`,\n \"Only the included-content setting was saved.\",\n \"No files were pulled and sync state was not changed.\",\n ],\n items: [\n ...(runRoute\n ? [\n {\n id: \"continue\",\n label: continueLabel(origin),\n description: \"Start a fresh check and exact preview for this sync setup.\",\n action: \"continue\" as const,\n },\n ]\n : []),\n { id: \"done\", label: \"Done\", action: \"done\" },\n ],\n hint: \"close\",\n }),\n },\n actions: {\n adopt: async ({ state, signal: actionSignal }) => {\n const signal = combineSignals(sessionSignal, actionSignal);\n try {\n const currentConfig = await loadConfig(state.decision.setupName);\n if (signal.aborted) return { kind: \"close\" as const };\n assertLocalSelectionCurrent(currentConfig, state.decision);\n if (!currentConfig.include.includes(\"sessions\") && state.decision.remoteInclude.includes(\"sessions\")) {\n const acknowledged = await ctx.ui.confirm(\n \"Use a content list that includes session conversations?\",\n \"Session JSONL may contain prompts, tool output, file paths, images, and secrets. This saves the list only; it does not pull files.\",\n { signal },\n );\n if (signal.aborted) return { kind: \"close\" as const };\n if (!acknowledged) return { kind: \"stay\" as const };\n }\n const review = await runWithOptionalStateAccess(options, async () => {\n const loaded = await loadAdoptionReview(state.decision, signal, factory);\n if (signal.aborted) throw signal.reason;\n await revalidateAndAdopt(loaded, state.decision, signal);\n return loaded;\n });\n if (signal.aborted) return { kind: \"close\" as const };\n options.onSelectionResolved?.();\n continuationReview = {\n ...review.storageReview,\n setupName: state.decision.setupName,\n include: [...state.decision.remoteInclude],\n automatic: review.config.automatic,\n automaticTransfer: review.config.automaticTransfer,\n onSwitch: review.config.onSwitch,\n showStatus: review.config.showStatus,\n };\n flowState = { decision: state.decision, saved: true };\n return { kind: \"to\" as const, screen: \"saved\" as const };\n } catch (error) {\n if (signal.aborted) return { kind: \"close\" as const };\n if (isStaleReviewError(error)) {\n ctx.ui.notify(`${errorMessage(error)} Refreshing the comparison.`, \"warning\");\n refreshRequested = true;\n return { kind: \"close\" as const };\n }\n ctx.ui.notify(`Could not save the remote content list: ${errorMessage(error)}`, \"error\");\n return { kind: \"stay\" as const };\n }\n },\n keep: async ({ state, signal: actionSignal }) => {\n if (!runRoute) {\n ctx.ui.notify(\"The reviewed update-remote route is unavailable.\", \"error\");\n return { kind: \"stay\" as const };\n }\n const signal = combineSignals(sessionSignal, actionSignal);\n try {\n const latest = await loadConfig(state.decision.setupName);\n if (signal.aborted) return { kind: \"close\" as const };\n assertLocalSelectionCurrent(latest, state.decision);\n const result = await runCancellableOperation(\n ctx,\n \"Preparing this device's push preview\u2026\",\n \"push --force\",\n runRoute,\n {\n commitAware: true,\n cancelledMessage: \"Push preparation cancelled; no remote files were changed.\",\n target: state.decision.setupName,\n signal,\n },\n );\n return handleNestedRouteResult(result, \"push\");\n } catch (error) {\n if (signal.aborted) return { kind: \"close\" as const };\n if (isStaleReviewError(error)) {\n ctx.ui.notify(`${errorMessage(error)} Refreshing the comparison.`, \"warning\");\n refreshRequested = true;\n return { kind: \"close\" as const };\n }\n ctx.ui.notify(`Could not prepare the remote update: ${errorMessage(error)}`, \"error\");\n return { kind: \"stay\" as const };\n }\n },\n continue: async ({ state, signal: actionSignal }) => {\n if (!runRoute || !continuationReview) return { kind: \"stay\" as const };\n const signal = combineSignals(sessionSignal, actionSignal);\n try {\n const latest = await loadPartialConfig(state.decision.setupName);\n if (signal.aborted) return { kind: \"close\" as const };\n if (!sameContinuationReview(latest, continuationReview)) {\n throw new StaleRemoteSelectionReviewError(\n `Sync setup \u201C${safeTerminalText(state.decision.setupName)}\u201D changed after the remote content list was saved.`,\n );\n }\n const result = await runCancellableOperation(ctx, continueBusyLabel(origin), route, runRoute, {\n commitAware: true,\n cancelledMessage: continuationCancelledMessage(route),\n target: state.decision.setupName,\n signal,\n });\n return handleNestedRouteResult(result, route);\n } catch (error) {\n if (signal.aborted) return { kind: \"close\" as const };\n ctx.ui.notify(`Could not continue: ${errorMessage(error)}`, \"error\");\n return { kind: \"stay\" as const };\n }\n },\n cancel: async () => ({ kind: \"back\" }),\n done: async () => {\n nextResult = { kind: \"done\" };\n return { kind: \"close\" };\n },\n },\n });\n\n function handleNestedRouteResult(\n result: Awaited<ReturnType<typeof runCancellableOperation>>,\n nestedRoute: \"sync\" | \"pull\" | \"push\",\n ) {\n if (result.kind === \"completed\" && result.outcome === \"applied\") {\n options.onSelectionResolved?.();\n }\n if (result.kind === \"closed\") {\n nextResult = { kind: \"closed\" };\n return { kind: \"close\" as const };\n }\n if (\n result.kind === \"cancelled\" ||\n (result.kind === \"completed\" && result.outcome === \"cancelled\") ||\n result.kind === \"failed\"\n ) {\n return { kind: \"stay\" as const };\n }\n nextResult = { kind: \"route-result\", result, route: nestedRoute };\n return { kind: \"close\" as const };\n }\n\n const menuResult = await runMenu(ctx, menu, {\n getState: () => flowState,\n signal: sessionSignal,\n isCurrent: () => !sessionSignal?.aborted,\n onError: (_menuCtx, error) => ctx.ui.notify(errorMessage(error), \"error\"),\n });\n if (sessionSignal?.aborted || menuResult.kind === \"stale\") return { kind: \"stale\" };\n if (refreshRequested) return { kind: \"refresh\" };\n if (nextResult) return nextResult;\n if (menuResult.kind === \"closed\") {\n return menuResult.reason === \"back\" ? { kind: \"back\" } : { kind: \"closed\" };\n }\n return { kind: \"closed\" };\n}\n\ninterface AdoptionReview {\n config: AnySyncConfig;\n storageReview: SyncSetupStorageReview;\n backend: SyncBackend;\n reviewedHead: RemoteHead;\n}\n\nasync function loadAdoptionReview(\n decision: RemoteSelectionDecision,\n signal: AbortSignal,\n factory: SyncBackendFactory,\n): Promise<AdoptionReview> {\n const config = await loadConfig(decision.setupName);\n throwIfAborted(signal);\n assertLocalSelectionCurrent(config, decision);\n const partial = await loadPartialConfig(decision.setupName);\n throwIfAborted(signal);\n if (!sameSyncInclude(partial.include, decision.localInclude)) {\n throw new StaleRemoteSelectionReviewError(\n `Sync setup \u201C${safeTerminalText(decision.setupName)}\u201D changed while the comparison was open.`,\n );\n }\n const backend = await factory(config);\n throwIfAborted(signal);\n const reviewedHead = await backend.readHead(signal);\n throwIfAborted(signal);\n if (!reviewedHead) {\n throw new StaleRemoteSelectionReviewError(\"Remote storage changed while the comparison was open.\");\n }\n const snapshot = await readSnapshotForHead(backend, reviewedHead, signal);\n throwIfAborted(signal);\n const state = inspectRemoteSelection(config.include, snapshot);\n if (state.kind !== \"different\" || !sameSyncInclude(state.include, decision.remoteInclude)) {\n throw new StaleRemoteSelectionReviewError(\"Remote synced content changed while the comparison was open.\");\n }\n return { config, storageReview: partial, backend, reviewedHead };\n}\n\nasync function revalidateAndAdopt(review: AdoptionReview, decision: RemoteSelectionDecision, signal: AbortSignal) {\n const currentHead = await review.backend.readHead(signal);\n throwIfAborted(signal);\n if (!currentHead || !review.backend.sameRevision(review.reviewedHead.revision, currentHead.revision)) {\n throw new StaleRemoteSelectionReviewError(\"Remote storage changed while the comparison was open.\");\n }\n const currentSnapshot = await readSnapshotForHead(review.backend, currentHead, signal);\n throwIfAborted(signal);\n const currentState = inspectRemoteSelection(review.config.include, currentSnapshot);\n if (currentState.kind !== \"different\" || !sameSyncInclude(currentState.include, decision.remoteInclude)) {\n throw new StaleRemoteSelectionReviewError(\"Remote synced content changed while the comparison was open.\");\n }\n await updateSyncSetup(\n decision.setupName,\n (setup) => ({\n ...setup,\n sync: { ...setup.sync, include: [...decision.remoteInclude] },\n }),\n {\n expectedStorage: review.storageReview,\n expectedInclude: decision.localInclude,\n signal,\n },\n );\n}\n\nasync function inspectConfiguredRemoteSelection(\n ctx: ExtensionContext,\n setupName: string | undefined,\n signal: AbortSignal | undefined,\n factory: SyncBackendFactory,\n): Promise<\n | { kind: \"empty\"; config: AnySyncConfig }\n | { kind: \"selection\"; config: AnySyncConfig; state: RemoteSelectionState }\n | undefined\n> {\n const config = await loadConfig(setupName);\n if (signal?.aborted) return undefined;\n setSyncStatus(ctx, `checking synced content for ${safeTerminalText(config.setupName)}`);\n const backend = await factory(config);\n if (signal?.aborted) return undefined;\n const head = await backend.readHead(signal);\n if (signal?.aborted) return undefined;\n if (!head) return { kind: \"empty\", config };\n const snapshot = await readSnapshotForHead(backend, head, signal);\n if (signal?.aborted) return undefined;\n return {\n kind: \"selection\",\n config,\n state: inspectRemoteSelection(config.include, snapshot),\n };\n}\n\nasync function showLegacyDiscovery(\n ctx: ExtensionContext,\n config: AnySyncConfig,\n discovered: string[],\n signal?: AbortSignal,\n) {\n const menu = defineMenu<undefined, \"choice\" | \"review\", \"back\", ExtensionContext>({\n start: \"choice\",\n screens: {\n choice: () => ({\n kind: \"actions\",\n title: `Compare synced content \u00B7 ${safeTerminalText(config.setupName)}`,\n lines: [\n \"This legacy snapshot has no portable synced-content list.\",\n \"Discovered paths are partial and read-only; preserved files may not have been selected.\",\n ],\n items: [\n { id: \"review\", label: \"Review discovered paths\", to: \"review\" },\n { id: \"back\", label: \"Back\", action: \"back\" },\n ],\n hint: \"close\",\n }),\n review: () => ({\n kind: \"review\",\n title: \"Partial discovery from legacy snapshot\",\n content: [\n \"Partial discovery only \u2014 not an authoritative selection.\",\n \"\",\n ...(discovered.length > 0\n ? discovered.map((item) => `Discovered: ${safeTerminalText(item)}`)\n : [\"No safe paths were discovered.\"]),\n \"\",\n \"Use Add custom path\u2026 in the local Included Content editor if needed.\",\n ].join(\"\\n\"),\n format: { kind: \"text\" },\n viewportSize: \"adaptive\",\n hint: \"back\",\n }),\n },\n actions: { back: async () => ({ kind: \"close\" }) },\n });\n await runMenu(ctx, menu, {\n getState: () => undefined,\n signal,\n isCurrent: () => !signal?.aborted,\n });\n}\n\nfunction selectionSummaryLines(decision: RemoteSelectionDecision) {\n const comparison = compareSyncInclude(decision.localInclude, decision.remoteInclude);\n return [\n `Sync setup: ${safeTerminalText(decision.setupName)}`,\n \"Nothing changed. Review both lists before choosing what happens next.\",\n ...(comparison.remoteOnly.length === 0 && comparison.localOnly.length === 0\n ? [\"Only the ordering differs; membership is the same.\"]\n : [`Remote-only paths: ${comparison.remoteOnly.length} \u00B7 Device-only paths: ${comparison.localOnly.length}`]),\n ];\n}\n\nfunction formatSelectionDifference(decision: RemoteSelectionDecision) {\n const comparison = compareSyncInclude(decision.localInclude, decision.remoteInclude);\n return [\n ...(comparison.remoteOnly.length === 0 && comparison.localOnly.length === 0\n ? [\"Only ordering differs; both lists contain the same paths.\", \"\"]\n : []),\n \"Remote-only paths:\",\n ...(comparison.remoteOnly.length > 0\n ? comparison.remoteOnly.map((item) => `+ ${safeTerminalText(item)}`)\n : [\"(none)\"]),\n \"\",\n \"Device-only paths:\",\n ...(comparison.localOnly.length > 0\n ? comparison.localOnly.map((item) => `- ${safeTerminalText(item)}`)\n : [\"(none)\"]),\n \"\",\n \"Remote ordered list:\",\n ...(decision.remoteInclude.length > 0\n ? decision.remoteInclude.map((item, index) => `${index + 1}. ${safeTerminalText(item)}`)\n : [\"(none)\"]),\n \"\",\n \"This device's ordered list:\",\n ...(decision.localInclude.length > 0\n ? decision.localInclude.map((item, index) => `${index + 1}. ${safeTerminalText(item)}`)\n : [\"(none)\"]),\n \"\",\n \"Using the remote list saves settings only and does not pull files.\",\n ].join(\"\\n\");\n}\n\nfunction formatRemoteSelectionSummary(decision: RemoteSelectionDecision) {\n const comparison = compareSyncInclude(decision.localInclude, decision.remoteInclude);\n return [\n `Synced content for \u201C${safeTerminalText(decision.setupName)}\u201D differs from this device.`,\n `Remote-only: ${safeList(comparison.remoteOnly)}`,\n `Device-only: ${safeList(comparison.localOnly)}`,\n ...(comparison.remoteOnly.length === 0 && comparison.localOnly.length === 0\n ? [\n \"Only ordering differs.\",\n `Remote order: ${safeList(decision.remoteInclude)}`,\n `Device order: ${safeList(decision.localInclude)}`,\n ]\n : []),\n \"Run /sync in TUI to choose a content list; RPC review is read-only.\",\n ].join(\"\\n\");\n}\n\nfunction formatLegacySummary(config: AnySyncConfig, discovered: readonly string[]) {\n return `Remote snapshot for \u201C${safeTerminalText(config.setupName)}\u201D has no portable synced-content list; ${discovered.length} safe path${discovered.length === 1 ? \" was\" : \"s were\"} discovered, but the result is partial and read-only.`;\n}\n\nfunction decisionFromState(\n config: AnySyncConfig,\n state: Extract<RemoteSelectionState, { kind: \"different\" }>,\n): RemoteSelectionDecision {\n return {\n setupName: config.setupName,\n configIdentity: syncConfigReviewFingerprint(config),\n localInclude: [...config.include],\n remoteInclude: [...state.include],\n };\n}\n\nfunction assertLocalSelectionCurrent(config: AnySyncConfig, decision: RemoteSelectionDecision) {\n if (\n syncConfigReviewFingerprint(config) === decision.configIdentity &&\n sameSyncInclude(config.include, decision.localInclude)\n ) {\n return;\n }\n throw new StaleRemoteSelectionReviewError(\n `Sync setup \u201C${safeTerminalText(config.setupName)}\u201D changed while the comparison was open.`,\n );\n}\n\nfunction sameContinuationReview(left: PartialConfig, right: PartialConfig) {\n return (\n left.setupName === right.setupName &&\n left.connectionName === right.connectionName &&\n left.storageKind === right.storageKind &&\n left.storagePath === right.storagePath &&\n left.bucket === right.bucket &&\n left.branch === right.branch &&\n sameSyncInclude(left.include, right.include)\n );\n}\n\nfunction continueLabel(origin: RemoteSelectionOrigin) {\n if (origin === \"pull\") return \"Continue Pull now\u2026\";\n if (origin === \"push\") return \"Continue Push now\u2026\";\n return \"Continue Sync now\u2026\";\n}\n\nfunction continueBusyLabel(origin: RemoteSelectionOrigin) {\n if (origin === \"pull\") return \"Checking remote changes\u2026\";\n if (origin === \"push\") return \"Preparing push preview\u2026\";\n return \"Checking current sync setup\u2026\";\n}\n\nfunction continuationCancelledMessage(route: \"sync\" | \"pull\" | \"push\") {\n if (route === \"pull\") return \"Pull check cancelled; no local files were changed.\";\n if (route === \"push\") return \"Push preparation cancelled; no remote files were changed.\";\n return \"Sync check cancelled; no settings or files were changed.\";\n}\n\nfunction safeList(values: readonly string[]) {\n return values.length > 0 ? values.map(safeTerminalText).join(\", \") : \"none\";\n}\n\nclass StaleRemoteSelectionReviewError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"StaleRemoteSelectionReviewError\";\n }\n}\n\nfunction isStaleReviewError(error: unknown) {\n return error instanceof StaleRemoteSelectionReviewError || error instanceof SyncSetupReviewChangedError;\n}\n\nfunction runWithOptionalStateAccess<T>(\n options: Pick<RemoteSelectionReviewOptions, \"withStateAccess\">,\n task: () => Promise<T>,\n) {\n return options.withStateAccess ? options.withStateAccess(task) : task();\n}\n\nfunction combineSignals(sessionSignal: AbortSignal | undefined, actionSignal: AbortSignal) {\n return sessionSignal ? AbortSignal.any([sessionSignal, actionSignal]) : actionSignal;\n}\n\nfunction throwIfAborted(signal: AbortSignal) {\n if (!signal.aborted) return;\n throw signal.reason instanceof Error ? signal.reason : new DOMException(\"The operation was aborted\", \"AbortError\");\n}\n", "import { BorderedLoader, type ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { isKeyRelease, Key, matchesKey, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport { formatInteractionHints, runCustomInteraction } from \"@narumitw/pi-tui-kit\";\nimport type { SetupPullOutcome } from \"../sync/setup-switch.js\";\nimport type { SyncDecision } from \"../sync/sync-decision.js\";\nimport type { RemoteSelectionDecision } from \"../sync/sync-policy.js\";\n\nexport type RunRouteResult =\n | { kind: \"completed\"; outcome?: SetupPullOutcome }\n | { kind: \"decision-required\"; decision: SyncDecision }\n | { kind: \"remote-selection-required\"; decision: RemoteSelectionDecision }\n | { kind: \"failed\" };\n\nexport type RunRoute = (\n route: string,\n signal?: AbortSignal,\n onCommit?: () => void,\n target?: string,\n onDialog?: (active: boolean) => void,\n) => Promise<RunRouteResult | undefined>;\n\nexport type CancellableOperationResult = RunRouteResult | { kind: \"closed\" } | { kind: \"cancelled\" };\n\ninterface CancellableOperationOptions {\n commitAware?: boolean;\n cancelAcrossDialogs?: boolean;\n cancelledMessage?: string | null;\n target?: string;\n signal?: AbortSignal;\n}\n\nexport async function runCancellableOperation(\n ctx: ExtensionContext,\n message: string,\n route: string,\n runRoute: RunRoute,\n options: CancellableOperationOptions = {},\n): Promise<CancellableOperationResult> {\n const {\n commitAware = false,\n cancelAcrossDialogs = false,\n cancelledMessage = \"Check cancelled; no settings or files were changed.\",\n target,\n signal,\n } = options;\n if (ctx.mode !== \"tui\") {\n return (await runRoute(route, signal, undefined, target)) ?? { kind: \"failed\" };\n }\n let commitStarted = false;\n let routeResult: RunRouteResult | undefined;\n const interaction = await runCustomInteraction<{ cancelled?: boolean; error?: unknown }, ExtensionContext>(ctx, {\n signal,\n isCurrent: () => !signal?.aborted,\n create: ({ tui, theme, keybindings, signal: interactionSignal, complete }) => {\n const loader = new BorderedLoader(tui, theme, message, { cancellable: false });\n const cancelHint = formatInteractionHints(keybindings, [\n {\n keys: [...keybindings.getKeys(\"tui.select.cancel\").filter((key) => !hasControlCharacter(key)), \"ctrl+c\"],\n label: \"cancel\",\n },\n ]);\n const cancel = (data: string) => {\n // Raw terminal listeners run before Pi filters Kitty key releases.\n if (isKeyRelease(data)) return false;\n if (!matchesKey(data, Key.ctrl(\"c\")) && !keybindings.matches(data, \"tui.select.cancel\")) return false;\n if (commitStarted) {\n ctx.ui.notify(\"Applying or publishing has started and cannot be cancelled safely.\", \"warning\");\n } else complete({ cancelled: true });\n return true;\n };\n // Pi dialogs replace this loader and restore the normal editor. Defer\n // ordinary keys while they are open; retain raw cancellation afterward.\n // Ctrl+C remains the root flow's hard-cancel path regardless of focus.\n let activeDialogs = 0;\n const unsubscribe = cancelAcrossDialogs\n ? ctx.ui.onTerminalInput((data) => {\n if (isKeyRelease(data)) return;\n if (activeDialogs > 0 && !matchesKey(data, Key.ctrl(\"c\"))) return;\n return cancel(data) ? { consume: true } : undefined;\n })\n : undefined;\n let pendingRoute: ReturnType<RunRoute>;\n try {\n pendingRoute = runRoute(\n route,\n interactionSignal,\n commitAware ? () => (commitStarted = true) : undefined,\n target,\n cancelAcrossDialogs\n ? (active) => {\n activeDialogs += active ? 1 : -1;\n }\n : undefined,\n );\n } catch (error) {\n unsubscribe?.();\n loader.dispose();\n throw error;\n }\n const operation = pendingRoute.then(\n (result) => {\n routeResult = result;\n complete({});\n },\n (error: unknown) => complete({ error }),\n );\n return {\n render(width: number) {\n const safeWidth = Math.max(1, width);\n const lines = loader.render(safeWidth);\n const bottomBorder = lines.at(-1);\n return [\n ...lines.slice(0, -1),\n truncateToWidth(theme.fg(\"dim\", cancelHint), safeWidth, \"\"),\n ...(bottomBorder === undefined ? [] : [bottomBorder]),\n ];\n },\n invalidate: () => loader.invalidate(),\n handleInput: cancel,\n dispose() {\n unsubscribe?.();\n loader.dispose();\n },\n waitForPending: () => operation,\n };\n },\n });\n if (interaction.kind === \"error\") throw interaction.error;\n if (interaction.kind !== \"completed\") return { kind: \"closed\" };\n if (interaction.value.cancelled) {\n if (cancelledMessage) ctx.ui.notify(cancelledMessage, \"info\");\n return { kind: \"cancelled\" };\n }\n if (interaction.value.error) throw interaction.value.error;\n return routeResult ?? { kind: \"failed\" };\n}\n\nfunction hasControlCharacter(value: string) {\n // biome-ignore lint/suspicious/noControlCharactersInRegex: Unsafe key labels must be omitted.\n return /[\\u0000-\\u001f\\u007f-\\u009f]/u.test(value);\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
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}\n/** A no-op must not skip seeding or repairing ancestors required by later merges. */\nexport async function hasCurrentMergeBaseline(config: AnySyncConfig, snapshot: Snapshot, state: SyncState) {\n try {\n const ancestors = await readMergeAncestors(config, state);\n if (!ancestors) return false;\n const hashes = new Map(ancestors.map((file) => [file.path, file.sha256]));\n return snapshot.files.every(\n (file) =>\n !(file.path === \"settings.json\" || config.mergeContent) ||\n !eligible(file) ||\n hashes.get(file.path) === file.sha256,\n );\n } catch {\n // Preserve the existing full path's validation and repair behavior for unknown evidence.\n return false;\n }\n}\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
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/sync/sync-local.ts", "../../src/state/lock.ts"],
4
- "sourcesContent": ["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ExtensionCommandContext, ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { agentDir, sessionDirFromContext } from \"../snapshot/session-paths.js\";\nimport { createSnapshot, sessionSnapshotPathFromAbsolute } from \"../snapshot/snapshot.js\";\nimport { encodeSnapshot } from \"../snapshot/snapshot-codec.js\";\nimport type { SnapshotOptions } from \"../snapshot/snapshot-types.js\";\nimport { syncDirectory } from \"../state/json-file.js\";\nimport { stateDir } from \"../state/state-directory.js\";\nimport { throwIfAborted } from \"./signals.js\";\n\nexport function protectedSessionPaths(\n ctx: ExtensionCommandContext | ExtensionContext,\n sessionRoot = sessionDirFromContext(ctx),\n) {\n const getSessionFile = ctx.sessionManager.getSessionFile;\n if (typeof getSessionFile !== \"function\") return new Set<string>();\n const sessionFile = getSessionFile.call(ctx.sessionManager) as string | undefined;\n const snapshotPath = sessionFile ? sessionSnapshotPathFromAbsolute(sessionFile, sessionRoot) : undefined;\n return snapshotPath ? new Set([snapshotPath]) : new Set<string>();\n}\n\nexport function captureMutationOwner(ctx: ExtensionContext | ExtensionCommandContext, signal?: AbortSignal) {\n const manager = ctx.sessionManager;\n const file = manager.getSessionFile?.();\n const id = manager.getSessionId?.();\n const cwd = manager.getCwd?.();\n const root = agentDir();\n return () => {\n throwIfAborted(signal);\n if (\n ctx.sessionManager !== manager ||\n manager.getSessionFile?.() !== file ||\n manager.getSessionId?.() !== id ||\n manager.getCwd?.() !== cwd ||\n agentDir() !== root\n )\n throw new Error(\"Session changed during file mutation; evidence retained for review.\");\n };\n}\n\nexport async function backupLocal(profile: string, options: SnapshotOptions = {}, signal?: AbortSignal) {\n throwIfAborted(signal);\n const snapshot = await createSnapshot(profile, { ...options, signal });\n throwIfAborted(signal);\n const backupDirectory = path.join(stateDir(), \"backups\");\n await fs.mkdir(backupDirectory, { recursive: true, mode: 0o700 });\n throwIfAborted(signal);\n const backupPath = path.join(backupDirectory, `${snapshot.id}.json.gz`);\n const encoded = await encodeSnapshot(snapshot);\n throwIfAborted(signal);\n const handle = await fs.open(backupPath, \"wx\", 0o600);\n try {\n await handle.writeFile(encoded);\n await handle.sync();\n } finally {\n await handle.close();\n }\n await syncDirectory(backupDirectory);\n return backupPath;\n}\n", "import { randomUUID } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport lockfile from \"proper-lockfile\";\nimport type { CommandOptions } from \"../commands/command-types.js\";\nimport { LOCK_GUARD_STALE_MS, LOCK_GUARD_UPDATE_MS } from \"./lock-policy.js\";\nimport { LOCKFILE_FS_ADAPTER } from \"./lockfile-fs.js\";\nimport type { LockFile } from \"./state-types.js\";\nimport { ensureStateDir, lockPath } from \"./sync-state-store.js\";\n\nconst LOCK_STALE_MS = 30 * 60 * 1000;\nconst MAX_PROCESS_ID = 2_147_483_647;\n\ninterface Guard {\n release: () => Promise<void>;\n throwIfCompromised: () => void;\n isCompromised: () => boolean;\n}\n\nexport type LockInspection = { status: \"missing\" } | { status: \"unreadable\" } | { status: \"valid\"; lock: LockFile };\n\nexport async function withLock<T>(\n command: string,\n fn: () => Promise<T>,\n options: { reclaimStale?: boolean } = {},\n): Promise<T> {\n await ensureStateDir();\n const lock: LockFile = {\n id: randomUUID(),\n pid: process.pid,\n command,\n startedAt: new Date().toISOString(),\n };\n let guard: Guard | undefined;\n let result: T | undefined;\n let failed = false;\n let failure: unknown;\n try {\n try {\n guard = await acquireGuard();\n } catch (error) {\n if (!isLockHeldError(error)) throw error;\n throw await describeHeldLock();\n }\n\n let inspection = await inspectLock();\n if (inspection.status === \"valid\" && isStaleLock(inspection.lock)) {\n if (!options.reclaimStale) {\n throw new Error(`pi-sync lock is stale (pid ${inspection.lock.pid}). Run /sync unlock --stale, then retry.`);\n }\n guard.throwIfCompromised();\n const rechecked = await inspectLock();\n if (rechecked.status !== \"valid\" || rechecked.lock.id !== inspection.lock.id || !isStaleLock(rechecked.lock)) {\n throw new Error(\"pi-sync lock changed while preparing transaction recovery; retry.\");\n }\n await fs.rm(lockPath(), { force: true });\n inspection = { status: \"missing\" };\n }\n if (inspection.status === \"valid\") {\n throw new Error(\n `pi-sync is already running (${inspection.lock.command}, pid ${inspection.lock.pid}, started ${inspection.lock.startedAt}).`,\n );\n }\n if (inspection.status === \"unreadable\") {\n throw new Error(\n \"pi-sync lock metadata is unreadable. Run /sync unlock --stale after verifying no sync is running.\",\n );\n }\n\n await fs.writeFile(lockPath(), JSON.stringify(lock, null, \"\\t\"), { flag: \"wx\" });\n guard.throwIfCompromised();\n result = await fn();\n guard.throwIfCompromised();\n } catch (error) {\n failed = true;\n failure = error;\n }\n\n try {\n const current = await readLock();\n if (current?.id === lock.id) await fs.rm(lockPath(), { force: true });\n } catch (error) {\n if (!failed) {\n failed = true;\n failure = error;\n }\n }\n if (guard) {\n const releaseError = await releaseGuard(guard);\n if (releaseError && !failed) {\n failed = true;\n failure = releaseError;\n }\n }\n if (failed) throw failure;\n return result as T;\n}\n\nexport async function inspectLock(): Promise<LockInspection> {\n try {\n const text = await fs.readFile(lockPath(), \"utf8\");\n if (text.trim().length === 0) return { status: \"unreadable\" };\n const parsed = JSON.parse(text) as unknown;\n return isLockFile(parsed) ? { status: \"valid\", lock: parsed } : { status: \"unreadable\" };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return { status: \"missing\" };\n if (error instanceof SyntaxError) return { status: \"unreadable\" };\n throw error;\n }\n}\n\nexport async function readLock(): Promise<LockFile | undefined> {\n const inspection = await inspectLock();\n return inspection.status === \"valid\" ? inspection.lock : undefined;\n}\n\nexport async function lockFileExists(): Promise<boolean> {\n try {\n await fs.stat(lockPath());\n return true;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw error;\n }\n}\n\nexport function isLockGuardHeld() {\n return lockfile.check(lockPath(), {\n fs: LOCKFILE_FS_ADAPTER,\n lockfilePath: `${lockPath()}.guard`,\n realpath: false,\n stale: LOCK_GUARD_STALE_MS,\n });\n}\n\nexport function isStaleLock(lock: LockFile) {\n try {\n process.kill(lock.pid, 0);\n return false;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ESRCH\") return true;\n return Date.now() - Date.parse(lock.startedAt) > LOCK_STALE_MS;\n }\n}\n\nexport async function unlock(ctx: ExtensionCommandContext, options: CommandOptions) {\n throwIfAborted(options.signal);\n await ensureStateDir();\n throwIfAborted(options.signal);\n let guard: Guard;\n try {\n guard = await acquireGuard();\n } catch (error) {\n if (!isLockHeldError(error)) throw error;\n ctx.ui.notify((await describeHeldLock()).message, \"warning\");\n return;\n }\n\n let failed = false;\n let failure: unknown;\n try {\n await unlockGuarded(ctx, options);\n } catch (error) {\n failed = true;\n failure = error;\n }\n const releaseError = await releaseGuard(guard);\n if (releaseError && !failed) {\n failed = true;\n failure = releaseError;\n }\n if (failed) throw failure;\n}\n\nasync function unlockGuarded(ctx: ExtensionCommandContext, options: CommandOptions) {\n throwIfAborted(options.signal);\n let inspection = await inspectLock();\n throwIfAborted(options.signal);\n if (inspection.status === \"missing\") {\n ctx.ui.notify(\"No pi-sync lock is present.\", \"info\");\n return;\n }\n if (inspection.status === \"unreadable\") {\n if (!options.stale) {\n ctx.ui.notify(\n \"Pi-sync lock metadata is unreadable. Use /sync unlock --stale only after verifying no sync is running.\",\n \"warning\",\n );\n return;\n }\n inspection = await inspectLock();\n throwIfAborted(options.signal);\n if (inspection.status === \"unreadable\") {\n // Legacy writers expose an empty file before writing owner metadata, so no\n // automatic test can prove this file is abandoned. The explicit --stale\n // flag is the user's confirmation that no legacy sync is still running.\n throwIfAborted(options.signal);\n await fs.rm(lockPath(), { force: true });\n if (!options.signal?.aborted) {\n ctx.ui.notify(\n \"Removed unreadable pi-sync lock. No settings, files, sync state, or remote data were changed.\",\n \"info\",\n );\n }\n return;\n }\n if (inspection.status === \"missing\") {\n ctx.ui.notify(\"No pi-sync lock is present.\", \"info\");\n return;\n }\n }\n if (!isStaleLock(inspection.lock)) {\n ctx.ui.notify(\"Lock owner is still live; refusing to remove it.\", \"warning\");\n return;\n }\n throwIfAborted(options.signal);\n await fs.rm(lockPath(), { force: true });\n if (!options.signal?.aborted) {\n ctx.ui.notify(\"Removed stale pi-sync lock. No settings, files, sync state, or remote data were changed.\", \"info\");\n }\n}\n\nfunction throwIfAborted(signal?: AbortSignal) {\n if (!signal?.aborted) return;\n throw signal.reason instanceof Error ? signal.reason : new DOMException(\"The operation was aborted\", \"AbortError\");\n}\n\nasync function releaseGuard(guard: Guard) {\n try {\n await guard.release();\n return undefined;\n } catch (error) {\n return guard.isCompromised() ? undefined : error;\n }\n}\n\nasync function acquireGuard(): Promise<Guard> {\n let compromisedError: Error | undefined;\n const release = await lockfile.lock(lockPath(), {\n fs: LOCKFILE_FS_ADAPTER,\n lockfilePath: `${lockPath()}.guard`,\n realpath: false,\n stale: LOCK_GUARD_STALE_MS,\n update: LOCK_GUARD_UPDATE_MS,\n onCompromised: (error) => {\n compromisedError = error;\n },\n });\n return {\n release,\n throwIfCompromised: () => {\n if (compromisedError) throw compromisedError;\n },\n isCompromised: () => compromisedError !== undefined,\n };\n}\n\nasync function describeHeldLock() {\n const current = await readLock();\n if (current && isStaleLock(current)) {\n return new Error(\"pi-sync lock owner exited; retry shortly while the lock guard expires.\");\n }\n if (current) {\n return new Error(\n `Pi-sync is currently running (${current.command}, pid ${current.pid}, started ${current.startedAt}).`,\n );\n }\n return new Error(\"Pi-sync is currently running (lock metadata is unreadable or still being written).\");\n}\n\nfunction isLockHeldError(error: unknown) {\n return (error as NodeJS.ErrnoException).code === \"ELOCKED\";\n}\n\nfunction isLockFile(value: unknown): value is LockFile {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const lock = value as Partial<LockFile>;\n return (\n typeof lock.id === \"string\" &&\n lock.id.length > 0 &&\n Number.isInteger(lock.pid) &&\n (lock.pid ?? 0) > 0 &&\n (lock.pid ?? 0) <= MAX_PROCESS_ID &&\n typeof lock.command === \"string\" &&\n lock.command.length > 0 &&\n typeof lock.startedAt === \"string\" &&\n Number.isFinite(Date.parse(lock.startedAt))\n );\n}\n"],
5
- "mappings": "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",
6
- "names": ["fs", "fs", "throwIfAborted", "fs"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/commands/setup-completions.ts", "../../src/ui/setup/text-input.ts", "../../src/ui/setup/setup-location-ui.ts", "../../src/ui/setup/setup-prompts.ts", "../../src/ui/setup/setup-review.ts", "../../src/ui/setup/git-ui.ts", "../../src/ui/secret-input.ts", "../../src/ui/setup/s3-credentials-ui.ts", "../../src/ui/setup/s3-ui.ts", "../../src/ui/setup/webdav-ui.ts"],
4
- "sourcesContent": ["import { configuredSyncSetupNames } from \"../settings/settings-store.js\";\nimport { setSyncSetupCompletions } from \"./command.js\";\n\nexport async function refreshTargetCompletions() {\n setSyncSetupCompletions(await configuredSyncSetupNames());\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { normalizeS3Bucket, requiredString } from \"../../settings/settings-validation.js\";\nimport { errorMessage } from \"../../sync/sync-errors.js\";\nimport { safeTerminalText } from \"../terminal-text.js\";\n\nexport type ValidateInput = (value: string) => string | Promise<string>;\n\nexport async function requiredExistingBucket(ctx: ExtensionCommandContext, example: string, signal?: AbortSignal) {\n return requiredValueInput(\n ctx,\n \"Existing bucket\\n\\nThe bucket must already exist; pi-sync will not create it.\",\n example,\n signal,\n normalizeS3Bucket,\n );\n}\n\nexport async function requiredInput(\n ctx: ExtensionCommandContext,\n title: string,\n defaultValue: string,\n signal?: AbortSignal,\n validate?: ValidateInput,\n) {\n return promptTextInput(ctx, title, { defaultValue, validate, rejectPlaceholders: true }, signal);\n}\n\nexport async function requiredValueInput(\n ctx: ExtensionCommandContext,\n title: string,\n example: string,\n signal?: AbortSignal,\n validate?: ValidateInput,\n) {\n return promptTextInput(ctx, title, { example, validate, rejectPlaceholders: true }, signal);\n}\n\nexport async function promptTextInput(\n ctx: ExtensionCommandContext,\n title: string,\n options: {\n defaultValue?: string;\n example?: string;\n validate?: ValidateInput;\n rejectPlaceholders?: boolean;\n },\n signal?: AbortSignal,\n) {\n // Pi ignores placeholders. Keep defaults/examples visible; only an explicit blank accepts a default.\n const hint =\n options.defaultValue !== undefined\n ? `Default: ${safeTerminalText(options.defaultValue)} (leave blank to keep)`\n : `Example: ${safeTerminalText(options.example ?? \"\")}\\nEnter your own value; this example is not a default.`;\n while (true) {\n signal?.throwIfAborted();\n const value = await ctx.ui.input(`${title}\\n\\n${hint}`, undefined, { signal });\n signal?.throwIfAborted();\n if (value === undefined) return undefined;\n try {\n const normalized = value.trim() || options.defaultValue;\n if (!normalized) throw new Error(`${title.split(\"\\n\")[0]} is required.`);\n if (options.rejectPlaceholders && /[<>]/u.test(normalized)) {\n throw new Error(\"Replace example placeholders such as <account-id> with your own value.\");\n }\n const checked = requiredString(normalized, title.split(\"\\n\")[0] ?? \"value\");\n const result = options.validate ? await options.validate(checked) : checked;\n signal?.throwIfAborted();\n return result;\n } catch (error) {\n signal?.throwIfAborted();\n ctx.ui.notify(`${errorMessage(error)} Enter a corrected value, or cancel.`, \"warning\");\n }\n }\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { normalizeGitBranch } from \"../../backends/git/git-config.js\";\nimport { readLocalConfigObject } from \"../../settings/settings-store.js\";\nimport type { StorageConnectionSettings, SyncSetupSettings } from \"../../settings/settings-types.js\";\nimport {\n effectiveSyncSetupRemoteIdentity,\n normalizeStoragePath,\n ownRecord,\n} from \"../../settings/settings-validation.js\";\nimport { errorMessage } from \"../../sync/sync-errors.js\";\nimport { safeTerminalText } from \"../terminal-text.js\";\nimport { promptTextInput, requiredExistingBucket, requiredInput, requiredValueInput } from \"./text-input.js\";\n\ninterface ChosenRemoteLocation {\n connectionName: string;\n bucket: string;\n path: string;\n}\n\nexport async function chooseInitialRemoteLocation(\n ctx: ExtensionCommandContext,\n _preset: string,\n setupName: string,\n signal?: AbortSignal,\n): Promise<ChosenRemoteLocation | undefined> {\n const choice = await ctx.ui.select(\n \"Choose storage location\\n\\nUse an existing bucket. ./ stores snapshots at the bucket root; a custom path keeps them in a separate folder.\",\n [\"Use an existing bucket at ./\", \"Customize remote location\", \"Cancel\"],\n { signal },\n );\n if (signal?.aborted || !choice || choice === \"Cancel\") return undefined;\n if (choice === \"Customize remote location\") return chooseCustomRemoteLocation(ctx, setupName, signal);\n const bucket = await requiredExistingBucket(ctx, \"pi-sync\", signal);\n return bucket ? { connectionName: setupName, bucket, path: \"./\" } : undefined;\n}\n\nexport async function chooseAdditionalRemoteLocation(\n ctx: ExtensionCommandContext,\n settings: Record<string, unknown>,\n connectionName: string,\n setupName: string,\n signal?: AbortSignal,\n): Promise<Omit<ChosenRemoteLocation, \"connectionName\"> | undefined> {\n const setups = ownRecord(settings.syncSetups) ?? {};\n const currentSetup = typeof settings.activeSyncSetup === \"string\" ? settings.activeSyncSetup : undefined;\n const candidates = Object.entries(setups)\n .map(([name, value]) => ({ name, storage: ownRecord(ownRecord(value)?.storage) }))\n .filter(\n (item): item is { name: string; storage: Record<string, unknown> } =>\n item.storage?.connection === connectionName && typeof item.storage.bucket === \"string\",\n );\n const source =\n candidates.find((item) => item.name === currentSetup) ??\n candidates.sort((left, right) => left.name.localeCompare(right.name))[0];\n if (source) {\n const suggestedPath = \"./\";\n const sameBucketLabel = `Same bucket as \u201C${safeTerminalText(source.name)}\u201D`;\n const choice = await ctx.ui.select(\n [\n `Storage location for \u201C${safeTerminalText(setupName)}\u201D`,\n \"\",\n `Existing bucket: ${safeTerminalText(String(source.storage.bucket))}`,\n `Remote path: ${safeTerminalText(suggestedPath)}`,\n \"./ uses the bucket root. Use a different path or bucket for independent setups.\",\n ].join(\"\\n\"),\n [sameBucketLabel, \"Use a different bucket\", \"Customize remote location\", \"Cancel\"],\n { signal },\n );\n if (signal?.aborted || !choice || choice === \"Cancel\") return undefined;\n if (choice === sameBucketLabel) {\n return { bucket: String(source.storage.bucket), path: suggestedPath };\n }\n if (choice === \"Use a different bucket\") {\n const bucket = await requiredExistingBucket(ctx, \"pi-sync\", signal);\n return bucket ? { bucket, path: \"./\" } : undefined;\n }\n const custom = await chooseCustomRemoteLocation(ctx, connectionName, signal);\n return custom ? { bucket: custom.bucket, path: custom.path } : undefined;\n }\n\n const location = await chooseInitialRemoteLocation(ctx, \"S3\", setupName, signal);\n return location ? { bucket: location.bucket, path: location.path } : undefined;\n}\n\nasync function chooseCustomRemoteLocation(\n ctx: ExtensionCommandContext,\n connectionName: string,\n signal?: AbortSignal,\n): Promise<ChosenRemoteLocation | undefined> {\n const bucket = await requiredExistingBucket(ctx, \"pi-sync\", signal);\n if (!bucket) return undefined;\n const storagePath = await requiredInput(\n ctx,\n \"Storage path\\n\\nPath inside the bucket, not your local filesystem.\\n./ uses the bucket root. Use different paths for independent setups.\",\n \"./\",\n signal,\n normalizeStoragePath,\n );\n if (!storagePath) return undefined;\n return { connectionName, bucket, path: normalizeStoragePath(storagePath) };\n}\n\n/** Early UI check only; the settings writer still validates uniqueness under its lock. */\nexport async function promptAvailableSetupStorage<T extends SyncSetupSettings[\"storage\"]>(\n ctx: ExtensionCommandContext,\n initial: T,\n signal?: AbortSignal,\n): Promise<T | undefined> {\n let storage = initial;\n while (!signal?.aborted) {\n const settings = await readLocalConfigObject();\n if (signal?.aborted) return undefined;\n const connection = settings?.storageConnections[storage.connection];\n if (!settings || !connection) throw new Error(\"Storage connection changed; reopen setup.\");\n const identity = setupPublicationIdentity(storage, connection);\n const occupied = Object.entries(settings.syncSetups).find(\n ([, setup]) =>\n setupPublicationIdentity(setup.storage, settings.storageConnections[setup.storage.connection]) === identity,\n );\n if (!occupied) return storage;\n const git = connection.type === \"git\";\n const message = `${git ? \"Git branch\" : \"Storage location\"} is already used by \u201C${safeTerminalText(occupied[0])}\u201D. ${git ? \"Use a different branch; pi-sync owns the entire branch.\" : \"Enter a different storage path, or cancel to choose another connection or bucket.\"}`;\n ctx.ui.notify(message, \"warning\");\n const title = `${git ? \"Git branch for the new setup\" : \"Storage path for the new setup\"}\\n\\n${message}`;\n const example = git ? \"pi-sync/work\" : \"backups/work\";\n const value =\n connection.type === \"webdav\"\n ? await promptTextInput(ctx, title, { example }, signal)\n : await requiredValueInput(ctx, title, example, signal);\n if (signal?.aborted || value === undefined) return undefined;\n try {\n storage = git\n ? { ...storage, branch: normalizeGitBranch(value) }\n : { ...storage, path: normalizeStoragePath(value) };\n } catch (error) {\n ctx.ui.notify(safeTerminalText(errorMessage(error)), \"warning\");\n }\n }\n return undefined;\n}\n\nfunction setupPublicationIdentity(storage: SyncSetupSettings[\"storage\"], connection: StorageConnectionSettings) {\n // Git publications own a complete branch tree; changing only its directory is not isolation.\n return effectiveSyncSetupRemoteIdentity(\n {\n storage: connection.type === \"git\" ? { ...storage, path: \"./\" } : storage,\n sync: { include: [], automatic: false },\n },\n connection,\n );\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { readLocalConfigObject } from \"../../settings/settings-store.js\";\nimport { validateConfigName } from \"../../settings/settings-validation.js\";\nimport { DEFAULT_SYNC_INCLUDE } from \"../../sync/sync-policy.js\";\nimport { AUTOMATIC_SYNC_DESCRIPTION } from \"../sync-behavior.js\";\nimport { safeTerminalText } from \"../terminal-text.js\";\n\nexport { AUTOMATIC_SYNC_DESCRIPTION } from \"../sync-behavior.js\";\n\nimport { promptTextInput } from \"./text-input.js\";\n\nexport async function readSetupConnection(name: string, signal?: AbortSignal) {\n const connection = (await readLocalConfigObject())?.storageConnections[name];\n signal?.throwIfAborted();\n if (!connection) throw new Error(\"Storage connection changed; reopen setup.\");\n return connection;\n}\n\nexport async function chooseSetupContent(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n const choice = await ctx.ui.select(\n \"Choose included content\\n\\nRecommended: Pi settings, instructions, skills, prompts, themes, and extensions.\\nMinimal: settings.json and AGENTS.md.\\nReview the exact paths before saving.\",\n [\"Recommended Pi settings\", \"Minimal settings\", \"Cancel\"],\n { signal },\n );\n signal?.throwIfAborted();\n if (!choice || choice === \"Cancel\") return undefined;\n return choice === \"Minimal settings\" ? [\"settings.json\", \"AGENTS.md\"] : [...DEFAULT_SYNC_INCLUDE];\n}\n\nexport async function chooseAutomaticSync(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n const choice = await ctx.ui.select(\n `Automatic sync for this setup\\n\\n${AUTOMATIC_SYNC_DESCRIPTION}`,\n [\"Keep automatic sync off\", \"Enable automatic sync\", \"Cancel\"],\n { signal },\n );\n signal?.throwIfAborted();\n return !choice || choice === \"Cancel\" ? undefined : choice === \"Enable automatic sync\";\n}\n\nexport async function chooseSessions(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n const choice = await ctx.ui.select(\n \"Session conversations\\n\\nSessions can contain prompts, tool output, paths, screenshots, and secrets.\",\n [\"Keep sessions off (recommended)\", \"Include session conversations\", \"Cancel\"],\n { signal },\n );\n signal?.throwIfAborted();\n if (!choice || choice === \"Cancel\") return undefined;\n if (choice !== \"Include session conversations\") return false;\n const confirmed = await ctx.ui.confirm(\n \"Include session conversations?\",\n \"I understand that session JSONL can contain prompts, tool output, paths, screenshots, and secrets.\",\n { signal },\n );\n signal?.throwIfAborted();\n return confirmed ? true : undefined;\n}\n\nexport function includedContentLines(include: readonly string[], sessions = false) {\n const paths = [...include, ...(sessions && !include.includes(\"sessions\") ? [\"sessions\"] : [])];\n return [\n `Included content: ${paths.length} paths`,\n ...paths.map((item) => ` ${safeTerminalText(item)}`),\n `Sessions: ${sessions ? \"On \u2014 privacy warning acknowledged\" : \"Off\"}`,\n ];\n}\n\nexport async function promptResourceName(\n ctx: ExtensionCommandContext,\n kind: \"sync setup\" | \"storage connection\",\n defaultValue: string,\n signal?: AbortSignal,\n literalBrackets = false,\n) {\n return promptTextInput(\n ctx,\n `Name this ${kind}\\n\\nA local label, such as home or work.`,\n {\n defaultValue,\n rejectPlaceholders: !literalBrackets,\n validate: async (name) => {\n validateConfigName(name, kind);\n const settings = await readLocalConfigObject();\n signal?.throwIfAborted();\n const names = kind === \"sync setup\" ? settings?.syncSetups : settings?.storageConnections;\n if (names && Object.hasOwn(names, name)) {\n throw new Error(`A ${kind} with this name already exists. Choose a different name.`);\n }\n return name;\n },\n },\n signal,\n );\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { defineMenu, runMenu } from \"@narumitw/pi-tui-kit\";\nimport { syncErrorGuidance } from \"../../sync/sync-error-guidance.js\";\n\n/** A settings draft is committed only after review; retryable I/O failures retain the same draft. */\nexport async function saveReviewedDraft(\n ctx: ExtensionCommandContext,\n title: string,\n lines: readonly string[],\n label: string,\n save: (signal: AbortSignal) => Promise<unknown>,\n signal?: AbortSignal,\n) {\n let saved = false;\n let failure: unknown;\n let failureText: string | undefined;\n const menu = defineMenu<undefined, \"review\", \"save\", ExtensionCommandContext>({\n start: \"review\",\n screens: {\n review: () => ({\n kind: \"review\",\n title,\n content: [...(failureText ? [failureText, \"\"] : []), ...lines].join(\"\\n\"),\n lines: [\"Review before saving. Back cancels this draft.\"],\n format: { kind: \"text\" },\n viewportSize: \"adaptive\",\n confirm: { id: \"save\", label, action: \"save\" },\n hint: \"back\",\n }),\n },\n actions: {\n save: async ({ signal: actionSignal }) => {\n try {\n actionSignal.throwIfAborted();\n await save(actionSignal);\n saved = true;\n return { kind: \"close\" };\n } catch (error) {\n if (actionSignal.aborted) return { kind: \"close\" };\n // Do not silently rebase a stale review or overwrite an invalid settings file.\n // The caller must reopen current settings for those failures.\n if (!retryableSettingsError(error)) {\n failure = error;\n return { kind: \"close\" };\n }\n failureText = `Not saved. ${syncErrorGuidance(error)}\\nYour draft is retained. Fix the problem, then save again, or cancel.`;\n ctx.ui.notify(failureText, \"error\");\n return { kind: \"stay\" };\n }\n },\n },\n });\n const result = await runMenu(ctx, menu, {\n getState: () => undefined,\n signal,\n isCurrent: () => !signal?.aborted,\n });\n if (signal?.aborted) return false;\n if (failure) throw failure;\n if (result.kind === \"error\") throw result.error;\n return saved;\n}\n\nfunction retryableSettingsError(error: unknown) {\n const code = (error as NodeJS.ErrnoException | undefined)?.code;\n return (\n code !== undefined && [\"EACCES\", \"EPERM\", \"ENOSPC\", \"EBUSY\", \"EIO\", \"EMFILE\", \"ENFILE\", \"EROFS\"].includes(code)\n );\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { normalizeGitBranch, normalizeGitDirectory, normalizeGitRemote } from \"../../backends/git/git-config.js\";\nimport {\n addStorageConnection,\n addSyncSetup,\n saveNewV3Settings,\n updateStorageConnection,\n updateSyncSetup,\n} from \"../../settings/settings-management.js\";\nimport type { PartialConfig } from \"../../settings/settings-types.js\";\nimport { automaticSyncSummary } from \"../automatic-sync-summary.js\";\nimport { safeTerminalText } from \"../terminal-text.js\";\nimport { promptAvailableSetupStorage } from \"./setup-location-ui.js\";\nimport {\n chooseAutomaticSync,\n chooseSetupContent,\n includedContentLines,\n promptResourceName,\n readSetupConnection,\n} from \"./setup-prompts.js\";\nimport { saveReviewedDraft } from \"./setup-review.js\";\nimport { requiredInput, requiredValueInput } from \"./text-input.js\";\n\nexport async function showGitSetup(ctx: ExtensionCommandContext, targetName: string, signal?: AbortSignal) {\n const remote = await promptGitRemote(ctx, signal);\n if (!remote) return false;\n const destination = await promptGitDestination(ctx, signal);\n if (!destination) return false;\n const include = await chooseSetupContent(ctx, signal);\n if (!include) return false;\n const automatic = await chooseAutomaticSync(ctx, signal);\n if (automatic === undefined) return false;\n const saved = await saveReviewedDraft(\n ctx,\n \"Review Git sync setup\",\n [\n `Sync setup: ${safeTerminalText(targetName)}`,\n `Storage connection: ${safeTerminalText(targetName)} (Git)`,\n `Remote: ${safeTerminalText(remote)}`,\n `Sync branch: ${safeTerminalText(destination.branch)}`,\n `Storage location: ${safeTerminalText(destination.directory)}`,\n ...includedContentLines(include),\n `Automatic sync: ${automaticSyncSummary(automatic)}`,\n \"Authentication: existing Git credential helper or SSH configuration (not stored by pi-sync).\",\n \"pi-sync manages the entire branch. The repository must already exist; a new branch is created on first push.\",\n \"Saving does not contact remote storage or start syncing.\",\n ],\n \"Save setup\",\n (saveSignal) =>\n saveNewV3Settings(\n {\n setupName: targetName,\n connectionName: targetName,\n connection: { type: \"git\", remote },\n setup: {\n storage: {\n connection: targetName,\n branch: destination.branch,\n path: destination.directory,\n },\n sync: { include, automatic },\n },\n },\n saveSignal,\n ),\n signal,\n );\n if (saved && !signal?.aborted)\n ctx.ui.notify(`Saved Git sync setup \u201C${safeTerminalText(targetName)}\u201D. Choose Sync now to start.`, \"info\");\n return saved;\n}\n\nexport async function showAddGitStorageProfile(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n const name = await promptResourceName(ctx, \"storage connection\", \"git\", signal);\n if (!name) return false;\n const remote = await promptGitRemote(ctx, signal);\n if (!remote) return false;\n const saved = await saveReviewedDraft(\n ctx,\n \"Review storage connection\",\n [\n `Name: ${safeTerminalText(name)}`,\n \"Type: Git\",\n `Remote: ${safeTerminalText(remote)}`,\n \"Credentials: existing Git/SSH authentication (not stored)\",\n \"Adding a connection does not contact the remote or start syncing.\",\n ],\n \"Add storage connection\",\n (saveSignal) => addStorageConnection(name, { type: \"git\", remote }, saveSignal),\n signal,\n );\n if (saved && !signal?.aborted) ctx.ui.notify(`Added storage connection \u201C${safeTerminalText(name)}\u201D.`, \"info\");\n return saved;\n}\n\nexport async function showEditGitStorageProfile(\n ctx: ExtensionCommandContext,\n name: string,\n profile: Record<string, unknown>,\n signal?: AbortSignal,\n affectedSetups?: string[],\n) {\n const remote = await promptGitRemote(ctx, signal, typeof profile.remote === \"string\" ? profile.remote : undefined);\n if (!remote) return false;\n const saved = await saveReviewedDraft(\n ctx,\n \"Review storage connection\",\n [\n `Storage connection: ${safeTerminalText(name)}`,\n `Remote: ${safeTerminalText(String(profile.remote ?? \"missing\"))} \u2192 ${safeTerminalText(remote)}`,\n `Affected sync setups: ${affectedSetups?.length ? affectedSetups.map(safeTerminalText).join(\", \") : \"None\"}`,\n \"Saving changes future storage access for every affected setup; it does not move or delete remote history.\",\n ],\n \"Save storage connection\",\n (saveSignal) =>\n updateStorageConnection(\n name,\n (current) => {\n if (current.type !== \"git\" || current.remote !== profile.remote)\n throw new Error(\"Storage connection changed while it was open; reopen it.\");\n return { ...current, remote };\n },\n affectedSetups,\n saveSignal,\n ),\n signal,\n );\n if (saved && !signal?.aborted) ctx.ui.notify(`Saved storage connection \u201C${safeTerminalText(name)}\u201D.`, \"info\");\n return saved;\n}\n\nexport async function showAddGitTarget(\n ctx: ExtensionCommandContext,\n name: string,\n profile: string,\n signal?: AbortSignal,\n) {\n const selected = await promptGitDestination(ctx, signal);\n if (!selected) return false;\n const storage = await promptAvailableSetupStorage(\n ctx,\n { connection: profile, branch: selected.branch, path: selected.directory },\n signal,\n );\n if (!storage) return false;\n const include = await chooseSetupContent(ctx, signal);\n if (!include) return false;\n const automatic = await chooseAutomaticSync(ctx, signal);\n if (automatic === undefined) return false;\n const connection = await readSetupConnection(profile, signal);\n if (connection?.type !== \"git\") throw new Error(\"Storage connection changed; reopen setup.\");\n const saved = await saveReviewedDraft(\n ctx,\n \"Review Git sync setup\",\n [\n `Sync setup: ${safeTerminalText(name)}`,\n `Storage connection: ${safeTerminalText(profile)}`,\n `Remote: ${safeTerminalText(connection.remote)}`,\n `Sync branch: ${safeTerminalText(storage.branch)}`,\n `Storage location: ${safeTerminalText(storage.path)}`,\n ...includedContentLines(include),\n `Automatic sync: ${automaticSyncSummary(automatic)}`,\n \"pi-sync manages the entire branch. Adding this setup does not sync or modify remote data.\",\n ],\n \"Add sync setup\",\n (saveSignal) => addSyncSetup(name, { storage, sync: { include, automatic } }, saveSignal, connection),\n signal,\n );\n if (saved && !signal?.aborted) ctx.ui.notify(`Added sync setup \u201C${safeTerminalText(name)}\u201D.`, \"info\");\n return saved;\n}\n\nexport async function showEditGitTarget(ctx: ExtensionCommandContext, partial: PartialConfig, signal?: AbortSignal) {\n let destination = await promptGitDestination(ctx, signal, partial);\n if (!destination) return false;\n while (destination.directory !== partial.storagePath && destination.branch === partial.branch) {\n ctx.ui.notify(\n \"Changing a Git storage path requires a new Git branch so the existing branch remains readable.\",\n \"warning\",\n );\n const branch = await requiredValueInput(\n ctx,\n \"New Git branch\\n\\nKeep the previous branch unchanged; enter a new branch for this path.\",\n \"pi-sync/archive\",\n signal,\n normalizeGitBranch,\n );\n if (!branch) return false;\n destination = { ...destination, branch };\n }\n const chosen = destination;\n const connection = await readSetupConnection(partial.connectionName, signal);\n if (connection.type !== \"git\") throw new Error(\"Storage connection changed; reopen setup.\");\n const saved = await saveReviewedDraft(\n ctx,\n \"Review sync setup\",\n [\n `Sync setup: ${safeTerminalText(partial.setupName)}`,\n `Storage connection: ${safeTerminalText(partial.connectionName)}`,\n `Remote: ${safeTerminalText(connection.remote)}`,\n `Branch: ${safeTerminalText(partial.branch ?? \"missing\")} \u2192 ${safeTerminalText(chosen.branch)}`,\n `Storage path: ${safeTerminalText(partial.storagePath)} \u2192 ${safeTerminalText(chosen.directory)}`,\n \"Saving changes the future storage location only; it does not move or delete remote history.\",\n ],\n \"Save sync setup\",\n (saveSignal) =>\n updateSyncSetup(\n partial.setupName,\n (setup) => {\n if (typeof setup.storage.branch !== \"string\") throw new Error(\"Sync setup storage type changed; reopen it.\");\n return {\n ...setup,\n storage: { ...setup.storage, branch: chosen.branch, path: chosen.directory },\n };\n },\n { expectedStorage: partial, expectedConnection: connection, signal: saveSignal },\n ),\n signal,\n );\n if (saved && !signal?.aborted) ctx.ui.notify(`Saved sync setup \u201C${safeTerminalText(partial.setupName)}\u201D.`, \"info\");\n return saved;\n}\n\nasync function promptGitRemote(ctx: ExtensionCommandContext, signal?: AbortSignal, current?: string) {\n const title =\n \"Git remote URL (SSH or HTTPS)\\n\\nUse an existing private repository with Git/SSH authentication already configured.\";\n const validate = (value: string) => {\n const remote = normalizeGitRemote(value);\n if (!remote) throw new Error(\"Git remote URL is required.\");\n return remote;\n };\n return current\n ? requiredInput(ctx, title, current, signal, validate)\n : requiredValueInput(\n ctx,\n title,\n \"git@github.com:owner/private-pi-sync.git (SSH) or https://github.com/owner/private-pi-sync.git (HTTPS)\",\n signal,\n validate,\n );\n}\n\nasync function promptGitDestination(\n ctx: ExtensionCommandContext,\n signal?: AbortSignal,\n current: Partial<PartialConfig> = {},\n) {\n const branch = await requiredInput(\n ctx,\n \"Git branch for sync snapshots\\n\\npi-sync manages this entire branch, not your local working branch.\\nUse a new branch or one already used by pi-sync; unrelated content is rejected.\",\n current.branch ?? \"main\",\n signal,\n normalizeGitBranch,\n );\n if (!branch) return undefined;\n const directory = await requiredInput(\n ctx,\n \"Git storage path\\n\\nRelative to the repository root, not your local filesystem.\\n./ stores manifest.json and files/ at the repository root.\",\n current.storagePath ?? \"./\",\n signal,\n normalizeGitDirectory,\n );\n return directory ? { branch, directory } : undefined;\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport {\n CURSOR_MARKER,\n decodeKittyPrintable,\n type Focusable,\n Key,\n type KeybindingsManager,\n matchesKey,\n Text,\n truncateToWidth,\n} from \"@earendil-works/pi-tui\";\nimport { formatInteractionHints, runCustomInteraction } from \"@narumitw/pi-tui-kit\";\n\nconst MASK = \"\u2022\";\n\nexport async function promptSecret(\n ctx: ExtensionCommandContext,\n title: string,\n options: { required?: boolean; signal?: AbortSignal } = { required: true },\n) {\n if (ctx.mode !== \"tui\" || options.signal?.aborted) return undefined;\n const result = await runCustomInteraction<string | undefined>(ctx, {\n signal: options.signal,\n isCurrent: () => !options.signal?.aborted,\n create: ({ tui, theme, keybindings, complete }) => {\n const heading = new Text(\"\", 0, 0);\n const hint = new Text(\"\", 0, 0);\n const interactionHint = formatInteractionHints(keybindings, [\n {\n keys: keybindings.getKeys(\"tui.input.submit\").filter((key) => !hasControlCharacter(key)),\n label: \"continue\",\n },\n {\n keys: [...keybindings.getKeys(\"tui.select.cancel\").filter((key) => !hasControlCharacter(key)), \"ctrl+c\"],\n label: \"cancel\",\n },\n ]);\n const applyTheme = () => {\n heading.setText(theme.fg(\"accent\", theme.bold(title)));\n hint.setText(theme.fg(\"dim\", `${interactionHint} \u2022 Input is hidden`));\n };\n applyTheme();\n const input = new MaskedInput(keybindings);\n const component: Focusable & {\n render(width: number): string[];\n invalidate(): void;\n handleInput(data: string): void;\n dispose(): void;\n } = {\n get focused() {\n return input.focused;\n },\n set focused(focused: boolean) {\n input.focused = focused;\n },\n render(width: number) {\n const safeWidth = Math.max(1, width);\n return [...heading.render(safeWidth), ...input.render(safeWidth), ...hint.render(safeWidth)].map((line) =>\n truncateToWidth(line, safeWidth),\n );\n },\n invalidate() {\n applyTheme();\n heading.invalidate();\n input.invalidate();\n hint.invalidate();\n },\n handleInput(data: string) {\n if (matchesKey(data, Key.ctrl(\"c\"))) {\n complete(undefined);\n } else if (input.isPasting || data.includes(\"\\u001b[200~\")) {\n input.handleInput(data);\n } else if (keybindings.matches(data, \"tui.select.cancel\")) {\n complete(undefined);\n } else if (keybindings.matches(data, \"tui.input.submit\")) {\n if (options.required !== false && input.getValue().length === 0) {\n ctx.ui.notify(`${title} is required. Enter a value, or cancel.`, \"warning\");\n } else if (hasControlCharacter(input.getValue())) {\n ctx.ui.notify(\n `${title} contains control characters. Remove them or re-enter the value, then continue.`,\n \"warning\",\n );\n } else complete(input.getValue());\n } else input.handleInput(data);\n tui.requestRender();\n },\n dispose() {\n input.clear();\n },\n };\n return component;\n },\n });\n if (result.kind === \"error\") throw result.error;\n if (result.kind !== \"completed\" || result.value === undefined) return undefined;\n const value = result.value;\n if (options.required !== false && value.length === 0) {\n ctx.ui.notify(`${title} is required.`, \"warning\");\n return undefined;\n }\n return value;\n}\n\nclass MaskedInput implements Focusable {\n focused = false;\n private value: string[] = [];\n private cursor = 0;\n private paste = \"\";\n private pasting = false;\n\n constructor(private readonly keybindings: KeybindingsManager) {}\n\n get isPasting() {\n return this.pasting;\n }\n\n getValue() {\n return this.value.join(\"\");\n }\n\n handleInput(data: string) {\n if (data.includes(\"\\u001b[200~\")) {\n this.pasting = true;\n this.paste = \"\";\n data = data.replace(\"\\u001b[200~\", \"\");\n }\n if (this.pasting) {\n this.paste += data;\n const end = this.paste.indexOf(\"\\u001b[201~\");\n if (end < 0) return;\n const pasted = this.paste\n .slice(0, end)\n .replace(/[\\r\\n]/gu, \"\")\n .replace(/\\t/gu, \" \");\n this.insert(pasted);\n const remaining = this.paste.slice(end + 6);\n this.paste = \"\";\n this.pasting = false;\n if (remaining) this.handleInput(remaining);\n return;\n }\n if (this.keybindings.matches(data, \"tui.editor.deleteCharBackward\")) {\n if (this.cursor > 0) this.value.splice(--this.cursor, 1);\n return;\n }\n if (this.keybindings.matches(data, \"tui.editor.deleteCharForward\")) {\n if (this.cursor < this.value.length) this.value.splice(this.cursor, 1);\n return;\n }\n if (this.keybindings.matches(data, \"tui.editor.cursorLeft\")) {\n this.cursor = Math.max(0, this.cursor - 1);\n return;\n }\n if (this.keybindings.matches(data, \"tui.editor.cursorRight\")) {\n this.cursor = Math.min(this.value.length, this.cursor + 1);\n return;\n }\n if (this.keybindings.matches(data, \"tui.editor.cursorLineStart\")) {\n this.cursor = 0;\n return;\n }\n if (this.keybindings.matches(data, \"tui.editor.cursorLineEnd\")) {\n this.cursor = this.value.length;\n return;\n }\n if (this.keybindings.matches(data, \"tui.editor.deleteToLineStart\")) {\n this.value.splice(0, this.cursor);\n this.cursor = 0;\n return;\n }\n if (this.keybindings.matches(data, \"tui.editor.deleteToLineEnd\")) {\n this.value.splice(this.cursor);\n return;\n }\n const printable = decodeKittyPrintable(data) ?? data;\n if (!hasControlCharacter(printable)) this.insert(printable);\n }\n\n render(width: number) {\n const prompt = \"> \";\n const available = width - prompt.length;\n if (available <= 0) return [truncateToWidth(prompt, Math.max(1, width))];\n const contentWidth = Math.max(0, available - 1);\n let start = 0;\n if (this.value.length > contentWidth) {\n start = Math.max(0, Math.min(this.cursor - Math.floor(contentWidth / 2), this.value.length - contentWidth));\n }\n const end = Math.min(this.value.length, start + contentWidth);\n const visibleCursor = Math.max(0, Math.min(this.cursor - start, end - start));\n const masks = Array.from({ length: end - start }, () => MASK);\n const before = masks.slice(0, visibleCursor).join(\"\");\n const atCursor = visibleCursor < masks.length ? MASK : \" \";\n const after = masks.slice(visibleCursor + (visibleCursor < masks.length ? 1 : 0)).join(\"\");\n const marker = this.focused ? CURSOR_MARKER : \"\";\n const line = `${prompt}${before}${marker}\\u001b[7m${atCursor}\\u001b[27m${after}`;\n return [truncateToWidth(line, width, \"\")];\n }\n\n invalidate() {}\n\n clear() {\n this.value.fill(\"\");\n this.value = [];\n this.paste = \"\";\n this.cursor = 0;\n this.pasting = false;\n }\n\n private insert(value: string) {\n const characters = Array.from(value);\n this.value.splice(this.cursor, 0, ...characters);\n this.cursor += characters.length;\n }\n}\n\nfunction hasControlCharacter(value: string) {\n return [...value].some((character) => {\n const code = character.codePointAt(0) ?? 0;\n return code < 0x20 || (code >= 0x7f && code <= 0x9f);\n });\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { promptSecret } from \"../secret-input.js\";\nimport { requiredValueInput } from \"./text-input.js\";\n\nexport interface ChosenS3Credentials {\n profileFields: { accessKeyId?: string; secretAccessKey?: string };\n summary: string;\n ready: boolean;\n replace?: boolean;\n}\n\nexport async function chooseS3CredentialUpdate(\n ctx: ExtensionCommandContext,\n profile: Record<string, unknown>,\n signal?: AbortSignal,\n) {\n const hasStored =\n typeof profile.accessKeyId === \"string\" &&\n profile.accessKeyId.length > 0 &&\n typeof profile.secretAccessKey === \"string\" &&\n profile.secretAccessKey.length > 0;\n if (hasStored) {\n const action = await ctx.ui.select(\"Credentials\", [\"Keep current credentials\", \"Replace credentials\", \"Cancel\"], {\n signal,\n });\n throwIfAborted(signal);\n if (!action || action === \"Cancel\") return undefined;\n if (action === \"Keep current credentials\") {\n return { profileFields: {}, summary: \"Unchanged (values hidden)\", ready: true };\n }\n }\n const selected = await chooseS3Credentials(ctx, signal);\n return selected ? { ...selected, replace: true } : undefined;\n}\n\nexport function applyS3CredentialUpdate(profile: Record<string, unknown>, credentials: ChosenS3Credentials) {\n const next = { ...profile };\n if (credentials.replace) {\n delete next.accessKeyId;\n delete next.secretAccessKey;\n delete next.sessionToken;\n }\n return { ...next, ...credentials.profileFields };\n}\n\nexport async function chooseS3Credentials(\n ctx: ExtensionCommandContext,\n signal?: AbortSignal,\n): Promise<ChosenS3Credentials | undefined> {\n const choice = await ctx.ui.select(\n \"Credentials\\n\\nCredentials are stored in the private pi-sync settings file. Secret values are masked during input and never shown afterward.\",\n [\"Store credentials privately\", \"Cancel\"],\n { signal },\n );\n throwIfAborted(signal);\n if (choice !== \"Store credentials privately\") return undefined;\n const accessKeyId = await requiredValueInput(\n ctx,\n \"Access key ID\\n\\nUse the S3 API access key ID issued by your provider, not the secret access key.\",\n \"access-key-id\",\n signal,\n );\n if (!accessKeyId) return undefined;\n const secretAccessKey = await promptSecret(ctx, \"Secret access key\", { signal });\n throwIfAborted(signal);\n if (secretAccessKey === undefined) return undefined;\n return {\n profileFields: { accessKeyId, secretAccessKey },\n summary: \"Stored privately (values hidden)\",\n ready: true,\n };\n}\n\nfunction throwIfAborted(signal?: AbortSignal) {\n if (!signal?.aborted) return;\n throw signal.reason instanceof Error ? signal.reason : new DOMException(\"The operation was aborted\", \"AbortError\");\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { refreshTargetCompletions } from \"../../commands/setup-completions.js\";\nimport { addSyncSetup, saveNewV3Settings, updateSyncSetup } from \"../../settings/settings-management.js\";\nimport type { PartialConfig } from \"../../settings/settings-types.js\";\nimport { normalizeS3Bucket, normalizeS3Endpoint, normalizeStoragePath } from \"../../settings/settings-validation.js\";\nimport { automaticSyncSummary } from \"../automatic-sync-summary.js\";\nimport { safeTerminalText } from \"../terminal-text.js\";\nimport { chooseS3Credentials } from \"./s3-credentials-ui.js\";\nimport {\n chooseAdditionalRemoteLocation,\n chooseInitialRemoteLocation,\n promptAvailableSetupStorage,\n} from \"./setup-location-ui.js\";\nimport {\n chooseAutomaticSync,\n chooseSessions,\n chooseSetupContent,\n includedContentLines,\n readSetupConnection,\n} from \"./setup-prompts.js\";\nimport { saveReviewedDraft } from \"./setup-review.js\";\nimport { requiredInput, requiredValueInput } from \"./text-input.js\";\n\nexport async function showS3Setup(\n ctx: ExtensionCommandContext,\n preset: string,\n targetName: string,\n signal?: AbortSignal,\n) {\n const endpoint = await requiredValueInput(\n ctx,\n preset === \"Cloudflare R2\"\n ? \"Cloudflare R2 endpoint\\n\\nCopy the S3 API endpoint from your R2 account; replace <account-id>.\"\n : \"S3-compatible endpoint\\n\\nUse your provider's S3 API URL, not its web console.\",\n preset === \"Cloudflare R2\" ? \"https://<account-id>.r2.cloudflarestorage.com\" : \"https://s3.example.com\",\n signal,\n normalizeS3Endpoint,\n );\n if (!endpoint) return false;\n const region =\n preset === \"Cloudflare R2\"\n ? \"auto\"\n : await requiredInput(\n ctx,\n \"Storage region\\n\\nUse the region assigned to your bucket by the provider.\",\n \"us-east-1\",\n signal,\n );\n if (!region) return false;\n const location = await chooseInitialRemoteLocation(ctx, preset, targetName, signal);\n if (!location) return false;\n const credentials = await chooseS3Credentials(ctx, signal);\n if (!credentials) return false;\n const include = await chooseSetupContent(ctx, signal);\n if (!include) return false;\n const automatic = await chooseAutomaticSync(ctx, signal);\n if (automatic === undefined) return false;\n const sessions = await chooseSessions(ctx, signal);\n if (sessions === undefined) return false;\n const saved = await saveReviewedDraft(\n ctx,\n \"Review sync setup\",\n [\n `Sync setup: ${safeTerminalText(targetName)}`,\n `Storage connection: ${safeTerminalText(location.connectionName)} (${preset})`,\n `Endpoint: ${safeTerminalText(endpoint)}`,\n `Region: ${safeTerminalText(region)}`,\n `Bucket: ${safeTerminalText(location.bucket)}`,\n `Storage location: ${safeTerminalText(location.path)}`,\n ...includedContentLines(include, sessions),\n `Automatic sync: ${automaticSyncSummary(automatic)}`,\n `Credentials: ${credentials.summary}`,\n \"The bucket must already exist. Saving does not contact remote storage or start syncing.\",\n ],\n \"Save sync setup\",\n (saveSignal) =>\n saveNewV3Settings(\n {\n setupName: targetName,\n connectionName: location.connectionName,\n connection: {\n type: \"s3\",\n endpoint,\n region,\n credentials: {\n accessKeyId: credentials.profileFields.accessKeyId ?? \"\",\n secretAccessKey: credentials.profileFields.secretAccessKey ?? \"\",\n },\n },\n setup: {\n storage: {\n connection: location.connectionName,\n bucket: location.bucket,\n path: location.path,\n },\n sync: { include: [...include, ...(sessions ? [\"sessions\"] : [])], automatic },\n },\n },\n saveSignal,\n ),\n signal,\n );\n if (!saved || signal?.aborted) return false;\n await refreshTargetCompletions();\n if (!signal?.aborted)\n ctx.ui.notify(`Sync setup \u201C${safeTerminalText(targetName)}\u201D saved. Choose Sync now to start.`, \"info\");\n return true;\n}\n\nexport async function showAddS3Target(\n ctx: ExtensionCommandContext,\n raw: Record<string, unknown>,\n profile: string,\n name: string,\n signal?: AbortSignal,\n) {\n const location = await chooseAdditionalRemoteLocation(ctx, raw, profile, name, signal);\n if (!location) return;\n const storage = await promptAvailableSetupStorage(ctx, { connection: profile, ...location }, signal);\n if (!storage) return;\n const include = await chooseSetupContent(ctx, signal);\n if (!include) return;\n const automatic = await chooseAutomaticSync(ctx, signal);\n if (automatic === undefined) return;\n const connection = await readSetupConnection(profile, signal);\n if (connection.type !== \"s3\") throw new Error(\"Storage connection changed; reopen setup.\");\n const saved = await saveReviewedDraft(\n ctx,\n \"Review new sync setup\",\n [\n `Sync setup: ${safeTerminalText(name)}`,\n `Storage connection: ${safeTerminalText(profile)}`,\n `Endpoint: ${safeTerminalText(connection.endpoint)}`,\n `Bucket: ${safeTerminalText(storage.bucket)}`,\n `Storage location: ${safeTerminalText(storage.path)}`,\n ...includedContentLines(include),\n `Automatic sync: ${automaticSyncSummary(automatic)}`,\n \"Only the current setup is checked at startup. Shutdown can push selected content when sessions are included.\",\n \"The bucket must already exist. Adding this setup does not sync or modify remote data.\",\n ],\n \"Add sync setup\",\n (saveSignal) => addSyncSetup(name, { storage, sync: { include, automatic } }, saveSignal, connection),\n signal,\n );\n if (!saved || signal?.aborted) return;\n await refreshTargetCompletions();\n if (!signal?.aborted) ctx.ui.notify(`Added sync setup \u201C${safeTerminalText(name)}\u201D.`, \"info\");\n}\n\nexport async function showEditS3Target(ctx: ExtensionCommandContext, partial: PartialConfig, signal?: AbortSignal) {\n const bucket = await requiredInput(\n ctx,\n \"Bucket\\n\\nUse an existing bucket; pi-sync will not create it.\",\n partial.bucket ?? \"pi-sync\",\n signal,\n normalizeS3Bucket,\n );\n if (!bucket) return;\n const storagePath = await requiredInput(\n ctx,\n \"Storage path\\n\\nPath inside the bucket, not your local filesystem. ./ uses the bucket root.\",\n partial.storagePath,\n signal,\n normalizeStoragePath,\n );\n if (!storagePath) return;\n const connection = await readSetupConnection(partial.connectionName, signal);\n if (connection.type !== \"s3\") throw new Error(\"Storage connection changed; reopen setup.\");\n const saved = await saveReviewedDraft(\n ctx,\n \"Review sync setup\",\n [\n `Sync setup: ${safeTerminalText(partial.setupName)}`,\n `Storage connection: ${safeTerminalText(partial.connectionName)}`,\n `Endpoint: ${safeTerminalText(connection.endpoint)}`,\n `Bucket: ${safeTerminalText(partial.bucket ?? \"missing\")} \u2192 ${safeTerminalText(bucket)}`,\n `Storage path: ${safeTerminalText(partial.storagePath)} \u2192 ${safeTerminalText(storagePath)}`,\n \"Saving changes the future storage location only; it does not move or delete remote data.\",\n ],\n \"Save sync setup\",\n (saveSignal) =>\n updateSyncSetup(\n partial.setupName,\n (setup) => {\n if (typeof setup.storage.bucket !== \"string\") throw new Error(\"Sync setup storage type changed; reopen it.\");\n return { ...setup, storage: { ...setup.storage, bucket, path: storagePath } };\n },\n { expectedStorage: partial, expectedConnection: connection, signal: saveSignal },\n ),\n signal,\n );\n if (saved && !signal?.aborted) ctx.ui.notify(`Saved sync setup \u201C${safeTerminalText(partial.setupName)}\u201D.`, \"info\");\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport {\n normalizeWebDavPath,\n normalizeWebDavUrl,\n validateWebDavCredentials,\n} from \"../../backends/webdav/webdav-config.js\";\nimport {\n addStorageConnection,\n addSyncSetup,\n saveNewV3Settings,\n updateStorageConnection,\n updateSyncSetup,\n} from \"../../settings/settings-management.js\";\nimport type { PartialConfig } from \"../../settings/settings-types.js\";\nimport { automaticSyncSummary } from \"../automatic-sync-summary.js\";\nimport { promptSecret } from \"../secret-input.js\";\nimport { safeTerminalText as safe } from \"../terminal-text.js\";\nimport { promptAvailableSetupStorage } from \"./setup-location-ui.js\";\nimport {\n chooseAutomaticSync,\n chooseSessions,\n chooseSetupContent,\n includedContentLines,\n promptResourceName,\n readSetupConnection,\n} from \"./setup-prompts.js\";\nimport { saveReviewedDraft } from \"./setup-review.js\";\nimport { promptTextInput } from \"./text-input.js\";\n\nexport async function showWebDavSetup(ctx: ExtensionCommandContext, targetName: string, signal?: AbortSignal) {\n const url = await promptWebDavUrl(ctx, signal);\n if (!url) return false;\n const username = await promptUsername(ctx, signal);\n if (!username) return false;\n const password = await promptSecret(ctx, \"WebDAV password\", { signal });\n signal?.throwIfAborted();\n if (password === undefined) return false;\n const remotePath = await chooseDestination(ctx, signal);\n if (!remotePath) return false;\n const include = await chooseSetupContent(ctx, signal);\n if (!include) return false;\n const automatic = await chooseAutomaticSync(ctx, signal);\n if (automatic === undefined) return false;\n const sessions = await chooseSessions(ctx, signal);\n if (sessions === undefined) return false;\n const saved = await saveReviewedDraft(\n ctx,\n \"Review WebDAV setup\",\n [\n `Sync setup: ${safe(targetName)}`,\n `Storage connection: ${safe(targetName)} (WebDAV)`,\n `URL: ${safe(url)}`,\n `Storage location: ${safe(remotePath)}`,\n \"Username and password: stored privately (values hidden)\",\n ...includedContentLines(include, sessions),\n `Automatic sync: ${automaticSyncSummary(automatic)}`,\n \"Check setup tests whether this server can safely save sync updates using a temporary probe.\",\n \"Saving does not contact remote storage or start syncing.\",\n ],\n \"Save setup\",\n (saveSignal) =>\n saveNewV3Settings(\n {\n setupName: targetName,\n connectionName: targetName,\n connection: { type: \"webdav\", url, credentials: { username, password } },\n setup: {\n storage: { connection: targetName, path: remotePath },\n sync: { include: [...include, ...(sessions ? [\"sessions\"] : [])], automatic },\n },\n },\n saveSignal,\n ),\n signal,\n );\n if (saved && !signal?.aborted)\n ctx.ui.notify(`Sync setup \u201C${safe(targetName)}\u201D saved. Choose Sync now to start.`, \"info\");\n return saved;\n}\n\nexport async function showAddWebDavTarget(\n ctx: ExtensionCommandContext,\n name: string,\n profile: string,\n signal?: AbortSignal,\n) {\n const remotePath = await chooseDestination(ctx, signal);\n if (!remotePath) return false;\n const storage = await promptAvailableSetupStorage(ctx, { connection: profile, path: remotePath }, signal);\n if (!storage) return false;\n const include = await chooseSetupContent(ctx, signal);\n if (!include) return false;\n const automatic = await chooseAutomaticSync(ctx, signal);\n if (automatic === undefined) return false;\n const connection = await readSetupConnection(profile, signal);\n if (connection.type !== \"webdav\") throw new Error(\"Storage connection changed; reopen setup.\");\n const saved = await saveReviewedDraft(\n ctx,\n \"Review WebDAV sync setup\",\n [\n `Sync setup: ${safe(name)}`,\n `Storage connection: ${safe(profile)}`,\n `URL: ${safe(connection.url)}`,\n `Storage location: ${safe(storage.path)}`,\n ...includedContentLines(include),\n `Automatic sync: ${automaticSyncSummary(automatic)}`,\n \"Adding this setup does not sync or modify remote data.\",\n ],\n \"Add sync setup\",\n (saveSignal) => addSyncSetup(name, { storage, sync: { include, automatic } }, saveSignal, connection),\n signal,\n );\n if (saved && !signal?.aborted) ctx.ui.notify(`Added sync setup \u201C${safe(name)}\u201D.`, \"info\");\n return saved;\n}\n\nexport async function showEditWebDavTarget(ctx: ExtensionCommandContext, partial: PartialConfig, signal?: AbortSignal) {\n const remotePath = await chooseDestination(ctx, signal, partial.storagePath);\n if (!remotePath) return false;\n const connection = await readSetupConnection(partial.connectionName, signal);\n if (connection.type !== \"webdav\") throw new Error(\"Storage connection changed; reopen setup.\");\n const saved = await saveReviewedDraft(\n ctx,\n \"Review sync setup\",\n [\n `Sync setup: ${safe(partial.setupName)}`,\n `Storage connection: ${safe(partial.connectionName)}`,\n `URL: ${safe(connection.url)}`,\n `Storage path: ${safe(partial.storagePath)} \u2192 ${safe(remotePath)}`,\n \"Saving changes the future storage location only; it does not move or delete remote data.\",\n ],\n \"Save sync setup\",\n (saveSignal) =>\n updateSyncSetup(\n partial.setupName,\n (setup) => ({\n ...setup,\n storage: { ...setup.storage, path: remotePath },\n }),\n { expectedStorage: partial, expectedConnection: connection, signal: saveSignal },\n ),\n signal,\n );\n if (saved && !signal?.aborted) ctx.ui.notify(`Saved sync setup \u201C${safe(partial.setupName)}\u201D.`, \"info\");\n return saved;\n}\n\nexport async function showAddWebDavStorageProfile(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n const name = await promptResourceName(ctx, \"storage connection\", \"webdav\", signal, true);\n if (!name) return false;\n const url = await promptWebDavUrl(ctx, signal);\n if (!url) return false;\n const username = await promptUsername(ctx, signal);\n if (!username) return false;\n const password = await promptSecret(ctx, \"WebDAV password\", { signal });\n signal?.throwIfAborted();\n if (password === undefined) return false;\n const saved = await saveReviewedDraft(\n ctx,\n \"Review storage connection\",\n [\n `Name: ${safe(name)}`,\n \"Type: WebDAV\",\n `URL: ${safe(url)}`,\n \"Username and password: stored privately (values hidden)\",\n \"Adding a connection does not contact the server or start syncing.\",\n ],\n \"Add storage connection\",\n (saveSignal) =>\n addStorageConnection(name, { type: \"webdav\", url, credentials: { username, password } }, saveSignal),\n signal,\n );\n if (saved && !signal?.aborted) ctx.ui.notify(`Added storage connection \u201C${safe(name)}\u201D.`, \"info\");\n return saved;\n}\n\nexport async function showEditWebDavStorageProfile(\n ctx: ExtensionCommandContext,\n name: string,\n profile: Record<string, unknown>,\n signal?: AbortSignal,\n affectedSetups?: string[],\n) {\n const url = await promptWebDavUrl(ctx, signal, typeof profile.url === \"string\" ? profile.url : undefined);\n if (!url) return false;\n const username = await promptUsername(ctx, signal);\n if (!username) return false;\n const hasPassword = typeof profile.password === \"string\" && profile.password.length > 0;\n const passwordAction = hasPassword\n ? await select(ctx, \"WebDAV password\", [\"Keep current password\", \"Replace password\", \"Cancel\"], signal)\n : \"Replace password\";\n if (!passwordAction || passwordAction === \"Cancel\") return false;\n const replacePassword = passwordAction === \"Replace password\";\n const password = replacePassword ? await promptSecret(ctx, \"New WebDAV password\", { signal }) : undefined;\n signal?.throwIfAborted();\n if (replacePassword && password === undefined) return false;\n const saved = await saveReviewedDraft(\n ctx,\n \"Review storage connection\",\n [\n `Storage connection: ${safe(name)}`,\n `URL: ${safe(String(profile.url))} \u2192 ${safe(url)}`,\n \"Username: stored privately (value hidden)\",\n `Password: ${replacePassword ? \"will be replaced\" : \"unchanged\"} (value hidden)`,\n `Affected sync setups: ${affectedSetups?.length ? affectedSetups.map(safe).join(\", \") : \"None\"}`,\n \"Saving changes future storage access for every affected setup; it does not move remote data.\",\n ],\n \"Save storage connection\",\n (saveSignal) =>\n updateStorageConnection(\n name,\n (current) => {\n if (\n current.type !== \"webdav\" ||\n current.url !== profile.url ||\n current.credentials.username !== profile.username ||\n current.credentials.password !== profile.password\n )\n throw new Error(\"Storage connection changed while it was open; reopen it.\");\n return {\n ...current,\n url,\n credentials: {\n ...current.credentials,\n username,\n password: password ?? current.credentials.password,\n },\n };\n },\n affectedSetups,\n saveSignal,\n ),\n signal,\n );\n if (saved && !signal?.aborted) ctx.ui.notify(`Saved storage connection \u201C${safe(name)}\u201D.`, \"info\");\n return saved;\n}\n\nasync function chooseDestination(ctx: ExtensionCommandContext, signal?: AbortSignal, current = \"./\") {\n return promptTextInput(\n ctx,\n \"WebDAV storage path\\n\\nFolder relative to the collection URL, not your local filesystem.\\n./ uses the collection root. Use different folders for independent setups.\",\n { defaultValue: current, validate: normalizeWebDavPath },\n signal,\n );\n}\n\nasync function promptUsername(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n return promptTextInput(\n ctx,\n \"WebDAV username\\n\\nEnter the account username; stored values remain hidden.\",\n {\n example: \"user\",\n validate: (value) => {\n validateWebDavCredentials(value);\n return value;\n },\n },\n signal,\n );\n}\n\nasync function promptWebDavUrl(ctx: ExtensionCommandContext, signal?: AbortSignal, current?: string) {\n return promptTextInput(\n ctx,\n \"WebDAV collection URL\\n\\nUse the HTTPS WebDAV URL from your provider, not its web login page.\",\n {\n ...(current ? { defaultValue: current } : { example: \"https://cloud.example.com/remote.php/dav/files/user\" }),\n validate: (value) => {\n const url = normalizeWebDavUrl(value);\n if (!url) throw new Error(\"WebDAV URL is required.\");\n return url;\n },\n },\n signal,\n );\n}\n\nasync function select(ctx: ExtensionCommandContext, title: string, options: string[], signal?: AbortSignal) {\n const value = await ctx.ui.select(title, options, { signal });\n signal?.throwIfAborted();\n return value;\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }