@narumitw/pi-sync 0.51.1 → 0.52.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -5
- package/dist/chunks/{chunk-7KHKWL3Q.ts → chunk-2CBF6SMT.ts} +8 -7
- package/dist/chunks/chunk-2CBF6SMT.ts.map +7 -0
- package/dist/chunks/{chunk-YFADF5ZQ.ts → chunk-2DI6PDZV.ts} +5 -1
- package/dist/chunks/chunk-2DI6PDZV.ts.map +7 -0
- package/dist/chunks/{chunk-4MPIH46N.ts → chunk-3B4Z2SKV.ts} +40 -6
- package/dist/chunks/chunk-3B4Z2SKV.ts.map +7 -0
- package/dist/chunks/{chunk-YPXGU5OR.ts → chunk-4QVPTIZB.ts} +16 -6
- package/dist/chunks/{chunk-YPXGU5OR.ts.map → chunk-4QVPTIZB.ts.map} +2 -2
- package/dist/chunks/{chunk-UA7RXOIT.ts → chunk-4SBTAVFL.ts} +6 -6
- package/dist/chunks/{chunk-6546TS54.ts → chunk-5RZPINUQ.ts} +7 -4
- package/dist/chunks/{chunk-6546TS54.ts.map → chunk-5RZPINUQ.ts.map} +2 -2
- package/dist/chunks/chunk-76NB4R7U.ts +107 -0
- package/dist/chunks/chunk-76NB4R7U.ts.map +7 -0
- package/dist/chunks/{chunk-DM4X4FIA.ts → chunk-7D6RDCVC.ts} +8 -10
- package/dist/chunks/{chunk-DM4X4FIA.ts.map → chunk-7D6RDCVC.ts.map} +2 -2
- package/dist/chunks/chunk-A6HU4ERM.ts +124 -0
- package/dist/chunks/chunk-A6HU4ERM.ts.map +7 -0
- package/dist/chunks/chunk-AMJRUXFT.ts +17 -0
- package/dist/chunks/chunk-AMJRUXFT.ts.map +7 -0
- package/dist/chunks/chunk-ANWNQIR7.ts +1013 -0
- package/dist/chunks/chunk-ANWNQIR7.ts.map +7 -0
- package/dist/chunks/{chunk-T56RNRZJ.ts → chunk-BDB4IDM3.ts} +19 -10
- package/dist/chunks/chunk-BDB4IDM3.ts.map +7 -0
- package/dist/chunks/{chunk-2RZSQWBH.ts → chunk-CHSIAC4N.ts} +5 -5
- package/dist/chunks/{chunk-2RZSQWBH.ts.map → chunk-CHSIAC4N.ts.map} +2 -2
- package/dist/chunks/chunk-HUZ5CR4W.ts +110 -0
- package/dist/chunks/chunk-HUZ5CR4W.ts.map +7 -0
- package/dist/chunks/{chunk-QLSN7AGX.ts → chunk-IJ6VV6FN.ts} +81 -19
- package/dist/chunks/chunk-IJ6VV6FN.ts.map +7 -0
- package/dist/chunks/chunk-NLS2NV3K.ts +1746 -0
- package/dist/chunks/chunk-NLS2NV3K.ts.map +7 -0
- package/dist/chunks/chunk-ORQRHEEO.ts +362 -0
- package/dist/chunks/chunk-ORQRHEEO.ts.map +7 -0
- package/dist/chunks/chunk-QE7NZZWT.ts +380 -0
- package/dist/chunks/chunk-QE7NZZWT.ts.map +7 -0
- package/dist/chunks/{chunk-HGJH56KR.ts → chunk-QHSQCK7L.ts} +4 -4
- package/dist/chunks/chunk-QOFMXPM5.ts +735 -0
- package/dist/chunks/chunk-QOFMXPM5.ts.map +7 -0
- package/dist/chunks/{chunk-DZUSTGQV.ts → chunk-UQ3ALBIB.ts} +4 -4
- package/dist/chunks/{chunk-Q32CQWPM.ts → chunk-V6VZ5TLG.ts} +13 -6
- package/dist/chunks/chunk-V6VZ5TLG.ts.map +7 -0
- package/dist/chunks/{chunk-E42GXD6D.ts → chunk-WKPX2SIC.ts} +4 -4
- package/dist/chunks/chunk-ZW5ZLGBI.ts +154 -0
- package/dist/chunks/chunk-ZW5ZLGBI.ts.map +7 -0
- package/dist/chunks/{chunk-6NT3YFGY.ts → chunk-ZX2Q6THB.ts} +8 -3
- package/dist/chunks/{chunk-6NT3YFGY.ts.map → chunk-ZX2Q6THB.ts.map} +2 -2
- package/dist/chunks/conflict-artifacts-BB2FZMIE.ts +27 -0
- package/dist/chunks/conflict-review-4WPGCXFB.ts +175 -0
- package/dist/chunks/conflict-review-4WPGCXFB.ts.map +7 -0
- package/dist/chunks/{file-selection-RAVHRYFG.ts → file-selection-WZX7HAY2.ts} +8 -7
- package/dist/chunks/{file-selection-RAVHRYFG.ts.map → file-selection-WZX7HAY2.ts.map} +1 -1
- package/dist/chunks/{git-backend-IAANDL3K.ts → git-backend-HLGKUQJT.ts} +19 -7
- package/dist/chunks/git-backend-HLGKUQJT.ts.map +7 -0
- package/dist/chunks/local-fields-6DGYOOIK.ts +22 -0
- package/dist/chunks/manager-result-dispatcher-VIDT3QBU.ts +23 -0
- package/dist/chunks/{manager-ui-763NEKJY.ts → manager-ui-HSMHS3OK.ts} +236 -57
- package/dist/chunks/manager-ui-HSMHS3OK.ts.map +7 -0
- package/dist/chunks/merge-baseline-store-EVQAAML6.ts +22 -0
- package/dist/chunks/remote-selection-ui-SMF5CLFO.ts +22 -0
- package/dist/chunks/{s3-backend-XGXUOPUN.ts → s3-backend-DJ2NT3SZ.ts} +16 -9
- package/dist/chunks/s3-backend-DJ2NT3SZ.ts.map +7 -0
- package/dist/chunks/{setup-switch-5G2VNJHL.ts → setup-switch-KTUWL6DE.ts} +9 -6
- package/dist/chunks/{setup-wizard-YIEWGX32.ts → setup-wizard-GSDPDFC4.ts} +10 -7
- package/dist/chunks/{setup-wizard-YIEWGX32.ts.map → setup-wizard-GSDPDFC4.ts.map} +1 -1
- package/dist/chunks/{snapshot-JL5DFSXI.ts → snapshot-THS5EY2L.ts} +6 -9
- package/dist/chunks/snapshot-THS5EY2L.ts.map +7 -0
- package/dist/chunks/{sync-inspection-P3ENJLNF.ts → sync-inspection-VBJF2FWC.ts} +10 -10
- package/dist/chunks/sync-inspection-VBJF2FWC.ts.map +7 -0
- package/dist/chunks/{sync-operations-AR76EB6C.ts → sync-operations-RHNECOOG.ts} +309 -508
- package/dist/chunks/sync-operations-RHNECOOG.ts.map +7 -0
- package/dist/chunks/{sync-state-VHJUZ4YG.ts → sync-state-CFL4RRRB.ts} +6 -6
- package/dist/chunks/sync-state-CFL4RRRB.ts.map +7 -0
- package/dist/chunks/{webdav-backend-3EGUONAT.ts → webdav-backend-ETQGSI6I.ts} +13 -7
- package/dist/chunks/webdav-backend-ETQGSI6I.ts.map +7 -0
- package/dist/index.ts +142 -43
- package/dist/index.ts.map +2 -2
- package/docs/content-merge-audit.md +156 -0
- package/docs/merge-implementation-audit.md +312 -0
- package/docs/settings-merge-audit.md +153 -0
- package/docs/settings.md +36 -0
- package/package.json +5 -5
- package/src/backends/git/git-backend.ts +2 -0
- package/src/backends/git/git-storage.ts +8 -3
- package/src/backends/s3/s3-backend.ts +2 -1
- package/src/backends/webdav/webdav-backend.ts +2 -1
- package/src/commands/command-execution.ts +10 -0
- package/src/commands/command.ts +4 -0
- package/src/settings/config.ts +12 -0
- package/src/settings/settings-management.ts +2 -2
- package/src/settings/settings-types.ts +14 -1
- package/src/settings/settings-validation.ts +24 -3
- package/src/snapshot/session-paths.ts +34 -7
- package/src/snapshot/snapshot-apply.ts +81 -32
- package/src/snapshot/snapshot-case-replacement.ts +80 -0
- package/src/snapshot/snapshot-codec.ts +6 -1
- package/src/snapshot/snapshot-root-transition.ts +154 -0
- package/src/snapshot/snapshot-transaction-plan.ts +72 -0
- package/src/snapshot/snapshot-transaction.ts +844 -102
- package/src/snapshot/snapshot-types.ts +5 -0
- package/src/state/json-file.ts +32 -5
- package/src/state/merge-baseline-store.ts +182 -0
- package/src/state/mutation-directory-sync.ts +34 -0
- package/src/state/state-types.ts +4 -0
- package/src/state/sync-state-store.ts +14 -1
- package/src/sync/automatic-sync.ts +11 -3
- package/src/sync/conflict-artifact-ownership.ts +63 -0
- package/src/sync/conflict-artifacts.ts +195 -0
- package/src/sync/conflict-groups.ts +68 -0
- package/src/sync/conflict-preview.ts +56 -0
- package/src/sync/conflict-resolution.ts +93 -0
- package/src/sync/conflict-retention.ts +72 -0
- package/src/sync/conflict-review.ts +95 -0
- package/src/sync/content-conflicts.ts +73 -0
- package/src/sync/field-migration.ts +39 -0
- package/src/sync/file-merge-planner.ts +143 -0
- package/src/sync/json-document.ts +184 -0
- package/src/sync/local-fields.ts +134 -0
- package/src/sync/merge-apply.ts +428 -0
- package/src/sync/merge-journal.ts +219 -0
- package/src/sync/merged-sync.ts +723 -0
- package/src/sync/partial-progress.ts +54 -0
- package/src/sync/remote-snapshot.ts +6 -0
- package/src/sync/session-merge.ts +194 -0
- package/src/sync/settings-conflicts.ts +52 -0
- package/src/sync/settings-merge.ts +57 -0
- package/src/sync/startup-check.ts +90 -5
- package/src/sync/sync-inspection.ts +1 -0
- package/src/sync/sync-local.ts +61 -0
- package/src/sync/sync-mutations.ts +256 -114
- package/src/sync/sync-queries.ts +6 -2
- package/src/sync/sync-state.ts +14 -5
- package/src/sync/text-merge.ts +133 -0
- package/src/sync-extension.ts +8 -0
- package/src/ui/manager-state.ts +12 -1
- package/src/ui/manager-ui.ts +10 -0
- package/src/ui/merge-review.ts +28 -0
- package/src/ui/remote-selection-ui.ts +1 -0
- package/src/ui/settings-ui.ts +183 -2
- package/src/ui/setup/setup-actions.ts +2 -2
- package/src/ui/setup/setup-switcher.ts +2 -1
- package/src/ui/storage-connections-ui.ts +11 -7
- package/src/ui/sync-attention.ts +3 -0
- package/src/ui/sync-format.ts +16 -12
- package/src/ui/sync-setups-ui.ts +1 -0
- package/src/ui/terminal-text.ts +9 -2
- package/dist/chunks/chunk-4AIHXRKE.ts +0 -197
- package/dist/chunks/chunk-4AIHXRKE.ts.map +0 -7
- package/dist/chunks/chunk-4MPIH46N.ts.map +0 -7
- package/dist/chunks/chunk-7KHKWL3Q.ts.map +0 -7
- package/dist/chunks/chunk-EEJPYTWE.ts +0 -348
- package/dist/chunks/chunk-EEJPYTWE.ts.map +0 -7
- package/dist/chunks/chunk-IVXEDPAD.ts +0 -370
- package/dist/chunks/chunk-IVXEDPAD.ts.map +0 -7
- package/dist/chunks/chunk-MSSW6F3R.ts +0 -12
- package/dist/chunks/chunk-MSSW6F3R.ts.map +0 -7
- package/dist/chunks/chunk-OVDTF5CH.ts +0 -90
- package/dist/chunks/chunk-OVDTF5CH.ts.map +0 -7
- package/dist/chunks/chunk-Q32CQWPM.ts.map +0 -7
- package/dist/chunks/chunk-QLSN7AGX.ts.map +0 -7
- package/dist/chunks/chunk-SWUXA3MH.ts +0 -18
- package/dist/chunks/chunk-SWUXA3MH.ts.map +0 -7
- package/dist/chunks/chunk-T56RNRZJ.ts.map +0 -7
- package/dist/chunks/chunk-YFADF5ZQ.ts.map +0 -7
- package/dist/chunks/git-backend-IAANDL3K.ts.map +0 -7
- package/dist/chunks/manager-result-dispatcher-OTUMQM26.ts +0 -23
- package/dist/chunks/manager-ui-763NEKJY.ts.map +0 -7
- package/dist/chunks/remote-selection-ui-TZTJF32Y.ts +0 -22
- package/dist/chunks/s3-backend-XGXUOPUN.ts.map +0 -7
- package/dist/chunks/sync-operations-AR76EB6C.ts.map +0 -7
- package/dist/chunks/webdav-backend-3EGUONAT.ts.map +0 -7
- /package/dist/chunks/{chunk-UA7RXOIT.ts.map → chunk-4SBTAVFL.ts.map} +0 -0
- /package/dist/chunks/{chunk-HGJH56KR.ts.map → chunk-QHSQCK7L.ts.map} +0 -0
- /package/dist/chunks/{chunk-DZUSTGQV.ts.map → chunk-UQ3ALBIB.ts.map} +0 -0
- /package/dist/chunks/{chunk-E42GXD6D.ts.map → chunk-WKPX2SIC.ts.map} +0 -0
- /package/dist/chunks/{manager-result-dispatcher-OTUMQM26.ts.map → conflict-artifacts-BB2FZMIE.ts.map} +0 -0
- /package/dist/chunks/{remote-selection-ui-TZTJF32Y.ts.map → local-fields-6DGYOOIK.ts.map} +0 -0
- /package/dist/chunks/{setup-switch-5G2VNJHL.ts.map → manager-result-dispatcher-VIDT3QBU.ts.map} +0 -0
- /package/dist/chunks/{snapshot-JL5DFSXI.ts.map → merge-baseline-store-EVQAAML6.ts.map} +0 -0
- /package/dist/chunks/{sync-inspection-P3ENJLNF.ts.map → remote-selection-ui-SMF5CLFO.ts.map} +0 -0
- /package/dist/chunks/{sync-state-VHJUZ4YG.ts.map → setup-switch-KTUWL6DE.ts.map} +0 -0
|
@@ -1,18 +1,77 @@
|
|
|
1
1
|
// @generated by scripts/build-runtime.mjs; do not edit.
|
|
2
2
|
// @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
|
|
3
|
+
import {
|
|
4
|
+
throwIfAborted
|
|
5
|
+
} from "./chunk-PWMWOJP4.ts";
|
|
3
6
|
import {
|
|
4
7
|
ensureStateDir,
|
|
5
8
|
lockPath
|
|
6
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-4QVPTIZB.ts";
|
|
7
10
|
import {
|
|
8
11
|
LOCKFILE_FS_ADAPTER,
|
|
9
12
|
LOCK_GUARD_STALE_MS,
|
|
10
|
-
LOCK_GUARD_UPDATE_MS
|
|
13
|
+
LOCK_GUARD_UPDATE_MS,
|
|
14
|
+
stateDir
|
|
11
15
|
} from "./chunk-BVVP33U5.ts";
|
|
16
|
+
import {
|
|
17
|
+
encodeSnapshot
|
|
18
|
+
} from "./chunk-ZX2Q6THB.ts";
|
|
19
|
+
import {
|
|
20
|
+
agentDir,
|
|
21
|
+
createSnapshot,
|
|
22
|
+
sessionDirFromContext,
|
|
23
|
+
sessionSnapshotPathFromAbsolute
|
|
24
|
+
} from "./chunk-QOFMXPM5.ts";
|
|
25
|
+
import {
|
|
26
|
+
syncDirectory
|
|
27
|
+
} from "./chunk-HUZ5CR4W.ts";
|
|
28
|
+
|
|
29
|
+
// src/sync/sync-local.ts
|
|
30
|
+
import fs from "node:fs/promises";
|
|
31
|
+
import path from "node:path";
|
|
32
|
+
function protectedSessionPaths(ctx, sessionRoot = sessionDirFromContext(ctx)) {
|
|
33
|
+
const getSessionFile = ctx.sessionManager.getSessionFile;
|
|
34
|
+
if (typeof getSessionFile !== "function") return /* @__PURE__ */ new Set();
|
|
35
|
+
const sessionFile = getSessionFile.call(ctx.sessionManager);
|
|
36
|
+
const snapshotPath = sessionFile ? sessionSnapshotPathFromAbsolute(sessionFile, sessionRoot) : void 0;
|
|
37
|
+
return snapshotPath ? /* @__PURE__ */ new Set([snapshotPath]) : /* @__PURE__ */ new Set();
|
|
38
|
+
}
|
|
39
|
+
function captureMutationOwner(ctx, signal) {
|
|
40
|
+
const manager = ctx.sessionManager;
|
|
41
|
+
const file = manager.getSessionFile?.();
|
|
42
|
+
const id = manager.getSessionId?.();
|
|
43
|
+
const cwd = manager.getCwd?.();
|
|
44
|
+
const root = agentDir();
|
|
45
|
+
return () => {
|
|
46
|
+
throwIfAborted(signal);
|
|
47
|
+
if (ctx.sessionManager !== manager || manager.getSessionFile?.() !== file || manager.getSessionId?.() !== id || manager.getCwd?.() !== cwd || agentDir() !== root)
|
|
48
|
+
throw new Error("Session changed during file mutation; evidence retained for review.");
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
async function backupLocal(profile, options = {}, signal) {
|
|
52
|
+
throwIfAborted(signal);
|
|
53
|
+
const snapshot = await createSnapshot(profile, { ...options, signal });
|
|
54
|
+
throwIfAborted(signal);
|
|
55
|
+
const backupDirectory = path.join(stateDir(), "backups");
|
|
56
|
+
await fs.mkdir(backupDirectory, { recursive: true, mode: 448 });
|
|
57
|
+
throwIfAborted(signal);
|
|
58
|
+
const backupPath = path.join(backupDirectory, `${snapshot.id}.json.gz`);
|
|
59
|
+
const encoded = await encodeSnapshot(snapshot);
|
|
60
|
+
throwIfAborted(signal);
|
|
61
|
+
const handle = await fs.open(backupPath, "wx", 384);
|
|
62
|
+
try {
|
|
63
|
+
await handle.writeFile(encoded);
|
|
64
|
+
await handle.sync();
|
|
65
|
+
} finally {
|
|
66
|
+
await handle.close();
|
|
67
|
+
}
|
|
68
|
+
await syncDirectory(backupDirectory);
|
|
69
|
+
return backupPath;
|
|
70
|
+
}
|
|
12
71
|
|
|
13
72
|
// src/state/lock.ts
|
|
14
73
|
import { randomUUID } from "node:crypto";
|
|
15
|
-
import
|
|
74
|
+
import fs2 from "node:fs/promises";
|
|
16
75
|
import lockfile from "proper-lockfile";
|
|
17
76
|
var LOCK_STALE_MS = 30 * 60 * 1e3;
|
|
18
77
|
var MAX_PROCESS_ID = 2147483647;
|
|
@@ -45,7 +104,7 @@ async function withLock(command, fn, options = {}) {
|
|
|
45
104
|
if (rechecked.status !== "valid" || rechecked.lock.id !== inspection.lock.id || !isStaleLock(rechecked.lock)) {
|
|
46
105
|
throw new Error("pi-sync lock changed while preparing transaction recovery; retry.");
|
|
47
106
|
}
|
|
48
|
-
await
|
|
107
|
+
await fs2.rm(lockPath(), { force: true });
|
|
49
108
|
inspection = { status: "missing" };
|
|
50
109
|
}
|
|
51
110
|
if (inspection.status === "valid") {
|
|
@@ -58,7 +117,7 @@ async function withLock(command, fn, options = {}) {
|
|
|
58
117
|
"pi-sync lock metadata is unreadable. Run /sync unlock --stale after verifying no sync is running."
|
|
59
118
|
);
|
|
60
119
|
}
|
|
61
|
-
await
|
|
120
|
+
await fs2.writeFile(lockPath(), JSON.stringify(lock, null, " "), { flag: "wx" });
|
|
62
121
|
guard.throwIfCompromised();
|
|
63
122
|
result = await fn();
|
|
64
123
|
guard.throwIfCompromised();
|
|
@@ -68,7 +127,7 @@ async function withLock(command, fn, options = {}) {
|
|
|
68
127
|
}
|
|
69
128
|
try {
|
|
70
129
|
const current = await readLock();
|
|
71
|
-
if (current?.id === lock.id) await
|
|
130
|
+
if (current?.id === lock.id) await fs2.rm(lockPath(), { force: true });
|
|
72
131
|
} catch (error) {
|
|
73
132
|
if (!failed) {
|
|
74
133
|
failed = true;
|
|
@@ -87,7 +146,7 @@ async function withLock(command, fn, options = {}) {
|
|
|
87
146
|
}
|
|
88
147
|
async function inspectLock() {
|
|
89
148
|
try {
|
|
90
|
-
const text = await
|
|
149
|
+
const text = await fs2.readFile(lockPath(), "utf8");
|
|
91
150
|
if (text.trim().length === 0) return { status: "unreadable" };
|
|
92
151
|
const parsed = JSON.parse(text);
|
|
93
152
|
return isLockFile(parsed) ? { status: "valid", lock: parsed } : { status: "unreadable" };
|
|
@@ -119,9 +178,9 @@ function isStaleLock(lock) {
|
|
|
119
178
|
}
|
|
120
179
|
}
|
|
121
180
|
async function unlock(ctx, options) {
|
|
122
|
-
|
|
181
|
+
throwIfAborted2(options.signal);
|
|
123
182
|
await ensureStateDir();
|
|
124
|
-
|
|
183
|
+
throwIfAborted2(options.signal);
|
|
125
184
|
let guard;
|
|
126
185
|
try {
|
|
127
186
|
guard = await acquireGuard();
|
|
@@ -146,9 +205,9 @@ async function unlock(ctx, options) {
|
|
|
146
205
|
if (failed) throw failure;
|
|
147
206
|
}
|
|
148
207
|
async function unlockGuarded(ctx, options) {
|
|
149
|
-
|
|
208
|
+
throwIfAborted2(options.signal);
|
|
150
209
|
let inspection = await inspectLock();
|
|
151
|
-
|
|
210
|
+
throwIfAborted2(options.signal);
|
|
152
211
|
if (inspection.status === "missing") {
|
|
153
212
|
ctx.ui.notify("No pi-sync lock is present.", "info");
|
|
154
213
|
return;
|
|
@@ -162,10 +221,10 @@ async function unlockGuarded(ctx, options) {
|
|
|
162
221
|
return;
|
|
163
222
|
}
|
|
164
223
|
inspection = await inspectLock();
|
|
165
|
-
|
|
224
|
+
throwIfAborted2(options.signal);
|
|
166
225
|
if (inspection.status === "unreadable") {
|
|
167
|
-
|
|
168
|
-
await
|
|
226
|
+
throwIfAborted2(options.signal);
|
|
227
|
+
await fs2.rm(lockPath(), { force: true });
|
|
169
228
|
if (!options.signal?.aborted) {
|
|
170
229
|
ctx.ui.notify(
|
|
171
230
|
"Removed unreadable pi-sync lock. No settings, files, sync state, or remote data were changed.",
|
|
@@ -183,13 +242,13 @@ async function unlockGuarded(ctx, options) {
|
|
|
183
242
|
ctx.ui.notify("Lock owner is still live; refusing to remove it.", "warning");
|
|
184
243
|
return;
|
|
185
244
|
}
|
|
186
|
-
|
|
187
|
-
await
|
|
245
|
+
throwIfAborted2(options.signal);
|
|
246
|
+
await fs2.rm(lockPath(), { force: true });
|
|
188
247
|
if (!options.signal?.aborted) {
|
|
189
248
|
ctx.ui.notify("Removed stale pi-sync lock. No settings, files, sync state, or remote data were changed.", "info");
|
|
190
249
|
}
|
|
191
250
|
}
|
|
192
|
-
function
|
|
251
|
+
function throwIfAborted2(signal) {
|
|
193
252
|
if (!signal?.aborted) return;
|
|
194
253
|
throw signal.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted", "AbortError");
|
|
195
254
|
}
|
|
@@ -247,6 +306,9 @@ export {
|
|
|
247
306
|
inspectLock,
|
|
248
307
|
isLockGuardHeld,
|
|
249
308
|
isStaleLock,
|
|
250
|
-
unlock
|
|
309
|
+
unlock,
|
|
310
|
+
protectedSessionPaths,
|
|
311
|
+
captureMutationOwner,
|
|
312
|
+
backupLocal
|
|
251
313
|
};
|
|
252
|
-
//# sourceMappingURL=chunk-
|
|
314
|
+
//# sourceMappingURL=chunk-IJ6VV6FN.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/sync/sync-local.ts", "../../src/state/lock.ts"],
|
|
4
|
+
"sourcesContent": ["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ExtensionCommandContext, ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { agentDir, sessionDirFromContext } from \"../snapshot/session-paths.js\";\nimport { createSnapshot, sessionSnapshotPathFromAbsolute } from \"../snapshot/snapshot.js\";\nimport { encodeSnapshot } from \"../snapshot/snapshot-codec.js\";\nimport type { SnapshotOptions } from \"../snapshot/snapshot-types.js\";\nimport { syncDirectory } from \"../state/json-file.js\";\nimport { stateDir } from \"../state/state-directory.js\";\nimport { throwIfAborted } from \"./signals.js\";\n\nexport function protectedSessionPaths(\n ctx: ExtensionCommandContext | ExtensionContext,\n sessionRoot = sessionDirFromContext(ctx),\n) {\n const getSessionFile = ctx.sessionManager.getSessionFile;\n if (typeof getSessionFile !== \"function\") return new Set<string>();\n const sessionFile = getSessionFile.call(ctx.sessionManager) as string | undefined;\n const snapshotPath = sessionFile ? sessionSnapshotPathFromAbsolute(sessionFile, sessionRoot) : undefined;\n return snapshotPath ? new Set([snapshotPath]) : new Set<string>();\n}\n\nexport function captureMutationOwner(ctx: ExtensionContext | ExtensionCommandContext, signal?: AbortSignal) {\n const manager = ctx.sessionManager;\n const file = manager.getSessionFile?.();\n const id = manager.getSessionId?.();\n const cwd = manager.getCwd?.();\n const root = agentDir();\n return () => {\n throwIfAborted(signal);\n if (\n ctx.sessionManager !== manager ||\n manager.getSessionFile?.() !== file ||\n manager.getSessionId?.() !== id ||\n manager.getCwd?.() !== cwd ||\n agentDir() !== root\n )\n throw new Error(\"Session changed during file mutation; evidence retained for review.\");\n };\n}\n\nexport async function backupLocal(profile: string, options: SnapshotOptions = {}, signal?: AbortSignal) {\n throwIfAborted(signal);\n const snapshot = await createSnapshot(profile, { ...options, signal });\n throwIfAborted(signal);\n const backupDirectory = path.join(stateDir(), \"backups\");\n await fs.mkdir(backupDirectory, { recursive: true, mode: 0o700 });\n throwIfAborted(signal);\n const backupPath = path.join(backupDirectory, `${snapshot.id}.json.gz`);\n const encoded = await encodeSnapshot(snapshot);\n throwIfAborted(signal);\n const handle = await fs.open(backupPath, \"wx\", 0o600);\n try {\n await handle.writeFile(encoded);\n await handle.sync();\n } finally {\n await handle.close();\n }\n await syncDirectory(backupDirectory);\n return backupPath;\n}\n", "import { randomUUID } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport lockfile from \"proper-lockfile\";\nimport type { CommandOptions } from \"../commands/command-types.js\";\nimport { LOCK_GUARD_STALE_MS, LOCK_GUARD_UPDATE_MS } from \"./lock-policy.js\";\nimport { LOCKFILE_FS_ADAPTER } from \"./lockfile-fs.js\";\nimport type { LockFile } from \"./state-types.js\";\nimport { ensureStateDir, lockPath } from \"./sync-state-store.js\";\n\nconst LOCK_STALE_MS = 30 * 60 * 1000;\nconst MAX_PROCESS_ID = 2_147_483_647;\n\ninterface Guard {\n release: () => Promise<void>;\n throwIfCompromised: () => void;\n isCompromised: () => boolean;\n}\n\nexport type LockInspection = { status: \"missing\" } | { status: \"unreadable\" } | { status: \"valid\"; lock: LockFile };\n\nexport async function withLock<T>(\n command: string,\n fn: () => Promise<T>,\n options: { reclaimStale?: boolean } = {},\n): Promise<T> {\n await ensureStateDir();\n const lock: LockFile = {\n id: randomUUID(),\n pid: process.pid,\n command,\n startedAt: new Date().toISOString(),\n };\n let guard: Guard | undefined;\n let result: T | undefined;\n let failed = false;\n let failure: unknown;\n try {\n try {\n guard = await acquireGuard();\n } catch (error) {\n if (!isLockHeldError(error)) throw error;\n throw await describeHeldLock();\n }\n\n let inspection = await inspectLock();\n if (inspection.status === \"valid\" && isStaleLock(inspection.lock)) {\n if (!options.reclaimStale) {\n throw new Error(`pi-sync lock is stale (pid ${inspection.lock.pid}). Run /sync unlock --stale, then retry.`);\n }\n guard.throwIfCompromised();\n const rechecked = await inspectLock();\n if (rechecked.status !== \"valid\" || rechecked.lock.id !== inspection.lock.id || !isStaleLock(rechecked.lock)) {\n throw new Error(\"pi-sync lock changed while preparing transaction recovery; retry.\");\n }\n await fs.rm(lockPath(), { force: true });\n inspection = { status: \"missing\" };\n }\n if (inspection.status === \"valid\") {\n throw new Error(\n `pi-sync is already running (${inspection.lock.command}, pid ${inspection.lock.pid}, started ${inspection.lock.startedAt}).`,\n );\n }\n if (inspection.status === \"unreadable\") {\n throw new Error(\n \"pi-sync lock metadata is unreadable. Run /sync unlock --stale after verifying no sync is running.\",\n );\n }\n\n await fs.writeFile(lockPath(), JSON.stringify(lock, null, \"\\t\"), { flag: \"wx\" });\n guard.throwIfCompromised();\n result = await fn();\n guard.throwIfCompromised();\n } catch (error) {\n failed = true;\n failure = error;\n }\n\n try {\n const current = await readLock();\n if (current?.id === lock.id) await fs.rm(lockPath(), { force: true });\n } catch (error) {\n if (!failed) {\n failed = true;\n failure = error;\n }\n }\n if (guard) {\n const releaseError = await releaseGuard(guard);\n if (releaseError && !failed) {\n failed = true;\n failure = releaseError;\n }\n }\n if (failed) throw failure;\n return result as T;\n}\n\nexport async function inspectLock(): Promise<LockInspection> {\n try {\n const text = await fs.readFile(lockPath(), \"utf8\");\n if (text.trim().length === 0) return { status: \"unreadable\" };\n const parsed = JSON.parse(text) as unknown;\n return isLockFile(parsed) ? { status: \"valid\", lock: parsed } : { status: \"unreadable\" };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return { status: \"missing\" };\n if (error instanceof SyntaxError) return { status: \"unreadable\" };\n throw error;\n }\n}\n\nexport async function readLock(): Promise<LockFile | undefined> {\n const inspection = await inspectLock();\n return inspection.status === \"valid\" ? inspection.lock : undefined;\n}\n\nexport async function lockFileExists(): Promise<boolean> {\n try {\n await fs.stat(lockPath());\n return true;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw error;\n }\n}\n\nexport function isLockGuardHeld() {\n return lockfile.check(lockPath(), {\n fs: LOCKFILE_FS_ADAPTER,\n lockfilePath: `${lockPath()}.guard`,\n realpath: false,\n stale: LOCK_GUARD_STALE_MS,\n });\n}\n\nexport function isStaleLock(lock: LockFile) {\n try {\n process.kill(lock.pid, 0);\n return false;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ESRCH\") return true;\n return Date.now() - Date.parse(lock.startedAt) > LOCK_STALE_MS;\n }\n}\n\nexport async function unlock(ctx: ExtensionCommandContext, options: CommandOptions) {\n throwIfAborted(options.signal);\n await ensureStateDir();\n throwIfAborted(options.signal);\n let guard: Guard;\n try {\n guard = await acquireGuard();\n } catch (error) {\n if (!isLockHeldError(error)) throw error;\n ctx.ui.notify((await describeHeldLock()).message, \"warning\");\n return;\n }\n\n let failed = false;\n let failure: unknown;\n try {\n await unlockGuarded(ctx, options);\n } catch (error) {\n failed = true;\n failure = error;\n }\n const releaseError = await releaseGuard(guard);\n if (releaseError && !failed) {\n failed = true;\n failure = releaseError;\n }\n if (failed) throw failure;\n}\n\nasync function unlockGuarded(ctx: ExtensionCommandContext, options: CommandOptions) {\n throwIfAborted(options.signal);\n let inspection = await inspectLock();\n throwIfAborted(options.signal);\n if (inspection.status === \"missing\") {\n ctx.ui.notify(\"No pi-sync lock is present.\", \"info\");\n return;\n }\n if (inspection.status === \"unreadable\") {\n if (!options.stale) {\n ctx.ui.notify(\n \"Pi-sync lock metadata is unreadable. Use /sync unlock --stale only after verifying no sync is running.\",\n \"warning\",\n );\n return;\n }\n inspection = await inspectLock();\n throwIfAborted(options.signal);\n if (inspection.status === \"unreadable\") {\n // Legacy writers expose an empty file before writing owner metadata, so no\n // automatic test can prove this file is abandoned. The explicit --stale\n // flag is the user's confirmation that no legacy sync is still running.\n throwIfAborted(options.signal);\n await fs.rm(lockPath(), { force: true });\n if (!options.signal?.aborted) {\n ctx.ui.notify(\n \"Removed unreadable pi-sync lock. No settings, files, sync state, or remote data were changed.\",\n \"info\",\n );\n }\n return;\n }\n if (inspection.status === \"missing\") {\n ctx.ui.notify(\"No pi-sync lock is present.\", \"info\");\n return;\n }\n }\n if (!isStaleLock(inspection.lock)) {\n ctx.ui.notify(\"Lock owner is still live; refusing to remove it.\", \"warning\");\n return;\n }\n throwIfAborted(options.signal);\n await fs.rm(lockPath(), { force: true });\n if (!options.signal?.aborted) {\n ctx.ui.notify(\"Removed stale pi-sync lock. No settings, files, sync state, or remote data were changed.\", \"info\");\n }\n}\n\nfunction throwIfAborted(signal?: AbortSignal) {\n if (!signal?.aborted) return;\n throw signal.reason instanceof Error ? signal.reason : new DOMException(\"The operation was aborted\", \"AbortError\");\n}\n\nasync function releaseGuard(guard: Guard) {\n try {\n await guard.release();\n return undefined;\n } catch (error) {\n return guard.isCompromised() ? undefined : error;\n }\n}\n\nasync function acquireGuard(): Promise<Guard> {\n let compromisedError: Error | undefined;\n const release = await lockfile.lock(lockPath(), {\n fs: LOCKFILE_FS_ADAPTER,\n lockfilePath: `${lockPath()}.guard`,\n realpath: false,\n stale: LOCK_GUARD_STALE_MS,\n update: LOCK_GUARD_UPDATE_MS,\n onCompromised: (error) => {\n compromisedError = error;\n },\n });\n return {\n release,\n throwIfCompromised: () => {\n if (compromisedError) throw compromisedError;\n },\n isCompromised: () => compromisedError !== undefined,\n };\n}\n\nasync function describeHeldLock() {\n const current = await readLock();\n if (current && isStaleLock(current)) {\n return new Error(\"pi-sync lock owner exited; retry shortly while the lock guard expires.\");\n }\n if (current) {\n return new Error(\n `Pi-sync is currently running (${current.command}, pid ${current.pid}, started ${current.startedAt}).`,\n );\n }\n return new Error(\"Pi-sync is currently running (lock metadata is unreadable or still being written).\");\n}\n\nfunction isLockHeldError(error: unknown) {\n return (error as NodeJS.ErrnoException).code === \"ELOCKED\";\n}\n\nfunction isLockFile(value: unknown): value is LockFile {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const lock = value as Partial<LockFile>;\n return (\n typeof lock.id === \"string\" &&\n lock.id.length > 0 &&\n Number.isInteger(lock.pid) &&\n (lock.pid ?? 0) > 0 &&\n (lock.pid ?? 0) <= MAX_PROCESS_ID &&\n typeof lock.command === \"string\" &&\n lock.command.length > 0 &&\n typeof lock.startedAt === \"string\" &&\n Number.isFinite(Date.parse(lock.startedAt))\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["fs", "fs", "throwIfAborted", "fs"]
|
|
7
|
+
}
|