@narumitw/pi-sync 0.54.3 → 0.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/README.md +38 -11
  2. package/dist/chunks/agent-candidate-3JN6DJKT.ts +26 -0
  3. package/dist/chunks/agent-plan-QCUJWBP4.ts +99 -0
  4. package/dist/chunks/agent-plan-QCUJWBP4.ts.map +7 -0
  5. package/dist/chunks/agent-runner-E2JU2VZ6.ts +182 -0
  6. package/dist/chunks/agent-runner-E2JU2VZ6.ts.map +7 -0
  7. package/dist/chunks/agent-store-A3F6IYWZ.ts +152 -0
  8. package/dist/chunks/agent-store-A3F6IYWZ.ts.map +7 -0
  9. package/dist/chunks/chunk-5Q5SSKNG.ts +128 -0
  10. package/dist/chunks/chunk-5Q5SSKNG.ts.map +7 -0
  11. package/dist/chunks/chunk-5XZOC7FD.ts +215 -0
  12. package/dist/chunks/chunk-5XZOC7FD.ts.map +7 -0
  13. package/dist/chunks/{chunk-GC3QOL6J.ts → chunk-AAEEHR7H.ts} +31 -87
  14. package/dist/chunks/chunk-AAEEHR7H.ts.map +7 -0
  15. package/dist/chunks/{chunk-R35N4CL3.ts → chunk-B4QZBDBT.ts} +2 -2
  16. package/dist/chunks/{chunk-KGE47GCZ.ts → chunk-CRKTAPSL.ts} +8 -8
  17. package/dist/chunks/chunk-DT7M4VQS.ts +69 -0
  18. package/dist/chunks/chunk-DT7M4VQS.ts.map +7 -0
  19. package/dist/chunks/chunk-ED3TYIVW.ts +229 -0
  20. package/dist/chunks/chunk-ED3TYIVW.ts.map +7 -0
  21. package/dist/chunks/{chunk-HMXUKU43.ts → chunk-EUMINX7L.ts} +6 -6
  22. package/dist/chunks/chunk-FQOSHGJ7.ts +215 -0
  23. package/dist/chunks/chunk-FQOSHGJ7.ts.map +7 -0
  24. package/dist/chunks/chunk-GNH73BJ5.ts +153 -0
  25. package/dist/chunks/chunk-GNH73BJ5.ts.map +7 -0
  26. package/dist/chunks/{chunk-YTHQEW35.ts → chunk-GP5DU62N.ts} +8 -9
  27. package/dist/chunks/chunk-GP5DU62N.ts.map +7 -0
  28. package/dist/chunks/{chunk-AAZDBIBJ.ts → chunk-GSNPASKB.ts} +2 -2
  29. package/dist/chunks/{chunk-E6ONFG57.ts → chunk-IWZH5KYS.ts} +11 -8
  30. package/dist/chunks/chunk-IWZH5KYS.ts.map +7 -0
  31. package/dist/chunks/{chunk-CAGJOKB7.ts → chunk-JJTARUSO.ts} +15 -14
  32. package/dist/chunks/chunk-JJTARUSO.ts.map +7 -0
  33. package/dist/chunks/{chunk-ITFR6NNQ.ts → chunk-NLWS55B6.ts} +2 -1
  34. package/dist/chunks/{chunk-ITFR6NNQ.ts.map → chunk-NLWS55B6.ts.map} +2 -2
  35. package/dist/chunks/{chunk-2FETCGGT.ts → chunk-OEWQVWLC.ts} +4 -4
  36. package/dist/chunks/{chunk-35GM6XKM.ts → chunk-OTZRCKYP.ts} +128 -382
  37. package/dist/chunks/chunk-OTZRCKYP.ts.map +7 -0
  38. package/dist/chunks/{chunk-XU2VXGQV.ts → chunk-OWBAZA6J.ts} +14 -8
  39. package/dist/chunks/chunk-OWBAZA6J.ts.map +7 -0
  40. package/dist/chunks/chunk-PRUEIIK7.ts +24 -0
  41. package/dist/chunks/chunk-PRUEIIK7.ts.map +7 -0
  42. package/dist/chunks/chunk-QGK445K7.ts +21 -0
  43. package/dist/chunks/chunk-QGK445K7.ts.map +7 -0
  44. package/dist/chunks/{chunk-KATKRR3D.ts → chunk-QO333NM4.ts} +32 -11
  45. package/dist/chunks/chunk-QO333NM4.ts.map +7 -0
  46. package/dist/chunks/{chunk-I4JYVFUS.ts → chunk-QSHMOL3I.ts} +21 -22
  47. package/dist/chunks/chunk-QSHMOL3I.ts.map +7 -0
  48. package/dist/chunks/chunk-S2FMH5FT.ts +97 -0
  49. package/dist/chunks/chunk-S2FMH5FT.ts.map +7 -0
  50. package/dist/chunks/{chunk-BVVP33U5.ts → chunk-SWRVXVFD.ts} +12 -9
  51. package/dist/chunks/chunk-SWRVXVFD.ts.map +7 -0
  52. package/dist/chunks/{chunk-ZX2Q6THB.ts → chunk-UBV24CG4.ts} +4 -5
  53. package/dist/chunks/chunk-UBV24CG4.ts.map +7 -0
  54. package/dist/chunks/chunk-UOHR7LRO.ts +70 -0
  55. package/dist/chunks/chunk-UOHR7LRO.ts.map +7 -0
  56. package/dist/chunks/{chunk-VCL7TZYW.ts → chunk-UPNVIUBN.ts} +3 -3
  57. package/dist/chunks/chunk-VJN7KU4J.ts +350 -0
  58. package/dist/chunks/chunk-VJN7KU4J.ts.map +7 -0
  59. package/dist/chunks/chunk-YHT4YTYG.ts +31 -0
  60. package/dist/chunks/chunk-YHT4YTYG.ts.map +7 -0
  61. package/dist/chunks/{chunk-A3TFXY4O.ts → chunk-YK52VDXG.ts} +6 -5
  62. package/dist/chunks/chunk-YK52VDXG.ts.map +7 -0
  63. package/dist/chunks/config-KGIYTTXQ.ts +37 -0
  64. package/dist/chunks/{conflict-artifacts-4CZFB7WI.ts → conflict-artifacts-FXFIIBCB.ts} +8 -7
  65. package/dist/chunks/{conflict-review-ZOTOHL2E.ts → conflict-review-6WIEQLXW.ts} +31 -25
  66. package/dist/chunks/{conflict-review-ZOTOHL2E.ts.map → conflict-review-6WIEQLXW.ts.map} +1 -1
  67. package/dist/chunks/continuous-record-LFRVXQBD.ts +30 -0
  68. package/dist/chunks/continuous-sync-AWAAOXK2.ts +545 -0
  69. package/dist/chunks/continuous-sync-AWAAOXK2.ts.map +7 -0
  70. package/dist/chunks/{file-selection-UNHBVVON.ts → file-selection-3JJYOVNR.ts} +5 -5
  71. package/dist/chunks/{git-backend-FD7AVSK6.ts → git-backend-KYDZ673X.ts} +28 -32
  72. package/dist/chunks/git-backend-KYDZ673X.ts.map +7 -0
  73. package/dist/chunks/{manager-result-dispatcher-HVRTPEVK.ts → manager-result-dispatcher-AGBBVDDS.ts} +10 -9
  74. package/dist/chunks/{manager-ui-ZIN4BUSF.ts → manager-ui-KRAW3NE2.ts} +184 -45
  75. package/dist/chunks/manager-ui-KRAW3NE2.ts.map +7 -0
  76. package/dist/chunks/{merge-baseline-store-ICXVTCML.ts → merge-baseline-store-RFCAH7KL.ts} +5 -5
  77. package/dist/chunks/{remote-selection-ui-H6AEVA3Q.ts → remote-selection-ui-5725JDNC.ts} +9 -8
  78. package/dist/chunks/remote-selection-ui-5725JDNC.ts.map +7 -0
  79. package/dist/chunks/{s3-backend-Y4P3O5B5.ts → s3-backend-Y7WSCLJI.ts} +38 -38
  80. package/dist/chunks/s3-backend-Y7WSCLJI.ts.map +7 -0
  81. package/dist/chunks/{setup-switch-ZMW5C4M7.ts → setup-switch-E7PHKI6J.ts} +7 -6
  82. package/dist/chunks/setup-switch-E7PHKI6J.ts.map +7 -0
  83. package/dist/chunks/{setup-wizard-VW7F3JN4.ts → setup-wizard-65DROCIJ.ts} +14 -13
  84. package/dist/chunks/setup-wizard-65DROCIJ.ts.map +7 -0
  85. package/dist/chunks/{sync-inspection-3EMS2J5B.ts → sync-inspection-XFJOAMJD.ts} +8 -8
  86. package/dist/chunks/sync-inspection-XFJOAMJD.ts.map +7 -0
  87. package/dist/chunks/{sync-operations-2CWST333.ts → sync-operations-HDUDT5PD.ts} +62 -63
  88. package/dist/chunks/sync-operations-HDUDT5PD.ts.map +7 -0
  89. package/dist/chunks/{webdav-backend-TBILVEQK.ts → webdav-backend-6K26F6LT.ts} +39 -48
  90. package/dist/chunks/webdav-backend-6K26F6LT.ts.map +7 -0
  91. package/dist/index.ts +165 -85
  92. package/dist/index.ts.map +3 -3
  93. package/docs/agent-mode-verification.md +99 -0
  94. package/docs/continuous-sync-verification.md +87 -0
  95. package/docs/settings.md +32 -247
  96. package/package.json +11 -5
  97. package/skills/configure-pi-sync/SKILL.md +54 -0
  98. package/skills/configure-pi-sync/references/configuration.md +650 -0
  99. package/src/backends/git/git-backend.ts +1 -4
  100. package/src/backends/git/git-runner.ts +1 -5
  101. package/src/backends/s3/s3-backend.ts +3 -25
  102. package/src/backends/s3/s3-client.ts +14 -2
  103. package/src/backends/snapshot-pointer.ts +27 -0
  104. package/src/backends/webdav/webdav-backend.ts +3 -29
  105. package/src/backends/webdav/webdav-client.ts +11 -7
  106. package/src/commands/command-execution.ts +5 -2
  107. package/src/commands/command-handler.ts +15 -3
  108. package/src/commands/command-types.ts +6 -0
  109. package/src/commands/command.ts +1 -0
  110. package/src/settings/config.ts +7 -0
  111. package/src/settings/settings-store.ts +0 -34
  112. package/src/settings/settings-types.ts +8 -0
  113. package/src/settings/settings-validation.ts +1 -1
  114. package/src/snapshot/snapshot-codec.ts +1 -5
  115. package/src/state/lock.ts +13 -10
  116. package/src/state/merge-baseline-store.ts +2 -2
  117. package/src/state/state-directory.ts +8 -1
  118. package/src/sync/agent-candidate.ts +251 -0
  119. package/src/sync/agent-plan.ts +87 -0
  120. package/src/sync/agent-policy.ts +13 -0
  121. package/src/sync/agent-request.ts +17 -0
  122. package/src/sync/agent-runner.ts +188 -0
  123. package/src/sync/agent-store.ts +151 -0
  124. package/src/sync/agent-sync.ts +91 -0
  125. package/src/sync/automatic-sync.ts +2 -1
  126. package/src/sync/continuous-errors.ts +85 -0
  127. package/src/sync/continuous-lease.ts +221 -0
  128. package/src/sync/continuous-record.ts +179 -0
  129. package/src/sync/continuous-storage.ts +55 -0
  130. package/src/sync/continuous-sync.ts +516 -0
  131. package/src/sync/continuous-watch.ts +59 -0
  132. package/src/sync/merged-sync.ts +70 -12
  133. package/src/sync/remote-snapshot.ts +2 -3
  134. package/src/sync/settings-merge.ts +19 -3
  135. package/src/sync/setup-switch.ts +1 -5
  136. package/src/sync/startup-check.ts +15 -11
  137. package/src/sync/sync-inspection.ts +8 -1
  138. package/src/sync/sync-mutations.ts +6 -17
  139. package/src/sync/sync-queries.ts +5 -0
  140. package/src/sync/text-merge.ts +3 -3
  141. package/src/sync-extension.ts +75 -19
  142. package/src/ui/agent-mode-setting.ts +91 -0
  143. package/src/ui/manager-state.ts +2 -0
  144. package/src/ui/remote-selection-ui.ts +5 -5
  145. package/src/ui/settings-ui.ts +83 -1
  146. package/src/ui/setup/s3-credentials-ui.ts +1 -5
  147. package/src/ui/setup/setup-name-ui.ts +2 -5
  148. package/src/ui/setup/setup-switcher.ts +2 -0
  149. package/src/ui/sync-setups-ui.ts +3 -5
  150. package/dist/chunks/chunk-26PMXY7E.ts +0 -362
  151. package/dist/chunks/chunk-26PMXY7E.ts.map +0 -7
  152. package/dist/chunks/chunk-35GM6XKM.ts.map +0 -7
  153. package/dist/chunks/chunk-A3TFXY4O.ts.map +0 -7
  154. package/dist/chunks/chunk-BVVP33U5.ts.map +0 -7
  155. package/dist/chunks/chunk-CAGJOKB7.ts.map +0 -7
  156. package/dist/chunks/chunk-E6ONFG57.ts.map +0 -7
  157. package/dist/chunks/chunk-GC3QOL6J.ts.map +0 -7
  158. package/dist/chunks/chunk-I4JYVFUS.ts.map +0 -7
  159. package/dist/chunks/chunk-KATKRR3D.ts.map +0 -7
  160. package/dist/chunks/chunk-XU2VXGQV.ts.map +0 -7
  161. package/dist/chunks/chunk-YTHQEW35.ts.map +0 -7
  162. package/dist/chunks/chunk-ZX2Q6THB.ts.map +0 -7
  163. package/dist/chunks/git-backend-FD7AVSK6.ts.map +0 -7
  164. package/dist/chunks/manager-ui-ZIN4BUSF.ts.map +0 -7
  165. package/dist/chunks/s3-backend-Y4P3O5B5.ts.map +0 -7
  166. package/dist/chunks/setup-wizard-VW7F3JN4.ts.map +0 -7
  167. package/dist/chunks/sync-operations-2CWST333.ts.map +0 -7
  168. package/dist/chunks/webdav-backend-TBILVEQK.ts.map +0 -7
  169. /package/dist/chunks/{conflict-artifacts-4CZFB7WI.ts.map → agent-candidate-3JN6DJKT.ts.map} +0 -0
  170. /package/dist/chunks/{chunk-R35N4CL3.ts.map → chunk-B4QZBDBT.ts.map} +0 -0
  171. /package/dist/chunks/{chunk-KGE47GCZ.ts.map → chunk-CRKTAPSL.ts.map} +0 -0
  172. /package/dist/chunks/{chunk-HMXUKU43.ts.map → chunk-EUMINX7L.ts.map} +0 -0
  173. /package/dist/chunks/{chunk-AAZDBIBJ.ts.map → chunk-GSNPASKB.ts.map} +0 -0
  174. /package/dist/chunks/{chunk-2FETCGGT.ts.map → chunk-OEWQVWLC.ts.map} +0 -0
  175. /package/dist/chunks/{chunk-VCL7TZYW.ts.map → chunk-UPNVIUBN.ts.map} +0 -0
  176. /package/dist/chunks/{manager-result-dispatcher-HVRTPEVK.ts.map → config-KGIYTTXQ.ts.map} +0 -0
  177. /package/dist/chunks/{merge-baseline-store-ICXVTCML.ts.map → conflict-artifacts-FXFIIBCB.ts.map} +0 -0
  178. /package/dist/chunks/{remote-selection-ui-H6AEVA3Q.ts.map → continuous-record-LFRVXQBD.ts.map} +0 -0
  179. /package/dist/chunks/{file-selection-UNHBVVON.ts.map → file-selection-3JJYOVNR.ts.map} +0 -0
  180. /package/dist/chunks/{setup-switch-ZMW5C4M7.ts.map → manager-result-dispatcher-AGBBVDDS.ts.map} +0 -0
  181. /package/dist/chunks/{sync-inspection-3EMS2J5B.ts.map → merge-baseline-store-RFCAH7KL.ts.map} +0 -0
