@narumitw/pi-sync 0.54.2 → 0.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -15
- package/dist/chunks/agent-candidate-3JN6DJKT.ts +26 -0
- package/dist/chunks/agent-plan-QCUJWBP4.ts +99 -0
- package/dist/chunks/agent-plan-QCUJWBP4.ts.map +7 -0
- package/dist/chunks/agent-runner-E2JU2VZ6.ts +182 -0
- package/dist/chunks/agent-runner-E2JU2VZ6.ts.map +7 -0
- package/dist/chunks/agent-store-A3F6IYWZ.ts +152 -0
- package/dist/chunks/agent-store-A3F6IYWZ.ts.map +7 -0
- package/dist/chunks/chunk-5Q5SSKNG.ts +128 -0
- package/dist/chunks/chunk-5Q5SSKNG.ts.map +7 -0
- package/dist/chunks/chunk-5XZOC7FD.ts +215 -0
- package/dist/chunks/chunk-5XZOC7FD.ts.map +7 -0
- package/dist/chunks/{chunk-IJ6VV6FN.ts → chunk-AAEEHR7H.ts} +31 -87
- package/dist/chunks/chunk-AAEEHR7H.ts.map +7 -0
- package/dist/chunks/{chunk-CHSIAC4N.ts → chunk-B4QZBDBT.ts} +2 -2
- package/dist/chunks/{chunk-CL7BZRRQ.ts → chunk-CRKTAPSL.ts} +8 -8
- package/dist/chunks/chunk-DT7M4VQS.ts +69 -0
- package/dist/chunks/chunk-DT7M4VQS.ts.map +7 -0
- package/dist/chunks/chunk-ED3TYIVW.ts +229 -0
- package/dist/chunks/chunk-ED3TYIVW.ts.map +7 -0
- package/dist/chunks/{chunk-VHXBCEVF.ts → chunk-EUMINX7L.ts} +6 -6
- package/dist/chunks/chunk-FQOSHGJ7.ts +215 -0
- package/dist/chunks/chunk-FQOSHGJ7.ts.map +7 -0
- package/dist/chunks/chunk-GNH73BJ5.ts +153 -0
- package/dist/chunks/chunk-GNH73BJ5.ts.map +7 -0
- package/dist/chunks/{chunk-UQ3ALBIB.ts → chunk-GP5DU62N.ts} +8 -9
- package/dist/chunks/chunk-GP5DU62N.ts.map +7 -0
- package/dist/chunks/{chunk-5RZPINUQ.ts → chunk-GSNPASKB.ts} +2 -2
- package/dist/chunks/{chunk-QE7NZZWT.ts → chunk-IWZH5KYS.ts} +23 -7
- package/dist/chunks/chunk-IWZH5KYS.ts.map +7 -0
- package/dist/chunks/{chunk-5ZWQ33XL.ts → chunk-JJTARUSO.ts} +15 -14
- package/dist/chunks/chunk-JJTARUSO.ts.map +7 -0
- package/dist/chunks/{chunk-2DI6PDZV.ts → chunk-NLWS55B6.ts} +15 -2
- package/dist/chunks/chunk-NLWS55B6.ts.map +7 -0
- package/dist/chunks/{chunk-SDZCTCYQ.ts → chunk-OEWQVWLC.ts} +4 -4
- package/dist/chunks/{chunk-MYPSMJHJ.ts → chunk-OTZRCKYP.ts} +380 -510
- package/dist/chunks/chunk-OTZRCKYP.ts.map +7 -0
- package/dist/chunks/{chunk-WFKUKVCP.ts → chunk-OWBAZA6J.ts} +24 -12
- package/dist/chunks/chunk-OWBAZA6J.ts.map +7 -0
- package/dist/chunks/chunk-PRUEIIK7.ts +24 -0
- package/dist/chunks/chunk-PRUEIIK7.ts.map +7 -0
- package/dist/chunks/chunk-QGK445K7.ts +21 -0
- package/dist/chunks/chunk-QGK445K7.ts.map +7 -0
- package/dist/chunks/{chunk-3B4Z2SKV.ts → chunk-QO333NM4.ts} +49 -21
- package/dist/chunks/chunk-QO333NM4.ts.map +7 -0
- package/dist/chunks/{chunk-4SBTAVFL.ts → chunk-QSHMOL3I.ts} +22 -24
- package/dist/chunks/chunk-QSHMOL3I.ts.map +7 -0
- package/dist/chunks/chunk-S2FMH5FT.ts +97 -0
- package/dist/chunks/chunk-S2FMH5FT.ts.map +7 -0
- package/dist/chunks/{chunk-BVVP33U5.ts → chunk-SWRVXVFD.ts} +12 -9
- package/dist/chunks/chunk-SWRVXVFD.ts.map +7 -0
- package/dist/chunks/{chunk-ZX2Q6THB.ts → chunk-UBV24CG4.ts} +4 -5
- package/dist/chunks/chunk-UBV24CG4.ts.map +7 -0
- package/dist/chunks/chunk-UOHR7LRO.ts +70 -0
- package/dist/chunks/chunk-UOHR7LRO.ts.map +7 -0
- package/dist/chunks/{chunk-4QVPTIZB.ts → chunk-UPNVIUBN.ts} +3 -3
- package/dist/chunks/chunk-UZPMDLTL.ts +54 -0
- package/dist/chunks/chunk-UZPMDLTL.ts.map +7 -0
- package/dist/chunks/chunk-VJN7KU4J.ts +350 -0
- package/dist/chunks/chunk-VJN7KU4J.ts.map +7 -0
- package/dist/chunks/chunk-YHT4YTYG.ts +31 -0
- package/dist/chunks/chunk-YHT4YTYG.ts.map +7 -0
- package/dist/chunks/{chunk-V6VZ5TLG.ts → chunk-YK52VDXG.ts} +6 -5
- package/dist/chunks/chunk-YK52VDXG.ts.map +7 -0
- package/dist/chunks/config-KGIYTTXQ.ts +37 -0
- package/dist/chunks/{conflict-artifacts-BB2FZMIE.ts → conflict-artifacts-FXFIIBCB.ts} +8 -7
- package/dist/chunks/{conflict-review-4PLVLMRO.ts → conflict-review-6WIEQLXW.ts} +31 -24
- package/dist/chunks/{conflict-review-4PLVLMRO.ts.map → conflict-review-6WIEQLXW.ts.map} +1 -1
- package/dist/chunks/continuous-record-LFRVXQBD.ts +30 -0
- package/dist/chunks/continuous-sync-AWAAOXK2.ts +545 -0
- package/dist/chunks/continuous-sync-AWAAOXK2.ts.map +7 -0
- package/dist/chunks/{file-selection-WZX7HAY2.ts → file-selection-3JJYOVNR.ts} +5 -5
- package/dist/chunks/{git-backend-FD7AVSK6.ts → git-backend-KYDZ673X.ts} +28 -32
- package/dist/chunks/git-backend-KYDZ673X.ts.map +7 -0
- package/dist/chunks/{manager-result-dispatcher-6MQKFCWB.ts → manager-result-dispatcher-AGBBVDDS.ts} +10 -9
- package/dist/chunks/{manager-ui-IURS4WXY.ts → manager-ui-KRAW3NE2.ts} +464 -164
- package/dist/chunks/manager-ui-KRAW3NE2.ts.map +7 -0
- package/dist/chunks/{merge-baseline-store-EVQAAML6.ts → merge-baseline-store-RFCAH7KL.ts} +7 -5
- package/dist/chunks/{remote-selection-ui-6LJJ4IMQ.ts → remote-selection-ui-5725JDNC.ts} +9 -8
- package/dist/chunks/remote-selection-ui-5725JDNC.ts.map +7 -0
- package/dist/chunks/{s3-backend-AQGV6LFT.ts → s3-backend-Y7WSCLJI.ts} +38 -38
- package/dist/chunks/s3-backend-Y7WSCLJI.ts.map +7 -0
- package/dist/chunks/{setup-switch-KTUWL6DE.ts → setup-switch-E7PHKI6J.ts} +7 -6
- package/dist/chunks/setup-switch-E7PHKI6J.ts.map +7 -0
- package/dist/chunks/{setup-wizard-GSDPDFC4.ts → setup-wizard-65DROCIJ.ts} +14 -13
- package/dist/chunks/setup-wizard-65DROCIJ.ts.map +7 -0
- package/dist/chunks/{sync-inspection-K45QVLHB.ts → sync-inspection-XFJOAMJD.ts} +9 -8
- package/dist/chunks/sync-inspection-XFJOAMJD.ts.map +7 -0
- package/dist/chunks/{sync-operations-47OUX76C.ts → sync-operations-HDUDT5PD.ts} +188 -73
- package/dist/chunks/sync-operations-HDUDT5PD.ts.map +7 -0
- package/dist/chunks/{webdav-backend-TBILVEQK.ts → webdav-backend-6K26F6LT.ts} +39 -48
- package/dist/chunks/webdav-backend-6K26F6LT.ts.map +7 -0
- package/dist/index.ts +246 -131
- package/dist/index.ts.map +3 -3
- package/docs/agent-mode-verification.md +99 -0
- package/docs/continuous-sync-verification.md +87 -0
- package/docs/settings.md +131 -11
- package/docs/tui-contract.md +61 -0
- package/package.json +3 -2
- package/src/backends/git/git-backend.ts +1 -4
- package/src/backends/git/git-runner.ts +1 -5
- package/src/backends/s3/s3-backend.ts +3 -25
- package/src/backends/s3/s3-client.ts +14 -2
- package/src/backends/snapshot-pointer.ts +27 -0
- package/src/backends/webdav/webdav-backend.ts +3 -29
- package/src/backends/webdav/webdav-client.ts +11 -7
- package/src/commands/command-execution.ts +7 -3
- package/src/commands/command-handler.ts +15 -3
- package/src/commands/command-types.ts +10 -0
- package/src/commands/command.ts +4 -1
- package/src/settings/config.ts +20 -10
- package/src/settings/settings-store.ts +1 -34
- package/src/settings/settings-types.ts +10 -0
- package/src/settings/settings-validation.ts +4 -1
- package/src/snapshot/snapshot-codec.ts +1 -5
- package/src/state/lock.ts +13 -10
- package/src/state/merge-baseline-store.ts +19 -1
- package/src/state/state-directory.ts +8 -1
- package/src/sync/agent-candidate.ts +251 -0
- package/src/sync/agent-plan.ts +87 -0
- package/src/sync/agent-policy.ts +13 -0
- package/src/sync/agent-request.ts +17 -0
- package/src/sync/agent-runner.ts +188 -0
- package/src/sync/agent-store.ts +151 -0
- package/src/sync/agent-sync.ts +91 -0
- package/src/sync/apply-review.ts +63 -0
- package/src/sync/automatic-sync.ts +46 -33
- package/src/sync/continuous-errors.ts +85 -0
- package/src/sync/continuous-lease.ts +221 -0
- package/src/sync/continuous-record.ts +179 -0
- package/src/sync/continuous-storage.ts +55 -0
- package/src/sync/continuous-sync.ts +516 -0
- package/src/sync/continuous-watch.ts +59 -0
- package/src/sync/merged-sync.ts +268 -112
- package/src/sync/remote-snapshot.ts +2 -3
- package/src/sync/settings-merge.ts +19 -3
- package/src/sync/setup-switch.ts +1 -5
- package/src/sync/startup-check.ts +51 -29
- package/src/sync/startup-timings.ts +90 -0
- package/src/sync/sync-inspection.ts +16 -5
- package/src/sync/sync-mutations.ts +55 -28
- package/src/sync/sync-queries.ts +19 -3
- package/src/sync/text-merge.ts +3 -3
- package/src/sync-extension.ts +75 -19
- package/src/ui/agent-mode-setting.ts +91 -0
- package/src/ui/manager-state.ts +12 -6
- package/src/ui/manager-ui.ts +57 -7
- package/src/ui/merge-review.ts +3 -3
- package/src/ui/merged-sync-summary.ts +2 -18
- package/src/ui/remote-selection-ui.ts +5 -5
- package/src/ui/settings-frame.ts +55 -0
- package/src/ui/settings-ui.ts +223 -43
- package/src/ui/setup/s3-credentials-ui.ts +1 -5
- package/src/ui/setup/setup-name-ui.ts +2 -5
- package/src/ui/setup/setup-prompts.ts +4 -3
- package/src/ui/setup/setup-switcher.ts +2 -0
- package/src/ui/sync-behavior.ts +15 -0
- package/src/ui/sync-format.ts +69 -38
- package/src/ui/sync-setups-ui.ts +3 -5
- package/src/ui/transfer-changes.ts +33 -0
- package/src/ui/transfer-review.ts +27 -0
- package/dist/chunks/chunk-2DI6PDZV.ts.map +0 -7
- package/dist/chunks/chunk-3B4Z2SKV.ts.map +0 -7
- package/dist/chunks/chunk-4SBTAVFL.ts.map +0 -7
- package/dist/chunks/chunk-5ZWQ33XL.ts.map +0 -7
- package/dist/chunks/chunk-BVVP33U5.ts.map +0 -7
- package/dist/chunks/chunk-IJ6VV6FN.ts.map +0 -7
- package/dist/chunks/chunk-MYPSMJHJ.ts.map +0 -7
- package/dist/chunks/chunk-ORQRHEEO.ts +0 -362
- package/dist/chunks/chunk-ORQRHEEO.ts.map +0 -7
- package/dist/chunks/chunk-QE7NZZWT.ts.map +0 -7
- package/dist/chunks/chunk-UQ3ALBIB.ts.map +0 -7
- package/dist/chunks/chunk-V6VZ5TLG.ts.map +0 -7
- package/dist/chunks/chunk-WFKUKVCP.ts.map +0 -7
- package/dist/chunks/chunk-ZX2Q6THB.ts.map +0 -7
- package/dist/chunks/git-backend-FD7AVSK6.ts.map +0 -7
- package/dist/chunks/manager-ui-IURS4WXY.ts.map +0 -7
- package/dist/chunks/s3-backend-AQGV6LFT.ts.map +0 -7
- package/dist/chunks/setup-wizard-GSDPDFC4.ts.map +0 -7
- package/dist/chunks/sync-operations-47OUX76C.ts.map +0 -7
- package/dist/chunks/webdav-backend-TBILVEQK.ts.map +0 -7
- /package/dist/chunks/{conflict-artifacts-BB2FZMIE.ts.map → agent-candidate-3JN6DJKT.ts.map} +0 -0
- /package/dist/chunks/{chunk-CHSIAC4N.ts.map → chunk-B4QZBDBT.ts.map} +0 -0
- /package/dist/chunks/{chunk-CL7BZRRQ.ts.map → chunk-CRKTAPSL.ts.map} +0 -0
- /package/dist/chunks/{chunk-VHXBCEVF.ts.map → chunk-EUMINX7L.ts.map} +0 -0
- /package/dist/chunks/{chunk-5RZPINUQ.ts.map → chunk-GSNPASKB.ts.map} +0 -0
- /package/dist/chunks/{chunk-SDZCTCYQ.ts.map → chunk-OEWQVWLC.ts.map} +0 -0
- /package/dist/chunks/{chunk-4QVPTIZB.ts.map → chunk-UPNVIUBN.ts.map} +0 -0
- /package/dist/chunks/{manager-result-dispatcher-6MQKFCWB.ts.map → config-KGIYTTXQ.ts.map} +0 -0
- /package/dist/chunks/{merge-baseline-store-EVQAAML6.ts.map → conflict-artifacts-FXFIIBCB.ts.map} +0 -0
- /package/dist/chunks/{remote-selection-ui-6LJJ4IMQ.ts.map → continuous-record-LFRVXQBD.ts.map} +0 -0
- /package/dist/chunks/{file-selection-WZX7HAY2.ts.map → file-selection-3JJYOVNR.ts.map} +0 -0
- /package/dist/chunks/{setup-switch-KTUWL6DE.ts.map → manager-result-dispatcher-AGBBVDDS.ts.map} +0 -0
- /package/dist/chunks/{sync-inspection-K45QVLHB.ts.map → merge-baseline-store-RFCAH7KL.ts.map} +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/sync/startup-timings.ts"],
|
|
4
|
+
"sourcesContent": ["import { performance } from \"node:perf_hooks\";\nimport type { ExtensionContext } from \"@earendil-works/pi-coding-agent\";\n\ntype StartupStage =\n | \"transaction recovery\"\n | \"settings read\"\n | \"config resolution\"\n | \"inspection import\"\n | \"inspection and guards\"\n | \"backend initialization\"\n | \"local snapshot\"\n | \"sync state read\"\n | \"remote head\"\n | \"operations import\"\n | \"automatic transfer\"\n | \"transfer authorization\"\n | \"transfer backend initialization\"\n | \"transfer journal read\"\n | \"transfer journal recovery\"\n | \"transfer state read\"\n | \"transfer local snapshot\"\n | \"transfer remote head\"\n | \"transfer snapshot download\"\n | \"transfer unchanged verification\"\n | \"transfer merge planning\"\n | \"transfer settings merge\"\n | \"transfer content merge\"\n | \"transfer preflight\"\n | \"transfer backup\"\n | \"transfer journal write\"\n | \"transfer remote publication\"\n | \"transfer local apply\"\n | \"transfer baseline write\"\n | \"transfer cleanup\";\n\n/** Fixed labels and durations only: never retain errors, paths, settings, or payloads. */\nexport function createStartupTimings() {\n const started = performance.now();\n const stages = new Map<StartupStage, { ms: number; calls: number; interrupted: boolean }>();\n let unchanged = false;\n return {\n markUnchanged() {\n unchanged = true;\n },\n async measure<T>(stage: StartupStage, run: () => T | Promise<T>): Promise<T> {\n const start = performance.now();\n let completed = false;\n try {\n const result = await run();\n completed = true;\n return result;\n } finally {\n const previous = stages.get(stage);\n stages.set(stage, {\n ms: (previous?.ms ?? 0) + performance.now() - start,\n calls: (previous?.calls ?? 0) + 1,\n interrupted: Boolean(previous?.interrupted || !completed),\n });\n }\n },\n publish(\n ctx: ExtensionContext,\n enabled: boolean,\n sessionSignal: AbortSignal,\n scope: \"local initialization\" | \"background startup\",\n outcome: \"completed\" | \"stopped\" = \"completed\",\n ) {\n if (!enabled || !ctx.hasUI || sessionSignal.aborted) return;\n try {\n ctx.ui.notify(\n [\n `pi-sync debug: ${scope} (${outcome})`,\n ...Array.from(\n stages,\n ([stage, value]) =>\n `${stage}: ${value.ms.toFixed(1)} ms${value.calls > 1 ? ` (${value.calls} calls)` : \"\"}${value.interrupted ? \" (interrupted)\" : \"\"}`,\n ),\n ...(unchanged ? [\"transfer result: unchanged (fast path)\"] : []),\n `total: ${(performance.now() - started).toFixed(1)} ms`,\n ].join(\"\\n\"),\n \"info\",\n );\n } catch {\n // Diagnostics must not change sync behavior if the UI is unavailable during teardown.\n }\n },\n };\n}\n\nexport type StartupTimings = ReturnType<typeof createStartupTimings>;\n"],
|
|
5
|
+
"mappings": ";;;;AAAA,SAAS,mBAAmB;AAoCrB,SAAS,uBAAuB;AACrC,QAAM,UAAU,YAAY,IAAI;AAChC,QAAM,SAAS,oBAAI,IAAuE;AAC1F,MAAI,YAAY;AAChB,SAAO;AAAA,IACL,gBAAgB;AACd,kBAAY;AAAA,IACd;AAAA,IACA,MAAM,QAAW,OAAqB,KAAuC;AAC3E,YAAM,QAAQ,YAAY,IAAI;AAC9B,UAAI,YAAY;AAChB,UAAI;AACF,cAAM,SAAS,MAAM,IAAI;AACzB,oBAAY;AACZ,eAAO;AAAA,MACT,UAAE;AACA,cAAM,WAAW,OAAO,IAAI,KAAK;AACjC,eAAO,IAAI,OAAO;AAAA,UAChB,KAAK,UAAU,MAAM,KAAK,YAAY,IAAI,IAAI;AAAA,UAC9C,QAAQ,UAAU,SAAS,KAAK;AAAA,UAChC,aAAa,QAAQ,UAAU,eAAe,CAAC,SAAS;AAAA,QAC1D,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA,QACE,KACA,SACA,eACA,OACA,UAAmC,aACnC;AACA,UAAI,CAAC,WAAW,CAAC,IAAI,SAAS,cAAc,QAAS;AACrD,UAAI;AACF,YAAI,GAAG;AAAA,UACL;AAAA,YACE,kBAAkB,KAAK,KAAK,OAAO;AAAA,YACnC,GAAG,MAAM;AAAA,cACP;AAAA,cACA,CAAC,CAAC,OAAO,KAAK,MACZ,GAAG,KAAK,KAAK,MAAM,GAAG,QAAQ,CAAC,CAAC,MAAM,MAAM,QAAQ,IAAI,KAAK,MAAM,KAAK,YAAY,EAAE,GAAG,MAAM,cAAc,mBAAmB,EAAE;AAAA,YACtI;AAAA,YACA,GAAI,YAAY,CAAC,wCAAwC,IAAI,CAAC;AAAA,YAC9D,WAAW,YAAY,IAAI,IAAI,SAAS,QAAQ,CAAC,CAAC;AAAA,UACpD,EAAE,KAAK,IAAI;AAAA,UACX;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
// @generated by scripts/build-runtime.mjs; do not edit.
|
|
2
|
+
// @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
|
|
3
|
+
import {
|
|
4
|
+
withLock
|
|
5
|
+
} from "./chunk-AAEEHR7H.ts";
|
|
6
|
+
import {
|
|
7
|
+
ContinuousError
|
|
8
|
+
} from "./chunk-DT7M4VQS.ts";
|
|
9
|
+
import {
|
|
10
|
+
ensureStateDir
|
|
11
|
+
} from "./chunk-UPNVIUBN.ts";
|
|
12
|
+
import {
|
|
13
|
+
LOCKFILE_FS_ADAPTER,
|
|
14
|
+
stateDir,
|
|
15
|
+
withStateDirectoryAccess
|
|
16
|
+
} from "./chunk-SWRVXVFD.ts";
|
|
17
|
+
import {
|
|
18
|
+
backendIdentityCoordinates
|
|
19
|
+
} from "./chunk-2JZFHNLM.ts";
|
|
20
|
+
import {
|
|
21
|
+
writeJson
|
|
22
|
+
} from "./chunk-HUZ5CR4W.ts";
|
|
23
|
+
|
|
24
|
+
// src/sync/continuous-lease.ts
|
|
25
|
+
import { randomUUID } from "node:crypto";
|
|
26
|
+
import { lstatSync, readFileSync, rmdirSync, stat } from "node:fs";
|
|
27
|
+
import fs2 from "node:fs/promises";
|
|
28
|
+
import path2 from "node:path";
|
|
29
|
+
import lockfile from "proper-lockfile";
|
|
30
|
+
|
|
31
|
+
// src/sync/continuous-storage.ts
|
|
32
|
+
import { createHash } from "node:crypto";
|
|
33
|
+
import fs from "node:fs/promises";
|
|
34
|
+
import path from "node:path";
|
|
35
|
+
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
36
|
+
function hashContinuous(value) {
|
|
37
|
+
return createHash("sha256").update(JSON.stringify(value) ?? "null").digest("hex");
|
|
38
|
+
}
|
|
39
|
+
async function continuousBinding(config) {
|
|
40
|
+
return hashContinuous([await fs.realpath(getAgentDir()), config.setupName, backendIdentityCoordinates(config)]);
|
|
41
|
+
}
|
|
42
|
+
function continuousRoot() {
|
|
43
|
+
return path.join(stateDir(), "continuous");
|
|
44
|
+
}
|
|
45
|
+
async function prepareContinuousRoot() {
|
|
46
|
+
await ensureStateDir();
|
|
47
|
+
await fs.mkdir(continuousRoot(), { recursive: true, mode: 448 });
|
|
48
|
+
await checkContinuousRoot();
|
|
49
|
+
}
|
|
50
|
+
async function checkContinuousRoot() {
|
|
51
|
+
const stat2 = await fs.lstat(continuousRoot());
|
|
52
|
+
if (!stat2.isDirectory() || stat2.isSymbolicLink() || process.platform !== "win32" && stat2.mode & 63)
|
|
53
|
+
throw new Error("Unsafe continuous sync directory; evidence retained.");
|
|
54
|
+
}
|
|
55
|
+
async function readContinuousPrivate(name) {
|
|
56
|
+
try {
|
|
57
|
+
await checkContinuousRoot();
|
|
58
|
+
const file = path.join(continuousRoot(), name);
|
|
59
|
+
const stat2 = await fs.lstat(file);
|
|
60
|
+
if (!stat2.isFile() || stat2.isSymbolicLink() || stat2.nlink !== 1 || stat2.size > 131072 || process.platform !== "win32" && stat2.mode & 63)
|
|
61
|
+
throw new Error("Unsafe continuous sync record; evidence retained.");
|
|
62
|
+
return JSON.parse(await fs.readFile(file, "utf8"));
|
|
63
|
+
} catch (error) {
|
|
64
|
+
if (error.code === "ENOENT") return void 0;
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async function writeContinuousPrivate(name, value) {
|
|
69
|
+
await checkContinuousRoot();
|
|
70
|
+
await readContinuousPrivate(name);
|
|
71
|
+
await writeJson(path.join(continuousRoot(), name), value, { maxBytes: 131072 });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// src/sync/continuous-lease.ts
|
|
75
|
+
var STALE_MS = 3e4;
|
|
76
|
+
var localLeases = /* @__PURE__ */ new Set();
|
|
77
|
+
var futureGuards = /* @__PURE__ */ new Map();
|
|
78
|
+
function validOwner(value) {
|
|
79
|
+
if (!value || typeof value !== "object") return false;
|
|
80
|
+
const owner = value;
|
|
81
|
+
return Object.keys(owner).sort().join(",") === "binding,id,pid,version" && owner.version === 1 && typeof owner.id === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/u.test(owner.id) && Number.isSafeInteger(owner.pid) && owner.pid > 0 && owner.pid <= 2147483647 && typeof owner.binding === "string" && /^[a-f0-9]{64}$/u.test(owner.binding);
|
|
82
|
+
}
|
|
83
|
+
async function continuousLeaseOwner(binding) {
|
|
84
|
+
const owner = await readContinuousPrivate("owner.json");
|
|
85
|
+
if (owner === void 0) return "Local scheduler lease: not observed; waiting for an eligible session";
|
|
86
|
+
if (!validOwner(owner)) throw new Error("Invalid continuous sync owner");
|
|
87
|
+
try {
|
|
88
|
+
const guard = await fs2.lstat(path2.join(continuousRoot(), "scheduler.lock"));
|
|
89
|
+
if (guard.isDirectory() && !guard.isSymbolicLink() && Date.now() - guard.mtimeMs <= STALE_MS && owner.binding === binding)
|
|
90
|
+
return `Local scheduler lease: observed for pid ${owner.pid}; this can be another session`;
|
|
91
|
+
} catch (error) {
|
|
92
|
+
if (error.code !== "ENOENT") throw error;
|
|
93
|
+
}
|
|
94
|
+
return "Local scheduler lease: not observed; waiting for an eligible session";
|
|
95
|
+
}
|
|
96
|
+
async function acquireContinuousLease(binding) {
|
|
97
|
+
await prepareContinuousRoot();
|
|
98
|
+
const file = path2.join(continuousRoot(), "scheduler");
|
|
99
|
+
const guardPath = `${file}.lock`;
|
|
100
|
+
if (localLeases.has(file)) return void 0;
|
|
101
|
+
const previousOwner = await readContinuousPrivate("owner.json");
|
|
102
|
+
if (previousOwner !== void 0 && !validOwner(previousOwner))
|
|
103
|
+
throw new Error("Invalid continuous sync owner; evidence retained.");
|
|
104
|
+
if (localLeases.has(file)) return void 0;
|
|
105
|
+
localLeases.add(file);
|
|
106
|
+
const acquiredAt = performance.now();
|
|
107
|
+
const ownerPath = path2.join(continuousRoot(), "owner.json");
|
|
108
|
+
const controller = new AbortController();
|
|
109
|
+
const owner = { version: 1, id: randomUUID(), pid: process.pid, binding };
|
|
110
|
+
let identity;
|
|
111
|
+
let published = false;
|
|
112
|
+
const removeGuard = (target) => {
|
|
113
|
+
if (identity) {
|
|
114
|
+
const current2 = lstatSync(target);
|
|
115
|
+
if (current2.dev !== identity.dev || current2.ino !== identity.ino) return;
|
|
116
|
+
}
|
|
117
|
+
let current;
|
|
118
|
+
try {
|
|
119
|
+
const record = lstatSync(ownerPath);
|
|
120
|
+
if (!record.isFile() || record.isSymbolicLink() || record.nlink !== 1 || record.size > 4096 || process.platform !== "win32" && record.mode & 63)
|
|
121
|
+
return;
|
|
122
|
+
current = JSON.parse(readFileSync(ownerPath, "utf8"));
|
|
123
|
+
} catch (error) {
|
|
124
|
+
if (error.code !== "ENOENT") throw error;
|
|
125
|
+
}
|
|
126
|
+
if (published && current === void 0) return;
|
|
127
|
+
if (current !== void 0 && (!validOwner(current) || current.id !== owner.id && (published || current.id !== previousOwner?.id)))
|
|
128
|
+
return;
|
|
129
|
+
rmdirSync(target);
|
|
130
|
+
};
|
|
131
|
+
const adapter = {
|
|
132
|
+
...LOCKFILE_FS_ADAPTER,
|
|
133
|
+
stat: (target, callback) => stat(target, (error, value) => {
|
|
134
|
+
if (!error && value.mtimeMs > Date.now() + STALE_MS) {
|
|
135
|
+
const identity2 = `${value.dev}:${value.ino}:${value.mtimeMs}`;
|
|
136
|
+
const previous = futureGuards.get(target);
|
|
137
|
+
if (!previous || previous.identity !== identity2)
|
|
138
|
+
futureGuards.set(target, { identity: identity2, since: performance.now() });
|
|
139
|
+
else if (performance.now() - previous.since > STALE_MS) value.mtime = new Date(Date.now() - STALE_MS - 1);
|
|
140
|
+
} else futureGuards.delete(target);
|
|
141
|
+
callback(error, value);
|
|
142
|
+
}),
|
|
143
|
+
rmdirSync: removeGuard,
|
|
144
|
+
rmdir: (target, callback) => {
|
|
145
|
+
try {
|
|
146
|
+
removeGuard(target);
|
|
147
|
+
callback();
|
|
148
|
+
} catch (error) {
|
|
149
|
+
callback(error);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
let compromised = false;
|
|
154
|
+
let unlock;
|
|
155
|
+
try {
|
|
156
|
+
unlock = await lockfile.lock(file, {
|
|
157
|
+
fs: adapter,
|
|
158
|
+
realpath: false,
|
|
159
|
+
stale: STALE_MS,
|
|
160
|
+
update: 1e4,
|
|
161
|
+
retries: 0,
|
|
162
|
+
onCompromised: () => {
|
|
163
|
+
compromised = true;
|
|
164
|
+
controller.abort(new DOMException("Continuous sync ownership lost", "AbortError"));
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
} catch (error) {
|
|
168
|
+
localLeases.delete(file);
|
|
169
|
+
if (error.code === "ELOCKED") return void 0;
|
|
170
|
+
throw error;
|
|
171
|
+
}
|
|
172
|
+
let released = false;
|
|
173
|
+
const release = async () => {
|
|
174
|
+
if (released) return;
|
|
175
|
+
released = true;
|
|
176
|
+
controller.abort(new DOMException("Continuous sync owner released", "AbortError"));
|
|
177
|
+
try {
|
|
178
|
+
if (!compromised) await unlock();
|
|
179
|
+
} finally {
|
|
180
|
+
localLeases.delete(file);
|
|
181
|
+
futureGuards.delete(guardPath);
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
try {
|
|
185
|
+
identity = await fs2.lstat(guardPath);
|
|
186
|
+
await withLock("continuous-owner", async () => {
|
|
187
|
+
const previous = await readContinuousPrivate("owner.json");
|
|
188
|
+
if (previous !== void 0 && !validOwner(previous))
|
|
189
|
+
throw new Error("Invalid continuous sync owner; evidence retained.");
|
|
190
|
+
if (previous?.id !== previousOwner?.id || performance.now() - acquiredAt > STALE_MS)
|
|
191
|
+
throw new Error("Continuous lease generation changed before publication.");
|
|
192
|
+
const current = lstatSync(guardPath);
|
|
193
|
+
if (controller.signal.aborted || current.dev !== identity?.dev || current.ino !== identity.ino)
|
|
194
|
+
throw new Error("Continuous lease changed before publication.");
|
|
195
|
+
await writeContinuousPrivate("owner.json", owner);
|
|
196
|
+
published = true;
|
|
197
|
+
});
|
|
198
|
+
const assert = () => {
|
|
199
|
+
controller.signal.throwIfAborted();
|
|
200
|
+
try {
|
|
201
|
+
const root = lstatSync(continuousRoot());
|
|
202
|
+
if (!root.isDirectory() || root.isSymbolicLink() || process.platform !== "win32" && root.mode & 63)
|
|
203
|
+
throw new Error("Unsafe lease root");
|
|
204
|
+
const stat2 = lstatSync(guardPath);
|
|
205
|
+
if (stat2.isSymbolicLink() || !stat2.isDirectory() || stat2.dev !== identity?.dev || stat2.ino !== identity.ino || Date.now() - stat2.mtimeMs > STALE_MS)
|
|
206
|
+
throw new Error("Lease guard changed");
|
|
207
|
+
const record = lstatSync(ownerPath);
|
|
208
|
+
if (!record.isFile() || record.isSymbolicLink() || record.nlink !== 1 || record.size > 4096 || process.platform !== "win32" && record.mode & 63)
|
|
209
|
+
throw new Error("Unsafe owner record");
|
|
210
|
+
const value = JSON.parse(readFileSync(ownerPath, "utf8"));
|
|
211
|
+
if (!validOwner(value) || value.id !== owner.id || value.binding !== binding || value.pid !== process.pid)
|
|
212
|
+
throw new Error("Lease owner changed");
|
|
213
|
+
} catch {
|
|
214
|
+
controller.abort(new DOMException("Continuous sync ownership lost", "AbortError"));
|
|
215
|
+
controller.signal.throwIfAborted();
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
assert();
|
|
219
|
+
return { signal: controller.signal, assert, release };
|
|
220
|
+
} catch (error) {
|
|
221
|
+
await release();
|
|
222
|
+
throw error;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// src/sync/continuous-record.ts
|
|
227
|
+
var REQUEST_WINDOW_MS = 15 * 6e4;
|
|
228
|
+
var digest = (value) => typeof value === "string" && /^[a-f0-9]{64}$/u.test(value);
|
|
229
|
+
var timestamp = (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && value <= 864e13;
|
|
230
|
+
function validateContinuousRecord(value, binding) {
|
|
231
|
+
const record = value;
|
|
232
|
+
if (!record || typeof record !== "object" || record.version !== 1 || record.binding !== binding || Object.keys(record).some(
|
|
233
|
+
(key) => ![
|
|
234
|
+
"version",
|
|
235
|
+
"binding",
|
|
236
|
+
"pending",
|
|
237
|
+
"phase",
|
|
238
|
+
"next",
|
|
239
|
+
"failures",
|
|
240
|
+
"evidence",
|
|
241
|
+
"recovery",
|
|
242
|
+
"notice",
|
|
243
|
+
"configuration",
|
|
244
|
+
"error",
|
|
245
|
+
"checked",
|
|
246
|
+
"transferred",
|
|
247
|
+
"calls",
|
|
248
|
+
"attempts"
|
|
249
|
+
].includes(key)
|
|
250
|
+
) || typeof record.pending !== "boolean" || !["waiting", "syncing", "retry", "blocked"].includes(record.phase) || !timestamp(record.next) || !timestamp(record.failures) || record.failures > 30 || record.evidence !== void 0 && !digest(record.evidence) || record.recovery !== void 0 && !digest(record.recovery) || record.notice !== void 0 && !digest(record.notice) || record.configuration !== void 0 && !digest(record.configuration) || record.error !== void 0 && ![
|
|
251
|
+
"transient",
|
|
252
|
+
"contention",
|
|
253
|
+
"stale",
|
|
254
|
+
"authentication",
|
|
255
|
+
"storage",
|
|
256
|
+
"unsafe",
|
|
257
|
+
"model",
|
|
258
|
+
"budget",
|
|
259
|
+
"unknown"
|
|
260
|
+
].includes(record.error) || record.checked !== void 0 && !timestamp(record.checked) || record.transferred !== void 0 && !timestamp(record.transferred) || !Array.isArray(record.calls) || record.calls.length > 2 || record.calls.some(
|
|
261
|
+
(call) => !call || Object.keys(call).sort().join(",") !== "at,key" || !digest(call.key) || !timestamp(call.at)
|
|
262
|
+
) || !record.attempts || typeof record.attempts !== "object" || Array.isArray(record.attempts) || Object.entries(record.attempts).some(
|
|
263
|
+
([key, count]) => !digest(key) || !Number.isInteger(count) || count < 1 || count > 2
|
|
264
|
+
) || record.calls.some(
|
|
265
|
+
(call) => (record.attempts[call.key] ?? 0) < record.calls.filter((other) => other.key === call.key).length
|
|
266
|
+
))
|
|
267
|
+
throw new Error("Invalid continuous sync state; evidence retained.");
|
|
268
|
+
}
|
|
269
|
+
async function readContinuousRecord(binding) {
|
|
270
|
+
const value = await readContinuousPrivate(`${binding}.json`);
|
|
271
|
+
if (value === void 0)
|
|
272
|
+
return { version: 1, binding, pending: true, phase: "waiting", next: 0, failures: 0, calls: [], attempts: {} };
|
|
273
|
+
validateContinuousRecord(value, binding);
|
|
274
|
+
return value;
|
|
275
|
+
}
|
|
276
|
+
async function updateContinuousRecord(binding, lease, update) {
|
|
277
|
+
return withStateDirectoryAccess(
|
|
278
|
+
() => withLock("continuous-state", async () => {
|
|
279
|
+
lease.assert();
|
|
280
|
+
const record = await readContinuousRecord(binding);
|
|
281
|
+
lease.assert();
|
|
282
|
+
const result = update(record);
|
|
283
|
+
validateContinuousRecord(record, binding);
|
|
284
|
+
lease.assert();
|
|
285
|
+
await writeContinuousPrivate(`${binding}.json`, record);
|
|
286
|
+
lease.assert();
|
|
287
|
+
return result;
|
|
288
|
+
})
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
function normalizeContinuousClock(record, now) {
|
|
292
|
+
record.calls = record.calls.map((call) => ({ ...call, at: Math.min(call.at, now) })).filter((call) => now - call.at < REQUEST_WINDOW_MS);
|
|
293
|
+
record.next = Math.min(record.next, now + (record.error === "budget" ? REQUEST_WINDOW_MS : 3e5));
|
|
294
|
+
}
|
|
295
|
+
async function reserveContinuousRequest(binding, lease, key, clock = Date.now) {
|
|
296
|
+
if (!digest(key)) throw new Error("Invalid continuous candidate key.");
|
|
297
|
+
let failure;
|
|
298
|
+
await updateContinuousRecord(binding, lease, (record) => {
|
|
299
|
+
const now = clock();
|
|
300
|
+
normalizeContinuousClock(record, now);
|
|
301
|
+
if ((record.attempts[key] ?? 0) >= 2)
|
|
302
|
+
failure = new ContinuousError(
|
|
303
|
+
"model",
|
|
304
|
+
"Automatic request limit reached for this evidence. Use Sync now for an explicit retry."
|
|
305
|
+
);
|
|
306
|
+
else if (record.calls.length >= 2)
|
|
307
|
+
failure = new ContinuousError(
|
|
308
|
+
"budget",
|
|
309
|
+
"Automatic request window is full.",
|
|
310
|
+
Math.max(0, (record.calls[0]?.at ?? now) + REQUEST_WINDOW_MS - now)
|
|
311
|
+
);
|
|
312
|
+
else {
|
|
313
|
+
record.attempts[key] = (record.attempts[key] ?? 0) + 1;
|
|
314
|
+
record.calls.push({ key, at: now });
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
if (failure) throw failure;
|
|
318
|
+
}
|
|
319
|
+
async function continuousStatusLines(config) {
|
|
320
|
+
if (!config.continuous) return ["Continuous sync: Off"];
|
|
321
|
+
if (!config.agentMode) return ["Continuous sync: paused; enable Agent mode first"];
|
|
322
|
+
try {
|
|
323
|
+
const record = await readContinuousRecord(await continuousBinding(config));
|
|
324
|
+
return [
|
|
325
|
+
`Continuous sync: ${record.phase}${record.error ? ` (${record.error})` : ""}`,
|
|
326
|
+
await continuousLeaseOwner(record.binding),
|
|
327
|
+
`Last successful background check: ${record.checked ? new Date(record.checked).toISOString() : "not yet checked"}`,
|
|
328
|
+
`Last successful background transfer: ${record.transferred ? new Date(record.transferred).toISOString() : "none"}`,
|
|
329
|
+
...record.phase === "retry" ? [`Next background attempt: ${new Date(record.next).toISOString()}`] : [],
|
|
330
|
+
...record.phase === "blocked" ? ["Background sync needs changed evidence or repair. Review /sync, or use Sync now for an explicit retry."] : [],
|
|
331
|
+
"Monitoring requires an eligible open Pi session. Status does not spend model requests or clear retry limits."
|
|
332
|
+
];
|
|
333
|
+
} catch {
|
|
334
|
+
return ["Continuous sync: private state unavailable; retain evidence and repair access before retrying."];
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
export {
|
|
339
|
+
hashContinuous,
|
|
340
|
+
continuousBinding,
|
|
341
|
+
acquireContinuousLease,
|
|
342
|
+
REQUEST_WINDOW_MS,
|
|
343
|
+
validateContinuousRecord,
|
|
344
|
+
readContinuousRecord,
|
|
345
|
+
updateContinuousRecord,
|
|
346
|
+
normalizeContinuousClock,
|
|
347
|
+
reserveContinuousRequest,
|
|
348
|
+
continuousStatusLines
|
|
349
|
+
};
|
|
350
|
+
//# sourceMappingURL=chunk-VJN7KU4J.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/sync/continuous-lease.ts", "../../src/sync/continuous-storage.ts", "../../src/sync/continuous-record.ts"],
|
|
4
|
+
"sourcesContent": ["import { randomUUID } from \"node:crypto\";\nimport { lstatSync, readFileSync, rmdirSync, type Stats, stat } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport lockfile from \"proper-lockfile\";\nimport { withLock } from \"../state/lock.js\";\nimport { LOCKFILE_FS_ADAPTER } from \"../state/lockfile-fs.js\";\nimport {\n continuousRoot,\n prepareContinuousRoot,\n readContinuousPrivate,\n writeContinuousPrivate,\n} from \"./continuous-storage.js\";\n\nconst STALE_MS = 30_000;\nconst localLeases = new Set<string>();\nconst futureGuards = new Map<string, { identity: string; since: number }>();\ninterface Owner {\n version: 1;\n id: string;\n pid: number;\n binding: string;\n}\nexport interface ContinuousLease {\n signal: AbortSignal;\n assert(): void;\n release(): Promise<void>;\n}\nfunction validOwner(value: unknown): value is Owner {\n if (!value || typeof value !== \"object\") return false;\n const owner = value as Owner;\n return (\n Object.keys(owner).sort().join(\",\") === \"binding,id,pid,version\" &&\n owner.version === 1 &&\n typeof owner.id === \"string\" &&\n /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/u.test(owner.id) &&\n Number.isSafeInteger(owner.pid) &&\n owner.pid > 0 &&\n owner.pid <= 2147483647 &&\n typeof owner.binding === \"string\" &&\n /^[a-f0-9]{64}$/u.test(owner.binding)\n );\n}\n\n/** Advisory only: never authority for a transfer or lease takeover. */\nexport async function continuousLeaseOwner(binding: string): Promise<string> {\n const owner = await readContinuousPrivate(\"owner.json\");\n if (owner === undefined) return \"Local scheduler lease: not observed; waiting for an eligible session\";\n if (!validOwner(owner)) throw new Error(\"Invalid continuous sync owner\");\n try {\n const guard = await fs.lstat(path.join(continuousRoot(), \"scheduler.lock\"));\n if (\n guard.isDirectory() &&\n !guard.isSymbolicLink() &&\n Date.now() - guard.mtimeMs <= STALE_MS &&\n owner.binding === binding\n )\n return `Local scheduler lease: observed for pid ${owner.pid}; this can be another session`;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n }\n return \"Local scheduler lease: not observed; waiting for an eligible session\";\n}\n\n/** Caller holds state-directory access during acquisition; the renewable guard prevents live migration. */\nexport async function acquireContinuousLease(binding: string): Promise<ContinuousLease | undefined> {\n await prepareContinuousRoot();\n const file = path.join(continuousRoot(), \"scheduler\");\n const guardPath = `${file}.lock`;\n if (localLeases.has(file)) return undefined;\n const previousOwner = await readContinuousPrivate(\"owner.json\");\n if (previousOwner !== undefined && !validOwner(previousOwner))\n throw new Error(\"Invalid continuous sync owner; evidence retained.\");\n if (localLeases.has(file)) return undefined;\n localLeases.add(file);\n const acquiredAt = performance.now();\n const ownerPath = path.join(continuousRoot(), \"owner.json\");\n const controller = new AbortController();\n const owner: Owner = { version: 1, id: randomUUID(), pid: process.pid, binding };\n let identity: { dev: number; ino: number } | undefined;\n let published = false;\n // proper-lockfile also uses rmdirSync at process exit. Fence both cleanup paths.\n const removeGuard = (target: string) => {\n if (identity) {\n const current = lstatSync(target);\n if (current.dev !== identity.dev || current.ino !== identity.ino) return;\n }\n let current: unknown;\n try {\n const record = lstatSync(ownerPath);\n if (\n !record.isFile() ||\n record.isSymbolicLink() ||\n record.nlink !== 1 ||\n record.size > 4096 ||\n (process.platform !== \"win32\" && record.mode & 0o077)\n )\n return;\n current = JSON.parse(readFileSync(ownerPath, \"utf8\"));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n }\n if (published && current === undefined) return;\n if (\n current !== undefined &&\n (!validOwner(current) ||\n (current.id !== owner.id && (published || current.id !== (previousOwner as Owner | undefined)?.id)))\n )\n return;\n rmdirSync(target);\n };\n const adapter = {\n ...LOCKFILE_FS_ADAPTER,\n stat: (target: string, callback: (error: NodeJS.ErrnoException | null, value?: Stats) => void) =>\n stat(target, (error, value) => {\n if (!error && value.mtimeMs > Date.now() + STALE_MS) {\n const identity = `${value.dev}:${value.ino}:${value.mtimeMs}`;\n const previous = futureGuards.get(target);\n if (!previous || previous.identity !== identity)\n futureGuards.set(target, { identity, since: performance.now() });\n else if (performance.now() - previous.since > STALE_MS) value.mtime = new Date(Date.now() - STALE_MS - 1);\n } else futureGuards.delete(target);\n callback(error, value);\n }),\n rmdirSync: removeGuard,\n rmdir: (target: string, callback: (error?: NodeJS.ErrnoException | null) => void) => {\n try {\n removeGuard(target);\n callback();\n } catch (error) {\n callback(error as NodeJS.ErrnoException);\n }\n },\n };\n let compromised = false;\n let unlock: () => Promise<void>;\n try {\n unlock = await lockfile.lock(file, {\n fs: adapter,\n realpath: false,\n stale: STALE_MS,\n update: 10_000,\n retries: 0,\n onCompromised: () => {\n compromised = true;\n controller.abort(new DOMException(\"Continuous sync ownership lost\", \"AbortError\"));\n },\n });\n } catch (error) {\n localLeases.delete(file);\n if ((error as NodeJS.ErrnoException).code === \"ELOCKED\") return undefined;\n throw error;\n }\n let released = false;\n const release = async () => {\n if (released) return;\n released = true;\n controller.abort(new DOMException(\"Continuous sync owner released\", \"AbortError\"));\n try {\n if (!compromised) await unlock();\n } finally {\n localLeases.delete(file);\n futureGuards.delete(guardPath);\n }\n };\n try {\n identity = await fs.lstat(guardPath);\n await withLock(\"continuous-owner\", async () => {\n const previous = await readContinuousPrivate(\"owner.json\");\n if (previous !== undefined && !validOwner(previous))\n throw new Error(\"Invalid continuous sync owner; evidence retained.\");\n if (\n (previous as Owner | undefined)?.id !== (previousOwner as Owner | undefined)?.id ||\n performance.now() - acquiredAt > STALE_MS\n )\n throw new Error(\"Continuous lease generation changed before publication.\");\n const current = lstatSync(guardPath);\n if (controller.signal.aborted || current.dev !== identity?.dev || current.ino !== identity.ino)\n throw new Error(\"Continuous lease changed before publication.\");\n await writeContinuousPrivate(\"owner.json\", owner);\n published = true;\n });\n const assert = () => {\n controller.signal.throwIfAborted();\n try {\n const root = lstatSync(continuousRoot());\n if (!root.isDirectory() || root.isSymbolicLink() || (process.platform !== \"win32\" && root.mode & 0o077))\n throw new Error(\"Unsafe lease root\");\n const stat = lstatSync(guardPath);\n if (\n stat.isSymbolicLink() ||\n !stat.isDirectory() ||\n stat.dev !== identity?.dev ||\n stat.ino !== identity.ino ||\n Date.now() - stat.mtimeMs > STALE_MS\n )\n throw new Error(\"Lease guard changed\");\n const record = lstatSync(ownerPath);\n if (\n !record.isFile() ||\n record.isSymbolicLink() ||\n record.nlink !== 1 ||\n record.size > 4096 ||\n (process.platform !== \"win32\" && record.mode & 0o077)\n )\n throw new Error(\"Unsafe owner record\");\n const value: unknown = JSON.parse(readFileSync(ownerPath, \"utf8\"));\n if (!validOwner(value) || value.id !== owner.id || value.binding !== binding || value.pid !== process.pid)\n throw new Error(\"Lease owner changed\");\n } catch {\n controller.abort(new DOMException(\"Continuous sync ownership lost\", \"AbortError\"));\n controller.signal.throwIfAborted();\n }\n };\n assert();\n return { signal: controller.signal, assert, release };\n } catch (error) {\n await release();\n throw error;\n }\n}\n", "import { createHash } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { getAgentDir } from \"@earendil-works/pi-coding-agent\";\nimport { backendIdentityCoordinates } from \"../backends/backend-identity.js\";\nimport type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport { writeJson } from \"../state/json-file.js\";\nimport { stateDir } from \"../state/state-directory.js\";\nimport { ensureStateDir } from \"../state/sync-state-store.js\";\n\nexport function hashContinuous(value: unknown) {\n return createHash(\"sha256\")\n .update(JSON.stringify(value) ?? \"null\")\n .digest(\"hex\");\n}\nexport async function continuousBinding(config: AnySyncConfig) {\n return hashContinuous([await fs.realpath(getAgentDir()), config.setupName, backendIdentityCoordinates(config)]);\n}\nexport function continuousRoot() {\n return path.join(stateDir(), \"continuous\");\n}\nexport async function prepareContinuousRoot() {\n await ensureStateDir();\n await fs.mkdir(continuousRoot(), { recursive: true, mode: 0o700 });\n await checkContinuousRoot();\n}\nexport async function checkContinuousRoot() {\n const stat = await fs.lstat(continuousRoot());\n if (!stat.isDirectory() || stat.isSymbolicLink() || (process.platform !== \"win32\" && stat.mode & 0o077))\n throw new Error(\"Unsafe continuous sync directory; evidence retained.\");\n}\nexport async function readContinuousPrivate(name: string): Promise<unknown> {\n try {\n await checkContinuousRoot();\n const file = path.join(continuousRoot(), name);\n const stat = await fs.lstat(file);\n if (\n !stat.isFile() ||\n stat.isSymbolicLink() ||\n stat.nlink !== 1 ||\n stat.size > 131072 ||\n (process.platform !== \"win32\" && stat.mode & 0o077)\n )\n throw new Error(\"Unsafe continuous sync record; evidence retained.\");\n return JSON.parse(await fs.readFile(file, \"utf8\"));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return undefined;\n throw error;\n }\n}\nexport async function writeContinuousPrivate(name: string, value: unknown) {\n await checkContinuousRoot();\n await readContinuousPrivate(name); // Never replace unsafe or malformed evidence.\n await writeJson(path.join(continuousRoot(), name), value, { maxBytes: 131072 });\n}\n", "import type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport { withLock } from \"../state/lock.js\";\nimport { withStateDirectoryAccess } from \"../state/state-directory.js\";\nimport { ContinuousError, type ContinuousErrorKind } from \"./continuous-errors.js\";\nimport { type ContinuousLease, continuousLeaseOwner } from \"./continuous-lease.js\";\nimport { continuousBinding, readContinuousPrivate, writeContinuousPrivate } from \"./continuous-storage.js\";\n\nexport const REQUEST_WINDOW_MS = 15 * 60_000;\nexport interface ContinuousRecord {\n version: 1;\n binding: string;\n pending: boolean;\n phase: \"waiting\" | \"syncing\" | \"retry\" | \"blocked\";\n next: number;\n failures: number;\n evidence?: string;\n recovery?: string;\n notice?: string;\n configuration?: string;\n error?: ContinuousErrorKind;\n checked?: number;\n transferred?: number;\n calls: { key: string; at: number }[];\n attempts: Record<string, number>;\n}\nconst digest = (value: unknown) => typeof value === \"string\" && /^[a-f0-9]{64}$/u.test(value);\nconst timestamp = (value: unknown) =>\n typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0 && value <= 8_640_000_000_000_000;\nexport function validateContinuousRecord(value: unknown, binding: string): asserts value is ContinuousRecord {\n const record = value as ContinuousRecord;\n if (\n !record ||\n typeof record !== \"object\" ||\n record.version !== 1 ||\n record.binding !== binding ||\n Object.keys(record).some(\n (key) =>\n ![\n \"version\",\n \"binding\",\n \"pending\",\n \"phase\",\n \"next\",\n \"failures\",\n \"evidence\",\n \"recovery\",\n \"notice\",\n \"configuration\",\n \"error\",\n \"checked\",\n \"transferred\",\n \"calls\",\n \"attempts\",\n ].includes(key),\n ) ||\n typeof record.pending !== \"boolean\" ||\n ![\"waiting\", \"syncing\", \"retry\", \"blocked\"].includes(record.phase) ||\n !timestamp(record.next) ||\n !timestamp(record.failures) ||\n record.failures > 30 ||\n (record.evidence !== undefined && !digest(record.evidence)) ||\n (record.recovery !== undefined && !digest(record.recovery)) ||\n (record.notice !== undefined && !digest(record.notice)) ||\n (record.configuration !== undefined && !digest(record.configuration)) ||\n (record.error !== undefined &&\n ![\n \"transient\",\n \"contention\",\n \"stale\",\n \"authentication\",\n \"storage\",\n \"unsafe\",\n \"model\",\n \"budget\",\n \"unknown\",\n ].includes(record.error)) ||\n (record.checked !== undefined && !timestamp(record.checked)) ||\n (record.transferred !== undefined && !timestamp(record.transferred)) ||\n !Array.isArray(record.calls) ||\n record.calls.length > 2 ||\n record.calls.some(\n (call) => !call || Object.keys(call).sort().join(\",\") !== \"at,key\" || !digest(call.key) || !timestamp(call.at),\n ) ||\n !record.attempts ||\n typeof record.attempts !== \"object\" ||\n Array.isArray(record.attempts) ||\n Object.entries(record.attempts).some(\n ([key, count]) => !digest(key) || !Number.isInteger(count) || count < 1 || count > 2,\n ) ||\n record.calls.some(\n (call) => (record.attempts[call.key] ?? 0) < record.calls.filter((other) => other.key === call.key).length,\n )\n )\n throw new Error(\"Invalid continuous sync state; evidence retained.\");\n}\nexport async function readContinuousRecord(binding: string): Promise<ContinuousRecord> {\n const value = await readContinuousPrivate(`${binding}.json`);\n if (value === undefined)\n return { version: 1, binding, pending: true, phase: \"waiting\", next: 0, failures: 0, calls: [], attempts: {} };\n validateContinuousRecord(value, binding);\n return value;\n}\nexport async function updateContinuousRecord<T>(\n binding: string,\n lease: ContinuousLease,\n update: (record: ContinuousRecord) => T,\n): Promise<T> {\n return withStateDirectoryAccess(() =>\n withLock(\"continuous-state\", async () => {\n lease.assert();\n const record = await readContinuousRecord(binding);\n lease.assert();\n const result = update(record);\n validateContinuousRecord(record, binding);\n lease.assert();\n await writeContinuousPrivate(`${binding}.json`, record);\n lease.assert();\n return result;\n }),\n );\n}\nexport function normalizeContinuousClock(record: ContinuousRecord, now: number) {\n // A backward wall-clock jump cannot grant more calls: retain them for a full window.\n record.calls = record.calls\n .map((call) => ({ ...call, at: Math.min(call.at, now) }))\n .filter((call) => now - call.at < REQUEST_WINDOW_MS);\n record.next = Math.min(record.next, now + (record.error === \"budget\" ? REQUEST_WINDOW_MS : 300_000));\n}\nexport async function reserveContinuousRequest(\n binding: string,\n lease: ContinuousLease,\n key: string,\n clock: () => number = Date.now,\n) {\n if (!digest(key)) throw new Error(\"Invalid continuous candidate key.\");\n let failure: ContinuousError | undefined;\n await updateContinuousRecord(binding, lease, (record) => {\n const now = clock();\n normalizeContinuousClock(record, now);\n if ((record.attempts[key] ?? 0) >= 2)\n failure = new ContinuousError(\n \"model\",\n \"Automatic request limit reached for this evidence. Use Sync now for an explicit retry.\",\n );\n else if (record.calls.length >= 2)\n failure = new ContinuousError(\n \"budget\",\n \"Automatic request window is full.\",\n Math.max(0, (record.calls[0]?.at ?? now) + REQUEST_WINDOW_MS - now),\n );\n else {\n record.attempts[key] = (record.attempts[key] ?? 0) + 1;\n record.calls.push({ key, at: now });\n }\n });\n if (failure) throw failure;\n}\n\n/** Read-only status: no directory creation, lease, mutation, request reservation or provider call. */\nexport async function continuousStatusLines(config: AnySyncConfig): Promise<string[]> {\n if (!config.continuous) return [\"Continuous sync: Off\"];\n if (!config.agentMode) return [\"Continuous sync: paused; enable Agent mode first\"];\n try {\n const record = await readContinuousRecord(await continuousBinding(config));\n return [\n `Continuous sync: ${record.phase}${record.error ? ` (${record.error})` : \"\"}`,\n await continuousLeaseOwner(record.binding),\n `Last successful background check: ${record.checked ? new Date(record.checked).toISOString() : \"not yet checked\"}`,\n `Last successful background transfer: ${record.transferred ? new Date(record.transferred).toISOString() : \"none\"}`,\n ...(record.phase === \"retry\" ? [`Next background attempt: ${new Date(record.next).toISOString()}`] : []),\n ...(record.phase === \"blocked\"\n ? [\"Background sync needs changed evidence or repair. Review /sync, or use Sync now for an explicit retry.\"]\n : []),\n \"Monitoring requires an eligible open Pi session. Status does not spend model requests or clear retry limits.\",\n ];\n } catch {\n return [\"Continuous sync: private state unavailable; retain evidence and repair access before retrying.\"];\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,kBAAkB;AAC3B,SAAS,WAAW,cAAc,WAAuB,YAAY;AACrE,OAAOA,SAAQ;AACf,OAAOC,WAAU;AACjB,OAAO,cAAc;;;ACJrB,SAAS,kBAAkB;AAC3B,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,mBAAmB;AAOrB,SAAS,eAAe,OAAgB;AAC7C,SAAO,WAAW,QAAQ,EACvB,OAAO,KAAK,UAAU,KAAK,KAAK,MAAM,EACtC,OAAO,KAAK;AACjB;AACA,eAAsB,kBAAkB,QAAuB;AAC7D,SAAO,eAAe,CAAC,MAAM,GAAG,SAAS,YAAY,CAAC,GAAG,OAAO,WAAW,2BAA2B,MAAM,CAAC,CAAC;AAChH;AACO,SAAS,iBAAiB;AAC/B,SAAO,KAAK,KAAK,SAAS,GAAG,YAAY;AAC3C;AACA,eAAsB,wBAAwB;AAC5C,QAAM,eAAe;AACrB,QAAM,GAAG,MAAM,eAAe,GAAG,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AACjE,QAAM,oBAAoB;AAC5B;AACA,eAAsB,sBAAsB;AAC1C,QAAMC,QAAO,MAAM,GAAG,MAAM,eAAe,CAAC;AAC5C,MAAI,CAACA,MAAK,YAAY,KAAKA,MAAK,eAAe,KAAM,QAAQ,aAAa,WAAWA,MAAK,OAAO;AAC/F,UAAM,IAAI,MAAM,sDAAsD;AAC1E;AACA,eAAsB,sBAAsB,MAAgC;AAC1E,MAAI;AACF,UAAM,oBAAoB;AAC1B,UAAM,OAAO,KAAK,KAAK,eAAe,GAAG,IAAI;AAC7C,UAAMA,QAAO,MAAM,GAAG,MAAM,IAAI;AAChC,QACE,CAACA,MAAK,OAAO,KACbA,MAAK,eAAe,KACpBA,MAAK,UAAU,KACfA,MAAK,OAAO,UACX,QAAQ,aAAa,WAAWA,MAAK,OAAO;AAE7C,YAAM,IAAI,MAAM,mDAAmD;AACrE,WAAO,KAAK,MAAM,MAAM,GAAG,SAAS,MAAM,MAAM,CAAC;AAAA,EACnD,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,SAAU,QAAO;AAC/D,UAAM;AAAA,EACR;AACF;AACA,eAAsB,uBAAuB,MAAc,OAAgB;AACzE,QAAM,oBAAoB;AAC1B,QAAM,sBAAsB,IAAI;AAChC,QAAM,UAAU,KAAK,KAAK,eAAe,GAAG,IAAI,GAAG,OAAO,EAAE,UAAU,OAAO,CAAC;AAChF;;;ADxCA,IAAM,WAAW;AACjB,IAAM,cAAc,oBAAI,IAAY;AACpC,IAAM,eAAe,oBAAI,IAAiD;AAY1E,SAAS,WAAW,OAAgC;AAClD,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAM,QAAQ;AACd,SACE,OAAO,KAAK,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,4BACxC,MAAM,YAAY,KAClB,OAAO,MAAM,OAAO,YACpB,kEAAkE,KAAK,MAAM,EAAE,KAC/E,OAAO,cAAc,MAAM,GAAG,KAC9B,MAAM,MAAM,KACZ,MAAM,OAAO,cACb,OAAO,MAAM,YAAY,YACzB,kBAAkB,KAAK,MAAM,OAAO;AAExC;AAGA,eAAsB,qBAAqB,SAAkC;AAC3E,QAAM,QAAQ,MAAM,sBAAsB,YAAY;AACtD,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,CAAC,WAAW,KAAK,EAAG,OAAM,IAAI,MAAM,+BAA+B;AACvE,MAAI;AACF,UAAM,QAAQ,MAAMC,IAAG,MAAMC,MAAK,KAAK,eAAe,GAAG,gBAAgB,CAAC;AAC1E,QACE,MAAM,YAAY,KAClB,CAAC,MAAM,eAAe,KACtB,KAAK,IAAI,IAAI,MAAM,WAAW,YAC9B,MAAM,YAAY;AAElB,aAAO,2CAA2C,MAAM,GAAG;AAAA,EAC/D,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,SAAU,OAAM;AAAA,EAChE;AACA,SAAO;AACT;AAGA,eAAsB,uBAAuB,SAAuD;AAClG,QAAM,sBAAsB;AAC5B,QAAM,OAAOA,MAAK,KAAK,eAAe,GAAG,WAAW;AACpD,QAAM,YAAY,GAAG,IAAI;AACzB,MAAI,YAAY,IAAI,IAAI,EAAG,QAAO;AAClC,QAAM,gBAAgB,MAAM,sBAAsB,YAAY;AAC9D,MAAI,kBAAkB,UAAa,CAAC,WAAW,aAAa;AAC1D,UAAM,IAAI,MAAM,mDAAmD;AACrE,MAAI,YAAY,IAAI,IAAI,EAAG,QAAO;AAClC,cAAY,IAAI,IAAI;AACpB,QAAM,aAAa,YAAY,IAAI;AACnC,QAAM,YAAYA,MAAK,KAAK,eAAe,GAAG,YAAY;AAC1D,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,QAAe,EAAE,SAAS,GAAG,IAAI,WAAW,GAAG,KAAK,QAAQ,KAAK,QAAQ;AAC/E,MAAI;AACJ,MAAI,YAAY;AAEhB,QAAM,cAAc,CAAC,WAAmB;AACtC,QAAI,UAAU;AACZ,YAAMC,WAAU,UAAU,MAAM;AAChC,UAAIA,SAAQ,QAAQ,SAAS,OAAOA,SAAQ,QAAQ,SAAS,IAAK;AAAA,IACpE;AACA,QAAI;AACJ,QAAI;AACF,YAAM,SAAS,UAAU,SAAS;AAClC,UACE,CAAC,OAAO,OAAO,KACf,OAAO,eAAe,KACtB,OAAO,UAAU,KACjB,OAAO,OAAO,QACb,QAAQ,aAAa,WAAW,OAAO,OAAO;AAE/C;AACF,gBAAU,KAAK,MAAM,aAAa,WAAW,MAAM,CAAC;AAAA,IACtD,SAAS,OAAO;AACd,UAAK,MAAgC,SAAS,SAAU,OAAM;AAAA,IAChE;AACA,QAAI,aAAa,YAAY,OAAW;AACxC,QACE,YAAY,WACX,CAAC,WAAW,OAAO,KACjB,QAAQ,OAAO,MAAM,OAAO,aAAa,QAAQ,OAAQ,eAAqC;AAEjG;AACF,cAAU,MAAM;AAAA,EAClB;AACA,QAAM,UAAU;AAAA,IACd,GAAG;AAAA,IACH,MAAM,CAAC,QAAgB,aACrB,KAAK,QAAQ,CAAC,OAAO,UAAU;AAC7B,UAAI,CAAC,SAAS,MAAM,UAAU,KAAK,IAAI,IAAI,UAAU;AACnD,cAAMC,YAAW,GAAG,MAAM,GAAG,IAAI,MAAM,GAAG,IAAI,MAAM,OAAO;AAC3D,cAAM,WAAW,aAAa,IAAI,MAAM;AACxC,YAAI,CAAC,YAAY,SAAS,aAAaA;AACrC,uBAAa,IAAI,QAAQ,EAAE,UAAAA,WAAU,OAAO,YAAY,IAAI,EAAE,CAAC;AAAA,iBACxD,YAAY,IAAI,IAAI,SAAS,QAAQ,SAAU,OAAM,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,WAAW,CAAC;AAAA,MAC1G,MAAO,cAAa,OAAO,MAAM;AACjC,eAAS,OAAO,KAAK;AAAA,IACvB,CAAC;AAAA,IACH,WAAW;AAAA,IACX,OAAO,CAAC,QAAgB,aAA6D;AACnF,UAAI;AACF,oBAAY,MAAM;AAClB,iBAAS;AAAA,MACX,SAAS,OAAO;AACd,iBAAS,KAA8B;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AACA,MAAI,cAAc;AAClB,MAAI;AACJ,MAAI;AACF,aAAS,MAAM,SAAS,KAAK,MAAM;AAAA,MACjC,IAAI;AAAA,MACJ,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,eAAe,MAAM;AACnB,sBAAc;AACd,mBAAW,MAAM,IAAI,aAAa,kCAAkC,YAAY,CAAC;AAAA,MACnF;AAAA,IACF,CAAC;AAAA,EACH,SAAS,OAAO;AACd,gBAAY,OAAO,IAAI;AACvB,QAAK,MAAgC,SAAS,UAAW,QAAO;AAChE,UAAM;AAAA,EACR;AACA,MAAI,WAAW;AACf,QAAM,UAAU,YAAY;AAC1B,QAAI,SAAU;AACd,eAAW;AACX,eAAW,MAAM,IAAI,aAAa,kCAAkC,YAAY,CAAC;AACjF,QAAI;AACF,UAAI,CAAC,YAAa,OAAM,OAAO;AAAA,IACjC,UAAE;AACA,kBAAY,OAAO,IAAI;AACvB,mBAAa,OAAO,SAAS;AAAA,IAC/B;AAAA,EACF;AACA,MAAI;AACF,eAAW,MAAMH,IAAG,MAAM,SAAS;AACnC,UAAM,SAAS,oBAAoB,YAAY;AAC7C,YAAM,WAAW,MAAM,sBAAsB,YAAY;AACzD,UAAI,aAAa,UAAa,CAAC,WAAW,QAAQ;AAChD,cAAM,IAAI,MAAM,mDAAmD;AACrE,UACG,UAAgC,OAAQ,eAAqC,MAC9E,YAAY,IAAI,IAAI,aAAa;AAEjC,cAAM,IAAI,MAAM,yDAAyD;AAC3E,YAAM,UAAU,UAAU,SAAS;AACnC,UAAI,WAAW,OAAO,WAAW,QAAQ,QAAQ,UAAU,OAAO,QAAQ,QAAQ,SAAS;AACzF,cAAM,IAAI,MAAM,8CAA8C;AAChE,YAAM,uBAAuB,cAAc,KAAK;AAChD,kBAAY;AAAA,IACd,CAAC;AACD,UAAM,SAAS,MAAM;AACnB,iBAAW,OAAO,eAAe;AACjC,UAAI;AACF,cAAM,OAAO,UAAU,eAAe,CAAC;AACvC,YAAI,CAAC,KAAK,YAAY,KAAK,KAAK,eAAe,KAAM,QAAQ,aAAa,WAAW,KAAK,OAAO;AAC/F,gBAAM,IAAI,MAAM,mBAAmB;AACrC,cAAMI,QAAO,UAAU,SAAS;AAChC,YACEA,MAAK,eAAe,KACpB,CAACA,MAAK,YAAY,KAClBA,MAAK,QAAQ,UAAU,OACvBA,MAAK,QAAQ,SAAS,OACtB,KAAK,IAAI,IAAIA,MAAK,UAAU;AAE5B,gBAAM,IAAI,MAAM,qBAAqB;AACvC,cAAM,SAAS,UAAU,SAAS;AAClC,YACE,CAAC,OAAO,OAAO,KACf,OAAO,eAAe,KACtB,OAAO,UAAU,KACjB,OAAO,OAAO,QACb,QAAQ,aAAa,WAAW,OAAO,OAAO;AAE/C,gBAAM,IAAI,MAAM,qBAAqB;AACvC,cAAM,QAAiB,KAAK,MAAM,aAAa,WAAW,MAAM,CAAC;AACjE,YAAI,CAAC,WAAW,KAAK,KAAK,MAAM,OAAO,MAAM,MAAM,MAAM,YAAY,WAAW,MAAM,QAAQ,QAAQ;AACpG,gBAAM,IAAI,MAAM,qBAAqB;AAAA,MACzC,QAAQ;AACN,mBAAW,MAAM,IAAI,aAAa,kCAAkC,YAAY,CAAC;AACjF,mBAAW,OAAO,eAAe;AAAA,MACnC;AAAA,IACF;AACA,WAAO;AACP,WAAO,EAAE,QAAQ,WAAW,QAAQ,QAAQ,QAAQ;AAAA,EACtD,SAAS,OAAO;AACd,UAAM,QAAQ;AACd,UAAM;AAAA,EACR;AACF;;;AErNO,IAAM,oBAAoB,KAAK;AAkBtC,IAAM,SAAS,CAAC,UAAmB,OAAO,UAAU,YAAY,kBAAkB,KAAK,KAAK;AAC5F,IAAM,YAAY,CAAC,UACjB,OAAO,UAAU,YAAY,OAAO,cAAc,KAAK,KAAK,SAAS,KAAK,SAAS;AAC9E,SAAS,yBAAyB,OAAgB,SAAoD;AAC3G,QAAM,SAAS;AACf,MACE,CAAC,UACD,OAAO,WAAW,YAClB,OAAO,YAAY,KACnB,OAAO,YAAY,WACnB,OAAO,KAAK,MAAM,EAAE;AAAA,IAClB,CAAC,QACC,CAAC;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,SAAS,GAAG;AAAA,EAClB,KACA,OAAO,OAAO,YAAY,aAC1B,CAAC,CAAC,WAAW,WAAW,SAAS,SAAS,EAAE,SAAS,OAAO,KAAK,KACjE,CAAC,UAAU,OAAO,IAAI,KACtB,CAAC,UAAU,OAAO,QAAQ,KAC1B,OAAO,WAAW,MACjB,OAAO,aAAa,UAAa,CAAC,OAAO,OAAO,QAAQ,KACxD,OAAO,aAAa,UAAa,CAAC,OAAO,OAAO,QAAQ,KACxD,OAAO,WAAW,UAAa,CAAC,OAAO,OAAO,MAAM,KACpD,OAAO,kBAAkB,UAAa,CAAC,OAAO,OAAO,aAAa,KAClE,OAAO,UAAU,UAChB,CAAC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,SAAS,OAAO,KAAK,KACxB,OAAO,YAAY,UAAa,CAAC,UAAU,OAAO,OAAO,KACzD,OAAO,gBAAgB,UAAa,CAAC,UAAU,OAAO,WAAW,KAClE,CAAC,MAAM,QAAQ,OAAO,KAAK,KAC3B,OAAO,MAAM,SAAS,KACtB,OAAO,MAAM;AAAA,IACX,CAAC,SAAS,CAAC,QAAQ,OAAO,KAAK,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,YAAY,CAAC,OAAO,KAAK,GAAG,KAAK,CAAC,UAAU,KAAK,EAAE;AAAA,EAC/G,KACA,CAAC,OAAO,YACR,OAAO,OAAO,aAAa,YAC3B,MAAM,QAAQ,OAAO,QAAQ,KAC7B,OAAO,QAAQ,OAAO,QAAQ,EAAE;AAAA,IAC9B,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,KAAK,QAAQ;AAAA,EACrF,KACA,OAAO,MAAM;AAAA,IACX,CAAC,UAAU,OAAO,SAAS,KAAK,GAAG,KAAK,KAAK,OAAO,MAAM,OAAO,CAAC,UAAU,MAAM,QAAQ,KAAK,GAAG,EAAE;AAAA,EACtG;AAEA,UAAM,IAAI,MAAM,mDAAmD;AACvE;AACA,eAAsB,qBAAqB,SAA4C;AACrF,QAAM,QAAQ,MAAM,sBAAsB,GAAG,OAAO,OAAO;AAC3D,MAAI,UAAU;AACZ,WAAO,EAAE,SAAS,GAAG,SAAS,SAAS,MAAM,OAAO,WAAW,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,GAAG,UAAU,CAAC,EAAE;AAC/G,2BAAyB,OAAO,OAAO;AACvC,SAAO;AACT;AACA,eAAsB,uBACpB,SACA,OACA,QACY;AACZ,SAAO;AAAA,IAAyB,MAC9B,SAAS,oBAAoB,YAAY;AACvC,YAAM,OAAO;AACb,YAAM,SAAS,MAAM,qBAAqB,OAAO;AACjD,YAAM,OAAO;AACb,YAAM,SAAS,OAAO,MAAM;AAC5B,+BAAyB,QAAQ,OAAO;AACxC,YAAM,OAAO;AACb,YAAM,uBAAuB,GAAG,OAAO,SAAS,MAAM;AACtD,YAAM,OAAO;AACb,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;AACO,SAAS,yBAAyB,QAA0B,KAAa;AAE9E,SAAO,QAAQ,OAAO,MACnB,IAAI,CAAC,UAAU,EAAE,GAAG,MAAM,IAAI,KAAK,IAAI,KAAK,IAAI,GAAG,EAAE,EAAE,EACvD,OAAO,CAAC,SAAS,MAAM,KAAK,KAAK,iBAAiB;AACrD,SAAO,OAAO,KAAK,IAAI,OAAO,MAAM,OAAO,OAAO,UAAU,WAAW,oBAAoB,IAAQ;AACrG;AACA,eAAsB,yBACpB,SACA,OACA,KACA,QAAsB,KAAK,KAC3B;AACA,MAAI,CAAC,OAAO,GAAG,EAAG,OAAM,IAAI,MAAM,mCAAmC;AACrE,MAAI;AACJ,QAAM,uBAAuB,SAAS,OAAO,CAAC,WAAW;AACvD,UAAM,MAAM,MAAM;AAClB,6BAAyB,QAAQ,GAAG;AACpC,SAAK,OAAO,SAAS,GAAG,KAAK,MAAM;AACjC,gBAAU,IAAI;AAAA,QACZ;AAAA,QACA;AAAA,MACF;AAAA,aACO,OAAO,MAAM,UAAU;AAC9B,gBAAU,IAAI;AAAA,QACZ;AAAA,QACA;AAAA,QACA,KAAK,IAAI,IAAI,OAAO,MAAM,CAAC,GAAG,MAAM,OAAO,oBAAoB,GAAG;AAAA,MACpE;AAAA,SACG;AACH,aAAO,SAAS,GAAG,KAAK,OAAO,SAAS,GAAG,KAAK,KAAK;AACrD,aAAO,MAAM,KAAK,EAAE,KAAK,IAAI,IAAI,CAAC;AAAA,IACpC;AAAA,EACF,CAAC;AACD,MAAI,QAAS,OAAM;AACrB;AAGA,eAAsB,sBAAsB,QAA0C;AACpF,MAAI,CAAC,OAAO,WAAY,QAAO,CAAC,sBAAsB;AACtD,MAAI,CAAC,OAAO,UAAW,QAAO,CAAC,kDAAkD;AACjF,MAAI;AACF,UAAM,SAAS,MAAM,qBAAqB,MAAM,kBAAkB,MAAM,CAAC;AACzE,WAAO;AAAA,MACL,oBAAoB,OAAO,KAAK,GAAG,OAAO,QAAQ,KAAK,OAAO,KAAK,MAAM,EAAE;AAAA,MAC3E,MAAM,qBAAqB,OAAO,OAAO;AAAA,MACzC,qCAAqC,OAAO,UAAU,IAAI,KAAK,OAAO,OAAO,EAAE,YAAY,IAAI,iBAAiB;AAAA,MAChH,wCAAwC,OAAO,cAAc,IAAI,KAAK,OAAO,WAAW,EAAE,YAAY,IAAI,MAAM;AAAA,MAChH,GAAI,OAAO,UAAU,UAAU,CAAC,4BAA4B,IAAI,KAAK,OAAO,IAAI,EAAE,YAAY,CAAC,EAAE,IAAI,CAAC;AAAA,MACtG,GAAI,OAAO,UAAU,YACjB,CAAC,wGAAwG,IACzG,CAAC;AAAA,MACL;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO,CAAC,gGAAgG;AAAA,EAC1G;AACF;",
|
|
6
|
+
"names": ["fs", "path", "stat", "fs", "path", "current", "identity", "stat"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// @generated by scripts/build-runtime.mjs; do not edit.
|
|
2
|
+
// @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
|
|
3
|
+
|
|
4
|
+
// src/backends/snapshot-pointer.ts
|
|
5
|
+
function createLatestPointer(namespace, snapshot, checksum) {
|
|
6
|
+
return {
|
|
7
|
+
version: 1,
|
|
8
|
+
profile: namespace,
|
|
9
|
+
snapshot: snapshot.id,
|
|
10
|
+
sha256: checksum,
|
|
11
|
+
createdAt: snapshot.createdAt,
|
|
12
|
+
machine: snapshot.machine,
|
|
13
|
+
syncSessions: snapshot.syncSessions === true || snapshot.files.some((file) => file.path.startsWith("sessions/")),
|
|
14
|
+
...snapshot.selection === void 0 ? {} : { selection: snapshot.selection }
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function remoteHistoryEntry(pointer) {
|
|
18
|
+
return {
|
|
19
|
+
snapshotRef: pointer.snapshot,
|
|
20
|
+
snapshotId: pointer.snapshot,
|
|
21
|
+
createdAt: pointer.createdAt,
|
|
22
|
+
machine: pointer.machine,
|
|
23
|
+
syncSessions: pointer.syncSessions === true
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
createLatestPointer,
|
|
29
|
+
remoteHistoryEntry
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=chunk-YHT4YTYG.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/backends/snapshot-pointer.ts"],
|
|
4
|
+
"sourcesContent": ["import type { Snapshot } from \"../snapshot/snapshot-types.js\";\nimport type { LatestPointer } from \"./backend-types.js\";\nimport type { RemoteHistoryEntry } from \"./sync-backend.js\";\n\n/** Shared latest/history metadata for the S3 and WebDAV object-store format. */\nexport function createLatestPointer(namespace: string, snapshot: Snapshot, checksum: string): LatestPointer {\n return {\n version: 1,\n profile: namespace,\n snapshot: snapshot.id,\n sha256: checksum,\n createdAt: snapshot.createdAt,\n machine: snapshot.machine,\n syncSessions: snapshot.syncSessions === true || snapshot.files.some((file) => file.path.startsWith(\"sessions/\")),\n ...(snapshot.selection === undefined ? {} : { selection: snapshot.selection }),\n };\n}\n\nexport function remoteHistoryEntry(pointer: LatestPointer): RemoteHistoryEntry {\n return {\n snapshotRef: pointer.snapshot,\n snapshotId: pointer.snapshot,\n createdAt: pointer.createdAt,\n machine: pointer.machine,\n syncSessions: pointer.syncSessions === true,\n };\n}\n"],
|
|
5
|
+
"mappings": ";;;;AAKO,SAAS,oBAAoB,WAAmB,UAAoB,UAAiC;AAC1G,SAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS;AAAA,IACT,UAAU,SAAS;AAAA,IACnB,QAAQ;AAAA,IACR,WAAW,SAAS;AAAA,IACpB,SAAS,SAAS;AAAA,IAClB,cAAc,SAAS,iBAAiB,QAAQ,SAAS,MAAM,KAAK,CAAC,SAAS,KAAK,KAAK,WAAW,WAAW,CAAC;AAAA,IAC/G,GAAI,SAAS,cAAc,SAAY,CAAC,IAAI,EAAE,WAAW,SAAS,UAAU;AAAA,EAC9E;AACF;AAEO,SAAS,mBAAmB,SAA4C;AAC7E,SAAO;AAAA,IACL,aAAa,QAAQ;AAAA,IACrB,YAAY,QAAQ;AAAA,IACpB,WAAW,QAAQ;AAAA,IACnB,SAAS,QAAQ;AAAA,IACjB,cAAc,QAAQ,iBAAiB;AAAA,EACzC;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -5,11 +5,14 @@ import {
|
|
|
5
5
|
} from "./chunk-AMJRUXFT.ts";
|
|
6
6
|
import {
|
|
7
7
|
syncConfigReviewFingerprint
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-QO333NM4.ts";
|
|
9
9
|
import {
|
|
10
10
|
sameLocalFields,
|
|
11
11
|
validatePortableSnapshot
|
|
12
12
|
} from "./chunk-A6HU4ERM.ts";
|
|
13
|
+
import {
|
|
14
|
+
throwIfAborted
|
|
15
|
+
} from "./chunk-PWMWOJP4.ts";
|
|
13
16
|
import {
|
|
14
17
|
filterSnapshotForConfigPolicy,
|
|
15
18
|
inspectRemoteSelection,
|
|
@@ -21,9 +24,7 @@ import {
|
|
|
21
24
|
// src/sync/remote-snapshot.ts
|
|
22
25
|
async function readSnapshotForHead(backend, head, signal) {
|
|
23
26
|
const snapshot = await backend.readSnapshot(head.snapshotRef, signal);
|
|
24
|
-
|
|
25
|
-
throw signal.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted", "AbortError");
|
|
26
|
-
}
|
|
27
|
+
throwIfAborted(signal);
|
|
27
28
|
validatePortableSnapshot(snapshot);
|
|
28
29
|
if (snapshot.id !== head.snapshotId) {
|
|
29
30
|
throw new Error(`Remote head ${head.snapshotId} resolved to unexpected snapshot ${snapshot.id}.`);
|
|
@@ -83,4 +84,4 @@ export {
|
|
|
83
84
|
formatRemoteSelectionStatus,
|
|
84
85
|
readRemoteSnapshot
|
|
85
86
|
};
|
|
86
|
-
//# sourceMappingURL=chunk-
|
|
87
|
+
//# sourceMappingURL=chunk-YK52VDXG.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/sync/remote-snapshot.ts"],
|
|
4
|
+
"sourcesContent": ["import type { RemoteHead, SyncBackend } from \"../backends/sync-backend.js\";\nimport { syncConfigReviewFingerprint } from \"../settings/config.js\";\nimport type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport { filterSnapshotForConfigPolicy } from \"../snapshot/snapshot.js\";\nimport type { Snapshot } from \"../snapshot/snapshot-types.js\";\nimport { safeTerminalText } from \"../ui/terminal-text.js\";\nimport { sameLocalFields, validatePortableSnapshot } from \"./local-fields.js\";\nimport { throwIfAborted } from \"./signals.js\";\nimport {\n inspectRemoteSelection,\n type RemoteSelectionState,\n remoteSelectionMismatch,\n sameSyncInclude,\n snapshotSelectionInclude,\n} from \"./sync-policy.js\";\n\nexport async function readSnapshotForHead(backend: SyncBackend, head: RemoteHead, signal?: AbortSignal) {\n const snapshot = await backend.readSnapshot(head.snapshotRef, signal);\n throwIfAborted(signal);\n validatePortableSnapshot(snapshot);\n if (snapshot.id !== head.snapshotId) {\n throw new Error(`Remote head ${head.snapshotId} resolved to unexpected snapshot ${snapshot.id}.`);\n }\n if (head.selection) {\n const snapshotInclude = snapshotSelectionInclude(snapshot);\n if (!snapshotInclude || !sameSyncInclude(head.selection.include, snapshotInclude)) {\n throw new Error(\"Remote head selection does not match its immutable snapshot.\");\n }\n }\n return snapshot;\n}\n\nexport function requireCompatibleRemoteSelection(config: AnySyncConfig, snapshot: Snapshot) {\n if (!sameLocalFields(config.localFields, snapshot.localFields))\n throw new Error(\n \"Remote local-field policy differs; confirm a reviewed directional migration. Old history is not erased.\",\n );\n const state = inspectRemoteSelection(config.include, snapshot);\n if (state.kind === \"different\") {\n throw remoteSelectionMismatch(config, state.include, syncConfigReviewFingerprint(config));\n }\n}\n\nexport function formatRemoteSelectionStatus(state: RemoteSelectionState | undefined) {\n if (!state) return \"remote included content: unavailable (remote is empty)\";\n if (state.kind === \"same\") return \"remote included content: matches this setup\";\n if (state.kind === \"legacy\") {\n return `remote included content: unavailable in legacy snapshot (${state.discovered.length} path${state.discovered.length === 1 ? \"\" : \"s\"} discovered, partial)`;\n }\n return [\n \"remote included content: differs from this setup\",\n `remote-only selection: ${safeList(state.remoteOnly)}`,\n `local-only selection: ${safeList(state.localOnly)}`,\n ].join(\"\\n\");\n}\n\nfunction safeList(values: readonly string[]) {\n return values.length > 0 ? values.map(safeTerminalText).join(\", \") : \"none\";\n}\n\nexport async function readRemoteSnapshot(\n backend: SyncBackend,\n config: AnySyncConfig,\n signal?: AbortSignal,\n options: { allowSelectionDifference?: boolean } = {},\n) {\n const head = await backend.readHead(signal);\n if (!head) return { head: undefined, snapshot: undefined, selectionState: undefined };\n const snapshot = await readSnapshotForHead(backend, head, signal);\n const selectionState = inspectRemoteSelection(config.include, snapshot);\n if (!options.allowSelectionDifference && selectionState.kind === \"different\") {\n const configIdentity = syncConfigReviewFingerprint(config);\n throw remoteSelectionMismatch(config, selectionState.include, configIdentity);\n }\n return {\n head,\n snapshot: filterSnapshotForConfigPolicy(snapshot, config),\n selectionState,\n };\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAgBA,eAAsB,oBAAoB,SAAsB,MAAkB,QAAsB;AACtG,QAAM,WAAW,MAAM,QAAQ,aAAa,KAAK,aAAa,MAAM;AACpE,iBAAe,MAAM;AACrB,2BAAyB,QAAQ;AACjC,MAAI,SAAS,OAAO,KAAK,YAAY;AACnC,UAAM,IAAI,MAAM,eAAe,KAAK,UAAU,oCAAoC,SAAS,EAAE,GAAG;AAAA,EAClG;AACA,MAAI,KAAK,WAAW;AAClB,UAAM,kBAAkB,yBAAyB,QAAQ;AACzD,QAAI,CAAC,mBAAmB,CAAC,gBAAgB,KAAK,UAAU,SAAS,eAAe,GAAG;AACjF,YAAM,IAAI,MAAM,8DAA8D;AAAA,IAChF;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,iCAAiC,QAAuB,UAAoB;AAC1F,MAAI,CAAC,gBAAgB,OAAO,aAAa,SAAS,WAAW;AAC3D,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AACF,QAAM,QAAQ,uBAAuB,OAAO,SAAS,QAAQ;AAC7D,MAAI,MAAM,SAAS,aAAa;AAC9B,UAAM,wBAAwB,QAAQ,MAAM,SAAS,4BAA4B,MAAM,CAAC;AAAA,EAC1F;AACF;AAEO,SAAS,4BAA4B,OAAyC;AACnF,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,MAAM,SAAS,OAAQ,QAAO;AAClC,MAAI,MAAM,SAAS,UAAU;AAC3B,WAAO,4DAA4D,MAAM,WAAW,MAAM,QAAQ,MAAM,WAAW,WAAW,IAAI,KAAK,GAAG;AAAA,EAC5I;AACA,SAAO;AAAA,IACL;AAAA,IACA,0BAA0B,SAAS,MAAM,UAAU,CAAC;AAAA,IACpD,yBAAyB,SAAS,MAAM,SAAS,CAAC;AAAA,EACpD,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,SAAS,QAA2B;AAC3C,SAAO,OAAO,SAAS,IAAI,OAAO,IAAI,gBAAgB,EAAE,KAAK,IAAI,IAAI;AACvE;AAEA,eAAsB,mBACpB,SACA,QACA,QACA,UAAkD,CAAC,GACnD;AACA,QAAM,OAAO,MAAM,QAAQ,SAAS,MAAM;AAC1C,MAAI,CAAC,KAAM,QAAO,EAAE,MAAM,QAAW,UAAU,QAAW,gBAAgB,OAAU;AACpF,QAAM,WAAW,MAAM,oBAAoB,SAAS,MAAM,MAAM;AAChE,QAAM,iBAAiB,uBAAuB,OAAO,SAAS,QAAQ;AACtE,MAAI,CAAC,QAAQ,4BAA4B,eAAe,SAAS,aAAa;AAC5E,UAAM,iBAAiB,4BAA4B,MAAM;AACzD,UAAM,wBAAwB,QAAQ,eAAe,SAAS,cAAc;AAAA,EAC9E;AACA,SAAO;AAAA,IACL;AAAA,IACA,UAAU,8BAA8B,UAAU,MAAM;AAAA,IACxD;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// @generated by scripts/build-runtime.mjs; do not edit.
|
|
2
|
+
// @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
|
|
3
|
+
import {
|
|
4
|
+
isEnabled,
|
|
5
|
+
isExplicitlyEnabled,
|
|
6
|
+
loadConfig,
|
|
7
|
+
loadConfigForCheck,
|
|
8
|
+
loadPartialConfig,
|
|
9
|
+
sessionTokenWarnings,
|
|
10
|
+
syncCheckConfigFingerprint,
|
|
11
|
+
syncConfigReviewFingerprint,
|
|
12
|
+
syncConfigReviewIdentity,
|
|
13
|
+
syncSessionsWarnings,
|
|
14
|
+
syncSetupReviewIdentity,
|
|
15
|
+
syncSetupStorageReview
|
|
16
|
+
} from "./chunk-QO333NM4.ts";
|
|
17
|
+
import "./chunk-A6HU4ERM.ts";
|
|
18
|
+
import "./chunk-QOFMXPM5.ts";
|
|
19
|
+
import "./chunk-ZW5ZLGBI.ts";
|
|
20
|
+
import "./chunk-2JZFHNLM.ts";
|
|
21
|
+
import "./chunk-T2SJD3N7.ts";
|
|
22
|
+
import "./chunk-HUZ5CR4W.ts";
|
|
23
|
+
export {
|
|
24
|
+
isEnabled,
|
|
25
|
+
isExplicitlyEnabled,
|
|
26
|
+
loadConfig,
|
|
27
|
+
loadConfigForCheck,
|
|
28
|
+
loadPartialConfig,
|
|
29
|
+
sessionTokenWarnings,
|
|
30
|
+
syncCheckConfigFingerprint,
|
|
31
|
+
syncConfigReviewFingerprint,
|
|
32
|
+
syncConfigReviewIdentity,
|
|
33
|
+
syncSessionsWarnings,
|
|
34
|
+
syncSetupReviewIdentity,
|
|
35
|
+
syncSetupStorageReview
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=config-KGIYTTXQ.ts.map
|
|
@@ -6,16 +6,17 @@ import {
|
|
|
6
6
|
conflictGroups,
|
|
7
7
|
readConflictArtifact,
|
|
8
8
|
saveConflictArtifact
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ED3TYIVW.ts";
|
|
10
|
+
import "./chunk-GNH73BJ5.ts";
|
|
10
11
|
import "./chunk-BDB4IDM3.ts";
|
|
11
|
-
import "./chunk-76NB4R7U.ts";
|
|
12
|
-
import "./chunk-4QVPTIZB.ts";
|
|
13
|
-
import "./chunk-BVVP33U5.ts";
|
|
14
|
-
import "./chunk-2JZFHNLM.ts";
|
|
15
|
-
import "./chunk-T2SJD3N7.ts";
|
|
16
12
|
import "./chunk-A6HU4ERM.ts";
|
|
17
13
|
import "./chunk-QOFMXPM5.ts";
|
|
14
|
+
import "./chunk-76NB4R7U.ts";
|
|
18
15
|
import "./chunk-ZW5ZLGBI.ts";
|
|
16
|
+
import "./chunk-UPNVIUBN.ts";
|
|
17
|
+
import "./chunk-SWRVXVFD.ts";
|
|
18
|
+
import "./chunk-2JZFHNLM.ts";
|
|
19
|
+
import "./chunk-T2SJD3N7.ts";
|
|
19
20
|
import "./chunk-HUZ5CR4W.ts";
|
|
20
21
|
export {
|
|
21
22
|
conflictArtifactFingerprint,
|
|
@@ -24,4 +25,4 @@ export {
|
|
|
24
25
|
readConflictArtifact,
|
|
25
26
|
saveConflictArtifact
|
|
26
27
|
};
|
|
27
|
-
//# sourceMappingURL=conflict-artifacts-
|
|
28
|
+
//# sourceMappingURL=conflict-artifacts-FXFIIBCB.ts.map
|