@narumitw/pi-sync 0.50.3 → 0.51.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/README.md +4 -1
  2. package/dist/chunks/{chunk-6LP3MCR2.ts → chunk-2JZFHNLM.ts} +3 -5
  3. package/dist/chunks/chunk-2JZFHNLM.ts.map +7 -0
  4. package/dist/chunks/{chunk-LCRI3ABW.ts → chunk-2RZSQWBH.ts} +8 -19
  5. package/dist/chunks/chunk-2RZSQWBH.ts.map +7 -0
  6. package/dist/chunks/{chunk-IJ6FJFA5.ts → chunk-4AIHXRKE.ts} +11 -17
  7. package/dist/chunks/chunk-4AIHXRKE.ts.map +7 -0
  8. package/dist/chunks/{chunk-C7XY5NF5.ts → chunk-4MPIH46N.ts} +29 -51
  9. package/dist/chunks/chunk-4MPIH46N.ts.map +7 -0
  10. package/dist/chunks/{chunk-5B3FXBLE.ts → chunk-6546TS54.ts} +16 -20
  11. package/dist/chunks/chunk-6546TS54.ts.map +7 -0
  12. package/dist/chunks/{chunk-Q2TUM5X6.ts → chunk-6NT3YFGY.ts} +2 -2
  13. package/dist/chunks/chunk-6NT3YFGY.ts.map +7 -0
  14. package/dist/chunks/{chunk-2B2ELUF5.ts → chunk-7D5SF7P3.ts} +1 -1
  15. package/dist/chunks/chunk-7D5SF7P3.ts.map +7 -0
  16. package/dist/chunks/{chunk-YDWUZVPN.ts → chunk-7KHKWL3Q.ts} +28 -47
  17. package/dist/chunks/chunk-7KHKWL3Q.ts.map +7 -0
  18. package/dist/chunks/{chunk-ZI5MXMEX.ts → chunk-BVVP33U5.ts} +2 -4
  19. package/dist/chunks/chunk-BVVP33U5.ts.map +7 -0
  20. package/dist/chunks/{chunk-SZWBGPID.ts → chunk-DM4X4FIA.ts} +8 -13
  21. package/dist/chunks/chunk-DM4X4FIA.ts.map +7 -0
  22. package/dist/chunks/{chunk-SL64RLXR.ts → chunk-DZUSTGQV.ts} +8 -16
  23. package/dist/chunks/chunk-DZUSTGQV.ts.map +7 -0
  24. package/dist/chunks/{chunk-YHEMENKV.ts → chunk-E42GXD6D.ts} +13 -19
  25. package/dist/chunks/chunk-E42GXD6D.ts.map +7 -0
  26. package/dist/chunks/{chunk-Z4DQF6L3.ts → chunk-ECYCNZOE.ts} +1 -1
  27. package/dist/chunks/chunk-ECYCNZOE.ts.map +7 -0
  28. package/dist/chunks/{chunk-OEX4ABY6.ts → chunk-EEJPYTWE.ts} +11 -21
  29. package/dist/chunks/chunk-EEJPYTWE.ts.map +7 -0
  30. package/dist/chunks/{chunk-CPEHGXJV.ts → chunk-G4RUXRWZ.ts} +3 -5
  31. package/dist/chunks/chunk-G4RUXRWZ.ts.map +7 -0
  32. package/dist/chunks/{chunk-T2B5IU74.ts → chunk-HGJH56KR.ts} +4 -4
  33. package/dist/chunks/chunk-HGJH56KR.ts.map +7 -0
  34. package/dist/chunks/{chunk-JAAKLL6M.ts → chunk-IVXEDPAD.ts} +10 -34
  35. package/dist/chunks/chunk-IVXEDPAD.ts.map +7 -0
  36. package/dist/chunks/chunk-K3RIEL6J.ts +20 -0
  37. package/dist/chunks/chunk-K3RIEL6J.ts.map +7 -0
  38. package/dist/chunks/{chunk-LTBWGSBV.ts → chunk-MSSW6F3R.ts} +1 -1
  39. package/dist/chunks/chunk-MSSW6F3R.ts.map +7 -0
  40. package/dist/chunks/{chunk-T3HH3UEJ.ts → chunk-OVDTF5CH.ts} +4 -10
  41. package/dist/chunks/chunk-OVDTF5CH.ts.map +7 -0
  42. package/dist/chunks/{chunk-NJFUIVYL.ts → chunk-PWMWOJP4.ts} +1 -1
  43. package/dist/chunks/chunk-PWMWOJP4.ts.map +7 -0
  44. package/dist/chunks/{chunk-HUDQATCL.ts → chunk-Q32CQWPM.ts} +6 -8
  45. package/dist/chunks/chunk-Q32CQWPM.ts.map +7 -0
  46. package/dist/chunks/{chunk-ETTRJDNP.ts → chunk-QLSN7AGX.ts} +6 -13
  47. package/dist/chunks/chunk-QLSN7AGX.ts.map +7 -0
  48. package/dist/chunks/{chunk-THMF4BVL.ts → chunk-SWUXA3MH.ts} +1 -1
  49. package/dist/chunks/chunk-SWUXA3MH.ts.map +7 -0
  50. package/dist/chunks/{chunk-TEN2ZBJV.ts → chunk-T2SJD3N7.ts} +2 -4
  51. package/dist/chunks/chunk-T2SJD3N7.ts.map +7 -0
  52. package/dist/chunks/{chunk-AUSDLD6F.ts → chunk-T56RNRZJ.ts} +10 -26
  53. package/dist/chunks/chunk-T56RNRZJ.ts.map +7 -0
  54. package/dist/chunks/{chunk-DHVFS4QK.ts → chunk-UA7RXOIT.ts} +37 -90
  55. package/dist/chunks/chunk-UA7RXOIT.ts.map +7 -0
  56. package/dist/chunks/{chunk-D5X27LCA.ts → chunk-UETBKTDI.ts} +1 -1
  57. package/dist/chunks/chunk-UETBKTDI.ts.map +7 -0
  58. package/dist/chunks/{chunk-CHH26D4F.ts → chunk-YFADF5ZQ.ts} +7 -6
  59. package/dist/chunks/chunk-YFADF5ZQ.ts.map +7 -0
  60. package/dist/chunks/{chunk-CCSN3F47.ts → chunk-YPXGU5OR.ts} +4 -4
  61. package/dist/chunks/chunk-YPXGU5OR.ts.map +7 -0
  62. package/dist/chunks/{file-selection-FTTKAOYX.ts → file-selection-RAVHRYFG.ts} +14 -26
  63. package/dist/chunks/file-selection-RAVHRYFG.ts.map +7 -0
  64. package/dist/chunks/{git-backend-GMVS4PD4.ts → git-backend-IAANDL3K.ts} +41 -104
  65. package/dist/chunks/git-backend-IAANDL3K.ts.map +7 -0
  66. package/dist/chunks/manager-result-dispatcher-OTUMQM26.ts +23 -0
  67. package/dist/chunks/{manager-ui-IPAOAWZA.ts → manager-ui-763NEKJY.ts} +124 -251
  68. package/dist/chunks/manager-ui-763NEKJY.ts.map +7 -0
  69. package/dist/chunks/remote-selection-ui-TZTJF32Y.ts +22 -0
  70. package/dist/chunks/{s3-backend-66O4FGBH.ts → s3-backend-XGXUOPUN.ts} +23 -54
  71. package/dist/chunks/s3-backend-XGXUOPUN.ts.map +7 -0
  72. package/dist/chunks/{setup-switch-IS2PEZ3J.ts → setup-switch-5G2VNJHL.ts} +9 -9
  73. package/dist/chunks/{setup-wizard-JUJZYNNM.ts → setup-wizard-YIEWGX32.ts} +12 -12
  74. package/dist/chunks/setup-wizard-YIEWGX32.ts.map +7 -0
  75. package/dist/chunks/{snapshot-HKEWCVK6.ts → snapshot-JL5DFSXI.ts} +5 -5
  76. package/dist/chunks/sync-inspection-P3ENJLNF.ts +20 -0
  77. package/dist/chunks/{sync-operations-LBX3GKCM.ts → sync-operations-AR76EB6C.ts} +85 -201
  78. package/dist/chunks/sync-operations-AR76EB6C.ts.map +7 -0
  79. package/dist/chunks/{sync-state-Q2FTXTW6.ts → sync-state-VHJUZ4YG.ts} +6 -6
  80. package/dist/chunks/{webdav-backend-ECIKD7SO.ts → webdav-backend-3EGUONAT.ts} +20 -51
  81. package/dist/chunks/webdav-backend-3EGUONAT.ts.map +7 -0
  82. package/dist/index.ts +49 -74
  83. package/dist/index.ts.map +3 -3
  84. package/docs/settings.md +9 -0
  85. package/package.json +61 -62
  86. package/src/backends/backend-factory.ts +15 -15
  87. package/src/backends/backend-identity.ts +31 -31
  88. package/src/backends/backend-types.ts +42 -42
  89. package/src/backends/git/git-backend.ts +714 -788
  90. package/src/backends/git/git-config.ts +104 -111
  91. package/src/backends/git/git-runner.ts +230 -247
  92. package/src/backends/git/git-storage.ts +228 -245
  93. package/src/backends/s3/s3-backend.ts +408 -441
  94. package/src/backends/s3/s3-client.ts +288 -333
  95. package/src/backends/sync-backend.ts +65 -65
  96. package/src/backends/webdav/webdav-backend.ts +542 -589
  97. package/src/backends/webdav/webdav-client.ts +292 -316
  98. package/src/backends/webdav/webdav-config.ts +57 -68
  99. package/src/commands/command-execution.ts +270 -289
  100. package/src/commands/command-handler.ts +160 -163
  101. package/src/commands/command-types.ts +13 -13
  102. package/src/commands/command.ts +190 -196
  103. package/src/commands/setup-completions.ts +1 -1
  104. package/src/paths.ts +47 -47
  105. package/src/settings/config-errors.ts +4 -5
  106. package/src/settings/config-file.ts +473 -506
  107. package/src/settings/config.ts +171 -174
  108. package/src/settings/settings-management.ts +191 -216
  109. package/src/settings/settings-store.ts +63 -77
  110. package/src/settings/settings-types.ts +78 -75
  111. package/src/settings/settings-validation.ts +328 -364
  112. package/src/snapshot/session-paths.ts +41 -55
  113. package/src/snapshot/snapshot-apply.ts +197 -229
  114. package/src/snapshot/snapshot-codec.ts +29 -31
  115. package/src/snapshot/snapshot-paths.ts +4 -6
  116. package/src/snapshot/snapshot-transaction.ts +161 -170
  117. package/src/snapshot/snapshot-types.ts +24 -24
  118. package/src/snapshot/snapshot.ts +310 -343
  119. package/src/state/json-file.ts +11 -11
  120. package/src/state/lock.ts +226 -242
  121. package/src/state/lockfile-fs.ts +20 -20
  122. package/src/state/operation-availability.ts +36 -41
  123. package/src/state/state-directory.ts +171 -173
  124. package/src/state/state-types.ts +15 -15
  125. package/src/state/sync-state-store.ts +23 -23
  126. package/src/sync/automatic-sync.ts +75 -80
  127. package/src/sync/remote-snapshot.ts +52 -60
  128. package/src/sync/setup-switch.ts +99 -114
  129. package/src/sync/signals.ts +3 -5
  130. package/src/sync/startup-check.ts +97 -111
  131. package/src/sync/sync-decision.ts +76 -80
  132. package/src/sync/sync-error-guidance.ts +41 -48
  133. package/src/sync/sync-errors.ts +10 -10
  134. package/src/sync/sync-inspection.ts +29 -33
  135. package/src/sync/sync-loaders.ts +28 -36
  136. package/src/sync/sync-mutations.ts +510 -622
  137. package/src/sync/sync-operations.ts +7 -7
  138. package/src/sync/sync-policy.ts +296 -326
  139. package/src/sync/sync-queries.ts +175 -194
  140. package/src/sync/sync-state.ts +74 -100
  141. package/src/sync-extension.ts +89 -101
  142. package/src/sync.ts +26 -26
  143. package/src/types.ts +37 -37
  144. package/src/ui/automatic-sync-summary.ts +1 -3
  145. package/src/ui/cancellable-operation.ts +89 -101
  146. package/src/ui/file-selection.ts +250 -274
  147. package/src/ui/manager-attention.ts +51 -63
  148. package/src/ui/manager-recovery.ts +48 -57
  149. package/src/ui/manager-result-dispatcher.ts +62 -76
  150. package/src/ui/manager-state.ts +200 -232
  151. package/src/ui/manager-ui.ts +264 -362
  152. package/src/ui/remote-selection-ui.ts +547 -588
  153. package/src/ui/secret-input.ts +197 -205
  154. package/src/ui/settings-ui.ts +175 -172
  155. package/src/ui/setup/git-ui.ts +232 -261
  156. package/src/ui/setup/s3-credentials-ui.ts +58 -65
  157. package/src/ui/setup/s3-ui.ts +171 -195
  158. package/src/ui/setup/setup-actions.ts +91 -101
  159. package/src/ui/setup/setup-location-ui.ts +121 -137
  160. package/src/ui/setup/setup-name-ui.ts +27 -27
  161. package/src/ui/setup/setup-prompts.ts +65 -65
  162. package/src/ui/setup/setup-review.ts +58 -59
  163. package/src/ui/setup/setup-switcher.ts +156 -160
  164. package/src/ui/setup/setup-wizard.ts +28 -28
  165. package/src/ui/setup/text-input.ts +54 -58
  166. package/src/ui/setup/webdav-ui.ts +246 -293
  167. package/src/ui/storage-connections-ui.ts +317 -369
  168. package/src/ui/sync-attention.ts +148 -164
  169. package/src/ui/sync-format.ts +110 -121
  170. package/src/ui/sync-resolution-ui.ts +147 -153
  171. package/src/ui/sync-setups-ui.ts +218 -238
  172. package/src/ui/sync-status.ts +17 -0
  173. package/src/ui/terminal-text.ts +2 -2
  174. package/dist/chunks/chunk-2B2ELUF5.ts.map +0 -7
  175. package/dist/chunks/chunk-5B3FXBLE.ts.map +0 -7
  176. package/dist/chunks/chunk-6LP3MCR2.ts.map +0 -7
  177. package/dist/chunks/chunk-AUSDLD6F.ts.map +0 -7
  178. package/dist/chunks/chunk-C7XY5NF5.ts.map +0 -7
  179. package/dist/chunks/chunk-CCSN3F47.ts.map +0 -7
  180. package/dist/chunks/chunk-CHH26D4F.ts.map +0 -7
  181. package/dist/chunks/chunk-CPEHGXJV.ts.map +0 -7
  182. package/dist/chunks/chunk-D5X27LCA.ts.map +0 -7
  183. package/dist/chunks/chunk-DHVFS4QK.ts.map +0 -7
  184. package/dist/chunks/chunk-ETTRJDNP.ts.map +0 -7
  185. package/dist/chunks/chunk-HUDQATCL.ts.map +0 -7
  186. package/dist/chunks/chunk-IJ6FJFA5.ts.map +0 -7
  187. package/dist/chunks/chunk-JAAKLL6M.ts.map +0 -7
  188. package/dist/chunks/chunk-LCRI3ABW.ts.map +0 -7
  189. package/dist/chunks/chunk-LTBWGSBV.ts.map +0 -7
  190. package/dist/chunks/chunk-NJFUIVYL.ts.map +0 -7
  191. package/dist/chunks/chunk-OEX4ABY6.ts.map +0 -7
  192. package/dist/chunks/chunk-Q2TUM5X6.ts.map +0 -7
  193. package/dist/chunks/chunk-SL64RLXR.ts.map +0 -7
  194. package/dist/chunks/chunk-SZWBGPID.ts.map +0 -7
  195. package/dist/chunks/chunk-T2B5IU74.ts.map +0 -7
  196. package/dist/chunks/chunk-T3HH3UEJ.ts.map +0 -7
  197. package/dist/chunks/chunk-TEN2ZBJV.ts.map +0 -7
  198. package/dist/chunks/chunk-THMF4BVL.ts.map +0 -7
  199. package/dist/chunks/chunk-YDWUZVPN.ts.map +0 -7
  200. package/dist/chunks/chunk-YHEMENKV.ts.map +0 -7
  201. package/dist/chunks/chunk-Z4DQF6L3.ts.map +0 -7
  202. package/dist/chunks/chunk-ZI5MXMEX.ts.map +0 -7
  203. package/dist/chunks/file-selection-FTTKAOYX.ts.map +0 -7
  204. package/dist/chunks/git-backend-GMVS4PD4.ts.map +0 -7
  205. package/dist/chunks/manager-result-dispatcher-ASKGOSW5.ts +0 -22
  206. package/dist/chunks/manager-ui-IPAOAWZA.ts.map +0 -7
  207. package/dist/chunks/remote-selection-ui-QDNR7WEI.ts +0 -21
  208. package/dist/chunks/s3-backend-66O4FGBH.ts.map +0 -7
  209. package/dist/chunks/setup-wizard-JUJZYNNM.ts.map +0 -7
  210. package/dist/chunks/sync-inspection-CST2KL65.ts +0 -20
  211. package/dist/chunks/sync-operations-LBX3GKCM.ts.map +0 -7
  212. package/dist/chunks/webdav-backend-ECIKD7SO.ts.map +0 -7
  213. /package/dist/chunks/{manager-result-dispatcher-ASKGOSW5.ts.map → manager-result-dispatcher-OTUMQM26.ts.map} +0 -0
  214. /package/dist/chunks/{remote-selection-ui-QDNR7WEI.ts.map → remote-selection-ui-TZTJF32Y.ts.map} +0 -0
  215. /package/dist/chunks/{setup-switch-IS2PEZ3J.ts.map → setup-switch-5G2VNJHL.ts.map} +0 -0
  216. /package/dist/chunks/{snapshot-HKEWCVK6.ts.map → snapshot-JL5DFSXI.ts.map} +0 -0
  217. /package/dist/chunks/{sync-inspection-CST2KL65.ts.map → sync-inspection-P3ENJLNF.ts.map} +0 -0
  218. /package/dist/chunks/{sync-state-Q2FTXTW6.ts.map → sync-state-VHJUZ4YG.ts.map} +0 -0
