@narumitw/pi-sync 0.57.9 → 0.57.10

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 (147) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +2 -0
  3. package/dist/chunks/{agent-candidate-GNEYR225.ts → agent-candidate-EYB35AGL.ts} +12 -9
  4. package/dist/chunks/{agent-plan-3L7CRFDM.ts → agent-plan-KO43GTOR.ts} +22 -18
  5. package/dist/chunks/{agent-plan-3L7CRFDM.ts.map → agent-plan-KO43GTOR.ts.map} +1 -1
  6. package/dist/chunks/{agent-refusal-retry-RPTMUQXK.ts → agent-refusal-retry-C2HQROTP.ts} +11 -8
  7. package/dist/chunks/{agent-refusal-retry-RPTMUQXK.ts.map → agent-refusal-retry-C2HQROTP.ts.map} +1 -1
  8. package/dist/chunks/{agent-store-55CZOCPX.ts → agent-store-UT52DS7B.ts} +12 -11
  9. package/dist/chunks/{agent-store-55CZOCPX.ts.map → agent-store-UT52DS7B.ts.map} +1 -1
  10. package/dist/chunks/agent-sync-VM3TXWA3.ts +22 -0
  11. package/dist/chunks/{chunk-6FVVRTL5.ts → chunk-2VSN3MFX.ts} +71 -63
  12. package/dist/chunks/{chunk-6FVVRTL5.ts.map → chunk-2VSN3MFX.ts.map} +1 -1
  13. package/dist/chunks/{chunk-PG7NMFP2.ts → chunk-4RLATUP4.ts} +7 -7
  14. package/dist/chunks/chunk-5SFMBY5P.ts +26 -0
  15. package/dist/chunks/chunk-5SFMBY5P.ts.map +7 -0
  16. package/dist/chunks/chunk-5WJQ6XOW.ts +27 -0
  17. package/dist/chunks/chunk-5WJQ6XOW.ts.map +7 -0
  18. package/dist/chunks/{chunk-GNH73BJ5.ts → chunk-66GAUVDL.ts} +7 -7
  19. package/dist/chunks/{chunk-UPNVIUBN.ts → chunk-73MDIVYJ.ts} +3 -3
  20. package/dist/chunks/{chunk-CRKTAPSL.ts → chunk-AAPAHANE.ts} +24 -29
  21. package/dist/chunks/chunk-AAPAHANE.ts.map +7 -0
  22. package/dist/chunks/{chunk-S7QS4AWK.ts → chunk-AO6EDUA6.ts} +5 -5
  23. package/dist/chunks/chunk-AR2DGDUI.ts +55 -0
  24. package/dist/chunks/chunk-AR2DGDUI.ts.map +7 -0
  25. package/dist/chunks/{chunk-JCH3VXIO.ts → chunk-BJXSCGQK.ts} +9 -9
  26. package/dist/chunks/{chunk-IWZH5KYS.ts → chunk-CDQGSZL3.ts} +7 -7
  27. package/dist/chunks/chunk-DFJGTVPX.ts +319 -0
  28. package/dist/chunks/chunk-DFJGTVPX.ts.map +7 -0
  29. package/dist/chunks/chunk-DO55XUNU.ts +104 -0
  30. package/dist/chunks/chunk-DO55XUNU.ts.map +7 -0
  31. package/dist/chunks/{chunk-ED3TYIVW.ts → chunk-DOJRPBQU.ts} +5 -5
  32. package/dist/chunks/{chunk-5QAE3G3K.ts → chunk-IMMMZUFC.ts} +6 -6
  33. package/dist/chunks/{chunk-B4QZBDBT.ts → chunk-JXWTEJS5.ts} +3 -3
  34. package/dist/chunks/{chunk-BDB4IDM3.ts → chunk-JY2RVOUL.ts} +8 -6
  35. package/dist/chunks/{chunk-BDB4IDM3.ts.map → chunk-JY2RVOUL.ts.map} +1 -1
  36. package/dist/chunks/{chunk-P7DD5PWZ.ts → chunk-M5IV3KL2.ts} +3 -3
  37. package/dist/chunks/{chunk-AAEEHR7H.ts → chunk-MDUORMCK.ts} +2 -2
  38. package/dist/chunks/{chunk-UBV24CG4.ts → chunk-MRIPZGPR.ts} +3 -3
  39. package/dist/chunks/{chunk-MKKF4IMY.ts → chunk-ODF2M4RF.ts} +5 -5
  40. package/dist/chunks/chunk-PHANBTVM.ts +348 -0
  41. package/dist/chunks/chunk-PHANBTVM.ts.map +7 -0
  42. package/dist/chunks/{chunk-GP5DU62N.ts → chunk-PWA3YN5Z.ts} +2 -2
  43. package/dist/chunks/{chunk-YK52VDXG.ts → chunk-QWV3XKNJ.ts} +10 -8
  44. package/dist/chunks/{chunk-YK52VDXG.ts.map → chunk-QWV3XKNJ.ts.map} +1 -1
  45. package/dist/chunks/{chunk-ORGBI36T.ts → chunk-RAMHGOX2.ts} +4 -4
  46. package/dist/chunks/{chunk-QO333NM4.ts → chunk-RX3WGWVL.ts} +5 -5
  47. package/dist/chunks/chunk-RX3WGWVL.ts.map +7 -0
  48. package/dist/chunks/{chunk-PQW6GS4J.ts → chunk-STVQQ5KG.ts} +12 -10
  49. package/dist/chunks/{chunk-PQW6GS4J.ts.map → chunk-STVQQ5KG.ts.map} +1 -1
  50. package/dist/chunks/{chunk-76NB4R7U.ts → chunk-TO2GMX3K.ts} +2 -2
  51. package/dist/chunks/{chunk-GSNPASKB.ts → chunk-U77DWNRH.ts} +6 -6
  52. package/dist/chunks/{chunk-U3XRI2HF.ts → chunk-UCD7TQDT.ts} +11 -11
  53. package/dist/chunks/{chunk-A6HU4ERM.ts → chunk-UGSSZWQ6.ts} +6 -23
  54. package/dist/chunks/chunk-UGSSZWQ6.ts.map +7 -0
  55. package/dist/chunks/chunk-X7R6DCVF.ts +28 -0
  56. package/dist/chunks/chunk-X7R6DCVF.ts.map +7 -0
  57. package/dist/chunks/{chunk-HUZ5CR4W.ts → chunk-YZ5BQNRZ.ts} +2 -51
  58. package/dist/chunks/{chunk-HUZ5CR4W.ts.map → chunk-YZ5BQNRZ.ts.map} +4 -4
  59. package/dist/chunks/{chunk-UOHR7LRO.ts → chunk-Z5O2TLNF.ts} +9 -21
  60. package/dist/chunks/chunk-Z5O2TLNF.ts.map +7 -0
  61. package/dist/chunks/command-handler-FO6F2APH.ts +543 -0
  62. package/dist/chunks/command-handler-FO6F2APH.ts.map +7 -0
  63. package/dist/chunks/{config-KGIYTTXQ.ts → config-B37W7FXW.ts} +5 -6
  64. package/dist/chunks/{conflict-artifacts-FXFIIBCB.ts → conflict-artifacts-6XGSSU5S.ts} +13 -9
  65. package/dist/chunks/{conflict-review-3X37QEIT.ts → conflict-review-BQSHSJB3.ts} +31 -25
  66. package/dist/chunks/{conflict-review-3X37QEIT.ts.map → conflict-review-BQSHSJB3.ts.map} +1 -1
  67. package/dist/chunks/{continuous-record-SQJ47CXN.ts → continuous-record-4DQ2EAZS.ts} +8 -7
  68. package/dist/chunks/{continuous-sync-Q6QUD6TY.ts → continuous-sync-ZT3UEQLK.ts} +33 -28
  69. package/dist/chunks/{continuous-sync-Q6QUD6TY.ts.map → continuous-sync-ZT3UEQLK.ts.map} +1 -1
  70. package/dist/chunks/{file-selection-3JJYOVNR.ts → file-selection-FBLKM25V.ts} +12 -10
  71. package/dist/chunks/{file-selection-3JJYOVNR.ts.map → file-selection-FBLKM25V.ts.map} +1 -1
  72. package/dist/chunks/{git-backend-NYKSG5X6.ts → git-backend-7PCWECRN.ts} +16 -12
  73. package/dist/chunks/{git-backend-NYKSG5X6.ts.map → git-backend-7PCWECRN.ts.map} +1 -1
  74. package/dist/chunks/{local-fields-6DGYOOIK.ts → local-fields-B6JWLPAE.ts} +10 -5
  75. package/dist/chunks/manager-result-dispatcher-NODX3KKH.ts +28 -0
  76. package/dist/chunks/{manager-ui-ZH6DEC2G.ts → manager-ui-DGRTG76I.ts} +46 -40
  77. package/dist/chunks/{manager-ui-ZH6DEC2G.ts.map → manager-ui-DGRTG76I.ts.map} +1 -1
  78. package/dist/chunks/{merge-baseline-store-RFCAH7KL.ts → merge-baseline-store-HL3VLMAM.ts} +6 -5
  79. package/dist/chunks/{remote-selection-ui-YFPGYGNE.ts → remote-selection-ui-OHMIQ32X.ts} +14 -10
  80. package/dist/chunks/{s3-backend-F7PR5FB3.ts → s3-backend-CJXBEWWU.ts} +21 -17
  81. package/dist/chunks/{s3-backend-F7PR5FB3.ts.map → s3-backend-CJXBEWWU.ts.map} +1 -1
  82. package/dist/chunks/{setup-switch-E7PHKI6J.ts → setup-switch-66GWMBNH.ts} +6 -7
  83. package/dist/chunks/{setup-wizard-OVHZYXNW.ts → setup-wizard-OHZXJVQZ.ts} +8 -9
  84. package/dist/chunks/{setup-wizard-OVHZYXNW.ts.map → setup-wizard-OHZXJVQZ.ts.map} +1 -1
  85. package/dist/chunks/{snapshot-THS5EY2L.ts → snapshot-VRHNAUUH.ts} +11 -6
  86. package/dist/chunks/snapshot-transaction-EUGA4VX6.ts +24 -0
  87. package/dist/chunks/sync-inspection-4WFQEJOE.ts +25 -0
  88. package/dist/chunks/sync-inspection-4WFQEJOE.ts.map +7 -0
  89. package/dist/chunks/{sync-operations-Y72GNIQ2.ts → sync-operations-X4AOXMBT.ts} +66 -57
  90. package/dist/chunks/{sync-operations-Y72GNIQ2.ts.map → sync-operations-X4AOXMBT.ts.map} +1 -1
  91. package/dist/chunks/{sync-state-CFL4RRRB.ts → sync-state-SWLSMK4G.ts} +9 -5
  92. package/dist/chunks/sync-state-SWLSMK4G.ts.map +7 -0
  93. package/dist/chunks/{webdav-backend-TGFUH3SF.ts → webdav-backend-2Q5ZEBST.ts} +16 -12
  94. package/dist/chunks/{webdav-backend-TGFUH3SF.ts.map → webdav-backend-2Q5ZEBST.ts.map} +1 -1
  95. package/dist/index.ts +54 -537
  96. package/dist/index.ts.map +3 -3
  97. package/package.json +2 -2
  98. package/src/settings/config.ts +1 -1
  99. package/src/settings/settings-validation.ts +1 -1
  100. package/src/snapshot/snapshot-transaction-directory.ts +16 -0
  101. package/src/snapshot/snapshot-transaction.ts +1 -12
  102. package/src/sync/automatic-sync.ts +12 -6
  103. package/src/sync/local-field-policy.ts +29 -0
  104. package/src/sync/local-fields.ts +3 -29
  105. package/src/sync/mutation-owner.ts +22 -0
  106. package/src/sync/startup-check.ts +3 -2
  107. package/src/sync/sync-loaders.ts +4 -0
  108. package/src/sync/sync-local.ts +2 -19
  109. package/src/sync-extension.ts +7 -2
  110. package/dist/chunks/chunk-A6HU4ERM.ts.map +0 -7
  111. package/dist/chunks/chunk-CRKTAPSL.ts.map +0 -7
  112. package/dist/chunks/chunk-QO333NM4.ts.map +0 -7
  113. package/dist/chunks/chunk-QOFMXPM5.ts +0 -735
  114. package/dist/chunks/chunk-QOFMXPM5.ts.map +0 -7
  115. package/dist/chunks/chunk-UOHR7LRO.ts.map +0 -7
  116. package/dist/chunks/manager-result-dispatcher-HOCM2GDA.ts +0 -24
  117. package/dist/chunks/sync-inspection-J25EEKZK.ts +0 -21
  118. /package/dist/chunks/{agent-candidate-GNEYR225.ts.map → agent-candidate-EYB35AGL.ts.map} +0 -0
  119. /package/dist/chunks/{config-KGIYTTXQ.ts.map → agent-sync-VM3TXWA3.ts.map} +0 -0
  120. /package/dist/chunks/{chunk-PG7NMFP2.ts.map → chunk-4RLATUP4.ts.map} +0 -0
  121. /package/dist/chunks/{chunk-GNH73BJ5.ts.map → chunk-66GAUVDL.ts.map} +0 -0
  122. /package/dist/chunks/{chunk-UPNVIUBN.ts.map → chunk-73MDIVYJ.ts.map} +0 -0
  123. /package/dist/chunks/{chunk-S7QS4AWK.ts.map → chunk-AO6EDUA6.ts.map} +0 -0
  124. /package/dist/chunks/{chunk-JCH3VXIO.ts.map → chunk-BJXSCGQK.ts.map} +0 -0
  125. /package/dist/chunks/{chunk-IWZH5KYS.ts.map → chunk-CDQGSZL3.ts.map} +0 -0
  126. /package/dist/chunks/{chunk-ED3TYIVW.ts.map → chunk-DOJRPBQU.ts.map} +0 -0
  127. /package/dist/chunks/{chunk-5QAE3G3K.ts.map → chunk-IMMMZUFC.ts.map} +0 -0
  128. /package/dist/chunks/{chunk-B4QZBDBT.ts.map → chunk-JXWTEJS5.ts.map} +0 -0
  129. /package/dist/chunks/{chunk-P7DD5PWZ.ts.map → chunk-M5IV3KL2.ts.map} +0 -0
  130. /package/dist/chunks/{chunk-AAEEHR7H.ts.map → chunk-MDUORMCK.ts.map} +0 -0
  131. /package/dist/chunks/{chunk-UBV24CG4.ts.map → chunk-MRIPZGPR.ts.map} +0 -0
  132. /package/dist/chunks/{chunk-MKKF4IMY.ts.map → chunk-ODF2M4RF.ts.map} +0 -0
  133. /package/dist/chunks/{chunk-GP5DU62N.ts.map → chunk-PWA3YN5Z.ts.map} +0 -0
  134. /package/dist/chunks/{chunk-ORGBI36T.ts.map → chunk-RAMHGOX2.ts.map} +0 -0
  135. /package/dist/chunks/{chunk-76NB4R7U.ts.map → chunk-TO2GMX3K.ts.map} +0 -0
  136. /package/dist/chunks/{chunk-GSNPASKB.ts.map → chunk-U77DWNRH.ts.map} +0 -0
  137. /package/dist/chunks/{chunk-U3XRI2HF.ts.map → chunk-UCD7TQDT.ts.map} +0 -0
  138. /package/dist/chunks/{conflict-artifacts-FXFIIBCB.ts.map → config-B37W7FXW.ts.map} +0 -0
  139. /package/dist/chunks/{continuous-record-SQJ47CXN.ts.map → conflict-artifacts-6XGSSU5S.ts.map} +0 -0
  140. /package/dist/chunks/{local-fields-6DGYOOIK.ts.map → continuous-record-4DQ2EAZS.ts.map} +0 -0
  141. /package/dist/chunks/{manager-result-dispatcher-HOCM2GDA.ts.map → local-fields-B6JWLPAE.ts.map} +0 -0
  142. /package/dist/chunks/{merge-baseline-store-RFCAH7KL.ts.map → manager-result-dispatcher-NODX3KKH.ts.map} +0 -0
  143. /package/dist/chunks/{remote-selection-ui-YFPGYGNE.ts.map → merge-baseline-store-HL3VLMAM.ts.map} +0 -0
  144. /package/dist/chunks/{setup-switch-E7PHKI6J.ts.map → remote-selection-ui-OHMIQ32X.ts.map} +0 -0
  145. /package/dist/chunks/{snapshot-THS5EY2L.ts.map → setup-switch-66GWMBNH.ts.map} +0 -0
  146. /package/dist/chunks/{sync-inspection-J25EEKZK.ts.map → snapshot-VRHNAUUH.ts.map} +0 -0
  147. /package/dist/chunks/{sync-state-CFL4RRRB.ts.map → snapshot-transaction-EUGA4VX6.ts.map} +0 -0