@@ -1,5 +1,8 @@
1
1
  // @generated by scripts/build-runtime.mjs; do not edit.
2
2
  // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
+ import {
4
+ confirmMergeReview
5
+ } from "./chunk-5XZOC7FD.ts";
3
6
  import {
4
7
  applyS3CredentialUpdate,
5
8
  chooseS3CredentialUpdate,
@@ -19,34 +22,37 @@ import {
19
22
  showEditS3Target,
20
23
  showEditWebDavStorageProfile,
21
24
  showEditWebDavTarget
22
- } from "./chunk-I4JYVFUS.ts";
25
+ } from "./chunk-QSHMOL3I.ts";
23
26
  import {
24
27
  dispatchManagerResult
25
- } from "./chunk-HMXUKU43.ts";
28
+ } from "./chunk-EUMINX7L.ts";
26
29
  import {
27
30
  runCancellableOperation
28
- } from "./chunk-CAGJOKB7.ts";
29
- import "./chunk-A3TFXY4O.ts";
30
- import "./chunk-2FETCGGT.ts";
31
+ } from "./chunk-JJTARUSO.ts";
32
+ import "./chunk-YK52VDXG.ts";
31
33
  import {
32
34
  SETUP_SWITCH_ACTION_OPTIONS,
33
35
  saveOnSwitch,
34
36
  setupSwitchActionFromLabel,
35
37
  setupSwitchActionLabel,
36
38
  useSyncSetup
37
- } from "./chunk-YTHQEW35.ts";
39
+ } from "./chunk-GP5DU62N.ts";
40
+ import "./chunk-OEWQVWLC.ts";
41
+ import {
42
+ addStorageConnection,
43
+ removeStorageConnection,
44
+ removeSyncSetup,
45
+ updateStorageConnection,
46
+ updateSyncSetup
47
+ } from "./chunk-B4QZBDBT.ts";
38
48
  import {
39
49
  observationMatchesConfig,
40
50
  observationSummary,
41
51
  syncAttentionMatchesConfig
42
- } from "./chunk-AAZDBIBJ.ts";
52
+ } from "./chunk-GSNPASKB.ts";
43
53
  import {
44
- captureMutationOwner,
45
- inspectLock,
46
- isLockGuardHeld,
47
- isStaleLock
48
- } from "./chunk-GC3QOL6J.ts";
49
- import "./chunk-PWMWOJP4.ts";
54
+ captureMutationOwner
55
+ } from "./chunk-UOHR7LRO.ts";
50
56
  import {
51
57
  automaticSyncSummary
52
58
  } from "./chunk-ECYCNZOE.ts";