@@ -3,7 +3,7 @@
3
3
  import {
4
4
  filterSnapshotForConfigPolicy,
5
5
  isSessionPath
6
- } from "./chunk-OEX4ABY6.ts";
6
+ } from "./chunk-EEJPYTWE.ts";
7
7
  import {
8
8
  canonicalSnapshotPathForConfig,
9
9
  customIncludePathsByLower,
@@ -11,7 +11,7 @@ import {
11
11
  isConfiguredSnapshotPath,
12
12
  normalizeSyncInclude,
13
13
  toPosix
14
- } from "./chunk-JAAKLL6M.ts";
14
+ } from "./chunk-IVXEDPAD.ts";
15
15
 
16
16
  // src/sync/sync-state.ts
17
17
  function hasLocalChanges(local, state, config) {
@@ -20,19 +20,13 @@ function hasLocalChanges(local, state, config) {
20
20
  function remoteChangedSinceState(head, state, config, sameRevision) {
21
21
  if (!head) return Boolean(state.lastAppliedSnapshot);
22
22
  if (head.snapshotId !== state.lastAppliedSnapshot) return true;
23
- if (state.lastRemoteRevision && !sameRevision(head.revision, state.lastRemoteRevision))
24
- return true;
23
+ if (state.lastRemoteRevision && !sameRevision(head.revision, state.lastRemoteRevision)) return true;
25
24
  if (syncIncludeChanged(state, config)) return true;
26
25
  return includeFromSelectionConfig(config).includes("sessions") && !state.include?.includes("sessions") && head.syncSessions;
27
26
  }
28
27
  function hasRemoteChanges(remote, state, config, ignoredPaths = /* @__PURE__ */ new Set()) {
29
28
  if (remote.id === state.lastAppliedSnapshot && !syncPolicyChanged(state, config)) return false;
30
- return !snapshotHashesMatchState(
31
- filterSnapshotForConfigPolicy(remote, config),
32
- state,
33
- config,
34
- ignoredPaths
35
- );
29
+ return !snapshotHashesMatchState(filterSnapshotForConfigPolicy(remote, config), state, config, ignoredPaths);
36
30
  }
37
31
  function sameHashes(left, right) {
38
32
  const keys = /* @__PURE__ */ new Set([...Object.keys(left), ...Object.keys(right)]);
@@ -59,17 +53,13 @@ function snapshotsMatch(left, right) {
59
53
  }
60
54
  function withoutHashPaths(hashes, ignoredPaths) {
61
55
  if (ignoredPaths.size === 0) return hashes;
62
- return Object.fromEntries(
63
- Object.entries(hashes).filter(([filePath]) => !ignoredPaths.has(toPosix(filePath)))
64
- );
56
+ return Object.fromEntries(Object.entries(hashes).filter(([filePath]) => !ignoredPaths.has(toPosix(filePath))));
65
57
  }
66
58
  function syncPolicyChanged(state, config) {
67
59
  return syncIncludeChanged(state, config);
68
60
  }
69
61
  function shouldRefreshSyncedState(remote, head, state, config, sameRevision) {
70
- return remote.id !== state.lastAppliedSnapshot || Boolean(
71
- head && (!state.lastRemoteRevision || !sameRevision(head.revision, state.lastRemoteRevision))
72
- ) || syncPolicyChanged(state, config);
62
+ return remote.id !== state.lastAppliedSnapshot || Boolean(head && (!state.lastRemoteRevision || !sameRevision(head.revision, state.lastRemoteRevision))) || syncPolicyChanged(state, config);
73
63
  }
74
64
  function syncIncludeChanged(state, config) {
75
65
  const stored = state.include ? normalizeSyncInclude(state.include) : includeFromSelectionConfig(state);
@@ -87,25 +77,19 @@ function sessionHashMap(snapshot) {
87
77
  );
88
78
  }
89
79
  function settingsHashMapFromState(state) {
90
- return Object.fromEntries(
91
- Object.entries(state.lastFileHashes).filter(([filePath]) => !isSessionPath(filePath))
92
- );
80
+ return Object.fromEntries(Object.entries(state.lastFileHashes).filter(([filePath]) => !isSessionPath(filePath)));
93
81
  }
94
82
  function settingsHashesMatchState(remote, state) {
95
83
  return sameHashes(settingsHashMap(remote), settingsHashMapFromState(state));
96
84
  }
97
85
  function canPullRemoteSettingsOnFirstSync(local, remote) {
98
86
  const remoteSettings = settingsHashMap(remote);
99
- return Object.entries(settingsHashMap(local)).every(
100
- ([filePath, hash]) => remoteSettings[filePath] === hash
101
- );
87
+ return Object.entries(settingsHashMap(local)).every(([filePath, hash]) => remoteSettings[filePath] === hash);
102
88
  }
103
89
  function canPullRemoteSessionsOnFirstSync(local, remote) {
104
90
  const localSessions = sessionHashMap(local);
105
91
  const remoteSessions = sessionHashMap(remote);
106
- return Object.entries(localSessions).every(
107
- ([filePath, hash]) => remoteSessions[filePath] === hash
108
- );
92
+ return Object.entries(localSessions).every(([filePath, hash]) => remoteSessions[filePath] === hash);
109
93
  }
110
94
 
111
95
  export {
@@ -125,4 +109,4 @@ export {
125
109
  canPullRemoteSettingsOnFirstSync,
126
110
  canPullRemoteSessionsOnFirstSync
127
111
  };
128
- //# sourceMappingURL=chunk-AUSDLD6F.ts.map
112
+ //# sourceMappingURL=chunk-T56RNRZJ.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/sync/sync-state.ts"],
4
+ "sourcesContent": ["import type { RemoteHead } from \"../backends/sync-backend.js\";\nimport { toPosix } from \"../paths.js\";\nimport {\n canonicalSnapshotPathForConfig,\n filterSnapshotForConfigPolicy,\n isConfiguredSnapshotPath,\n isSessionPath,\n} from \"../snapshot/snapshot.js\";\nimport type { Snapshot } from \"../snapshot/snapshot-types.js\";\nimport type { SyncState } from \"../state/state-types.js\";\nimport {\n customIncludePathsByLower,\n includeFromSelectionConfig,\n normalizeSyncInclude,\n type SyncSelectionConfig,\n} from \"./sync-policy.js\";\n\ntype SyncPolicyConfig = SyncSelectionConfig;\n\nexport function hasLocalChanges(local: Snapshot, state: SyncState, config: SyncPolicyConfig) {\n return !sameHashes(fileHashMap(local), stateHashMapForConfig(state, config));\n}\n\nexport function remoteChangedSinceState(\n head: RemoteHead | undefined,\n state: SyncState,\n config: SyncPolicyConfig,\n sameRevision: (left: string, right: string) => boolean,\n) {\n if (!head) return Boolean(state.lastAppliedSnapshot);\n if (head.snapshotId !== state.lastAppliedSnapshot) return true;\n if (state.lastRemoteRevision && !sameRevision(head.revision, state.lastRemoteRevision)) return true;\n if (syncIncludeChanged(state, config)) return true;\n return (\n includeFromSelectionConfig(config).includes(\"sessions\") && !state.include?.includes(\"sessions\") && head.syncSessions\n );\n}\n\nexport function hasRemoteChanges(\n remote: Snapshot,\n state: SyncState,\n config: SyncPolicyConfig,\n ignoredPaths = new Set<string>(),\n) {\n if (remote.id === state.lastAppliedSnapshot && !syncPolicyChanged(state, config)) return false;\n return !snapshotHashesMatchState(filterSnapshotForConfigPolicy(remote, config), state, config, ignoredPaths);\n}\n\nexport function sameHashes(left: Record<string, string>, right: Record<string, string>) {\n const keys = new Set([...Object.keys(left), ...Object.keys(right)]);\n for (const key of keys) if (left[key] !== right[key]) return false;\n return true;\n}\n\nexport function fileHashMap(snapshot: Snapshot) {\n return Object.fromEntries(snapshot.files.map((file) => [file.path, file.sha256]));\n}\n\nfunction stateHashMapForConfig(state: SyncState, config: SyncPolicyConfig) {\n const includePaths = customIncludePathsByLower(includeFromSelectionConfig(config));\n return Object.fromEntries(\n Object.entries(state.lastFileHashes)\n .filter(([filePath]) => isConfiguredSnapshotPath(filePath, config))\n .map(([filePath, hash]) => [canonicalSnapshotPathForConfig(filePath, includePaths), hash]),\n );\n}\n\nexport function snapshotHashesMatchState(\n snapshot: Snapshot,\n state: SyncState,\n config: SyncPolicyConfig,\n ignoredPaths = new Set<string>(),\n) {\n return sameHashes(\n withoutHashPaths(fileHashMap(snapshot), ignoredPaths),\n withoutHashPaths(stateHashMapForConfig(state, config), ignoredPaths),\n );\n}\n\nexport function snapshotsMatch(left: Snapshot, right: Snapshot) {\n return left.syncSessions === right.syncSessions && sameHashes(fileHashMap(left), fileHashMap(right));\n}\n\nfunction withoutHashPaths(hashes: Record<string, string>, ignoredPaths: Set<string>) {\n if (ignoredPaths.size === 0) return hashes;\n return Object.fromEntries(Object.entries(hashes).filter(([filePath]) => !ignoredPaths.has(toPosix(filePath))));\n}\n\nexport function syncPolicyChanged(state: SyncState, config: SyncPolicyConfig) {\n return syncIncludeChanged(state, config);\n}\n\nexport function shouldRefreshSyncedState(\n remote: Snapshot,\n head: RemoteHead | undefined,\n state: SyncState,\n config: SyncPolicyConfig,\n sameRevision: (left: string, right: string) => boolean,\n) {\n return (\n remote.id !== state.lastAppliedSnapshot ||\n Boolean(head && (!state.lastRemoteRevision || !sameRevision(head.revision, state.lastRemoteRevision))) ||\n syncPolicyChanged(state, config)\n );\n}\n\nfunction syncIncludeChanged(state: SyncState, config: SyncPolicyConfig) {\n const stored = state.include ? normalizeSyncInclude(state.include) : includeFromSelectionConfig(state);\n const current = includeFromSelectionConfig(config);\n return stored.length !== current.length || stored.some((item, index) => item !== current[index]);\n}\n\nexport function settingsHashMap(snapshot: Snapshot) {\n return Object.fromEntries(\n snapshot.files.filter((file) => !isSessionPath(file.path)).map((file) => [file.path, file.sha256]),\n );\n}\n\nexport function sessionHashMap(snapshot: Snapshot) {\n return Object.fromEntries(\n snapshot.files.filter((file) => isSessionPath(file.path)).map((file) => [file.path, file.sha256]),\n );\n}\n\nexport function settingsHashMapFromState(state: SyncState) {\n return Object.fromEntries(Object.entries(state.lastFileHashes).filter(([filePath]) => !isSessionPath(filePath)));\n}\n\nexport function settingsHashesMatchState(remote: Snapshot, state: SyncState) {\n return sameHashes(settingsHashMap(remote), settingsHashMapFromState(state));\n}\n\nexport function canPullRemoteSettingsOnFirstSync(local: Snapshot, remote: Snapshot) {\n const remoteSettings = settingsHashMap(remote);\n return Object.entries(settingsHashMap(local)).every(([filePath, hash]) => remoteSettings[filePath] === hash);\n}\n\nexport function canPullRemoteSessionsOnFirstSync(local: Snapshot, remote: Snapshot) {\n const localSessions = sessionHashMap(local);\n const remoteSessions = sessionHashMap(remote);\n return Object.entries(localSessions).every(([filePath, hash]) => remoteSessions[filePath] === hash);\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -2,20 +2,20 @@
2
2
  // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
3
  import {
4
4
  automaticSyncSummary
5
- } from "./chunk-Z4DQF6L3.ts";
5
+ } from "./chunk-ECYCNZOE.ts";
6
6
  import {
7
7
  setSyncSetupCompletions
8
- } from "./chunk-CHH26D4F.ts";
8
+ } from "./chunk-YFADF5ZQ.ts";
9
9
  import {
10
10
  safeTerminalText
11
- } from "./chunk-LTBWGSBV.ts";
11
+ } from "./chunk-MSSW6F3R.ts";
12
12
  import {
13
13
  addStorageConnection,
14
14
  addSyncSetup,
15
15
  saveNewV3Settings,
16
16
  updateStorageConnection,
17
17
  updateSyncSetup
18
- } from "./chunk-LCRI3ABW.ts";
18
+ } from "./chunk-2RZSQWBH.ts";
19
19
  import {
20
20
  configuredSyncSetupNames,
21
21
  effectiveSyncSetupRemoteIdentity,
@@ -26,26 +26,26 @@ import {
26
26
  readLocalConfigObject,
27
27
  requiredString,
28
28
  validateConfigName
29
- } from "./chunk-C7XY5NF5.ts";
29
+ } from "./chunk-4MPIH46N.ts";
30
30
  import {
31
31
  normalizeWebDavPath,
32
32
  normalizeWebDavUrl,
33
33
  validateWebDavCredentials
34
- } from "./chunk-6LP3MCR2.ts";
34
+ } from "./chunk-2JZFHNLM.ts";
35
35
  import {
36
36
  normalizeGitBranch,
37
37
  normalizeGitDirectory,
38
38
  normalizeGitRemote
39
- } from "./chunk-TEN2ZBJV.ts";
39
+ } from "./chunk-T2SJD3N7.ts";
40
40
  import {
41
41
  syncErrorGuidance
42
- } from "./chunk-CPEHGXJV.ts";
42
+ } from "./chunk-G4RUXRWZ.ts";
43
43
  import {
44
44
  errorMessage
45
- } from "./chunk-2B2ELUF5.ts";
45
+ } from "./chunk-7D5SF7P3.ts";
46
46
  import {
47
47
  DEFAULT_SYNC_INCLUDE
48
- } from "./chunk-JAAKLL6M.ts";
48
+ } from "./chunk-IVXEDPAD.ts";
49
49
 
