@narumitw/pi-sync 0.50.3 → 0.51.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 +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
package/src/ui/setup/git-ui.ts
CHANGED
|
@@ -1,293 +1,264 @@
|
|
|
1
1
|
import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { normalizeGitBranch, normalizeGitDirectory, normalizeGitRemote } from "../../backends/git/git-config.js";
|
|
2
3
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
addStorageConnection,
|
|
9
|
-
addSyncSetup,
|
|
10
|
-
saveNewV3Settings,
|
|
11
|
-
updateStorageConnection,
|
|
12
|
-
updateSyncSetup,
|
|
4
|
+
addStorageConnection,
|
|
5
|
+
addSyncSetup,
|
|
6
|
+
saveNewV3Settings,
|
|
7
|
+
updateStorageConnection,
|
|
8
|
+
updateSyncSetup,
|
|
13
9
|
} from "../../settings/settings-management.js";
|
|
14
10
|
import type { PartialConfig } from "../../settings/settings-types.js";
|
|
15
11
|
import { automaticSyncSummary } from "../automatic-sync-summary.js";
|
|
16
12
|
import { safeTerminalText } from "../terminal-text.js";
|
|
17
13
|
import { promptAvailableSetupStorage } from "./setup-location-ui.js";
|
|
18
14
|
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
chooseAutomaticSync,
|
|
16
|
+
chooseSetupContent,
|
|
17
|
+
includedContentLines,
|
|
18
|
+
promptResourceName,
|
|
19
|
+
readSetupConnection,
|
|
24
20
|
} from "./setup-prompts.js";
|
|
25
21
|
import { saveReviewedDraft } from "./setup-review.js";
|
|
26
22
|
import { requiredInput, requiredValueInput } from "./text-input.js";
|
|
27
23
|
|
|
28
|
-
export async function showGitSetup(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
);
|
|
76
|
-
if (saved && !signal?.aborted)
|
|
77
|
-
ctx.ui.notify(
|
|
78
|
-
`Saved Git sync setup “${safeTerminalText(targetName)}”. Choose Sync now to start.`,
|
|
79
|
-
"info",
|
|
80
|
-
);
|
|
81
|
-
return saved;
|
|
24
|
+
export async function showGitSetup(ctx: ExtensionCommandContext, targetName: string, signal?: AbortSignal) {
|
|
25
|
+
const remote = await promptGitRemote(ctx, signal);
|
|
26
|
+
if (!remote) return false;
|
|
27
|
+
const destination = await promptGitDestination(ctx, signal);
|
|
28
|
+
if (!destination) return false;
|
|
29
|
+
const include = await chooseSetupContent(ctx, signal);
|
|
30
|
+
if (!include) return false;
|
|
31
|
+
const automatic = await chooseAutomaticSync(ctx, signal);
|
|
32
|
+
if (automatic === undefined) return false;
|
|
33
|
+
const saved = await saveReviewedDraft(
|
|
34
|
+
ctx,
|
|
35
|
+
"Review Git sync setup",
|
|
36
|
+
[
|
|
37
|
+
`Sync setup: ${safeTerminalText(targetName)}`,
|
|
38
|
+
`Storage connection: ${safeTerminalText(targetName)} (Git)`,
|
|
39
|
+
`Remote: ${safeTerminalText(remote)}`,
|
|
40
|
+
`Sync branch: ${safeTerminalText(destination.branch)}`,
|
|
41
|
+
`Storage location: ${safeTerminalText(destination.directory)}`,
|
|
42
|
+
...includedContentLines(include),
|
|
43
|
+
`Automatic sync: ${automaticSyncSummary(automatic)}`,
|
|
44
|
+
"Authentication: existing Git credential helper or SSH configuration (not stored by pi-sync).",
|
|
45
|
+
"pi-sync manages the entire branch. The repository must already exist; a new branch is created on first push.",
|
|
46
|
+
"Saving does not contact remote storage or start syncing.",
|
|
47
|
+
],
|
|
48
|
+
"Save setup",
|
|
49
|
+
(saveSignal) =>
|
|
50
|
+
saveNewV3Settings(
|
|
51
|
+
{
|
|
52
|
+
setupName: targetName,
|
|
53
|
+
connectionName: targetName,
|
|
54
|
+
connection: { type: "git", remote },
|
|
55
|
+
setup: {
|
|
56
|
+
storage: {
|
|
57
|
+
connection: targetName,
|
|
58
|
+
branch: destination.branch,
|
|
59
|
+
path: destination.directory,
|
|
60
|
+
},
|
|
61
|
+
sync: { include, automatic },
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
saveSignal,
|
|
65
|
+
),
|
|
66
|
+
signal,
|
|
67
|
+
);
|
|
68
|
+
if (saved && !signal?.aborted)
|
|
69
|
+
ctx.ui.notify(`Saved Git sync setup “${safeTerminalText(targetName)}”. Choose Sync now to start.`, "info");
|
|
70
|
+
return saved;
|
|
82
71
|
}
|
|
83
72
|
|
|
84
73
|
export async function showAddGitStorageProfile(ctx: ExtensionCommandContext, signal?: AbortSignal) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
return saved;
|
|
74
|
+
const name = await promptResourceName(ctx, "storage connection", "git", signal);
|
|
75
|
+
if (!name) return false;
|
|
76
|
+
const remote = await promptGitRemote(ctx, signal);
|
|
77
|
+
if (!remote) return false;
|
|
78
|
+
const saved = await saveReviewedDraft(
|
|
79
|
+
ctx,
|
|
80
|
+
"Review storage connection",
|
|
81
|
+
[
|
|
82
|
+
`Name: ${safeTerminalText(name)}`,
|
|
83
|
+
"Type: Git",
|
|
84
|
+
`Remote: ${safeTerminalText(remote)}`,
|
|
85
|
+
"Credentials: existing Git/SSH authentication (not stored)",
|
|
86
|
+
"Adding a connection does not contact the remote or start syncing.",
|
|
87
|
+
],
|
|
88
|
+
"Add storage connection",
|
|
89
|
+
(saveSignal) => addStorageConnection(name, { type: "git", remote }, saveSignal),
|
|
90
|
+
signal,
|
|
91
|
+
);
|
|
92
|
+
if (saved && !signal?.aborted) ctx.ui.notify(`Added storage connection “${safeTerminalText(name)}”.`, "info");
|
|
93
|
+
return saved;
|
|
106
94
|
}
|
|
107
95
|
|
|
108
96
|
export async function showEditGitStorageProfile(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
97
|
+
ctx: ExtensionCommandContext,
|
|
98
|
+
name: string,
|
|
99
|
+
profile: Record<string, unknown>,
|
|
100
|
+
signal?: AbortSignal,
|
|
101
|
+
affectedSetups?: string[],
|
|
114
102
|
) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
signal,
|
|
143
|
-
);
|
|
144
|
-
if (saved && !signal?.aborted)
|
|
145
|
-
ctx.ui.notify(`Saved storage connection “${safeTerminalText(name)}”.`, "info");
|
|
146
|
-
return saved;
|
|
103
|
+
const remote = await promptGitRemote(ctx, signal, typeof profile.remote === "string" ? profile.remote : undefined);
|
|
104
|
+
if (!remote) return false;
|
|
105
|
+
const saved = await saveReviewedDraft(
|
|
106
|
+
ctx,
|
|
107
|
+
"Review storage connection",
|
|
108
|
+
[
|
|
109
|
+
`Storage connection: ${safeTerminalText(name)}`,
|
|
110
|
+
`Remote: ${safeTerminalText(String(profile.remote ?? "missing"))} → ${safeTerminalText(remote)}`,
|
|
111
|
+
`Affected sync setups: ${affectedSetups?.length ? affectedSetups.map(safeTerminalText).join(", ") : "None"}`,
|
|
112
|
+
"Saving changes future storage access for every affected setup; it does not move or delete remote history.",
|
|
113
|
+
],
|
|
114
|
+
"Save storage connection",
|
|
115
|
+
(saveSignal) =>
|
|
116
|
+
updateStorageConnection(
|
|
117
|
+
name,
|
|
118
|
+
(current) => {
|
|
119
|
+
if (current.type !== "git" || current.remote !== profile.remote)
|
|
120
|
+
throw new Error("Storage connection changed while it was open; reopen it.");
|
|
121
|
+
return { ...current, remote };
|
|
122
|
+
},
|
|
123
|
+
affectedSetups,
|
|
124
|
+
saveSignal,
|
|
125
|
+
),
|
|
126
|
+
signal,
|
|
127
|
+
);
|
|
128
|
+
if (saved && !signal?.aborted) ctx.ui.notify(`Saved storage connection “${safeTerminalText(name)}”.`, "info");
|
|
129
|
+
return saved;
|
|
147
130
|
}
|
|
148
131
|
|
|
149
132
|
export async function showAddGitTarget(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
133
|
+
ctx: ExtensionCommandContext,
|
|
134
|
+
name: string,
|
|
135
|
+
profile: string,
|
|
136
|
+
signal?: AbortSignal,
|
|
154
137
|
) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
ctx.ui.notify(`Added sync setup “${safeTerminalText(name)}”.`, "info");
|
|
189
|
-
return saved;
|
|
138
|
+
const selected = await promptGitDestination(ctx, signal);
|
|
139
|
+
if (!selected) return false;
|
|
140
|
+
const storage = await promptAvailableSetupStorage(
|
|
141
|
+
ctx,
|
|
142
|
+
{ connection: profile, branch: selected.branch, path: selected.directory },
|
|
143
|
+
signal,
|
|
144
|
+
);
|
|
145
|
+
if (!storage) return false;
|
|
146
|
+
const include = await chooseSetupContent(ctx, signal);
|
|
147
|
+
if (!include) return false;
|
|
148
|
+
const automatic = await chooseAutomaticSync(ctx, signal);
|
|
149
|
+
if (automatic === undefined) return false;
|
|
150
|
+
const connection = await readSetupConnection(profile, signal);
|
|
151
|
+
if (connection?.type !== "git") throw new Error("Storage connection changed; reopen setup.");
|
|
152
|
+
const saved = await saveReviewedDraft(
|
|
153
|
+
ctx,
|
|
154
|
+
"Review Git sync setup",
|
|
155
|
+
[
|
|
156
|
+
`Sync setup: ${safeTerminalText(name)}`,
|
|
157
|
+
`Storage connection: ${safeTerminalText(profile)}`,
|
|
158
|
+
`Remote: ${safeTerminalText(connection.remote)}`,
|
|
159
|
+
`Sync branch: ${safeTerminalText(storage.branch)}`,
|
|
160
|
+
`Storage location: ${safeTerminalText(storage.path)}`,
|
|
161
|
+
...includedContentLines(include),
|
|
162
|
+
`Automatic sync: ${automaticSyncSummary(automatic)}`,
|
|
163
|
+
"pi-sync manages the entire branch. Adding this setup does not sync or modify remote data.",
|
|
164
|
+
],
|
|
165
|
+
"Add sync setup",
|
|
166
|
+
(saveSignal) => addSyncSetup(name, { storage, sync: { include, automatic } }, saveSignal, connection),
|
|
167
|
+
signal,
|
|
168
|
+
);
|
|
169
|
+
if (saved && !signal?.aborted) ctx.ui.notify(`Added sync setup “${safeTerminalText(name)}”.`, "info");
|
|
170
|
+
return saved;
|
|
190
171
|
}
|
|
191
172
|
|
|
192
|
-
export async function showEditGitTarget(
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
),
|
|
242
|
-
signal,
|
|
243
|
-
);
|
|
244
|
-
if (saved && !signal?.aborted)
|
|
245
|
-
ctx.ui.notify(`Saved sync setup “${safeTerminalText(partial.setupName)}”.`, "info");
|
|
246
|
-
return saved;
|
|
173
|
+
export async function showEditGitTarget(ctx: ExtensionCommandContext, partial: PartialConfig, signal?: AbortSignal) {
|
|
174
|
+
let destination = await promptGitDestination(ctx, signal, partial);
|
|
175
|
+
if (!destination) return false;
|
|
176
|
+
while (destination.directory !== partial.storagePath && destination.branch === partial.branch) {
|
|
177
|
+
ctx.ui.notify(
|
|
178
|
+
"Changing a Git storage path requires a new Git branch so the existing branch remains readable.",
|
|
179
|
+
"warning",
|
|
180
|
+
);
|
|
181
|
+
const branch = await requiredValueInput(
|
|
182
|
+
ctx,
|
|
183
|
+
"New Git branch\n\nKeep the previous branch unchanged; enter a new branch for this path.",
|
|
184
|
+
"pi-sync/archive",
|
|
185
|
+
signal,
|
|
186
|
+
normalizeGitBranch,
|
|
187
|
+
);
|
|
188
|
+
if (!branch) return false;
|
|
189
|
+
destination = { ...destination, branch };
|
|
190
|
+
}
|
|
191
|
+
const chosen = destination;
|
|
192
|
+
const connection = await readSetupConnection(partial.connectionName, signal);
|
|
193
|
+
if (connection.type !== "git") throw new Error("Storage connection changed; reopen setup.");
|
|
194
|
+
const saved = await saveReviewedDraft(
|
|
195
|
+
ctx,
|
|
196
|
+
"Review sync setup",
|
|
197
|
+
[
|
|
198
|
+
`Sync setup: ${safeTerminalText(partial.setupName)}`,
|
|
199
|
+
`Storage connection: ${safeTerminalText(partial.connectionName)}`,
|
|
200
|
+
`Remote: ${safeTerminalText(connection.remote)}`,
|
|
201
|
+
`Branch: ${safeTerminalText(partial.branch ?? "missing")} → ${safeTerminalText(chosen.branch)}`,
|
|
202
|
+
`Storage path: ${safeTerminalText(partial.storagePath)} → ${safeTerminalText(chosen.directory)}`,
|
|
203
|
+
"Saving changes the future storage location only; it does not move or delete remote history.",
|
|
204
|
+
],
|
|
205
|
+
"Save sync setup",
|
|
206
|
+
(saveSignal) =>
|
|
207
|
+
updateSyncSetup(
|
|
208
|
+
partial.setupName,
|
|
209
|
+
(setup) => {
|
|
210
|
+
if (typeof setup.storage.branch !== "string") throw new Error("Sync setup storage type changed; reopen it.");
|
|
211
|
+
return {
|
|
212
|
+
...setup,
|
|
213
|
+
storage: { ...setup.storage, branch: chosen.branch, path: chosen.directory },
|
|
214
|
+
};
|
|
215
|
+
},
|
|
216
|
+
{ expectedStorage: partial, expectedConnection: connection, signal: saveSignal },
|
|
217
|
+
),
|
|
218
|
+
signal,
|
|
219
|
+
);
|
|
220
|
+
if (saved && !signal?.aborted) ctx.ui.notify(`Saved sync setup “${safeTerminalText(partial.setupName)}”.`, "info");
|
|
221
|
+
return saved;
|
|
247
222
|
}
|
|
248
223
|
|
|
249
|
-
async function promptGitRemote(
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
)
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
"git@github.com:owner/private-pi-sync.git (SSH) or https://github.com/owner/private-pi-sync.git (HTTPS)",
|
|
267
|
-
signal,
|
|
268
|
-
validate,
|
|
269
|
-
);
|
|
224
|
+
async function promptGitRemote(ctx: ExtensionCommandContext, signal?: AbortSignal, current?: string) {
|
|
225
|
+
const title =
|
|
226
|
+
"Git remote URL (SSH or HTTPS)\n\nUse an existing private repository with Git/SSH authentication already configured.";
|
|
227
|
+
const validate = (value: string) => {
|
|
228
|
+
const remote = normalizeGitRemote(value);
|
|
229
|
+
if (!remote) throw new Error("Git remote URL is required.");
|
|
230
|
+
return remote;
|
|
231
|
+
};
|
|
232
|
+
return current
|
|
233
|
+
? requiredInput(ctx, title, current, signal, validate)
|
|
234
|
+
: requiredValueInput(
|
|
235
|
+
ctx,
|
|
236
|
+
title,
|
|
237
|
+
"git@github.com:owner/private-pi-sync.git (SSH) or https://github.com/owner/private-pi-sync.git (HTTPS)",
|
|
238
|
+
signal,
|
|
239
|
+
validate,
|
|
240
|
+
);
|
|
270
241
|
}
|
|
271
242
|
|
|
272
243
|
async function promptGitDestination(
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
244
|
+
ctx: ExtensionCommandContext,
|
|
245
|
+
signal?: AbortSignal,
|
|
246
|
+
current: Partial<PartialConfig> = {},
|
|
276
247
|
) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
248
|
+
const branch = await requiredInput(
|
|
249
|
+
ctx,
|
|
250
|
+
"Git branch for sync snapshots\n\npi-sync manages this entire branch, not your local working branch.\nUse a new branch or one already used by pi-sync; unrelated content is rejected.",
|
|
251
|
+
current.branch ?? "main",
|
|
252
|
+
signal,
|
|
253
|
+
normalizeGitBranch,
|
|
254
|
+
);
|
|
255
|
+
if (!branch) return undefined;
|
|
256
|
+
const directory = await requiredInput(
|
|
257
|
+
ctx,
|
|
258
|
+
"Git storage path\n\nRelative to the repository root, not your local filesystem.\n./ stores manifest.json and files/ at the repository root.",
|
|
259
|
+
current.storagePath ?? "./",
|
|
260
|
+
signal,
|
|
261
|
+
normalizeGitDirectory,
|
|
262
|
+
);
|
|
263
|
+
return directory ? { branch, directory } : undefined;
|
|
293
264
|
}
|