@@ -57,22 +63,17 @@ import {
57
63
  AUTOMATIC_SYNC_DESCRIPTION,
58
64
  STARTUP_TRANSFER_DESCRIPTION,
59
65
  startupTransferSummary
60
- } from "./chunk-ITFR6NNQ.ts";
66
+ } from "./chunk-NLWS55B6.ts";
61
67
  import {
62
68
  safeTerminalText
63
69
  } from "./chunk-AMJRUXFT.ts";
70
+ import "./chunk-UBV24CG4.ts";
64
71
  import {
65
- readStateForConfig,
66
- syncStateFingerprint
67
- } from "./chunk-VCL7TZYW.ts";
68
- import "./chunk-BVVP33U5.ts";
72
+ syncErrorGuidance
73
+ } from "./chunk-G4RUXRWZ.ts";
69
74
  import {
70
- addStorageConnection,
71
- removeStorageConnection,
72
- removeSyncSetup,
73
- updateStorageConnection,
74
- updateSyncSetup
75
- } from "./chunk-R35N4CL3.ts";
75
+ errorMessage
76
+ } from "./chunk-7D5SF7P3.ts";
76
77
  import {
77
78
  activeLocalConfigPath,
78
79
  isCloudflareR2Endpoint,
@@ -83,28 +84,35 @@ import {
83
84
  normalizeS3Endpoint,
84
85
  ownRecord,
85
86
  readLocalConfigObject,
87
+ requireSettings,
86
88
  syncCheckConfigFingerprint,
87
89
  syncConfigReviewIdentity,
88
90
  updateLocalConfig
89
- } from "./chunk-KATKRR3D.ts";
90
- import "./chunk-2JZFHNLM.ts";
91
- import "./chunk-T2SJD3N7.ts";
92
- import "./chunk-ZX2Q6THB.ts";
93
- import {
94
- syncErrorGuidance
95
- } from "./chunk-G4RUXRWZ.ts";
96
- import {
97
- errorMessage
98
- } from "./chunk-7D5SF7P3.ts";
91
+ } from "./chunk-QO333NM4.ts";
99
92
  import {
100
93
  normalizeLocalFields,
101
94
  sameLocalFields
102
95
  } from "./chunk-A6HU4ERM.ts";