package/dist/index.ts CHANGED
@@ -1,566 +1,69 @@
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
3
  import {
4
- withAgentSyncLock
5
- } from "./chunks/chunk-MKKF4IMY.ts";
6
- import "./chunks/chunk-3ST7RSYN.ts";
7
- import {
8
- recoverSnapshotTransactionsOnStartup
9
- } from "./chunks/chunk-CRKTAPSL.ts";
4
+ createSyncAttentionController
5
+ } from "./chunks/chunk-U77DWNRH.ts";
10
6
  import {
11
7
  createStartupTimings
12
8
  } from "./chunks/chunk-M6VQJIOU.ts";
13
- import {
14
- createSyncAttentionController,
15
- observationMatchesConfig,
16
- syncAttentionMatchesConfig
17
- } from "./chunks/chunk-GSNPASKB.ts";
18
- import {
19
- automaticSyncSummary
20
- } from "./chunks/chunk-ECYCNZOE.ts";
21
- import {
22
- configureSyncStatus,
23
- setSyncStatus
24
- } from "./chunks/chunk-K3RIEL6J.ts";
25
9
  import {
26
10
  completeSyncArguments,
27
- parseOptions,
28
- resolveSyncCommand,
29
11
  setSyncSetupCompletions,
30
- splitArgs,
31
- startupTransferSummary,
32
- usage,
33
- validateCommandOptions
12
+ splitArgs
34
13
  } from "./chunks/chunk-NLWS55B6.ts";
