@narumitw/pi-sync 0.50.3 → 0.51.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 +4 -1
- package/dist/chunks/{chunk-6LP3MCR2.ts → chunk-2JZFHNLM.ts} +3 -5
- package/dist/chunks/chunk-2JZFHNLM.ts.map +7 -0
- package/dist/chunks/{chunk-LCRI3ABW.ts → chunk-2RZSQWBH.ts} +8 -19
- package/dist/chunks/chunk-2RZSQWBH.ts.map +7 -0
- package/dist/chunks/{chunk-IJ6FJFA5.ts → chunk-4AIHXRKE.ts} +11 -17
- package/dist/chunks/chunk-4AIHXRKE.ts.map +7 -0
- package/dist/chunks/{chunk-C7XY5NF5.ts → chunk-4MPIH46N.ts} +29 -51
- package/dist/chunks/chunk-4MPIH46N.ts.map +7 -0
- package/dist/chunks/{chunk-5B3FXBLE.ts → chunk-6546TS54.ts} +16 -20
- package/dist/chunks/chunk-6546TS54.ts.map +7 -0
- package/dist/chunks/{chunk-Q2TUM5X6.ts → chunk-6NT3YFGY.ts} +2 -2
- package/dist/chunks/chunk-6NT3YFGY.ts.map +7 -0
- package/dist/chunks/{chunk-2B2ELUF5.ts → chunk-7D5SF7P3.ts} +1 -1
- package/dist/chunks/chunk-7D5SF7P3.ts.map +7 -0
- package/dist/chunks/{chunk-YDWUZVPN.ts → chunk-7KHKWL3Q.ts} +28 -47
- package/dist/chunks/chunk-7KHKWL3Q.ts.map +7 -0
- package/dist/chunks/{chunk-ZI5MXMEX.ts → chunk-BVVP33U5.ts} +2 -4
- package/dist/chunks/chunk-BVVP33U5.ts.map +7 -0
- package/dist/chunks/{chunk-SZWBGPID.ts → chunk-DM4X4FIA.ts} +8 -13
- package/dist/chunks/chunk-DM4X4FIA.ts.map +7 -0
- package/dist/chunks/{chunk-SL64RLXR.ts → chunk-DZUSTGQV.ts} +8 -16
- package/dist/chunks/chunk-DZUSTGQV.ts.map +7 -0
- package/dist/chunks/{chunk-YHEMENKV.ts → chunk-E42GXD6D.ts} +13 -19
- package/dist/chunks/chunk-E42GXD6D.ts.map +7 -0
- package/dist/chunks/{chunk-Z4DQF6L3.ts → chunk-ECYCNZOE.ts} +1 -1
- package/dist/chunks/chunk-ECYCNZOE.ts.map +7 -0
- package/dist/chunks/{chunk-OEX4ABY6.ts → chunk-EEJPYTWE.ts} +11 -21
- package/dist/chunks/chunk-EEJPYTWE.ts.map +7 -0
- package/dist/chunks/{chunk-CPEHGXJV.ts → chunk-G4RUXRWZ.ts} +3 -5
- package/dist/chunks/chunk-G4RUXRWZ.ts.map +7 -0
- package/dist/chunks/{chunk-T2B5IU74.ts → chunk-HGJH56KR.ts} +4 -4
- package/dist/chunks/chunk-HGJH56KR.ts.map +7 -0
- package/dist/chunks/{chunk-JAAKLL6M.ts → chunk-IVXEDPAD.ts} +10 -34
- package/dist/chunks/chunk-IVXEDPAD.ts.map +7 -0
- package/dist/chunks/chunk-K3RIEL6J.ts +20 -0
- package/dist/chunks/chunk-K3RIEL6J.ts.map +7 -0
- package/dist/chunks/{chunk-LTBWGSBV.ts → chunk-MSSW6F3R.ts} +1 -1
- package/dist/chunks/chunk-MSSW6F3R.ts.map +7 -0
- package/dist/chunks/{chunk-T3HH3UEJ.ts → chunk-OVDTF5CH.ts} +4 -10
- package/dist/chunks/chunk-OVDTF5CH.ts.map +7 -0
- package/dist/chunks/{chunk-NJFUIVYL.ts → chunk-PWMWOJP4.ts} +1 -1
- package/dist/chunks/chunk-PWMWOJP4.ts.map +7 -0
- package/dist/chunks/{chunk-HUDQATCL.ts → chunk-Q32CQWPM.ts} +6 -8
- package/dist/chunks/chunk-Q32CQWPM.ts.map +7 -0
- package/dist/chunks/{chunk-ETTRJDNP.ts → chunk-QLSN7AGX.ts} +6 -13
- package/dist/chunks/chunk-QLSN7AGX.ts.map +7 -0
- package/dist/chunks/{chunk-THMF4BVL.ts → chunk-SWUXA3MH.ts} +1 -1
- package/dist/chunks/chunk-SWUXA3MH.ts.map +7 -0
- package/dist/chunks/{chunk-TEN2ZBJV.ts → chunk-T2SJD3N7.ts} +2 -4
- package/dist/chunks/chunk-T2SJD3N7.ts.map +7 -0
- package/dist/chunks/{chunk-AUSDLD6F.ts → chunk-T56RNRZJ.ts} +10 -26
- package/dist/chunks/chunk-T56RNRZJ.ts.map +7 -0
- package/dist/chunks/{chunk-DHVFS4QK.ts → chunk-UA7RXOIT.ts} +37 -90
- package/dist/chunks/chunk-UA7RXOIT.ts.map +7 -0
- package/dist/chunks/{chunk-D5X27LCA.ts → chunk-UETBKTDI.ts} +1 -1
- package/dist/chunks/chunk-UETBKTDI.ts.map +7 -0
- package/dist/chunks/{chunk-CHH26D4F.ts → chunk-YFADF5ZQ.ts} +7 -6
- package/dist/chunks/chunk-YFADF5ZQ.ts.map +7 -0
- package/dist/chunks/{chunk-CCSN3F47.ts → chunk-YPXGU5OR.ts} +4 -4
- package/dist/chunks/chunk-YPXGU5OR.ts.map +7 -0
- package/dist/chunks/{file-selection-FTTKAOYX.ts → file-selection-RAVHRYFG.ts} +14 -26
- package/dist/chunks/file-selection-RAVHRYFG.ts.map +7 -0
- package/dist/chunks/{git-backend-GMVS4PD4.ts → git-backend-IAANDL3K.ts} +41 -104
- package/dist/chunks/git-backend-IAANDL3K.ts.map +7 -0
- package/dist/chunks/manager-result-dispatcher-OTUMQM26.ts +23 -0
- package/dist/chunks/{manager-ui-IPAOAWZA.ts → manager-ui-763NEKJY.ts} +124 -251
- package/dist/chunks/manager-ui-763NEKJY.ts.map +7 -0
- package/dist/chunks/remote-selection-ui-TZTJF32Y.ts +22 -0
- package/dist/chunks/{s3-backend-66O4FGBH.ts → s3-backend-XGXUOPUN.ts} +23 -54
- package/dist/chunks/s3-backend-XGXUOPUN.ts.map +7 -0
- package/dist/chunks/{setup-switch-IS2PEZ3J.ts → setup-switch-5G2VNJHL.ts} +9 -9
- package/dist/chunks/{setup-wizard-JUJZYNNM.ts → setup-wizard-YIEWGX32.ts} +12 -12
- package/dist/chunks/setup-wizard-YIEWGX32.ts.map +7 -0
- package/dist/chunks/{snapshot-HKEWCVK6.ts → snapshot-JL5DFSXI.ts} +5 -5
- package/dist/chunks/sync-inspection-P3ENJLNF.ts +20 -0
- package/dist/chunks/{sync-operations-LBX3GKCM.ts → sync-operations-AR76EB6C.ts} +85 -201
- package/dist/chunks/sync-operations-AR76EB6C.ts.map +7 -0
- package/dist/chunks/{sync-state-Q2FTXTW6.ts → sync-state-VHJUZ4YG.ts} +6 -6
- package/dist/chunks/{webdav-backend-ECIKD7SO.ts → webdav-backend-3EGUONAT.ts} +20 -51
- package/dist/chunks/webdav-backend-3EGUONAT.ts.map +7 -0
- package/dist/index.ts +49 -74
- package/dist/index.ts.map +3 -3
- package/docs/settings.md +9 -0
- package/package.json +61 -62
- package/src/backends/backend-factory.ts +15 -15
- package/src/backends/backend-identity.ts +31 -31
- package/src/backends/backend-types.ts +42 -42
- package/src/backends/git/git-backend.ts +714 -788
- package/src/backends/git/git-config.ts +104 -111
- package/src/backends/git/git-runner.ts +230 -247
- package/src/backends/git/git-storage.ts +228 -245
- package/src/backends/s3/s3-backend.ts +408 -441
- package/src/backends/s3/s3-client.ts +288 -333
- package/src/backends/sync-backend.ts +65 -65
- package/src/backends/webdav/webdav-backend.ts +542 -589
- package/src/backends/webdav/webdav-client.ts +292 -316
- package/src/backends/webdav/webdav-config.ts +57 -68
- package/src/commands/command-execution.ts +270 -289
- package/src/commands/command-handler.ts +160 -163
- package/src/commands/command-types.ts +13 -13
- package/src/commands/command.ts +190 -196
- package/src/commands/setup-completions.ts +1 -1
- package/src/paths.ts +47 -47
- package/src/settings/config-errors.ts +4 -5
- package/src/settings/config-file.ts +473 -506
- package/src/settings/config.ts +171 -174
- package/src/settings/settings-management.ts +191 -216
- package/src/settings/settings-store.ts +63 -77
- package/src/settings/settings-types.ts +78 -75
- package/src/settings/settings-validation.ts +328 -364
- package/src/snapshot/session-paths.ts +41 -55
- package/src/snapshot/snapshot-apply.ts +197 -229
- package/src/snapshot/snapshot-codec.ts +29 -31
- package/src/snapshot/snapshot-paths.ts +4 -6
- package/src/snapshot/snapshot-transaction.ts +161 -170
- package/src/snapshot/snapshot-types.ts +24 -24
- package/src/snapshot/snapshot.ts +310 -343
- package/src/state/json-file.ts +11 -11
- package/src/state/lock.ts +226 -242
- package/src/state/lockfile-fs.ts +20 -20
- package/src/state/operation-availability.ts +36 -41
- package/src/state/state-directory.ts +171 -173
- package/src/state/state-types.ts +15 -15
- package/src/state/sync-state-store.ts +23 -23
- package/src/sync/automatic-sync.ts +75 -80
- package/src/sync/remote-snapshot.ts +52 -60
- package/src/sync/setup-switch.ts +99 -114
- package/src/sync/signals.ts +3 -5
- package/src/sync/startup-check.ts +97 -111
- package/src/sync/sync-decision.ts +76 -80
- package/src/sync/sync-error-guidance.ts +41 -48
- package/src/sync/sync-errors.ts +10 -10
- package/src/sync/sync-inspection.ts +29 -33
- package/src/sync/sync-loaders.ts +28 -36
- package/src/sync/sync-mutations.ts +510 -622
- package/src/sync/sync-operations.ts +7 -7
- package/src/sync/sync-policy.ts +296 -326
- package/src/sync/sync-queries.ts +175 -194
- package/src/sync/sync-state.ts +74 -100
- package/src/sync-extension.ts +89 -101
- package/src/sync.ts +26 -26
- package/src/types.ts +37 -37
- package/src/ui/automatic-sync-summary.ts +1 -3
- package/src/ui/cancellable-operation.ts +89 -101
- package/src/ui/file-selection.ts +250 -274
- package/src/ui/manager-attention.ts +51 -63
- package/src/ui/manager-recovery.ts +48 -57
- package/src/ui/manager-result-dispatcher.ts +62 -76
- package/src/ui/manager-state.ts +200 -232
- package/src/ui/manager-ui.ts +264 -362
- package/src/ui/remote-selection-ui.ts +547 -588
- package/src/ui/secret-input.ts +197 -205
- package/src/ui/settings-ui.ts +175 -172
- package/src/ui/setup/git-ui.ts +232 -261
- package/src/ui/setup/s3-credentials-ui.ts +58 -65
- package/src/ui/setup/s3-ui.ts +171 -195
- package/src/ui/setup/setup-actions.ts +91 -101
- package/src/ui/setup/setup-location-ui.ts +121 -137
- package/src/ui/setup/setup-name-ui.ts +27 -27
- package/src/ui/setup/setup-prompts.ts +65 -65
- package/src/ui/setup/setup-review.ts +58 -59
- package/src/ui/setup/setup-switcher.ts +156 -160
- package/src/ui/setup/setup-wizard.ts +28 -28
- package/src/ui/setup/text-input.ts +54 -58
- package/src/ui/setup/webdav-ui.ts +246 -293
- package/src/ui/storage-connections-ui.ts +317 -369
- package/src/ui/sync-attention.ts +148 -164
- package/src/ui/sync-format.ts +110 -121
- package/src/ui/sync-resolution-ui.ts +147 -153
- package/src/ui/sync-setups-ui.ts +218 -238
- package/src/ui/sync-status.ts +17 -0
- package/src/ui/terminal-text.ts +2 -2
- package/dist/chunks/chunk-2B2ELUF5.ts.map +0 -7
- package/dist/chunks/chunk-5B3FXBLE.ts.map +0 -7
- package/dist/chunks/chunk-6LP3MCR2.ts.map +0 -7
- package/dist/chunks/chunk-AUSDLD6F.ts.map +0 -7
- package/dist/chunks/chunk-C7XY5NF5.ts.map +0 -7
- package/dist/chunks/chunk-CCSN3F47.ts.map +0 -7
- package/dist/chunks/chunk-CHH26D4F.ts.map +0 -7
- package/dist/chunks/chunk-CPEHGXJV.ts.map +0 -7
- package/dist/chunks/chunk-D5X27LCA.ts.map +0 -7
- package/dist/chunks/chunk-DHVFS4QK.ts.map +0 -7
- package/dist/chunks/chunk-ETTRJDNP.ts.map +0 -7
- package/dist/chunks/chunk-HUDQATCL.ts.map +0 -7
- package/dist/chunks/chunk-IJ6FJFA5.ts.map +0 -7
- package/dist/chunks/chunk-JAAKLL6M.ts.map +0 -7
- package/dist/chunks/chunk-LCRI3ABW.ts.map +0 -7
- package/dist/chunks/chunk-LTBWGSBV.ts.map +0 -7
- package/dist/chunks/chunk-NJFUIVYL.ts.map +0 -7
- package/dist/chunks/chunk-OEX4ABY6.ts.map +0 -7
- package/dist/chunks/chunk-Q2TUM5X6.ts.map +0 -7
- package/dist/chunks/chunk-SL64RLXR.ts.map +0 -7
- package/dist/chunks/chunk-SZWBGPID.ts.map +0 -7
- package/dist/chunks/chunk-T2B5IU74.ts.map +0 -7
- package/dist/chunks/chunk-T3HH3UEJ.ts.map +0 -7
- package/dist/chunks/chunk-TEN2ZBJV.ts.map +0 -7
- package/dist/chunks/chunk-THMF4BVL.ts.map +0 -7
- package/dist/chunks/chunk-YDWUZVPN.ts.map +0 -7
- package/dist/chunks/chunk-YHEMENKV.ts.map +0 -7
- package/dist/chunks/chunk-Z4DQF6L3.ts.map +0 -7
- package/dist/chunks/chunk-ZI5MXMEX.ts.map +0 -7
- package/dist/chunks/file-selection-FTTKAOYX.ts.map +0 -7
- package/dist/chunks/git-backend-GMVS4PD4.ts.map +0 -7
- package/dist/chunks/manager-result-dispatcher-ASKGOSW5.ts +0 -22
- package/dist/chunks/manager-ui-IPAOAWZA.ts.map +0 -7
- package/dist/chunks/remote-selection-ui-QDNR7WEI.ts +0 -21
- package/dist/chunks/s3-backend-66O4FGBH.ts.map +0 -7
- package/dist/chunks/setup-wizard-JUJZYNNM.ts.map +0 -7
- package/dist/chunks/sync-inspection-CST2KL65.ts +0 -20
- package/dist/chunks/sync-operations-LBX3GKCM.ts.map +0 -7
- package/dist/chunks/webdav-backend-ECIKD7SO.ts.map +0 -7
- /package/dist/chunks/{manager-result-dispatcher-ASKGOSW5.ts.map → manager-result-dispatcher-OTUMQM26.ts.map} +0 -0
- /package/dist/chunks/{remote-selection-ui-QDNR7WEI.ts.map → remote-selection-ui-TZTJF32Y.ts.map} +0 -0
- /package/dist/chunks/{setup-switch-IS2PEZ3J.ts.map → setup-switch-5G2VNJHL.ts.map} +0 -0
- /package/dist/chunks/{snapshot-HKEWCVK6.ts.map → snapshot-JL5DFSXI.ts.map} +0 -0
- /package/dist/chunks/{sync-inspection-CST2KL65.ts.map → sync-inspection-P3ENJLNF.ts.map} +0 -0
- /package/dist/chunks/{sync-state-Q2FTXTW6.ts.map → sync-state-VHJUZ4YG.ts.map} +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/backends/sync-backend.ts"],
|
|
4
|
+
"sourcesContent": ["import type { Snapshot, SnapshotSelection } from \"../snapshot/snapshot-types.js\";\n\nexport type PublicationCapability =\n | \"read-check-write-verify\"\n | \"conditional-required\"\n | \"atomic-conditional\"\n | \"lease-protected\";\n\nexport interface RemoteHead {\n /** Backend-owned reference used only to retrieve this immutable snapshot. */\n snapshotRef: string;\n /** Backend-neutral snapshot content identity retained in local sync state. */\n snapshotId: string;\n revision: string;\n createdAt: string;\n machine: string;\n syncSessions: boolean;\n /** Validated lightweight projection; revalidate it against the immutable snapshot before adoption. */\n selection?: SnapshotSelection;\n}\n\nexport interface RemoteHistoryEntry {\n snapshotRef: string;\n snapshotId: string;\n createdAt: string;\n machine: string;\n syncSessions: boolean;\n}\n\nexport type ExpectedRemoteHead = { kind: \"missing\" } | { kind: \"revision\"; revision: string };\n\nexport interface PublishSnapshotOptions {\n signal?: AbortSignal;\n /** Called at the backend's active-head commit boundary. */\n onCommit?: () => void;\n}\n\nexport interface PublishSnapshotResult {\n head: RemoteHead;\n warnings: string[];\n}\n\nexport interface BackendDiagnostic {\n key: string;\n level: \"info\" | \"warning\" | \"error\";\n message: string;\n}\n\nexport interface SyncBackend {\n readonly identity: string;\n readonly destination: string;\n readonly capability: PublicationCapability;\n /** Compare opaque revisions produced by this backend identity. */\n sameRevision(left: string, right: string): boolean;\n readHead(signal?: AbortSignal): Promise<RemoteHead | undefined>;\n readSnapshot(reference: string, signal?: AbortSignal): Promise<Snapshot>;\n publishSnapshot(\n snapshot: Snapshot,\n expected: ExpectedRemoteHead,\n options?: PublishSnapshotOptions,\n ): Promise<PublishSnapshotResult>;\n listHistory(signal?: AbortSignal): Promise<RemoteHistoryEntry[]>;\n diagnose(signal?: AbortSignal): Promise<BackendDiagnostic[]>;\n}\n\nexport class SyncBackendConflictError extends Error {\n readonly code = \"SYNC_BACKEND_CONFLICT\";\n readonly phase: \"before-commit\" | \"after-commit\";\n readonly currentHead?: RemoteHead;\n readonly candidateMayHaveBeenActive: boolean;\n\n constructor(\n message: string,\n options: ErrorOptions & {\n phase?: \"before-commit\" | \"after-commit\";\n currentHead?: RemoteHead;\n candidateMayHaveBeenActive?: boolean;\n } = {},\n ) {\n super(message, options);\n this.name = \"SyncBackendConflictError\";\n this.phase = options.phase ?? \"before-commit\";\n this.currentHead = options.currentHead;\n this.candidateMayHaveBeenActive = options.candidateMayHaveBeenActive ?? false;\n }\n}\n\nexport class SyncBackendPublicationOutcomeUnknownError extends Error {\n readonly code = \"SYNC_BACKEND_PUBLICATION_OUTCOME_UNKNOWN\";\n\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"SyncBackendPublicationOutcomeUnknownError\";\n }\n}\n\nexport function expectedRemoteHead(head: RemoteHead | undefined): ExpectedRemoteHead {\n return head ? { kind: \"revision\", revision: head.revision } : { kind: \"missing\" };\n}\n"],
|
|
5
|
+
"mappings": ";;;;AAiEO,IAAM,2BAAN,cAAuC,MAAM;AAAA,EACzC,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EAET,YACE,SACA,UAII,CAAC,GACL;AACA,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AACZ,SAAK,QAAQ,QAAQ,SAAS;AAC9B,SAAK,cAAc,QAAQ;AAC3B,SAAK,6BAA6B,QAAQ,8BAA8B;AAAA,EAC1E;AACF;AAEO,IAAM,4CAAN,cAAwD,MAAM;AAAA,EAC1D,OAAO;AAAA,EAEhB,YAAY,SAAiB,SAAwB;AACnD,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AAAA,EACd;AACF;AAEO,SAAS,mBAAmB,MAAkD;AACnF,SAAO,OAAO,EAAE,MAAM,YAAY,UAAU,KAAK,SAAS,IAAI,EAAE,MAAM,UAAU;AAClF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -23,9 +23,11 @@ var SYNC_COMMANDS = [
|
|
|
23
23
|
{ name: "migrate-state", description: "Move legacy state into pi-sync/" },
|
|
24
24
|
{ name: "unlock", description: "Remove a stale local lock", usageSuffix: " --stale" }
|
|
25
25
|
];
|
|
26
|
-
var SYNC_COMMAND_COMPLETIONS = SYNC_COMMANDS.map(
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
var SYNC_COMMAND_COMPLETIONS = SYNC_COMMANDS.map(({ name, description }) => ({
|
|
27
|
+
value: name,
|
|
28
|
+
label: name,
|
|
29
|
+
description
|
|
30
|
+
}));
|
|
29
31
|
var setupCompletionNames = [];
|
|
30
32
|
function setSyncSetupCompletions(names) {
|
|
31
33
|
setupCompletionNames = [...new Set(names)].sort((left, right) => left.localeCompare(right));
|
|
@@ -123,8 +125,7 @@ function validateCommandOptions(command, options) {
|
|
|
123
125
|
}
|
|
124
126
|
const expectedValues = command === "rollback" || command === "use" ? 1 : 0;
|
|
125
127
|
if (options.args.length !== expectedValues) {
|
|
126
|
-
if (command === "rollback")
|
|
127
|
-
throw new Error("Usage: /sync rollback <snapshot-id> [--yes] [--setup <name>]");
|
|
128
|
+
if (command === "rollback") throw new Error("Usage: /sync rollback <snapshot-id> [--yes] [--setup <name>]");
|
|
128
129
|
if (command === "use") throw new Error("Usage: /sync use <setup>");
|
|
129
130
|
throw new Error(`Unexpected argument for /sync ${command}: ${options.args.join(" ")}`);
|
|
130
131
|
}
|
|
@@ -219,4 +220,4 @@ export {
|
|
|
219
220
|
resolveSyncCommand,
|
|
220
221
|
usage
|
|
221
222
|
};
|
|
222
|
-
//# sourceMappingURL=chunk-
|
|
223
|
+
//# sourceMappingURL=chunk-YFADF5ZQ.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/commands/command.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport type { CommandArgumentCompletion, CommandOptions } from \"./command-types.js\";\n\nconst YES_FLAG_COMPLETIONS: readonly CommandArgumentCompletion[] = [\n { value: \"--yes\", label: \"--yes\", description: \"Skip confirmation prompts\" },\n { value: \"-y\", label: \"-y\", description: \"Skip confirmation prompts\" },\n];\nexport const SYNC_COMMANDS = [\n { name: \"help\", description: \"Show command usage\" },\n { name: \"use\", description: \"Switch the current sync setup\", usageSuffix: \" <setup>\" },\n { name: \"init\", description: \"Create local config template\" },\n { name: \"config\", description: \"Show resolved configuration\" },\n { name: \"files\", description: \"Choose included content\" },\n { name: \"status\", description: \"Show sync status\" },\n { name: \"diff\", description: \"Show local/remote diff\" },\n { name: \"doctor\", description: \"Check config, secrets, and lock state\" },\n { name: \"push\", description: \"Upload local settings\" },\n { name: \"pull\", description: \"Apply remote settings\" },\n { name: \"sync\", description: \"Push or pull as needed\" },\n { name: \"history\", description: \"Show recent remote snapshots\" },\n { name: \"rollback\", description: \"Apply a previous snapshot\", usageSuffix: \" <snapshot>\" },\n { name: \"migrate-state\", description: \"Move legacy state into pi-sync/\" },\n { name: \"unlock\", description: \"Remove a stale local lock\", usageSuffix: \" --stale\" },\n] as const;\n\nexport type SyncCommandName = (typeof SYNC_COMMANDS)[number][\"name\"];\n\nconst SYNC_COMMAND_COMPLETIONS: readonly CommandArgumentCompletion[] = SYNC_COMMANDS.map(({ name, description }) => ({\n value: name,\n label: name,\n description,\n}));\nlet setupCompletionNames: string[] = [];\n\nexport function setSyncSetupCompletions(names: readonly string[]) {\n setupCompletionNames = [...new Set(names)].sort((left, right) => left.localeCompare(right));\n}\nconst SETUP_FLAG_COMPLETION = {\n value: \"--setup\",\n label: \"--setup\",\n description: \"Address a sync setup without switching\",\n} as const;\nconst SYNC_FLAG_COMPLETIONS: Record<string, readonly CommandArgumentCompletion[]> = {\n config: [SETUP_FLAG_COMPLETION],\n files: [SETUP_FLAG_COMPLETION],\n status: [SETUP_FLAG_COMPLETION],\n diff: [SETUP_FLAG_COMPLETION],\n doctor: [SETUP_FLAG_COMPLETION],\n push: [\n ...YES_FLAG_COMPLETIONS,\n { value: \"--force\", label: \"--force\", description: \"Overwrite visible remote changes\" },\n SETUP_FLAG_COMPLETION,\n ],\n pull: [\n ...YES_FLAG_COMPLETIONS,\n { value: \"--force\", label: \"--force\", description: \"Overwrite local changes\" },\n SETUP_FLAG_COMPLETION,\n ],\n sync: [\n ...YES_FLAG_COMPLETIONS,\n { value: \"--force\", label: \"--force\", description: \"Resolve conflicts by forcing action\" },\n SETUP_FLAG_COMPLETION,\n ],\n history: [SETUP_FLAG_COMPLETION],\n rollback: [...YES_FLAG_COMPLETIONS, SETUP_FLAG_COMPLETION],\n \"migrate-state\": YES_FLAG_COMPLETIONS,\n unlock: [{ value: \"--stale\", label: \"--stale\", description: \"Remove only a stale lock\" }],\n};\n\nexport function splitArgs(input: string) {\n return input.match(/(?:[^\\s\"']+|\"[^\"]*\"|'[^']*')+/g)?.map((arg) => arg.replace(/^['\"]|['\"]$/g, \"\")) ?? [];\n}\n\nexport function parseOptions(args: string[]): CommandOptions {\n const values: string[] = [];\n let yes = false;\n let force = false;\n let stale = false;\n let setup: string | undefined;\n for (let index = 0; index < args.length; index += 1) {\n const arg = args[index];\n if (arg === \"--yes\" || arg === \"-y\") yes = true;\n else if (arg === \"--force\") force = true;\n else if (arg === \"--stale\") stale = true;\n else if (arg === \"--setup\") {\n const name = args[index + 1];\n if (!name || name.startsWith(\"-\")) throw new Error(\"--setup requires a sync setup name.\");\n if (setup !== undefined) throw new Error(\"--setup may be provided only once.\");\n setup = name;\n index += 1;\n } else if (arg.startsWith(\"-\")) {\n throw new Error(`Unknown sync option: ${arg}`);\n } else values.push(arg);\n }\n return {\n yes,\n force,\n stale,\n silent: false,\n reload: true,\n auto: false,\n ...(setup === undefined ? {} : { setup }),\n args: values,\n };\n}\n\nexport function validateCommandOptions(command: string, options: CommandOptions) {\n const setupAllowed = new Set([\n \"config\",\n \"files\",\n \"status\",\n \"diff\",\n \"doctor\",\n \"push\",\n \"pull\",\n \"sync\",\n \"history\",\n \"rollback\",\n ]);\n if (options.setup && !setupAllowed.has(command)) {\n throw new Error(`--setup is not supported by /sync ${command}.`);\n }\n if (options.yes && ![\"push\", \"pull\", \"sync\", \"rollback\", \"migrate-state\"].includes(command)) {\n throw new Error(`Confirmation/force options are not supported by /sync ${command}.`);\n }\n if (options.force && ![\"push\", \"pull\", \"sync\", \"rollback\"].includes(command)) {\n throw new Error(`Confirmation/force options are not supported by /sync ${command}.`);\n }\n if (options.stale && command !== \"unlock\") {\n throw new Error(`--stale is not supported by /sync ${command}.`);\n }\n const expectedValues = command === \"rollback\" || command === \"use\" ? 1 : 0;\n if (options.args.length !== expectedValues) {\n if (command === \"rollback\") throw new Error(\"Usage: /sync rollback <snapshot-id> [--yes] [--setup <name>]\");\n if (command === \"use\") throw new Error(\"Usage: /sync use <setup>\");\n throw new Error(`Unexpected argument for /sync ${command}: ${options.args.join(\" \")}`);\n }\n}\n\nexport function completeSyncArguments(argumentPrefix: string): CommandArgumentCompletion[] | null {\n const prefix = argumentPrefix.trimStart();\n if (prefix === \"\") return [...SYNC_COMMAND_COMPLETIONS];\n\n const trailingSpace = /\\s$/.test(prefix);\n const tokens = splitArgs(prefix);\n if (tokens.length === 0) return [...SYNC_COMMAND_COMPLETIONS];\n\n const [command] = tokens;\n if (tokens.length === 1 && !trailingSpace) {\n const matches = SYNC_COMMAND_COMPLETIONS.filter((item) => item.value.startsWith(command));\n return matches.length > 0 ? [...matches] : null;\n }\n\n const args = tokens.slice(1);\n if (command === \"use\") {\n if (args.length > 1 || (trailingSpace && args.length > 0)) return null;\n return completeSetupValue(prefix, trailingSpace ? \"\" : (args[0] ?? \"\"));\n }\n const setupFlagIndex = args.lastIndexOf(\"--setup\");\n if (setupFlagIndex >= 0 && setupFlagIndex === args.length - (trailingSpace ? 1 : 2)) {\n const currentSetup = trailingSpace ? \"\" : (args.at(-1) ?? \"\");\n if (!currentSetup.startsWith(\"-\")) return completeSetupValue(prefix, currentSetup);\n }\n\n const flagCompletions = SYNC_FLAG_COMPLETIONS[command];\n if (!flagCompletions) return null;\n\n const completedArgs = trailingSpace ? args : args.slice(0, -1);\n const completedValues = completedArgs.filter((arg) => !arg.startsWith(\"-\"));\n if (command === \"rollback\" ? completedValues.length > 1 : completedValues.length > 0) {\n return null;\n }\n\n const current = trailingSpace ? \"\" : (args.at(-1) ?? \"\");\n if (current && !current.startsWith(\"-\")) return null;\n\n const currentRaw = trailingSpace ? \"\" : (prefix.match(/\\S+$/)?.[0] ?? \"\");\n const completionPrefix = trailingSpace ? prefix : prefix.slice(0, prefix.length - currentRaw.length);\n const matches = flagCompletions.filter((item) => item.value.startsWith(current));\n return matches.length > 0 ? matches.map((item) => ({ ...item, value: `${completionPrefix}${item.value}` })) : null;\n}\n\nfunction completeSetupValue(prefix: string, current: string) {\n const currentRaw = current ? (prefix.match(/\\S+$/u)?.[0] ?? \"\") : \"\";\n const completionPrefix = currentRaw ? prefix.slice(0, prefix.length - currentRaw.length) : prefix;\n const matches = setupCompletionNames.filter((name) => name.startsWith(current));\n return matches.length > 0\n ? matches.map((name) => ({\n value: `${completionPrefix}${name}`,\n label: name,\n description: \"Sync setup\",\n }))\n : null;\n}\n\nexport function syncMenuOptions() {\n return SYNC_COMMANDS.map(({ name, description }) => `${name} \u2014 ${description}`);\n}\n\nexport function syncCommandFromMenuOption(option: string): SyncCommandName | undefined {\n return SYNC_COMMANDS.find(({ name, description }) => option === `${name} \u2014 ${description}`)?.name;\n}\n\nexport async function resolveSyncCommand(input: string, ctx: ExtensionCommandContext) {\n const [subcommand, ...rest] = splitArgs(input);\n if (subcommand) return { subcommand, rest };\n if (!ctx.hasUI) {\n ctx.ui.notify(usage(), \"info\");\n return undefined;\n }\n\n const selectedOption = await ctx.ui.select(\"pi-sync\", syncMenuOptions());\n const selected = selectedOption ? syncCommandFromMenuOption(selectedOption) : undefined;\n if (!selected) return undefined;\n if (selected !== \"rollback\") return { subcommand: selected, rest: [] };\n\n const target = (await ctx.ui.input(\"Rollback snapshot\", \"snapshot id\"))?.trim();\n if (!target) {\n ctx.ui.notify(\"Rollback cancelled.\", \"info\");\n return undefined;\n }\n return { subcommand: selected, rest: [target] };\n}\n\nexport function usage() {\n const commands = SYNC_COMMANDS.map(\n (command) => `${command.name}${\"usageSuffix\" in command ? command.usageSuffix : \"\"}`,\n ).join(\", \");\n return [\n \"Usage: /sync <command>\",\n `Commands: ${commands}`,\n \"Automatic sync: background startup checks only; use /sync to review and transfer. At shutdown, selected content is pushed automatically only when sessions are included. Startup checks run in TUI/RPC, not print/JSON.\",\n \"Settings: use /sync init or edit storage connections and sync setups in ~/.pi/agent/pi-sync.json (or the configured Pi agent directory). Version 1 and version 2 settings are unsupported and are never rewritten.\",\n ].join(\"\\n\");\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["matches"]
|
|
7
|
+
}
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
// @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
|
|
3
3
|
import {
|
|
4
4
|
backendIdentityCoordinates
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-2JZFHNLM.ts";
|
|
6
6
|
import {
|
|
7
7
|
stateDir
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-BVVP33U5.ts";
|
|
9
9
|
import {
|
|
10
10
|
readJsonIfExists,
|
|
11
11
|
writeJson
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-OVDTF5CH.ts";
|
|
13
13
|
|
|
14
14
|
// src/state/sync-state-store.ts
|
|
15
15
|
import { createHash } from "node:crypto";
|
|
@@ -48,4 +48,4 @@ export {
|
|
|
48
48
|
lockPath,
|
|
49
49
|
ensureStateDir
|
|
50
50
|
};
|
|
51
|
-
//# sourceMappingURL=chunk-
|
|
51
|
+
//# sourceMappingURL=chunk-YPXGU5OR.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/state/sync-state-store.ts"],
|
|
4
|
+
"sourcesContent": ["import { createHash } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { backendIdentityCoordinates } from \"../backends/backend-identity.js\";\nimport { safeName } from \"../paths.js\";\nimport type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport { readJsonIfExists, writeJson } from \"./json-file.js\";\nimport { stateDir } from \"./state-directory.js\";\nimport type { SyncState } from \"./state-types.js\";\n\nconst STATE_VERSION = 2;\n\n/** Bounded observation token; do not retain the full baseline in passive UI state. */\nexport function syncStateFingerprint(state: SyncState) {\n return createHash(\"sha256\").update(JSON.stringify(state)).digest(\"hex\");\n}\n\nexport async function readState(profile: string): Promise<SyncState> {\n return (\n (await readJsonIfExists<SyncState>(statePath(profile))) ?? {\n version: STATE_VERSION,\n profile,\n lastFileHashes: {},\n }\n );\n}\n\nexport async function writeState(profile: string, state: SyncState) {\n await writeJson(statePath(profile), state);\n}\n\nexport async function readStateForConfig(config: AnySyncConfig): Promise<SyncState> {\n return (\n (await readJsonIfExists<SyncState>(statePathForConfig(config))) ?? {\n version: STATE_VERSION,\n profile: config.snapshotIdentity,\n lastFileHashes: {},\n }\n );\n}\n\nexport async function writeStateForConfig(config: AnySyncConfig, state: SyncState) {\n await writeJson(statePathForConfig(config), state);\n}\n\nexport function statePathForConfig(config: AnySyncConfig) {\n const identity = backendIdentityCoordinates(config);\n const hash = createHash(\"sha256\").update(identity).digest(\"hex\").slice(0, 16);\n return path.join(stateDir(), \"setups\", `${config.backend.type}-${hash}.state.json`);\n}\n\nfunction statePath(profile: string) {\n return path.join(stateDir(), `${safeName(profile)}.state.json`);\n}\n\nexport function lockPath() {\n return path.join(stateDir(), \"lock\");\n}\n\nexport async function ensureStateDir() {\n await fs.mkdir(stateDir(), { recursive: true });\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;AAAA,SAAS,kBAAkB;AAC3B,OAAO,QAAQ;AACf,OAAO,UAAU;AAQjB,IAAM,gBAAgB;AAGf,SAAS,qBAAqB,OAAkB;AACrD,SAAO,WAAW,QAAQ,EAAE,OAAO,KAAK,UAAU,KAAK,CAAC,EAAE,OAAO,KAAK;AACxE;AAgBA,eAAsB,mBAAmB,QAA2C;AAClF,SACG,MAAM,iBAA4B,mBAAmB,MAAM,CAAC,KAAM;AAAA,IACjE,SAAS;AAAA,IACT,SAAS,OAAO;AAAA,IAChB,gBAAgB,CAAC;AAAA,EACnB;AAEJ;AAEA,eAAsB,oBAAoB,QAAuB,OAAkB;AACjF,QAAM,UAAU,mBAAmB,MAAM,GAAG,KAAK;AACnD;AAEO,SAAS,mBAAmB,QAAuB;AACxD,QAAM,WAAW,2BAA2B,MAAM;AAClD,QAAM,OAAO,WAAW,QAAQ,EAAE,OAAO,QAAQ,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AAC5E,SAAO,KAAK,KAAK,SAAS,GAAG,UAAU,GAAG,OAAO,QAAQ,IAAI,IAAI,IAAI,aAAa;AACpF;AAMO,SAAS,WAAW;AACzB,SAAO,KAAK,KAAK,SAAS,GAAG,MAAM;AACrC;AAEA,eAAsB,iBAAiB;AACrC,QAAM,GAAG,MAAM,SAAS,GAAG,EAAE,WAAW,KAAK,CAAC;AAChD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
// @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
|
|
3
3
|
import {
|
|
4
4
|
updateSyncSetup
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-2RZSQWBH.ts";
|
|
6
6
|
import {
|
|
7
7
|
loadConfig,
|
|
8
8
|
localConfigPath
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-4MPIH46N.ts";
|
|
10
|
+
import "./chunk-2JZFHNLM.ts";
|
|
11
|
+
import "./chunk-T2SJD3N7.ts";
|
|
12
12
|
import {
|
|
13
13
|
agentDir
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-OVDTF5CH.ts";
|
|
15
15
|
import {
|
|
16
16
|
BUILT_IN_SYNC_ROOTS,
|
|
17
17
|
isSafeCustomIncludePath,
|
|
18
18
|
normalizeSyncInclude,
|
|
19
19
|
syncIncludeSelection
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-IVXEDPAD.ts";
|
|
21
21
|
|
|
22
22
|
// src/ui/file-selection.ts
|
|
23
23
|
import fs from "node:fs/promises";
|
|
@@ -156,9 +156,7 @@ async function showDraftEditor(ctx, setupName, draft, customCandidates, signal)
|
|
|
156
156
|
if (actionSignal.aborted) return { kind: "stay" };
|
|
157
157
|
const requested = entered?.trim();
|
|
158
158
|
if (!requested) return { kind: "stay" };
|
|
159
|
-
const existing = customCandidates.find(
|
|
160
|
-
(candidate) => candidate.toLowerCase() === requested.toLowerCase()
|
|
161
|
-
);
|
|
159
|
+
const existing = customCandidates.find((candidate) => candidate.toLowerCase() === requested.toLowerCase());
|
|
162
160
|
const relativePath = existing ?? requested;
|
|
163
161
|
if (draft.custom.has(relativePath)) return { kind: "stay" };
|
|
164
162
|
try {
|
|
@@ -226,10 +224,8 @@ async function showDraftReview(ctx, original, draft, signal) {
|
|
|
226
224
|
return choice;
|
|
227
225
|
}
|
|
228
226
|
function updateDraft(draft, id, included) {
|
|
229
|
-
if (id.startsWith(BUILT_IN_PREFIX))
|
|
230
|
-
|
|
231
|
-
if (id.startsWith(CUSTOM_PREFIX))
|
|
232
|
-
return updateSet(draft.custom, id.slice(CUSTOM_PREFIX.length), included);
|
|
227
|
+
if (id.startsWith(BUILT_IN_PREFIX)) return updateSet(draft.builtIns, id.slice(BUILT_IN_PREFIX.length), included);
|
|
228
|
+
if (id.startsWith(CUSTOM_PREFIX)) return updateSet(draft.custom, id.slice(CUSTOM_PREFIX.length), included);
|
|
233
229
|
if (id === SESSIONS_ID) {
|
|
234
230
|
draft.sessions = included;
|
|
235
231
|
return;
|
|
@@ -242,18 +238,12 @@ function updateSet(set, value, included) {
|
|
|
242
238
|
}
|
|
243
239
|
function formatDraftPreview(original, draft) {
|
|
244
240
|
const lines = ["Review included-content changes", ""];
|
|
245
|
-
for (const item of /* @__PURE__ */ new Set([
|
|
246
|
-
...original.builtIns,
|
|
247
|
-
...draft.builtIns,
|
|
248
|
-
...original.custom,
|
|
249
|
-
...draft.custom
|
|
250
|
-
])) {
|
|
241
|
+
for (const item of /* @__PURE__ */ new Set([...original.builtIns, ...draft.builtIns, ...original.custom, ...draft.custom])) {
|
|
251
242
|
const before = original.builtIns.has(item) || original.custom.has(item);
|
|
252
243
|
const after = draft.builtIns.has(item) || draft.custom.has(item);
|
|
253
244
|
if (before !== after) lines.push(`${after ? "Include" : "Exclude"}: ${safeTerminalText(item)}`);
|
|
254
245
|
}
|
|
255
|
-
if (original.sessions !== draft.sessions)
|
|
256
|
-
lines.push(`${draft.sessions ? "Include" : "Exclude"}: sessions`);
|
|
246
|
+
if (original.sessions !== draft.sessions) lines.push(`${draft.sessions ? "Include" : "Exclude"}: sessions`);
|
|
257
247
|
lines.push("", "Saving does not start a network sync.");
|
|
258
248
|
return lines.join("\n");
|
|
259
249
|
}
|
|
@@ -261,10 +251,8 @@ async function listCustomCandidates(configured) {
|
|
|
261
251
|
const candidates = new Map([...configured].map((item) => [item.toLowerCase(), item]));
|
|
262
252
|
try {
|
|
263
253
|
for (const entry of await fs.readdir(agentDir(), { withFileTypes: true })) {
|
|
264
|
-
if (!entry.isFile() && !entry.isDirectory() || !isSafeCustomIncludePath(entry.name))
|
|
265
|
-
|
|
266
|
-
if (!candidates.has(entry.name.toLowerCase()))
|
|
267
|
-
candidates.set(entry.name.toLowerCase(), entry.name);
|
|
254
|
+
if (!entry.isFile() && !entry.isDirectory() || !isSafeCustomIncludePath(entry.name)) continue;
|
|
255
|
+
if (!candidates.has(entry.name.toLowerCase())) candidates.set(entry.name.toLowerCase(), entry.name);
|
|
268
256
|
}
|
|
269
257
|
} catch (error) {
|
|
270
258
|
if (error.code !== "ENOENT") throw error;
|
|
@@ -290,4 +278,4 @@ function safeTerminalText(value) {
|
|
|
290
278
|
export {
|
|
291
279
|
showFileSelection
|
|
292
280
|
};
|
|
293
|
-
//# sourceMappingURL=file-selection-
|
|
281
|
+
//# sourceMappingURL=file-selection-RAVHRYFG.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/ui/file-selection.ts"],
|
|
4
|
+
"sourcesContent": ["import fs from \"node:fs/promises\";\nimport type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { defineMenu, runMenu } from \"@narumitw/pi-tui-kit\";\nimport { loadConfig } from \"../settings/config.js\";\nimport { localConfigPath } from \"../settings/config-file.js\";\nimport { updateSyncSetup } from \"../settings/settings-management.js\";\nimport { agentDir } from \"../snapshot/session-paths.js\";\nimport {\n BUILT_IN_SYNC_ROOTS,\n isSafeCustomIncludePath,\n normalizeSyncInclude,\n syncIncludeSelection,\n} from \"../sync/sync-policy.js\";\n\nconst BUILT_IN_PREFIX = \"builtin:\";\nconst CUSTOM_PREFIX = \"custom:\";\nconst SESSIONS_ID = \"sessions\";\nconst ADD_CUSTOM_ID = \"add-custom\";\n\ninterface SelectionDraft {\n builtIns: Set<string>;\n custom: Set<string>;\n sessions: boolean;\n}\n\nexport async function showFileSelection(ctx: ExtensionCommandContext, setupName?: string, signal?: AbortSignal) {\n const config = await loadConfig(setupName);\n if (signal?.aborted) return;\n const selection = syncIncludeSelection(config.include);\n const original: SelectionDraft = {\n builtIns: new Set(selection.builtIns),\n custom: new Set(selection.custom),\n sessions: selection.sessions,\n };\n const draft = cloneDraft(original);\n const customCandidates = await listCustomCandidates(draft.custom);\n\n if (ctx.mode !== \"tui\") {\n ctx.ui.notify(\n [\n `pi-sync included content for sync setup ${safeTerminalText(config.setupName)}:`,\n `include: ${config.include.map(safeTerminalText).join(\", \") || \"none\"}`,\n `Edit sync.include in ${safeTerminalText(localConfigPath())}.`,\n ].join(\"\\n\"),\n \"info\",\n );\n return;\n }\n\n while (!signal?.aborted) {\n await showDraftEditor(ctx, config.setupName, draft, customCandidates, signal);\n if (signal?.aborted || sameDraft(original, draft)) return;\n const choice = await showDraftReview(ctx, original, draft, signal);\n if (signal?.aborted) return;\n if (choice === \"Continue editing\") continue;\n if (choice !== \"Save changes\") {\n ctx.ui.notify(\"Included-content changes discarded.\", \"info\");\n return;\n }\n try {\n if (!original.sessions && draft.sessions) {\n const acknowledged = await ctx.ui.confirm(\n \"Include session conversations?\",\n \"Session JSONL may contain prompts, tool output, file paths, images, and secrets. Continue only with storage you trust.\",\n { signal },\n );\n if (signal?.aborted) return;\n if (!acknowledged) {\n ctx.ui.notify(\"Session inclusion was not saved.\", \"info\");\n return;\n }\n }\n const include = [\n ...BUILT_IN_SYNC_ROOTS.filter((candidate) => draft.builtIns.has(candidate)),\n ...draft.custom,\n ...(draft.sessions ? [\"sessions\"] : []),\n ];\n if (signal?.aborted) return;\n await updateSyncSetup(\n config.setupName,\n (setup) => ({\n ...setup,\n sync: { ...setup.sync, include },\n }),\n { expectedInclude: config.include, signal },\n );\n if (signal?.aborted) return;\n ctx.ui.notify(\n `Saved included content for sync setup \u201C${safeTerminalText(config.setupName)}\u201D. It applies to the next manual or automatic sync.`,\n \"info\",\n );\n } catch (error) {\n if (signal?.aborted) return;\n ctx.ui.notify(\n `Could not save pi-sync file selection: ${safeTerminalText(error instanceof Error ? error.message : String(error))}`,\n \"error\",\n );\n }\n return;\n }\n}\n\nasync function showDraftEditor(\n ctx: ExtensionCommandContext,\n setupName: string,\n draft: SelectionDraft,\n customCandidates: string[],\n signal?: AbortSignal,\n) {\n const menu = defineMenu<undefined, \"editor\", \"toggle\" | \"addCustom\", ExtensionCommandContext>({\n start: \"editor\",\n screens: {\n editor: () => ({\n kind: \"multiSelect\",\n title: `Included Content \u00B7 ${safeTerminalText(setupName)}`,\n lines: [\"Draft only \u00B7 leaving this screen opens Save, Discard, or Continue editing.\"],\n viewportSize: 12,\n items: [\n ...BUILT_IN_SYNC_ROOTS.map((relativePath) => ({\n id: `${BUILT_IN_PREFIX}${relativePath}`,\n label: relativePath,\n description: relativePath.includes(\".\")\n ? `Sync the top-level ${relativePath} file when present.`\n : `Recursively sync every safe file under ${relativePath}/.`,\n selected: draft.builtIns.has(relativePath),\n })),\n ...customCandidates.map((relativePath) => ({\n id: `${CUSTOM_PREFIX}${relativePath}`,\n label: safeTerminalText(relativePath),\n description: \"Additional safe agent-relative file or directory.\",\n selected: draft.custom.has(relativePath),\n })),\n {\n id: SESSIONS_ID,\n label: \"sessions\",\n description:\n \"Session JSONL may contain prompts, tool output, paths, images, and secrets. Sync only to storage you trust.\",\n selected: draft.sessions,\n },\n ],\n action: \"toggle\",\n actions: [\n {\n id: ADD_CUSTOM_ID,\n label: \"Add custom path\u2026\",\n description: \"Include an agent-relative file or directory even when it exists only remotely.\",\n action: \"addCustom\",\n },\n ],\n hint: \"close\",\n doneLabel: \"Review changes\",\n }),\n },\n actions: {\n toggle: async ({ itemId, selected }) => {\n updateDraft(draft, itemId, selected === true);\n return { kind: \"stay\" };\n },\n addCustom: async ({ ctx: actionCtx, signal: actionSignal }) => {\n const entered = await actionCtx.ui.input(\n \"Add included content\",\n \"Agent-relative path, for example custom.toml or snippets\",\n { signal: actionSignal },\n );\n if (actionSignal.aborted) return { kind: \"stay\" };\n const requested = entered?.trim();\n if (!requested) return { kind: \"stay\" };\n const existing = customCandidates.find((candidate) => candidate.toLowerCase() === requested.toLowerCase());\n const relativePath = existing ?? requested;\n if (draft.custom.has(relativePath)) return { kind: \"stay\" };\n try {\n if (!isSafeCustomIncludePath(relativePath)) {\n throw new Error(\"Enter a safe agent-relative file or directory path.\");\n }\n normalizeSyncInclude([\n ...draft.builtIns,\n ...draft.custom,\n ...(draft.sessions ? [\"sessions\"] : []),\n relativePath,\n ]);\n } catch (error) {\n if (actionSignal.aborted) return { kind: \"stay\" };\n actionCtx.ui.notify(\n `Could not add included content: ${safeTerminalText(error instanceof Error ? error.message : String(error))}`,\n \"error\",\n );\n return { kind: \"stay\" };\n }\n if (!existing) {\n customCandidates.push(relativePath);\n customCandidates.sort((left, right) => left.localeCompare(right));\n }\n draft.custom.add(relativePath);\n return { kind: \"stay\" };\n },\n },\n });\n await runMenu(ctx, menu, {\n getState: () => undefined,\n signal,\n isCurrent: () => !signal?.aborted,\n });\n}\n\nasync function showDraftReview(\n ctx: ExtensionCommandContext,\n original: SelectionDraft,\n draft: SelectionDraft,\n signal?: AbortSignal,\n) {\n let choice: \"Save changes\" | \"Discard changes\" | \"Continue editing\" | undefined;\n const menu = defineMenu<undefined, \"review\", \"choose\", ExtensionCommandContext>({\n start: \"review\",\n screens: {\n review: () => ({\n kind: \"actions\",\n title: \"Review included-content changes\",\n lines: formatDraftPreview(original, draft).split(\"\\n\").slice(2),\n items: [\n { id: \"save\", label: \"Save changes\", action: \"choose\" },\n { id: \"discard\", label: \"Discard changes\", action: \"choose\" },\n { id: \"continue\", label: \"Continue editing\", action: \"choose\" },\n ],\n hint: \"close\",\n }),\n },\n actions: {\n choose: async ({ itemId }) => {\n choice = itemId === \"save\" ? \"Save changes\" : itemId === \"continue\" ? \"Continue editing\" : \"Discard changes\";\n return { kind: \"close\" };\n },\n },\n });\n await runMenu(ctx, menu, {\n getState: () => undefined,\n signal,\n isCurrent: () => !signal?.aborted,\n });\n return choice;\n}\n\nfunction updateDraft(draft: SelectionDraft, id: string, included: boolean) {\n if (id.startsWith(BUILT_IN_PREFIX)) return updateSet(draft.builtIns, id.slice(BUILT_IN_PREFIX.length), included);\n if (id.startsWith(CUSTOM_PREFIX)) return updateSet(draft.custom, id.slice(CUSTOM_PREFIX.length), included);\n if (id === SESSIONS_ID) {\n draft.sessions = included;\n return;\n }\n throw new Error(`Unknown file selection: ${id}`);\n}\n\nfunction updateSet(set: Set<string>, value: string, included: boolean) {\n if (included) set.add(value);\n else set.delete(value);\n}\n\nfunction formatDraftPreview(original: SelectionDraft, draft: SelectionDraft) {\n const lines = [\"Review included-content changes\", \"\"];\n for (const item of new Set([...original.builtIns, ...draft.builtIns, ...original.custom, ...draft.custom])) {\n const before = original.builtIns.has(item) || original.custom.has(item);\n const after = draft.builtIns.has(item) || draft.custom.has(item);\n if (before !== after) lines.push(`${after ? \"Include\" : \"Exclude\"}: ${safeTerminalText(item)}`);\n }\n if (original.sessions !== draft.sessions) lines.push(`${draft.sessions ? \"Include\" : \"Exclude\"}: sessions`);\n lines.push(\"\", \"Saving does not start a network sync.\");\n return lines.join(\"\\n\");\n}\n\nasync function listCustomCandidates(configured: Set<string>) {\n const candidates = new Map([...configured].map((item) => [item.toLowerCase(), item]));\n try {\n for (const entry of await fs.readdir(agentDir(), { withFileTypes: true })) {\n if ((!entry.isFile() && !entry.isDirectory()) || !isSafeCustomIncludePath(entry.name)) continue;\n if (!candidates.has(entry.name.toLowerCase())) candidates.set(entry.name.toLowerCase(), entry.name);\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n }\n return [...candidates.values()].sort((left, right) => left.localeCompare(right));\n}\n\nfunction cloneDraft(value: SelectionDraft): SelectionDraft {\n return {\n builtIns: new Set(value.builtIns),\n custom: new Set(value.custom),\n sessions: value.sessions,\n };\n}\n\nfunction sameDraft(left: SelectionDraft, right: SelectionDraft) {\n return (\n left.sessions === right.sessions && sameSet(left.builtIns, right.builtIns) && sameSet(left.custom, right.custom)\n );\n}\n\nfunction sameSet(left: Set<string>, right: Set<string>) {\n return left.size === right.size && [...left].every((item) => right.has(item));\n}\n\nfunction safeTerminalText(value: string) {\n // biome-ignore lint/suspicious/noControlCharactersInRegex: Escape untrusted terminal controls.\n return value.replace(/[\\u0000-\\u001f\\u007f-\\u009f]/gu, \"?\");\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -2,27 +2,27 @@
|
|
|
2
2
|
// @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
|
|
3
3
|
import {
|
|
4
4
|
stateDir
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-BVVP33U5.ts";
|
|
6
6
|
import {
|
|
7
7
|
normalizeGitBranch,
|
|
8
8
|
normalizeGitDirectory,
|
|
9
9
|
normalizeGitRemote,
|
|
10
10
|
normalizeGitRemoteIdentity,
|
|
11
11
|
validateGitNamespace
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-T2SJD3N7.ts";
|
|
13
13
|
import {
|
|
14
14
|
SyncBackendConflictError,
|
|
15
15
|
SyncBackendPublicationOutcomeUnknownError
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-UETBKTDI.ts";
|
|
17
17
|
import {
|
|
18
18
|
syncErrorGuidance
|
|
19
|
-
} from "./chunk-
|
|
20
|
-
import "./chunk-
|
|
19
|
+
} from "./chunk-G4RUXRWZ.ts";
|
|
20
|
+
import "./chunk-7D5SF7P3.ts";
|
|
21
21
|
import {
|
|
22
22
|
portableSnapshotSelection,
|
|
23
23
|
posixJoin,
|
|
24
24
|
snapshotSelectionInclude
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-IVXEDPAD.ts";
|
|
26
26
|
|
|
27
27
|
// src/backends/git/git-backend.ts
|
|
28
28
|
import { createHash as createHash2, randomUUID } from "node:crypto";
|
|
@@ -63,11 +63,7 @@ async function runGit(args, options = {}) {
|
|
|
63
63
|
"protocol.ssh.allow=always"
|
|
64
64
|
];
|
|
65
65
|
if (options.allowFileProtocol) protocolArgs.push("-c", "protocol.file.allow=always");
|
|
66
|
-
const commandArgs = [
|
|
67
|
-
...options.gitDir ? [`--git-dir=${options.gitDir}`] : [],
|
|
68
|
-
...protocolArgs,
|
|
69
|
-
...args
|
|
70
|
-
];
|
|
66
|
+
const commandArgs = [...options.gitDir ? [`--git-dir=${options.gitDir}`] : [], ...protocolArgs, ...args];
|
|
71
67
|
const inheritedEnvironment = Object.fromEntries(
|
|
72
68
|
Object.entries(process2.env).filter(
|
|
73
69
|
([key]) => !key.startsWith("GIT_") && key !== "PAGER" && key !== "EDITOR" && key !== "VISUAL" && key !== "SSH_ASKPASS" && key !== "SSH_ASKPASS_REQUIRE"
|
|
@@ -83,9 +79,7 @@ async function runGit(args, options = {}) {
|
|
|
83
79
|
"GIT_COMMITTER_DATE"
|
|
84
80
|
]);
|
|
85
81
|
const suppliedEnvironment = Object.fromEntries(
|
|
86
|
-
Object.entries(options.env ?? {}).filter(
|
|
87
|
-
([key]) => !key.startsWith("GIT_") || allowedGitOverrides.has(key)
|
|
88
|
-
)
|
|
82
|
+
Object.entries(options.env ?? {}).filter(([key]) => !key.startsWith("GIT_") || allowedGitOverrides.has(key))
|
|
89
83
|
);
|
|
90
84
|
const env = {
|
|
91
85
|
...inheritedEnvironment,
|
|
@@ -169,9 +163,7 @@ async function runGit(args, options = {}) {
|
|
|
169
163
|
);
|
|
170
164
|
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
171
165
|
const timer = setTimeout(
|
|
172
|
-
() => terminate(
|
|
173
|
-
new Error(`Git command timed out after ${options.timeoutMs ?? DEFAULT_TIMEOUT_MS}ms.`)
|
|
174
|
-
),
|
|
166
|
+
() => terminate(new Error(`Git command timed out after ${options.timeoutMs ?? DEFAULT_TIMEOUT_MS}ms.`)),
|
|
175
167
|
options.timeoutMs ?? DEFAULT_TIMEOUT_MS
|
|
176
168
|
);
|
|
177
169
|
let result;
|
|
@@ -189,13 +181,7 @@ async function runGit(args, options = {}) {
|
|
|
189
181
|
}
|
|
190
182
|
if (code !== 0) {
|
|
191
183
|
const stderrText = stderrBuffer.toString("utf8").trim();
|
|
192
|
-
reject(
|
|
193
|
-
new GitCommandError(
|
|
194
|
-
stderrText || `Git exited with status ${code ?? "unknown"}.`,
|
|
195
|
-
code,
|
|
196
|
-
stderrText
|
|
197
|
-
)
|
|
198
|
-
);
|
|
184
|
+
reject(new GitCommandError(stderrText || `Git exited with status ${code ?? "unknown"}.`, code, stderrText));
|
|
199
185
|
return;
|
|
200
186
|
}
|
|
201
187
|
resolve({ stdout: stdoutBuffer, stderr: stderrBuffer });
|
|
@@ -371,9 +357,7 @@ function parseGitTree(output) {
|
|
|
371
357
|
if (output.byteLength === 0) return [];
|
|
372
358
|
if (output.at(-1) !== 0) throw new Error("Git publication tree response is malformed.");
|
|
373
359
|
return output.subarray(0, -1).toString("utf8").split("\0").map((line) => {
|
|
374
|
-
const match = /^(?<mode>[0-9]{6}) (?<type>blob|tree|commit) (?<object>[0-9a-f]{40})\t(?<path>.+)$/u.exec(
|
|
375
|
-
line
|
|
376
|
-
);
|
|
360
|
+
const match = /^(?<mode>[0-9]{6}) (?<type>blob|tree|commit) (?<object>[0-9a-f]{40})\t(?<path>.+)$/u.exec(line);
|
|
377
361
|
if (!match?.groups || hasControlCharacter(match.groups.path)) {
|
|
378
362
|
throw new Error("Git publication tree response is malformed.");
|
|
379
363
|
}
|
|
@@ -408,9 +392,7 @@ function sameOptionalInclude(left, right) {
|
|
|
408
392
|
return left.length === right.length && left.every((item, index) => item === right[index]);
|
|
409
393
|
}
|
|
410
394
|
function isSafeSnapshotPath(value) {
|
|
411
|
-
return typeof value === "string" && value.length > 0 && value.length <= 4096 && !value.startsWith("/") && !value.includes("\\") && !hasControlCharacter(value) && value.split("/").every(
|
|
412
|
-
(segment) => segment && segment !== "." && segment !== ".." && segment.toLowerCase() !== ".git"
|
|
413
|
-
);
|
|
395
|
+
return typeof value === "string" && value.length > 0 && value.length <= 4096 && !value.startsWith("/") && !value.includes("\\") && !hasControlCharacter(value) && value.split("/").every((segment) => segment && segment !== "." && segment !== ".." && segment.toLowerCase() !== ".git");
|
|
414
396
|
}
|
|
415
397
|
function hasExactKeys(value, expected) {
|
|
416
398
|
const keys = Object.keys(value).sort();
|
|
@@ -565,17 +547,9 @@ var GitSyncBackend = class {
|
|
|
565
547
|
const lease = `--force-with-lease=${ref}:${observed ?? ""}`;
|
|
566
548
|
let pushError;
|
|
567
549
|
try {
|
|
568
|
-
await this.git(
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
"--porcelain",
|
|
572
|
-
"--no-verify",
|
|
573
|
-
lease,
|
|
574
|
-
this.config.profile.remote,
|
|
575
|
-
`${candidate}:${ref}`
|
|
576
|
-
],
|
|
577
|
-
{ timeoutMs: this.postCommitTimeoutMs }
|
|
578
|
-
);
|
|
550
|
+
await this.git(["push", "--porcelain", "--no-verify", lease, this.config.profile.remote, `${candidate}:${ref}`], {
|
|
551
|
+
timeoutMs: this.postCommitTimeoutMs
|
|
552
|
+
});
|
|
579
553
|
await this.afterPushForTest?.();
|
|
580
554
|
} catch (error) {
|
|
581
555
|
pushError = error;
|
|
@@ -591,12 +565,9 @@ var GitSyncBackend = class {
|
|
|
591
565
|
}
|
|
592
566
|
if (current !== candidate) {
|
|
593
567
|
if (pushError && current === observed) {
|
|
594
|
-
throw new Error(
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
cause: pushError
|
|
598
|
-
}
|
|
599
|
-
);
|
|
568
|
+
throw new Error(`Git publication failed without updating the owned branch: ${this.safeError(pushError)}`, {
|
|
569
|
+
cause: pushError
|
|
570
|
+
});
|
|
600
571
|
}
|
|
601
572
|
throw new SyncBackendConflictError(
|
|
602
573
|
pushError ? `Git publication lease was rejected: ${this.safeError(pushError)}` : "Git remote changed immediately after publication.",
|
|
@@ -614,10 +585,7 @@ var GitSyncBackend = class {
|
|
|
614
585
|
async listHistory(signal) {
|
|
615
586
|
const sha = await this.fetchRemoteHead(signal);
|
|
616
587
|
if (!sha) return [];
|
|
617
|
-
const result = await this.git(
|
|
618
|
-
["rev-list", "--first-parent", "--reverse", "--max-count=100", sha],
|
|
619
|
-
{ signal }
|
|
620
|
-
);
|
|
588
|
+
const result = await this.git(["rev-list", "--first-parent", "--reverse", "--max-count=100", sha], { signal });
|
|
621
589
|
const commits = result.stdout.toString("utf8").trim().split("\n").filter(Boolean);
|
|
622
590
|
const entries = [];
|
|
623
591
|
for (const commit of commits) {
|
|
@@ -704,9 +672,7 @@ var GitSyncBackend = class {
|
|
|
704
672
|
throw new Error(`Git snapshot publication was not found: ${reference}`);
|
|
705
673
|
}
|
|
706
674
|
if (matches.length > 1) {
|
|
707
|
-
throw new Error(
|
|
708
|
-
`Git snapshot id is ambiguous; use a commit reference from /sync history: ${reference}`
|
|
709
|
-
);
|
|
675
|
+
throw new Error(`Git snapshot id is ambiguous; use a commit reference from /sync history: ${reference}`);
|
|
710
676
|
}
|
|
711
677
|
return matches[0];
|
|
712
678
|
}
|
|
@@ -716,10 +682,7 @@ var GitSyncBackend = class {
|
|
|
716
682
|
}
|
|
717
683
|
async fetchRemoteHead(signal) {
|
|
718
684
|
await this.ensureCache(signal);
|
|
719
|
-
const result = await this.git(
|
|
720
|
-
["ls-remote", "--refs", this.config.profile.remote, this.remoteRef()],
|
|
721
|
-
{ signal }
|
|
722
|
-
);
|
|
685
|
+
const result = await this.git(["ls-remote", "--refs", this.config.profile.remote, this.remoteRef()], { signal });
|
|
723
686
|
const line = result.stdout.toString("utf8").trim();
|
|
724
687
|
if (!line) return void 0;
|
|
725
688
|
const [sha, ref, ...extra] = line.split(/\s+/u);
|
|
@@ -734,22 +697,14 @@ var GitSyncBackend = class {
|
|
|
734
697
|
const localRef = `refs/pisync/fetch/${process.pid}-${randomUUID()}`;
|
|
735
698
|
try {
|
|
736
699
|
await this.git(
|
|
737
|
-
[
|
|
738
|
-
"fetch",
|
|
739
|
-
"--no-tags",
|
|
740
|
-
"--force",
|
|
741
|
-
this.config.profile.remote,
|
|
742
|
-
`${this.remoteRef()}:${localRef}`
|
|
743
|
-
],
|
|
700
|
+
["fetch", "--no-tags", "--force", this.config.profile.remote, `${this.remoteRef()}:${localRef}`],
|
|
744
701
|
{ signal }
|
|
745
702
|
);
|
|
746
703
|
const fetched = (await this.git(["rev-parse", "--verify", localRef], { signal })).stdout.toString("utf8").trim();
|
|
747
704
|
requireCommitSha(fetched);
|
|
748
705
|
return fetched;
|
|
749
706
|
} finally {
|
|
750
|
-
await this.git(["update-ref", "-d", localRef], { timeoutMs: 5e3 }).catch(
|
|
751
|
-
() => void 0
|
|
752
|
-
);
|
|
707
|
+
await this.git(["update-ref", "-d", localRef], { timeoutMs: 5e3 }).catch(() => void 0);
|
|
753
708
|
}
|
|
754
709
|
},
|
|
755
710
|
signal
|
|
@@ -767,9 +722,7 @@ var GitSyncBackend = class {
|
|
|
767
722
|
return requireGitManifest(parsed);
|
|
768
723
|
}
|
|
769
724
|
showFile(commit, filePath, signal, maxOutputBytes) {
|
|
770
|
-
return this.git(["show", `${commit}:${filePath}`], { signal, maxOutputBytes }).then(
|
|
771
|
-
(result) => result.stdout
|
|
772
|
-
);
|
|
725
|
+
return this.git(["show", `${commit}:${filePath}`], { signal, maxOutputBytes }).then((result) => result.stdout);
|
|
773
726
|
}
|
|
774
727
|
async createCommit(snapshot, files, manifest, parent, signal) {
|
|
775
728
|
const manifestBytes = Buffer.from(`${JSON.stringify(manifest)}
|
|
@@ -806,9 +759,7 @@ var GitSyncBackend = class {
|
|
|
806
759
|
if (objectIds.length !== uniqueFiles.length || objectIds.some((id) => !isCommitSha(id))) {
|
|
807
760
|
throw new Error("Git hash-object returned a malformed payload response.");
|
|
808
761
|
}
|
|
809
|
-
const objectsBySha256 = new Map(
|
|
810
|
-
uniqueFiles.map((file, index) => [file.sha256, objectIds[index]])
|
|
811
|
-
);
|
|
762
|
+
const objectsBySha256 = new Map(uniqueFiles.map((file, index) => [file.sha256, objectIds[index]]));
|
|
812
763
|
const manifestBlob = (await this.git(["hash-object", "-w", "--stdin"], { input: manifestBytes, signal })).stdout.toString("utf8").trim();
|
|
813
764
|
if (!isCommitSha(manifestBlob)) throw new Error("Git returned an invalid manifest blob id.");
|
|
814
765
|
await this.git(["read-tree", "--empty"], { env, signal });
|
|
@@ -827,22 +778,19 @@ var GitSyncBackend = class {
|
|
|
827
778
|
});
|
|
828
779
|
const tree = (await this.git(["write-tree"], { env, signal })).stdout.toString("utf8").trim();
|
|
829
780
|
const date = Number.isNaN(Date.parse(snapshot.createdAt)) ? (/* @__PURE__ */ new Date()).toISOString() : snapshot.createdAt;
|
|
830
|
-
const commit = await this.git(
|
|
831
|
-
|
|
832
|
-
{
|
|
833
|
-
signal,
|
|
834
|
-
input: `pi-sync snapshot ${snapshot.id}
|
|
781
|
+
const commit = await this.git(["commit-tree", tree, ...parent ? ["-p", parent] : [], "-F", "-"], {
|
|
782
|
+
signal,
|
|
783
|
+
input: `pi-sync snapshot ${snapshot.id}
|
|
835
784
|
`,
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
}
|
|
785
|
+
env: {
|
|
786
|
+
GIT_AUTHOR_NAME: "pi-sync",
|
|
787
|
+
GIT_AUTHOR_EMAIL: "pi-sync@localhost",
|
|
788
|
+
GIT_COMMITTER_NAME: "pi-sync",
|
|
789
|
+
GIT_COMMITTER_EMAIL: "pi-sync@localhost",
|
|
790
|
+
GIT_AUTHOR_DATE: date,
|
|
791
|
+
GIT_COMMITTER_DATE: date
|
|
844
792
|
}
|
|
845
|
-
);
|
|
793
|
+
});
|
|
846
794
|
const sha = commit.stdout.toString("utf8").trim();
|
|
847
795
|
requireCommitSha(sha);
|
|
848
796
|
return sha;
|
|
@@ -852,11 +800,7 @@ var GitSyncBackend = class {
|
|
|
852
800
|
}
|
|
853
801
|
ensureCache(signal) {
|
|
854
802
|
if (!this.cacheReady) {
|
|
855
|
-
const operation = withGitCacheMutation(
|
|
856
|
-
this.cacheDir,
|
|
857
|
-
() => this.initializeCache(signal),
|
|
858
|
-
signal
|
|
859
|
-
);
|
|
803
|
+
const operation = withGitCacheMutation(this.cacheDir, () => this.initializeCache(signal), signal);
|
|
860
804
|
const wrapped = operation.catch((error) => {
|
|
861
805
|
if (this.cacheReady === wrapped) this.cacheReady = void 0;
|
|
862
806
|
throw this.redactedError(error);
|
|
@@ -872,9 +816,7 @@ var GitSyncBackend = class {
|
|
|
872
816
|
});
|
|
873
817
|
const versionText = version.stdout.toString("utf8").trim();
|
|
874
818
|
if (!isSupportedGitVersion(versionText)) {
|
|
875
|
-
throw new Error(
|
|
876
|
-
`${versionText || "Unknown Git version"}; pi-sync requires Git 2.30 or newer.`
|
|
877
|
-
);
|
|
819
|
+
throw new Error(`${versionText || "Unknown Git version"}; pi-sync requires Git 2.30 or newer.`);
|
|
878
820
|
}
|
|
879
821
|
const parent = path.dirname(this.cacheDir);
|
|
880
822
|
const cacheParent = path.dirname(this.cacheRoot);
|
|
@@ -982,11 +924,7 @@ function gitBackendIdentity(config) {
|
|
|
982
924
|
} catch {
|
|
983
925
|
remoteIdentity = config.profile.remote;
|
|
984
926
|
}
|
|
985
|
-
const canonical = JSON.stringify([
|
|
986
|
-
remoteIdentity,
|
|
987
|
-
config.destination.branch,
|
|
988
|
-
config.destination.directory
|
|
989
|
-
]);
|
|
927
|
+
const canonical = JSON.stringify([remoteIdentity, config.destination.branch, config.destination.directory]);
|
|
990
928
|
return `git:${sha2562(Buffer.from(canonical))}`;
|
|
991
929
|
}
|
|
992
930
|
function gitDestination(config) {
|
|
@@ -1064,8 +1002,7 @@ function assertProductionRemote(remote) {
|
|
|
1064
1002
|
cause: error
|
|
1065
1003
|
});
|
|
1066
1004
|
}
|
|
1067
|
-
if (!normalized || normalized !== remote)
|
|
1068
|
-
throw new Error("Invalid or non-normalized Git remote.");
|
|
1005
|
+
if (!normalized || normalized !== remote) throw new Error("Invalid or non-normalized Git remote.");
|
|
1069
1006
|
}
|
|
1070
1007
|
async function withGitCacheMutation(cacheDir, run, signal) {
|
|
1071
1008
|
const previous = gitCacheMutationQueues.get(cacheDir) ?? Promise.resolve();
|
|
@@ -1126,4 +1063,4 @@ export {
|
|
|
1126
1063
|
gitBackendIdentity,
|
|
1127
1064
|
isSupportedGitVersion
|
|
1128
1065
|
};
|
|
1129
|
-
//# sourceMappingURL=git-backend-
|
|
1066
|
+
//# sourceMappingURL=git-backend-IAANDL3K.ts.map
|