@narumitw/pi-sync 0.57.8 → 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 (151) hide show
  1. package/CHANGELOG.md +306 -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-AH7TXOQT.ts → agent-refusal-retry-C2HQROTP.ts} +12 -9
  7. package/dist/chunks/{agent-refusal-retry-AH7TXOQT.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-N5TFMPB5.ts → chunk-2VSN3MFX.ts} +71 -63
  12. package/dist/chunks/{chunk-N5TFMPB5.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-5XZOC7FD.ts → chunk-KHBPED6W.ts} +4 -1
  37. package/dist/chunks/chunk-KHBPED6W.ts.map +7 -0
  38. package/dist/chunks/{chunk-P7DD5PWZ.ts → chunk-M5IV3KL2.ts} +3 -3
  39. package/dist/chunks/{chunk-AAEEHR7H.ts → chunk-MDUORMCK.ts} +2 -2
  40. package/dist/chunks/{chunk-UBV24CG4.ts → chunk-MRIPZGPR.ts} +3 -3
  41. package/dist/chunks/{chunk-WD6FJHCK.ts → chunk-ODF2M4RF.ts} +5 -5
  42. package/dist/chunks/chunk-PHANBTVM.ts +348 -0
  43. package/dist/chunks/chunk-PHANBTVM.ts.map +7 -0
  44. package/dist/chunks/{chunk-GP5DU62N.ts → chunk-PWA3YN5Z.ts} +2 -2
  45. package/dist/chunks/{chunk-YK52VDXG.ts → chunk-QWV3XKNJ.ts} +10 -8
  46. package/dist/chunks/{chunk-YK52VDXG.ts.map → chunk-QWV3XKNJ.ts.map} +1 -1
  47. package/dist/chunks/{chunk-ORGBI36T.ts → chunk-RAMHGOX2.ts} +4 -4
  48. package/dist/chunks/{chunk-QO333NM4.ts → chunk-RX3WGWVL.ts} +5 -5
  49. package/dist/chunks/chunk-RX3WGWVL.ts.map +7 -0
  50. package/dist/chunks/{chunk-PQW6GS4J.ts → chunk-STVQQ5KG.ts} +12 -10
  51. package/dist/chunks/{chunk-PQW6GS4J.ts.map → chunk-STVQQ5KG.ts.map} +1 -1
  52. package/dist/chunks/{chunk-76NB4R7U.ts → chunk-TO2GMX3K.ts} +2 -2
  53. package/dist/chunks/{chunk-GSNPASKB.ts → chunk-U77DWNRH.ts} +6 -6
  54. package/dist/chunks/{chunk-U3XRI2HF.ts → chunk-UCD7TQDT.ts} +11 -11
  55. package/dist/chunks/{chunk-A6HU4ERM.ts → chunk-UGSSZWQ6.ts} +6 -23
  56. package/dist/chunks/chunk-UGSSZWQ6.ts.map +7 -0
  57. package/dist/chunks/chunk-X7R6DCVF.ts +28 -0
  58. package/dist/chunks/chunk-X7R6DCVF.ts.map +7 -0
  59. package/dist/chunks/{chunk-HUZ5CR4W.ts → chunk-YZ5BQNRZ.ts} +2 -51
  60. package/dist/chunks/{chunk-HUZ5CR4W.ts.map → chunk-YZ5BQNRZ.ts.map} +4 -4
  61. package/dist/chunks/{chunk-UOHR7LRO.ts → chunk-Z5O2TLNF.ts} +9 -21
  62. package/dist/chunks/chunk-Z5O2TLNF.ts.map +7 -0
  63. package/dist/chunks/command-handler-FO6F2APH.ts +543 -0
  64. package/dist/chunks/command-handler-FO6F2APH.ts.map +7 -0
  65. package/dist/chunks/{config-KGIYTTXQ.ts → config-B37W7FXW.ts} +5 -6
  66. package/dist/chunks/{conflict-artifacts-FXFIIBCB.ts → conflict-artifacts-6XGSSU5S.ts} +13 -9
  67. package/dist/chunks/{conflict-review-UC5AGVER.ts → conflict-review-BQSHSJB3.ts} +32 -26
  68. package/dist/chunks/{conflict-review-UC5AGVER.ts.map → conflict-review-BQSHSJB3.ts.map} +1 -1
  69. package/dist/chunks/{continuous-record-SQJ47CXN.ts → continuous-record-4DQ2EAZS.ts} +8 -7
  70. package/dist/chunks/{continuous-sync-POEQXR25.ts → continuous-sync-ZT3UEQLK.ts} +33 -28
  71. package/dist/chunks/{continuous-sync-POEQXR25.ts.map → continuous-sync-ZT3UEQLK.ts.map} +1 -1
  72. package/dist/chunks/{file-selection-3JJYOVNR.ts → file-selection-FBLKM25V.ts} +12 -10
  73. package/dist/chunks/{file-selection-3JJYOVNR.ts.map → file-selection-FBLKM25V.ts.map} +1 -1
  74. package/dist/chunks/{git-backend-NYKSG5X6.ts → git-backend-7PCWECRN.ts} +16 -12
  75. package/dist/chunks/{git-backend-NYKSG5X6.ts.map → git-backend-7PCWECRN.ts.map} +1 -1
  76. package/dist/chunks/{local-fields-6DGYOOIK.ts → local-fields-B6JWLPAE.ts} +10 -5
  77. package/dist/chunks/manager-result-dispatcher-NODX3KKH.ts +28 -0
  78. package/dist/chunks/{manager-ui-26LEINEX.ts → manager-ui-DGRTG76I.ts} +47 -41
  79. package/dist/chunks/{manager-ui-26LEINEX.ts.map → manager-ui-DGRTG76I.ts.map} +1 -1
  80. package/dist/chunks/{merge-baseline-store-RFCAH7KL.ts → merge-baseline-store-HL3VLMAM.ts} +6 -5
  81. package/dist/chunks/{remote-selection-ui-YFPGYGNE.ts → remote-selection-ui-OHMIQ32X.ts} +14 -10
  82. package/dist/chunks/{s3-backend-F7PR5FB3.ts → s3-backend-CJXBEWWU.ts} +21 -17
  83. package/dist/chunks/{s3-backend-F7PR5FB3.ts.map → s3-backend-CJXBEWWU.ts.map} +1 -1
  84. package/dist/chunks/{setup-switch-E7PHKI6J.ts → setup-switch-66GWMBNH.ts} +6 -7
  85. package/dist/chunks/{setup-wizard-OVHZYXNW.ts → setup-wizard-OHZXJVQZ.ts} +8 -9
  86. package/dist/chunks/{setup-wizard-OVHZYXNW.ts.map → setup-wizard-OHZXJVQZ.ts.map} +1 -1
  87. package/dist/chunks/{snapshot-THS5EY2L.ts → snapshot-VRHNAUUH.ts} +11 -6
  88. package/dist/chunks/snapshot-transaction-EUGA4VX6.ts +24 -0
  89. package/dist/chunks/sync-inspection-4WFQEJOE.ts +25 -0
  90. package/dist/chunks/sync-inspection-4WFQEJOE.ts.map +7 -0
  91. package/dist/chunks/{sync-operations-ZHA6HQDB.ts → sync-operations-X4AOXMBT.ts} +66 -57
  92. package/dist/chunks/{sync-operations-ZHA6HQDB.ts.map → sync-operations-X4AOXMBT.ts.map} +1 -1
  93. package/dist/chunks/{sync-state-CFL4RRRB.ts → sync-state-SWLSMK4G.ts} +9 -5
  94. package/dist/chunks/sync-state-SWLSMK4G.ts.map +7 -0
  95. package/dist/chunks/{webdav-backend-TGFUH3SF.ts → webdav-backend-2Q5ZEBST.ts} +16 -12
  96. package/dist/chunks/{webdav-backend-TGFUH3SF.ts.map → webdav-backend-2Q5ZEBST.ts.map} +1 -1
  97. package/dist/index.ts +54 -537
  98. package/dist/index.ts.map +3 -3
  99. package/package.json +5 -4
  100. package/src/settings/config.ts +1 -1
  101. package/src/settings/settings-validation.ts +1 -1
  102. package/src/snapshot/snapshot-transaction-directory.ts +16 -0
  103. package/src/snapshot/snapshot-transaction.ts +1 -12
  104. package/src/sync/automatic-sync.ts +12 -6
  105. package/src/sync/local-field-policy.ts +29 -0
  106. package/src/sync/local-fields.ts +3 -29
  107. package/src/sync/mutation-owner.ts +22 -0
  108. package/src/sync/startup-check.ts +3 -2
  109. package/src/sync/sync-loaders.ts +4 -0
  110. package/src/sync/sync-local.ts +2 -19
  111. package/src/sync-extension.ts +7 -2
  112. package/src/ui/sync-confirmation.ts +3 -0
  113. package/dist/chunks/chunk-5XZOC7FD.ts.map +0 -7
  114. package/dist/chunks/chunk-A6HU4ERM.ts.map +0 -7
  115. package/dist/chunks/chunk-CRKTAPSL.ts.map +0 -7
  116. package/dist/chunks/chunk-QO333NM4.ts.map +0 -7
  117. package/dist/chunks/chunk-QOFMXPM5.ts +0 -735
  118. package/dist/chunks/chunk-QOFMXPM5.ts.map +0 -7
  119. package/dist/chunks/chunk-UOHR7LRO.ts.map +0 -7
  120. package/dist/chunks/manager-result-dispatcher-HOCM2GDA.ts +0 -24
  121. package/dist/chunks/sync-inspection-J25EEKZK.ts +0 -21
  122. /package/dist/chunks/{agent-candidate-GNEYR225.ts.map → agent-candidate-EYB35AGL.ts.map} +0 -0
  123. /package/dist/chunks/{config-KGIYTTXQ.ts.map → agent-sync-VM3TXWA3.ts.map} +0 -0
  124. /package/dist/chunks/{chunk-PG7NMFP2.ts.map → chunk-4RLATUP4.ts.map} +0 -0
  125. /package/dist/chunks/{chunk-GNH73BJ5.ts.map → chunk-66GAUVDL.ts.map} +0 -0
  126. /package/dist/chunks/{chunk-UPNVIUBN.ts.map → chunk-73MDIVYJ.ts.map} +0 -0
  127. /package/dist/chunks/{chunk-S7QS4AWK.ts.map → chunk-AO6EDUA6.ts.map} +0 -0
  128. /package/dist/chunks/{chunk-JCH3VXIO.ts.map → chunk-BJXSCGQK.ts.map} +0 -0
  129. /package/dist/chunks/{chunk-IWZH5KYS.ts.map → chunk-CDQGSZL3.ts.map} +0 -0
  130. /package/dist/chunks/{chunk-ED3TYIVW.ts.map → chunk-DOJRPBQU.ts.map} +0 -0
  131. /package/dist/chunks/{chunk-5QAE3G3K.ts.map → chunk-IMMMZUFC.ts.map} +0 -0
  132. /package/dist/chunks/{chunk-B4QZBDBT.ts.map → chunk-JXWTEJS5.ts.map} +0 -0
  133. /package/dist/chunks/{chunk-P7DD5PWZ.ts.map → chunk-M5IV3KL2.ts.map} +0 -0
  134. /package/dist/chunks/{chunk-AAEEHR7H.ts.map → chunk-MDUORMCK.ts.map} +0 -0
  135. /package/dist/chunks/{chunk-UBV24CG4.ts.map → chunk-MRIPZGPR.ts.map} +0 -0
  136. /package/dist/chunks/{chunk-WD6FJHCK.ts.map → chunk-ODF2M4RF.ts.map} +0 -0
  137. /package/dist/chunks/{chunk-GP5DU62N.ts.map → chunk-PWA3YN5Z.ts.map} +0 -0
  138. /package/dist/chunks/{chunk-ORGBI36T.ts.map → chunk-RAMHGOX2.ts.map} +0 -0
  139. /package/dist/chunks/{chunk-76NB4R7U.ts.map → chunk-TO2GMX3K.ts.map} +0 -0
  140. /package/dist/chunks/{chunk-GSNPASKB.ts.map → chunk-U77DWNRH.ts.map} +0 -0
  141. /package/dist/chunks/{chunk-U3XRI2HF.ts.map → chunk-UCD7TQDT.ts.map} +0 -0
  142. /package/dist/chunks/{conflict-artifacts-FXFIIBCB.ts.map → config-B37W7FXW.ts.map} +0 -0
  143. /package/dist/chunks/{continuous-record-SQJ47CXN.ts.map → conflict-artifacts-6XGSSU5S.ts.map} +0 -0
  144. /package/dist/chunks/{local-fields-6DGYOOIK.ts.map → continuous-record-4DQ2EAZS.ts.map} +0 -0
  145. /package/dist/chunks/{manager-result-dispatcher-HOCM2GDA.ts.map → local-fields-B6JWLPAE.ts.map} +0 -0
  146. /package/dist/chunks/{merge-baseline-store-RFCAH7KL.ts.map → manager-result-dispatcher-NODX3KKH.ts.map} +0 -0
  147. /package/dist/chunks/{remote-selection-ui-YFPGYGNE.ts.map → merge-baseline-store-HL3VLMAM.ts.map} +0 -0
  148. /package/dist/chunks/{setup-switch-E7PHKI6J.ts.map → remote-selection-ui-OHMIQ32X.ts.map} +0 -0
  149. /package/dist/chunks/{snapshot-THS5EY2L.ts.map → setup-switch-66GWMBNH.ts.map} +0 -0
  150. /package/dist/chunks/{sync-inspection-J25EEKZK.ts.map → snapshot-VRHNAUUH.ts.map} +0 -0
  151. /package/dist/chunks/{sync-state-CFL4RRRB.ts.map → snapshot-transaction-EUGA4VX6.ts.map} +0 -0