35
14
  import {
36
15
  captureMutationOwner
37
- } from "./chunks/chunk-UOHR7LRO.ts";
16
+ } from "./chunks/chunk-5WJQ6XOW.ts";
38
17
  import {
39
18
  safeTerminalText
40
19
  } from "./chunks/chunk-AMJRUXFT.ts";
41
- import "./chunks/chunk-UBV24CG4.ts";
42
20
  import {
43
- syncErrorGuidance
44
- } from "./chunks/chunk-G4RUXRWZ.ts";
21
+ configureSyncStatus,
22
+ setSyncStatus
23
+ } from "./chunks/chunk-K3RIEL6J.ts";
45
24
  import {
46
- SetupPullRequiresUiError,
47
- errorMessage,
48
- isSyncDecisionRequiredError
25
+ errorMessage
49
26
  } from "./chunks/chunk-7D5SF7P3.ts";
50
27
  import {
51
- activeLocalConfigPath,
52
28
  consumeLocalConfigMigrationNotice,
53
- createLocalConfigDocument,
54
29
  loadConfig,
55
30
  loadConfigForCheck,
56
31
  loadPartialConfig,
57
- localConfigPath,
58
- localConfigTemplate,
59
32
  readLocalConfigObject,
60
- sessionTokenWarnings,
61
- syncCheckConfigFingerprint,
62
- syncSessionsWarnings
63
- } from "./chunks/chunk-QO333NM4.ts";
64
- import "./chunks/chunk-A6HU4ERM.ts";
33
+ syncCheckConfigFingerprint
34
+ } from "./chunks/chunk-RX3WGWVL.ts";
35
+ import "./chunks/chunk-X7R6DCVF.ts";
36
+ import {
37
+ pendingTransactionEntries
38
+ } from "./chunks/chunk-5SFMBY5P.ts";
65
39
  import {
66
- unlock,
67
40
  withLock
68
- } from "./chunks/chunk-AAEEHR7H.ts";
69
- import "./chunks/chunk-DT7M4VQS.ts";
70
- import "./chunks/chunk-YDVQYUHE.ts";
41
+ } from "./chunks/chunk-MDUORMCK.ts";
71
42
  import {
72
43
  combineSignals,
73
44
  throwIfAborted
74
45
  } from "./chunks/chunk-PWMWOJP4.ts";