50
50
  // src/commands/setup-completions.ts
51
51
  async function refreshTargetCompletions() {
@@ -103,8 +103,7 @@ async function chooseInitialRemoteLocation(ctx, _preset, setupName, signal) {
103
103
  { signal }
104
104
  );
105
105
  if (signal?.aborted || !choice || choice === "Cancel") return void 0;
106
- if (choice === "Customize remote location")
107
- return chooseCustomRemoteLocation(ctx, setupName, signal);
106
+ if (choice === "Customize remote location") return chooseCustomRemoteLocation(ctx, setupName, signal);
108
107
  const bucket = await requiredExistingBucket(ctx, "pi-sync", signal);
109
108
  return bucket ? { connectionName: setupName, bucket, path: "./" } : void 0;
110
109
  }
@@ -165,10 +164,7 @@ async function promptAvailableSetupStorage(ctx, initial, signal) {
165
164
  if (!settings || !connection) throw new Error("Storage connection changed; reopen setup.");
166
165
  const identity = setupPublicationIdentity(storage, connection);
167
166
  const occupied = Object.entries(settings.syncSetups).find(
168
- ([, setup]) => setupPublicationIdentity(
169
- setup.storage,
170
- settings.storageConnections[setup.storage.connection]
171
- ) === identity
167
+ ([, setup]) => setupPublicationIdentity(setup.storage, settings.storageConnections[setup.storage.connection]) === identity
172
168
  );
173
169
  if (!occupied) return storage;
174
170
  const git = connection.type === "git";
@@ -377,10 +373,7 @@ async function showGitSetup(ctx, targetName, signal) {
377
373
  signal
378
374
  );
379
375
  if (saved && !signal?.aborted)
380
- ctx.ui.notify(
381
- `Saved Git sync setup \u201C${safeTerminalText(targetName)}\u201D. Choose Sync now to start.`,
382
- "info"
383
- );
376
+ ctx.ui.notify(`Saved Git sync setup \u201C${safeTerminalText(targetName)}\u201D. Choose Sync now to start.`, "info");
384
377
  return saved;
385
378
  }