package/dist/index.ts.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/ui/operation-dialogs.ts", "../src/commands/command-execution.ts", "../src/commands/command-handler.ts", "../src/settings/config-errors.ts", "../src/sync/automatic-sync.ts", "../src/sync/startup-check.ts", "../src/sync/sync-loaders.ts", "../src/ui/startup-timings-entry.ts", "../src/sync-extension.ts"],
4
- "sourcesContent": ["import type { ExtensionContext } from \"@earendil-works/pi-coding-agent\";\n\n/** Track History's Pi-owned selector/confirmation lifetime without inspecting renderer internals. */\nexport function trackOperationDialogs<Context extends ExtensionContext>(\n ctx: Context,\n onDialog?: (active: boolean) => void,\n): Context {\n if (!onDialog) return ctx;\n const runDialog = async <Value>(task: () => Promise<Value>): Promise<Value> => {\n onDialog(true);\n try {\n return await task();\n } finally {\n onDialog(false);\n }\n };\n const ui: ExtensionContext[\"ui\"] = {\n ...ctx.ui,\n select: (...args) => runDialog(() => ctx.ui.select(...args)),\n confirm: (...args) => runDialog(() => ctx.ui.confirm(...args)),\n };\n // Forward live context properties: copying the context would hide session\n // replacement from mutation-owner revalidation after a dialog settles.\n return new Proxy(ctx, {\n get(target, key, receiver) {\n return key === \"ui\" ? ui : Reflect.get(target, key, receiver);\n },\n });\n}\n", "import type { ExtensionCommandContext, ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { loadConfig, sessionTokenWarnings, syncSessionsWarnings } from \"../settings/config.js\";\nimport { activeLocalConfigPath, createLocalConfigDocument, localConfigPath } from \"../settings/config-file.js\";\nimport { localConfigTemplate, readLocalConfigObject } from \"../settings/settings-store.js\";\nimport type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport { unlock, withLock } from \"../state/lock.js\";\nimport { migrateLegacyStateDirectory, stateDirectoryMigrationNotice } from \"../state/state-directory.js\";\nimport { withAgentSyncLock } from \"../sync/agent-sync.js\";\nimport { throwIfAborted } from \"../sync/signals.js\";\nimport { syncErrorGuidance } from \"../sync/sync-error-guidance.js\";\nimport { isSyncDecisionRequiredError, SetupPullRequiresUiError } from \"../sync/sync-errors.js\";\nimport type { SyncLoaders } from \"../sync/sync-loaders.js\";\nimport { RemoteSelectionMismatchError } from \"../sync/sync-policy.js\";\nimport { automaticSyncSummary } from \"../ui/automatic-sync-summary.js\";\nimport type { RunRouteResult } from \"../ui/cancellable-operation.js\";\nimport { trackOperationDialogs } from \"../ui/operation-dialogs.js\";\nimport { startupTransferSummary } from \"../ui/sync-behavior.js\";\nimport { setSyncStatus } from \"../ui/sync-status.js\";\nimport { safeTerminalText } from \"../ui/terminal-text.js\";\nimport { parseOptions, resolveSyncCommand, splitArgs, usage, validateCommandOptions } from \"./command.js\";\nimport type { CommandOptions } from \"./command-types.js\";\n\nexport async function executeRecoveryCommand(\n rawArgs: string,\n ctx: ExtensionContext,\n signal: AbortSignal | undefined,\n loaders: SyncLoaders,\n onCommit?: () => void,\n setup?: string,\n): Promise<RunRouteResult> {\n try {\n const [subcommand, ...rest] = splitArgs(rawArgs);\n if (subcommand !== \"sync\" && subcommand !== \"pull\" && subcommand !== \"push\") {\n throw new Error(`Unsupported sync recovery route: ${subcommand ?? \"missing\"}`);\n }\n const options = parseOptions(rest);\n if (setup !== undefined) options.setup = setup;\n if (signal) options.signal = signal;\n if (onCommit) options.onCommit = onCommit;\n options.reload = false;\n options.auto = false;\n validateCommandOptions(subcommand, options);\n const operations = await loaders.operations();\n throwIfAborted(options.signal);\n if (subcommand === \"push\") {\n const outcome = await withLock(\"push\", () => operations.push(ctx, options));\n return { kind: \"completed\", ...(outcome ? { outcome } : {}) };\n }\n if (subcommand === \"pull\") {\n const outcome = await withLock(\"pull\", () => operations.pull(ctx, options));\n return { kind: \"completed\", ...(outcome ? { outcome } : {}) };\n }\n await withAgentSyncLock(ctx, options, (current) => operations.syncBoth(ctx, current));\n return { kind: \"completed\" };\n } catch (error) {\n if (signal?.aborted) return { kind: \"failed\" };\n setSyncStatus(ctx, undefined);\n if (error instanceof RemoteSelectionMismatchError) {\n return { kind: \"remote-selection-required\", decision: error.decision };\n }\n if (isSyncDecisionRequiredError(error)) {\n return { kind: \"decision-required\", decision: error.decision };\n }\n ctx.ui.notify(syncErrorGuidance(error), \"error\");\n return { kind: \"failed\" };\n }\n}\n\nexport async function executeCommand(\n rawArgs: string,\n ctx: ExtensionCommandContext,\n signal: AbortSignal | undefined,\n loaders: SyncLoaders,\n onCommit?: () => void,\n setup?: string,\n onDialog?: (active: boolean) => void,\n retryRefusal = false,\n): Promise<RunRouteResult> {\n ctx = trackOperationDialogs(ctx, onDialog);\n try {\n const command = await resolveSyncCommand(rawArgs, ctx);\n if (signal?.aborted || !command) return { kind: \"completed\" };\n const { subcommand, rest } = command;\n const options = parseOptions(rest);\n if (setup !== undefined) options.setup = setup;\n if (signal) options.signal = signal;\n if (onCommit) options.onCommit = onCommit;\n validateCommandOptions(subcommand, options);\n if (retryRefusal) {\n if (subcommand !== \"sync\") throw new Error(\"A refused-model retry is available only for merged sync.\");\n options.agentRetryRefusal = true;\n }\n\n switch (subcommand) {\n case \"help\":\n ctx.ui.notify(usage(), \"info\");\n return { kind: \"completed\" };\n case \"use\": {\n const { useSyncSetup } = await loaders.setupSwitch();\n throwIfAborted(options.signal);\n await useSyncSetup(\n ctx,\n options.args[0] ?? \"\",\n async (selectedSetup) => {\n const operations = await loaders.operations();\n throwIfAborted(options.signal);\n return withLock(\"pull\", () => operations.pull(ctx, { ...options, setup: selectedSetup }));\n },\n undefined,\n options.signal,\n );\n return { kind: \"completed\" };\n }\n case \"init\":\n await initConfig(ctx, signal);\n return { kind: \"completed\" };\n case \"config\":\n await showConfig(ctx, options);\n return { kind: \"completed\" };\n case \"files\": {\n const { showFileSelection } = await import(\"../ui/file-selection.js\");\n throwIfAborted(options.signal);\n await showFileSelection(ctx, options.setup, options.signal);\n return { kind: \"completed\" };\n }\n case \"status\": {\n const operations = await loaders.operations();\n throwIfAborted(options.signal);\n await operations.status(ctx, options);\n return { kind: \"completed\" };\n }\n case \"diff\": {\n const operations = await loaders.operations();\n throwIfAborted(options.signal);\n await operations.diff(ctx, options);\n return { kind: \"completed\" };\n }\n case \"conflicts\": {\n const { showConflicts } = await import(\"../sync/conflict-review.js\");\n throwIfAborted(options.signal);\n await withLock(\"sync\", () => showConflicts(ctx, options));\n return { kind: \"completed\" };\n }\n case \"doctor\": {\n const operations = await loaders.operations();\n throwIfAborted(options.signal);\n await operations.doctor(ctx, options);\n return { kind: \"completed\" };\n }\n case \"push\": {\n const operations = await loaders.operations();\n throwIfAborted(options.signal);\n const outcome = await withLock(\"push\", () => operations.push(ctx, options));\n return { kind: \"completed\", ...(outcome ? { outcome } : {}) };\n }\n case \"pull\": {\n const operations = await loaders.operations();\n throwIfAborted(options.signal);\n const outcome = await withLock(\"pull\", () => operations.pull(ctx, options));\n return { kind: \"completed\", ...(outcome ? { outcome } : {}) };\n }\n case \"sync\": {\n const operations = await loaders.operations();\n throwIfAborted(options.signal);\n const outcome = await withAgentSyncLock(ctx, options, (current) => operations.syncBoth(ctx, current));\n return { kind: \"completed\", ...(retryRefusal && outcome ? { outcome } : {}) };\n }\n case \"history\": {\n const operations = await loaders.operations();\n throwIfAborted(options.signal);\n await operations.history(ctx, options);\n return { kind: \"completed\" };\n }\n case \"rollback\": {\n const operations = await loaders.operations();\n throwIfAborted(options.signal);\n await withLock(\"rollback\", () => operations.rollback(ctx, options));\n return { kind: \"completed\" };\n }\n case \"migrate-state\":\n await migrateStateDirectory(ctx, options);\n return { kind: \"completed\" };\n case \"unlock\":\n await unlock(ctx, options);\n return { kind: \"completed\" };\n default:\n ctx.ui.notify(`Unknown /sync command: ${subcommand}\\n\\n${usage()}`, \"warning\");\n return { kind: \"failed\" };\n }\n } catch (error) {\n if (signal?.aborted) return { kind: \"failed\" };\n setSyncStatus(ctx, undefined);\n if (error instanceof SetupPullRequiresUiError) throw error;\n if (error instanceof RemoteSelectionMismatchError) {\n return { kind: \"remote-selection-required\", decision: error.decision };\n }\n if (isSyncDecisionRequiredError(error)) {\n return { kind: \"decision-required\", decision: error.decision };\n }\n ctx.ui.notify(syncErrorGuidance(error), \"error\");\n return { kind: \"failed\" };\n }\n}\n\nasync function migrateStateDirectory(ctx: ExtensionCommandContext, options: CommandOptions) {\n const notice = stateDirectoryMigrationNotice();\n if (!notice) {\n ctx.ui.notify(\"pi-sync already uses the canonical pi-sync/ state directory.\", \"info\");\n return;\n }\n if (\n !options.yes &&\n !(await ctx.ui.confirm(\n \"Migrate pi-sync state directory\",\n \"Confirm that every other Pi process is closed. pi-sync will atomically rename .pisync/ to pi-sync/ without merging or deleting either root.\",\n { signal: options.signal },\n ))\n ) {\n ctx.ui.notify(\"pi-sync state migration cancelled.\", \"info\");\n return;\n }\n throwIfAborted(options.signal);\n const result = await migrateLegacyStateDirectory();\n throwIfAborted(options.signal);\n if (result.status === \"ready\") {\n ctx.ui.notify(\"pi-sync already uses the canonical pi-sync/ state directory.\", \"info\");\n return;\n }\n ctx.ui.notify(result.message, result.status === \"migrated\" ? \"info\" : \"warning\");\n}\n\nasync function initConfig(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n const configPath = localConfigPath();\n if (await readLocalConfigObject()) {\n ctx.ui.notify(`Config already exists: ${await activeLocalConfigPath()}`, \"info\");\n return;\n }\n\n if (ctx.mode === \"tui\") {\n const { showSetupWizard } = await import(\"../ui/setup/setup-wizard.js\");\n throwIfAborted(signal);\n await showSetupWizard(ctx, signal);\n return;\n }\n await createLocalConfigDocument(localConfigTemplate());\n ctx.ui.notify(`Created ${configPath}. Add a storage connection and sync setup before syncing.`, \"info\");\n}\n\nasync function showConfig(ctx: ExtensionCommandContext, options: CommandOptions) {\n const config = await loadConfig(options.setup);\n const warnings = [\n ...(config.backend.type === \"s3\" ? sessionTokenWarnings(config.backend.profile) : []),\n ...syncSessionsWarnings(config),\n ];\n const storageLines = configStorageLines(config);\n ctx.ui.notify(\n [\n \"pi-sync config:\",\n `sync setup: ${config.setupName}`,\n `storage connection: ${config.connectionName}`,\n ...storageLines,\n `storage path: ${config.storagePath}`,\n `automatic sync: ${automaticSyncSummary(config.automatic)}`,\n `settings field merge: ${config.mergeSettings ? \"On (experimental)\" : \"Off\"}`,\n `machine-local settings.json fields: ${(config.localFields ?? []).map(safeTerminalText).join(\", \") || \"none\"}`,\n `startup transfer: ${startupTransferSummary(config)}`,\n `agent mode: ${config.agentMode ? \"On (experimental)\" : \"Off\"}`,\n `continuous sync: ${config.continuous ? (config.agentMode ? \"On (experimental)\" : \"paused; Agent mode is Off\") : \"Off\"}`,\n `included content: ${config.include.join(\", \") || \"none\"}`,\n `sessions: ${config.include.includes(\"sessions\") ? \"included\" : \"not included\"}`,\n `settings file: ${localConfigPath()}`,\n ...warnings,\n ].join(\"\\n\"),\n warnings.length > 0 ? \"warning\" : \"info\",\n );\n}\n\nfunction configStorageLines(config: AnySyncConfig) {\n switch (config.backend.type) {\n case \"git\":\n return [\n \"kind: git\",\n `remote: ${displayGitRemote(config.backend.profile.remote)}`,\n \"authentication: existing Git/SSH credentials (not stored)\",\n `branch: ${config.backend.destination.branch}`,\n ];\n case \"webdav\":\n return [\n \"kind: webdav\",\n `url: ${displayWebDavUrl(config.backend.profile.url, config.backend.profile.username)}`,\n \"username: configured (value hidden)\",\n \"password: configured\",\n ];\n case \"s3\":\n return [\n \"kind: s3\",\n `endpoint: ${config.backend.profile.endpoint}`,\n `bucket: ${config.backend.destination.bucket}`,\n `region: ${config.backend.profile.region}`,\n \"access key id: configured\",\n \"secret access key: configured\",\n `session token: ${config.backend.profile.sessionToken ? \"configured\" : \"not configured\"}`,\n ];\n }\n}\n\nfunction displayGitRemote(value: string | undefined) {\n if (!value) return \"missing\";\n try {\n const url = new URL(value);\n url.username = \"\";\n url.password = \"\";\n url.search = \"\";\n url.hash = \"\";\n return url.toString();\n } catch {\n return value.replace(/^(?:[^@\\s]+@)?(?<host>[^:]+):.+$/u, \"$<host>:\u2026\");\n }\n}\n\nfunction displayWebDavUrl(value: string | undefined, username: string | undefined) {\n if (!value) return \"missing\";\n try {\n const url = new URL(value);\n url.username = \"\";\n url.password = \"\";\n url.search = \"\";\n url.hash = \"\";\n return username ? `${url.origin}/\u2026` : `${url.origin}${url.pathname}`;\n } catch {\n return \"invalid (value hidden)\";\n }\n}\n", "import type { ExtensionCommandContext, ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { loadConfig } from \"../settings/config.js\";\nimport { readStateForConfig, syncStateFingerprint } from \"../state/sync-state-store.js\";\nimport { combineSignals } from \"../sync/signals.js\";\nimport { errorMessage } from \"../sync/sync-errors.js\";\nimport type { SyncLoaders } from \"../sync/sync-loaders.js\";\nimport { formatRemoteSelectionMismatch } from \"../sync/sync-policy.js\";\nimport type { RunRouteResult } from \"../ui/cancellable-operation.js\";\nimport {\n observationMatchesConfig,\n type SyncAttentionController,\n type SyncAttentionOrigin,\n syncAttentionMatchesConfig,\n} from \"../ui/sync-attention.js\";\nimport { setSyncStatus } from \"../ui/sync-status.js\";\nimport { parseOptions, splitArgs, validateCommandOptions } from \"./command.js\";\nimport { executeCommand, executeRecoveryCommand } from \"./command-execution.js\";\n\nexport async function handleCommand(\n rawArgs: string,\n ctx: ExtensionCommandContext,\n sessionSignal: AbortSignal,\n loaders: SyncLoaders,\n attention: SyncAttentionController,\n onExplicitSync?: (setup?: string) => void,\n) {\n await reconcileObservation(attention, sessionSignal);\n if (sessionSignal.aborted) return;\n const run = (\n route: string,\n signal?: AbortSignal,\n onCommit?: () => void,\n target?: string,\n onDialog?: (active: boolean) => void,\n retryRefusal = false,\n ) => {\n const [command, ...args] = splitArgs(route);\n if (command === \"sync\" && !retryRefusal) {\n try {\n const options = parseOptions(args);\n validateCommandOptions(\"sync\", options);\n onExplicitSync?.(target ?? options.setup);\n } catch {\n /* Invalid routes do not request an automatic retry. */\n }\n }\n return executeCommand(\n route,\n ctx,\n combineSignals(sessionSignal, signal),\n loaders,\n observationCommitCallback(attention, sessionSignal, onCommit),\n target,\n onDialog,\n retryRefusal,\n );\n };\n if (!rawArgs.trim()) {\n try {\n const { showSyncManager } = await import(\"../ui/manager-ui.js\");\n if (sessionSignal.aborted) return;\n await showSyncManager(ctx, run, sessionSignal, {\n getAttention: () => attention.current(),\n getObservation: () => attention.observation(),\n onObservationInvalidated: () => attention.clearObservation(),\n onSelectionResolved: (expected) => {\n if (attention.current() === expected) attention.clear(ctx);\n },\n });\n } catch (error) {\n if (sessionSignal.aborted) return;\n setSyncStatus(ctx, undefined);\n ctx.ui.notify(errorMessage(error), \"error\");\n }\n await reconcileObservation(attention, sessionSignal);\n if (!sessionSignal.aborted) await attention.publish(ctx, sessionSignal);\n return;\n }\n const result = await run(rawArgs);\n if (result.kind === \"decision-required\") {\n ctx.ui.notify(result.decision.directMessage, \"error\");\n } else if (result.kind === \"remote-selection-required\") {\n const origin = directSelectionOrigin(rawArgs);\n if (origin) attention.set(result.decision, origin);\n const deterministic = splitArgs(rawArgs).some((arg) => arg === \"--yes\" || arg === \"-y\");\n if (origin && ctx.mode === \"tui\" && !deterministic) {\n await resolveSelectionAttention(ctx, attention, sessionSignal, loaders);\n } else {\n ctx.ui.notify(\n formatRemoteSelectionMismatch(\n result.decision.setupName,\n result.decision.localInclude,\n result.decision.remoteInclude,\n ),\n \"error\",\n );\n }\n }\n await clearAttentionAfterCompletedOperation(rawArgs, result, ctx, attention, sessionSignal);\n await reconcileSelectionAttention(ctx, attention, sessionSignal);\n await reconcileObservation(attention, sessionSignal);\n if (!sessionSignal.aborted) await attention.publish(ctx, sessionSignal);\n}\n\nfunction observationCommitCallback(\n attention: SyncAttentionController,\n sessionSignal: AbortSignal,\n onCommit?: () => void,\n) {\n const observed = attention.observation();\n return () => {\n // Opening or cancelling a review changes nothing. A commit may change data\n // even if later publication/baseline cleanup fails; never restore old hints.\n if (!sessionSignal.aborted && attention.observation() === observed) attention.clearObservation();\n onCommit?.();\n };\n}\n\nasync function reconcileObservation(attention: SyncAttentionController, signal: AbortSignal) {\n const observed = attention.observation();\n if (!observed || signal.aborted) return;\n try {\n const config = await loadConfig();\n if (signal.aborted || attention.observation() !== observed) return;\n if (!observationMatchesConfig(observed, config)) {\n attention.clearObservation();\n return;\n }\n const state = await readStateForConfig(config);\n if (signal.aborted || attention.observation() !== observed) return;\n if (syncStateFingerprint(state) !== observed.inspection.stateIdentity) attention.clearObservation();\n } catch {\n if (!signal.aborted && attention.observation() === observed) attention.clearObservation();\n }\n}\n\nasync function clearAttentionAfterCompletedOperation(\n rawArgs: string,\n result: RunRouteResult,\n ctx: ExtensionContext,\n attention: SyncAttentionController,\n signal: AbortSignal,\n) {\n if (result.kind !== \"completed\" || result.outcome === \"cancelled\" || signal.aborted) return;\n const [command, ...rest] = splitArgs(rawArgs);\n if (command !== \"sync\" && command !== \"pull\" && command !== \"push\") return;\n const current = attention.current();\n if (!current) return;\n try {\n const options = parseOptions(rest);\n const setupName = options.setup ?? (await loadConfig()).setupName;\n if (signal.aborted || attention.current() !== current) return;\n if (current.decision.setupName === setupName) attention.clear(ctx);\n } catch {\n // Attention reconciliation below owns malformed or concurrently changed settings.\n }\n}\n\nasync function reconcileSelectionAttention(\n ctx: ExtensionContext,\n attention: SyncAttentionController,\n signal: AbortSignal,\n) {\n const current = attention.current();\n if (!current || signal.aborted) return;\n try {\n const config = await loadConfig(current.decision.setupName);\n if (signal.aborted || attention.current() !== current) return;\n if (!syncAttentionMatchesConfig(current, config)) attention.clear(ctx);\n } catch {\n if (!signal.aborted && attention.current() === current) attention.clear(ctx);\n }\n}\n\nfunction directSelectionOrigin(rawArgs: string): SyncAttentionOrigin | undefined {\n const command = splitArgs(rawArgs)[0];\n return command === \"sync\" || command === \"pull\" || command === \"push\" ? command : undefined;\n}\n\nexport async function resolveSelectionAttention(\n ctx: ExtensionContext,\n attention: SyncAttentionController,\n signal: AbortSignal,\n loaders: SyncLoaders,\n options: {\n cancelLabel?: string;\n withStateAccess?: <T>(task: () => Promise<T>) => Promise<T>;\n } = {},\n) {\n const current = attention.current();\n if (!current || signal.aborted) return;\n const { dispatchManagerResult } = await import(\"../ui/manager-result-dispatcher.js\");\n if (signal.aborted || attention.current() !== current) return;\n await dispatchManagerResult(\n ctx,\n { kind: \"remote-selection-required\", decision: current.decision },\n current.origin,\n (route, actionSignal, onCommit, target) => {\n const execute = () =>\n executeRecoveryCommand(\n route,\n ctx,\n combineSignals(signal, actionSignal),\n loaders,\n observationCommitCallback(attention, signal, onCommit),\n target,\n );\n return options.withStateAccess ? options.withStateAccess(execute) : execute();\n },\n signal,\n {\n cancelLabel: options.cancelLabel,\n withStateAccess: options.withStateAccess,\n onSelectionResolved: () => {\n if (attention.current() === current) attention.clear(ctx);\n },\n },\n );\n}\n", "export function isMissingConfigError(error: unknown) {\n return (\n error instanceof Error &&\n (error.message.startsWith(\"Missing pi-sync settings.\") || error.message === \"No sync setups are configured.\")\n );\n}\n", "import type { ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { setSyncSetupCompletions } from \"../commands/command.js\";\nimport type { CommandOptions } from \"../commands/command-types.js\";\nimport { loadConfig, loadPartialConfig } from \"../settings/config.js\";\nimport { isMissingConfigError } from \"../settings/config-errors.js\";\nimport { consumeLocalConfigMigrationNotice } from \"../settings/config-file.js\";\nimport { readLocalConfigObject } from \"../settings/settings-store.js\";\nimport type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport { sessionDirFromContext, snapshotOptionsForContext } from \"../snapshot/session-paths.js\";\nimport { recoverSnapshotTransactionsOnStartup } from \"../snapshot/snapshot-transaction.js\";\nimport { withLock } from \"../state/lock.js\";\nimport { stateDirectoryMigrationNotice } from \"../state/state-directory.js\";\nimport { ensureStateDir, readStateForConfig } from \"../state/sync-state-store.js\";\nimport { configureSyncStatus, setSyncStatus } from \"../ui/sync-status.js\";\nimport { safeTerminalText } from \"../ui/terminal-text.js\";\nimport { throwIfAborted } from \"./signals.js\";\nimport { createStartupTimings, type StartupTimingPublisher } from \"./startup-timings.js\";\nimport { errorMessage } from \"./sync-errors.js\";\nimport type { SyncLoaders } from \"./sync-loaders.js\";\nimport { captureMutationOwner } from \"./sync-local.js\";\n\nconst AUTO_SYNC_OPTIONS: CommandOptions = {\n yes: true,\n force: false,\n stale: false,\n silent: true,\n reload: false,\n auto: true,\n args: [],\n};\n\nexport async function startSession(\n ctx: ExtensionContext,\n signal: AbortSignal,\n publish?: StartupTimingPublisher,\n): Promise<{ debug: boolean; config?: AnySyncConfig } | undefined> {\n const timings = createStartupTimings(publish);\n let debug = false;\n let outcome: \"completed\" | \"stopped\" = \"stopped\";\n try {\n throwIfAborted(signal);\n const stateNotice = stateDirectoryMigrationNotice();\n if (stateNotice && ctx.hasUI) ctx.ui.notify(stateNotice, \"warning\");\n // Recovery can restore managed files: finish it before Pi accepts user edits.\n // Unlike remote inspection, it must never be detached behind startup.\n const validateMutation = captureMutationOwner(ctx, signal);\n const currentFile = ctx.sessionManager.getSessionFile?.();\n await timings.measure(\"transaction recovery\", () =>\n recoverSnapshotTransactionsOnStartup({\n signal,\n sessionDir: sessionDirFromContext(ctx),\n protectedTargets: currentFile ? [currentFile] : [],\n validateMutation,\n }),\n );\n throwIfAborted(signal);\n try {\n const settings = await timings.measure(\"settings read\", () => readLocalConfigObject());\n throwIfAborted(signal);\n debug = settings?.debug ?? false;\n const names = settings ? Object.keys(settings.syncSetups).sort((left, right) => left.localeCompare(right)) : [];\n setSyncSetupCompletions(names);\n configureSyncStatus(ctx, settings?.showStatus ?? true);\n } catch {\n if (signal.aborted) return;\n setSyncSetupCompletions([]);\n }\n const migrationNotice = consumeLocalConfigMigrationNotice();\n if (migrationNotice && ctx.hasUI) ctx.ui.notify(migrationNotice, \"warning\");\n throwIfAborted(signal);\n if (!ctx.hasUI) return { debug };\n try {\n const config = await timings.measure(\"config resolution\", () => loadConfig());\n throwIfAborted(signal);\n configureSyncStatus(ctx, config.showStatus);\n outcome = \"completed\";\n return { debug, config };\n } catch (error) {\n throwIfAborted(signal);\n if (!isMissingConfigError(error)) {\n ctx.ui.notify(`pi-sync startup check skipped: ${safeTerminalText(errorMessage(error))}`, \"warning\");\n }\n }\n return { debug };\n } finally {\n timings.publish(ctx, debug, signal, \"local initialization\", outcome);\n }\n}\n\nexport async function autoPushSessions(ctx: ExtensionContext, signal: AbortSignal, loaders: SyncLoaders) {\n try {\n const partial = await loadPartialConfig();\n throwIfAborted(signal);\n if (!partial.automatic) return;\n if (!partial.include.includes(\"sessions\")) return;\n await ensureStateDir();\n throwIfAborted(signal);\n const config = await loadConfig();\n throwIfAborted(signal);\n if (!config.include.includes(\"sessions\")) return;\n const [operations, snapshotModule, syncStateModule] = await Promise.all([\n loaders.operations(),\n loaders.snapshot(),\n loaders.syncState(),\n ]);\n throwIfAborted(signal);\n await withLock(\"auto-session-push\", async () => {\n throwIfAborted(signal);\n const state = await readStateForConfig(config);\n throwIfAborted(signal);\n const local = await snapshotModule.createSnapshot(config.snapshotIdentity, {\n ...snapshotOptionsForContext(ctx, config),\n signal,\n });\n throwIfAborted(signal);\n if (!syncStateModule.hasLocalChanges(local, state, config)) return;\n await operations.push(ctx, { ...AUTO_SYNC_OPTIONS, signal }, { config, state, local });\n });\n } catch (error) {\n if (signal.aborted || isMissingConfigError(error)) return;\n setSyncStatus(ctx, undefined);\n ctx.ui.notify(`pi-sync session push skipped: ${errorMessage(error)}`, \"warning\");\n }\n}\n", "import type { ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { loadConfigForCheck, syncCheckConfigFingerprint } from \"../settings/config.js\";\nimport { isMissingConfigError } from \"../settings/config-errors.js\";\nimport type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport { snapshotOptionsForContext } from \"../snapshot/session-paths.js\";\nimport { withLock } from \"../state/lock.js\";\nimport { withStateDirectoryAccess } from \"../state/state-directory.js\";\nimport { readStateForConfig, syncStateFingerprint } from \"../state/sync-state-store.js\";\nimport type { SyncAttentionController } from \"../ui/sync-attention.js\";\nimport { setSyncStatus } from \"../ui/sync-status.js\";\nimport { safeTerminalText } from \"../ui/terminal-text.js\";\nimport { startupTransferEnabled } from \"./agent-policy.js\";\nimport { withAgentSyncLock } from \"./agent-sync.js\";\nimport { combineSignals, throwIfAborted } from \"./signals.js\";\nimport { createStartupTimings, type StartupTimingPublisher } from \"./startup-timings.js\";\nimport { errorMessage } from \"./sync-errors.js\";\nimport type { SyncLoaders } from \"./sync-loaders.js\";\n\n/** One owned task per extension session, never keyed by the shared headless UI. */\nexport function createStartupCheck(\n loaders: SyncLoaders,\n attention: SyncAttentionController,\n timeoutMs = 30_000,\n publish?: StartupTimingPublisher,\n) {\n let active:\n | {\n controller: AbortController;\n promise: Promise<void>;\n owner: ExtensionContext[\"sessionManager\"];\n transfer: boolean;\n }\n | undefined;\n\n let pending: { ctx: ExtensionContext; signal: AbortSignal; config: AnySyncConfig } | undefined;\n\n const controllerApi = {\n async interrupt(ctx: ExtensionContext) {\n const task = active;\n if (!task?.transfer || task.owner !== ctx.sessionManager) return;\n task.controller.abort(new DOMException(\"Agent became busy\", \"AbortError\"));\n await task.promise;\n },\n settled(ctx: ExtensionContext) {\n const queued = pending;\n if (!queued || queued.ctx.sessionManager !== ctx.sessionManager || queued.signal.aborted || !ctx.isIdle()) return;\n pending = undefined;\n controllerApi.start(ctx, queued.signal, queued.config);\n },\n start(ctx: ExtensionContext, sessionSignal: AbortSignal, initialConfig?: AnySyncConfig) {\n if (!ctx.hasUI || sessionSignal.aborted) return;\n if (initialConfig && startupTransferEnabled(initialConfig) && !ctx.isIdle()) {\n pending = { ctx, signal: sessionSignal, config: initialConfig };\n return;\n }\n if (active) throw new Error(\"Previous startup check has not been drained.\");\n const timings = createStartupTimings(publish);\n const controller = new AbortController();\n const signal = combineSignals(sessionSignal, controller.signal);\n const task = {\n controller,\n owner: ctx.sessionManager,\n promise: Promise.resolve(),\n transfer: Boolean(initialConfig && startupTransferEnabled(initialConfig)),\n };\n active = task;\n const isCurrent = () => !sessionSignal.aborted && active === task && task.owner === ctx.sessionManager;\n const timer = setTimeout(\n () => controller.abort(new DOMException(\"Startup check timed out\", \"TimeoutError\")),\n timeoutMs,\n );\n timer.unref();\n let config: AnySyncConfig | undefined;\n let checking = false;\n let stopped = false;\n // Handle every detached rejection here; Pi's awaited event runner cannot catch it.\n task.promise = Promise.resolve()\n .then(async () => {\n try {\n throwIfAborted(signal);\n config = initialConfig ?? (await loadConfigForCheck());\n task.transfer = startupTransferEnabled(config);\n throwIfAborted(signal);\n if (!config.automatic && !startupTransferEnabled(config)) return;\n const captured = config;\n const identity = syncCheckConfigFingerprint(captured);\n checking = true;\n setSyncStatus(ctx, \"sync ...\");\n const { inspectSync } = await timings.measure(\"inspection import\", () => loaders.inspection());\n throwIfAborted(signal);\n const currentConfig = await loadConfigForCheck();\n throwIfAborted(signal);\n if (syncCheckConfigFingerprint(currentConfig) !== identity) return;\n // Lock order: state migration guard \u2192 sync operation \u2192 backend cache.\n // Read heads may write only private cache data. Never call doctor/syncBoth.\n const inspection = await timings.measure(\"inspection and guards\", () =>\n withStateDirectoryAccess(() => {\n throwIfAborted(signal);\n return withLock(\"startup-check\", () => {\n throwIfAborted(signal);\n return inspectSync(captured, snapshotOptionsForContext(ctx, captured), signal, undefined, timings);\n });\n }),\n );\n throwIfAborted(signal);\n const latest = await loadConfigForCheck();\n throwIfAborted(signal);\n if (syncCheckConfigFingerprint(latest) !== identity) return;\n const state = await withStateDirectoryAccess(() => readStateForConfig(latest));\n throwIfAborted(signal);\n if (syncStateFingerprint(state) !== inspection.stateIdentity || !isCurrent()) return;\n attention.observe({\n setupName: captured.setupName,\n configIdentity: identity,\n checkedAt: new Date().toISOString(),\n inspection,\n automaticTransfer: startupTransferEnabled(captured),\n });\n if (\n startupTransferEnabled(captured) &&\n !inspection.firstSync &&\n inspection.head &&\n inspection.selectionState?.kind === \"same\"\n ) {\n const operations = await timings.measure(\"operations import\", () => loaders.operations());\n throwIfAborted(signal);\n if (!isCurrent()) return;\n if (!ctx.isIdle()) {\n pending = { ctx, signal: sessionSignal, config: captured };\n return;\n }\n await timings.measure(\"automatic transfer\", () =>\n withStateDirectoryAccess(() =>\n withAgentSyncLock(\n ctx,\n {\n args: [],\n yes: true,\n force: false,\n stale: false,\n silent: true,\n reload: false,\n auto: true,\n signal,\n startupTimings: timings,\n onCommit: () => attention.clearObservation(),\n },\n (options) => operations.syncBoth(ctx, options),\n ),\n ),\n );\n throwIfAborted(signal);\n if (!isCurrent()) return;\n attention.clearObservation();\n return;\n }\n attention.observe({\n setupName: captured.setupName,\n configIdentity: identity,\n checkedAt: new Date().toISOString(),\n inspection,\n automaticTransfer: startupTransferEnabled(captured),\n });\n if (ctx.mode === \"rpc\") attention.notifyObservation(ctx);\n } catch (error) {\n stopped = true;\n if (!isCurrent() || sessionSignal.aborted || isMissingConfigError(error)) return;\n if (signal.aborted && controller.signal.reason?.name !== \"TimeoutError\") return;\n // A settings edit invalidates failures as well as successful observations.\n if (config) {\n const latest = await loadConfigForCheck().catch(() => undefined);\n if (!isCurrent() || (signal.aborted && controller.signal.reason?.name !== \"TimeoutError\")) return;\n if (!latest || syncCheckConfigFingerprint(latest) !== syncCheckConfigFingerprint(config)) return;\n }\n ctx.ui.notify(\n config && startupTransferEnabled(config)\n ? `pi-sync automatic transfer stopped: ${safeTerminalText(errorMessage(error))}. Run /sync to review or reconcile retained recovery evidence. No resources were reloaded.`\n : `pi-sync startup check skipped: ${safeTerminalText(errorMessage(error))}. Run /sync status to retry. No startup transfer was performed.`,\n \"warning\",\n );\n } finally {\n clearTimeout(timer);\n if (isCurrent() && checking) {\n if (!signal.aborted || controller.signal.reason?.name === \"TimeoutError\") {\n const latest = await loadConfigForCheck().catch(() => undefined);\n if (isCurrent()) {\n if (signal.aborted && controller.signal.reason?.name !== \"TimeoutError\")\n setSyncStatus(ctx, undefined);\n else if (\n config &&\n latest &&\n syncCheckConfigFingerprint(latest) === syncCheckConfigFingerprint(config)\n )\n await attention.publish(ctx, sessionSignal);\n else attention.reset(ctx);\n }\n } else setSyncStatus(ctx, undefined);\n }\n if (isCurrent()) {\n timings.publish(\n ctx,\n config?.debug ?? false,\n sessionSignal,\n \"background startup\",\n signal.aborted || stopped ? \"stopped\" : \"completed\",\n );\n }\n if (active === task) active = undefined;\n }\n })\n .catch(() => {\n // UI teardown can itself throw. No unhandled rejection or retained timer.\n clearTimeout(timer);\n if (active === task) active = undefined;\n });\n },\n async stop() {\n pending = undefined;\n const task = active;\n if (!task) return;\n task.controller.abort(new DOMException(\"Startup check cancelled\", \"AbortError\"));\n // Drain the actual work, including child/ref cleanup, before foreground guards.\n await task.promise;\n },\n };\n return controllerApi;\n}\n", "type SetupSwitchModule = Pick<typeof import(\"./setup-switch.js\"), \"useSyncSetup\">;\ntype SnapshotModule = Pick<typeof import(\"../snapshot/snapshot.js\"), \"createSnapshot\">;\ntype SyncStateModule = Pick<typeof import(\"./sync-state.js\"), \"hasLocalChanges\">;\ntype SyncOperations = typeof import(\"./sync-operations.js\");\n\ntype SyncInspectionModule = Pick<typeof import(\"./sync-inspection.js\"), \"inspectSync\">;\n\nexport interface SyncDependencies {\n loadSyncInspection(): Promise<SyncInspectionModule>;\n loadSetupSwitch(): Promise<SetupSwitchModule>;\n loadSnapshot(): Promise<SnapshotModule>;\n loadSyncState(): Promise<SyncStateModule>;\n loadSyncOperations(): Promise<SyncOperations>;\n}\n\nexport interface SyncLoaders {\n inspection(): Promise<SyncInspectionModule>;\n setupSwitch(): Promise<SetupSwitchModule>;\n snapshot(): Promise<SnapshotModule>;\n syncState(): Promise<SyncStateModule>;\n operations(): Promise<SyncOperations>;\n}\n\nexport function createSyncLoaders(dependencies: Partial<SyncDependencies>): SyncLoaders {\n const loaders: SyncLoaders = {\n inspection: cachedModuleLoader(dependencies.loadSyncInspection ?? (() => import(\"./sync-inspection.js\"))),\n setupSwitch: cachedModuleLoader(dependencies.loadSetupSwitch ?? (() => import(\"./setup-switch.js\"))),\n snapshot: cachedModuleLoader(dependencies.loadSnapshot ?? (() => import(\"../snapshot/snapshot.js\"))),\n syncState: cachedModuleLoader(dependencies.loadSyncState ?? (() => import(\"./sync-state.js\"))),\n operations: cachedModuleLoader(dependencies.loadSyncOperations ?? (() => import(\"./sync-operations.js\"))),\n };\n return loaders;\n}\n\nfunction cachedModuleLoader<Module>(load: () => Promise<Module>): () => Promise<Module> {\n let pending: Promise<Module> | undefined;\n return () => {\n if (!pending) {\n pending = load().catch((error) => {\n pending = undefined;\n throw error;\n });\n }\n return pending;\n };\n}\n", "import type { ExtensionAPI } from \"@earendil-works/pi-coding-agent\";\nimport { Text, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport type { StartupTimingPublisher } from \"../sync/startup-timings.js\";\nimport { safeTerminalText } from \"./terminal-text.js\";\n\nexport const STARTUP_TIMING_ENTRY = \"pi-sync-startup-timings\";\n\nexport interface StartupTimingEntry {\n version: 1;\n report: string;\n}\n\nexport function registerStartupTimings(pi: ExtensionAPI): StartupTimingPublisher {\n pi.registerEntryRenderer<StartupTimingEntry>(STARTUP_TIMING_ENTRY, (entry, _options, theme) => {\n const data = entry.data;\n if (data?.version !== 1 || typeof data.report !== \"string\") return undefined;\n const text = new Text(\n data.report\n .split(\"\\n\")\n .map((line, index) => theme.fg(index === 0 ? \"accent\" : \"muted\", safeTerminalText(line)))\n .join(\"\\n\"),\n 0,\n 0,\n );\n return {\n render: (width) => (width > 0 ? text.render(width).map((line) => truncateToWidth(line, width)) : []),\n invalidate: () => text.invalidate(),\n };\n });\n return (ctx, report) => {\n // Pi coalesces consecutive info notifications, including the final /reload notice.\n // Custom entries remain visible without adding messages to model context.\n if (ctx.mode === \"tui\") pi.appendEntry<StartupTimingEntry>(STARTUP_TIMING_ENTRY, { version: 1, report });\n else ctx.ui.notify(report, \"info\");\n };\n}\n", "import type { ExtensionAPI, ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { completeSyncArguments, splitArgs } from \"./commands/command.js\";\nimport { handleCommand } from \"./commands/command-handler.js\";\nimport type { AnySyncConfig } from \"./settings/settings-types.js\";\nimport { withStateDirectoryAccess } from \"./state/state-directory.js\";\nimport { startupTransferEnabled } from \"./sync/agent-policy.js\";\nimport { autoPushSessions, startSession } from \"./sync/automatic-sync.js\";\nimport { combineSignals } from \"./sync/signals.js\";\nimport { createStartupCheck } from \"./sync/startup-check.js\";\nimport { errorMessage } from \"./sync/sync-errors.js\";\nimport { createSyncLoaders, type SyncDependencies } from \"./sync/sync-loaders.js\";\nimport { registerStartupTimings } from \"./ui/startup-timings-entry.js\";\nimport { createSyncAttentionController } from \"./ui/sync-attention.js\";\nimport { setSyncStatus } from \"./ui/sync-status.js\";\nimport { safeTerminalText } from \"./ui/terminal-text.js\";\n\nexport default function sync(pi: ExtensionAPI, dependencies: Partial<SyncDependencies> = {}) {\n const loaders = createSyncLoaders(dependencies);\n const attention = createSyncAttentionController();\n const publishTimings = registerStartupTimings(pi);\n const check = createStartupCheck(loaders, attention, 30_000, publishTimings);\n let sessionAbort = new AbortController();\n let shutdownAbort: AbortController | undefined;\n let initialization = Promise.resolve<AnySyncConfig | false | undefined>(undefined);\n let continuous: ReturnType<typeof import(\"./sync/continuous-sync.js\")[\"createContinuousSync\"]> | undefined;\n let owner: ExtensionContext[\"sessionManager\"] | undefined;\n let continuousPossible = false;\n let startupDebug = false;\n const foreground = new Map<ExtensionContext[\"sessionManager\"], number>();\n async function resumeContinuous(ctx: ExtensionContext, signal: AbortSignal, retry?: { setup?: string }) {\n const isCurrent = () => !signal.aborted && !foreground.has(ctx.sessionManager) && owner === ctx.sessionManager;\n if (!isCurrent() || !ctx.hasUI) return;\n try {\n const { loadConfigForCheck } = await import(\"./settings/config.js\");\n if (!isCurrent()) return;\n const config = await loadConfigForCheck();\n if (!isCurrent()) return;\n continuousPossible = Boolean(config.continuous && config.agentMode);\n if (!continuousPossible) {\n await continuous?.stop(ctx.sessionManager);\n return;\n }\n const { createContinuousSync } = await import(\"./sync/continuous-sync.js\");\n if (!isCurrent()) return;\n continuous ??= createContinuousSync(loaders, undefined, publishTimings);\n continuous.start(\n ctx,\n signal,\n Boolean(retry && (retry.setup === undefined || retry.setup === config.setupName)),\n startupDebug,\n );\n } catch {\n /* Existing initialization/command paths report settings errors. */\n }\n }\n\n pi.registerCommand(\"sync\", {\n description: \"Sync Pi settings through Git, WebDAV, R2, or S3-compatible storage\",\n getArgumentCompletions: completeSyncArguments,\n handler: async (args, ctx) => {\n if (!ctx.hasUI) {\n throw new Error(\"/sync requires TUI or RPC mode so results and safety prompts are observable.\");\n }\n const signal = sessionAbort.signal;\n const manager = ctx.sessionManager;\n const command = splitArgs(args)[0];\n let retry: { setup?: string } | undefined;\n let mayResume = false;\n foreground.set(manager, (foreground.get(manager) ?? 0) + 1);\n try {\n const ready = await initialization;\n mayResume = ready !== false;\n if (signal.aborted) return;\n await continuous?.stop(manager);\n if (signal.aborted) return;\n await check.stop();\n if (signal.aborted) return;\n if (ready === false && command !== \"help\" && command !== \"unlock\" && command !== \"migrate-state\") {\n ctx.ui.notify(\n \"pi-sync recovery required. Repair the startup error, then /reload before syncing. Use /sync help for recovery guidance.\",\n \"error\",\n );\n return;\n }\n const run = () =>\n handleCommand(args, ctx, signal, loaders, attention, (setup) => {\n retry = { setup };\n });\n // Drain background children before foreground guards. Help remains reachable during repair.\n if (command === \"migrate-state\" || command === \"help\") await run();\n else await withStateDirectoryAccess(run);\n } finally {\n const count = (foreground.get(manager) ?? 1) - 1;\n if (count) foreground.set(manager, count);\n else foreground.delete(manager);\n if (mayResume) await resumeContinuous(ctx, signal, retry);\n }\n },\n });\n\n pi.on(\"session_start\", async (_event, ctx) => {\n shutdownAbort?.abort(new DOMException(\"Session replaced\", \"AbortError\"));\n shutdownAbort = undefined;\n sessionAbort.abort(new DOMException(\"Session replaced\", \"AbortError\"));\n sessionAbort = new AbortController();\n const signal = sessionAbort.signal;\n owner = ctx.sessionManager;\n continuousPossible = false;\n startupDebug = false;\n attention.reset(ctx);\n const previous = initialization;\n initialization = (async () => {\n await previous;\n if (signal.aborted) return false;\n await continuous?.stop();\n if (signal.aborted) return false;\n await check.stop();\n if (signal.aborted) return false;\n try {\n const startup = await withStateDirectoryAccess(() => startSession(ctx, signal, publishTimings));\n if (signal.aborted) return false;\n startupDebug = startup?.debug ?? false;\n return startup?.config;\n } catch (error) {\n if (!signal.aborted && ctx.hasUI) {\n ctx.ui.notify(`pi-sync recovery required: ${safeTerminalText(errorMessage(error))}`, \"error\");\n }\n return false;\n }\n })();\n const ready = await initialization;\n if (ready && !signal.aborted) {\n if (ready.continuous && ready.agentMode) await resumeContinuous(ctx, signal);\n else if (ready.automatic || startupTransferEnabled(ready)) check.start(ctx, signal, ready);\n }\n });\n\n pi.on(\"agent_start\", async (_event, ctx) => {\n await continuous?.stop(ctx.sessionManager);\n await check.interrupt(ctx);\n });\n\n pi.on(\"agent_settled\", async (_event, ctx) => {\n const signal = sessionAbort.signal;\n if (!signal.aborted) {\n check.settled(ctx);\n if (continuousPossible) await resumeContinuous(ctx, signal);\n }\n });\n\n pi.on(\"session_shutdown\", async (event, ctx) => {\n if (continuous && owner && owner !== ctx.sessionManager) return;\n sessionAbort.abort(new DOMException(\"Session shut down\", \"AbortError\"));\n attention.reset(ctx);\n shutdownAbort?.abort(new DOMException(\"Session shut down again\", \"AbortError\"));\n const controller = new AbortController();\n shutdownAbort = controller;\n const signal = combineSignals(controller.signal, AbortSignal.timeout(30_000));\n const reason = typeof event === \"object\" && event ? (event as { reason?: string }).reason : undefined;\n try {\n const ready = await initialization;\n if (signal.aborted) return;\n await continuous?.stop(ctx.sessionManager);\n if (signal.aborted) return;\n await check.stop();\n if (signal.aborted) return;\n if (ready !== false && reason !== \"reload\") {\n await withStateDirectoryAccess(async () => {\n if (signal.aborted) return;\n await autoPushSessions(ctx, signal, loaders);\n });\n }\n } catch (error) {\n if (!signal.aborted) {\n ctx.ui.notify(`pi-sync session push skipped: ${errorMessage(error)}`, \"warning\");\n }\n } finally {\n if (shutdownAbort === controller) shutdownAbort = undefined;\n }\n if (signal.aborted) return;\n setSyncStatus(ctx, undefined);\n });\n}\n\nexport type { SyncDependencies } from \"./sync/sync-loaders.js\";\n"],
5
- "mappings": "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",
3
+ "sources": ["../src/settings/config-errors.ts", "../src/sync/automatic-sync.ts", "../src/sync/startup-check.ts", "../src/sync/sync-loaders.ts", "../src/ui/startup-timings-entry.ts", "../src/sync-extension.ts"],
4
+ "sourcesContent": ["export function isMissingConfigError(error: unknown) {\n return (\n error instanceof Error &&\n (error.message.startsWith(\"Missing pi-sync settings.\") || error.message === \"No sync setups are configured.\")\n );\n}\n", "import type { ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { setSyncSetupCompletions } from \"../commands/command.js\";\nimport type { CommandOptions } from \"../commands/command-types.js\";\nimport { loadConfig, loadPartialConfig } from \"../settings/config.js\";\nimport { isMissingConfigError } from \"../settings/config-errors.js\";\nimport { consumeLocalConfigMigrationNotice } from \"../settings/config-file.js\";\nimport { readLocalConfigObject } from \"../settings/settings-store.js\";\nimport type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport { sessionDirFromContext, snapshotOptionsForContext } from \"../snapshot/session-paths.js\";\nimport { pendingTransactionEntries } from \"../snapshot/snapshot-transaction-directory.js\";\nimport { withLock } from \"../state/lock.js\";\nimport { stateDirectoryMigrationNotice } from \"../state/state-directory.js\";\nimport { ensureStateDir, readStateForConfig } from \"../state/sync-state-store.js\";\nimport { configureSyncStatus, setSyncStatus } from \"../ui/sync-status.js\";\nimport { safeTerminalText } from \"../ui/terminal-text.js\";\nimport { captureMutationOwner } from \"./mutation-owner.js\";\nimport { throwIfAborted } from \"./signals.js\";\nimport { createStartupTimings, type StartupTimingPublisher } from \"./startup-timings.js\";\nimport { errorMessage } from \"./sync-errors.js\";\nimport type { SyncLoaders } from \"./sync-loaders.js\";\n\nconst AUTO_SYNC_OPTIONS: CommandOptions = {\n yes: true,\n force: false,\n stale: false,\n silent: true,\n reload: false,\n auto: true,\n args: [],\n};\n\nexport async function startSession(\n ctx: ExtensionContext,\n signal: AbortSignal,\n publish?: StartupTimingPublisher,\n): Promise<{ debug: boolean; config?: AnySyncConfig } | undefined> {\n const timings = createStartupTimings(publish);\n let debug = false;\n let outcome: \"completed\" | \"stopped\" = \"stopped\";\n try {\n throwIfAborted(signal);\n const stateNotice = stateDirectoryMigrationNotice();\n if (stateNotice && ctx.hasUI) ctx.ui.notify(stateNotice, \"warning\");\n // Recovery can restore managed files: finish it before Pi accepts user edits.\n // Unlike remote inspection, it must never be detached behind startup.\n const validateMutation = captureMutationOwner(ctx, signal);\n const currentFile = ctx.sessionManager.getSessionFile?.();\n await timings.measure(\"transaction recovery\", async () => {\n const pending = await pendingTransactionEntries();\n validateMutation();\n if (!pending.some((entry) => entry.isDirectory())) return;\n // Normal startup needs only the directory probe, not the recovery/snapshot graph.\n const { recoverSnapshotTransactionsOnStartup } = await import(\"../snapshot/snapshot-transaction.js\");\n validateMutation();\n await recoverSnapshotTransactionsOnStartup({\n signal,\n sessionDir: sessionDirFromContext(ctx),\n protectedTargets: currentFile ? [currentFile] : [],\n validateMutation,\n });\n });\n throwIfAborted(signal);\n try {\n const settings = await timings.measure(\"settings read\", () => readLocalConfigObject());\n throwIfAborted(signal);\n debug = settings?.debug ?? false;\n const names = settings ? Object.keys(settings.syncSetups).sort((left, right) => left.localeCompare(right)) : [];\n setSyncSetupCompletions(names);\n configureSyncStatus(ctx, settings?.showStatus ?? true);\n } catch {\n if (signal.aborted) return;\n setSyncSetupCompletions([]);\n }\n const migrationNotice = consumeLocalConfigMigrationNotice();\n if (migrationNotice && ctx.hasUI) ctx.ui.notify(migrationNotice, \"warning\");\n throwIfAborted(signal);\n if (!ctx.hasUI) return { debug };\n try {\n const config = await timings.measure(\"config resolution\", () => loadConfig());\n throwIfAborted(signal);\n configureSyncStatus(ctx, config.showStatus);\n outcome = \"completed\";\n return { debug, config };\n } catch (error) {\n throwIfAborted(signal);\n if (!isMissingConfigError(error)) {\n ctx.ui.notify(`pi-sync startup check skipped: ${safeTerminalText(errorMessage(error))}`, \"warning\");\n }\n }\n return { debug };\n } finally {\n timings.publish(ctx, debug, signal, \"local initialization\", outcome);\n }\n}\n\nexport async function autoPushSessions(ctx: ExtensionContext, signal: AbortSignal, loaders: SyncLoaders) {\n try {\n const partial = await loadPartialConfig();\n throwIfAborted(signal);\n if (!partial.automatic) return;\n if (!partial.include.includes(\"sessions\")) return;\n await ensureStateDir();\n throwIfAborted(signal);\n const config = await loadConfig();\n throwIfAborted(signal);\n if (!config.include.includes(\"sessions\")) return;\n const [operations, snapshotModule, syncStateModule] = await Promise.all([\n loaders.operations(),\n loaders.snapshot(),\n loaders.syncState(),\n ]);\n throwIfAborted(signal);\n await withLock(\"auto-session-push\", async () => {\n throwIfAborted(signal);\n const state = await readStateForConfig(config);\n throwIfAborted(signal);\n const local = await snapshotModule.createSnapshot(config.snapshotIdentity, {\n ...snapshotOptionsForContext(ctx, config),\n signal,\n });\n throwIfAborted(signal);\n if (!syncStateModule.hasLocalChanges(local, state, config)) return;\n await operations.push(ctx, { ...AUTO_SYNC_OPTIONS, signal }, { config, state, local });\n });\n } catch (error) {\n if (signal.aborted || isMissingConfigError(error)) return;\n setSyncStatus(ctx, undefined);\n ctx.ui.notify(`pi-sync session push skipped: ${errorMessage(error)}`, \"warning\");\n }\n}\n", "import type { ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { loadConfigForCheck, syncCheckConfigFingerprint } from \"../settings/config.js\";\nimport { isMissingConfigError } from \"../settings/config-errors.js\";\nimport type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport { snapshotOptionsForContext } from \"../snapshot/session-paths.js\";\nimport { withLock } from \"../state/lock.js\";\nimport { withStateDirectoryAccess } from \"../state/state-directory.js\";\nimport { readStateForConfig, syncStateFingerprint } from \"../state/sync-state-store.js\";\nimport type { SyncAttentionController } from \"../ui/sync-attention.js\";\nimport { setSyncStatus } from \"../ui/sync-status.js\";\nimport { safeTerminalText } from \"../ui/terminal-text.js\";\nimport { startupTransferEnabled } from \"./agent-policy.js\";\nimport { combineSignals, throwIfAborted } from \"./signals.js\";\nimport { createStartupTimings, type StartupTimingPublisher } from \"./startup-timings.js\";\nimport { errorMessage } from \"./sync-errors.js\";\nimport type { SyncLoaders } from \"./sync-loaders.js\";\n\n/** One owned task per extension session, never keyed by the shared headless UI. */\nexport function createStartupCheck(\n loaders: SyncLoaders,\n attention: SyncAttentionController,\n timeoutMs = 30_000,\n publish?: StartupTimingPublisher,\n) {\n let active:\n | {\n controller: AbortController;\n promise: Promise<void>;\n owner: ExtensionContext[\"sessionManager\"];\n transfer: boolean;\n }\n | undefined;\n\n let pending: { ctx: ExtensionContext; signal: AbortSignal; config: AnySyncConfig } | undefined;\n\n const controllerApi = {\n async interrupt(ctx: ExtensionContext) {\n const task = active;\n if (!task?.transfer || task.owner !== ctx.sessionManager) return;\n task.controller.abort(new DOMException(\"Agent became busy\", \"AbortError\"));\n await task.promise;\n },\n settled(ctx: ExtensionContext) {\n const queued = pending;\n if (!queued || queued.ctx.sessionManager !== ctx.sessionManager || queued.signal.aborted || !ctx.isIdle()) return;\n pending = undefined;\n controllerApi.start(ctx, queued.signal, queued.config);\n },\n start(ctx: ExtensionContext, sessionSignal: AbortSignal, initialConfig?: AnySyncConfig) {\n if (!ctx.hasUI || sessionSignal.aborted) return;\n if (initialConfig && startupTransferEnabled(initialConfig) && !ctx.isIdle()) {\n pending = { ctx, signal: sessionSignal, config: initialConfig };\n return;\n }\n if (active) throw new Error(\"Previous startup check has not been drained.\");\n const timings = createStartupTimings(publish);\n const controller = new AbortController();\n const signal = combineSignals(sessionSignal, controller.signal);\n const task = {\n controller,\n owner: ctx.sessionManager,\n promise: Promise.resolve(),\n transfer: Boolean(initialConfig && startupTransferEnabled(initialConfig)),\n };\n active = task;\n const isCurrent = () => !sessionSignal.aborted && active === task && task.owner === ctx.sessionManager;\n const timer = setTimeout(\n () => controller.abort(new DOMException(\"Startup check timed out\", \"TimeoutError\")),\n timeoutMs,\n );\n timer.unref();\n let config: AnySyncConfig | undefined;\n let checking = false;\n let stopped = false;\n // Handle every detached rejection here; Pi's awaited event runner cannot catch it.\n task.promise = Promise.resolve()\n .then(async () => {\n try {\n throwIfAborted(signal);\n config = initialConfig ?? (await loadConfigForCheck());\n task.transfer = startupTransferEnabled(config);\n throwIfAborted(signal);\n if (!config.automatic && !startupTransferEnabled(config)) return;\n const captured = config;\n const identity = syncCheckConfigFingerprint(captured);\n checking = true;\n setSyncStatus(ctx, \"sync ...\");\n const { inspectSync } = await timings.measure(\"inspection import\", () => loaders.inspection());\n throwIfAborted(signal);\n const currentConfig = await loadConfigForCheck();\n throwIfAborted(signal);\n if (syncCheckConfigFingerprint(currentConfig) !== identity) return;\n // Lock order: state migration guard \u2192 sync operation \u2192 backend cache.\n // Read heads may write only private cache data. Never call doctor/syncBoth.\n const inspection = await timings.measure(\"inspection and guards\", () =>\n withStateDirectoryAccess(() => {\n throwIfAborted(signal);\n return withLock(\"startup-check\", () => {\n throwIfAborted(signal);\n return inspectSync(captured, snapshotOptionsForContext(ctx, captured), signal, undefined, timings);\n });\n }),\n );\n throwIfAborted(signal);\n const latest = await loadConfigForCheck();\n throwIfAborted(signal);\n if (syncCheckConfigFingerprint(latest) !== identity) return;\n const state = await withStateDirectoryAccess(() => readStateForConfig(latest));\n throwIfAborted(signal);\n if (syncStateFingerprint(state) !== inspection.stateIdentity || !isCurrent()) return;\n attention.observe({\n setupName: captured.setupName,\n configIdentity: identity,\n checkedAt: new Date().toISOString(),\n inspection,\n automaticTransfer: startupTransferEnabled(captured),\n });\n if (\n startupTransferEnabled(captured) &&\n !inspection.firstSync &&\n inspection.head &&\n inspection.selectionState?.kind === \"same\"\n ) {\n const [operations, { withAgentSyncLock }] = await timings.measure(\"operations import\", () =>\n Promise.all([loaders.operations(), import(\"./agent-sync.js\")]),\n );\n throwIfAborted(signal);\n if (!isCurrent()) return;\n if (!ctx.isIdle()) {\n pending = { ctx, signal: sessionSignal, config: captured };\n return;\n }\n await timings.measure(\"automatic transfer\", () =>\n withStateDirectoryAccess(() =>\n withAgentSyncLock(\n ctx,\n {\n args: [],\n yes: true,\n force: false,\n stale: false,\n silent: true,\n reload: false,\n auto: true,\n signal,\n startupTimings: timings,\n onCommit: () => attention.clearObservation(),\n },\n (options) => operations.syncBoth(ctx, options),\n ),\n ),\n );\n throwIfAborted(signal);\n if (!isCurrent()) return;\n attention.clearObservation();\n return;\n }\n attention.observe({\n setupName: captured.setupName,\n configIdentity: identity,\n checkedAt: new Date().toISOString(),\n inspection,\n automaticTransfer: startupTransferEnabled(captured),\n });\n if (ctx.mode === \"rpc\") attention.notifyObservation(ctx);\n } catch (error) {\n stopped = true;\n if (!isCurrent() || sessionSignal.aborted || isMissingConfigError(error)) return;\n if (signal.aborted && controller.signal.reason?.name !== \"TimeoutError\") return;\n // A settings edit invalidates failures as well as successful observations.\n if (config) {\n const latest = await loadConfigForCheck().catch(() => undefined);\n if (!isCurrent() || (signal.aborted && controller.signal.reason?.name !== \"TimeoutError\")) return;\n if (!latest || syncCheckConfigFingerprint(latest) !== syncCheckConfigFingerprint(config)) return;\n }\n ctx.ui.notify(\n config && startupTransferEnabled(config)\n ? `pi-sync automatic transfer stopped: ${safeTerminalText(errorMessage(error))}. Run /sync to review or reconcile retained recovery evidence. No resources were reloaded.`\n : `pi-sync startup check skipped: ${safeTerminalText(errorMessage(error))}. Run /sync status to retry. No startup transfer was performed.`,\n \"warning\",\n );\n } finally {\n clearTimeout(timer);\n if (isCurrent() && checking) {\n if (!signal.aborted || controller.signal.reason?.name === \"TimeoutError\") {\n const latest = await loadConfigForCheck().catch(() => undefined);\n if (isCurrent()) {\n if (signal.aborted && controller.signal.reason?.name !== \"TimeoutError\")\n setSyncStatus(ctx, undefined);\n else if (\n config &&\n latest &&\n syncCheckConfigFingerprint(latest) === syncCheckConfigFingerprint(config)\n )\n await attention.publish(ctx, sessionSignal);\n else attention.reset(ctx);\n }\n } else setSyncStatus(ctx, undefined);\n }\n if (isCurrent()) {\n timings.publish(\n ctx,\n config?.debug ?? false,\n sessionSignal,\n \"background startup\",\n signal.aborted || stopped ? \"stopped\" : \"completed\",\n );\n }\n if (active === task) active = undefined;\n }\n })\n .catch(() => {\n // UI teardown can itself throw. No unhandled rejection or retained timer.\n clearTimeout(timer);\n if (active === task) active = undefined;\n });\n },\n async stop() {\n pending = undefined;\n const task = active;\n if (!task) return;\n task.controller.abort(new DOMException(\"Startup check cancelled\", \"AbortError\"));\n // Drain the actual work, including child/ref cleanup, before foreground guards.\n await task.promise;\n },\n };\n return controllerApi;\n}\n", "type SetupSwitchModule = Pick<typeof import(\"./setup-switch.js\"), \"useSyncSetup\">;\ntype SnapshotModule = Pick<typeof import(\"../snapshot/snapshot.js\"), \"createSnapshot\">;\ntype SyncStateModule = Pick<typeof import(\"./sync-state.js\"), \"hasLocalChanges\">;\ntype SyncOperations = typeof import(\"./sync-operations.js\");\ntype CommandHandlerModule = Pick<typeof import(\"../commands/command-handler.js\"), \"handleCommand\">;\n\ntype SyncInspectionModule = Pick<typeof import(\"./sync-inspection.js\"), \"inspectSync\">;\n\nexport interface SyncDependencies {\n loadCommandHandler(): Promise<CommandHandlerModule>;\n loadSyncInspection(): Promise<SyncInspectionModule>;\n loadSetupSwitch(): Promise<SetupSwitchModule>;\n loadSnapshot(): Promise<SnapshotModule>;\n loadSyncState(): Promise<SyncStateModule>;\n loadSyncOperations(): Promise<SyncOperations>;\n}\n\nexport interface SyncLoaders {\n commands(): Promise<CommandHandlerModule>;\n inspection(): Promise<SyncInspectionModule>;\n setupSwitch(): Promise<SetupSwitchModule>;\n snapshot(): Promise<SnapshotModule>;\n syncState(): Promise<SyncStateModule>;\n operations(): Promise<SyncOperations>;\n}\n\nexport function createSyncLoaders(dependencies: Partial<SyncDependencies>): SyncLoaders {\n const loaders: SyncLoaders = {\n commands: cachedModuleLoader(dependencies.loadCommandHandler ?? (() => import(\"../commands/command-handler.js\"))),\n inspection: cachedModuleLoader(dependencies.loadSyncInspection ?? (() => import(\"./sync-inspection.js\"))),\n setupSwitch: cachedModuleLoader(dependencies.loadSetupSwitch ?? (() => import(\"./setup-switch.js\"))),\n snapshot: cachedModuleLoader(dependencies.loadSnapshot ?? (() => import(\"../snapshot/snapshot.js\"))),\n syncState: cachedModuleLoader(dependencies.loadSyncState ?? (() => import(\"./sync-state.js\"))),\n operations: cachedModuleLoader(dependencies.loadSyncOperations ?? (() => import(\"./sync-operations.js\"))),\n };\n return loaders;\n}\n\nfunction cachedModuleLoader<Module>(load: () => Promise<Module>): () => Promise<Module> {\n let pending: Promise<Module> | undefined;\n return () => {\n if (!pending) {\n pending = load().catch((error) => {\n pending = undefined;\n throw error;\n });\n }\n return pending;\n };\n}\n", "import type { ExtensionAPI } from \"@earendil-works/pi-coding-agent\";\nimport { Text, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport type { StartupTimingPublisher } from \"../sync/startup-timings.js\";\nimport { safeTerminalText } from \"./terminal-text.js\";\n\nexport const STARTUP_TIMING_ENTRY = \"pi-sync-startup-timings\";\n\nexport interface StartupTimingEntry {\n version: 1;\n report: string;\n}\n\nexport function registerStartupTimings(pi: ExtensionAPI): StartupTimingPublisher {\n pi.registerEntryRenderer<StartupTimingEntry>(STARTUP_TIMING_ENTRY, (entry, _options, theme) => {\n const data = entry.data;\n if (data?.version !== 1 || typeof data.report !== \"string\") return undefined;\n const text = new Text(\n data.report\n .split(\"\\n\")\n .map((line, index) => theme.fg(index === 0 ? \"accent\" : \"muted\", safeTerminalText(line)))\n .join(\"\\n\"),\n 0,\n 0,\n );\n return {\n render: (width) => (width > 0 ? text.render(width).map((line) => truncateToWidth(line, width)) : []),\n invalidate: () => text.invalidate(),\n };\n });\n return (ctx, report) => {\n // Pi coalesces consecutive info notifications, including the final /reload notice.\n // Custom entries remain visible without adding messages to model context.\n if (ctx.mode === \"tui\") pi.appendEntry<StartupTimingEntry>(STARTUP_TIMING_ENTRY, { version: 1, report });\n else ctx.ui.notify(report, \"info\");\n };\n}\n", "import type { ExtensionAPI, ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { completeSyncArguments, splitArgs } from \"./commands/command.js\";\nimport type { AnySyncConfig } from \"./settings/settings-types.js\";\nimport { withStateDirectoryAccess } from \"./state/state-directory.js\";\nimport { startupTransferEnabled } from \"./sync/agent-policy.js\";\nimport { autoPushSessions, startSession } from \"./sync/automatic-sync.js\";\nimport { combineSignals } from \"./sync/signals.js\";\nimport { createStartupCheck } from \"./sync/startup-check.js\";\nimport { errorMessage } from \"./sync/sync-errors.js\";\nimport { createSyncLoaders, type SyncDependencies } from \"./sync/sync-loaders.js\";\nimport { registerStartupTimings } from \"./ui/startup-timings-entry.js\";\nimport { createSyncAttentionController } from \"./ui/sync-attention.js\";\nimport { setSyncStatus } from \"./ui/sync-status.js\";\nimport { safeTerminalText } from \"./ui/terminal-text.js\";\n\nexport default function sync(pi: ExtensionAPI, dependencies: Partial<SyncDependencies> = {}) {\n const loaders = createSyncLoaders(dependencies);\n const attention = createSyncAttentionController();\n const publishTimings = registerStartupTimings(pi);\n const check = createStartupCheck(loaders, attention, 30_000, publishTimings);\n let sessionAbort = new AbortController();\n let shutdownAbort: AbortController | undefined;\n let initialization = Promise.resolve<AnySyncConfig | false | undefined>(undefined);\n let continuous: ReturnType<typeof import(\"./sync/continuous-sync.js\")[\"createContinuousSync\"]> | undefined;\n let owner: ExtensionContext[\"sessionManager\"] | undefined;\n let continuousPossible = false;\n let startupDebug = false;\n const foreground = new Map<ExtensionContext[\"sessionManager\"], number>();\n async function resumeContinuous(ctx: ExtensionContext, signal: AbortSignal, retry?: { setup?: string }) {\n const isCurrent = () => !signal.aborted && !foreground.has(ctx.sessionManager) && owner === ctx.sessionManager;\n if (!isCurrent() || !ctx.hasUI) return;\n try {\n const { loadConfigForCheck } = await import(\"./settings/config.js\");\n if (!isCurrent()) return;\n const config = await loadConfigForCheck();\n if (!isCurrent()) return;\n continuousPossible = Boolean(config.continuous && config.agentMode);\n if (!continuousPossible) {\n await continuous?.stop(ctx.sessionManager);\n return;\n }\n const { createContinuousSync } = await import(\"./sync/continuous-sync.js\");\n if (!isCurrent()) return;\n continuous ??= createContinuousSync(loaders, undefined, publishTimings);\n continuous.start(\n ctx,\n signal,\n Boolean(retry && (retry.setup === undefined || retry.setup === config.setupName)),\n startupDebug,\n );\n } catch {\n /* Existing initialization/command paths report settings errors. */\n }\n }\n\n pi.registerCommand(\"sync\", {\n description: \"Sync Pi settings through Git, WebDAV, R2, or S3-compatible storage\",\n getArgumentCompletions: completeSyncArguments,\n handler: async (args, ctx) => {\n if (!ctx.hasUI) {\n throw new Error(\"/sync requires TUI or RPC mode so results and safety prompts are observable.\");\n }\n const signal = sessionAbort.signal;\n const manager = ctx.sessionManager;\n const command = splitArgs(args)[0];\n let retry: { setup?: string } | undefined;\n let mayResume = false;\n foreground.set(manager, (foreground.get(manager) ?? 0) + 1);\n try {\n const ready = await initialization;\n mayResume = ready !== false;\n if (signal.aborted) return;\n await continuous?.stop(manager);\n if (signal.aborted) return;\n await check.stop();\n if (signal.aborted) return;\n if (ready === false && command !== \"help\" && command !== \"unlock\" && command !== \"migrate-state\") {\n ctx.ui.notify(\n \"pi-sync recovery required. Repair the startup error, then /reload before syncing. Use /sync help for recovery guidance.\",\n \"error\",\n );\n return;\n }\n const commands = await loaders.commands().catch((error) => {\n if (!signal.aborted) {\n ctx.ui.notify(`pi-sync command unavailable: ${safeTerminalText(errorMessage(error))}`, \"error\");\n }\n });\n if (signal.aborted || !commands) return;\n const run = () =>\n commands.handleCommand(args, ctx, signal, loaders, attention, (setup) => {\n retry = { setup };\n });\n // Drain background children before foreground guards. Help remains reachable during repair.\n if (command === \"migrate-state\" || command === \"help\") await run();\n else await withStateDirectoryAccess(run);\n } finally {\n const count = (foreground.get(manager) ?? 1) - 1;\n if (count) foreground.set(manager, count);\n else foreground.delete(manager);\n if (mayResume) await resumeContinuous(ctx, signal, retry);\n }\n },\n });\n\n pi.on(\"session_start\", async (_event, ctx) => {\n shutdownAbort?.abort(new DOMException(\"Session replaced\", \"AbortError\"));\n shutdownAbort = undefined;\n sessionAbort.abort(new DOMException(\"Session replaced\", \"AbortError\"));\n sessionAbort = new AbortController();\n const signal = sessionAbort.signal;\n owner = ctx.sessionManager;\n continuousPossible = false;\n startupDebug = false;\n attention.reset(ctx);\n const previous = initialization;\n initialization = (async () => {\n await previous;\n if (signal.aborted) return false;\n await continuous?.stop();\n if (signal.aborted) return false;\n await check.stop();\n if (signal.aborted) return false;\n try {\n const startup = await withStateDirectoryAccess(() => startSession(ctx, signal, publishTimings));\n if (signal.aborted) return false;\n startupDebug = startup?.debug ?? false;\n return startup?.config;\n } catch (error) {\n if (!signal.aborted && ctx.hasUI) {\n ctx.ui.notify(`pi-sync recovery required: ${safeTerminalText(errorMessage(error))}`, \"error\");\n }\n return false;\n }\n })();\n const ready = await initialization;\n if (ready && !signal.aborted) {\n if (ready.continuous && ready.agentMode) await resumeContinuous(ctx, signal);\n else if (ready.automatic || startupTransferEnabled(ready)) check.start(ctx, signal, ready);\n }\n });\n\n pi.on(\"agent_start\", async (_event, ctx) => {\n await continuous?.stop(ctx.sessionManager);\n await check.interrupt(ctx);\n });\n\n pi.on(\"agent_settled\", async (_event, ctx) => {\n const signal = sessionAbort.signal;\n if (!signal.aborted) {\n check.settled(ctx);\n if (continuousPossible) await resumeContinuous(ctx, signal);\n }\n });\n\n pi.on(\"session_shutdown\", async (event, ctx) => {\n if (continuous && owner && owner !== ctx.sessionManager) return;\n sessionAbort.abort(new DOMException(\"Session shut down\", \"AbortError\"));\n attention.reset(ctx);\n shutdownAbort?.abort(new DOMException(\"Session shut down again\", \"AbortError\"));\n const controller = new AbortController();\n shutdownAbort = controller;\n const signal = combineSignals(controller.signal, AbortSignal.timeout(30_000));\n const reason = typeof event === \"object\" && event ? (event as { reason?: string }).reason : undefined;\n try {\n const ready = await initialization;\n if (signal.aborted) return;\n await continuous?.stop(ctx.sessionManager);\n if (signal.aborted) return;\n await check.stop();\n if (signal.aborted) return;\n if (ready !== false && reason !== \"reload\") {\n await withStateDirectoryAccess(async () => {\n if (signal.aborted) return;\n await autoPushSessions(ctx, signal, loaders);\n });\n }\n } catch (error) {\n if (!signal.aborted) {\n ctx.ui.notify(`pi-sync session push skipped: ${errorMessage(error)}`, \"warning\");\n }\n } finally {\n if (shutdownAbort === controller) shutdownAbort = undefined;\n }\n if (signal.aborted) return;\n setSyncStatus(ctx, undefined);\n });\n}\n\nexport type { SyncDependencies } from \"./sync/sync-loaders.js\";\n"],
5
+ "mappings": "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",
6
6
  "names": ["loadConfigForCheck"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@narumitw/pi-sync",
3
- "version": "0.57.8",
3
+ "version": "0.57.10",
4
4
  "description": "Pi extension that syncs Pi configuration through Git, WebDAV, Cloudflare R2, or S3-compatible storage.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -27,6 +27,7 @@
27
27
  "docs",
28
28
  "skills",
29
29
  "README.md",
30
+ "CHANGELOG.md",
30
31
  "LICENSE"
31
32
  ],