75
- import {
76
- RemoteSelectionMismatchError,
77
- formatRemoteSelectionMismatch,
78
- sessionDirFromContext,
79
- snapshotOptionsForContext
80
- } from "./chunks/chunk-QOFMXPM5.ts";
81
- import "./chunks/chunk-76NB4R7U.ts";
82
- import "./chunks/chunk-ZW5ZLGBI.ts";
83
- import {
84
- startupTransferEnabled
85
- } from "./chunks/chunk-PRUEIIK7.ts";
86
46
  import {
87
47
  ensureStateDir,
88
48
  readStateForConfig,
89
49
  syncStateFingerprint
90
- } from "./chunks/chunk-UPNVIUBN.ts";
50
+ } from "./chunks/chunk-73MDIVYJ.ts";
91
51
  import {
92
- migrateLegacyStateDirectory,
93
52
  stateDirectoryMigrationNotice,
94
53
  withStateDirectoryAccess
95
54
  } from "./chunks/chunk-SWRVXVFD.ts";
96
55
  import "./chunks/chunk-2JZFHNLM.ts";
97
56
  import "./chunks/chunk-T2SJD3N7.ts";
98
- import "./chunks/chunk-HUZ5CR4W.ts";
99
-
100
- // src/ui/operation-dialogs.ts
101
- function trackOperationDialogs(ctx, onDialog) {
102
- if (!onDialog) return ctx;
103
- const runDialog = async (task) => {
104
- onDialog(true);
105
- try {
106
- return await task();
107
- } finally {
108
- onDialog(false);
109
- }
110
- };
111
- const ui = {
112
- ...ctx.ui,
113
- select: (...args) => runDialog(() => ctx.ui.select(...args)),
114
- confirm: (...args) => runDialog(() => ctx.ui.confirm(...args))
115
- };
116
- return new Proxy(ctx, {
117
- get(target, key, receiver) {
118
- return key === "ui" ? ui : Reflect.get(target, key, receiver);
119
- }
120
- });
121
- }
122
-
123
- // src/commands/command-execution.ts
124
- async function executeRecoveryCommand(rawArgs, ctx, signal, loaders, onCommit, setup) {
125
- try {
126
- const [subcommand, ...rest] = splitArgs(rawArgs);
127
- if (subcommand !== "sync" && subcommand !== "pull" && subcommand !== "push") {
128
- throw new Error(`Unsupported sync recovery route: ${subcommand ?? "missing"}`);
129
- }
130
- const options = parseOptions(rest);
131
- if (setup !== void 0) options.setup = setup;
132
- if (signal) options.signal = signal;
133
- if (onCommit) options.onCommit = onCommit;
134
- options.reload = false;
135
- options.auto = false;
136
- validateCommandOptions(subcommand, options);
137
- const operations = await loaders.operations();
138
- throwIfAborted(options.signal);
139
- if (subcommand === "push") {
140
- const outcome = await withLock("push", () => operations.push(ctx, options));
141
- return { kind: "completed", ...outcome ? { outcome } : {} };
142
- }
143
- if (subcommand === "pull") {
144
- const outcome = await withLock("pull", () => operations.pull(ctx, options));
145
- return { kind: "completed", ...outcome ? { outcome } : {} };
146
- }
147
- await withAgentSyncLock(ctx, options, (current) => operations.syncBoth(ctx, current));
148
- return { kind: "completed" };
149
- } catch (error) {
150
- if (signal?.aborted) return { kind: "failed" };
151
- setSyncStatus(ctx, void 0);
152
- if (error instanceof RemoteSelectionMismatchError) {
153
- return { kind: "remote-selection-required", decision: error.decision };
154
- }
155
- if (isSyncDecisionRequiredError(error)) {
156
- return { kind: "decision-required", decision: error.decision };
157
- }
158
- ctx.ui.notify(syncErrorGuidance(error), "error");
159
- return { kind: "failed" };
160
- }
161
- }
162
- async function executeCommand(rawArgs, ctx, signal, loaders, onCommit, setup, onDialog, retryRefusal = false) {
163
- ctx = trackOperationDialogs(ctx, onDialog);
164
- try {
165
- const command = await resolveSyncCommand(rawArgs, ctx);
166
- if (signal?.aborted || !command) return { kind: "completed" };
167
- const { subcommand, rest } = command;
168
- const options = parseOptions(rest);
169
- if (setup !== void 0) options.setup = setup;
170
- if (signal) options.signal = signal;
171
- if (onCommit) options.onCommit = onCommit;
172
- validateCommandOptions(subcommand, options);
173
- if (retryRefusal) {
174
- if (subcommand !== "sync") throw new Error("A refused-model retry is available only for merged sync.");
175
- options.agentRetryRefusal = true;
176
- }
177
- switch (subcommand) {
178
- case "help":
179
- ctx.ui.notify(usage(), "info");
180
- return { kind: "completed" };
181
- case "use": {
182
- const { useSyncSetup } = await loaders.setupSwitch();
183
- throwIfAborted(options.signal);
184
- await useSyncSetup(
185
- ctx,
186
- options.args[0] ?? "",
187
- async (selectedSetup) => {
188
- const operations = await loaders.operations();
189
- throwIfAborted(options.signal);
190
- return withLock("pull", () => operations.pull(ctx, { ...options, setup: selectedSetup }));
191
- },
192
- void 0,
193
- options.signal
194
- );
195
- return { kind: "completed" };
196
- }
197
- case "init":
198
- await initConfig(ctx, signal);
199
- return { kind: "completed" };
200
- case "config":
201
- await showConfig(ctx, options);
202
- return { kind: "completed" };
203
- case "files": {
204
- const { showFileSelection } = await import("./chunks/file-selection-3JJYOVNR.ts");
205
- throwIfAborted(options.signal);
206
- await showFileSelection(ctx, options.setup, options.signal);
207
- return { kind: "completed" };
208
- }
209
- case "status": {
210
- const operations = await loaders.operations();
211
- throwIfAborted(options.signal);
212
- await operations.status(ctx, options);
213
- return { kind: "completed" };
214
- }
215
- case "diff": {
216
- const operations = await loaders.operations();
217
- throwIfAborted(options.signal);
218
- await operations.diff(ctx, options);
219
- return { kind: "completed" };
220
- }
221
- case "conflicts": {
222
- const { showConflicts } = await import("./chunks/conflict-review-3X37QEIT.ts");
223
- throwIfAborted(options.signal);
224
- await withLock("sync", () => showConflicts(ctx, options));
225
- return { kind: "completed" };
226
- }
227
- case "doctor": {
228
- const operations = await loaders.operations();
229
- throwIfAborted(options.signal);
230
- await operations.doctor(ctx, options);
231
- return { kind: "completed" };
232
- }
233
- case "push": {
234
- const operations = await loaders.operations();
235
- throwIfAborted(options.signal);
236
- const outcome = await withLock("push", () => operations.push(ctx, options));
237
- return { kind: "completed", ...outcome ? { outcome } : {} };
238
- }
239
- case "pull": {
240
- const operations = await loaders.operations();
241
- throwIfAborted(options.signal);
242
- const outcome = await withLock("pull", () => operations.pull(ctx, options));
243
- return { kind: "completed", ...outcome ? { outcome } : {} };
244
- }
245
- case "sync": {
246
- const operations = await loaders.operations();
247
- throwIfAborted(options.signal);
248
- const outcome = await withAgentSyncLock(ctx, options, (current) => operations.syncBoth(ctx, current));
249
- return { kind: "completed", ...retryRefusal && outcome ? { outcome } : {} };
250
- }
251
- case "history": {
252
- const operations = await loaders.operations();
253
- throwIfAborted(options.signal);
254
- await operations.history(ctx, options);
255
- return { kind: "completed" };
256
- }
257
- case "rollback": {
258
- const operations = await loaders.operations();
259
- throwIfAborted(options.signal);
260
- await withLock("rollback", () => operations.rollback(ctx, options));
261
- return { kind: "completed" };
262
- }
263
- case "migrate-state":
264
- await migrateStateDirectory(ctx, options);
265
- return { kind: "completed" };
266
- case "unlock":
267
- await unlock(ctx, options);
268
- return { kind: "completed" };
269
- default:
270
- ctx.ui.notify(`Unknown /sync command: ${subcommand}
271
-
272
- ${usage()}`, "warning");
273
- return { kind: "failed" };
274
- }
275
- } catch (error) {
276
- if (signal?.aborted) return { kind: "failed" };
277
- setSyncStatus(ctx, void 0);
278
- if (error instanceof SetupPullRequiresUiError) throw error;
279
- if (error instanceof RemoteSelectionMismatchError) {
280
- return { kind: "remote-selection-required", decision: error.decision };
281
- }
282
- if (isSyncDecisionRequiredError(error)) {
283
- return { kind: "decision-required", decision: error.decision };
284
- }
285
- ctx.ui.notify(syncErrorGuidance(error), "error");
286
- return { kind: "failed" };
287
- }
288
- }
289
- async function migrateStateDirectory(ctx, options) {
290
- const notice = stateDirectoryMigrationNotice();
291
- if (!notice) {
292
- ctx.ui.notify("pi-sync already uses the canonical pi-sync/ state directory.", "info");
293
- return;
294
- }
295
- if (!options.yes && !await ctx.ui.confirm(
296
- "Migrate pi-sync state directory",
297
- "Confirm that every other Pi process is closed. pi-sync will atomically rename .pisync/ to pi-sync/ without merging or deleting either root.",
298
- { signal: options.signal }
299
- )) {
300
- ctx.ui.notify("pi-sync state migration cancelled.", "info");
301
- return;
302
- }
303
- throwIfAborted(options.signal);
304
- const result = await migrateLegacyStateDirectory();
305
- throwIfAborted(options.signal);
306
- if (result.status === "ready") {
307
- ctx.ui.notify("pi-sync already uses the canonical pi-sync/ state directory.", "info");
308
- return;
309
- }
310
- ctx.ui.notify(result.message, result.status === "migrated" ? "info" : "warning");
311
- }
312
- async function initConfig(ctx, signal) {
313
- const configPath = localConfigPath();
314
- if (await readLocalConfigObject()) {
315
- ctx.ui.notify(`Config already exists: ${await activeLocalConfigPath()}`, "info");
316
- return;
317
- }
318
- if (ctx.mode === "tui") {
319
- const { showSetupWizard } = await import("./chunks/setup-wizard-OVHZYXNW.ts");
320
- throwIfAborted(signal);
321
- await showSetupWizard(ctx, signal);
322
- return;
323
- }
324
- await createLocalConfigDocument(localConfigTemplate());
325
- ctx.ui.notify(`Created ${configPath}. Add a storage connection and sync setup before syncing.`, "info");
326
- }
327
- async function showConfig(ctx, options) {
328
- const config = await loadConfig(options.setup);
329
- const warnings = [
330
- ...config.backend.type === "s3" ? sessionTokenWarnings(config.backend.profile) : [],
331
- ...syncSessionsWarnings(config)
332
- ];
333
- const storageLines = configStorageLines(config);
334
- ctx.ui.notify(
335
- [
336
- "pi-sync config:",
337
- `sync setup: ${config.setupName}`,
338
- `storage connection: ${config.connectionName}`,
339
- ...storageLines,
340
- `storage path: ${config.storagePath}`,
341
- `automatic sync: ${automaticSyncSummary(config.automatic)}`,
342
- `settings field merge: ${config.mergeSettings ? "On (experimental)" : "Off"}`,
343
- `machine-local settings.json fields: ${(config.localFields ?? []).map(safeTerminalText).join(", ") || "none"}`,
344
- `startup transfer: ${startupTransferSummary(config)}`,
345
- `agent mode: ${config.agentMode ? "On (experimental)" : "Off"}`,
346
- `continuous sync: ${config.continuous ? config.agentMode ? "On (experimental)" : "paused; Agent mode is Off" : "Off"}`,
347
- `included content: ${config.include.join(", ") || "none"}`,
348
- `sessions: ${config.include.includes("sessions") ? "included" : "not included"}`,
349
- `settings file: ${localConfigPath()}`,
350
- ...warnings
351
- ].join("\n"),
352
- warnings.length > 0 ? "warning" : "info"
353
- );
354
- }
355
- function configStorageLines(config) {
356
- switch (config.backend.type) {
357
- case "git":
358
- return [
359
- "kind: git",
360
- `remote: ${displayGitRemote(config.backend.profile.remote)}`,
361
- "authentication: existing Git/SSH credentials (not stored)",
362
- `branch: ${config.backend.destination.branch}`
363
- ];
364
- case "webdav":
365
- return [
366
- "kind: webdav",
367
- `url: ${displayWebDavUrl(config.backend.profile.url, config.backend.profile.username)}`,
368
- "username: configured (value hidden)",
369
- "password: configured"
370
- ];
371
- case "s3":
372
- return [
373
- "kind: s3",
374
- `endpoint: ${config.backend.profile.endpoint}`,
375
- `bucket: ${config.backend.destination.bucket}`,
376
- `region: ${config.backend.profile.region}`,
377
- "access key id: configured",
378
- "secret access key: configured",
379
- `session token: ${config.backend.profile.sessionToken ? "configured" : "not configured"}`
380
- ];
381
- }
382
- }
383
- function displayGitRemote(value) {
384
- if (!value) return "missing";
385
- try {
386
- const url = new URL(value);
387
- url.username = "";
388
- url.password = "";
389
- url.search = "";
390
- url.hash = "";
391
- return url.toString();
392
- } catch {
393
- return value.replace(/^(?:[^@\s]+@)?(?<host>[^:]+):.+$/u, "$<host>:\u2026");
394
- }
395
- }
396
- function displayWebDavUrl(value, username) {
397
- if (!value) return "missing";
398
- try {
399
- const url = new URL(value);
400
- url.username = "";
401
- url.password = "";
402
- url.search = "";
403
- url.hash = "";
404
- return username ? `${url.origin}/\u2026` : `${url.origin}${url.pathname}`;
405
- } catch {
406
- return "invalid (value hidden)";
407
- }
408
- }
409
-
410
- // src/commands/command-handler.ts
411
- async function handleCommand(rawArgs, ctx, sessionSignal, loaders, attention, onExplicitSync) {
412
- await reconcileObservation(attention, sessionSignal);
413
- if (sessionSignal.aborted) return;
414
- const run = (route, signal, onCommit, target, onDialog, retryRefusal = false) => {
415
- const [command, ...args] = splitArgs(route);
416
- if (command === "sync" && !retryRefusal) {
417
- try {
418
- const options = parseOptions(args);
419
- validateCommandOptions("sync", options);
420
- onExplicitSync?.(target ?? options.setup);
421
- } catch {
422
- }
423
- }
424
- return executeCommand(
425
- route,
426
- ctx,
427
- combineSignals(sessionSignal, signal),
428
- loaders,
429
- observationCommitCallback(attention, sessionSignal, onCommit),
430
- target,
431
- onDialog,
432
- retryRefusal
433
- );
434
- };
435
- if (!rawArgs.trim()) {
436
- try {
437
- const { showSyncManager } = await import("./chunks/manager-ui-ZH6DEC2G.ts");
438
- if (sessionSignal.aborted) return;
439
- await showSyncManager(ctx, run, sessionSignal, {
440
- getAttention: () => attention.current(),
441
- getObservation: () => attention.observation(),
442
- onObservationInvalidated: () => attention.clearObservation(),
443
- onSelectionResolved: (expected) => {
444
- if (attention.current() === expected) attention.clear(ctx);
445
- }
446
- });
447
- } catch (error) {
448
- if (sessionSignal.aborted) return;
449
- setSyncStatus(ctx, void 0);
450
- ctx.ui.notify(errorMessage(error), "error");
451
- }
452
- await reconcileObservation(attention, sessionSignal);
453
- if (!sessionSignal.aborted) await attention.publish(ctx, sessionSignal);
454
- return;
455
- }
456
- const result = await run(rawArgs);
457
- if (result.kind === "decision-required") {
458
- ctx.ui.notify(result.decision.directMessage, "error");
459
- } else if (result.kind === "remote-selection-required") {
460
- const origin = directSelectionOrigin(rawArgs);
461
- if (origin) attention.set(result.decision, origin);
462
- const deterministic = splitArgs(rawArgs).some((arg) => arg === "--yes" || arg === "-y");
463
- if (origin && ctx.mode === "tui" && !deterministic) {
464
- await resolveSelectionAttention(ctx, attention, sessionSignal, loaders);
465
- } else {
466
- ctx.ui.notify(
467
- formatRemoteSelectionMismatch(
468
- result.decision.setupName,
469
- result.decision.localInclude,
470
- result.decision.remoteInclude
471
- ),
472
- "error"
473
- );
474
- }
475
- }
476
- await clearAttentionAfterCompletedOperation(rawArgs, result, ctx, attention, sessionSignal);
477
- await reconcileSelectionAttention(ctx, attention, sessionSignal);
478
- await reconcileObservation(attention, sessionSignal);
479
- if (!sessionSignal.aborted) await attention.publish(ctx, sessionSignal);
480
- }
481
- function observationCommitCallback(attention, sessionSignal, onCommit) {
482
- const observed = attention.observation();
483
- return () => {
484
- if (!sessionSignal.aborted && attention.observation() === observed) attention.clearObservation();
485
- onCommit?.();
486
- };
487
- }
488
- async function reconcileObservation(attention, signal) {
489
- const observed = attention.observation();
490
- if (!observed || signal.aborted) return;
491
- try {
492
- const config = await loadConfig();
493
- if (signal.aborted || attention.observation() !== observed) return;
494
- if (!observationMatchesConfig(observed, config)) {
495
- attention.clearObservation();
496
- return;
497
- }
498
- const state = await readStateForConfig(config);
499
- if (signal.aborted || attention.observation() !== observed) return;
500
- if (syncStateFingerprint(state) !== observed.inspection.stateIdentity) attention.clearObservation();
501
- } catch {
502
- if (!signal.aborted && attention.observation() === observed) attention.clearObservation();
503
- }
504
- }
505
- async function clearAttentionAfterCompletedOperation(rawArgs, result, ctx, attention, signal) {
506
- if (result.kind !== "completed" || result.outcome === "cancelled" || signal.aborted) return;
507
- const [command, ...rest] = splitArgs(rawArgs);
508
- if (command !== "sync" && command !== "pull" && command !== "push") return;
509
- const current = attention.current();
510
- if (!current) return;
511
- try {
512
- const options = parseOptions(rest);
513
- const setupName = options.setup ?? (await loadConfig()).setupName;
514
- if (signal.aborted || attention.current() !== current) return;
515
- if (current.decision.setupName === setupName) attention.clear(ctx);
516
- } catch {
517
- }
518
- }
519
- async function reconcileSelectionAttention(ctx, attention, signal) {
520
- const current = attention.current();
521
- if (!current || signal.aborted) return;
522
- try {
523
- const config = await loadConfig(current.decision.setupName);
524
- if (signal.aborted || attention.current() !== current) return;
525
- if (!syncAttentionMatchesConfig(current, config)) attention.clear(ctx);
526
- } catch {
527
- if (!signal.aborted && attention.current() === current) attention.clear(ctx);
528
- }
529
- }
530
- function directSelectionOrigin(rawArgs) {
531
- const command = splitArgs(rawArgs)[0];
532
- return command === "sync" || command === "pull" || command === "push" ? command : void 0;
533
- }
534
- async function resolveSelectionAttention(ctx, attention, signal, loaders, options = {}) {
535
- const current = attention.current();
536
- if (!current || signal.aborted) return;
537
- const { dispatchManagerResult } = await import("./chunks/manager-result-dispatcher-HOCM2GDA.ts");
538
- if (signal.aborted || attention.current() !== current) return;
539
- await dispatchManagerResult(
540
- ctx,
541
- { kind: "remote-selection-required", decision: current.decision },
542
- current.origin,
543
- (route, actionSignal, onCommit, target) => {
544
- const execute = () => executeRecoveryCommand(
545
- route,
546
- ctx,
547
- combineSignals(signal, actionSignal),
548
- loaders,
549
- observationCommitCallback(attention, signal, onCommit),
550
- target
551
- );
552
- return options.withStateAccess ? options.withStateAccess(execute) : execute();
553
- },
554
- signal,
555
- {
556
- cancelLabel: options.cancelLabel,
557
- withStateAccess: options.withStateAccess,
558
- onSelectionResolved: () => {
559
- if (attention.current() === current) attention.clear(ctx);
560
- }
561
- }
562
- );
563
- }
57
+ import "./chunks/chunk-DFJGTVPX.ts";
58
+ import {
59
+ sessionDirFromContext,
60
+ snapshotOptionsForContext
61
+ } from "./chunks/chunk-DO55XUNU.ts";
62
+ import "./chunks/chunk-AR2DGDUI.ts";
63
+ import "./chunks/chunk-YZ5BQNRZ.ts";
64
+ import {
65
+ startupTransferEnabled
66
+ } from "./chunks/chunk-PRUEIIK7.ts";
564
67
 