386
379
  async function showAddGitStorageProfile(ctx, signal) {
@@ -402,16 +395,11 @@ async function showAddGitStorageProfile(ctx, signal) {
402
395
  (saveSignal) => addStorageConnection(name, { type: "git", remote }, saveSignal),
403
396
  signal
404
397
  );
405
- if (saved && !signal?.aborted)
406
- ctx.ui.notify(`Added storage connection \u201C${safeTerminalText(name)}\u201D.`, "info");
398
+ if (saved && !signal?.aborted) ctx.ui.notify(`Added storage connection \u201C${safeTerminalText(name)}\u201D.`, "info");
407
399
  return saved;
408
400
  }
409
401
  async function showEditGitStorageProfile(ctx, name, profile, signal, affectedSetups) {
410
- const remote = await promptGitRemote(
411
- ctx,
412
- signal,
413
- typeof profile.remote === "string" ? profile.remote : void 0
414
- );
402
+ const remote = await promptGitRemote(ctx, signal, typeof profile.remote === "string" ? profile.remote : void 0);
415
403
  if (!remote) return false;
416
404
  const saved = await saveReviewedDraft(
417
405
  ctx,
@@ -435,8 +423,7 @@ async function showEditGitStorageProfile(ctx, name, profile, signal, affectedSet
435
423
  ),
436
424
  signal
437
425
  );
438
- if (saved && !signal?.aborted)
439
- ctx.ui.notify(`Saved storage connection \u201C${safeTerminalText(name)}\u201D.`, "info");
426
+ if (saved && !signal?.aborted) ctx.ui.notify(`Saved storage connection \u201C${safeTerminalText(name)}\u201D.`, "info");
440
427
  return saved;
441
428
  }