32
33
  "pi": {
@@ -45,14 +46,14 @@
45
46
  "typecheck": "tsc --noEmit"
46
47
  },
47
48
  "dependencies": {
48
- "@narumitw/pi-tui-kit": "^0.68.1",
49
+ "@narumitw/pi-tui-kit": "^0.69.1",
49
50
  "fast-xml-parser": "^5.11.2",
50
51
  "proper-lockfile": "^4.1.2",
51
52
  "semver": "^7.8.5"
52
53
  },
53
54
  "devDependencies": {
54
- "@earendil-works/pi-coding-agent": "1.4.0",
55
- "@earendil-works/pi-tui": "1.4.0",
55
+ "@earendil-works/pi-coding-agent": "1.5.0",
56
+ "@earendil-works/pi-tui": "1.5.0",
56
57
  "@types/proper-lockfile": "^4.1.4",
57
58
  "@types/semver": "^7.8.0",
58
59
  "esbuild": "0.28.2",
@@ -2,7 +2,7 @@ import { createHash } from "node:crypto";
2
2
  import { backendIdentityCoordinates } from "../backends/backend-identity.js";
3
3
  import { normalizeGitBranch, normalizeGitDirectory, normalizeGitRemote } from "../backends/git/git-config.js";
4
4
  import { normalizeWebDavPath, normalizeWebDavUrl } from "../backends/webdav/webdav-config.js";
5
- import { normalizeLocalFields } from "../sync/local-fields.js";
5
+ import { normalizeLocalFields } from "../sync/local-field-policy.js";
6
6
  import { normalizeSyncInclude } from "../sync/sync-policy.js";
7
7
  import { localConfigPath, readActiveLocalConfigDocumentForRepair } from "./config-file.js";
8
8
  import { requireSettings } from "./settings-store.js";
@@ -12,7 +12,7 @@ import {
12
12
  normalizeWebDavUrl,
13
13
  validateWebDavCredentials,
14
14
  } from "../backends/webdav/webdav-config.js";
15
- import { normalizeLocalFields } from "../sync/local-fields.js";
15
+ import { normalizeLocalFields } from "../sync/local-field-policy.js";
16
16
  import { normalizeSyncInclude } from "../sync/sync-policy.js";
17
17
  import { localConfigPath } from "./config-file.js";
18
18
  import type {
@@ -0,0 +1,16 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { stateDir } from "../state/state-directory.js";
4
+
5
+ export function transactionRoot() {
6
+ return path.join(stateDir(), "transactions");
7
+ }
8
+
9
+ export async function pendingTransactionEntries() {
10
+ try {
11
+ return await fs.readdir(transactionRoot(), { withFileTypes: true });
12
+ } catch (error) {
13
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return [];
14
+ throw error;
15
+ }
16
+ }
@@ -18,6 +18,7 @@ import {
18
18
  type SessionRootTransition,
19
19
  validateSessionRootTransition,
20
20
  } from "./snapshot-root-transition.js";
21
+ import { pendingTransactionEntries, transactionRoot } from "./snapshot-transaction-directory.js";
21
22
  import { fileImage, indexTransactionPlan } from "./snapshot-transaction-plan.js";
22
23
  import type { SnapshotApplyPlan } from "./snapshot-types.js";
23
24
 
@@ -290,15 +291,6 @@ export async function recoverPendingSnapshotTransactions(options: TransactionOpt
290
291
  }
291
292
  }
292
293
 
293
- async function pendingTransactionEntries() {
294
- try {
295
- return await fs.readdir(transactionRoot(), { withFileTypes: true });
296
- } catch (error) {
297
- if ((error as NodeJS.ErrnoException).code === "ENOENT") return [];
298
- throw error;
299
- }
300
- }
301
-
302
294
  async function prepareTransaction(
303
295
  plan: SnapshotApplyPlan,
304
296
  targets: string[],
@@ -943,6 +935,3 @@ async function removeTransaction(directory: string) {
943
935
  // was established before cleanup; a surviving completed journal allows only cleanup.
944
936
  await syncDirectory(transactionRoot()).catch(() => {});
945
937
  }
946
- function transactionRoot() {
947
- return path.join(stateDir(), "transactions");
948
- }
@@ -7,17 +7,17 @@ import { consumeLocalConfigMigrationNotice } from "../settings/config-file.js";
7
7
  import { readLocalConfigObject } from "../settings/settings-store.js";
8
8
  import type { AnySyncConfig } from "../settings/settings-types.js";
9
9
  import { sessionDirFromContext, snapshotOptionsForContext } from "../snapshot/session-paths.js";
10
- import { recoverSnapshotTransactionsOnStartup } from "../snapshot/snapshot-transaction.js";
10
+ import { pendingTransactionEntries } from "../snapshot/snapshot-transaction-directory.js";
11
11
  import { withLock } from "../state/lock.js";
12
12
  import { stateDirectoryMigrationNotice } from "../state/state-directory.js";
13
13
  import { ensureStateDir, readStateForConfig } from "../state/sync-state-store.js";
14
14
  import { configureSyncStatus, setSyncStatus } from "../ui/sync-status.js";
15
15
  import { safeTerminalText } from "../ui/terminal-text.js";
16
+ import { captureMutationOwner } from "./mutation-owner.js";
16
17
  import { throwIfAborted } from "./signals.js";
17
18
  import { createStartupTimings, type StartupTimingPublisher } from "./startup-timings.js";
18
19
  import { errorMessage } from "./sync-errors.js";
19
20
  import type { SyncLoaders } from "./sync-loaders.js";
20
- import { captureMutationOwner } from "./sync-local.js";
21
21
 
22
22
  const AUTO_SYNC_OPTIONS: CommandOptions = {
23
23
  yes: true,
@@ -45,14 +45,20 @@ export async function startSession(
45
45
  // Unlike remote inspection, it must never be detached behind startup.
46
46
  const validateMutation = captureMutationOwner(ctx, signal);
47
47
  const currentFile = ctx.sessionManager.getSessionFile?.();
48
- await timings.measure("transaction recovery", () =>
49
- recoverSnapshotTransactionsOnStartup({
48
+ await timings.measure("transaction recovery", async () => {
49
+ const pending = await pendingTransactionEntries();
50
+ validateMutation();
51
+ if (!pending.some((entry) => entry.isDirectory())) return;
52
+ // Normal startup needs only the directory probe, not the recovery/snapshot graph.
53
+ const { recoverSnapshotTransactionsOnStartup } = await import("../snapshot/snapshot-transaction.js");
54
+ validateMutation();
55
+ await recoverSnapshotTransactionsOnStartup({
50
56
  signal,
51
57
  sessionDir: sessionDirFromContext(ctx),
52
58
  protectedTargets: currentFile ? [currentFile] : [],
53
59
  validateMutation,
54
- }),
55
- );
60
+ });
61
+ });
56
62
  throwIfAborted(signal);
57
63
  try {
58
64
  const settings = await timings.measure("settings read", () => readLocalConfigObject());
@@ -0,0 +1,29 @@
1
+ /** Initial rules select whole root fields of the global settings.json only. */
2
+ export function normalizeLocalFields(value: unknown): string[] {
3
+ if (value === undefined) return [];
4
+ if (
5
+ !Array.isArray(value) ||
6
+ value.length > 128 ||
7
+ value.some(
8
+ (field) =>
9
+ typeof field !== "string" ||
10
+ !field ||
11
+ field.length > 128 ||
12
+ /[\p{Cc}\p{Cf}\p{Cs}]/u.test(field) ||
13
+ ["__proto__", "constructor", "prototype"].includes(field),
14
+ )
15
+ )
16
+ throw new Error("localFields must be at most 128 safe settings.json root field names.");
17
+ if (new Set(value).size !== value.length) throw new Error("Duplicate localFields rule.");
18
+ for (const [first, second] of [
19
+ ["defaultProvider", "defaultModel"],
20
+ ["skills", "enableSkillCommands"],
21
+ ["queueMode", "steeringMode"],
22
+ ["websockets", "transport"],
23
+ ["enableAnalytics", "trackingId"],
24
+ ]) {
25
+ if (value.includes(first) !== value.includes(second))
26
+ throw new Error("Coupled settings fields must be excluded together.");
27
+ }
28
+ return [...value].sort();
29
+ }
@@ -8,36 +8,10 @@ import {
8
8
  parseSettingsDocument,
9
9
  renderSettingsMembers,
10
10
  } from "./json-document.js";
11
+ import { normalizeLocalFields } from "./local-field-policy.js";
12
+
13
+ export { normalizeLocalFields } from "./local-field-policy.js";
11
14
 
12
- /** Initial rules select whole root fields of the global settings.json only. */
13
- export function normalizeLocalFields(value: unknown): string[] {
14
- if (value === undefined) return [];
15
- if (
16
- !Array.isArray(value) ||
17
- value.length > 128 ||
18
- value.some(
19
- (field) =>
20
- typeof field !== "string" ||
21
- !field ||
22
- field.length > 128 ||
23
- /[\p{Cc}\p{Cf}\p{Cs}]/u.test(field) ||
24
- ["__proto__", "constructor", "prototype"].includes(field),
25
- )
26
- )
27
- throw new Error("localFields must be at most 128 safe settings.json root field names.");
28
- if (new Set(value).size !== value.length) throw new Error("Duplicate localFields rule.");
29
- for (const [first, second] of [
30
- ["defaultProvider", "defaultModel"],
31
- ["skills", "enableSkillCommands"],
32
- ["queueMode", "steeringMode"],
33
- ["websockets", "transport"],
34
- ["enableAnalytics", "trackingId"],
35
- ]) {
36
- if (value.includes(first) !== value.includes(second))
37
- throw new Error("Coupled settings fields must be excluded together.");
38
- }
39
- return [...value].sort();
40
- }
41
15
  /** Shared transport contract: older snapshots cannot carry portable policy metadata. */
42
16
  export function validateSnapshotFieldPolicy(snapshot: Pick<Snapshot, "version" | "localFields">) {
43
17
  if (snapshot.version !== 1 && snapshot.version !== 2 && snapshot.version !== 3)
@@ -0,0 +1,22 @@
1
+ import type { ExtensionCommandContext, ExtensionContext } from "@earendil-works/pi-coding-agent";
2
+ import { agentDir } from "../snapshot/session-paths.js";
3
+ import { throwIfAborted } from "./signals.js";
4
+
5
+ export function captureMutationOwner(ctx: ExtensionContext | ExtensionCommandContext, signal?: AbortSignal) {
6
+ const manager = ctx.sessionManager;
7
+ const file = manager.getSessionFile?.();
8
+ const id = manager.getSessionId?.();
9
+ const cwd = manager.getCwd?.();
10
+ const root = agentDir();
11
+ return () => {
12
+ throwIfAborted(signal);
13
+ if (
14
+ ctx.sessionManager !== manager ||
15
+ manager.getSessionFile?.() !== file ||
16
+ manager.getSessionId?.() !== id ||
17
+ manager.getCwd?.() !== cwd ||
18
+ agentDir() !== root
19
+ )
20
+ throw new Error("Session changed during file mutation; evidence retained for review.");
21
+ };
22
+ }
@@ -10,7 +10,6 @@ import type { SyncAttentionController } from "../ui/sync-attention.js";
10
10
  import { setSyncStatus } from "../ui/sync-status.js";
11
11
  import { safeTerminalText } from "../ui/terminal-text.js";
12
12
  import { startupTransferEnabled } from "./agent-policy.js";
13
- import { withAgentSyncLock } from "./agent-sync.js";
14
13
  import { combineSignals, throwIfAborted } from "./signals.js";
15
14
  import { createStartupTimings, type StartupTimingPublisher } from "./startup-timings.js";
16
15
  import { errorMessage } from "./sync-errors.js";
@@ -122,7 +121,9 @@ export function createStartupCheck(
122
121
  inspection.head &&
123
122
  inspection.selectionState?.kind === "same"
124
123
  ) {
125
- const operations = await timings.measure("operations import", () => loaders.operations());
124
+ const [operations, { withAgentSyncLock }] = await timings.measure("operations import", () =>
125
+ Promise.all([loaders.operations(), import("./agent-sync.js")]),
126
+ );
126
127
  throwIfAborted(signal);
127
128
  if (!isCurrent()) return;
128
129
  if (!ctx.isIdle()) {
@@ -2,10 +2,12 @@ type SetupSwitchModule = Pick<typeof import("./setup-switch.js"), "useSyncSetup"
2
2
  type SnapshotModule = Pick<typeof import("../snapshot/snapshot.js"), "createSnapshot">;
3
3
  type SyncStateModule = Pick<typeof import("./sync-state.js"), "hasLocalChanges">;
4
4
  type SyncOperations = typeof import("./sync-operations.js");
5
+ type CommandHandlerModule = Pick<typeof import("../commands/command-handler.js"), "handleCommand">;
5
6
 
6
7
  type SyncInspectionModule = Pick<typeof import("./sync-inspection.js"), "inspectSync">;
7
8
 
8
9
  export interface SyncDependencies {
10
+ loadCommandHandler(): Promise<CommandHandlerModule>;
9
11
  loadSyncInspection(): Promise<SyncInspectionModule>;
10
12
  loadSetupSwitch(): Promise<SetupSwitchModule>;
11
13
  loadSnapshot(): Promise<SnapshotModule>;
@@ -14,6 +16,7 @@ export interface SyncDependencies {
14
16
  }
15
17
 
16
18
  export interface SyncLoaders {
19
+ commands(): Promise<CommandHandlerModule>;
17
20
  inspection(): Promise<SyncInspectionModule>;
18
21
  setupSwitch(): Promise<SetupSwitchModule>;
19
22
  snapshot(): Promise<SnapshotModule>;
@@ -23,6 +26,7 @@ export interface SyncLoaders {
23
26
 
24
27
  export function createSyncLoaders(dependencies: Partial<SyncDependencies>): SyncLoaders {
25
28
  const loaders: SyncLoaders = {
29
+ commands: cachedModuleLoader(dependencies.loadCommandHandler ?? (() => import("../commands/command-handler.js"))),
26
30
  inspection: cachedModuleLoader(dependencies.loadSyncInspection ?? (() => import("./sync-inspection.js"))),
27
31
  setupSwitch: cachedModuleLoader(dependencies.loadSetupSwitch ?? (() => import("./setup-switch.js"))),
28
32
  snapshot: cachedModuleLoader(dependencies.loadSnapshot ?? (() => import("../snapshot/snapshot.js"))),