96
+ import {
97
+ inspectLock,
98
+ isLockGuardHeld,
99
+ isStaleLock
100
+ } from "./chunk-AAEEHR7H.ts";
101
+ import {
102
+ throwIfAborted
103
+ } from "./chunk-PWMWOJP4.ts";
103
104
  import {
104
105
  compareSyncInclude,
105
106
  syncIncludeSelection
106
107
  } from "./chunk-QOFMXPM5.ts";
107
108
  import "./chunk-ZW5ZLGBI.ts";
109
+ import {
110
+ readStateForConfig,
111
+ syncStateFingerprint
112
+ } from "./chunk-UPNVIUBN.ts";
113
+ import "./chunk-SWRVXVFD.ts";
114
+ import "./chunk-2JZFHNLM.ts";
115
+ import "./chunk-T2SJD3N7.ts";
108
116
  import "./chunk-HUZ5CR4W.ts";
109
117
 
110
118
  // src/ui/manager-ui.ts
@@ -176,7 +184,7 @@ function blockedSyncMenuItem(label, manager) {
176
184
  };
177
185
  }
178
186
  async function showManagerAttention(ctx, attention, runRoute, signal, onSelectionResolved) {
179
- const { showRemoteSelectionReview } = await import("./remote-selection-ui-H6AEVA3Q.ts");
187
+ const { showRemoteSelectionReview } = await import("./remote-selection-ui-5725JDNC.ts");
180
188
  if (signal?.aborted) return "close";
181
189
  const review = await showRemoteSelectionReview(ctx, attention.decision.setupName, signal, void 0, {
182
190
  decision: attention.decision,
@@ -258,10 +266,6 @@ async function countValidSyncSetups(setups, signal) {
258
266
  }
259
267
  return count;
260
268
  }
261
- function throwIfAborted(signal) {
262
- if (!signal?.aborted) return;
263
- throw signal.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted", "AbortError");
264
- }
265
269
  async function showSyncSetups(ctx, actions, signal) {
266
270
  let selectedName;
267
271
  let exit = false;
@@ -399,6 +403,8 @@ async function loadSetupMenuState(selectedName, signal) {
399
403
  `Sessions: ${selection.sessions ? "On \u2014 privacy-sensitive" : "Off"}`,
400
404
  `Automatic sync: ${config.automatic ? "On" : "Off"}`,
401
405
  `Automatic transfer at startup: ${config.automaticTransfer ? "On \u2014 may upload, replace, or delete selected files; no reload" : "Off"}`,
406
+ `Agent mode: ${config.agentMode ? "On (experimental; autonomous merged sync)" : "Off"}`,
407
+ `Continuous sync: ${config.continuous ? config.agentMode ? "On (experimental; recurring requests and transfers)" : "Saved On; paused until Agent mode is enabled" : "Off"}`,
402
408
  isCurrent ? "Edit included content and automatic sync in /sync \u2192 Settings." : "To edit included content or automatic sync, make this setup current, then open /sync \u2192 Settings."
403
409
  ];
404
410
  } catch (error) {
@@ -546,6 +552,8 @@ async function describeManagerState(signal, attention, inspectOperation = inspec
546
552
  `Included: ${selection.builtIns.length} built-in group${selection.builtIns.length === 1 ? "" : "s"} \xB7 ${selection.custom.length} extra path${selection.custom.length === 1 ? "" : "s"} \xB7 Sessions ${selection.sessions ? "on" : "off"}`,
547
553
  `Automatic sync: ${automaticSyncSummary(config.automatic)}`,
548
554
  `Startup transfer: ${startupTransferSummary(config)}`,
555
+ `Agent mode: ${config.agentMode ? "On (experimental; autonomous merged sync)" : "Off"}`,
556
+ ...config.continuous ? await (await import("./continuous-record-LFRVXQBD.ts")).continuousStatusLines(config) : [],
549
557
  `Last applied: ${lastAppliedSnapshot}`,
550
558
  ...noSyncedContent ? ["", "No included content is selected. Choose included content in Settings before syncing."] : [],
551
559
  "",
@@ -637,6 +645,66 @@ function backendStorageDescription(config) {
637
645
  // src/ui/settings-ui.ts
638
646
  import { defineMenu as defineMenu4, runMenu as runMenu4 } from "@narumitw/pi-tui-kit";
639
647
 
648
+ // src/ui/agent-mode-setting.ts
649
+ import { isDeepStrictEqual } from "node:util";
650
+ var AGENT_MODE_DESCRIPTION = "This setup, experimental: one autonomous merged sync next startup and on Sync now. Sends eligible conflict text to the selected Pi model; may incur costs and replace/delete selected local and remote content without transfer prompts. No automatic reload. Unsupported conflicts pause.";
651
+ var CONTINUOUS_DESCRIPTION = "This setup, experimental: recurring sync while Pi is open. Requires Agent mode. Watches selected files, checks the remote every 60\u201366 seconds, and retries temporary failures. Local changes and retries can cause extra requests between polls. May disclose conflict text and incur model/storage costs. No automatic reload.";
652
+ function saveContinuousMode(ctx, setupName, enabled, signal) {
653
+ return saveAgentMode(ctx, setupName, enabled, signal, "continuous");
654
+ }
655
+ async function saveAgentMode(ctx, setupName, enabled, signal, preference = "agentMode") {
656
+ const validate = captureMutationOwner(ctx, signal);
657
+ const settings = await requireSettings();
658
+ validate();
659
+ const setup = settings.syncSetups[setupName];
660
+ if (!setup || settings.activeSyncSetup !== setupName) throw new Error("Current sync setup changed; reopen Settings.");
661
+ const continuous = preference === "continuous";
662
+ const label = continuous ? "Continuous sync" : "Agent mode";
663
+ if (enabled && continuous && !setup.sync.agentMode) throw new Error("Enable Agent mode before Continuous sync.");
664
+ if (Boolean(setup.sync[preference]) === enabled) return true;
665
+ if (enabled) {
666
+ const summary = [
667
+ `Setup: ${safeTerminalText(setupName)}`,
668
+ `Storage connection: ${safeTerminalText(setup.storage.connection)}`,
669
+ `Storage path: ${safeTerminalText(setup.storage.path)}`,
670
+ ...setup.storage.bucket ? [`Bucket: ${safeTerminalText(String(setup.storage.bucket))}`] : [],
671
+ ...setup.storage.branch ? [`Branch: ${safeTerminalText(String(setup.storage.branch))}`] : [],
672
+ `Included paths: ${setup.sync.include.map(safeTerminalText).join(", ")}`,
673
+ continuous ? CONTINUOUS_DESCRIPTION : AGENT_MODE_DESCRIPTION,
674
+ ...continuous ? [
675
+ "Upgrade all Pi processes sharing this agent directory before enabling Continuous sync. Monitoring starts after the /sync command or manager closes. An elected idle local session uses its selected Pi model; another session can use a different provider/model. Each computer is a separate replica.",
676
+ "Automatic requests are limited to two per candidate and two per replica binding in a rolling 15-minute window, across restarts. Network/storage checks and requests may incur costs. Retries start at five seconds and grow to five minutes. These are request bounds, not a currency cap."
677
+ ] : setup.sync.continuous ? ["The saved Continuous sync preference will resume monitoring after the /sync command or manager closes."] : [],
678
+ "Only bounded Markdown/plain-text conflicts and atomic global settings choices are eligible. Model errors can change intended behavior. Session histories, code, deletion conflicts and path collisions are not model-resolved.",
679
+ "The existing baseline, selection, secret-scan and publication checks remain. Pi Sync cannot exclude arbitrary concurrent local writers. Disabling does not undo completed transfers or provider charges. No transfer starts from Settings."
680
+ ].join("\n\n");
681
+ if (!await confirmMergeReview(
682
+ ctx,
683
+ `Enable experimental ${label}?`,
684
+ summary,
685
+ signal,
686
+ () => !signal?.aborted,
687
+ `Enable ${label}`,
688
+ summary.split("\n")
689
+ ))
690
+ return false;
691
+ validate();
692
+ }
693
+ await updateLocalConfig((current) => {
694
+ validate();
695
+ if (current.activeSyncSetup !== setupName || !isDeepStrictEqual(current.syncSetups[setupName], setup) || !isDeepStrictEqual(
696
+ current.storageConnections[setup.storage.connection],
697
+ settings.storageConnections[setup.storage.connection]
698
+ ))
699
+ throw new Error("Sync setup or connection changed during Agent mode review; reopen Settings.");
700
+ return {
701
+ ...current,
702
+ syncSetups: { ...current.syncSetups, [setupName]: { ...setup, sync: { ...setup.sync, [preference]: enabled } } }
703
+ };
704
+ }, signal);
705
+ return true;
706
+ }
707
+
640
708
  // src/ui/settings-frame.ts
641
709
  import { stripVTControlCharacters } from "node:util";
642
710
  function boundedSettingsUI(ctx) {
@@ -682,7 +750,7 @@ function boundedSettingsUI(ctx) {
682
750
  }
683
751
 
684
752
  // src/ui/storage-connections-ui.ts
685
- import { isDeepStrictEqual } from "node:util";
753
+ import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
686
754
  import { defineMenu as defineMenu2, runMenu as runMenu2 } from "@narumitw/pi-tui-kit";
687
755
  async function showStorageConnections(ctx, signal) {
688
756
  let selectedName;
@@ -877,7 +945,7 @@ async function editStorageConnection(ctx, name, profile, usedBy, signal) {
877
945
  (saveSignal) => updateStorageConnection(
878
946
  name,
879
947
  (current) => {
880
- if (current.type !== "s3" || !isDeepStrictEqual(current, profile)) {
948
+ if (current.type !== "s3" || !isDeepStrictEqual2(current, profile)) {
881
949
  throw new Error("Storage connection changed while it was open; reopen it.");
882
950
  }
883
951
  return {
@@ -1089,6 +1157,8 @@ async function showSetupSwitcher(ctx, runRoute, selectedName, signal) {
1089
1157
  `Included content: ${config.include.length} paths`,
1090
1158
  `Automatic sync: ${automaticSyncSummary(config.automatic)} \xB7 Sessions: ${config.include.includes("sessions") ? "On" : "Off"}`,
1091
1159
  `Automatic transfer at startup: ${config.automaticTransfer ? "On \u2014 may upload, replace, or delete selected files; no reload" : "Off"}`,
1160
+ `Agent mode: ${config.agentMode ? "On (experimental; autonomous merged sync)" : "Off"}`,
1161
+ `Continuous sync: ${config.continuous ? config.agentMode ? "On (experimental; recurring requests and transfers)" : "Saved On; paused until Agent mode is enabled" : "Off"}`,
1092
1162
  "",
1093
1163
  switchEffect
1094
1164
  ].join("\n"),
@@ -1280,7 +1350,10 @@ async function showSyncSettings(ctx, runRoute, signal) {
1280
1350
  const setupName = initial.setupName;
1281
1351
  const groups = {
1282
1352
  content: { label: "Sync content", ids: ["include", "remoteInclude", "localFields"] },
1283
- behavior: { label: "Sync behavior", ids: ["automatic", "automaticTransfer", "onSwitch"] },
1353
+ behavior: {
1354
+ label: "Sync behavior",
1355
+ ids: ["automatic", "automaticTransfer", "agentMode", "continuous", "onSwitch"]
1356
+ },
1284
1357
  storage: { label: "Storage & setups", ids: ["storageLocation", "setups", "connections"] },
1285
1358
  advanced: { label: "Advanced", ids: ["mergeSettings", "contentPolicy", "skipSecretScan", "showStatus", "debug"] },
1286
1359
  all: { label: "All settings (search)", ids: [] }
@@ -1352,6 +1425,22 @@ async function showSyncSettings(ctx, runRoute, signal) {
1352
1425
  values: ["On", "Off"],
1353
1426
  action: "automatic-transfer"
1354
1427
  },
1428
+ {
1429
+ id: "agentMode",
1430
+ label: "Agent mode (experimental)",
1431
+ description: AGENT_MODE_DESCRIPTION,
1432
+ currentValue: state.agentMode ? "On" : "Off",
1433
+ values: ["On", "Off"],
1434
+ action: "agent-mode"
1435
+ },
1436
+ {
1437
+ id: "continuous",
1438
+ label: "Continuous sync (experimental)",
1439
+ description: `${CONTINUOUS_DESCRIPTION}${state.continuous && !state.agentMode ? " Saved On, but paused until Agent mode is enabled." : ""}`,
1440
+ currentValue: state.continuous ? "On" : "Off",
1441
+ values: ["On", "Off"],
1442
+ action: "continuous"
1443
+ },
1355
1444
  {
1356
1445
  id: "onSwitch",
1357
1446
  label: "On setup switch",
@@ -1570,6 +1659,56 @@ async function showSyncSettings(ctx, runRoute, signal) {
1570
1659
  return { kind: "rejected" };
1571
1660
  }
1572
1661
  },
1662
+ "agent-mode": async ({ value, signal: actionSignal }) => {
1663
+ const mutationSignal = signal ? AbortSignal.any([signal, actionSignal]) : actionSignal;
1664
+ const validate = captureMutationOwner(ctx, mutationSignal);
1665
+ try {
1666
+ const saved = await saveAgentMode(ctx, setupName, value === "On", mutationSignal);
1667
+ if (!saved) return { kind: "rejected" };
1668
+ try {
1669
+ validate();
1670
+ ctx.ui.notify(
1671
+ "Agent mode saved. Applies to subsequent sync and the next session start; no transfer started.",
1672
+ "info"
1673
+ );
1674
+ } catch {
1675
+ }
1676
+ return { kind: "stay" };
1677
+ } catch (error) {
1678
+ try {
1679
+ validate();
1680
+ } catch {
1681
+ return { kind: "rejected" };
1682
+ }
1683
+ notifySaveFailure(ctx, error);
1684
+ return { kind: "rejected" };
1685
+ }
1686
+ },
1687
+ continuous: async ({ value, signal: actionSignal }) => {
1688
+ const mutationSignal = signal ? AbortSignal.any([signal, actionSignal]) : actionSignal;
1689
+ const validate = captureMutationOwner(ctx, mutationSignal);
1690
+ try {
1691
+ const saved = await saveContinuousMode(ctx, setupName, value === "On", mutationSignal);
1692
+ if (!saved) return { kind: "rejected" };
1693
+ try {
1694
+ validate();
1695
+ ctx.ui.notify(
1696
+ value === "On" ? "Continuous sync enabled. Monitoring starts after the /sync command or manager closes; completed work is not undone." : "Continuous sync disabled. Completed work is not undone.",
1697
+ "info"
1698
+ );
1699
+ } catch {
1700
+ }
1701
+ return { kind: "stay" };
1702
+ } catch (error) {
1703
+ try {
1704
+ validate();
1705
+ } catch {
1706
+ return { kind: "rejected" };
1707
+ }
1708
+ notifySaveFailure(ctx, error);
1709
+ return { kind: "rejected" };
1710
+ }
1711
+ },
1573
1712
  "automatic-transfer": async ({ value, signal: actionSignal }) => {
1574
1713
  const automaticTransfer = value === "On";
1575
1714
  const mutationSignal = signal ? AbortSignal.any([signal, actionSignal]) : actionSignal;
@@ -1657,7 +1796,7 @@ async function showSyncSettings(ctx, runRoute, signal) {
1657
1796
  },
1658
1797
  "remote-include": async ({ signal: actionSignal }) => {
1659
1798
  const reviewSignal = signal ? AbortSignal.any([signal, actionSignal]) : actionSignal;
1660
- const { showRemoteSelectionReview } = await import("./remote-selection-ui-H6AEVA3Q.ts");
1799
+ const { showRemoteSelectionReview } = await import("./remote-selection-ui-5725JDNC.ts");
1661
1800
  if (reviewSignal.aborted) return { kind: "rejected" };
1662
1801
  const review = await showRemoteSelectionReview(ctx, setupName, reviewSignal, void 0, {
1663
1802
  origin: "settings",
@@ -1752,7 +1891,7 @@ async function showSyncManager(ctx, runRoute, sessionSignal, options = {}) {
1752
1891
  if (!attention) {
1753
1892
  const observation = options.getObservation?.();
1754
1893
  if (!observation) return { kind: "stay" };
1755
- const { showRemoteSelectionReview } = await import("./remote-selection-ui-H6AEVA3Q.ts");
1894
+ const { showRemoteSelectionReview } = await import("./remote-selection-ui-5725JDNC.ts");
1756
1895
  if (sessionSignal?.aborted) return { kind: "close" };
1757
1896
  const config = await loadConfig();
1758
1897
  if (sessionSignal?.aborted) return { kind: "close" };
@@ -1955,4 +2094,4 @@ function syncMainMenuItem(label) {
1955
2094
  export {
1956
2095
  showSyncManager
1957
2096
  };
1958
- //# sourceMappingURL=manager-ui-ZIN4BUSF.ts.map
2097
+ //# sourceMappingURL=manager-ui-KRAW3NE2.ts.map