442
429
  async function showAddGitTarget(ctx, name, profile, signal) {
@@ -471,8 +458,7 @@ async function showAddGitTarget(ctx, name, profile, signal) {
471
458
  (saveSignal) => addSyncSetup(name, { storage, sync: { include, automatic } }, saveSignal, connection),
472
459
  signal
473
460
  );
474
- if (saved && !signal?.aborted)
475
- ctx.ui.notify(`Added sync setup \u201C${safeTerminalText(name)}\u201D.`, "info");
461
+ if (saved && !signal?.aborted) ctx.ui.notify(`Added sync setup \u201C${safeTerminalText(name)}\u201D.`, "info");
476
462
  return saved;
477
463
  }
478
464
  async function showEditGitTarget(ctx, partial, signal) {
@@ -511,8 +497,7 @@ async function showEditGitTarget(ctx, partial, signal) {
511
497
  (saveSignal) => updateSyncSetup(
512
498
  partial.setupName,
513
499
  (setup) => {
514
- if (typeof setup.storage.branch !== "string")
515
- throw new Error("Sync setup storage type changed; reopen it.");
500
+ if (typeof setup.storage.branch !== "string") throw new Error("Sync setup storage type changed; reopen it.");
516
501
  return {
517
502
  ...setup,
518
503
  storage: { ...setup.storage, branch: chosen.branch, path: chosen.directory }
@@ -522,8 +507,7 @@ async function showEditGitTarget(ctx, partial, signal) {
522
507
  ),
523
508
  signal
524
509
  );
525
- if (saved && !signal?.aborted)
526
- ctx.ui.notify(`Saved sync setup \u201C${safeTerminalText(partial.setupName)}\u201D.`, "info");
510
+ if (saved && !signal?.aborted) ctx.ui.notify(`Saved sync setup \u201C${safeTerminalText(partial.setupName)}\u201D.`, "info");
527
511
  return saved;
528
512
  }
529
513
  async function promptGitRemote(ctx, signal, current) {
@@ -585,10 +569,7 @@ async function promptSecret(ctx, title, options = { required: true }) {
585
569
  label: "continue"
586
570
  },
587
571
  {
588
- keys: [
589
- ...keybindings.getKeys("tui.select.cancel").filter((key) => !hasControlCharacter(key)),
590
- "ctrl+c"
591
- ],
572
+ keys: [...keybindings.getKeys("tui.select.cancel").filter((key) => !hasControlCharacter(key)), "ctrl+c"],
592
573
  label: "cancel"
593
574
  }
594
575
  ]);
@@ -607,11 +588,9 @@ async function promptSecret(ctx, title, options = { required: true }) {
607
588
  },
608
589
  render(width) {
609
590
  const safeWidth = Math.max(1, width);
610
- return [
611
- ...heading.render(safeWidth),
612
- ...input.render(safeWidth),
613
- ...hint.render(safeWidth)
614
- ].map((line) => truncateToWidth(line, safeWidth));
591
+ return [...heading.render(safeWidth), ...input.render(safeWidth), ...hint.render(safeWidth)].map(
592
+ (line) => truncateToWidth(line, safeWidth)
593
+ );
615
594
  },
616
595
  invalidate() {
617
596
  applyTheme();
@@ -731,10 +710,7 @@ var MaskedInput = class {
731
710
  const contentWidth = Math.max(0, available - 1);
732
711
  let start = 0;
733
712
  if (this.value.length > contentWidth) {
734
- start = Math.max(
735
- 0,
736
- Math.min(this.cursor - Math.floor(contentWidth / 2), this.value.length - contentWidth)
737
- );
713
+ start = Math.max(0, Math.min(this.cursor - Math.floor(contentWidth / 2), this.value.length - contentWidth));
738
714
  }
739
715
  const end = Math.min(this.value.length, start + contentWidth);
740
716
  const visibleCursor = Math.max(0, Math.min(this.cursor - start, end - start));
@@ -772,11 +748,9 @@ function hasControlCharacter(value) {
772
748
  async function chooseS3CredentialUpdate(ctx, profile, signal) {
773
749
  const hasStored = typeof profile.accessKeyId === "string" && profile.accessKeyId.length > 0 && typeof profile.secretAccessKey === "string" && profile.secretAccessKey.length > 0;
774
750
  if (hasStored) {
775
- const action = await ctx.ui.select(
776
- "Credentials",
777
- ["Keep current credentials", "Replace credentials", "Cancel"],
778
- { signal }
779
- );
751
+ const action = await ctx.ui.select("Credentials", ["Keep current credentials", "Replace credentials", "Cancel"], {
752
+ signal
753
+ });
780
754
  throwIfAborted(signal);
781
755
  if (!action || action === "Cancel") return void 0;
782
756
  if (action === "Keep current credentials") {
@@ -896,20 +870,13 @@ async function showS3Setup(ctx, preset, targetName, signal) {
896
870
  if (!saved || signal?.aborted) return false;
897
871
  await refreshTargetCompletions();
898
872
  if (!signal?.aborted)
899
- ctx.ui.notify(
900
- `Sync setup \u201C${safeTerminalText(targetName)}\u201D saved. Choose Sync now to start.`,
901
- "info"
902
- );
873
+ ctx.ui.notify(`Sync setup \u201C${safeTerminalText(targetName)}\u201D saved. Choose Sync now to start.`, "info");
903
874
  return true;
904
875
  }
905
876
  async function showAddS3Target(ctx, raw, profile, name, signal) {
906
877
  const location = await chooseAdditionalRemoteLocation(ctx, raw, profile, name, signal);
907
878
  if (!location) return;
908
- const storage = await promptAvailableSetupStorage(
909
- ctx,
910
- { connection: profile, ...location },
911
- signal
912
- );
879
+ const storage = await promptAvailableSetupStorage(ctx, { connection: profile, ...location }, signal);
913
880
  if (!storage) return;
914
881
  const include = await chooseSetupContent(ctx, signal);
915
882
  if (!include) return;
@@ -973,16 +940,14 @@ async function showEditS3Target(ctx, partial, signal) {
973
940
  (saveSignal) => updateSyncSetup(
974
941
  partial.setupName,
975
942
  (setup) => {
976
- if (typeof setup.storage.bucket !== "string")
977
- throw new Error("Sync setup storage type changed; reopen it.");
943
+ if (typeof setup.storage.bucket !== "string") throw new Error("Sync setup storage type changed; reopen it.");
978
944
  return { ...setup, storage: { ...setup.storage, bucket, path: storagePath } };
979
945
  },
980
946
  { expectedStorage: partial, expectedConnection: connection, signal: saveSignal }
981
947
  ),
982
948
  signal
983
949
  );
984
- if (saved && !signal?.aborted)
985
- ctx.ui.notify(`Saved sync setup \u201C${safeTerminalText(partial.setupName)}\u201D.`, "info");
950
+ if (saved && !signal?.aborted) ctx.ui.notify(`Saved sync setup \u201C${safeTerminalText(partial.setupName)}\u201D.`, "info");
986
951
  }
987
952
 
988
953
  // src/ui/setup/webdav-ui.ts
@@ -1038,11 +1003,7 @@ async function showWebDavSetup(ctx, targetName, signal) {
1038
1003
  async function showAddWebDavTarget(ctx, name, profile, signal) {
1039
1004
  const remotePath = await chooseDestination(ctx, signal);
1040
1005
  if (!remotePath) return false;
1041
- const storage = await promptAvailableSetupStorage(
1042
- ctx,
1043
- { connection: profile, path: remotePath },
1044
- signal
1045
- );
1006
+ const storage = await promptAvailableSetupStorage(ctx, { connection: profile, path: remotePath }, signal);
1046
1007
  if (!storage) return false;
1047
1008
  const include = await chooseSetupContent(ctx, signal);
1048
1009
  if (!include) return false;
@@ -1095,8 +1056,7 @@ async function showEditWebDavTarget(ctx, partial, signal) {
1095
1056
  ),
1096
1057
  signal
1097
1058
  );
1098
- if (saved && !signal?.aborted)
1099
- ctx.ui.notify(`Saved sync setup \u201C${safeTerminalText(partial.setupName)}\u201D.`, "info");
1059
+ if (saved && !signal?.aborted) ctx.ui.notify(`Saved sync setup \u201C${safeTerminalText(partial.setupName)}\u201D.`, "info");
1100
1060
  return saved;
1101
1061
  }
1102
1062
  async function showAddWebDavStorageProfile(ctx, signal) {
@@ -1120,32 +1080,19 @@ async function showAddWebDavStorageProfile(ctx, signal) {
1120
1080
  "Adding a connection does not contact the server or start syncing."
1121
1081
  ],
1122
1082
  "Add storage connection",
1123
- (saveSignal) => addStorageConnection(
1124
- name,
1125
- { type: "webdav", url, credentials: { username, password } },
1126
- saveSignal
1127
- ),
1083
+ (saveSignal) => addStorageConnection(name, { type: "webdav", url, credentials: { username, password } }, saveSignal),
1128
1084
  signal
1129
1085
  );
1130
1086
  if (saved && !signal?.aborted) ctx.ui.notify(`Added storage connection \u201C${safeTerminalText(name)}\u201D.`, "info");
1131
1087
  return saved;
1132
1088
  }
1133
1089
  async function showEditWebDavStorageProfile(ctx, name, profile, signal, affectedSetups) {
1134
- const url = await promptWebDavUrl(
1135
- ctx,
1136
- signal,
1137
- typeof profile.url === "string" ? profile.url : void 0
1138
- );
1090
+ const url = await promptWebDavUrl(ctx, signal, typeof profile.url === "string" ? profile.url : void 0);
1139
1091
  if (!url) return false;
1140
1092
  const username = await promptUsername(ctx, signal);
1141
1093
  if (!username) return false;
1142
1094
  const hasPassword = typeof profile.password === "string" && profile.password.length > 0;
1143
- const passwordAction = hasPassword ? await select(
1144
- ctx,
1145
- "WebDAV password",
1146
- ["Keep current password", "Replace password", "Cancel"],
1147
- signal
1148
- ) : "Replace password";
1095
+ const passwordAction = hasPassword ? await select(ctx, "WebDAV password", ["Keep current password", "Replace password", "Cancel"], signal) : "Replace password";
1149
1096
  if (!passwordAction || passwordAction === "Cancel") return false;
1150
1097
  const replacePassword = passwordAction === "Replace password";
1151
1098
  const password = replacePassword ? await promptSecret(ctx, "New WebDAV password", { signal }) : void 0;
@@ -1253,4 +1200,4 @@ export {
1253
1200
  showAddWebDavStorageProfile,
1254
1201
  showEditWebDavStorageProfile
1255
1202
  };
1256
- //# sourceMappingURL=chunk-DHVFS4QK.ts.map
1203
+ //# sourceMappingURL=chunk-UA7RXOIT.ts.map
@@ -0,0 +1,7 @@
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 { safeTerminalText } from \"../terminal-text.js\";\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 const AUTOMATIC_SYNC_DESCRIPTION =\n \"Check the current setup in the background at startup; review changes in /sync before transferring. At shutdown, automatically push selected content only when sessions are included. No startup dialogs.\";\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
+ }