565
68
  // src/settings/config-errors.ts
566
69
  function isMissingConfigError(error) {
@@ -587,15 +90,19 @@ async function startSession(ctx, signal, publish) {
587
90
  if (stateNotice && ctx.hasUI) ctx.ui.notify(stateNotice, "warning");
588
91
  const validateMutation = captureMutationOwner(ctx, signal);
589
92
  const currentFile = ctx.sessionManager.getSessionFile?.();
590
- await timings.measure(
591
- "transaction recovery",
592
- () => recoverSnapshotTransactionsOnStartup({
93
+ await timings.measure("transaction recovery", async () => {
94
+ const pending = await pendingTransactionEntries();
95
+ validateMutation();
96
+ if (!pending.some((entry) => entry.isDirectory())) return;
97
+ const { recoverSnapshotTransactionsOnStartup } = await import("./chunks/snapshot-transaction-EUGA4VX6.ts");
98
+ validateMutation();
99
+ await recoverSnapshotTransactionsOnStartup({
593
100
  signal,
594
101
  sessionDir: sessionDirFromContext(ctx),
595
102
  protectedTargets: currentFile ? [currentFile] : [],
596
103
  validateMutation
597
- })
598
- );
104
+ });
105
+ });
599
106
  throwIfAborted(signal);
600
107
  try {
601
108
  const settings = await timings.measure("settings read", () => readLocalConfigObject());
@@ -749,7 +256,10 @@ function createStartupCheck(loaders, attention, timeoutMs = 3e4, publish) {
749
256
  automaticTransfer: startupTransferEnabled(captured)
750
257
  });
751
258
  if (startupTransferEnabled(captured) && !inspection.firstSync && inspection.head && inspection.selectionState?.kind === "same") {
752
- const operations = await timings.measure("operations import", () => loaders.operations());
259
+ const [operations, { withAgentSyncLock }] = await timings.measure(
260
+ "operations import",
261
+ () => Promise.all([loaders.operations(), import("./chunks/agent-sync-VM3TXWA3.ts")])
262
+ );
753
263
  throwIfAborted(signal);
754
264
  if (!isCurrent()) return;
755
265
  if (!ctx.isIdle()) {
@@ -847,11 +357,12 @@ function createStartupCheck(loaders, attention, timeoutMs = 3e4, publish) {
847
357
  // src/sync/sync-loaders.ts
848
358
  function createSyncLoaders(dependencies) {
849
359
  const loaders = {
850
- inspection: cachedModuleLoader(dependencies.loadSyncInspection ?? (() => import("./chunks/sync-inspection-J25EEKZK.ts"))),
851
- setupSwitch: cachedModuleLoader(dependencies.loadSetupSwitch ?? (() => import("./chunks/setup-switch-E7PHKI6J.ts"))),
852
- snapshot: cachedModuleLoader(dependencies.loadSnapshot ?? (() => import("./chunks/snapshot-THS5EY2L.ts"))),
853
- syncState: cachedModuleLoader(dependencies.loadSyncState ?? (() => import("./chunks/sync-state-CFL4RRRB.ts"))),
854
- operations: cachedModuleLoader(dependencies.loadSyncOperations ?? (() => import("./chunks/sync-operations-Y72GNIQ2.ts")))
360
+ commands: cachedModuleLoader(dependencies.loadCommandHandler ?? (() => import("./chunks/command-handler-FO6F2APH.ts"))),
361
+ inspection: cachedModuleLoader(dependencies.loadSyncInspection ?? (() => import("./chunks/sync-inspection-4WFQEJOE.ts"))),
362
+ setupSwitch: cachedModuleLoader(dependencies.loadSetupSwitch ?? (() => import("./chunks/setup-switch-66GWMBNH.ts"))),
363
+ snapshot: cachedModuleLoader(dependencies.loadSnapshot ?? (() => import("./chunks/snapshot-VRHNAUUH.ts"))),
364
+ syncState: cachedModuleLoader(dependencies.loadSyncState ?? (() => import("./chunks/sync-state-SWLSMK4G.ts"))),
365
+ operations: cachedModuleLoader(dependencies.loadSyncOperations ?? (() => import("./chunks/sync-operations-X4AOXMBT.ts")))
855
366
  };
856
367
  return loaders;
857
368
  }
@@ -909,7 +420,7 @@ function sync(pi, dependencies = {}) {
909
420
  const isCurrent = () => !signal.aborted && !foreground.has(ctx.sessionManager) && owner === ctx.sessionManager;
910
421
  if (!isCurrent() || !ctx.hasUI) return;
911
422
  try {
912
- const { loadConfigForCheck: loadConfigForCheck2 } = await import("./chunks/config-KGIYTTXQ.ts");
423
+ const { loadConfigForCheck: loadConfigForCheck2 } = await import("./chunks/config-B37W7FXW.ts");
913
424
  if (!isCurrent()) return;
914
425
  const config = await loadConfigForCheck2();
915
426
  if (!isCurrent()) return;
@@ -918,7 +429,7 @@ function sync(pi, dependencies = {}) {
918
429
  await continuous?.stop(ctx.sessionManager);
919
430
  return;
920
431
  }
921
- const { createContinuousSync } = await import("./chunks/continuous-sync-Q6QUD6TY.ts");
432
+ const { createContinuousSync } = await import("./chunks/continuous-sync-ZT3UEQLK.ts");
922
433
  if (!isCurrent()) return;
923
434
  continuous ??= createContinuousSync(loaders, void 0, publishTimings);
924
435
  continuous.start(
@@ -958,7 +469,13 @@ function sync(pi, dependencies = {}) {
958
469
  );
959
470
  return;
960
471
  }
961
- const run = () => handleCommand(args, ctx, signal, loaders, attention, (setup) => {
472
+ const commands = await loaders.commands().catch((error) => {
473
+ if (!signal.aborted) {
474
+ ctx.ui.notify(`pi-sync command unavailable: ${safeTerminalText(errorMessage(error))}`, "error");
475
+ }
476
+ });
477
+ if (signal.aborted || !commands) return;
478
+ const run = () => commands.handleCommand(args, ctx, signal, loaders, attention, (setup) => {
962
479
  retry = { setup };
963
480
  });
964
481
  if (command === "migrate-state" || command === "help") await run();