@narumitw/pi-sync 0.50.2 → 0.50.3

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.
@@ -569,7 +569,7 @@ import {
569
569
  Text,
570
570
  truncateToWidth
571
571
  } from "@earendil-works/pi-tui";
572
- import { runCustomInteraction } from "@narumitw/pi-tui-kit";
572
+ import { formatInteractionHints, runCustomInteraction } from "@narumitw/pi-tui-kit";
573
573
  var MASK = "\u2022";
574
574
  async function promptSecret(ctx, title, options = { required: true }) {
575
575
  if (ctx.mode !== "tui" || options.signal?.aborted) return void 0;
@@ -579,13 +579,22 @@ async function promptSecret(ctx, title, options = { required: true }) {
579
579
  create: ({ tui, theme, keybindings, complete }) => {
580
580
  const heading = new Text("", 0, 0);
581
581
  const hint = new Text("", 0, 0);
582
- const submitKey = keybindingText(keybindings, "tui.input.submit", "enter");
583
- const cancelKey = keybindingText(keybindings, "tui.select.cancel", "esc", ["ctrl+c"]);
582
+ const interactionHint = formatInteractionHints(keybindings, [
583
+ {
584
+ keys: keybindings.getKeys("tui.input.submit").filter((key) => !hasControlCharacter(key)),
585
+ label: "continue"
586
+ },
587
+ {
588
+ keys: [
589
+ ...keybindings.getKeys("tui.select.cancel").filter((key) => !hasControlCharacter(key)),
590
+ "ctrl+c"
591
+ ],
592
+ label: "cancel"
593
+ }
594
+ ]);
584
595
  const applyTheme = () => {
585
596
  heading.setText(theme.fg("accent", theme.bold(title)));
586
- hint.setText(
587
- theme.fg("dim", `${submitKey} continue \u2022 ${cancelKey} cancel \u2022 Input is hidden`)
588
- );
597
+ hint.setText(theme.fg("dim", `${interactionHint} \u2022 Input is hidden`));
589
598
  };
590
599
  applyTheme();
591
600
  const input = new MaskedInput(keybindings);
@@ -752,14 +761,6 @@ var MaskedInput = class {
752
761
  this.cursor += characters.length;
753
762
  }
754
763
  };
755
- function keybindingText(keybindings, binding, fallback, additionalKeys = []) {
756
- const keys = [.../* @__PURE__ */ new Set([...keybindings.getKeys(binding), ...additionalKeys])].map(String).map((key) => {
757
- if (key === "return") return "enter";
758
- if (key === "escape") return "esc";
759
- return hasControlCharacter(key) ? "" : key;
760
- }).filter(Boolean);
761
- return keys.join("/") || fallback;
762
- }
763
764
  function hasControlCharacter(value) {
764
765
  return [...value].some((character) => {
765
766
  const code = character.codePointAt(0) ?? 0;
@@ -1252,4 +1253,4 @@ export {
1252
1253
  showAddWebDavStorageProfile,
1253
1254
  showEditWebDavStorageProfile
1254
1255
  };
1255
- //# sourceMappingURL=chunk-KW7YQEZN.ts.map
1256
+ //# sourceMappingURL=chunk-DHVFS4QK.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/commands/setup-completions.ts", "../../src/ui/setup/text-input.ts", "../../src/ui/setup/setup-location-ui.ts", "../../src/ui/setup/setup-prompts.ts", "../../src/ui/setup/setup-review.ts", "../../src/ui/setup/git-ui.ts", "../../src/ui/secret-input.ts", "../../src/ui/setup/s3-credentials-ui.ts", "../../src/ui/setup/s3-ui.ts", "../../src/ui/setup/webdav-ui.ts"],
4
+ "sourcesContent": ["import { configuredSyncSetupNames } from \"../settings/settings-store.js\";\nimport { setSyncSetupCompletions } from \"./command.js\";\n\nexport async function refreshTargetCompletions() {\n\tsetSyncSetupCompletions(await configuredSyncSetupNames());\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { normalizeS3Bucket, requiredString } from \"../../settings/settings-validation.js\";\nimport { errorMessage } from \"../../sync/sync-errors.js\";\nimport { safeTerminalText } from \"../terminal-text.js\";\n\nexport type ValidateInput = (value: string) => string | Promise<string>;\n\nexport async function requiredExistingBucket(\n\tctx: ExtensionCommandContext,\n\texample: string,\n\tsignal?: AbortSignal,\n) {\n\treturn requiredValueInput(\n\t\tctx,\n\t\t\"Existing bucket\\n\\nThe bucket must already exist; pi-sync will not create it.\",\n\t\texample,\n\t\tsignal,\n\t\tnormalizeS3Bucket,\n\t);\n}\n\nexport async function requiredInput(\n\tctx: ExtensionCommandContext,\n\ttitle: string,\n\tdefaultValue: string,\n\tsignal?: AbortSignal,\n\tvalidate?: ValidateInput,\n) {\n\treturn promptTextInput(ctx, title, { defaultValue, validate, rejectPlaceholders: true }, signal);\n}\n\nexport async function requiredValueInput(\n\tctx: ExtensionCommandContext,\n\ttitle: string,\n\texample: string,\n\tsignal?: AbortSignal,\n\tvalidate?: ValidateInput,\n) {\n\treturn promptTextInput(ctx, title, { example, validate, rejectPlaceholders: true }, signal);\n}\n\nexport async function promptTextInput(\n\tctx: ExtensionCommandContext,\n\ttitle: string,\n\toptions: {\n\t\tdefaultValue?: string;\n\t\texample?: string;\n\t\tvalidate?: ValidateInput;\n\t\trejectPlaceholders?: boolean;\n\t},\n\tsignal?: AbortSignal,\n) {\n\t// Pi ignores placeholders. Keep defaults/examples visible; only an explicit blank accepts a default.\n\tconst hint =\n\t\toptions.defaultValue !== undefined\n\t\t\t? `Default: ${safeTerminalText(options.defaultValue)} (leave blank to keep)`\n\t\t\t: `Example: ${safeTerminalText(options.example ?? \"\")}\\nEnter your own value; this example is not a default.`;\n\twhile (true) {\n\t\tsignal?.throwIfAborted();\n\t\tconst value = await ctx.ui.input(`${title}\\n\\n${hint}`, undefined, { signal });\n\t\tsignal?.throwIfAborted();\n\t\tif (value === undefined) return undefined;\n\t\ttry {\n\t\t\tconst normalized = value.trim() || options.defaultValue;\n\t\t\tif (!normalized) throw new Error(`${title.split(\"\\n\")[0]} is required.`);\n\t\t\tif (options.rejectPlaceholders && /[<>]/u.test(normalized)) {\n\t\t\t\tthrow new Error(\"Replace example placeholders such as <account-id> with your own value.\");\n\t\t\t}\n\t\t\tconst checked = requiredString(normalized, title.split(\"\\n\")[0] ?? \"value\");\n\t\t\tconst result = options.validate ? await options.validate(checked) : checked;\n\t\t\tsignal?.throwIfAborted();\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tsignal?.throwIfAborted();\n\t\t\tctx.ui.notify(`${errorMessage(error)} Enter a corrected value, or cancel.`, \"warning\");\n\t\t}\n\t}\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { normalizeGitBranch } from \"../../backends/git/git-config.js\";\nimport { readLocalConfigObject } from \"../../settings/settings-store.js\";\nimport type {\n\tStorageConnectionSettings,\n\tSyncSetupSettings,\n} from \"../../settings/settings-types.js\";\nimport {\n\teffectiveSyncSetupRemoteIdentity,\n\tnormalizeStoragePath,\n\townRecord,\n} from \"../../settings/settings-validation.js\";\nimport { errorMessage } from \"../../sync/sync-errors.js\";\nimport { safeTerminalText } from \"../terminal-text.js\";\nimport {\n\tpromptTextInput,\n\trequiredExistingBucket,\n\trequiredInput,\n\trequiredValueInput,\n} from \"./text-input.js\";\n\ninterface ChosenRemoteLocation {\n\tconnectionName: string;\n\tbucket: string;\n\tpath: string;\n}\n\nexport async function chooseInitialRemoteLocation(\n\tctx: ExtensionCommandContext,\n\t_preset: string,\n\tsetupName: string,\n\tsignal?: AbortSignal,\n): Promise<ChosenRemoteLocation | undefined> {\n\tconst choice = await ctx.ui.select(\n\t\t\"Choose storage location\\n\\nUse an existing bucket. ./ stores snapshots at the bucket root; a custom path keeps them in a separate folder.\",\n\t\t[\"Use an existing bucket at ./\", \"Customize remote location\", \"Cancel\"],\n\t\t{ signal },\n\t);\n\tif (signal?.aborted || !choice || choice === \"Cancel\") return undefined;\n\tif (choice === \"Customize remote location\")\n\t\treturn chooseCustomRemoteLocation(ctx, setupName, signal);\n\tconst bucket = await requiredExistingBucket(ctx, \"pi-sync\", signal);\n\treturn bucket ? { connectionName: setupName, bucket, path: \"./\" } : undefined;\n}\n\nexport async function chooseAdditionalRemoteLocation(\n\tctx: ExtensionCommandContext,\n\tsettings: Record<string, unknown>,\n\tconnectionName: string,\n\tsetupName: string,\n\tsignal?: AbortSignal,\n): Promise<Omit<ChosenRemoteLocation, \"connectionName\"> | undefined> {\n\tconst setups = ownRecord(settings.syncSetups) ?? {};\n\tconst currentSetup =\n\t\ttypeof settings.activeSyncSetup === \"string\" ? settings.activeSyncSetup : undefined;\n\tconst candidates = Object.entries(setups)\n\t\t.map(([name, value]) => ({ name, storage: ownRecord(ownRecord(value)?.storage) }))\n\t\t.filter(\n\t\t\t(item): item is { name: string; storage: Record<string, unknown> } =>\n\t\t\t\titem.storage?.connection === connectionName && typeof item.storage.bucket === \"string\",\n\t\t);\n\tconst source =\n\t\tcandidates.find((item) => item.name === currentSetup) ??\n\t\tcandidates.sort((left, right) => left.name.localeCompare(right.name))[0];\n\tif (source) {\n\t\tconst suggestedPath = \"./\";\n\t\tconst sameBucketLabel = `Same bucket as \u201C${safeTerminalText(source.name)}\u201D`;\n\t\tconst choice = await ctx.ui.select(\n\t\t\t[\n\t\t\t\t`Storage location for \u201C${safeTerminalText(setupName)}\u201D`,\n\t\t\t\t\"\",\n\t\t\t\t`Existing bucket: ${safeTerminalText(String(source.storage.bucket))}`,\n\t\t\t\t`Remote path: ${safeTerminalText(suggestedPath)}`,\n\t\t\t\t\"./ uses the bucket root. Use a different path or bucket for independent setups.\",\n\t\t\t].join(\"\\n\"),\n\t\t\t[sameBucketLabel, \"Use a different bucket\", \"Customize remote location\", \"Cancel\"],\n\t\t\t{ signal },\n\t\t);\n\t\tif (signal?.aborted || !choice || choice === \"Cancel\") return undefined;\n\t\tif (choice === sameBucketLabel) {\n\t\t\treturn { bucket: String(source.storage.bucket), path: suggestedPath };\n\t\t}\n\t\tif (choice === \"Use a different bucket\") {\n\t\t\tconst bucket = await requiredExistingBucket(ctx, \"pi-sync\", signal);\n\t\t\treturn bucket ? { bucket, path: \"./\" } : undefined;\n\t\t}\n\t\tconst custom = await chooseCustomRemoteLocation(ctx, connectionName, signal);\n\t\treturn custom ? { bucket: custom.bucket, path: custom.path } : undefined;\n\t}\n\n\tconst location = await chooseInitialRemoteLocation(ctx, \"S3\", setupName, signal);\n\treturn location ? { bucket: location.bucket, path: location.path } : undefined;\n}\n\nasync function chooseCustomRemoteLocation(\n\tctx: ExtensionCommandContext,\n\tconnectionName: string,\n\tsignal?: AbortSignal,\n): Promise<ChosenRemoteLocation | undefined> {\n\tconst bucket = await requiredExistingBucket(ctx, \"pi-sync\", signal);\n\tif (!bucket) return undefined;\n\tconst storagePath = await requiredInput(\n\t\tctx,\n\t\t\"Storage path\\n\\nPath inside the bucket, not your local filesystem.\\n./ uses the bucket root. Use different paths for independent setups.\",\n\t\t\"./\",\n\t\tsignal,\n\t\tnormalizeStoragePath,\n\t);\n\tif (!storagePath) return undefined;\n\treturn { connectionName, bucket, path: normalizeStoragePath(storagePath) };\n}\n\n/** Early UI check only; the settings writer still validates uniqueness under its lock. */\nexport async function promptAvailableSetupStorage<T extends SyncSetupSettings[\"storage\"]>(\n\tctx: ExtensionCommandContext,\n\tinitial: T,\n\tsignal?: AbortSignal,\n): Promise<T | undefined> {\n\tlet storage = initial;\n\twhile (!signal?.aborted) {\n\t\tconst settings = await readLocalConfigObject();\n\t\tif (signal?.aborted) return undefined;\n\t\tconst connection = settings?.storageConnections[storage.connection];\n\t\tif (!settings || !connection) throw new Error(\"Storage connection changed; reopen setup.\");\n\t\tconst identity = setupPublicationIdentity(storage, connection);\n\t\tconst occupied = Object.entries(settings.syncSetups).find(\n\t\t\t([, setup]) =>\n\t\t\t\tsetupPublicationIdentity(\n\t\t\t\t\tsetup.storage,\n\t\t\t\t\tsettings.storageConnections[setup.storage.connection],\n\t\t\t\t) === identity,\n\t\t);\n\t\tif (!occupied) return storage;\n\t\tconst git = connection.type === \"git\";\n\t\tconst message = `${git ? \"Git branch\" : \"Storage location\"} is already used by \u201C${safeTerminalText(occupied[0])}\u201D. ${git ? \"Use a different branch; pi-sync owns the entire branch.\" : \"Enter a different storage path, or cancel to choose another connection or bucket.\"}`;\n\t\tctx.ui.notify(message, \"warning\");\n\t\tconst title = `${git ? \"Git branch for the new setup\" : \"Storage path for the new setup\"}\\n\\n${message}`;\n\t\tconst example = git ? \"pi-sync/work\" : \"backups/work\";\n\t\tconst value =\n\t\t\tconnection.type === \"webdav\"\n\t\t\t\t? await promptTextInput(ctx, title, { example }, signal)\n\t\t\t\t: await requiredValueInput(ctx, title, example, signal);\n\t\tif (signal?.aborted || value === undefined) return undefined;\n\t\ttry {\n\t\t\tstorage = git\n\t\t\t\t? { ...storage, branch: normalizeGitBranch(value) }\n\t\t\t\t: { ...storage, path: normalizeStoragePath(value) };\n\t\t} catch (error) {\n\t\t\tctx.ui.notify(safeTerminalText(errorMessage(error)), \"warning\");\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction setupPublicationIdentity(\n\tstorage: SyncSetupSettings[\"storage\"],\n\tconnection: StorageConnectionSettings,\n) {\n\t// Git publications own a complete branch tree; changing only its directory is not isolation.\n\treturn effectiveSyncSetupRemoteIdentity(\n\t\t{\n\t\t\tstorage: connection.type === \"git\" ? { ...storage, path: \"./\" } : storage,\n\t\t\tsync: { include: [], automatic: false },\n\t\t},\n\t\tconnection,\n\t);\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { readLocalConfigObject } from \"../../settings/settings-store.js\";\nimport { validateConfigName } from \"../../settings/settings-validation.js\";\nimport { DEFAULT_SYNC_INCLUDE } from \"../../sync/sync-policy.js\";\nimport { safeTerminalText } from \"../terminal-text.js\";\nimport { promptTextInput } from \"./text-input.js\";\n\nexport async function readSetupConnection(name: string, signal?: AbortSignal) {\n\tconst connection = (await readLocalConfigObject())?.storageConnections[name];\n\tsignal?.throwIfAborted();\n\tif (!connection) throw new Error(\"Storage connection changed; reopen setup.\");\n\treturn connection;\n}\n\nexport const AUTOMATIC_SYNC_DESCRIPTION =\n\t\"Check the current setup in the background at startup; review changes in /sync before transferring. At shutdown, automatically push selected content only when sessions are included. No startup dialogs.\";\n\nexport async function chooseSetupContent(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n\tconst choice = await ctx.ui.select(\n\t\t\"Choose included content\\n\\nRecommended: Pi settings, instructions, skills, prompts, themes, and extensions.\\nMinimal: settings.json and AGENTS.md.\\nReview the exact paths before saving.\",\n\t\t[\"Recommended Pi settings\", \"Minimal settings\", \"Cancel\"],\n\t\t{ signal },\n\t);\n\tsignal?.throwIfAborted();\n\tif (!choice || choice === \"Cancel\") return undefined;\n\treturn choice === \"Minimal settings\" ? [\"settings.json\", \"AGENTS.md\"] : [...DEFAULT_SYNC_INCLUDE];\n}\n\nexport async function chooseAutomaticSync(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n\tconst choice = await ctx.ui.select(\n\t\t`Automatic sync for this setup\\n\\n${AUTOMATIC_SYNC_DESCRIPTION}`,\n\t\t[\"Keep automatic sync off\", \"Enable automatic sync\", \"Cancel\"],\n\t\t{ signal },\n\t);\n\tsignal?.throwIfAborted();\n\treturn !choice || choice === \"Cancel\" ? undefined : choice === \"Enable automatic sync\";\n}\n\nexport async function chooseSessions(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n\tconst choice = await ctx.ui.select(\n\t\t\"Session conversations\\n\\nSessions can contain prompts, tool output, paths, screenshots, and secrets.\",\n\t\t[\"Keep sessions off (recommended)\", \"Include session conversations\", \"Cancel\"],\n\t\t{ signal },\n\t);\n\tsignal?.throwIfAborted();\n\tif (!choice || choice === \"Cancel\") return undefined;\n\tif (choice !== \"Include session conversations\") return false;\n\tconst confirmed = await ctx.ui.confirm(\n\t\t\"Include session conversations?\",\n\t\t\"I understand that session JSONL can contain prompts, tool output, paths, screenshots, and secrets.\",\n\t\t{ signal },\n\t);\n\tsignal?.throwIfAborted();\n\treturn confirmed ? true : undefined;\n}\n\nexport function includedContentLines(include: readonly string[], sessions = false) {\n\tconst paths = [...include, ...(sessions && !include.includes(\"sessions\") ? [\"sessions\"] : [])];\n\treturn [\n\t\t`Included content: ${paths.length} paths`,\n\t\t...paths.map((item) => ` ${safeTerminalText(item)}`),\n\t\t`Sessions: ${sessions ? \"On \u2014 privacy warning acknowledged\" : \"Off\"}`,\n\t];\n}\n\nexport async function promptResourceName(\n\tctx: ExtensionCommandContext,\n\tkind: \"sync setup\" | \"storage connection\",\n\tdefaultValue: string,\n\tsignal?: AbortSignal,\n\tliteralBrackets = false,\n) {\n\treturn promptTextInput(\n\t\tctx,\n\t\t`Name this ${kind}\\n\\nA local label, such as home or work.`,\n\t\t{\n\t\t\tdefaultValue,\n\t\t\trejectPlaceholders: !literalBrackets,\n\t\t\tvalidate: async (name) => {\n\t\t\t\tvalidateConfigName(name, kind);\n\t\t\t\tconst settings = await readLocalConfigObject();\n\t\t\t\tsignal?.throwIfAborted();\n\t\t\t\tconst names = kind === \"sync setup\" ? settings?.syncSetups : settings?.storageConnections;\n\t\t\t\tif (names && Object.hasOwn(names, name)) {\n\t\t\t\t\tthrow new Error(`A ${kind} with this name already exists. Choose a different name.`);\n\t\t\t\t}\n\t\t\t\treturn name;\n\t\t\t},\n\t\t},\n\t\tsignal,\n\t);\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { defineMenu, runMenu } from \"@narumitw/pi-tui-kit\";\nimport { syncErrorGuidance } from \"../../sync/sync-error-guidance.js\";\n\n/** A settings draft is committed only after review; retryable I/O failures retain the same draft. */\nexport async function saveReviewedDraft(\n\tctx: ExtensionCommandContext,\n\ttitle: string,\n\tlines: readonly string[],\n\tlabel: string,\n\tsave: (signal: AbortSignal) => Promise<unknown>,\n\tsignal?: AbortSignal,\n) {\n\tlet saved = false;\n\tlet failure: unknown;\n\tlet failureText: string | undefined;\n\tconst menu = defineMenu<undefined, \"review\", \"save\", ExtensionCommandContext>({\n\t\tstart: \"review\",\n\t\tscreens: {\n\t\t\treview: () => ({\n\t\t\t\tkind: \"review\",\n\t\t\t\ttitle,\n\t\t\t\tcontent: [...(failureText ? [failureText, \"\"] : []), ...lines].join(\"\\n\"),\n\t\t\t\tlines: [\"Review before saving. Back cancels this draft.\"],\n\t\t\t\tformat: { kind: \"text\" },\n\t\t\t\tviewportSize: \"adaptive\",\n\t\t\t\tconfirm: { id: \"save\", label, action: \"save\" },\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t},\n\t\tactions: {\n\t\t\tsave: async ({ signal: actionSignal }) => {\n\t\t\t\ttry {\n\t\t\t\t\tactionSignal.throwIfAborted();\n\t\t\t\t\tawait save(actionSignal);\n\t\t\t\t\tsaved = true;\n\t\t\t\t\treturn { kind: \"close\" };\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (actionSignal.aborted) return { kind: \"close\" };\n\t\t\t\t\t// Do not silently rebase a stale review or overwrite an invalid settings file.\n\t\t\t\t\t// The caller must reopen current settings for those failures.\n\t\t\t\t\tif (!retryableSettingsError(error)) {\n\t\t\t\t\t\tfailure = error;\n\t\t\t\t\t\treturn { kind: \"close\" };\n\t\t\t\t\t}\n\t\t\t\t\tfailureText = `Not saved. ${syncErrorGuidance(error)}\\nYour draft is retained. Fix the problem, then save again, or cancel.`;\n\t\t\t\t\tctx.ui.notify(failureText, \"error\");\n\t\t\t\t\treturn { kind: \"stay\" };\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t});\n\tconst result = await runMenu(ctx, menu, {\n\t\tgetState: () => undefined,\n\t\tsignal,\n\t\tisCurrent: () => !signal?.aborted,\n\t});\n\tif (signal?.aborted) return false;\n\tif (failure) throw failure;\n\tif (result.kind === \"error\") throw result.error;\n\treturn saved;\n}\n\nfunction retryableSettingsError(error: unknown) {\n\tconst code = (error as NodeJS.ErrnoException | undefined)?.code;\n\treturn (\n\t\tcode !== undefined &&\n\t\t[\"EACCES\", \"EPERM\", \"ENOSPC\", \"EBUSY\", \"EIO\", \"EMFILE\", \"ENFILE\", \"EROFS\"].includes(code)\n\t);\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport {\n\tnormalizeGitBranch,\n\tnormalizeGitDirectory,\n\tnormalizeGitRemote,\n} from \"../../backends/git/git-config.js\";\nimport {\n\taddStorageConnection,\n\taddSyncSetup,\n\tsaveNewV3Settings,\n\tupdateStorageConnection,\n\tupdateSyncSetup,\n} from \"../../settings/settings-management.js\";\nimport type { PartialConfig } from \"../../settings/settings-types.js\";\nimport { automaticSyncSummary } from \"../automatic-sync-summary.js\";\nimport { safeTerminalText } from \"../terminal-text.js\";\nimport { promptAvailableSetupStorage } from \"./setup-location-ui.js\";\nimport {\n\tchooseAutomaticSync,\n\tchooseSetupContent,\n\tincludedContentLines,\n\tpromptResourceName,\n\treadSetupConnection,\n} from \"./setup-prompts.js\";\nimport { saveReviewedDraft } from \"./setup-review.js\";\nimport { requiredInput, requiredValueInput } from \"./text-input.js\";\n\nexport async function showGitSetup(\n\tctx: ExtensionCommandContext,\n\ttargetName: string,\n\tsignal?: AbortSignal,\n) {\n\tconst remote = await promptGitRemote(ctx, signal);\n\tif (!remote) return false;\n\tconst destination = await promptGitDestination(ctx, signal);\n\tif (!destination) return false;\n\tconst include = await chooseSetupContent(ctx, signal);\n\tif (!include) return false;\n\tconst automatic = await chooseAutomaticSync(ctx, signal);\n\tif (automatic === undefined) return false;\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review Git sync setup\",\n\t\t[\n\t\t\t`Sync setup: ${safeTerminalText(targetName)}`,\n\t\t\t`Storage connection: ${safeTerminalText(targetName)} (Git)`,\n\t\t\t`Remote: ${safeTerminalText(remote)}`,\n\t\t\t`Sync branch: ${safeTerminalText(destination.branch)}`,\n\t\t\t`Storage location: ${safeTerminalText(destination.directory)}`,\n\t\t\t...includedContentLines(include),\n\t\t\t`Automatic sync: ${automaticSyncSummary(automatic)}`,\n\t\t\t\"Authentication: existing Git credential helper or SSH configuration (not stored by pi-sync).\",\n\t\t\t\"pi-sync manages the entire branch. The repository must already exist; a new branch is created on first push.\",\n\t\t\t\"Saving does not contact remote storage or start syncing.\",\n\t\t],\n\t\t\"Save setup\",\n\t\t(saveSignal) =>\n\t\t\tsaveNewV3Settings(\n\t\t\t\t{\n\t\t\t\t\tsetupName: targetName,\n\t\t\t\t\tconnectionName: targetName,\n\t\t\t\t\tconnection: { type: \"git\", remote },\n\t\t\t\t\tsetup: {\n\t\t\t\t\t\tstorage: {\n\t\t\t\t\t\t\tconnection: targetName,\n\t\t\t\t\t\t\tbranch: destination.branch,\n\t\t\t\t\t\t\tpath: destination.directory,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsync: { include, automatic },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tsaveSignal,\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted)\n\t\tctx.ui.notify(\n\t\t\t`Saved Git sync setup \u201C${safeTerminalText(targetName)}\u201D. Choose Sync now to start.`,\n\t\t\t\"info\",\n\t\t);\n\treturn saved;\n}\n\nexport async function showAddGitStorageProfile(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n\tconst name = await promptResourceName(ctx, \"storage connection\", \"git\", signal);\n\tif (!name) return false;\n\tconst remote = await promptGitRemote(ctx, signal);\n\tif (!remote) return false;\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review storage connection\",\n\t\t[\n\t\t\t`Name: ${safeTerminalText(name)}`,\n\t\t\t\"Type: Git\",\n\t\t\t`Remote: ${safeTerminalText(remote)}`,\n\t\t\t\"Credentials: existing Git/SSH authentication (not stored)\",\n\t\t\t\"Adding a connection does not contact the remote or start syncing.\",\n\t\t],\n\t\t\"Add storage connection\",\n\t\t(saveSignal) => addStorageConnection(name, { type: \"git\", remote }, saveSignal),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted)\n\t\tctx.ui.notify(`Added storage connection \u201C${safeTerminalText(name)}\u201D.`, \"info\");\n\treturn saved;\n}\n\nexport async function showEditGitStorageProfile(\n\tctx: ExtensionCommandContext,\n\tname: string,\n\tprofile: Record<string, unknown>,\n\tsignal?: AbortSignal,\n\taffectedSetups?: string[],\n) {\n\tconst remote = await promptGitRemote(\n\t\tctx,\n\t\tsignal,\n\t\ttypeof profile.remote === \"string\" ? profile.remote : undefined,\n\t);\n\tif (!remote) return false;\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review storage connection\",\n\t\t[\n\t\t\t`Storage connection: ${safeTerminalText(name)}`,\n\t\t\t`Remote: ${safeTerminalText(String(profile.remote ?? \"missing\"))} \u2192 ${safeTerminalText(remote)}`,\n\t\t\t`Affected sync setups: ${affectedSetups?.length ? affectedSetups.map(safeTerminalText).join(\", \") : \"None\"}`,\n\t\t\t\"Saving changes future storage access for every affected setup; it does not move or delete remote history.\",\n\t\t],\n\t\t\"Save storage connection\",\n\t\t(saveSignal) =>\n\t\t\tupdateStorageConnection(\n\t\t\t\tname,\n\t\t\t\t(current) => {\n\t\t\t\t\tif (current.type !== \"git\" || current.remote !== profile.remote)\n\t\t\t\t\t\tthrow new Error(\"Storage connection changed while it was open; reopen it.\");\n\t\t\t\t\treturn { ...current, remote };\n\t\t\t\t},\n\t\t\t\taffectedSetups,\n\t\t\t\tsaveSignal,\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted)\n\t\tctx.ui.notify(`Saved storage connection \u201C${safeTerminalText(name)}\u201D.`, \"info\");\n\treturn saved;\n}\n\nexport async function showAddGitTarget(\n\tctx: ExtensionCommandContext,\n\tname: string,\n\tprofile: string,\n\tsignal?: AbortSignal,\n) {\n\tconst selected = await promptGitDestination(ctx, signal);\n\tif (!selected) return false;\n\tconst storage = await promptAvailableSetupStorage(\n\t\tctx,\n\t\t{ connection: profile, branch: selected.branch, path: selected.directory },\n\t\tsignal,\n\t);\n\tif (!storage) return false;\n\tconst include = await chooseSetupContent(ctx, signal);\n\tif (!include) return false;\n\tconst automatic = await chooseAutomaticSync(ctx, signal);\n\tif (automatic === undefined) return false;\n\tconst connection = await readSetupConnection(profile, signal);\n\tif (connection?.type !== \"git\") throw new Error(\"Storage connection changed; reopen setup.\");\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review Git sync setup\",\n\t\t[\n\t\t\t`Sync setup: ${safeTerminalText(name)}`,\n\t\t\t`Storage connection: ${safeTerminalText(profile)}`,\n\t\t\t`Remote: ${safeTerminalText(connection.remote)}`,\n\t\t\t`Sync branch: ${safeTerminalText(storage.branch)}`,\n\t\t\t`Storage location: ${safeTerminalText(storage.path)}`,\n\t\t\t...includedContentLines(include),\n\t\t\t`Automatic sync: ${automaticSyncSummary(automatic)}`,\n\t\t\t\"pi-sync manages the entire branch. Adding this setup does not sync or modify remote data.\",\n\t\t],\n\t\t\"Add sync setup\",\n\t\t(saveSignal) =>\n\t\t\taddSyncSetup(name, { storage, sync: { include, automatic } }, saveSignal, connection),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted)\n\t\tctx.ui.notify(`Added sync setup \u201C${safeTerminalText(name)}\u201D.`, \"info\");\n\treturn saved;\n}\n\nexport async function showEditGitTarget(\n\tctx: ExtensionCommandContext,\n\tpartial: PartialConfig,\n\tsignal?: AbortSignal,\n) {\n\tlet destination = await promptGitDestination(ctx, signal, partial);\n\tif (!destination) return false;\n\twhile (destination.directory !== partial.storagePath && destination.branch === partial.branch) {\n\t\tctx.ui.notify(\n\t\t\t\"Changing a Git storage path requires a new Git branch so the existing branch remains readable.\",\n\t\t\t\"warning\",\n\t\t);\n\t\tconst branch = await requiredValueInput(\n\t\t\tctx,\n\t\t\t\"New Git branch\\n\\nKeep the previous branch unchanged; enter a new branch for this path.\",\n\t\t\t\"pi-sync/archive\",\n\t\t\tsignal,\n\t\t\tnormalizeGitBranch,\n\t\t);\n\t\tif (!branch) return false;\n\t\tdestination = { ...destination, branch };\n\t}\n\tconst chosen = destination;\n\tconst connection = await readSetupConnection(partial.connectionName, signal);\n\tif (connection.type !== \"git\") throw new Error(\"Storage connection changed; reopen setup.\");\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review sync setup\",\n\t\t[\n\t\t\t`Sync setup: ${safeTerminalText(partial.setupName)}`,\n\t\t\t`Storage connection: ${safeTerminalText(partial.connectionName)}`,\n\t\t\t`Remote: ${safeTerminalText(connection.remote)}`,\n\t\t\t`Branch: ${safeTerminalText(partial.branch ?? \"missing\")} \u2192 ${safeTerminalText(chosen.branch)}`,\n\t\t\t`Storage path: ${safeTerminalText(partial.storagePath)} \u2192 ${safeTerminalText(chosen.directory)}`,\n\t\t\t\"Saving changes the future storage location only; it does not move or delete remote history.\",\n\t\t],\n\t\t\"Save sync setup\",\n\t\t(saveSignal) =>\n\t\t\tupdateSyncSetup(\n\t\t\t\tpartial.setupName,\n\t\t\t\t(setup) => {\n\t\t\t\t\tif (typeof setup.storage.branch !== \"string\")\n\t\t\t\t\t\tthrow new Error(\"Sync setup storage type changed; reopen it.\");\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...setup,\n\t\t\t\t\t\tstorage: { ...setup.storage, branch: chosen.branch, path: chosen.directory },\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\t{ expectedStorage: partial, expectedConnection: connection, signal: saveSignal },\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted)\n\t\tctx.ui.notify(`Saved sync setup \u201C${safeTerminalText(partial.setupName)}\u201D.`, \"info\");\n\treturn saved;\n}\n\nasync function promptGitRemote(\n\tctx: ExtensionCommandContext,\n\tsignal?: AbortSignal,\n\tcurrent?: string,\n) {\n\tconst title =\n\t\t\"Git remote URL (SSH or HTTPS)\\n\\nUse an existing private repository with Git/SSH authentication already configured.\";\n\tconst validate = (value: string) => {\n\t\tconst remote = normalizeGitRemote(value);\n\t\tif (!remote) throw new Error(\"Git remote URL is required.\");\n\t\treturn remote;\n\t};\n\treturn current\n\t\t? requiredInput(ctx, title, current, signal, validate)\n\t\t: requiredValueInput(\n\t\t\t\tctx,\n\t\t\t\ttitle,\n\t\t\t\t\"git@github.com:owner/private-pi-sync.git (SSH) or https://github.com/owner/private-pi-sync.git (HTTPS)\",\n\t\t\t\tsignal,\n\t\t\t\tvalidate,\n\t\t\t);\n}\n\nasync function promptGitDestination(\n\tctx: ExtensionCommandContext,\n\tsignal?: AbortSignal,\n\tcurrent: Partial<PartialConfig> = {},\n) {\n\tconst branch = await requiredInput(\n\t\tctx,\n\t\t\"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.\",\n\t\tcurrent.branch ?? \"main\",\n\t\tsignal,\n\t\tnormalizeGitBranch,\n\t);\n\tif (!branch) return undefined;\n\tconst directory = await requiredInput(\n\t\tctx,\n\t\t\"Git storage path\\n\\nRelative to the repository root, not your local filesystem.\\n./ stores manifest.json and files/ at the repository root.\",\n\t\tcurrent.storagePath ?? \"./\",\n\t\tsignal,\n\t\tnormalizeGitDirectory,\n\t);\n\treturn directory ? { branch, directory } : undefined;\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport {\n\tCURSOR_MARKER,\n\tdecodeKittyPrintable,\n\ttype Focusable,\n\tKey,\n\ttype KeybindingsManager,\n\tmatchesKey,\n\tText,\n\ttruncateToWidth,\n} from \"@earendil-works/pi-tui\";\nimport { formatInteractionHints, runCustomInteraction } from \"@narumitw/pi-tui-kit\";\n\nconst MASK = \"\u2022\";\n\nexport async function promptSecret(\n\tctx: ExtensionCommandContext,\n\ttitle: string,\n\toptions: { required?: boolean; signal?: AbortSignal } = { required: true },\n) {\n\tif (ctx.mode !== \"tui\" || options.signal?.aborted) return undefined;\n\tconst result = await runCustomInteraction<string | undefined>(ctx, {\n\t\tsignal: options.signal,\n\t\tisCurrent: () => !options.signal?.aborted,\n\t\tcreate: ({ tui, theme, keybindings, complete }) => {\n\t\t\tconst heading = new Text(\"\", 0, 0);\n\t\t\tconst hint = new Text(\"\", 0, 0);\n\t\t\tconst interactionHint = formatInteractionHints(keybindings, [\n\t\t\t\t{\n\t\t\t\t\tkeys: keybindings.getKeys(\"tui.input.submit\").filter((key) => !hasControlCharacter(key)),\n\t\t\t\t\tlabel: \"continue\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tkeys: [\n\t\t\t\t\t\t...keybindings.getKeys(\"tui.select.cancel\").filter((key) => !hasControlCharacter(key)),\n\t\t\t\t\t\t\"ctrl+c\",\n\t\t\t\t\t],\n\t\t\t\t\tlabel: \"cancel\",\n\t\t\t\t},\n\t\t\t]);\n\t\t\tconst applyTheme = () => {\n\t\t\t\theading.setText(theme.fg(\"accent\", theme.bold(title)));\n\t\t\t\thint.setText(theme.fg(\"dim\", `${interactionHint} \u2022 Input is hidden`));\n\t\t\t};\n\t\t\tapplyTheme();\n\t\t\tconst input = new MaskedInput(keybindings);\n\t\t\tconst component: Focusable & {\n\t\t\t\trender(width: number): string[];\n\t\t\t\tinvalidate(): void;\n\t\t\t\thandleInput(data: string): void;\n\t\t\t\tdispose(): void;\n\t\t\t} = {\n\t\t\t\tget focused() {\n\t\t\t\t\treturn input.focused;\n\t\t\t\t},\n\t\t\t\tset focused(focused: boolean) {\n\t\t\t\t\tinput.focused = focused;\n\t\t\t\t},\n\t\t\t\trender(width: number) {\n\t\t\t\t\tconst safeWidth = Math.max(1, width);\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...heading.render(safeWidth),\n\t\t\t\t\t\t...input.render(safeWidth),\n\t\t\t\t\t\t...hint.render(safeWidth),\n\t\t\t\t\t].map((line) => truncateToWidth(line, safeWidth));\n\t\t\t\t},\n\t\t\t\tinvalidate() {\n\t\t\t\t\tapplyTheme();\n\t\t\t\t\theading.invalidate();\n\t\t\t\t\tinput.invalidate();\n\t\t\t\t\thint.invalidate();\n\t\t\t\t},\n\t\t\t\thandleInput(data: string) {\n\t\t\t\t\tif (matchesKey(data, Key.ctrl(\"c\"))) {\n\t\t\t\t\t\tcomplete(undefined);\n\t\t\t\t\t} else if (input.isPasting || data.includes(\"\\u001b[200~\")) {\n\t\t\t\t\t\tinput.handleInput(data);\n\t\t\t\t\t} else if (keybindings.matches(data, \"tui.select.cancel\")) {\n\t\t\t\t\t\tcomplete(undefined);\n\t\t\t\t\t} else if (keybindings.matches(data, \"tui.input.submit\")) {\n\t\t\t\t\t\tif (options.required !== false && input.getValue().length === 0) {\n\t\t\t\t\t\t\tctx.ui.notify(`${title} is required. Enter a value, or cancel.`, \"warning\");\n\t\t\t\t\t\t} else if (hasControlCharacter(input.getValue())) {\n\t\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t\t`${title} contains control characters. Remove them or re-enter the value, then continue.`,\n\t\t\t\t\t\t\t\t\"warning\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else complete(input.getValue());\n\t\t\t\t\t} else input.handleInput(data);\n\t\t\t\t\ttui.requestRender();\n\t\t\t\t},\n\t\t\t\tdispose() {\n\t\t\t\t\tinput.clear();\n\t\t\t\t},\n\t\t\t};\n\t\t\treturn component;\n\t\t},\n\t});\n\tif (result.kind === \"error\") throw result.error;\n\tif (result.kind !== \"completed\" || result.value === undefined) return undefined;\n\tconst value = result.value;\n\tif (options.required !== false && value.length === 0) {\n\t\tctx.ui.notify(`${title} is required.`, \"warning\");\n\t\treturn undefined;\n\t}\n\treturn value;\n}\n\nclass MaskedInput implements Focusable {\n\tfocused = false;\n\tprivate value: string[] = [];\n\tprivate cursor = 0;\n\tprivate paste = \"\";\n\tprivate pasting = false;\n\n\tconstructor(private readonly keybindings: KeybindingsManager) {}\n\n\tget isPasting() {\n\t\treturn this.pasting;\n\t}\n\n\tgetValue() {\n\t\treturn this.value.join(\"\");\n\t}\n\n\thandleInput(data: string) {\n\t\tif (data.includes(\"\\u001b[200~\")) {\n\t\t\tthis.pasting = true;\n\t\t\tthis.paste = \"\";\n\t\t\tdata = data.replace(\"\\u001b[200~\", \"\");\n\t\t}\n\t\tif (this.pasting) {\n\t\t\tthis.paste += data;\n\t\t\tconst end = this.paste.indexOf(\"\\u001b[201~\");\n\t\t\tif (end < 0) return;\n\t\t\tconst pasted = this.paste\n\t\t\t\t.slice(0, end)\n\t\t\t\t.replace(/[\\r\\n]/gu, \"\")\n\t\t\t\t.replace(/\\t/gu, \" \");\n\t\t\tthis.insert(pasted);\n\t\t\tconst remaining = this.paste.slice(end + 6);\n\t\t\tthis.paste = \"\";\n\t\t\tthis.pasting = false;\n\t\t\tif (remaining) this.handleInput(remaining);\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.editor.deleteCharBackward\")) {\n\t\t\tif (this.cursor > 0) this.value.splice(--this.cursor, 1);\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.editor.deleteCharForward\")) {\n\t\t\tif (this.cursor < this.value.length) this.value.splice(this.cursor, 1);\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.editor.cursorLeft\")) {\n\t\t\tthis.cursor = Math.max(0, this.cursor - 1);\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.editor.cursorRight\")) {\n\t\t\tthis.cursor = Math.min(this.value.length, this.cursor + 1);\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.editor.cursorLineStart\")) {\n\t\t\tthis.cursor = 0;\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.editor.cursorLineEnd\")) {\n\t\t\tthis.cursor = this.value.length;\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.editor.deleteToLineStart\")) {\n\t\t\tthis.value.splice(0, this.cursor);\n\t\t\tthis.cursor = 0;\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.editor.deleteToLineEnd\")) {\n\t\t\tthis.value.splice(this.cursor);\n\t\t\treturn;\n\t\t}\n\t\tconst printable = decodeKittyPrintable(data) ?? data;\n\t\tif (!hasControlCharacter(printable)) this.insert(printable);\n\t}\n\n\trender(width: number) {\n\t\tconst prompt = \"> \";\n\t\tconst available = width - prompt.length;\n\t\tif (available <= 0) return [truncateToWidth(prompt, Math.max(1, width))];\n\t\tconst contentWidth = Math.max(0, available - 1);\n\t\tlet start = 0;\n\t\tif (this.value.length > contentWidth) {\n\t\t\tstart = Math.max(\n\t\t\t\t0,\n\t\t\t\tMath.min(this.cursor - Math.floor(contentWidth / 2), this.value.length - contentWidth),\n\t\t\t);\n\t\t}\n\t\tconst end = Math.min(this.value.length, start + contentWidth);\n\t\tconst visibleCursor = Math.max(0, Math.min(this.cursor - start, end - start));\n\t\tconst masks = Array.from({ length: end - start }, () => MASK);\n\t\tconst before = masks.slice(0, visibleCursor).join(\"\");\n\t\tconst atCursor = visibleCursor < masks.length ? MASK : \" \";\n\t\tconst after = masks.slice(visibleCursor + (visibleCursor < masks.length ? 1 : 0)).join(\"\");\n\t\tconst marker = this.focused ? CURSOR_MARKER : \"\";\n\t\tconst line = `${prompt}${before}${marker}\\u001b[7m${atCursor}\\u001b[27m${after}`;\n\t\treturn [truncateToWidth(line, width, \"\")];\n\t}\n\n\tinvalidate() {}\n\n\tclear() {\n\t\tthis.value.fill(\"\");\n\t\tthis.value = [];\n\t\tthis.paste = \"\";\n\t\tthis.cursor = 0;\n\t\tthis.pasting = false;\n\t}\n\n\tprivate insert(value: string) {\n\t\tconst characters = Array.from(value);\n\t\tthis.value.splice(this.cursor, 0, ...characters);\n\t\tthis.cursor += characters.length;\n\t}\n}\n\nfunction hasControlCharacter(value: string) {\n\treturn [...value].some((character) => {\n\t\tconst code = character.codePointAt(0) ?? 0;\n\t\treturn code < 0x20 || (code >= 0x7f && code <= 0x9f);\n\t});\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { promptSecret } from \"../secret-input.js\";\nimport { requiredValueInput } from \"./text-input.js\";\n\nexport interface ChosenS3Credentials {\n\tprofileFields: { accessKeyId?: string; secretAccessKey?: string };\n\tsummary: string;\n\tready: boolean;\n\treplace?: boolean;\n}\n\nexport async function chooseS3CredentialUpdate(\n\tctx: ExtensionCommandContext,\n\tprofile: Record<string, unknown>,\n\tsignal?: AbortSignal,\n) {\n\tconst hasStored =\n\t\ttypeof profile.accessKeyId === \"string\" &&\n\t\tprofile.accessKeyId.length > 0 &&\n\t\ttypeof profile.secretAccessKey === \"string\" &&\n\t\tprofile.secretAccessKey.length > 0;\n\tif (hasStored) {\n\t\tconst action = await ctx.ui.select(\n\t\t\t\"Credentials\",\n\t\t\t[\"Keep current credentials\", \"Replace credentials\", \"Cancel\"],\n\t\t\t{ signal },\n\t\t);\n\t\tthrowIfAborted(signal);\n\t\tif (!action || action === \"Cancel\") return undefined;\n\t\tif (action === \"Keep current credentials\") {\n\t\t\treturn { profileFields: {}, summary: \"Unchanged (values hidden)\", ready: true };\n\t\t}\n\t}\n\tconst selected = await chooseS3Credentials(ctx, signal);\n\treturn selected ? { ...selected, replace: true } : undefined;\n}\n\nexport function applyS3CredentialUpdate(\n\tprofile: Record<string, unknown>,\n\tcredentials: ChosenS3Credentials,\n) {\n\tconst next = { ...profile };\n\tif (credentials.replace) {\n\t\tdelete next.accessKeyId;\n\t\tdelete next.secretAccessKey;\n\t\tdelete next.sessionToken;\n\t}\n\treturn { ...next, ...credentials.profileFields };\n}\n\nexport async function chooseS3Credentials(\n\tctx: ExtensionCommandContext,\n\tsignal?: AbortSignal,\n): Promise<ChosenS3Credentials | undefined> {\n\tconst choice = await ctx.ui.select(\n\t\t\"Credentials\\n\\nCredentials are stored in the private pi-sync settings file. Secret values are masked during input and never shown afterward.\",\n\t\t[\"Store credentials privately\", \"Cancel\"],\n\t\t{ signal },\n\t);\n\tthrowIfAborted(signal);\n\tif (choice !== \"Store credentials privately\") return undefined;\n\tconst accessKeyId = await requiredValueInput(\n\t\tctx,\n\t\t\"Access key ID\\n\\nUse the S3 API access key ID issued by your provider, not the secret access key.\",\n\t\t\"access-key-id\",\n\t\tsignal,\n\t);\n\tif (!accessKeyId) return undefined;\n\tconst secretAccessKey = await promptSecret(ctx, \"Secret access key\", { signal });\n\tthrowIfAborted(signal);\n\tif (secretAccessKey === undefined) return undefined;\n\treturn {\n\t\tprofileFields: { accessKeyId, secretAccessKey },\n\t\tsummary: \"Stored privately (values hidden)\",\n\t\tready: true,\n\t};\n}\n\nfunction throwIfAborted(signal?: AbortSignal) {\n\tif (!signal?.aborted) return;\n\tthrow signal.reason instanceof Error\n\t\t? signal.reason\n\t\t: new DOMException(\"The operation was aborted\", \"AbortError\");\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { refreshTargetCompletions } from \"../../commands/setup-completions.js\";\nimport {\n\taddSyncSetup,\n\tsaveNewV3Settings,\n\tupdateSyncSetup,\n} from \"../../settings/settings-management.js\";\nimport type { PartialConfig } from \"../../settings/settings-types.js\";\nimport {\n\tnormalizeS3Bucket,\n\tnormalizeS3Endpoint,\n\tnormalizeStoragePath,\n} from \"../../settings/settings-validation.js\";\nimport { automaticSyncSummary } from \"../automatic-sync-summary.js\";\nimport { safeTerminalText } from \"../terminal-text.js\";\nimport { chooseS3Credentials } from \"./s3-credentials-ui.js\";\nimport {\n\tchooseAdditionalRemoteLocation,\n\tchooseInitialRemoteLocation,\n\tpromptAvailableSetupStorage,\n} from \"./setup-location-ui.js\";\nimport {\n\tchooseAutomaticSync,\n\tchooseSessions,\n\tchooseSetupContent,\n\tincludedContentLines,\n\treadSetupConnection,\n} from \"./setup-prompts.js\";\nimport { saveReviewedDraft } from \"./setup-review.js\";\nimport { requiredInput, requiredValueInput } from \"./text-input.js\";\n\nexport async function showS3Setup(\n\tctx: ExtensionCommandContext,\n\tpreset: string,\n\ttargetName: string,\n\tsignal?: AbortSignal,\n) {\n\tconst endpoint = await requiredValueInput(\n\t\tctx,\n\t\tpreset === \"Cloudflare R2\"\n\t\t\t? \"Cloudflare R2 endpoint\\n\\nCopy the S3 API endpoint from your R2 account; replace <account-id>.\"\n\t\t\t: \"S3-compatible endpoint\\n\\nUse your provider's S3 API URL, not its web console.\",\n\t\tpreset === \"Cloudflare R2\"\n\t\t\t? \"https://<account-id>.r2.cloudflarestorage.com\"\n\t\t\t: \"https://s3.example.com\",\n\t\tsignal,\n\t\tnormalizeS3Endpoint,\n\t);\n\tif (!endpoint) return false;\n\tconst region =\n\t\tpreset === \"Cloudflare R2\"\n\t\t\t? \"auto\"\n\t\t\t: await requiredInput(\n\t\t\t\t\tctx,\n\t\t\t\t\t\"Storage region\\n\\nUse the region assigned to your bucket by the provider.\",\n\t\t\t\t\t\"us-east-1\",\n\t\t\t\t\tsignal,\n\t\t\t\t);\n\tif (!region) return false;\n\tconst location = await chooseInitialRemoteLocation(ctx, preset, targetName, signal);\n\tif (!location) return false;\n\tconst credentials = await chooseS3Credentials(ctx, signal);\n\tif (!credentials) return false;\n\tconst include = await chooseSetupContent(ctx, signal);\n\tif (!include) return false;\n\tconst automatic = await chooseAutomaticSync(ctx, signal);\n\tif (automatic === undefined) return false;\n\tconst sessions = await chooseSessions(ctx, signal);\n\tif (sessions === undefined) return false;\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review sync setup\",\n\t\t[\n\t\t\t`Sync setup: ${safeTerminalText(targetName)}`,\n\t\t\t`Storage connection: ${safeTerminalText(location.connectionName)} (${preset})`,\n\t\t\t`Endpoint: ${safeTerminalText(endpoint)}`,\n\t\t\t`Region: ${safeTerminalText(region)}`,\n\t\t\t`Bucket: ${safeTerminalText(location.bucket)}`,\n\t\t\t`Storage location: ${safeTerminalText(location.path)}`,\n\t\t\t...includedContentLines(include, sessions),\n\t\t\t`Automatic sync: ${automaticSyncSummary(automatic)}`,\n\t\t\t`Credentials: ${credentials.summary}`,\n\t\t\t\"The bucket must already exist. Saving does not contact remote storage or start syncing.\",\n\t\t],\n\t\t\"Save sync setup\",\n\t\t(saveSignal) =>\n\t\t\tsaveNewV3Settings(\n\t\t\t\t{\n\t\t\t\t\tsetupName: targetName,\n\t\t\t\t\tconnectionName: location.connectionName,\n\t\t\t\t\tconnection: {\n\t\t\t\t\t\ttype: \"s3\",\n\t\t\t\t\t\tendpoint,\n\t\t\t\t\t\tregion,\n\t\t\t\t\t\tcredentials: {\n\t\t\t\t\t\t\taccessKeyId: credentials.profileFields.accessKeyId ?? \"\",\n\t\t\t\t\t\t\tsecretAccessKey: credentials.profileFields.secretAccessKey ?? \"\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tsetup: {\n\t\t\t\t\t\tstorage: {\n\t\t\t\t\t\t\tconnection: location.connectionName,\n\t\t\t\t\t\t\tbucket: location.bucket,\n\t\t\t\t\t\t\tpath: location.path,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsync: { include: [...include, ...(sessions ? [\"sessions\"] : [])], automatic },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tsaveSignal,\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (!saved || signal?.aborted) return false;\n\tawait refreshTargetCompletions();\n\tif (!signal?.aborted)\n\t\tctx.ui.notify(\n\t\t\t`Sync setup \u201C${safeTerminalText(targetName)}\u201D saved. Choose Sync now to start.`,\n\t\t\t\"info\",\n\t\t);\n\treturn true;\n}\n\nexport async function showAddS3Target(\n\tctx: ExtensionCommandContext,\n\traw: Record<string, unknown>,\n\tprofile: string,\n\tname: string,\n\tsignal?: AbortSignal,\n) {\n\tconst location = await chooseAdditionalRemoteLocation(ctx, raw, profile, name, signal);\n\tif (!location) return;\n\tconst storage = await promptAvailableSetupStorage(\n\t\tctx,\n\t\t{ connection: profile, ...location },\n\t\tsignal,\n\t);\n\tif (!storage) return;\n\tconst include = await chooseSetupContent(ctx, signal);\n\tif (!include) return;\n\tconst automatic = await chooseAutomaticSync(ctx, signal);\n\tif (automatic === undefined) return;\n\tconst connection = await readSetupConnection(profile, signal);\n\tif (connection.type !== \"s3\") throw new Error(\"Storage connection changed; reopen setup.\");\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review new sync setup\",\n\t\t[\n\t\t\t`Sync setup: ${safeTerminalText(name)}`,\n\t\t\t`Storage connection: ${safeTerminalText(profile)}`,\n\t\t\t`Endpoint: ${safeTerminalText(connection.endpoint)}`,\n\t\t\t`Bucket: ${safeTerminalText(storage.bucket)}`,\n\t\t\t`Storage location: ${safeTerminalText(storage.path)}`,\n\t\t\t...includedContentLines(include),\n\t\t\t`Automatic sync: ${automaticSyncSummary(automatic)}`,\n\t\t\t\"Only the current setup is checked at startup. Shutdown can push selected content when sessions are included.\",\n\t\t\t\"The bucket must already exist. Adding this setup does not sync or modify remote data.\",\n\t\t],\n\t\t\"Add sync setup\",\n\t\t(saveSignal) =>\n\t\t\taddSyncSetup(name, { storage, sync: { include, automatic } }, saveSignal, connection),\n\t\tsignal,\n\t);\n\tif (!saved || signal?.aborted) return;\n\tawait refreshTargetCompletions();\n\tif (!signal?.aborted) ctx.ui.notify(`Added sync setup \u201C${safeTerminalText(name)}\u201D.`, \"info\");\n}\n\nexport async function showEditS3Target(\n\tctx: ExtensionCommandContext,\n\tpartial: PartialConfig,\n\tsignal?: AbortSignal,\n) {\n\tconst bucket = await requiredInput(\n\t\tctx,\n\t\t\"Bucket\\n\\nUse an existing bucket; pi-sync will not create it.\",\n\t\tpartial.bucket ?? \"pi-sync\",\n\t\tsignal,\n\t\tnormalizeS3Bucket,\n\t);\n\tif (!bucket) return;\n\tconst storagePath = await requiredInput(\n\t\tctx,\n\t\t\"Storage path\\n\\nPath inside the bucket, not your local filesystem. ./ uses the bucket root.\",\n\t\tpartial.storagePath,\n\t\tsignal,\n\t\tnormalizeStoragePath,\n\t);\n\tif (!storagePath) return;\n\tconst connection = await readSetupConnection(partial.connectionName, signal);\n\tif (connection.type !== \"s3\") throw new Error(\"Storage connection changed; reopen setup.\");\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review sync setup\",\n\t\t[\n\t\t\t`Sync setup: ${safeTerminalText(partial.setupName)}`,\n\t\t\t`Storage connection: ${safeTerminalText(partial.connectionName)}`,\n\t\t\t`Endpoint: ${safeTerminalText(connection.endpoint)}`,\n\t\t\t`Bucket: ${safeTerminalText(partial.bucket ?? \"missing\")} \u2192 ${safeTerminalText(bucket)}`,\n\t\t\t`Storage path: ${safeTerminalText(partial.storagePath)} \u2192 ${safeTerminalText(storagePath)}`,\n\t\t\t\"Saving changes the future storage location only; it does not move or delete remote data.\",\n\t\t],\n\t\t\"Save sync setup\",\n\t\t(saveSignal) =>\n\t\t\tupdateSyncSetup(\n\t\t\t\tpartial.setupName,\n\t\t\t\t(setup) => {\n\t\t\t\t\tif (typeof setup.storage.bucket !== \"string\")\n\t\t\t\t\t\tthrow new Error(\"Sync setup storage type changed; reopen it.\");\n\t\t\t\t\treturn { ...setup, storage: { ...setup.storage, bucket, path: storagePath } };\n\t\t\t\t},\n\t\t\t\t{ expectedStorage: partial, expectedConnection: connection, signal: saveSignal },\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted)\n\t\tctx.ui.notify(`Saved sync setup \u201C${safeTerminalText(partial.setupName)}\u201D.`, \"info\");\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport {\n\tnormalizeWebDavPath,\n\tnormalizeWebDavUrl,\n\tvalidateWebDavCredentials,\n} from \"../../backends/webdav/webdav-config.js\";\nimport {\n\taddStorageConnection,\n\taddSyncSetup,\n\tsaveNewV3Settings,\n\tupdateStorageConnection,\n\tupdateSyncSetup,\n} from \"../../settings/settings-management.js\";\nimport type { PartialConfig } from \"../../settings/settings-types.js\";\nimport { automaticSyncSummary } from \"../automatic-sync-summary.js\";\nimport { promptSecret } from \"../secret-input.js\";\nimport { safeTerminalText as safe } from \"../terminal-text.js\";\nimport { promptAvailableSetupStorage } from \"./setup-location-ui.js\";\nimport {\n\tchooseAutomaticSync,\n\tchooseSessions,\n\tchooseSetupContent,\n\tincludedContentLines,\n\tpromptResourceName,\n\treadSetupConnection,\n} from \"./setup-prompts.js\";\nimport { saveReviewedDraft } from \"./setup-review.js\";\nimport { promptTextInput } from \"./text-input.js\";\n\nexport async function showWebDavSetup(\n\tctx: ExtensionCommandContext,\n\ttargetName: string,\n\tsignal?: AbortSignal,\n) {\n\tconst url = await promptWebDavUrl(ctx, signal);\n\tif (!url) return false;\n\tconst username = await promptUsername(ctx, signal);\n\tif (!username) return false;\n\tconst password = await promptSecret(ctx, \"WebDAV password\", { signal });\n\tsignal?.throwIfAborted();\n\tif (password === undefined) return false;\n\tconst remotePath = await chooseDestination(ctx, signal);\n\tif (!remotePath) return false;\n\tconst include = await chooseSetupContent(ctx, signal);\n\tif (!include) return false;\n\tconst automatic = await chooseAutomaticSync(ctx, signal);\n\tif (automatic === undefined) return false;\n\tconst sessions = await chooseSessions(ctx, signal);\n\tif (sessions === undefined) return false;\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review WebDAV setup\",\n\t\t[\n\t\t\t`Sync setup: ${safe(targetName)}`,\n\t\t\t`Storage connection: ${safe(targetName)} (WebDAV)`,\n\t\t\t`URL: ${safe(url)}`,\n\t\t\t`Storage location: ${safe(remotePath)}`,\n\t\t\t\"Username and password: stored privately (values hidden)\",\n\t\t\t...includedContentLines(include, sessions),\n\t\t\t`Automatic sync: ${automaticSyncSummary(automatic)}`,\n\t\t\t\"Check setup tests whether this server can safely save sync updates using a temporary probe.\",\n\t\t\t\"Saving does not contact remote storage or start syncing.\",\n\t\t],\n\t\t\"Save setup\",\n\t\t(saveSignal) =>\n\t\t\tsaveNewV3Settings(\n\t\t\t\t{\n\t\t\t\t\tsetupName: targetName,\n\t\t\t\t\tconnectionName: targetName,\n\t\t\t\t\tconnection: { type: \"webdav\", url, credentials: { username, password } },\n\t\t\t\t\tsetup: {\n\t\t\t\t\t\tstorage: { connection: targetName, path: remotePath },\n\t\t\t\t\t\tsync: { include: [...include, ...(sessions ? [\"sessions\"] : [])], automatic },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tsaveSignal,\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted)\n\t\tctx.ui.notify(`Sync setup \u201C${safe(targetName)}\u201D saved. Choose Sync now to start.`, \"info\");\n\treturn saved;\n}\n\nexport async function showAddWebDavTarget(\n\tctx: ExtensionCommandContext,\n\tname: string,\n\tprofile: string,\n\tsignal?: AbortSignal,\n) {\n\tconst remotePath = await chooseDestination(ctx, signal);\n\tif (!remotePath) return false;\n\tconst storage = await promptAvailableSetupStorage(\n\t\tctx,\n\t\t{ connection: profile, path: remotePath },\n\t\tsignal,\n\t);\n\tif (!storage) return false;\n\tconst include = await chooseSetupContent(ctx, signal);\n\tif (!include) return false;\n\tconst automatic = await chooseAutomaticSync(ctx, signal);\n\tif (automatic === undefined) return false;\n\tconst connection = await readSetupConnection(profile, signal);\n\tif (connection.type !== \"webdav\") throw new Error(\"Storage connection changed; reopen setup.\");\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review WebDAV sync setup\",\n\t\t[\n\t\t\t`Sync setup: ${safe(name)}`,\n\t\t\t`Storage connection: ${safe(profile)}`,\n\t\t\t`URL: ${safe(connection.url)}`,\n\t\t\t`Storage location: ${safe(storage.path)}`,\n\t\t\t...includedContentLines(include),\n\t\t\t`Automatic sync: ${automaticSyncSummary(automatic)}`,\n\t\t\t\"Adding this setup does not sync or modify remote data.\",\n\t\t],\n\t\t\"Add sync setup\",\n\t\t(saveSignal) =>\n\t\t\taddSyncSetup(name, { storage, sync: { include, automatic } }, saveSignal, connection),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted) ctx.ui.notify(`Added sync setup \u201C${safe(name)}\u201D.`, \"info\");\n\treturn saved;\n}\n\nexport async function showEditWebDavTarget(\n\tctx: ExtensionCommandContext,\n\tpartial: PartialConfig,\n\tsignal?: AbortSignal,\n) {\n\tconst remotePath = await chooseDestination(ctx, signal, partial.storagePath);\n\tif (!remotePath) return false;\n\tconst connection = await readSetupConnection(partial.connectionName, signal);\n\tif (connection.type !== \"webdav\") throw new Error(\"Storage connection changed; reopen setup.\");\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review sync setup\",\n\t\t[\n\t\t\t`Sync setup: ${safe(partial.setupName)}`,\n\t\t\t`Storage connection: ${safe(partial.connectionName)}`,\n\t\t\t`URL: ${safe(connection.url)}`,\n\t\t\t`Storage path: ${safe(partial.storagePath)} \u2192 ${safe(remotePath)}`,\n\t\t\t\"Saving changes the future storage location only; it does not move or delete remote data.\",\n\t\t],\n\t\t\"Save sync setup\",\n\t\t(saveSignal) =>\n\t\t\tupdateSyncSetup(\n\t\t\t\tpartial.setupName,\n\t\t\t\t(setup) => ({\n\t\t\t\t\t...setup,\n\t\t\t\t\tstorage: { ...setup.storage, path: remotePath },\n\t\t\t\t}),\n\t\t\t\t{ expectedStorage: partial, expectedConnection: connection, signal: saveSignal },\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted)\n\t\tctx.ui.notify(`Saved sync setup \u201C${safe(partial.setupName)}\u201D.`, \"info\");\n\treturn saved;\n}\n\nexport async function showAddWebDavStorageProfile(\n\tctx: ExtensionCommandContext,\n\tsignal?: AbortSignal,\n) {\n\tconst name = await promptResourceName(ctx, \"storage connection\", \"webdav\", signal, true);\n\tif (!name) return false;\n\tconst url = await promptWebDavUrl(ctx, signal);\n\tif (!url) return false;\n\tconst username = await promptUsername(ctx, signal);\n\tif (!username) return false;\n\tconst password = await promptSecret(ctx, \"WebDAV password\", { signal });\n\tsignal?.throwIfAborted();\n\tif (password === undefined) return false;\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review storage connection\",\n\t\t[\n\t\t\t`Name: ${safe(name)}`,\n\t\t\t\"Type: WebDAV\",\n\t\t\t`URL: ${safe(url)}`,\n\t\t\t\"Username and password: stored privately (values hidden)\",\n\t\t\t\"Adding a connection does not contact the server or start syncing.\",\n\t\t],\n\t\t\"Add storage connection\",\n\t\t(saveSignal) =>\n\t\t\taddStorageConnection(\n\t\t\t\tname,\n\t\t\t\t{ type: \"webdav\", url, credentials: { username, password } },\n\t\t\t\tsaveSignal,\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted) ctx.ui.notify(`Added storage connection \u201C${safe(name)}\u201D.`, \"info\");\n\treturn saved;\n}\n\nexport async function showEditWebDavStorageProfile(\n\tctx: ExtensionCommandContext,\n\tname: string,\n\tprofile: Record<string, unknown>,\n\tsignal?: AbortSignal,\n\taffectedSetups?: string[],\n) {\n\tconst url = await promptWebDavUrl(\n\t\tctx,\n\t\tsignal,\n\t\ttypeof profile.url === \"string\" ? profile.url : undefined,\n\t);\n\tif (!url) return false;\n\tconst username = await promptUsername(ctx, signal);\n\tif (!username) return false;\n\tconst hasPassword = typeof profile.password === \"string\" && profile.password.length > 0;\n\tconst passwordAction = hasPassword\n\t\t? await select(\n\t\t\t\tctx,\n\t\t\t\t\"WebDAV password\",\n\t\t\t\t[\"Keep current password\", \"Replace password\", \"Cancel\"],\n\t\t\t\tsignal,\n\t\t\t)\n\t\t: \"Replace password\";\n\tif (!passwordAction || passwordAction === \"Cancel\") return false;\n\tconst replacePassword = passwordAction === \"Replace password\";\n\tconst password = replacePassword\n\t\t? await promptSecret(ctx, \"New WebDAV password\", { signal })\n\t\t: undefined;\n\tsignal?.throwIfAborted();\n\tif (replacePassword && password === undefined) return false;\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review storage connection\",\n\t\t[\n\t\t\t`Storage connection: ${safe(name)}`,\n\t\t\t`URL: ${safe(String(profile.url))} \u2192 ${safe(url)}`,\n\t\t\t\"Username: stored privately (value hidden)\",\n\t\t\t`Password: ${replacePassword ? \"will be replaced\" : \"unchanged\"} (value hidden)`,\n\t\t\t`Affected sync setups: ${affectedSetups?.length ? affectedSetups.map(safe).join(\", \") : \"None\"}`,\n\t\t\t\"Saving changes future storage access for every affected setup; it does not move remote data.\",\n\t\t],\n\t\t\"Save storage connection\",\n\t\t(saveSignal) =>\n\t\t\tupdateStorageConnection(\n\t\t\t\tname,\n\t\t\t\t(current) => {\n\t\t\t\t\tif (\n\t\t\t\t\t\tcurrent.type !== \"webdav\" ||\n\t\t\t\t\t\tcurrent.url !== profile.url ||\n\t\t\t\t\t\tcurrent.credentials.username !== profile.username ||\n\t\t\t\t\t\tcurrent.credentials.password !== profile.password\n\t\t\t\t\t)\n\t\t\t\t\t\tthrow new Error(\"Storage connection changed while it was open; reopen it.\");\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...current,\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tcredentials: {\n\t\t\t\t\t\t\t...current.credentials,\n\t\t\t\t\t\t\tusername,\n\t\t\t\t\t\t\tpassword: password ?? current.credentials.password,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\taffectedSetups,\n\t\t\t\tsaveSignal,\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted) ctx.ui.notify(`Saved storage connection \u201C${safe(name)}\u201D.`, \"info\");\n\treturn saved;\n}\n\nasync function chooseDestination(\n\tctx: ExtensionCommandContext,\n\tsignal?: AbortSignal,\n\tcurrent = \"./\",\n) {\n\treturn promptTextInput(\n\t\tctx,\n\t\t\"WebDAV storage path\\n\\nFolder relative to the collection URL, not your local filesystem.\\n./ uses the collection root. Use different folders for independent setups.\",\n\t\t{ defaultValue: current, validate: normalizeWebDavPath },\n\t\tsignal,\n\t);\n}\n\nasync function promptUsername(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n\treturn promptTextInput(\n\t\tctx,\n\t\t\"WebDAV username\\n\\nEnter the account username; stored values remain hidden.\",\n\t\t{\n\t\t\texample: \"user\",\n\t\t\tvalidate: (value) => {\n\t\t\t\tvalidateWebDavCredentials(value);\n\t\t\t\treturn value;\n\t\t\t},\n\t\t},\n\t\tsignal,\n\t);\n}\n\nasync function promptWebDavUrl(\n\tctx: ExtensionCommandContext,\n\tsignal?: AbortSignal,\n\tcurrent?: string,\n) {\n\treturn promptTextInput(\n\t\tctx,\n\t\t\"WebDAV collection URL\\n\\nUse the HTTPS WebDAV URL from your provider, not its web login page.\",\n\t\t{\n\t\t\t...(current\n\t\t\t\t? { defaultValue: current }\n\t\t\t\t: { example: \"https://cloud.example.com/remote.php/dav/files/user\" }),\n\t\t\tvalidate: (value) => {\n\t\t\t\tconst url = normalizeWebDavUrl(value);\n\t\t\t\tif (!url) throw new Error(\"WebDAV URL is required.\");\n\t\t\t\treturn url;\n\t\t\t},\n\t\t},\n\t\tsignal,\n\t);\n}\n\nasync function select(\n\tctx: ExtensionCommandContext,\n\ttitle: string,\n\toptions: string[],\n\tsignal?: AbortSignal,\n) {\n\tconst value = await ctx.ui.select(title, options, { signal });\n\tsignal?.throwIfAborted();\n\treturn value;\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -31,11 +31,9 @@ import {
31
31
  import { defineMenu, runMenu } from "@narumitw/pi-tui-kit";
32
32
 
33
33
  // src/ui/cancellable-operation.ts
34
- import {
35
- BorderedLoader
36
- } from "@earendil-works/pi-coding-agent";
34
+ import { BorderedLoader } from "@earendil-works/pi-coding-agent";
37
35
  import { Key, matchesKey, truncateToWidth } from "@earendil-works/pi-tui";
38
- import { runCustomInteraction } from "@narumitw/pi-tui-kit";
36
+ import { formatInteractionHints, runCustomInteraction } from "@narumitw/pi-tui-kit";
39
37
  async function runCancellableOperation(ctx, message, route, runRoute, options = {}) {
40
38
  const {
41
39
  commitAware = false,
@@ -53,7 +51,15 @@ async function runCancellableOperation(ctx, message, route, runRoute, options =
53
51
  isCurrent: () => !signal?.aborted,
54
52
  create: ({ tui, theme, keybindings, signal: interactionSignal, complete }) => {
55
53
  const loader = new BorderedLoader(tui, theme, message, { cancellable: false });
56
- const cancelHint = `${keybindingText(keybindings, "tui.select.cancel", "esc")} cancel`;
54
+ const cancelHint = formatInteractionHints(keybindings, [
55
+ {
56
+ keys: [
57
+ ...keybindings.getKeys("tui.select.cancel").filter((key) => !hasControlCharacter(key)),
58
+ "ctrl+c"
59
+ ],
60
+ label: "cancel"
61
+ }
62
+ ]);
57
63
  const operation = runRoute(
58
64
  route,
59
65
  interactionSignal,
@@ -105,13 +111,8 @@ async function runCancellableOperation(ctx, message, route, runRoute, options =
105
111
  if (interaction.value.error) throw interaction.value.error;
106
112
  return routeResult ?? { kind: "failed" };
107
113
  }
108
- function keybindingText(keybindings, binding, fallback) {
109
- const keys = [.../* @__PURE__ */ new Set([...keybindings.getKeys(binding), "ctrl+c"])].map(String).map((key) => {
110
- if (key === "return") return "enter";
111
- if (key === "escape") return "esc";
112
- return safeTerminalText(key);
113
- }).filter(Boolean);
114
- return keys.join("/") || fallback;
114
+ function hasControlCharacter(value) {
115
+ return /[\u0000-\u001f\u007f-\u009f]/u.test(value);
115
116
  }
116
117
 
117
118
  // src/ui/remote-selection-ui.ts
@@ -620,4 +621,4 @@ export {
620
621
  runCancellableOperation,
621
622
  showRemoteSelectionReview
622
623
  };
623
- //# sourceMappingURL=chunk-4CHTZMEO.ts.map
624
+ //# sourceMappingURL=chunk-YDWUZVPN.ts.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/ui/remote-selection-ui.ts", "../../src/ui/cancellable-operation.ts"],
4
- "sourcesContent": ["import type { ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { defineMenu, runMenu } from \"@narumitw/pi-tui-kit\";\nimport { createSyncBackend, type SyncBackendFactory } from \"../backends/backend-factory.js\";\nimport type { RemoteHead, SyncBackend } from \"../backends/sync-backend.js\";\nimport {\n\tloadConfig,\n\tloadPartialConfig,\n\ttype SyncSetupStorageReview,\n\tsyncConfigReviewFingerprint,\n} from \"../settings/config.js\";\nimport { SyncSetupReviewChangedError, updateSyncSetup } from \"../settings/settings-management.js\";\nimport type { AnySyncConfig, PartialConfig } from \"../settings/settings-types.js\";\nimport { readSnapshotForHead } from \"../sync/remote-snapshot.js\";\nimport { errorMessage } from \"../sync/sync-errors.js\";\nimport {\n\tcompareSyncInclude,\n\tinspectRemoteSelection,\n\ttype RemoteSelectionDecision,\n\ttype RemoteSelectionState,\n\tsameSyncInclude,\n} from \"../sync/sync-policy.js\";\nimport {\n\ttype RunRoute,\n\ttype RunRouteResult,\n\trunCancellableOperation,\n} from \"./cancellable-operation.js\";\nimport { safeTerminalText } from \"./terminal-text.js\";\n\nconst STATUS_KEY = \"sync\";\n\nexport type RemoteSelectionOrigin = \"settings\" | \"sync\" | \"pull\" | \"push\";\n\nexport interface RemoteSelectionReviewOptions {\n\tdecision?: RemoteSelectionDecision;\n\torigin?: RemoteSelectionOrigin;\n\trunRoute?: RunRoute;\n\tcancelLabel?: string;\n\t/** The explicit mismatch is resolved or superseded; this does not imply file equality. */\n\tonSelectionResolved?: () => void;\n\twithStateAccess?: <T>(task: () => Promise<T>) => Promise<T>;\n}\n\nexport type RemoteSelectionReviewResult =\n\t| { kind: \"back\" }\n\t| { kind: \"closed\" }\n\t| { kind: \"done\" }\n\t| { kind: \"stale\" }\n\t| { kind: \"route-result\"; result: RunRouteResult; route: \"sync\" | \"pull\" | \"push\" };\n\nexport async function showRemoteSelectionReview(\n\tctx: ExtensionContext,\n\tsetupName?: string,\n\tsignal?: AbortSignal,\n\tfactory: SyncBackendFactory = createSyncBackend,\n\toptions: RemoteSelectionReviewOptions = {},\n): Promise<RemoteSelectionReviewResult> {\n\ttry {\n\t\tlet decision = options.decision;\n\t\tif (!decision) {\n\t\t\tconst inspected = await inspectConfiguredRemoteSelection(ctx, setupName, signal, factory);\n\t\t\tif (!inspected || signal?.aborted) return { kind: \"stale\" };\n\t\t\t// A successful fresh read can supersede an old explicit mismatch without\n\t\t\t// changing local settings. This is not user cancellation or proof of file equality.\n\t\t\tif (inspected.kind === \"empty\" || inspected.state.kind !== \"different\") {\n\t\t\t\toptions.onSelectionResolved?.();\n\t\t\t}\n\t\t\tif (inspected.kind === \"empty\") {\n\t\t\t\tctx.ui.notify(\"Remote storage has no snapshot or synced-content list yet.\", \"info\");\n\t\t\t\treturn { kind: \"back\" };\n\t\t\t}\n\t\t\tif (inspected.state.kind === \"same\") {\n\t\t\t\tctx.ui.notify(\"Remote synced content already matches this sync setup.\", \"info\");\n\t\t\t\treturn { kind: \"back\" };\n\t\t\t}\n\t\t\tif (inspected.state.kind === \"legacy\") {\n\t\t\t\tif (ctx.mode !== \"tui\") {\n\t\t\t\t\tctx.ui.notify(formatLegacySummary(inspected.config, inspected.state.discovered), \"info\");\n\t\t\t\t\treturn { kind: \"back\" };\n\t\t\t\t}\n\t\t\t\tawait showLegacyDiscovery(ctx, inspected.config, inspected.state.discovered, signal);\n\t\t\t\treturn signal?.aborted ? { kind: \"stale\" } : { kind: \"back\" };\n\t\t\t}\n\t\t\tdecision = decisionFromState(inspected.config, inspected.state);\n\t\t}\n\n\t\tif (ctx.mode !== \"tui\") {\n\t\t\tctx.ui.notify(formatRemoteSelectionSummary(decision), \"warning\");\n\t\t\treturn { kind: \"back\" };\n\t\t}\n\n\t\tlet currentDecision = decision;\n\t\tfor (;;) {\n\t\t\tif (signal?.aborted) return { kind: \"stale\" };\n\t\t\tconst result = await showSelectionDifference(\n\t\t\t\tctx,\n\t\t\t\tcurrentDecision,\n\t\t\t\toptions.origin ?? \"settings\",\n\t\t\t\toptions.runRoute,\n\t\t\t\tsignal,\n\t\t\t\tfactory,\n\t\t\t\toptions,\n\t\t\t);\n\t\t\tif (result.kind !== \"refresh\") return result;\n\t\t\tconst refreshed = await runWithOptionalStateAccess(options, () =>\n\t\t\t\tinspectConfiguredRemoteSelection(ctx, currentDecision.setupName, signal, factory),\n\t\t\t);\n\t\t\tif (!refreshed || signal?.aborted) return { kind: \"stale\" };\n\t\t\tif (refreshed.kind === \"empty\") {\n\t\t\t\toptions.onSelectionResolved?.();\n\t\t\t\tctx.ui.notify(\"Remote storage no longer has a snapshot or synced-content list.\", \"warning\");\n\t\t\t\treturn { kind: \"back\" };\n\t\t\t}\n\t\t\tif (refreshed.state.kind !== \"different\") {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\trefreshed.state.kind === \"same\"\n\t\t\t\t\t\t? \"Remote synced content now matches this sync setup.\"\n\t\t\t\t\t\t: \"The refreshed legacy snapshot has no authoritative synced-content list.\",\n\t\t\t\t\t\"info\",\n\t\t\t\t);\n\t\t\t\toptions.onSelectionResolved?.();\n\t\t\t\treturn { kind: \"done\" };\n\t\t\t}\n\t\t\tcurrentDecision = decisionFromState(refreshed.config, refreshed.state);\n\t\t}\n\t} catch (error) {\n\t\tif (signal?.aborted) return { kind: \"stale\" };\n\t\tctx.ui.notify(`Could not review synced content: ${errorMessage(error)}`, \"error\");\n\t\treturn { kind: \"back\" };\n\t} finally {\n\t\tctx.ui.setStatus(STATUS_KEY, undefined);\n\t}\n}\n\ntype DifferenceFlowResult = RemoteSelectionReviewResult | { kind: \"refresh\" };\n\nasync function showSelectionDifference(\n\tctx: ExtensionContext,\n\tinitialDecision: RemoteSelectionDecision,\n\torigin: RemoteSelectionOrigin,\n\trunRoute: RunRoute | undefined,\n\tsessionSignal: AbortSignal | undefined,\n\tfactory: SyncBackendFactory,\n\toptions: Pick<\n\t\tRemoteSelectionReviewOptions,\n\t\t\"cancelLabel\" | \"onSelectionResolved\" | \"withStateAccess\"\n\t>,\n): Promise<DifferenceFlowResult> {\n\ttype Screen = \"choice\" | \"review\" | \"saved\";\n\ttype Action = \"adopt\" | \"keep\" | \"cancel\" | \"continue\" | \"done\";\n\tinterface FlowState {\n\t\tdecision: RemoteSelectionDecision;\n\t\tsaved: boolean;\n\t}\n\tlet flowState: FlowState = { decision: initialDecision, saved: false };\n\tlet continuationReview: PartialConfig | undefined;\n\tlet nextResult: RemoteSelectionReviewResult | undefined;\n\tlet refreshRequested = false;\n\tconst route = origin === \"settings\" ? \"sync\" : origin;\n\tconst menu = defineMenu<FlowState, Screen, Action, ExtensionContext>({\n\t\tstart: \"choice\",\n\t\tscreens: {\n\t\t\tchoice: ({ state }) => ({\n\t\t\t\tkind: \"actions\",\n\t\t\t\ttitle: \"Synced content differs\",\n\t\t\t\tlines: selectionSummaryLines(state.decision),\n\t\t\t\titems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"review\",\n\t\t\t\t\t\tlabel: \"Review all paths (recommended)\",\n\t\t\t\t\t\tdescription: \"Compare exact remote-only, device-only, and ordered lists.\",\n\t\t\t\t\t\tto: \"review\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"adopt\",\n\t\t\t\t\t\tlabel: \"Use remote content list\",\n\t\t\t\t\t\tdescription: \"Save the reviewed list on this device without pulling files.\",\n\t\t\t\t\t\taction: \"adopt\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"keep\",\n\t\t\t\t\t\tlabel: \"Keep this device's content list and update remote\u2026\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Open the existing exact force-push preview without skipping confirmation.\",\n\t\t\t\t\t\taction: \"keep\",\n\t\t\t\t\t},\n\t\t\t\t\t{ id: \"cancel\", label: options.cancelLabel ?? \"Cancel\", action: \"cancel\" },\n\t\t\t\t],\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t\treview: ({ state }) => ({\n\t\t\t\tkind: \"review\",\n\t\t\t\ttitle: `Review synced content \u00B7 ${safeTerminalText(state.decision.setupName)}`,\n\t\t\t\tcontent: formatSelectionDifference(state.decision),\n\t\t\t\tformat: { kind: \"text\" },\n\t\t\t\tviewportSize: \"adaptive\",\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t\tsaved: ({ state }) => ({\n\t\t\t\tkind: \"actions\",\n\t\t\t\ttitle: \"Remote content list saved\",\n\t\t\t\tlines: [\n\t\t\t\t\t`Sync setup: ${safeTerminalText(state.decision.setupName)}`,\n\t\t\t\t\t\"Only the included-content setting was saved.\",\n\t\t\t\t\t\"No files were pulled and sync state was not changed.\",\n\t\t\t\t],\n\t\t\t\titems: [\n\t\t\t\t\t...(runRoute\n\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tid: \"continue\",\n\t\t\t\t\t\t\t\t\tlabel: continueLabel(origin),\n\t\t\t\t\t\t\t\t\tdescription: \"Start a fresh check and exact preview for this sync setup.\",\n\t\t\t\t\t\t\t\t\taction: \"continue\" as const,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t: []),\n\t\t\t\t\t{ id: \"done\", label: \"Done\", action: \"done\" },\n\t\t\t\t],\n\t\t\t\thint: \"close\",\n\t\t\t}),\n\t\t},\n\t\tactions: {\n\t\t\tadopt: async ({ state, signal: actionSignal }) => {\n\t\t\t\tconst signal = combineSignals(sessionSignal, actionSignal);\n\t\t\t\ttry {\n\t\t\t\t\tconst currentConfig = await loadConfig(state.decision.setupName);\n\t\t\t\t\tif (signal.aborted) return { kind: \"close\" as const };\n\t\t\t\t\tassertLocalSelectionCurrent(currentConfig, state.decision);\n\t\t\t\t\tif (\n\t\t\t\t\t\t!currentConfig.include.includes(\"sessions\") &&\n\t\t\t\t\t\tstate.decision.remoteInclude.includes(\"sessions\")\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst acknowledged = await ctx.ui.confirm(\n\t\t\t\t\t\t\t\"Use a content list that includes session conversations?\",\n\t\t\t\t\t\t\t\"Session JSONL may contain prompts, tool output, file paths, images, and secrets. This saves the list only; it does not pull files.\",\n\t\t\t\t\t\t\t{ signal },\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (signal.aborted) return { kind: \"close\" as const };\n\t\t\t\t\t\tif (!acknowledged) return { kind: \"stay\" as const };\n\t\t\t\t\t}\n\t\t\t\t\tconst review = await runWithOptionalStateAccess(options, async () => {\n\t\t\t\t\t\tconst loaded = await loadAdoptionReview(state.decision, signal, factory);\n\t\t\t\t\t\tif (signal.aborted) throw signal.reason;\n\t\t\t\t\t\tawait revalidateAndAdopt(loaded, state.decision, signal);\n\t\t\t\t\t\treturn loaded;\n\t\t\t\t\t});\n\t\t\t\t\tif (signal.aborted) return { kind: \"close\" as const };\n\t\t\t\t\toptions.onSelectionResolved?.();\n\t\t\t\t\tcontinuationReview = {\n\t\t\t\t\t\t...review.storageReview,\n\t\t\t\t\t\tsetupName: state.decision.setupName,\n\t\t\t\t\t\tinclude: [...state.decision.remoteInclude],\n\t\t\t\t\t\tautomatic: review.config.automatic,\n\t\t\t\t\t\tonSwitch: review.config.onSwitch,\n\t\t\t\t\t};\n\t\t\t\t\tflowState = { decision: state.decision, saved: true };\n\t\t\t\t\treturn { kind: \"to\" as const, screen: \"saved\" as const };\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (signal.aborted) return { kind: \"close\" as const };\n\t\t\t\t\tif (isStaleReviewError(error)) {\n\t\t\t\t\t\tctx.ui.notify(`${errorMessage(error)} Refreshing the comparison.`, \"warning\");\n\t\t\t\t\t\trefreshRequested = true;\n\t\t\t\t\t\treturn { kind: \"close\" as const };\n\t\t\t\t\t}\n\t\t\t\t\tctx.ui.notify(`Could not save the remote content list: ${errorMessage(error)}`, \"error\");\n\t\t\t\t\treturn { kind: \"stay\" as const };\n\t\t\t\t}\n\t\t\t},\n\t\t\tkeep: async ({ state, signal: actionSignal }) => {\n\t\t\t\tif (!runRoute) {\n\t\t\t\t\tctx.ui.notify(\"The reviewed update-remote route is unavailable.\", \"error\");\n\t\t\t\t\treturn { kind: \"stay\" as const };\n\t\t\t\t}\n\t\t\t\tconst signal = combineSignals(sessionSignal, actionSignal);\n\t\t\t\ttry {\n\t\t\t\t\tconst latest = await loadConfig(state.decision.setupName);\n\t\t\t\t\tif (signal.aborted) return { kind: \"close\" as const };\n\t\t\t\t\tassertLocalSelectionCurrent(latest, state.decision);\n\t\t\t\t\tconst result = await runCancellableOperation(\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\"Preparing this device's push preview\u2026\",\n\t\t\t\t\t\t\"push --force\",\n\t\t\t\t\t\trunRoute,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommitAware: true,\n\t\t\t\t\t\t\tcancelledMessage: \"Push preparation cancelled; no remote files were changed.\",\n\t\t\t\t\t\t\ttarget: state.decision.setupName,\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\treturn handleNestedRouteResult(result, \"push\");\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (signal.aborted) return { kind: \"close\" as const };\n\t\t\t\t\tif (isStaleReviewError(error)) {\n\t\t\t\t\t\tctx.ui.notify(`${errorMessage(error)} Refreshing the comparison.`, \"warning\");\n\t\t\t\t\t\trefreshRequested = true;\n\t\t\t\t\t\treturn { kind: \"close\" as const };\n\t\t\t\t\t}\n\t\t\t\t\tctx.ui.notify(`Could not prepare the remote update: ${errorMessage(error)}`, \"error\");\n\t\t\t\t\treturn { kind: \"stay\" as const };\n\t\t\t\t}\n\t\t\t},\n\t\t\tcontinue: async ({ state, signal: actionSignal }) => {\n\t\t\t\tif (!runRoute || !continuationReview) return { kind: \"stay\" as const };\n\t\t\t\tconst signal = combineSignals(sessionSignal, actionSignal);\n\t\t\t\ttry {\n\t\t\t\t\tconst latest = await loadPartialConfig(state.decision.setupName);\n\t\t\t\t\tif (signal.aborted) return { kind: \"close\" as const };\n\t\t\t\t\tif (!sameContinuationReview(latest, continuationReview)) {\n\t\t\t\t\t\tthrow new StaleRemoteSelectionReviewError(\n\t\t\t\t\t\t\t`Sync setup \u201C${safeTerminalText(state.decision.setupName)}\u201D changed after the remote content list was saved.`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tconst result = await runCancellableOperation(\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\tcontinueBusyLabel(origin),\n\t\t\t\t\t\troute,\n\t\t\t\t\t\trunRoute,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommitAware: true,\n\t\t\t\t\t\t\tcancelledMessage: continuationCancelledMessage(route),\n\t\t\t\t\t\t\ttarget: state.decision.setupName,\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\treturn handleNestedRouteResult(result, route);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (signal.aborted) return { kind: \"close\" as const };\n\t\t\t\t\tctx.ui.notify(`Could not continue: ${errorMessage(error)}`, \"error\");\n\t\t\t\t\treturn { kind: \"stay\" as const };\n\t\t\t\t}\n\t\t\t},\n\t\t\tcancel: async () => ({ kind: \"back\" }),\n\t\t\tdone: async () => {\n\t\t\t\tnextResult = { kind: \"done\" };\n\t\t\t\treturn { kind: \"close\" };\n\t\t\t},\n\t\t},\n\t});\n\n\tfunction handleNestedRouteResult(\n\t\tresult: Awaited<ReturnType<typeof runCancellableOperation>>,\n\t\tnestedRoute: \"sync\" | \"pull\" | \"push\",\n\t) {\n\t\tif (result.kind === \"completed\" && result.outcome === \"applied\") {\n\t\t\toptions.onSelectionResolved?.();\n\t\t}\n\t\tif (result.kind === \"closed\") {\n\t\t\tnextResult = { kind: \"closed\" };\n\t\t\treturn { kind: \"close\" as const };\n\t\t}\n\t\tif (\n\t\t\tresult.kind === \"cancelled\" ||\n\t\t\t(result.kind === \"completed\" && result.outcome === \"cancelled\") ||\n\t\t\tresult.kind === \"failed\"\n\t\t) {\n\t\t\treturn { kind: \"stay\" as const };\n\t\t}\n\t\tnextResult = { kind: \"route-result\", result, route: nestedRoute };\n\t\treturn { kind: \"close\" as const };\n\t}\n\n\tconst menuResult = await runMenu(ctx, menu, {\n\t\tgetState: () => flowState,\n\t\tsignal: sessionSignal,\n\t\tisCurrent: () => !sessionSignal?.aborted,\n\t\tonError: (_menuCtx, error) => ctx.ui.notify(errorMessage(error), \"error\"),\n\t});\n\tif (sessionSignal?.aborted || menuResult.kind === \"stale\") return { kind: \"stale\" };\n\tif (refreshRequested) return { kind: \"refresh\" };\n\tif (nextResult) return nextResult;\n\tif (menuResult.kind === \"closed\") {\n\t\treturn menuResult.reason === \"back\" ? { kind: \"back\" } : { kind: \"closed\" };\n\t}\n\treturn { kind: \"closed\" };\n}\n\ninterface AdoptionReview {\n\tconfig: AnySyncConfig;\n\tstorageReview: SyncSetupStorageReview;\n\tbackend: SyncBackend;\n\treviewedHead: RemoteHead;\n}\n\nasync function loadAdoptionReview(\n\tdecision: RemoteSelectionDecision,\n\tsignal: AbortSignal,\n\tfactory: SyncBackendFactory,\n): Promise<AdoptionReview> {\n\tconst config = await loadConfig(decision.setupName);\n\tthrowIfAborted(signal);\n\tassertLocalSelectionCurrent(config, decision);\n\tconst partial = await loadPartialConfig(decision.setupName);\n\tthrowIfAborted(signal);\n\tif (!sameSyncInclude(partial.include, decision.localInclude)) {\n\t\tthrow new StaleRemoteSelectionReviewError(\n\t\t\t`Sync setup \u201C${safeTerminalText(decision.setupName)}\u201D changed while the comparison was open.`,\n\t\t);\n\t}\n\tconst backend = await factory(config);\n\tthrowIfAborted(signal);\n\tconst reviewedHead = await backend.readHead(signal);\n\tthrowIfAborted(signal);\n\tif (!reviewedHead) {\n\t\tthrow new StaleRemoteSelectionReviewError(\n\t\t\t\"Remote storage changed while the comparison was open.\",\n\t\t);\n\t}\n\tconst snapshot = await readSnapshotForHead(backend, reviewedHead, signal);\n\tthrowIfAborted(signal);\n\tconst state = inspectRemoteSelection(config.include, snapshot);\n\tif (state.kind !== \"different\" || !sameSyncInclude(state.include, decision.remoteInclude)) {\n\t\tthrow new StaleRemoteSelectionReviewError(\n\t\t\t\"Remote synced content changed while the comparison was open.\",\n\t\t);\n\t}\n\treturn { config, storageReview: partial, backend, reviewedHead };\n}\n\nasync function revalidateAndAdopt(\n\treview: AdoptionReview,\n\tdecision: RemoteSelectionDecision,\n\tsignal: AbortSignal,\n) {\n\tconst currentHead = await review.backend.readHead(signal);\n\tthrowIfAborted(signal);\n\tif (\n\t\t!currentHead ||\n\t\t!review.backend.sameRevision(review.reviewedHead.revision, currentHead.revision)\n\t) {\n\t\tthrow new StaleRemoteSelectionReviewError(\n\t\t\t\"Remote storage changed while the comparison was open.\",\n\t\t);\n\t}\n\tconst currentSnapshot = await readSnapshotForHead(review.backend, currentHead, signal);\n\tthrowIfAborted(signal);\n\tconst currentState = inspectRemoteSelection(review.config.include, currentSnapshot);\n\tif (\n\t\tcurrentState.kind !== \"different\" ||\n\t\t!sameSyncInclude(currentState.include, decision.remoteInclude)\n\t) {\n\t\tthrow new StaleRemoteSelectionReviewError(\n\t\t\t\"Remote synced content changed while the comparison was open.\",\n\t\t);\n\t}\n\tawait updateSyncSetup(\n\t\tdecision.setupName,\n\t\t(setup) => ({\n\t\t\t...setup,\n\t\t\tsync: { ...setup.sync, include: [...decision.remoteInclude] },\n\t\t}),\n\t\t{\n\t\t\texpectedStorage: review.storageReview,\n\t\t\texpectedInclude: decision.localInclude,\n\t\t\tsignal,\n\t\t},\n\t);\n}\n\nasync function inspectConfiguredRemoteSelection(\n\tctx: ExtensionContext,\n\tsetupName: string | undefined,\n\tsignal: AbortSignal | undefined,\n\tfactory: SyncBackendFactory,\n): Promise<\n\t| { kind: \"empty\"; config: AnySyncConfig }\n\t| { kind: \"selection\"; config: AnySyncConfig; state: RemoteSelectionState }\n\t| undefined\n> {\n\tconst config = await loadConfig(setupName);\n\tif (signal?.aborted) return undefined;\n\tctx.ui.setStatus(STATUS_KEY, `checking synced content for ${safeTerminalText(config.setupName)}`);\n\tconst backend = await factory(config);\n\tif (signal?.aborted) return undefined;\n\tconst head = await backend.readHead(signal);\n\tif (signal?.aborted) return undefined;\n\tif (!head) return { kind: \"empty\", config };\n\tconst snapshot = await readSnapshotForHead(backend, head, signal);\n\tif (signal?.aborted) return undefined;\n\treturn {\n\t\tkind: \"selection\",\n\t\tconfig,\n\t\tstate: inspectRemoteSelection(config.include, snapshot),\n\t};\n}\n\nasync function showLegacyDiscovery(\n\tctx: ExtensionContext,\n\tconfig: AnySyncConfig,\n\tdiscovered: string[],\n\tsignal?: AbortSignal,\n) {\n\tconst menu = defineMenu<undefined, \"choice\" | \"review\", \"back\", ExtensionContext>({\n\t\tstart: \"choice\",\n\t\tscreens: {\n\t\t\tchoice: () => ({\n\t\t\t\tkind: \"actions\",\n\t\t\t\ttitle: `Compare synced content \u00B7 ${safeTerminalText(config.setupName)}`,\n\t\t\t\tlines: [\n\t\t\t\t\t\"This legacy snapshot has no portable synced-content list.\",\n\t\t\t\t\t\"Discovered paths are partial and read-only; preserved files may not have been selected.\",\n\t\t\t\t],\n\t\t\t\titems: [\n\t\t\t\t\t{ id: \"review\", label: \"Review discovered paths\", to: \"review\" },\n\t\t\t\t\t{ id: \"back\", label: \"Back\", action: \"back\" },\n\t\t\t\t],\n\t\t\t\thint: \"close\",\n\t\t\t}),\n\t\t\treview: () => ({\n\t\t\t\tkind: \"review\",\n\t\t\t\ttitle: \"Partial discovery from legacy snapshot\",\n\t\t\t\tcontent: [\n\t\t\t\t\t\"Partial discovery only \u2014 not an authoritative selection.\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t...(discovered.length > 0\n\t\t\t\t\t\t? discovered.map((item) => `Discovered: ${safeTerminalText(item)}`)\n\t\t\t\t\t\t: [\"No safe paths were discovered.\"]),\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Use Add custom path\u2026 in the local Included Content editor if needed.\",\n\t\t\t\t].join(\"\\n\"),\n\t\t\t\tformat: { kind: \"text\" },\n\t\t\t\tviewportSize: \"adaptive\",\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t},\n\t\tactions: { back: async () => ({ kind: \"close\" }) },\n\t});\n\tawait runMenu(ctx, menu, {\n\t\tgetState: () => undefined,\n\t\tsignal,\n\t\tisCurrent: () => !signal?.aborted,\n\t});\n}\n\nfunction selectionSummaryLines(decision: RemoteSelectionDecision) {\n\tconst comparison = compareSyncInclude(decision.localInclude, decision.remoteInclude);\n\treturn [\n\t\t`Sync setup: ${safeTerminalText(decision.setupName)}`,\n\t\t\"Nothing changed. Review both lists before choosing what happens next.\",\n\t\t...(comparison.remoteOnly.length === 0 && comparison.localOnly.length === 0\n\t\t\t? [\"Only the ordering differs; membership is the same.\"]\n\t\t\t: [\n\t\t\t\t\t`Remote-only paths: ${comparison.remoteOnly.length} \u00B7 Device-only paths: ${comparison.localOnly.length}`,\n\t\t\t\t]),\n\t];\n}\n\nfunction formatSelectionDifference(decision: RemoteSelectionDecision) {\n\tconst comparison = compareSyncInclude(decision.localInclude, decision.remoteInclude);\n\treturn [\n\t\t...(comparison.remoteOnly.length === 0 && comparison.localOnly.length === 0\n\t\t\t? [\"Only ordering differs; both lists contain the same paths.\", \"\"]\n\t\t\t: []),\n\t\t\"Remote-only paths:\",\n\t\t...(comparison.remoteOnly.length > 0\n\t\t\t? comparison.remoteOnly.map((item) => `+ ${safeTerminalText(item)}`)\n\t\t\t: [\"(none)\"]),\n\t\t\"\",\n\t\t\"Device-only paths:\",\n\t\t...(comparison.localOnly.length > 0\n\t\t\t? comparison.localOnly.map((item) => `- ${safeTerminalText(item)}`)\n\t\t\t: [\"(none)\"]),\n\t\t\"\",\n\t\t\"Remote ordered list:\",\n\t\t...(decision.remoteInclude.length > 0\n\t\t\t? decision.remoteInclude.map((item, index) => `${index + 1}. ${safeTerminalText(item)}`)\n\t\t\t: [\"(none)\"]),\n\t\t\"\",\n\t\t\"This device's ordered list:\",\n\t\t...(decision.localInclude.length > 0\n\t\t\t? decision.localInclude.map((item, index) => `${index + 1}. ${safeTerminalText(item)}`)\n\t\t\t: [\"(none)\"]),\n\t\t\"\",\n\t\t\"Using the remote list saves settings only and does not pull files.\",\n\t].join(\"\\n\");\n}\n\nfunction formatRemoteSelectionSummary(decision: RemoteSelectionDecision) {\n\tconst comparison = compareSyncInclude(decision.localInclude, decision.remoteInclude);\n\treturn [\n\t\t`Synced content for \u201C${safeTerminalText(decision.setupName)}\u201D differs from this device.`,\n\t\t`Remote-only: ${safeList(comparison.remoteOnly)}`,\n\t\t`Device-only: ${safeList(comparison.localOnly)}`,\n\t\t...(comparison.remoteOnly.length === 0 && comparison.localOnly.length === 0\n\t\t\t? [\n\t\t\t\t\t\"Only ordering differs.\",\n\t\t\t\t\t`Remote order: ${safeList(decision.remoteInclude)}`,\n\t\t\t\t\t`Device order: ${safeList(decision.localInclude)}`,\n\t\t\t\t]\n\t\t\t: []),\n\t\t\"Run /sync in TUI to choose a content list; RPC review is read-only.\",\n\t].join(\"\\n\");\n}\n\nfunction formatLegacySummary(config: AnySyncConfig, discovered: readonly string[]) {\n\treturn `Remote snapshot for \u201C${safeTerminalText(config.setupName)}\u201D has no portable synced-content list; ${discovered.length} safe path${discovered.length === 1 ? \" was\" : \"s were\"} discovered, but the result is partial and read-only.`;\n}\n\nfunction decisionFromState(\n\tconfig: AnySyncConfig,\n\tstate: Extract<RemoteSelectionState, { kind: \"different\" }>,\n): RemoteSelectionDecision {\n\treturn {\n\t\tsetupName: config.setupName,\n\t\tconfigIdentity: syncConfigReviewFingerprint(config),\n\t\tlocalInclude: [...config.include],\n\t\tremoteInclude: [...state.include],\n\t};\n}\n\nfunction assertLocalSelectionCurrent(config: AnySyncConfig, decision: RemoteSelectionDecision) {\n\tif (\n\t\tsyncConfigReviewFingerprint(config) === decision.configIdentity &&\n\t\tsameSyncInclude(config.include, decision.localInclude)\n\t) {\n\t\treturn;\n\t}\n\tthrow new StaleRemoteSelectionReviewError(\n\t\t`Sync setup \u201C${safeTerminalText(config.setupName)}\u201D changed while the comparison was open.`,\n\t);\n}\n\nfunction sameContinuationReview(left: PartialConfig, right: PartialConfig) {\n\treturn (\n\t\tleft.setupName === right.setupName &&\n\t\tleft.connectionName === right.connectionName &&\n\t\tleft.storageKind === right.storageKind &&\n\t\tleft.storagePath === right.storagePath &&\n\t\tleft.bucket === right.bucket &&\n\t\tleft.branch === right.branch &&\n\t\tsameSyncInclude(left.include, right.include)\n\t);\n}\n\nfunction continueLabel(origin: RemoteSelectionOrigin) {\n\tif (origin === \"pull\") return \"Continue Pull now\u2026\";\n\tif (origin === \"push\") return \"Continue Push now\u2026\";\n\treturn \"Continue Sync now\u2026\";\n}\n\nfunction continueBusyLabel(origin: RemoteSelectionOrigin) {\n\tif (origin === \"pull\") return \"Checking remote changes\u2026\";\n\tif (origin === \"push\") return \"Preparing push preview\u2026\";\n\treturn \"Checking current sync setup\u2026\";\n}\n\nfunction continuationCancelledMessage(route: \"sync\" | \"pull\" | \"push\") {\n\tif (route === \"pull\") return \"Pull check cancelled; no local files were changed.\";\n\tif (route === \"push\") return \"Push preparation cancelled; no remote files were changed.\";\n\treturn \"Sync check cancelled; no settings or files were changed.\";\n}\n\nfunction safeList(values: readonly string[]) {\n\treturn values.length > 0 ? values.map(safeTerminalText).join(\", \") : \"none\";\n}\n\nclass StaleRemoteSelectionReviewError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"StaleRemoteSelectionReviewError\";\n\t}\n}\n\nfunction isStaleReviewError(error: unknown) {\n\treturn (\n\t\terror instanceof StaleRemoteSelectionReviewError || error instanceof SyncSetupReviewChangedError\n\t);\n}\n\nfunction runWithOptionalStateAccess<T>(\n\toptions: Pick<RemoteSelectionReviewOptions, \"withStateAccess\">,\n\ttask: () => Promise<T>,\n) {\n\treturn options.withStateAccess ? options.withStateAccess(task) : task();\n}\n\nfunction combineSignals(sessionSignal: AbortSignal | undefined, actionSignal: AbortSignal) {\n\treturn sessionSignal ? AbortSignal.any([sessionSignal, actionSignal]) : actionSignal;\n}\n\nfunction throwIfAborted(signal: AbortSignal) {\n\tif (!signal.aborted) return;\n\tthrow signal.reason instanceof Error\n\t\t? signal.reason\n\t\t: new DOMException(\"The operation was aborted\", \"AbortError\");\n}\n", "import {\n\tBorderedLoader,\n\ttype ExtensionContext,\n\ttype KeybindingsManager,\n} from \"@earendil-works/pi-coding-agent\";\nimport { Key, matchesKey, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport { runCustomInteraction } from \"@narumitw/pi-tui-kit\";\nimport type { SetupPullOutcome } from \"../sync/setup-switch.js\";\nimport type { SyncDecision } from \"../sync/sync-decision.js\";\nimport type { RemoteSelectionDecision } from \"../sync/sync-policy.js\";\nimport { safeTerminalText } from \"./terminal-text.js\";\n\nexport type RunRouteResult =\n\t| { kind: \"completed\"; outcome?: SetupPullOutcome }\n\t| { kind: \"decision-required\"; decision: SyncDecision }\n\t| { kind: \"remote-selection-required\"; decision: RemoteSelectionDecision }\n\t| { kind: \"failed\" };\n\nexport type RunRoute = (\n\troute: string,\n\tsignal?: AbortSignal,\n\tonCommit?: () => void,\n\ttarget?: string,\n) => Promise<RunRouteResult | undefined>;\n\nexport type CancellableOperationResult =\n\t| RunRouteResult\n\t| { kind: \"closed\" }\n\t| { kind: \"cancelled\" };\n\ninterface CancellableOperationOptions {\n\tcommitAware?: boolean;\n\tcancelledMessage?: string | null;\n\ttarget?: string;\n\tsignal?: AbortSignal;\n}\n\nexport async function runCancellableOperation(\n\tctx: ExtensionContext,\n\tmessage: string,\n\troute: string,\n\trunRoute: RunRoute,\n\toptions: CancellableOperationOptions = {},\n): Promise<CancellableOperationResult> {\n\tconst {\n\t\tcommitAware = false,\n\t\tcancelledMessage = \"Check cancelled; no settings or files were changed.\",\n\t\ttarget,\n\t\tsignal,\n\t} = options;\n\tif (ctx.mode !== \"tui\") {\n\t\treturn (await runRoute(route, signal, undefined, target)) ?? { kind: \"failed\" };\n\t}\n\tlet commitStarted = false;\n\tlet routeResult: RunRouteResult | undefined;\n\tconst interaction = await runCustomInteraction<\n\t\t{ cancelled?: boolean; error?: unknown },\n\t\tExtensionContext\n\t>(ctx, {\n\t\tsignal,\n\t\tisCurrent: () => !signal?.aborted,\n\t\tcreate: ({ tui, theme, keybindings, signal: interactionSignal, complete }) => {\n\t\t\tconst loader = new BorderedLoader(tui, theme, message, { cancellable: false });\n\t\t\tconst cancelHint = `${keybindingText(keybindings, \"tui.select.cancel\", \"esc\")} cancel`;\n\t\t\tconst operation = runRoute(\n\t\t\t\troute,\n\t\t\t\tinteractionSignal,\n\t\t\t\tcommitAware ? () => (commitStarted = true) : undefined,\n\t\t\t\ttarget,\n\t\t\t).then(\n\t\t\t\t(result) => {\n\t\t\t\t\trouteResult = result;\n\t\t\t\t\tcomplete({});\n\t\t\t\t},\n\t\t\t\t(error: unknown) => complete({ error }),\n\t\t\t);\n\t\t\treturn {\n\t\t\t\trender(width: number) {\n\t\t\t\t\tconst safeWidth = Math.max(1, width);\n\t\t\t\t\tconst lines = loader.render(safeWidth);\n\t\t\t\t\tconst bottomBorder = lines.at(-1);\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...lines.slice(0, -1),\n\t\t\t\t\t\ttruncateToWidth(theme.fg(\"dim\", cancelHint), safeWidth, \"\"),\n\t\t\t\t\t\t...(bottomBorder === undefined ? [] : [bottomBorder]),\n\t\t\t\t\t];\n\t\t\t\t},\n\t\t\t\tinvalidate: () => loader.invalidate(),\n\t\t\t\thandleInput(data: string) {\n\t\t\t\t\tif (!matchesKey(data, Key.ctrl(\"c\")) && !keybindings.matches(data, \"tui.select.cancel\")) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (commitStarted) {\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t\"Applying or publishing has started and cannot be cancelled safely.\",\n\t\t\t\t\t\t\t\"warning\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcomplete({ cancelled: true });\n\t\t\t\t},\n\t\t\t\tdispose: () => loader.dispose(),\n\t\t\t\twaitForPending: () => operation,\n\t\t\t};\n\t\t},\n\t});\n\tif (interaction.kind === \"error\") throw interaction.error;\n\tif (interaction.kind !== \"completed\") return { kind: \"closed\" };\n\tif (interaction.value.cancelled) {\n\t\tif (cancelledMessage) ctx.ui.notify(cancelledMessage, \"info\");\n\t\treturn { kind: \"cancelled\" };\n\t}\n\tif (interaction.value.error) throw interaction.value.error;\n\treturn routeResult ?? { kind: \"failed\" };\n}\n\nfunction keybindingText(\n\tkeybindings: Pick<KeybindingsManager, \"getKeys\">,\n\tbinding: Parameters<KeybindingsManager[\"getKeys\"]>[0],\n\tfallback: string,\n) {\n\tconst keys = [...new Set([...keybindings.getKeys(binding), \"ctrl+c\"])]\n\t\t.map(String)\n\t\t.map((key) => {\n\t\t\tif (key === \"return\") return \"enter\";\n\t\t\tif (key === \"escape\") return \"esc\";\n\t\t\treturn safeTerminalText(key);\n\t\t})\n\t\t.filter(Boolean);\n\treturn keys.join(\"/\") || fallback;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { defineMenu, runMenu } from \"@narumitw/pi-tui-kit\";\nimport { createSyncBackend, type SyncBackendFactory } from \"../backends/backend-factory.js\";\nimport type { RemoteHead, SyncBackend } from \"../backends/sync-backend.js\";\nimport {\n\tloadConfig,\n\tloadPartialConfig,\n\ttype SyncSetupStorageReview,\n\tsyncConfigReviewFingerprint,\n} from \"../settings/config.js\";\nimport { SyncSetupReviewChangedError, updateSyncSetup } from \"../settings/settings-management.js\";\nimport type { AnySyncConfig, PartialConfig } from \"../settings/settings-types.js\";\nimport { readSnapshotForHead } from \"../sync/remote-snapshot.js\";\nimport { errorMessage } from \"../sync/sync-errors.js\";\nimport {\n\tcompareSyncInclude,\n\tinspectRemoteSelection,\n\ttype RemoteSelectionDecision,\n\ttype RemoteSelectionState,\n\tsameSyncInclude,\n} from \"../sync/sync-policy.js\";\nimport {\n\ttype RunRoute,\n\ttype RunRouteResult,\n\trunCancellableOperation,\n} from \"./cancellable-operation.js\";\nimport { safeTerminalText } from \"./terminal-text.js\";\n\nconst STATUS_KEY = \"sync\";\n\nexport type RemoteSelectionOrigin = \"settings\" | \"sync\" | \"pull\" | \"push\";\n\nexport interface RemoteSelectionReviewOptions {\n\tdecision?: RemoteSelectionDecision;\n\torigin?: RemoteSelectionOrigin;\n\trunRoute?: RunRoute;\n\tcancelLabel?: string;\n\t/** The explicit mismatch is resolved or superseded; this does not imply file equality. */\n\tonSelectionResolved?: () => void;\n\twithStateAccess?: <T>(task: () => Promise<T>) => Promise<T>;\n}\n\nexport type RemoteSelectionReviewResult =\n\t| { kind: \"back\" }\n\t| { kind: \"closed\" }\n\t| { kind: \"done\" }\n\t| { kind: \"stale\" }\n\t| { kind: \"route-result\"; result: RunRouteResult; route: \"sync\" | \"pull\" | \"push\" };\n\nexport async function showRemoteSelectionReview(\n\tctx: ExtensionContext,\n\tsetupName?: string,\n\tsignal?: AbortSignal,\n\tfactory: SyncBackendFactory = createSyncBackend,\n\toptions: RemoteSelectionReviewOptions = {},\n): Promise<RemoteSelectionReviewResult> {\n\ttry {\n\t\tlet decision = options.decision;\n\t\tif (!decision) {\n\t\t\tconst inspected = await inspectConfiguredRemoteSelection(ctx, setupName, signal, factory);\n\t\t\tif (!inspected || signal?.aborted) return { kind: \"stale\" };\n\t\t\t// A successful fresh read can supersede an old explicit mismatch without\n\t\t\t// changing local settings. This is not user cancellation or proof of file equality.\n\t\t\tif (inspected.kind === \"empty\" || inspected.state.kind !== \"different\") {\n\t\t\t\toptions.onSelectionResolved?.();\n\t\t\t}\n\t\t\tif (inspected.kind === \"empty\") {\n\t\t\t\tctx.ui.notify(\"Remote storage has no snapshot or synced-content list yet.\", \"info\");\n\t\t\t\treturn { kind: \"back\" };\n\t\t\t}\n\t\t\tif (inspected.state.kind === \"same\") {\n\t\t\t\tctx.ui.notify(\"Remote synced content already matches this sync setup.\", \"info\");\n\t\t\t\treturn { kind: \"back\" };\n\t\t\t}\n\t\t\tif (inspected.state.kind === \"legacy\") {\n\t\t\t\tif (ctx.mode !== \"tui\") {\n\t\t\t\t\tctx.ui.notify(formatLegacySummary(inspected.config, inspected.state.discovered), \"info\");\n\t\t\t\t\treturn { kind: \"back\" };\n\t\t\t\t}\n\t\t\t\tawait showLegacyDiscovery(ctx, inspected.config, inspected.state.discovered, signal);\n\t\t\t\treturn signal?.aborted ? { kind: \"stale\" } : { kind: \"back\" };\n\t\t\t}\n\t\t\tdecision = decisionFromState(inspected.config, inspected.state);\n\t\t}\n\n\t\tif (ctx.mode !== \"tui\") {\n\t\t\tctx.ui.notify(formatRemoteSelectionSummary(decision), \"warning\");\n\t\t\treturn { kind: \"back\" };\n\t\t}\n\n\t\tlet currentDecision = decision;\n\t\tfor (;;) {\n\t\t\tif (signal?.aborted) return { kind: \"stale\" };\n\t\t\tconst result = await showSelectionDifference(\n\t\t\t\tctx,\n\t\t\t\tcurrentDecision,\n\t\t\t\toptions.origin ?? \"settings\",\n\t\t\t\toptions.runRoute,\n\t\t\t\tsignal,\n\t\t\t\tfactory,\n\t\t\t\toptions,\n\t\t\t);\n\t\t\tif (result.kind !== \"refresh\") return result;\n\t\t\tconst refreshed = await runWithOptionalStateAccess(options, () =>\n\t\t\t\tinspectConfiguredRemoteSelection(ctx, currentDecision.setupName, signal, factory),\n\t\t\t);\n\t\t\tif (!refreshed || signal?.aborted) return { kind: \"stale\" };\n\t\t\tif (refreshed.kind === \"empty\") {\n\t\t\t\toptions.onSelectionResolved?.();\n\t\t\t\tctx.ui.notify(\"Remote storage no longer has a snapshot or synced-content list.\", \"warning\");\n\t\t\t\treturn { kind: \"back\" };\n\t\t\t}\n\t\t\tif (refreshed.state.kind !== \"different\") {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\trefreshed.state.kind === \"same\"\n\t\t\t\t\t\t? \"Remote synced content now matches this sync setup.\"\n\t\t\t\t\t\t: \"The refreshed legacy snapshot has no authoritative synced-content list.\",\n\t\t\t\t\t\"info\",\n\t\t\t\t);\n\t\t\t\toptions.onSelectionResolved?.();\n\t\t\t\treturn { kind: \"done\" };\n\t\t\t}\n\t\t\tcurrentDecision = decisionFromState(refreshed.config, refreshed.state);\n\t\t}\n\t} catch (error) {\n\t\tif (signal?.aborted) return { kind: \"stale\" };\n\t\tctx.ui.notify(`Could not review synced content: ${errorMessage(error)}`, \"error\");\n\t\treturn { kind: \"back\" };\n\t} finally {\n\t\tctx.ui.setStatus(STATUS_KEY, undefined);\n\t}\n}\n\ntype DifferenceFlowResult = RemoteSelectionReviewResult | { kind: \"refresh\" };\n\nasync function showSelectionDifference(\n\tctx: ExtensionContext,\n\tinitialDecision: RemoteSelectionDecision,\n\torigin: RemoteSelectionOrigin,\n\trunRoute: RunRoute | undefined,\n\tsessionSignal: AbortSignal | undefined,\n\tfactory: SyncBackendFactory,\n\toptions: Pick<\n\t\tRemoteSelectionReviewOptions,\n\t\t\"cancelLabel\" | \"onSelectionResolved\" | \"withStateAccess\"\n\t>,\n): Promise<DifferenceFlowResult> {\n\ttype Screen = \"choice\" | \"review\" | \"saved\";\n\ttype Action = \"adopt\" | \"keep\" | \"cancel\" | \"continue\" | \"done\";\n\tinterface FlowState {\n\t\tdecision: RemoteSelectionDecision;\n\t\tsaved: boolean;\n\t}\n\tlet flowState: FlowState = { decision: initialDecision, saved: false };\n\tlet continuationReview: PartialConfig | undefined;\n\tlet nextResult: RemoteSelectionReviewResult | undefined;\n\tlet refreshRequested = false;\n\tconst route = origin === \"settings\" ? \"sync\" : origin;\n\tconst menu = defineMenu<FlowState, Screen, Action, ExtensionContext>({\n\t\tstart: \"choice\",\n\t\tscreens: {\n\t\t\tchoice: ({ state }) => ({\n\t\t\t\tkind: \"actions\",\n\t\t\t\ttitle: \"Synced content differs\",\n\t\t\t\tlines: selectionSummaryLines(state.decision),\n\t\t\t\titems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"review\",\n\t\t\t\t\t\tlabel: \"Review all paths (recommended)\",\n\t\t\t\t\t\tdescription: \"Compare exact remote-only, device-only, and ordered lists.\",\n\t\t\t\t\t\tto: \"review\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"adopt\",\n\t\t\t\t\t\tlabel: \"Use remote content list\",\n\t\t\t\t\t\tdescription: \"Save the reviewed list on this device without pulling files.\",\n\t\t\t\t\t\taction: \"adopt\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"keep\",\n\t\t\t\t\t\tlabel: \"Keep this device's content list and update remote\u2026\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Open the existing exact force-push preview without skipping confirmation.\",\n\t\t\t\t\t\taction: \"keep\",\n\t\t\t\t\t},\n\t\t\t\t\t{ id: \"cancel\", label: options.cancelLabel ?? \"Cancel\", action: \"cancel\" },\n\t\t\t\t],\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t\treview: ({ state }) => ({\n\t\t\t\tkind: \"review\",\n\t\t\t\ttitle: `Review synced content \u00B7 ${safeTerminalText(state.decision.setupName)}`,\n\t\t\t\tcontent: formatSelectionDifference(state.decision),\n\t\t\t\tformat: { kind: \"text\" },\n\t\t\t\tviewportSize: \"adaptive\",\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t\tsaved: ({ state }) => ({\n\t\t\t\tkind: \"actions\",\n\t\t\t\ttitle: \"Remote content list saved\",\n\t\t\t\tlines: [\n\t\t\t\t\t`Sync setup: ${safeTerminalText(state.decision.setupName)}`,\n\t\t\t\t\t\"Only the included-content setting was saved.\",\n\t\t\t\t\t\"No files were pulled and sync state was not changed.\",\n\t\t\t\t],\n\t\t\t\titems: [\n\t\t\t\t\t...(runRoute\n\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tid: \"continue\",\n\t\t\t\t\t\t\t\t\tlabel: continueLabel(origin),\n\t\t\t\t\t\t\t\t\tdescription: \"Start a fresh check and exact preview for this sync setup.\",\n\t\t\t\t\t\t\t\t\taction: \"continue\" as const,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t: []),\n\t\t\t\t\t{ id: \"done\", label: \"Done\", action: \"done\" },\n\t\t\t\t],\n\t\t\t\thint: \"close\",\n\t\t\t}),\n\t\t},\n\t\tactions: {\n\t\t\tadopt: async ({ state, signal: actionSignal }) => {\n\t\t\t\tconst signal = combineSignals(sessionSignal, actionSignal);\n\t\t\t\ttry {\n\t\t\t\t\tconst currentConfig = await loadConfig(state.decision.setupName);\n\t\t\t\t\tif (signal.aborted) return { kind: \"close\" as const };\n\t\t\t\t\tassertLocalSelectionCurrent(currentConfig, state.decision);\n\t\t\t\t\tif (\n\t\t\t\t\t\t!currentConfig.include.includes(\"sessions\") &&\n\t\t\t\t\t\tstate.decision.remoteInclude.includes(\"sessions\")\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst acknowledged = await ctx.ui.confirm(\n\t\t\t\t\t\t\t\"Use a content list that includes session conversations?\",\n\t\t\t\t\t\t\t\"Session JSONL may contain prompts, tool output, file paths, images, and secrets. This saves the list only; it does not pull files.\",\n\t\t\t\t\t\t\t{ signal },\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (signal.aborted) return { kind: \"close\" as const };\n\t\t\t\t\t\tif (!acknowledged) return { kind: \"stay\" as const };\n\t\t\t\t\t}\n\t\t\t\t\tconst review = await runWithOptionalStateAccess(options, async () => {\n\t\t\t\t\t\tconst loaded = await loadAdoptionReview(state.decision, signal, factory);\n\t\t\t\t\t\tif (signal.aborted) throw signal.reason;\n\t\t\t\t\t\tawait revalidateAndAdopt(loaded, state.decision, signal);\n\t\t\t\t\t\treturn loaded;\n\t\t\t\t\t});\n\t\t\t\t\tif (signal.aborted) return { kind: \"close\" as const };\n\t\t\t\t\toptions.onSelectionResolved?.();\n\t\t\t\t\tcontinuationReview = {\n\t\t\t\t\t\t...review.storageReview,\n\t\t\t\t\t\tsetupName: state.decision.setupName,\n\t\t\t\t\t\tinclude: [...state.decision.remoteInclude],\n\t\t\t\t\t\tautomatic: review.config.automatic,\n\t\t\t\t\t\tonSwitch: review.config.onSwitch,\n\t\t\t\t\t};\n\t\t\t\t\tflowState = { decision: state.decision, saved: true };\n\t\t\t\t\treturn { kind: \"to\" as const, screen: \"saved\" as const };\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (signal.aborted) return { kind: \"close\" as const };\n\t\t\t\t\tif (isStaleReviewError(error)) {\n\t\t\t\t\t\tctx.ui.notify(`${errorMessage(error)} Refreshing the comparison.`, \"warning\");\n\t\t\t\t\t\trefreshRequested = true;\n\t\t\t\t\t\treturn { kind: \"close\" as const };\n\t\t\t\t\t}\n\t\t\t\t\tctx.ui.notify(`Could not save the remote content list: ${errorMessage(error)}`, \"error\");\n\t\t\t\t\treturn { kind: \"stay\" as const };\n\t\t\t\t}\n\t\t\t},\n\t\t\tkeep: async ({ state, signal: actionSignal }) => {\n\t\t\t\tif (!runRoute) {\n\t\t\t\t\tctx.ui.notify(\"The reviewed update-remote route is unavailable.\", \"error\");\n\t\t\t\t\treturn { kind: \"stay\" as const };\n\t\t\t\t}\n\t\t\t\tconst signal = combineSignals(sessionSignal, actionSignal);\n\t\t\t\ttry {\n\t\t\t\t\tconst latest = await loadConfig(state.decision.setupName);\n\t\t\t\t\tif (signal.aborted) return { kind: \"close\" as const };\n\t\t\t\t\tassertLocalSelectionCurrent(latest, state.decision);\n\t\t\t\t\tconst result = await runCancellableOperation(\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\"Preparing this device's push preview\u2026\",\n\t\t\t\t\t\t\"push --force\",\n\t\t\t\t\t\trunRoute,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommitAware: true,\n\t\t\t\t\t\t\tcancelledMessage: \"Push preparation cancelled; no remote files were changed.\",\n\t\t\t\t\t\t\ttarget: state.decision.setupName,\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\treturn handleNestedRouteResult(result, \"push\");\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (signal.aborted) return { kind: \"close\" as const };\n\t\t\t\t\tif (isStaleReviewError(error)) {\n\t\t\t\t\t\tctx.ui.notify(`${errorMessage(error)} Refreshing the comparison.`, \"warning\");\n\t\t\t\t\t\trefreshRequested = true;\n\t\t\t\t\t\treturn { kind: \"close\" as const };\n\t\t\t\t\t}\n\t\t\t\t\tctx.ui.notify(`Could not prepare the remote update: ${errorMessage(error)}`, \"error\");\n\t\t\t\t\treturn { kind: \"stay\" as const };\n\t\t\t\t}\n\t\t\t},\n\t\t\tcontinue: async ({ state, signal: actionSignal }) => {\n\t\t\t\tif (!runRoute || !continuationReview) return { kind: \"stay\" as const };\n\t\t\t\tconst signal = combineSignals(sessionSignal, actionSignal);\n\t\t\t\ttry {\n\t\t\t\t\tconst latest = await loadPartialConfig(state.decision.setupName);\n\t\t\t\t\tif (signal.aborted) return { kind: \"close\" as const };\n\t\t\t\t\tif (!sameContinuationReview(latest, continuationReview)) {\n\t\t\t\t\t\tthrow new StaleRemoteSelectionReviewError(\n\t\t\t\t\t\t\t`Sync setup \u201C${safeTerminalText(state.decision.setupName)}\u201D changed after the remote content list was saved.`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tconst result = await runCancellableOperation(\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\tcontinueBusyLabel(origin),\n\t\t\t\t\t\troute,\n\t\t\t\t\t\trunRoute,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommitAware: true,\n\t\t\t\t\t\t\tcancelledMessage: continuationCancelledMessage(route),\n\t\t\t\t\t\t\ttarget: state.decision.setupName,\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\treturn handleNestedRouteResult(result, route);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (signal.aborted) return { kind: \"close\" as const };\n\t\t\t\t\tctx.ui.notify(`Could not continue: ${errorMessage(error)}`, \"error\");\n\t\t\t\t\treturn { kind: \"stay\" as const };\n\t\t\t\t}\n\t\t\t},\n\t\t\tcancel: async () => ({ kind: \"back\" }),\n\t\t\tdone: async () => {\n\t\t\t\tnextResult = { kind: \"done\" };\n\t\t\t\treturn { kind: \"close\" };\n\t\t\t},\n\t\t},\n\t});\n\n\tfunction handleNestedRouteResult(\n\t\tresult: Awaited<ReturnType<typeof runCancellableOperation>>,\n\t\tnestedRoute: \"sync\" | \"pull\" | \"push\",\n\t) {\n\t\tif (result.kind === \"completed\" && result.outcome === \"applied\") {\n\t\t\toptions.onSelectionResolved?.();\n\t\t}\n\t\tif (result.kind === \"closed\") {\n\t\t\tnextResult = { kind: \"closed\" };\n\t\t\treturn { kind: \"close\" as const };\n\t\t}\n\t\tif (\n\t\t\tresult.kind === \"cancelled\" ||\n\t\t\t(result.kind === \"completed\" && result.outcome === \"cancelled\") ||\n\t\t\tresult.kind === \"failed\"\n\t\t) {\n\t\t\treturn { kind: \"stay\" as const };\n\t\t}\n\t\tnextResult = { kind: \"route-result\", result, route: nestedRoute };\n\t\treturn { kind: \"close\" as const };\n\t}\n\n\tconst menuResult = await runMenu(ctx, menu, {\n\t\tgetState: () => flowState,\n\t\tsignal: sessionSignal,\n\t\tisCurrent: () => !sessionSignal?.aborted,\n\t\tonError: (_menuCtx, error) => ctx.ui.notify(errorMessage(error), \"error\"),\n\t});\n\tif (sessionSignal?.aborted || menuResult.kind === \"stale\") return { kind: \"stale\" };\n\tif (refreshRequested) return { kind: \"refresh\" };\n\tif (nextResult) return nextResult;\n\tif (menuResult.kind === \"closed\") {\n\t\treturn menuResult.reason === \"back\" ? { kind: \"back\" } : { kind: \"closed\" };\n\t}\n\treturn { kind: \"closed\" };\n}\n\ninterface AdoptionReview {\n\tconfig: AnySyncConfig;\n\tstorageReview: SyncSetupStorageReview;\n\tbackend: SyncBackend;\n\treviewedHead: RemoteHead;\n}\n\nasync function loadAdoptionReview(\n\tdecision: RemoteSelectionDecision,\n\tsignal: AbortSignal,\n\tfactory: SyncBackendFactory,\n): Promise<AdoptionReview> {\n\tconst config = await loadConfig(decision.setupName);\n\tthrowIfAborted(signal);\n\tassertLocalSelectionCurrent(config, decision);\n\tconst partial = await loadPartialConfig(decision.setupName);\n\tthrowIfAborted(signal);\n\tif (!sameSyncInclude(partial.include, decision.localInclude)) {\n\t\tthrow new StaleRemoteSelectionReviewError(\n\t\t\t`Sync setup \u201C${safeTerminalText(decision.setupName)}\u201D changed while the comparison was open.`,\n\t\t);\n\t}\n\tconst backend = await factory(config);\n\tthrowIfAborted(signal);\n\tconst reviewedHead = await backend.readHead(signal);\n\tthrowIfAborted(signal);\n\tif (!reviewedHead) {\n\t\tthrow new StaleRemoteSelectionReviewError(\n\t\t\t\"Remote storage changed while the comparison was open.\",\n\t\t);\n\t}\n\tconst snapshot = await readSnapshotForHead(backend, reviewedHead, signal);\n\tthrowIfAborted(signal);\n\tconst state = inspectRemoteSelection(config.include, snapshot);\n\tif (state.kind !== \"different\" || !sameSyncInclude(state.include, decision.remoteInclude)) {\n\t\tthrow new StaleRemoteSelectionReviewError(\n\t\t\t\"Remote synced content changed while the comparison was open.\",\n\t\t);\n\t}\n\treturn { config, storageReview: partial, backend, reviewedHead };\n}\n\nasync function revalidateAndAdopt(\n\treview: AdoptionReview,\n\tdecision: RemoteSelectionDecision,\n\tsignal: AbortSignal,\n) {\n\tconst currentHead = await review.backend.readHead(signal);\n\tthrowIfAborted(signal);\n\tif (\n\t\t!currentHead ||\n\t\t!review.backend.sameRevision(review.reviewedHead.revision, currentHead.revision)\n\t) {\n\t\tthrow new StaleRemoteSelectionReviewError(\n\t\t\t\"Remote storage changed while the comparison was open.\",\n\t\t);\n\t}\n\tconst currentSnapshot = await readSnapshotForHead(review.backend, currentHead, signal);\n\tthrowIfAborted(signal);\n\tconst currentState = inspectRemoteSelection(review.config.include, currentSnapshot);\n\tif (\n\t\tcurrentState.kind !== \"different\" ||\n\t\t!sameSyncInclude(currentState.include, decision.remoteInclude)\n\t) {\n\t\tthrow new StaleRemoteSelectionReviewError(\n\t\t\t\"Remote synced content changed while the comparison was open.\",\n\t\t);\n\t}\n\tawait updateSyncSetup(\n\t\tdecision.setupName,\n\t\t(setup) => ({\n\t\t\t...setup,\n\t\t\tsync: { ...setup.sync, include: [...decision.remoteInclude] },\n\t\t}),\n\t\t{\n\t\t\texpectedStorage: review.storageReview,\n\t\t\texpectedInclude: decision.localInclude,\n\t\t\tsignal,\n\t\t},\n\t);\n}\n\nasync function inspectConfiguredRemoteSelection(\n\tctx: ExtensionContext,\n\tsetupName: string | undefined,\n\tsignal: AbortSignal | undefined,\n\tfactory: SyncBackendFactory,\n): Promise<\n\t| { kind: \"empty\"; config: AnySyncConfig }\n\t| { kind: \"selection\"; config: AnySyncConfig; state: RemoteSelectionState }\n\t| undefined\n> {\n\tconst config = await loadConfig(setupName);\n\tif (signal?.aborted) return undefined;\n\tctx.ui.setStatus(STATUS_KEY, `checking synced content for ${safeTerminalText(config.setupName)}`);\n\tconst backend = await factory(config);\n\tif (signal?.aborted) return undefined;\n\tconst head = await backend.readHead(signal);\n\tif (signal?.aborted) return undefined;\n\tif (!head) return { kind: \"empty\", config };\n\tconst snapshot = await readSnapshotForHead(backend, head, signal);\n\tif (signal?.aborted) return undefined;\n\treturn {\n\t\tkind: \"selection\",\n\t\tconfig,\n\t\tstate: inspectRemoteSelection(config.include, snapshot),\n\t};\n}\n\nasync function showLegacyDiscovery(\n\tctx: ExtensionContext,\n\tconfig: AnySyncConfig,\n\tdiscovered: string[],\n\tsignal?: AbortSignal,\n) {\n\tconst menu = defineMenu<undefined, \"choice\" | \"review\", \"back\", ExtensionContext>({\n\t\tstart: \"choice\",\n\t\tscreens: {\n\t\t\tchoice: () => ({\n\t\t\t\tkind: \"actions\",\n\t\t\t\ttitle: `Compare synced content \u00B7 ${safeTerminalText(config.setupName)}`,\n\t\t\t\tlines: [\n\t\t\t\t\t\"This legacy snapshot has no portable synced-content list.\",\n\t\t\t\t\t\"Discovered paths are partial and read-only; preserved files may not have been selected.\",\n\t\t\t\t],\n\t\t\t\titems: [\n\t\t\t\t\t{ id: \"review\", label: \"Review discovered paths\", to: \"review\" },\n\t\t\t\t\t{ id: \"back\", label: \"Back\", action: \"back\" },\n\t\t\t\t],\n\t\t\t\thint: \"close\",\n\t\t\t}),\n\t\t\treview: () => ({\n\t\t\t\tkind: \"review\",\n\t\t\t\ttitle: \"Partial discovery from legacy snapshot\",\n\t\t\t\tcontent: [\n\t\t\t\t\t\"Partial discovery only \u2014 not an authoritative selection.\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t...(discovered.length > 0\n\t\t\t\t\t\t? discovered.map((item) => `Discovered: ${safeTerminalText(item)}`)\n\t\t\t\t\t\t: [\"No safe paths were discovered.\"]),\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Use Add custom path\u2026 in the local Included Content editor if needed.\",\n\t\t\t\t].join(\"\\n\"),\n\t\t\t\tformat: { kind: \"text\" },\n\t\t\t\tviewportSize: \"adaptive\",\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t},\n\t\tactions: { back: async () => ({ kind: \"close\" }) },\n\t});\n\tawait runMenu(ctx, menu, {\n\t\tgetState: () => undefined,\n\t\tsignal,\n\t\tisCurrent: () => !signal?.aborted,\n\t});\n}\n\nfunction selectionSummaryLines(decision: RemoteSelectionDecision) {\n\tconst comparison = compareSyncInclude(decision.localInclude, decision.remoteInclude);\n\treturn [\n\t\t`Sync setup: ${safeTerminalText(decision.setupName)}`,\n\t\t\"Nothing changed. Review both lists before choosing what happens next.\",\n\t\t...(comparison.remoteOnly.length === 0 && comparison.localOnly.length === 0\n\t\t\t? [\"Only the ordering differs; membership is the same.\"]\n\t\t\t: [\n\t\t\t\t\t`Remote-only paths: ${comparison.remoteOnly.length} \u00B7 Device-only paths: ${comparison.localOnly.length}`,\n\t\t\t\t]),\n\t];\n}\n\nfunction formatSelectionDifference(decision: RemoteSelectionDecision) {\n\tconst comparison = compareSyncInclude(decision.localInclude, decision.remoteInclude);\n\treturn [\n\t\t...(comparison.remoteOnly.length === 0 && comparison.localOnly.length === 0\n\t\t\t? [\"Only ordering differs; both lists contain the same paths.\", \"\"]\n\t\t\t: []),\n\t\t\"Remote-only paths:\",\n\t\t...(comparison.remoteOnly.length > 0\n\t\t\t? comparison.remoteOnly.map((item) => `+ ${safeTerminalText(item)}`)\n\t\t\t: [\"(none)\"]),\n\t\t\"\",\n\t\t\"Device-only paths:\",\n\t\t...(comparison.localOnly.length > 0\n\t\t\t? comparison.localOnly.map((item) => `- ${safeTerminalText(item)}`)\n\t\t\t: [\"(none)\"]),\n\t\t\"\",\n\t\t\"Remote ordered list:\",\n\t\t...(decision.remoteInclude.length > 0\n\t\t\t? decision.remoteInclude.map((item, index) => `${index + 1}. ${safeTerminalText(item)}`)\n\t\t\t: [\"(none)\"]),\n\t\t\"\",\n\t\t\"This device's ordered list:\",\n\t\t...(decision.localInclude.length > 0\n\t\t\t? decision.localInclude.map((item, index) => `${index + 1}. ${safeTerminalText(item)}`)\n\t\t\t: [\"(none)\"]),\n\t\t\"\",\n\t\t\"Using the remote list saves settings only and does not pull files.\",\n\t].join(\"\\n\");\n}\n\nfunction formatRemoteSelectionSummary(decision: RemoteSelectionDecision) {\n\tconst comparison = compareSyncInclude(decision.localInclude, decision.remoteInclude);\n\treturn [\n\t\t`Synced content for \u201C${safeTerminalText(decision.setupName)}\u201D differs from this device.`,\n\t\t`Remote-only: ${safeList(comparison.remoteOnly)}`,\n\t\t`Device-only: ${safeList(comparison.localOnly)}`,\n\t\t...(comparison.remoteOnly.length === 0 && comparison.localOnly.length === 0\n\t\t\t? [\n\t\t\t\t\t\"Only ordering differs.\",\n\t\t\t\t\t`Remote order: ${safeList(decision.remoteInclude)}`,\n\t\t\t\t\t`Device order: ${safeList(decision.localInclude)}`,\n\t\t\t\t]\n\t\t\t: []),\n\t\t\"Run /sync in TUI to choose a content list; RPC review is read-only.\",\n\t].join(\"\\n\");\n}\n\nfunction formatLegacySummary(config: AnySyncConfig, discovered: readonly string[]) {\n\treturn `Remote snapshot for \u201C${safeTerminalText(config.setupName)}\u201D has no portable synced-content list; ${discovered.length} safe path${discovered.length === 1 ? \" was\" : \"s were\"} discovered, but the result is partial and read-only.`;\n}\n\nfunction decisionFromState(\n\tconfig: AnySyncConfig,\n\tstate: Extract<RemoteSelectionState, { kind: \"different\" }>,\n): RemoteSelectionDecision {\n\treturn {\n\t\tsetupName: config.setupName,\n\t\tconfigIdentity: syncConfigReviewFingerprint(config),\n\t\tlocalInclude: [...config.include],\n\t\tremoteInclude: [...state.include],\n\t};\n}\n\nfunction assertLocalSelectionCurrent(config: AnySyncConfig, decision: RemoteSelectionDecision) {\n\tif (\n\t\tsyncConfigReviewFingerprint(config) === decision.configIdentity &&\n\t\tsameSyncInclude(config.include, decision.localInclude)\n\t) {\n\t\treturn;\n\t}\n\tthrow new StaleRemoteSelectionReviewError(\n\t\t`Sync setup \u201C${safeTerminalText(config.setupName)}\u201D changed while the comparison was open.`,\n\t);\n}\n\nfunction sameContinuationReview(left: PartialConfig, right: PartialConfig) {\n\treturn (\n\t\tleft.setupName === right.setupName &&\n\t\tleft.connectionName === right.connectionName &&\n\t\tleft.storageKind === right.storageKind &&\n\t\tleft.storagePath === right.storagePath &&\n\t\tleft.bucket === right.bucket &&\n\t\tleft.branch === right.branch &&\n\t\tsameSyncInclude(left.include, right.include)\n\t);\n}\n\nfunction continueLabel(origin: RemoteSelectionOrigin) {\n\tif (origin === \"pull\") return \"Continue Pull now\u2026\";\n\tif (origin === \"push\") return \"Continue Push now\u2026\";\n\treturn \"Continue Sync now\u2026\";\n}\n\nfunction continueBusyLabel(origin: RemoteSelectionOrigin) {\n\tif (origin === \"pull\") return \"Checking remote changes\u2026\";\n\tif (origin === \"push\") return \"Preparing push preview\u2026\";\n\treturn \"Checking current sync setup\u2026\";\n}\n\nfunction continuationCancelledMessage(route: \"sync\" | \"pull\" | \"push\") {\n\tif (route === \"pull\") return \"Pull check cancelled; no local files were changed.\";\n\tif (route === \"push\") return \"Push preparation cancelled; no remote files were changed.\";\n\treturn \"Sync check cancelled; no settings or files were changed.\";\n}\n\nfunction safeList(values: readonly string[]) {\n\treturn values.length > 0 ? values.map(safeTerminalText).join(\", \") : \"none\";\n}\n\nclass StaleRemoteSelectionReviewError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"StaleRemoteSelectionReviewError\";\n\t}\n}\n\nfunction isStaleReviewError(error: unknown) {\n\treturn (\n\t\terror instanceof StaleRemoteSelectionReviewError || error instanceof SyncSetupReviewChangedError\n\t);\n}\n\nfunction runWithOptionalStateAccess<T>(\n\toptions: Pick<RemoteSelectionReviewOptions, \"withStateAccess\">,\n\ttask: () => Promise<T>,\n) {\n\treturn options.withStateAccess ? options.withStateAccess(task) : task();\n}\n\nfunction combineSignals(sessionSignal: AbortSignal | undefined, actionSignal: AbortSignal) {\n\treturn sessionSignal ? AbortSignal.any([sessionSignal, actionSignal]) : actionSignal;\n}\n\nfunction throwIfAborted(signal: AbortSignal) {\n\tif (!signal.aborted) return;\n\tthrow signal.reason instanceof Error\n\t\t? signal.reason\n\t\t: new DOMException(\"The operation was aborted\", \"AbortError\");\n}\n", "import { BorderedLoader, type ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { Key, matchesKey, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport { formatInteractionHints, runCustomInteraction } from \"@narumitw/pi-tui-kit\";\nimport type { SetupPullOutcome } from \"../sync/setup-switch.js\";\nimport type { SyncDecision } from \"../sync/sync-decision.js\";\nimport type { RemoteSelectionDecision } from \"../sync/sync-policy.js\";\n\nexport type RunRouteResult =\n\t| { kind: \"completed\"; outcome?: SetupPullOutcome }\n\t| { kind: \"decision-required\"; decision: SyncDecision }\n\t| { kind: \"remote-selection-required\"; decision: RemoteSelectionDecision }\n\t| { kind: \"failed\" };\n\nexport type RunRoute = (\n\troute: string,\n\tsignal?: AbortSignal,\n\tonCommit?: () => void,\n\ttarget?: string,\n) => Promise<RunRouteResult | undefined>;\n\nexport type CancellableOperationResult =\n\t| RunRouteResult\n\t| { kind: \"closed\" }\n\t| { kind: \"cancelled\" };\n\ninterface CancellableOperationOptions {\n\tcommitAware?: boolean;\n\tcancelledMessage?: string | null;\n\ttarget?: string;\n\tsignal?: AbortSignal;\n}\n\nexport async function runCancellableOperation(\n\tctx: ExtensionContext,\n\tmessage: string,\n\troute: string,\n\trunRoute: RunRoute,\n\toptions: CancellableOperationOptions = {},\n): Promise<CancellableOperationResult> {\n\tconst {\n\t\tcommitAware = false,\n\t\tcancelledMessage = \"Check cancelled; no settings or files were changed.\",\n\t\ttarget,\n\t\tsignal,\n\t} = options;\n\tif (ctx.mode !== \"tui\") {\n\t\treturn (await runRoute(route, signal, undefined, target)) ?? { kind: \"failed\" };\n\t}\n\tlet commitStarted = false;\n\tlet routeResult: RunRouteResult | undefined;\n\tconst interaction = await runCustomInteraction<\n\t\t{ cancelled?: boolean; error?: unknown },\n\t\tExtensionContext\n\t>(ctx, {\n\t\tsignal,\n\t\tisCurrent: () => !signal?.aborted,\n\t\tcreate: ({ tui, theme, keybindings, signal: interactionSignal, complete }) => {\n\t\t\tconst loader = new BorderedLoader(tui, theme, message, { cancellable: false });\n\t\t\tconst cancelHint = formatInteractionHints(keybindings, [\n\t\t\t\t{\n\t\t\t\t\tkeys: [\n\t\t\t\t\t\t...keybindings.getKeys(\"tui.select.cancel\").filter((key) => !hasControlCharacter(key)),\n\t\t\t\t\t\t\"ctrl+c\",\n\t\t\t\t\t],\n\t\t\t\t\tlabel: \"cancel\",\n\t\t\t\t},\n\t\t\t]);\n\t\t\tconst operation = runRoute(\n\t\t\t\troute,\n\t\t\t\tinteractionSignal,\n\t\t\t\tcommitAware ? () => (commitStarted = true) : undefined,\n\t\t\t\ttarget,\n\t\t\t).then(\n\t\t\t\t(result) => {\n\t\t\t\t\trouteResult = result;\n\t\t\t\t\tcomplete({});\n\t\t\t\t},\n\t\t\t\t(error: unknown) => complete({ error }),\n\t\t\t);\n\t\t\treturn {\n\t\t\t\trender(width: number) {\n\t\t\t\t\tconst safeWidth = Math.max(1, width);\n\t\t\t\t\tconst lines = loader.render(safeWidth);\n\t\t\t\t\tconst bottomBorder = lines.at(-1);\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...lines.slice(0, -1),\n\t\t\t\t\t\ttruncateToWidth(theme.fg(\"dim\", cancelHint), safeWidth, \"\"),\n\t\t\t\t\t\t...(bottomBorder === undefined ? [] : [bottomBorder]),\n\t\t\t\t\t];\n\t\t\t\t},\n\t\t\t\tinvalidate: () => loader.invalidate(),\n\t\t\t\thandleInput(data: string) {\n\t\t\t\t\tif (!matchesKey(data, Key.ctrl(\"c\")) && !keybindings.matches(data, \"tui.select.cancel\")) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (commitStarted) {\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t\"Applying or publishing has started and cannot be cancelled safely.\",\n\t\t\t\t\t\t\t\"warning\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcomplete({ cancelled: true });\n\t\t\t\t},\n\t\t\t\tdispose: () => loader.dispose(),\n\t\t\t\twaitForPending: () => operation,\n\t\t\t};\n\t\t},\n\t});\n\tif (interaction.kind === \"error\") throw interaction.error;\n\tif (interaction.kind !== \"completed\") return { kind: \"closed\" };\n\tif (interaction.value.cancelled) {\n\t\tif (cancelledMessage) ctx.ui.notify(cancelledMessage, \"info\");\n\t\treturn { kind: \"cancelled\" };\n\t}\n\tif (interaction.value.error) throw interaction.value.error;\n\treturn routeResult ?? { kind: \"failed\" };\n}\n\nfunction hasControlCharacter(value: string) {\n\t// biome-ignore lint/suspicious/noControlCharactersInRegex: Unsafe key labels must be omitted.\n\treturn /[\\u0000-\\u001f\\u007f-\\u009f]/u.test(value);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -3,7 +3,7 @@
3
3
  import {
4
4
  runCancellableOperation,
5
5
  showRemoteSelectionReview
6
- } from "./chunk-4CHTZMEO.ts";
6
+ } from "./chunk-YDWUZVPN.ts";
7
7
  import {
8
8
  safeTerminalText
9
9
  } from "./chunk-LTBWGSBV.ts";
@@ -212,4 +212,4 @@ async function dispatchManagerResult(ctx, initialResult, origin, runRoute, signa
212
212
  export {
213
213
  dispatchManagerResult
214
214
  };
215
- //# sourceMappingURL=chunk-G4RNQQZS.ts.map
215
+ //# sourceMappingURL=chunk-YHEMENKV.ts.map
@@ -2,8 +2,8 @@
2
2
  // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
3
  import {
4
4
  dispatchManagerResult
5
- } from "./chunk-G4RNQQZS.ts";
6
- import "./chunk-4CHTZMEO.ts";
5
+ } from "./chunk-YHEMENKV.ts";
6
+ import "./chunk-YDWUZVPN.ts";
7
7
  import "./chunk-HUDQATCL.ts";
8
8
  import "./chunk-T2B5IU74.ts";
9
9
  import "./chunk-LTBWGSBV.ts";
@@ -19,4 +19,4 @@ import "./chunk-JAAKLL6M.ts";
19
19
  export {
20
20
  dispatchManagerResult
21
21
  };
22
- //# sourceMappingURL=manager-result-dispatcher-FKIBM3GO.ts.map
22
+ //# sourceMappingURL=manager-result-dispatcher-ASKGOSW5.ts.map
@@ -2,10 +2,10 @@
2
2
  // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
3
  import {
4
4
  dispatchManagerResult
5
- } from "./chunk-G4RNQQZS.ts";
5
+ } from "./chunk-YHEMENKV.ts";
6
6
  import {
7
7
  runCancellableOperation
8
- } from "./chunk-4CHTZMEO.ts";
8
+ } from "./chunk-YDWUZVPN.ts";
9
9
  import {
10
10
  SETUP_SWITCH_ACTION_OPTIONS,
11
11
  saveOnSwitch,
@@ -49,7 +49,7 @@ import {
49
49
  showEditS3Target,
50
50
  showEditWebDavStorageProfile,
51
51
  showEditWebDavTarget
52
- } from "./chunk-KW7YQEZN.ts";
52
+ } from "./chunk-DHVFS4QK.ts";
53
53
  import {
54
54
  automaticSyncSummary
55
55
  } from "./chunk-Z4DQF6L3.ts";
@@ -164,7 +164,7 @@ function blockedSyncMenuItem(label, manager) {
164
164
  };
165
165
  }
166
166
  async function showManagerAttention(ctx, attention, runRoute, signal, onSelectionResolved) {
167
- const { showRemoteSelectionReview } = await import("./remote-selection-ui-D7RBRJNL.ts");
167
+ const { showRemoteSelectionReview } = await import("./remote-selection-ui-QDNR7WEI.ts");
168
168
  if (signal?.aborted) return "close";
169
169
  const review = await showRemoteSelectionReview(
170
170
  ctx,
@@ -767,7 +767,7 @@ async function showSyncSettings(ctx, runRoute, signal) {
767
767
  },
768
768
  "remote-include": async ({ signal: actionSignal }) => {
769
769
  const reviewSignal = signal ? AbortSignal.any([signal, actionSignal]) : actionSignal;
770
- const { showRemoteSelectionReview } = await import("./remote-selection-ui-D7RBRJNL.ts");
770
+ const { showRemoteSelectionReview } = await import("./remote-selection-ui-QDNR7WEI.ts");
771
771
  if (reviewSignal.aborted) return { kind: "rejected" };
772
772
  const review = await showRemoteSelectionReview(ctx, setupName, reviewSignal, void 0, {
773
773
  origin: "settings",
@@ -1452,7 +1452,7 @@ async function showSyncManager(ctx, runRoute, sessionSignal, options = {}) {
1452
1452
  if (!attention) {
1453
1453
  const observation = options.getObservation?.();
1454
1454
  if (!observation) return { kind: "stay" };
1455
- const { showRemoteSelectionReview } = await import("./remote-selection-ui-D7RBRJNL.ts");
1455
+ const { showRemoteSelectionReview } = await import("./remote-selection-ui-QDNR7WEI.ts");
1456
1456
  if (sessionSignal?.aborted) return { kind: "close" };
1457
1457
  const config = await loadConfig();
1458
1458
  if (sessionSignal?.aborted) return { kind: "close" };
@@ -1677,4 +1677,4 @@ function syncMainMenuItem(label) {
1677
1677
  export {
1678
1678
  showSyncManager
1679
1679
  };
1680
- //# sourceMappingURL=manager-ui-5KLKVMRC.ts.map
1680
+ //# sourceMappingURL=manager-ui-IPAOAWZA.ts.map
@@ -2,7 +2,7 @@
2
2
  // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
3
  import {
4
4
  showRemoteSelectionReview
5
- } from "./chunk-4CHTZMEO.ts";
5
+ } from "./chunk-YDWUZVPN.ts";
6
6
  import "./chunk-HUDQATCL.ts";
7
7
  import "./chunk-T2B5IU74.ts";
8
8
  import "./chunk-LTBWGSBV.ts";
@@ -18,4 +18,4 @@ import "./chunk-JAAKLL6M.ts";
18
18
  export {
19
19
  showRemoteSelectionReview
20
20
  };
21
- //# sourceMappingURL=remote-selection-ui-D7RBRJNL.ts.map
21
+ //# sourceMappingURL=remote-selection-ui-QDNR7WEI.ts.map
@@ -5,7 +5,7 @@ import {
5
5
  showGitSetup,
6
6
  showS3Setup,
7
7
  showWebDavSetup
8
- } from "./chunk-KW7YQEZN.ts";
8
+ } from "./chunk-DHVFS4QK.ts";
9
9
  import "./chunk-Z4DQF6L3.ts";
10
10
  import "./chunk-CHH26D4F.ts";
11
11
  import {
@@ -86,4 +86,4 @@ async function showSetupWizard(ctx, signal) {
86
86
  export {
87
87
  showSetupWizard
88
88
  };
89
- //# sourceMappingURL=setup-wizard-IUB6ESEU.ts.map
89
+ //# sourceMappingURL=setup-wizard-JUJZYNNM.ts.map
package/dist/index.ts CHANGED
@@ -264,7 +264,7 @@ async function initConfig(ctx, signal) {
264
264
  return;
265
265
  }
266
266
  if (ctx.mode === "tui") {
267
- const { showSetupWizard } = await import("./chunks/setup-wizard-IUB6ESEU.ts");
267
+ const { showSetupWizard } = await import("./chunks/setup-wizard-JUJZYNNM.ts");
268
268
  throwIfAborted(signal);
269
269
  await showSetupWizard(ctx, signal);
270
270
  return;
@@ -368,7 +368,7 @@ async function handleCommand(rawArgs, ctx, sessionSignal, loaders, attention) {
368
368
  );
369
369
  if (!rawArgs.trim()) {
370
370
  try {
371
- const { showSyncManager } = await import("./chunks/manager-ui-5KLKVMRC.ts");
371
+ const { showSyncManager } = await import("./chunks/manager-ui-IPAOAWZA.ts");
372
372
  if (sessionSignal.aborted) return;
373
373
  await showSyncManager(ctx, run, sessionSignal, {
374
374
  getAttention: () => attention.current(),
@@ -470,7 +470,7 @@ function directSelectionOrigin(rawArgs) {
470
470
  async function resolveSelectionAttention(ctx, attention, signal, loaders, options = {}) {
471
471
  const current = attention.current();
472
472
  if (!current || signal.aborted) return;
473
- const { dispatchManagerResult } = await import("./chunks/manager-result-dispatcher-FKIBM3GO.ts");
473
+ const { dispatchManagerResult } = await import("./chunks/manager-result-dispatcher-ASKGOSW5.ts");
474
474
  if (signal.aborted || attention.current() !== current) return;
475
475
  await dispatchManagerResult(
476
476
  ctx,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@narumitw/pi-sync",
3
- "version": "0.50.2",
3
+ "version": "0.50.3",
4
4
  "description": "Pi extension that syncs Pi configuration through Git, WebDAV, Cloudflare R2, or S3-compatible storage.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,14 +1,9 @@
1
- import {
2
- BorderedLoader,
3
- type ExtensionContext,
4
- type KeybindingsManager,
5
- } from "@earendil-works/pi-coding-agent";
1
+ import { BorderedLoader, type ExtensionContext } from "@earendil-works/pi-coding-agent";
6
2
  import { Key, matchesKey, truncateToWidth } from "@earendil-works/pi-tui";
7
- import { runCustomInteraction } from "@narumitw/pi-tui-kit";
3
+ import { formatInteractionHints, runCustomInteraction } from "@narumitw/pi-tui-kit";
8
4
  import type { SetupPullOutcome } from "../sync/setup-switch.js";
9
5
  import type { SyncDecision } from "../sync/sync-decision.js";
10
6
  import type { RemoteSelectionDecision } from "../sync/sync-policy.js";
11
- import { safeTerminalText } from "./terminal-text.js";
12
7
 
13
8
  export type RunRouteResult =
14
9
  | { kind: "completed"; outcome?: SetupPullOutcome }
@@ -61,7 +56,15 @@ export async function runCancellableOperation(
61
56
  isCurrent: () => !signal?.aborted,
62
57
  create: ({ tui, theme, keybindings, signal: interactionSignal, complete }) => {
63
58
  const loader = new BorderedLoader(tui, theme, message, { cancellable: false });
64
- const cancelHint = `${keybindingText(keybindings, "tui.select.cancel", "esc")} cancel`;
59
+ const cancelHint = formatInteractionHints(keybindings, [
60
+ {
61
+ keys: [
62
+ ...keybindings.getKeys("tui.select.cancel").filter((key) => !hasControlCharacter(key)),
63
+ "ctrl+c",
64
+ ],
65
+ label: "cancel",
66
+ },
67
+ ]);
65
68
  const operation = runRoute(
66
69
  route,
67
70
  interactionSignal,
@@ -114,18 +117,7 @@ export async function runCancellableOperation(
114
117
  return routeResult ?? { kind: "failed" };
115
118
  }
116
119
 
117
- function keybindingText(
118
- keybindings: Pick<KeybindingsManager, "getKeys">,
119
- binding: Parameters<KeybindingsManager["getKeys"]>[0],
120
- fallback: string,
121
- ) {
122
- const keys = [...new Set([...keybindings.getKeys(binding), "ctrl+c"])]
123
- .map(String)
124
- .map((key) => {
125
- if (key === "return") return "enter";
126
- if (key === "escape") return "esc";
127
- return safeTerminalText(key);
128
- })
129
- .filter(Boolean);
130
- return keys.join("/") || fallback;
120
+ function hasControlCharacter(value: string) {
121
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: Unsafe key labels must be omitted.
122
+ return /[\u0000-\u001f\u007f-\u009f]/u.test(value);
131
123
  }
@@ -9,7 +9,7 @@ import {
9
9
  Text,
10
10
  truncateToWidth,
11
11
  } from "@earendil-works/pi-tui";
12
- import { runCustomInteraction } from "@narumitw/pi-tui-kit";
12
+ import { formatInteractionHints, runCustomInteraction } from "@narumitw/pi-tui-kit";
13
13
 
14
14
  const MASK = "•";
15
15
 
@@ -25,13 +25,22 @@ export async function promptSecret(
25
25
  create: ({ tui, theme, keybindings, complete }) => {
26
26
  const heading = new Text("", 0, 0);
27
27
  const hint = new Text("", 0, 0);
28
- const submitKey = keybindingText(keybindings, "tui.input.submit", "enter");
29
- const cancelKey = keybindingText(keybindings, "tui.select.cancel", "esc", ["ctrl+c"]);
28
+ const interactionHint = formatInteractionHints(keybindings, [
29
+ {
30
+ keys: keybindings.getKeys("tui.input.submit").filter((key) => !hasControlCharacter(key)),
31
+ label: "continue",
32
+ },
33
+ {
34
+ keys: [
35
+ ...keybindings.getKeys("tui.select.cancel").filter((key) => !hasControlCharacter(key)),
36
+ "ctrl+c",
37
+ ],
38
+ label: "cancel",
39
+ },
40
+ ]);
30
41
  const applyTheme = () => {
31
42
  heading.setText(theme.fg("accent", theme.bold(title)));
32
- hint.setText(
33
- theme.fg("dim", `${submitKey} continue • ${cancelKey} cancel • Input is hidden`),
34
- );
43
+ hint.setText(theme.fg("dim", `${interactionHint} • Input is hidden`));
35
44
  };
36
45
  applyTheme();
37
46
  const input = new MaskedInput(keybindings);
@@ -212,23 +221,6 @@ class MaskedInput implements Focusable {
212
221
  }
213
222
  }
214
223
 
215
- function keybindingText(
216
- keybindings: Pick<KeybindingsManager, "getKeys">,
217
- binding: Parameters<KeybindingsManager["getKeys"]>[0],
218
- fallback: string,
219
- additionalKeys: readonly string[] = [],
220
- ) {
221
- const keys = [...new Set([...keybindings.getKeys(binding), ...additionalKeys])]
222
- .map(String)
223
- .map((key) => {
224
- if (key === "return") return "enter";
225
- if (key === "escape") return "esc";
226
- return hasControlCharacter(key) ? "" : key;
227
- })
228
- .filter(Boolean);
229
- return keys.join("/") || fallback;
230
- }
231
-
232
224
  function hasControlCharacter(value: string) {
233
225
  return [...value].some((character) => {
234
226
  const code = character.codePointAt(0) ?? 0;
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/commands/setup-completions.ts", "../../src/ui/setup/text-input.ts", "../../src/ui/setup/setup-location-ui.ts", "../../src/ui/setup/setup-prompts.ts", "../../src/ui/setup/setup-review.ts", "../../src/ui/setup/git-ui.ts", "../../src/ui/secret-input.ts", "../../src/ui/setup/s3-credentials-ui.ts", "../../src/ui/setup/s3-ui.ts", "../../src/ui/setup/webdav-ui.ts"],
4
- "sourcesContent": ["import { configuredSyncSetupNames } from \"../settings/settings-store.js\";\nimport { setSyncSetupCompletions } from \"./command.js\";\n\nexport async function refreshTargetCompletions() {\n\tsetSyncSetupCompletions(await configuredSyncSetupNames());\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { normalizeS3Bucket, requiredString } from \"../../settings/settings-validation.js\";\nimport { errorMessage } from \"../../sync/sync-errors.js\";\nimport { safeTerminalText } from \"../terminal-text.js\";\n\nexport type ValidateInput = (value: string) => string | Promise<string>;\n\nexport async function requiredExistingBucket(\n\tctx: ExtensionCommandContext,\n\texample: string,\n\tsignal?: AbortSignal,\n) {\n\treturn requiredValueInput(\n\t\tctx,\n\t\t\"Existing bucket\\n\\nThe bucket must already exist; pi-sync will not create it.\",\n\t\texample,\n\t\tsignal,\n\t\tnormalizeS3Bucket,\n\t);\n}\n\nexport async function requiredInput(\n\tctx: ExtensionCommandContext,\n\ttitle: string,\n\tdefaultValue: string,\n\tsignal?: AbortSignal,\n\tvalidate?: ValidateInput,\n) {\n\treturn promptTextInput(ctx, title, { defaultValue, validate, rejectPlaceholders: true }, signal);\n}\n\nexport async function requiredValueInput(\n\tctx: ExtensionCommandContext,\n\ttitle: string,\n\texample: string,\n\tsignal?: AbortSignal,\n\tvalidate?: ValidateInput,\n) {\n\treturn promptTextInput(ctx, title, { example, validate, rejectPlaceholders: true }, signal);\n}\n\nexport async function promptTextInput(\n\tctx: ExtensionCommandContext,\n\ttitle: string,\n\toptions: {\n\t\tdefaultValue?: string;\n\t\texample?: string;\n\t\tvalidate?: ValidateInput;\n\t\trejectPlaceholders?: boolean;\n\t},\n\tsignal?: AbortSignal,\n) {\n\t// Pi ignores placeholders. Keep defaults/examples visible; only an explicit blank accepts a default.\n\tconst hint =\n\t\toptions.defaultValue !== undefined\n\t\t\t? `Default: ${safeTerminalText(options.defaultValue)} (leave blank to keep)`\n\t\t\t: `Example: ${safeTerminalText(options.example ?? \"\")}\\nEnter your own value; this example is not a default.`;\n\twhile (true) {\n\t\tsignal?.throwIfAborted();\n\t\tconst value = await ctx.ui.input(`${title}\\n\\n${hint}`, undefined, { signal });\n\t\tsignal?.throwIfAborted();\n\t\tif (value === undefined) return undefined;\n\t\ttry {\n\t\t\tconst normalized = value.trim() || options.defaultValue;\n\t\t\tif (!normalized) throw new Error(`${title.split(\"\\n\")[0]} is required.`);\n\t\t\tif (options.rejectPlaceholders && /[<>]/u.test(normalized)) {\n\t\t\t\tthrow new Error(\"Replace example placeholders such as <account-id> with your own value.\");\n\t\t\t}\n\t\t\tconst checked = requiredString(normalized, title.split(\"\\n\")[0] ?? \"value\");\n\t\t\tconst result = options.validate ? await options.validate(checked) : checked;\n\t\t\tsignal?.throwIfAborted();\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tsignal?.throwIfAborted();\n\t\t\tctx.ui.notify(`${errorMessage(error)} Enter a corrected value, or cancel.`, \"warning\");\n\t\t}\n\t}\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { normalizeGitBranch } from \"../../backends/git/git-config.js\";\nimport { readLocalConfigObject } from \"../../settings/settings-store.js\";\nimport type {\n\tStorageConnectionSettings,\n\tSyncSetupSettings,\n} from \"../../settings/settings-types.js\";\nimport {\n\teffectiveSyncSetupRemoteIdentity,\n\tnormalizeStoragePath,\n\townRecord,\n} from \"../../settings/settings-validation.js\";\nimport { errorMessage } from \"../../sync/sync-errors.js\";\nimport { safeTerminalText } from \"../terminal-text.js\";\nimport {\n\tpromptTextInput,\n\trequiredExistingBucket,\n\trequiredInput,\n\trequiredValueInput,\n} from \"./text-input.js\";\n\ninterface ChosenRemoteLocation {\n\tconnectionName: string;\n\tbucket: string;\n\tpath: string;\n}\n\nexport async function chooseInitialRemoteLocation(\n\tctx: ExtensionCommandContext,\n\t_preset: string,\n\tsetupName: string,\n\tsignal?: AbortSignal,\n): Promise<ChosenRemoteLocation | undefined> {\n\tconst choice = await ctx.ui.select(\n\t\t\"Choose storage location\\n\\nUse an existing bucket. ./ stores snapshots at the bucket root; a custom path keeps them in a separate folder.\",\n\t\t[\"Use an existing bucket at ./\", \"Customize remote location\", \"Cancel\"],\n\t\t{ signal },\n\t);\n\tif (signal?.aborted || !choice || choice === \"Cancel\") return undefined;\n\tif (choice === \"Customize remote location\")\n\t\treturn chooseCustomRemoteLocation(ctx, setupName, signal);\n\tconst bucket = await requiredExistingBucket(ctx, \"pi-sync\", signal);\n\treturn bucket ? { connectionName: setupName, bucket, path: \"./\" } : undefined;\n}\n\nexport async function chooseAdditionalRemoteLocation(\n\tctx: ExtensionCommandContext,\n\tsettings: Record<string, unknown>,\n\tconnectionName: string,\n\tsetupName: string,\n\tsignal?: AbortSignal,\n): Promise<Omit<ChosenRemoteLocation, \"connectionName\"> | undefined> {\n\tconst setups = ownRecord(settings.syncSetups) ?? {};\n\tconst currentSetup =\n\t\ttypeof settings.activeSyncSetup === \"string\" ? settings.activeSyncSetup : undefined;\n\tconst candidates = Object.entries(setups)\n\t\t.map(([name, value]) => ({ name, storage: ownRecord(ownRecord(value)?.storage) }))\n\t\t.filter(\n\t\t\t(item): item is { name: string; storage: Record<string, unknown> } =>\n\t\t\t\titem.storage?.connection === connectionName && typeof item.storage.bucket === \"string\",\n\t\t);\n\tconst source =\n\t\tcandidates.find((item) => item.name === currentSetup) ??\n\t\tcandidates.sort((left, right) => left.name.localeCompare(right.name))[0];\n\tif (source) {\n\t\tconst suggestedPath = \"./\";\n\t\tconst sameBucketLabel = `Same bucket as \u201C${safeTerminalText(source.name)}\u201D`;\n\t\tconst choice = await ctx.ui.select(\n\t\t\t[\n\t\t\t\t`Storage location for \u201C${safeTerminalText(setupName)}\u201D`,\n\t\t\t\t\"\",\n\t\t\t\t`Existing bucket: ${safeTerminalText(String(source.storage.bucket))}`,\n\t\t\t\t`Remote path: ${safeTerminalText(suggestedPath)}`,\n\t\t\t\t\"./ uses the bucket root. Use a different path or bucket for independent setups.\",\n\t\t\t].join(\"\\n\"),\n\t\t\t[sameBucketLabel, \"Use a different bucket\", \"Customize remote location\", \"Cancel\"],\n\t\t\t{ signal },\n\t\t);\n\t\tif (signal?.aborted || !choice || choice === \"Cancel\") return undefined;\n\t\tif (choice === sameBucketLabel) {\n\t\t\treturn { bucket: String(source.storage.bucket), path: suggestedPath };\n\t\t}\n\t\tif (choice === \"Use a different bucket\") {\n\t\t\tconst bucket = await requiredExistingBucket(ctx, \"pi-sync\", signal);\n\t\t\treturn bucket ? { bucket, path: \"./\" } : undefined;\n\t\t}\n\t\tconst custom = await chooseCustomRemoteLocation(ctx, connectionName, signal);\n\t\treturn custom ? { bucket: custom.bucket, path: custom.path } : undefined;\n\t}\n\n\tconst location = await chooseInitialRemoteLocation(ctx, \"S3\", setupName, signal);\n\treturn location ? { bucket: location.bucket, path: location.path } : undefined;\n}\n\nasync function chooseCustomRemoteLocation(\n\tctx: ExtensionCommandContext,\n\tconnectionName: string,\n\tsignal?: AbortSignal,\n): Promise<ChosenRemoteLocation | undefined> {\n\tconst bucket = await requiredExistingBucket(ctx, \"pi-sync\", signal);\n\tif (!bucket) return undefined;\n\tconst storagePath = await requiredInput(\n\t\tctx,\n\t\t\"Storage path\\n\\nPath inside the bucket, not your local filesystem.\\n./ uses the bucket root. Use different paths for independent setups.\",\n\t\t\"./\",\n\t\tsignal,\n\t\tnormalizeStoragePath,\n\t);\n\tif (!storagePath) return undefined;\n\treturn { connectionName, bucket, path: normalizeStoragePath(storagePath) };\n}\n\n/** Early UI check only; the settings writer still validates uniqueness under its lock. */\nexport async function promptAvailableSetupStorage<T extends SyncSetupSettings[\"storage\"]>(\n\tctx: ExtensionCommandContext,\n\tinitial: T,\n\tsignal?: AbortSignal,\n): Promise<T | undefined> {\n\tlet storage = initial;\n\twhile (!signal?.aborted) {\n\t\tconst settings = await readLocalConfigObject();\n\t\tif (signal?.aborted) return undefined;\n\t\tconst connection = settings?.storageConnections[storage.connection];\n\t\tif (!settings || !connection) throw new Error(\"Storage connection changed; reopen setup.\");\n\t\tconst identity = setupPublicationIdentity(storage, connection);\n\t\tconst occupied = Object.entries(settings.syncSetups).find(\n\t\t\t([, setup]) =>\n\t\t\t\tsetupPublicationIdentity(\n\t\t\t\t\tsetup.storage,\n\t\t\t\t\tsettings.storageConnections[setup.storage.connection],\n\t\t\t\t) === identity,\n\t\t);\n\t\tif (!occupied) return storage;\n\t\tconst git = connection.type === \"git\";\n\t\tconst message = `${git ? \"Git branch\" : \"Storage location\"} is already used by \u201C${safeTerminalText(occupied[0])}\u201D. ${git ? \"Use a different branch; pi-sync owns the entire branch.\" : \"Enter a different storage path, or cancel to choose another connection or bucket.\"}`;\n\t\tctx.ui.notify(message, \"warning\");\n\t\tconst title = `${git ? \"Git branch for the new setup\" : \"Storage path for the new setup\"}\\n\\n${message}`;\n\t\tconst example = git ? \"pi-sync/work\" : \"backups/work\";\n\t\tconst value =\n\t\t\tconnection.type === \"webdav\"\n\t\t\t\t? await promptTextInput(ctx, title, { example }, signal)\n\t\t\t\t: await requiredValueInput(ctx, title, example, signal);\n\t\tif (signal?.aborted || value === undefined) return undefined;\n\t\ttry {\n\t\t\tstorage = git\n\t\t\t\t? { ...storage, branch: normalizeGitBranch(value) }\n\t\t\t\t: { ...storage, path: normalizeStoragePath(value) };\n\t\t} catch (error) {\n\t\t\tctx.ui.notify(safeTerminalText(errorMessage(error)), \"warning\");\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction setupPublicationIdentity(\n\tstorage: SyncSetupSettings[\"storage\"],\n\tconnection: StorageConnectionSettings,\n) {\n\t// Git publications own a complete branch tree; changing only its directory is not isolation.\n\treturn effectiveSyncSetupRemoteIdentity(\n\t\t{\n\t\t\tstorage: connection.type === \"git\" ? { ...storage, path: \"./\" } : storage,\n\t\t\tsync: { include: [], automatic: false },\n\t\t},\n\t\tconnection,\n\t);\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { readLocalConfigObject } from \"../../settings/settings-store.js\";\nimport { validateConfigName } from \"../../settings/settings-validation.js\";\nimport { DEFAULT_SYNC_INCLUDE } from \"../../sync/sync-policy.js\";\nimport { safeTerminalText } from \"../terminal-text.js\";\nimport { promptTextInput } from \"./text-input.js\";\n\nexport async function readSetupConnection(name: string, signal?: AbortSignal) {\n\tconst connection = (await readLocalConfigObject())?.storageConnections[name];\n\tsignal?.throwIfAborted();\n\tif (!connection) throw new Error(\"Storage connection changed; reopen setup.\");\n\treturn connection;\n}\n\nexport const AUTOMATIC_SYNC_DESCRIPTION =\n\t\"Check the current setup in the background at startup; review changes in /sync before transferring. At shutdown, automatically push selected content only when sessions are included. No startup dialogs.\";\n\nexport async function chooseSetupContent(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n\tconst choice = await ctx.ui.select(\n\t\t\"Choose included content\\n\\nRecommended: Pi settings, instructions, skills, prompts, themes, and extensions.\\nMinimal: settings.json and AGENTS.md.\\nReview the exact paths before saving.\",\n\t\t[\"Recommended Pi settings\", \"Minimal settings\", \"Cancel\"],\n\t\t{ signal },\n\t);\n\tsignal?.throwIfAborted();\n\tif (!choice || choice === \"Cancel\") return undefined;\n\treturn choice === \"Minimal settings\" ? [\"settings.json\", \"AGENTS.md\"] : [...DEFAULT_SYNC_INCLUDE];\n}\n\nexport async function chooseAutomaticSync(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n\tconst choice = await ctx.ui.select(\n\t\t`Automatic sync for this setup\\n\\n${AUTOMATIC_SYNC_DESCRIPTION}`,\n\t\t[\"Keep automatic sync off\", \"Enable automatic sync\", \"Cancel\"],\n\t\t{ signal },\n\t);\n\tsignal?.throwIfAborted();\n\treturn !choice || choice === \"Cancel\" ? undefined : choice === \"Enable automatic sync\";\n}\n\nexport async function chooseSessions(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n\tconst choice = await ctx.ui.select(\n\t\t\"Session conversations\\n\\nSessions can contain prompts, tool output, paths, screenshots, and secrets.\",\n\t\t[\"Keep sessions off (recommended)\", \"Include session conversations\", \"Cancel\"],\n\t\t{ signal },\n\t);\n\tsignal?.throwIfAborted();\n\tif (!choice || choice === \"Cancel\") return undefined;\n\tif (choice !== \"Include session conversations\") return false;\n\tconst confirmed = await ctx.ui.confirm(\n\t\t\"Include session conversations?\",\n\t\t\"I understand that session JSONL can contain prompts, tool output, paths, screenshots, and secrets.\",\n\t\t{ signal },\n\t);\n\tsignal?.throwIfAborted();\n\treturn confirmed ? true : undefined;\n}\n\nexport function includedContentLines(include: readonly string[], sessions = false) {\n\tconst paths = [...include, ...(sessions && !include.includes(\"sessions\") ? [\"sessions\"] : [])];\n\treturn [\n\t\t`Included content: ${paths.length} paths`,\n\t\t...paths.map((item) => ` ${safeTerminalText(item)}`),\n\t\t`Sessions: ${sessions ? \"On \u2014 privacy warning acknowledged\" : \"Off\"}`,\n\t];\n}\n\nexport async function promptResourceName(\n\tctx: ExtensionCommandContext,\n\tkind: \"sync setup\" | \"storage connection\",\n\tdefaultValue: string,\n\tsignal?: AbortSignal,\n\tliteralBrackets = false,\n) {\n\treturn promptTextInput(\n\t\tctx,\n\t\t`Name this ${kind}\\n\\nA local label, such as home or work.`,\n\t\t{\n\t\t\tdefaultValue,\n\t\t\trejectPlaceholders: !literalBrackets,\n\t\t\tvalidate: async (name) => {\n\t\t\t\tvalidateConfigName(name, kind);\n\t\t\t\tconst settings = await readLocalConfigObject();\n\t\t\t\tsignal?.throwIfAborted();\n\t\t\t\tconst names = kind === \"sync setup\" ? settings?.syncSetups : settings?.storageConnections;\n\t\t\t\tif (names && Object.hasOwn(names, name)) {\n\t\t\t\t\tthrow new Error(`A ${kind} with this name already exists. Choose a different name.`);\n\t\t\t\t}\n\t\t\t\treturn name;\n\t\t\t},\n\t\t},\n\t\tsignal,\n\t);\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { defineMenu, runMenu } from \"@narumitw/pi-tui-kit\";\nimport { syncErrorGuidance } from \"../../sync/sync-error-guidance.js\";\n\n/** A settings draft is committed only after review; retryable I/O failures retain the same draft. */\nexport async function saveReviewedDraft(\n\tctx: ExtensionCommandContext,\n\ttitle: string,\n\tlines: readonly string[],\n\tlabel: string,\n\tsave: (signal: AbortSignal) => Promise<unknown>,\n\tsignal?: AbortSignal,\n) {\n\tlet saved = false;\n\tlet failure: unknown;\n\tlet failureText: string | undefined;\n\tconst menu = defineMenu<undefined, \"review\", \"save\", ExtensionCommandContext>({\n\t\tstart: \"review\",\n\t\tscreens: {\n\t\t\treview: () => ({\n\t\t\t\tkind: \"review\",\n\t\t\t\ttitle,\n\t\t\t\tcontent: [...(failureText ? [failureText, \"\"] : []), ...lines].join(\"\\n\"),\n\t\t\t\tlines: [\"Review before saving. Back cancels this draft.\"],\n\t\t\t\tformat: { kind: \"text\" },\n\t\t\t\tviewportSize: \"adaptive\",\n\t\t\t\tconfirm: { id: \"save\", label, action: \"save\" },\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t},\n\t\tactions: {\n\t\t\tsave: async ({ signal: actionSignal }) => {\n\t\t\t\ttry {\n\t\t\t\t\tactionSignal.throwIfAborted();\n\t\t\t\t\tawait save(actionSignal);\n\t\t\t\t\tsaved = true;\n\t\t\t\t\treturn { kind: \"close\" };\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (actionSignal.aborted) return { kind: \"close\" };\n\t\t\t\t\t// Do not silently rebase a stale review or overwrite an invalid settings file.\n\t\t\t\t\t// The caller must reopen current settings for those failures.\n\t\t\t\t\tif (!retryableSettingsError(error)) {\n\t\t\t\t\t\tfailure = error;\n\t\t\t\t\t\treturn { kind: \"close\" };\n\t\t\t\t\t}\n\t\t\t\t\tfailureText = `Not saved. ${syncErrorGuidance(error)}\\nYour draft is retained. Fix the problem, then save again, or cancel.`;\n\t\t\t\t\tctx.ui.notify(failureText, \"error\");\n\t\t\t\t\treturn { kind: \"stay\" };\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t});\n\tconst result = await runMenu(ctx, menu, {\n\t\tgetState: () => undefined,\n\t\tsignal,\n\t\tisCurrent: () => !signal?.aborted,\n\t});\n\tif (signal?.aborted) return false;\n\tif (failure) throw failure;\n\tif (result.kind === \"error\") throw result.error;\n\treturn saved;\n}\n\nfunction retryableSettingsError(error: unknown) {\n\tconst code = (error as NodeJS.ErrnoException | undefined)?.code;\n\treturn (\n\t\tcode !== undefined &&\n\t\t[\"EACCES\", \"EPERM\", \"ENOSPC\", \"EBUSY\", \"EIO\", \"EMFILE\", \"ENFILE\", \"EROFS\"].includes(code)\n\t);\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport {\n\tnormalizeGitBranch,\n\tnormalizeGitDirectory,\n\tnormalizeGitRemote,\n} from \"../../backends/git/git-config.js\";\nimport {\n\taddStorageConnection,\n\taddSyncSetup,\n\tsaveNewV3Settings,\n\tupdateStorageConnection,\n\tupdateSyncSetup,\n} from \"../../settings/settings-management.js\";\nimport type { PartialConfig } from \"../../settings/settings-types.js\";\nimport { automaticSyncSummary } from \"../automatic-sync-summary.js\";\nimport { safeTerminalText } from \"../terminal-text.js\";\nimport { promptAvailableSetupStorage } from \"./setup-location-ui.js\";\nimport {\n\tchooseAutomaticSync,\n\tchooseSetupContent,\n\tincludedContentLines,\n\tpromptResourceName,\n\treadSetupConnection,\n} from \"./setup-prompts.js\";\nimport { saveReviewedDraft } from \"./setup-review.js\";\nimport { requiredInput, requiredValueInput } from \"./text-input.js\";\n\nexport async function showGitSetup(\n\tctx: ExtensionCommandContext,\n\ttargetName: string,\n\tsignal?: AbortSignal,\n) {\n\tconst remote = await promptGitRemote(ctx, signal);\n\tif (!remote) return false;\n\tconst destination = await promptGitDestination(ctx, signal);\n\tif (!destination) return false;\n\tconst include = await chooseSetupContent(ctx, signal);\n\tif (!include) return false;\n\tconst automatic = await chooseAutomaticSync(ctx, signal);\n\tif (automatic === undefined) return false;\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review Git sync setup\",\n\t\t[\n\t\t\t`Sync setup: ${safeTerminalText(targetName)}`,\n\t\t\t`Storage connection: ${safeTerminalText(targetName)} (Git)`,\n\t\t\t`Remote: ${safeTerminalText(remote)}`,\n\t\t\t`Sync branch: ${safeTerminalText(destination.branch)}`,\n\t\t\t`Storage location: ${safeTerminalText(destination.directory)}`,\n\t\t\t...includedContentLines(include),\n\t\t\t`Automatic sync: ${automaticSyncSummary(automatic)}`,\n\t\t\t\"Authentication: existing Git credential helper or SSH configuration (not stored by pi-sync).\",\n\t\t\t\"pi-sync manages the entire branch. The repository must already exist; a new branch is created on first push.\",\n\t\t\t\"Saving does not contact remote storage or start syncing.\",\n\t\t],\n\t\t\"Save setup\",\n\t\t(saveSignal) =>\n\t\t\tsaveNewV3Settings(\n\t\t\t\t{\n\t\t\t\t\tsetupName: targetName,\n\t\t\t\t\tconnectionName: targetName,\n\t\t\t\t\tconnection: { type: \"git\", remote },\n\t\t\t\t\tsetup: {\n\t\t\t\t\t\tstorage: {\n\t\t\t\t\t\t\tconnection: targetName,\n\t\t\t\t\t\t\tbranch: destination.branch,\n\t\t\t\t\t\t\tpath: destination.directory,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsync: { include, automatic },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tsaveSignal,\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted)\n\t\tctx.ui.notify(\n\t\t\t`Saved Git sync setup \u201C${safeTerminalText(targetName)}\u201D. Choose Sync now to start.`,\n\t\t\t\"info\",\n\t\t);\n\treturn saved;\n}\n\nexport async function showAddGitStorageProfile(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n\tconst name = await promptResourceName(ctx, \"storage connection\", \"git\", signal);\n\tif (!name) return false;\n\tconst remote = await promptGitRemote(ctx, signal);\n\tif (!remote) return false;\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review storage connection\",\n\t\t[\n\t\t\t`Name: ${safeTerminalText(name)}`,\n\t\t\t\"Type: Git\",\n\t\t\t`Remote: ${safeTerminalText(remote)}`,\n\t\t\t\"Credentials: existing Git/SSH authentication (not stored)\",\n\t\t\t\"Adding a connection does not contact the remote or start syncing.\",\n\t\t],\n\t\t\"Add storage connection\",\n\t\t(saveSignal) => addStorageConnection(name, { type: \"git\", remote }, saveSignal),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted)\n\t\tctx.ui.notify(`Added storage connection \u201C${safeTerminalText(name)}\u201D.`, \"info\");\n\treturn saved;\n}\n\nexport async function showEditGitStorageProfile(\n\tctx: ExtensionCommandContext,\n\tname: string,\n\tprofile: Record<string, unknown>,\n\tsignal?: AbortSignal,\n\taffectedSetups?: string[],\n) {\n\tconst remote = await promptGitRemote(\n\t\tctx,\n\t\tsignal,\n\t\ttypeof profile.remote === \"string\" ? profile.remote : undefined,\n\t);\n\tif (!remote) return false;\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review storage connection\",\n\t\t[\n\t\t\t`Storage connection: ${safeTerminalText(name)}`,\n\t\t\t`Remote: ${safeTerminalText(String(profile.remote ?? \"missing\"))} \u2192 ${safeTerminalText(remote)}`,\n\t\t\t`Affected sync setups: ${affectedSetups?.length ? affectedSetups.map(safeTerminalText).join(\", \") : \"None\"}`,\n\t\t\t\"Saving changes future storage access for every affected setup; it does not move or delete remote history.\",\n\t\t],\n\t\t\"Save storage connection\",\n\t\t(saveSignal) =>\n\t\t\tupdateStorageConnection(\n\t\t\t\tname,\n\t\t\t\t(current) => {\n\t\t\t\t\tif (current.type !== \"git\" || current.remote !== profile.remote)\n\t\t\t\t\t\tthrow new Error(\"Storage connection changed while it was open; reopen it.\");\n\t\t\t\t\treturn { ...current, remote };\n\t\t\t\t},\n\t\t\t\taffectedSetups,\n\t\t\t\tsaveSignal,\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted)\n\t\tctx.ui.notify(`Saved storage connection \u201C${safeTerminalText(name)}\u201D.`, \"info\");\n\treturn saved;\n}\n\nexport async function showAddGitTarget(\n\tctx: ExtensionCommandContext,\n\tname: string,\n\tprofile: string,\n\tsignal?: AbortSignal,\n) {\n\tconst selected = await promptGitDestination(ctx, signal);\n\tif (!selected) return false;\n\tconst storage = await promptAvailableSetupStorage(\n\t\tctx,\n\t\t{ connection: profile, branch: selected.branch, path: selected.directory },\n\t\tsignal,\n\t);\n\tif (!storage) return false;\n\tconst include = await chooseSetupContent(ctx, signal);\n\tif (!include) return false;\n\tconst automatic = await chooseAutomaticSync(ctx, signal);\n\tif (automatic === undefined) return false;\n\tconst connection = await readSetupConnection(profile, signal);\n\tif (connection?.type !== \"git\") throw new Error(\"Storage connection changed; reopen setup.\");\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review Git sync setup\",\n\t\t[\n\t\t\t`Sync setup: ${safeTerminalText(name)}`,\n\t\t\t`Storage connection: ${safeTerminalText(profile)}`,\n\t\t\t`Remote: ${safeTerminalText(connection.remote)}`,\n\t\t\t`Sync branch: ${safeTerminalText(storage.branch)}`,\n\t\t\t`Storage location: ${safeTerminalText(storage.path)}`,\n\t\t\t...includedContentLines(include),\n\t\t\t`Automatic sync: ${automaticSyncSummary(automatic)}`,\n\t\t\t\"pi-sync manages the entire branch. Adding this setup does not sync or modify remote data.\",\n\t\t],\n\t\t\"Add sync setup\",\n\t\t(saveSignal) =>\n\t\t\taddSyncSetup(name, { storage, sync: { include, automatic } }, saveSignal, connection),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted)\n\t\tctx.ui.notify(`Added sync setup \u201C${safeTerminalText(name)}\u201D.`, \"info\");\n\treturn saved;\n}\n\nexport async function showEditGitTarget(\n\tctx: ExtensionCommandContext,\n\tpartial: PartialConfig,\n\tsignal?: AbortSignal,\n) {\n\tlet destination = await promptGitDestination(ctx, signal, partial);\n\tif (!destination) return false;\n\twhile (destination.directory !== partial.storagePath && destination.branch === partial.branch) {\n\t\tctx.ui.notify(\n\t\t\t\"Changing a Git storage path requires a new Git branch so the existing branch remains readable.\",\n\t\t\t\"warning\",\n\t\t);\n\t\tconst branch = await requiredValueInput(\n\t\t\tctx,\n\t\t\t\"New Git branch\\n\\nKeep the previous branch unchanged; enter a new branch for this path.\",\n\t\t\t\"pi-sync/archive\",\n\t\t\tsignal,\n\t\t\tnormalizeGitBranch,\n\t\t);\n\t\tif (!branch) return false;\n\t\tdestination = { ...destination, branch };\n\t}\n\tconst chosen = destination;\n\tconst connection = await readSetupConnection(partial.connectionName, signal);\n\tif (connection.type !== \"git\") throw new Error(\"Storage connection changed; reopen setup.\");\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review sync setup\",\n\t\t[\n\t\t\t`Sync setup: ${safeTerminalText(partial.setupName)}`,\n\t\t\t`Storage connection: ${safeTerminalText(partial.connectionName)}`,\n\t\t\t`Remote: ${safeTerminalText(connection.remote)}`,\n\t\t\t`Branch: ${safeTerminalText(partial.branch ?? \"missing\")} \u2192 ${safeTerminalText(chosen.branch)}`,\n\t\t\t`Storage path: ${safeTerminalText(partial.storagePath)} \u2192 ${safeTerminalText(chosen.directory)}`,\n\t\t\t\"Saving changes the future storage location only; it does not move or delete remote history.\",\n\t\t],\n\t\t\"Save sync setup\",\n\t\t(saveSignal) =>\n\t\t\tupdateSyncSetup(\n\t\t\t\tpartial.setupName,\n\t\t\t\t(setup) => {\n\t\t\t\t\tif (typeof setup.storage.branch !== \"string\")\n\t\t\t\t\t\tthrow new Error(\"Sync setup storage type changed; reopen it.\");\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...setup,\n\t\t\t\t\t\tstorage: { ...setup.storage, branch: chosen.branch, path: chosen.directory },\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\t{ expectedStorage: partial, expectedConnection: connection, signal: saveSignal },\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted)\n\t\tctx.ui.notify(`Saved sync setup \u201C${safeTerminalText(partial.setupName)}\u201D.`, \"info\");\n\treturn saved;\n}\n\nasync function promptGitRemote(\n\tctx: ExtensionCommandContext,\n\tsignal?: AbortSignal,\n\tcurrent?: string,\n) {\n\tconst title =\n\t\t\"Git remote URL (SSH or HTTPS)\\n\\nUse an existing private repository with Git/SSH authentication already configured.\";\n\tconst validate = (value: string) => {\n\t\tconst remote = normalizeGitRemote(value);\n\t\tif (!remote) throw new Error(\"Git remote URL is required.\");\n\t\treturn remote;\n\t};\n\treturn current\n\t\t? requiredInput(ctx, title, current, signal, validate)\n\t\t: requiredValueInput(\n\t\t\t\tctx,\n\t\t\t\ttitle,\n\t\t\t\t\"git@github.com:owner/private-pi-sync.git (SSH) or https://github.com/owner/private-pi-sync.git (HTTPS)\",\n\t\t\t\tsignal,\n\t\t\t\tvalidate,\n\t\t\t);\n}\n\nasync function promptGitDestination(\n\tctx: ExtensionCommandContext,\n\tsignal?: AbortSignal,\n\tcurrent: Partial<PartialConfig> = {},\n) {\n\tconst branch = await requiredInput(\n\t\tctx,\n\t\t\"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.\",\n\t\tcurrent.branch ?? \"main\",\n\t\tsignal,\n\t\tnormalizeGitBranch,\n\t);\n\tif (!branch) return undefined;\n\tconst directory = await requiredInput(\n\t\tctx,\n\t\t\"Git storage path\\n\\nRelative to the repository root, not your local filesystem.\\n./ stores manifest.json and files/ at the repository root.\",\n\t\tcurrent.storagePath ?? \"./\",\n\t\tsignal,\n\t\tnormalizeGitDirectory,\n\t);\n\treturn directory ? { branch, directory } : undefined;\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport {\n\tCURSOR_MARKER,\n\tdecodeKittyPrintable,\n\ttype Focusable,\n\tKey,\n\ttype KeybindingsManager,\n\tmatchesKey,\n\tText,\n\ttruncateToWidth,\n} from \"@earendil-works/pi-tui\";\nimport { runCustomInteraction } from \"@narumitw/pi-tui-kit\";\n\nconst MASK = \"\u2022\";\n\nexport async function promptSecret(\n\tctx: ExtensionCommandContext,\n\ttitle: string,\n\toptions: { required?: boolean; signal?: AbortSignal } = { required: true },\n) {\n\tif (ctx.mode !== \"tui\" || options.signal?.aborted) return undefined;\n\tconst result = await runCustomInteraction<string | undefined>(ctx, {\n\t\tsignal: options.signal,\n\t\tisCurrent: () => !options.signal?.aborted,\n\t\tcreate: ({ tui, theme, keybindings, complete }) => {\n\t\t\tconst heading = new Text(\"\", 0, 0);\n\t\t\tconst hint = new Text(\"\", 0, 0);\n\t\t\tconst submitKey = keybindingText(keybindings, \"tui.input.submit\", \"enter\");\n\t\t\tconst cancelKey = keybindingText(keybindings, \"tui.select.cancel\", \"esc\", [\"ctrl+c\"]);\n\t\t\tconst applyTheme = () => {\n\t\t\t\theading.setText(theme.fg(\"accent\", theme.bold(title)));\n\t\t\t\thint.setText(\n\t\t\t\t\ttheme.fg(\"dim\", `${submitKey} continue \u2022 ${cancelKey} cancel \u2022 Input is hidden`),\n\t\t\t\t);\n\t\t\t};\n\t\t\tapplyTheme();\n\t\t\tconst input = new MaskedInput(keybindings);\n\t\t\tconst component: Focusable & {\n\t\t\t\trender(width: number): string[];\n\t\t\t\tinvalidate(): void;\n\t\t\t\thandleInput(data: string): void;\n\t\t\t\tdispose(): void;\n\t\t\t} = {\n\t\t\t\tget focused() {\n\t\t\t\t\treturn input.focused;\n\t\t\t\t},\n\t\t\t\tset focused(focused: boolean) {\n\t\t\t\t\tinput.focused = focused;\n\t\t\t\t},\n\t\t\t\trender(width: number) {\n\t\t\t\t\tconst safeWidth = Math.max(1, width);\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...heading.render(safeWidth),\n\t\t\t\t\t\t...input.render(safeWidth),\n\t\t\t\t\t\t...hint.render(safeWidth),\n\t\t\t\t\t].map((line) => truncateToWidth(line, safeWidth));\n\t\t\t\t},\n\t\t\t\tinvalidate() {\n\t\t\t\t\tapplyTheme();\n\t\t\t\t\theading.invalidate();\n\t\t\t\t\tinput.invalidate();\n\t\t\t\t\thint.invalidate();\n\t\t\t\t},\n\t\t\t\thandleInput(data: string) {\n\t\t\t\t\tif (matchesKey(data, Key.ctrl(\"c\"))) {\n\t\t\t\t\t\tcomplete(undefined);\n\t\t\t\t\t} else if (input.isPasting || data.includes(\"\\u001b[200~\")) {\n\t\t\t\t\t\tinput.handleInput(data);\n\t\t\t\t\t} else if (keybindings.matches(data, \"tui.select.cancel\")) {\n\t\t\t\t\t\tcomplete(undefined);\n\t\t\t\t\t} else if (keybindings.matches(data, \"tui.input.submit\")) {\n\t\t\t\t\t\tif (options.required !== false && input.getValue().length === 0) {\n\t\t\t\t\t\t\tctx.ui.notify(`${title} is required. Enter a value, or cancel.`, \"warning\");\n\t\t\t\t\t\t} else if (hasControlCharacter(input.getValue())) {\n\t\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t\t`${title} contains control characters. Remove them or re-enter the value, then continue.`,\n\t\t\t\t\t\t\t\t\"warning\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else complete(input.getValue());\n\t\t\t\t\t} else input.handleInput(data);\n\t\t\t\t\ttui.requestRender();\n\t\t\t\t},\n\t\t\t\tdispose() {\n\t\t\t\t\tinput.clear();\n\t\t\t\t},\n\t\t\t};\n\t\t\treturn component;\n\t\t},\n\t});\n\tif (result.kind === \"error\") throw result.error;\n\tif (result.kind !== \"completed\" || result.value === undefined) return undefined;\n\tconst value = result.value;\n\tif (options.required !== false && value.length === 0) {\n\t\tctx.ui.notify(`${title} is required.`, \"warning\");\n\t\treturn undefined;\n\t}\n\treturn value;\n}\n\nclass MaskedInput implements Focusable {\n\tfocused = false;\n\tprivate value: string[] = [];\n\tprivate cursor = 0;\n\tprivate paste = \"\";\n\tprivate pasting = false;\n\n\tconstructor(private readonly keybindings: KeybindingsManager) {}\n\n\tget isPasting() {\n\t\treturn this.pasting;\n\t}\n\n\tgetValue() {\n\t\treturn this.value.join(\"\");\n\t}\n\n\thandleInput(data: string) {\n\t\tif (data.includes(\"\\u001b[200~\")) {\n\t\t\tthis.pasting = true;\n\t\t\tthis.paste = \"\";\n\t\t\tdata = data.replace(\"\\u001b[200~\", \"\");\n\t\t}\n\t\tif (this.pasting) {\n\t\t\tthis.paste += data;\n\t\t\tconst end = this.paste.indexOf(\"\\u001b[201~\");\n\t\t\tif (end < 0) return;\n\t\t\tconst pasted = this.paste\n\t\t\t\t.slice(0, end)\n\t\t\t\t.replace(/[\\r\\n]/gu, \"\")\n\t\t\t\t.replace(/\\t/gu, \" \");\n\t\t\tthis.insert(pasted);\n\t\t\tconst remaining = this.paste.slice(end + 6);\n\t\t\tthis.paste = \"\";\n\t\t\tthis.pasting = false;\n\t\t\tif (remaining) this.handleInput(remaining);\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.editor.deleteCharBackward\")) {\n\t\t\tif (this.cursor > 0) this.value.splice(--this.cursor, 1);\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.editor.deleteCharForward\")) {\n\t\t\tif (this.cursor < this.value.length) this.value.splice(this.cursor, 1);\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.editor.cursorLeft\")) {\n\t\t\tthis.cursor = Math.max(0, this.cursor - 1);\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.editor.cursorRight\")) {\n\t\t\tthis.cursor = Math.min(this.value.length, this.cursor + 1);\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.editor.cursorLineStart\")) {\n\t\t\tthis.cursor = 0;\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.editor.cursorLineEnd\")) {\n\t\t\tthis.cursor = this.value.length;\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.editor.deleteToLineStart\")) {\n\t\t\tthis.value.splice(0, this.cursor);\n\t\t\tthis.cursor = 0;\n\t\t\treturn;\n\t\t}\n\t\tif (this.keybindings.matches(data, \"tui.editor.deleteToLineEnd\")) {\n\t\t\tthis.value.splice(this.cursor);\n\t\t\treturn;\n\t\t}\n\t\tconst printable = decodeKittyPrintable(data) ?? data;\n\t\tif (!hasControlCharacter(printable)) this.insert(printable);\n\t}\n\n\trender(width: number) {\n\t\tconst prompt = \"> \";\n\t\tconst available = width - prompt.length;\n\t\tif (available <= 0) return [truncateToWidth(prompt, Math.max(1, width))];\n\t\tconst contentWidth = Math.max(0, available - 1);\n\t\tlet start = 0;\n\t\tif (this.value.length > contentWidth) {\n\t\t\tstart = Math.max(\n\t\t\t\t0,\n\t\t\t\tMath.min(this.cursor - Math.floor(contentWidth / 2), this.value.length - contentWidth),\n\t\t\t);\n\t\t}\n\t\tconst end = Math.min(this.value.length, start + contentWidth);\n\t\tconst visibleCursor = Math.max(0, Math.min(this.cursor - start, end - start));\n\t\tconst masks = Array.from({ length: end - start }, () => MASK);\n\t\tconst before = masks.slice(0, visibleCursor).join(\"\");\n\t\tconst atCursor = visibleCursor < masks.length ? MASK : \" \";\n\t\tconst after = masks.slice(visibleCursor + (visibleCursor < masks.length ? 1 : 0)).join(\"\");\n\t\tconst marker = this.focused ? CURSOR_MARKER : \"\";\n\t\tconst line = `${prompt}${before}${marker}\\u001b[7m${atCursor}\\u001b[27m${after}`;\n\t\treturn [truncateToWidth(line, width, \"\")];\n\t}\n\n\tinvalidate() {}\n\n\tclear() {\n\t\tthis.value.fill(\"\");\n\t\tthis.value = [];\n\t\tthis.paste = \"\";\n\t\tthis.cursor = 0;\n\t\tthis.pasting = false;\n\t}\n\n\tprivate insert(value: string) {\n\t\tconst characters = Array.from(value);\n\t\tthis.value.splice(this.cursor, 0, ...characters);\n\t\tthis.cursor += characters.length;\n\t}\n}\n\nfunction keybindingText(\n\tkeybindings: Pick<KeybindingsManager, \"getKeys\">,\n\tbinding: Parameters<KeybindingsManager[\"getKeys\"]>[0],\n\tfallback: string,\n\tadditionalKeys: readonly string[] = [],\n) {\n\tconst keys = [...new Set([...keybindings.getKeys(binding), ...additionalKeys])]\n\t\t.map(String)\n\t\t.map((key) => {\n\t\t\tif (key === \"return\") return \"enter\";\n\t\t\tif (key === \"escape\") return \"esc\";\n\t\t\treturn hasControlCharacter(key) ? \"\" : key;\n\t\t})\n\t\t.filter(Boolean);\n\treturn keys.join(\"/\") || fallback;\n}\n\nfunction hasControlCharacter(value: string) {\n\treturn [...value].some((character) => {\n\t\tconst code = character.codePointAt(0) ?? 0;\n\t\treturn code < 0x20 || (code >= 0x7f && code <= 0x9f);\n\t});\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { promptSecret } from \"../secret-input.js\";\nimport { requiredValueInput } from \"./text-input.js\";\n\nexport interface ChosenS3Credentials {\n\tprofileFields: { accessKeyId?: string; secretAccessKey?: string };\n\tsummary: string;\n\tready: boolean;\n\treplace?: boolean;\n}\n\nexport async function chooseS3CredentialUpdate(\n\tctx: ExtensionCommandContext,\n\tprofile: Record<string, unknown>,\n\tsignal?: AbortSignal,\n) {\n\tconst hasStored =\n\t\ttypeof profile.accessKeyId === \"string\" &&\n\t\tprofile.accessKeyId.length > 0 &&\n\t\ttypeof profile.secretAccessKey === \"string\" &&\n\t\tprofile.secretAccessKey.length > 0;\n\tif (hasStored) {\n\t\tconst action = await ctx.ui.select(\n\t\t\t\"Credentials\",\n\t\t\t[\"Keep current credentials\", \"Replace credentials\", \"Cancel\"],\n\t\t\t{ signal },\n\t\t);\n\t\tthrowIfAborted(signal);\n\t\tif (!action || action === \"Cancel\") return undefined;\n\t\tif (action === \"Keep current credentials\") {\n\t\t\treturn { profileFields: {}, summary: \"Unchanged (values hidden)\", ready: true };\n\t\t}\n\t}\n\tconst selected = await chooseS3Credentials(ctx, signal);\n\treturn selected ? { ...selected, replace: true } : undefined;\n}\n\nexport function applyS3CredentialUpdate(\n\tprofile: Record<string, unknown>,\n\tcredentials: ChosenS3Credentials,\n) {\n\tconst next = { ...profile };\n\tif (credentials.replace) {\n\t\tdelete next.accessKeyId;\n\t\tdelete next.secretAccessKey;\n\t\tdelete next.sessionToken;\n\t}\n\treturn { ...next, ...credentials.profileFields };\n}\n\nexport async function chooseS3Credentials(\n\tctx: ExtensionCommandContext,\n\tsignal?: AbortSignal,\n): Promise<ChosenS3Credentials | undefined> {\n\tconst choice = await ctx.ui.select(\n\t\t\"Credentials\\n\\nCredentials are stored in the private pi-sync settings file. Secret values are masked during input and never shown afterward.\",\n\t\t[\"Store credentials privately\", \"Cancel\"],\n\t\t{ signal },\n\t);\n\tthrowIfAborted(signal);\n\tif (choice !== \"Store credentials privately\") return undefined;\n\tconst accessKeyId = await requiredValueInput(\n\t\tctx,\n\t\t\"Access key ID\\n\\nUse the S3 API access key ID issued by your provider, not the secret access key.\",\n\t\t\"access-key-id\",\n\t\tsignal,\n\t);\n\tif (!accessKeyId) return undefined;\n\tconst secretAccessKey = await promptSecret(ctx, \"Secret access key\", { signal });\n\tthrowIfAborted(signal);\n\tif (secretAccessKey === undefined) return undefined;\n\treturn {\n\t\tprofileFields: { accessKeyId, secretAccessKey },\n\t\tsummary: \"Stored privately (values hidden)\",\n\t\tready: true,\n\t};\n}\n\nfunction throwIfAborted(signal?: AbortSignal) {\n\tif (!signal?.aborted) return;\n\tthrow signal.reason instanceof Error\n\t\t? signal.reason\n\t\t: new DOMException(\"The operation was aborted\", \"AbortError\");\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { refreshTargetCompletions } from \"../../commands/setup-completions.js\";\nimport {\n\taddSyncSetup,\n\tsaveNewV3Settings,\n\tupdateSyncSetup,\n} from \"../../settings/settings-management.js\";\nimport type { PartialConfig } from \"../../settings/settings-types.js\";\nimport {\n\tnormalizeS3Bucket,\n\tnormalizeS3Endpoint,\n\tnormalizeStoragePath,\n} from \"../../settings/settings-validation.js\";\nimport { automaticSyncSummary } from \"../automatic-sync-summary.js\";\nimport { safeTerminalText } from \"../terminal-text.js\";\nimport { chooseS3Credentials } from \"./s3-credentials-ui.js\";\nimport {\n\tchooseAdditionalRemoteLocation,\n\tchooseInitialRemoteLocation,\n\tpromptAvailableSetupStorage,\n} from \"./setup-location-ui.js\";\nimport {\n\tchooseAutomaticSync,\n\tchooseSessions,\n\tchooseSetupContent,\n\tincludedContentLines,\n\treadSetupConnection,\n} from \"./setup-prompts.js\";\nimport { saveReviewedDraft } from \"./setup-review.js\";\nimport { requiredInput, requiredValueInput } from \"./text-input.js\";\n\nexport async function showS3Setup(\n\tctx: ExtensionCommandContext,\n\tpreset: string,\n\ttargetName: string,\n\tsignal?: AbortSignal,\n) {\n\tconst endpoint = await requiredValueInput(\n\t\tctx,\n\t\tpreset === \"Cloudflare R2\"\n\t\t\t? \"Cloudflare R2 endpoint\\n\\nCopy the S3 API endpoint from your R2 account; replace <account-id>.\"\n\t\t\t: \"S3-compatible endpoint\\n\\nUse your provider's S3 API URL, not its web console.\",\n\t\tpreset === \"Cloudflare R2\"\n\t\t\t? \"https://<account-id>.r2.cloudflarestorage.com\"\n\t\t\t: \"https://s3.example.com\",\n\t\tsignal,\n\t\tnormalizeS3Endpoint,\n\t);\n\tif (!endpoint) return false;\n\tconst region =\n\t\tpreset === \"Cloudflare R2\"\n\t\t\t? \"auto\"\n\t\t\t: await requiredInput(\n\t\t\t\t\tctx,\n\t\t\t\t\t\"Storage region\\n\\nUse the region assigned to your bucket by the provider.\",\n\t\t\t\t\t\"us-east-1\",\n\t\t\t\t\tsignal,\n\t\t\t\t);\n\tif (!region) return false;\n\tconst location = await chooseInitialRemoteLocation(ctx, preset, targetName, signal);\n\tif (!location) return false;\n\tconst credentials = await chooseS3Credentials(ctx, signal);\n\tif (!credentials) return false;\n\tconst include = await chooseSetupContent(ctx, signal);\n\tif (!include) return false;\n\tconst automatic = await chooseAutomaticSync(ctx, signal);\n\tif (automatic === undefined) return false;\n\tconst sessions = await chooseSessions(ctx, signal);\n\tif (sessions === undefined) return false;\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review sync setup\",\n\t\t[\n\t\t\t`Sync setup: ${safeTerminalText(targetName)}`,\n\t\t\t`Storage connection: ${safeTerminalText(location.connectionName)} (${preset})`,\n\t\t\t`Endpoint: ${safeTerminalText(endpoint)}`,\n\t\t\t`Region: ${safeTerminalText(region)}`,\n\t\t\t`Bucket: ${safeTerminalText(location.bucket)}`,\n\t\t\t`Storage location: ${safeTerminalText(location.path)}`,\n\t\t\t...includedContentLines(include, sessions),\n\t\t\t`Automatic sync: ${automaticSyncSummary(automatic)}`,\n\t\t\t`Credentials: ${credentials.summary}`,\n\t\t\t\"The bucket must already exist. Saving does not contact remote storage or start syncing.\",\n\t\t],\n\t\t\"Save sync setup\",\n\t\t(saveSignal) =>\n\t\t\tsaveNewV3Settings(\n\t\t\t\t{\n\t\t\t\t\tsetupName: targetName,\n\t\t\t\t\tconnectionName: location.connectionName,\n\t\t\t\t\tconnection: {\n\t\t\t\t\t\ttype: \"s3\",\n\t\t\t\t\t\tendpoint,\n\t\t\t\t\t\tregion,\n\t\t\t\t\t\tcredentials: {\n\t\t\t\t\t\t\taccessKeyId: credentials.profileFields.accessKeyId ?? \"\",\n\t\t\t\t\t\t\tsecretAccessKey: credentials.profileFields.secretAccessKey ?? \"\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tsetup: {\n\t\t\t\t\t\tstorage: {\n\t\t\t\t\t\t\tconnection: location.connectionName,\n\t\t\t\t\t\t\tbucket: location.bucket,\n\t\t\t\t\t\t\tpath: location.path,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsync: { include: [...include, ...(sessions ? [\"sessions\"] : [])], automatic },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tsaveSignal,\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (!saved || signal?.aborted) return false;\n\tawait refreshTargetCompletions();\n\tif (!signal?.aborted)\n\t\tctx.ui.notify(\n\t\t\t`Sync setup \u201C${safeTerminalText(targetName)}\u201D saved. Choose Sync now to start.`,\n\t\t\t\"info\",\n\t\t);\n\treturn true;\n}\n\nexport async function showAddS3Target(\n\tctx: ExtensionCommandContext,\n\traw: Record<string, unknown>,\n\tprofile: string,\n\tname: string,\n\tsignal?: AbortSignal,\n) {\n\tconst location = await chooseAdditionalRemoteLocation(ctx, raw, profile, name, signal);\n\tif (!location) return;\n\tconst storage = await promptAvailableSetupStorage(\n\t\tctx,\n\t\t{ connection: profile, ...location },\n\t\tsignal,\n\t);\n\tif (!storage) return;\n\tconst include = await chooseSetupContent(ctx, signal);\n\tif (!include) return;\n\tconst automatic = await chooseAutomaticSync(ctx, signal);\n\tif (automatic === undefined) return;\n\tconst connection = await readSetupConnection(profile, signal);\n\tif (connection.type !== \"s3\") throw new Error(\"Storage connection changed; reopen setup.\");\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review new sync setup\",\n\t\t[\n\t\t\t`Sync setup: ${safeTerminalText(name)}`,\n\t\t\t`Storage connection: ${safeTerminalText(profile)}`,\n\t\t\t`Endpoint: ${safeTerminalText(connection.endpoint)}`,\n\t\t\t`Bucket: ${safeTerminalText(storage.bucket)}`,\n\t\t\t`Storage location: ${safeTerminalText(storage.path)}`,\n\t\t\t...includedContentLines(include),\n\t\t\t`Automatic sync: ${automaticSyncSummary(automatic)}`,\n\t\t\t\"Only the current setup is checked at startup. Shutdown can push selected content when sessions are included.\",\n\t\t\t\"The bucket must already exist. Adding this setup does not sync or modify remote data.\",\n\t\t],\n\t\t\"Add sync setup\",\n\t\t(saveSignal) =>\n\t\t\taddSyncSetup(name, { storage, sync: { include, automatic } }, saveSignal, connection),\n\t\tsignal,\n\t);\n\tif (!saved || signal?.aborted) return;\n\tawait refreshTargetCompletions();\n\tif (!signal?.aborted) ctx.ui.notify(`Added sync setup \u201C${safeTerminalText(name)}\u201D.`, \"info\");\n}\n\nexport async function showEditS3Target(\n\tctx: ExtensionCommandContext,\n\tpartial: PartialConfig,\n\tsignal?: AbortSignal,\n) {\n\tconst bucket = await requiredInput(\n\t\tctx,\n\t\t\"Bucket\\n\\nUse an existing bucket; pi-sync will not create it.\",\n\t\tpartial.bucket ?? \"pi-sync\",\n\t\tsignal,\n\t\tnormalizeS3Bucket,\n\t);\n\tif (!bucket) return;\n\tconst storagePath = await requiredInput(\n\t\tctx,\n\t\t\"Storage path\\n\\nPath inside the bucket, not your local filesystem. ./ uses the bucket root.\",\n\t\tpartial.storagePath,\n\t\tsignal,\n\t\tnormalizeStoragePath,\n\t);\n\tif (!storagePath) return;\n\tconst connection = await readSetupConnection(partial.connectionName, signal);\n\tif (connection.type !== \"s3\") throw new Error(\"Storage connection changed; reopen setup.\");\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review sync setup\",\n\t\t[\n\t\t\t`Sync setup: ${safeTerminalText(partial.setupName)}`,\n\t\t\t`Storage connection: ${safeTerminalText(partial.connectionName)}`,\n\t\t\t`Endpoint: ${safeTerminalText(connection.endpoint)}`,\n\t\t\t`Bucket: ${safeTerminalText(partial.bucket ?? \"missing\")} \u2192 ${safeTerminalText(bucket)}`,\n\t\t\t`Storage path: ${safeTerminalText(partial.storagePath)} \u2192 ${safeTerminalText(storagePath)}`,\n\t\t\t\"Saving changes the future storage location only; it does not move or delete remote data.\",\n\t\t],\n\t\t\"Save sync setup\",\n\t\t(saveSignal) =>\n\t\t\tupdateSyncSetup(\n\t\t\t\tpartial.setupName,\n\t\t\t\t(setup) => {\n\t\t\t\t\tif (typeof setup.storage.bucket !== \"string\")\n\t\t\t\t\t\tthrow new Error(\"Sync setup storage type changed; reopen it.\");\n\t\t\t\t\treturn { ...setup, storage: { ...setup.storage, bucket, path: storagePath } };\n\t\t\t\t},\n\t\t\t\t{ expectedStorage: partial, expectedConnection: connection, signal: saveSignal },\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted)\n\t\tctx.ui.notify(`Saved sync setup \u201C${safeTerminalText(partial.setupName)}\u201D.`, \"info\");\n}\n", "import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport {\n\tnormalizeWebDavPath,\n\tnormalizeWebDavUrl,\n\tvalidateWebDavCredentials,\n} from \"../../backends/webdav/webdav-config.js\";\nimport {\n\taddStorageConnection,\n\taddSyncSetup,\n\tsaveNewV3Settings,\n\tupdateStorageConnection,\n\tupdateSyncSetup,\n} from \"../../settings/settings-management.js\";\nimport type { PartialConfig } from \"../../settings/settings-types.js\";\nimport { automaticSyncSummary } from \"../automatic-sync-summary.js\";\nimport { promptSecret } from \"../secret-input.js\";\nimport { safeTerminalText as safe } from \"../terminal-text.js\";\nimport { promptAvailableSetupStorage } from \"./setup-location-ui.js\";\nimport {\n\tchooseAutomaticSync,\n\tchooseSessions,\n\tchooseSetupContent,\n\tincludedContentLines,\n\tpromptResourceName,\n\treadSetupConnection,\n} from \"./setup-prompts.js\";\nimport { saveReviewedDraft } from \"./setup-review.js\";\nimport { promptTextInput } from \"./text-input.js\";\n\nexport async function showWebDavSetup(\n\tctx: ExtensionCommandContext,\n\ttargetName: string,\n\tsignal?: AbortSignal,\n) {\n\tconst url = await promptWebDavUrl(ctx, signal);\n\tif (!url) return false;\n\tconst username = await promptUsername(ctx, signal);\n\tif (!username) return false;\n\tconst password = await promptSecret(ctx, \"WebDAV password\", { signal });\n\tsignal?.throwIfAborted();\n\tif (password === undefined) return false;\n\tconst remotePath = await chooseDestination(ctx, signal);\n\tif (!remotePath) return false;\n\tconst include = await chooseSetupContent(ctx, signal);\n\tif (!include) return false;\n\tconst automatic = await chooseAutomaticSync(ctx, signal);\n\tif (automatic === undefined) return false;\n\tconst sessions = await chooseSessions(ctx, signal);\n\tif (sessions === undefined) return false;\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review WebDAV setup\",\n\t\t[\n\t\t\t`Sync setup: ${safe(targetName)}`,\n\t\t\t`Storage connection: ${safe(targetName)} (WebDAV)`,\n\t\t\t`URL: ${safe(url)}`,\n\t\t\t`Storage location: ${safe(remotePath)}`,\n\t\t\t\"Username and password: stored privately (values hidden)\",\n\t\t\t...includedContentLines(include, sessions),\n\t\t\t`Automatic sync: ${automaticSyncSummary(automatic)}`,\n\t\t\t\"Check setup tests whether this server can safely save sync updates using a temporary probe.\",\n\t\t\t\"Saving does not contact remote storage or start syncing.\",\n\t\t],\n\t\t\"Save setup\",\n\t\t(saveSignal) =>\n\t\t\tsaveNewV3Settings(\n\t\t\t\t{\n\t\t\t\t\tsetupName: targetName,\n\t\t\t\t\tconnectionName: targetName,\n\t\t\t\t\tconnection: { type: \"webdav\", url, credentials: { username, password } },\n\t\t\t\t\tsetup: {\n\t\t\t\t\t\tstorage: { connection: targetName, path: remotePath },\n\t\t\t\t\t\tsync: { include: [...include, ...(sessions ? [\"sessions\"] : [])], automatic },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tsaveSignal,\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted)\n\t\tctx.ui.notify(`Sync setup \u201C${safe(targetName)}\u201D saved. Choose Sync now to start.`, \"info\");\n\treturn saved;\n}\n\nexport async function showAddWebDavTarget(\n\tctx: ExtensionCommandContext,\n\tname: string,\n\tprofile: string,\n\tsignal?: AbortSignal,\n) {\n\tconst remotePath = await chooseDestination(ctx, signal);\n\tif (!remotePath) return false;\n\tconst storage = await promptAvailableSetupStorage(\n\t\tctx,\n\t\t{ connection: profile, path: remotePath },\n\t\tsignal,\n\t);\n\tif (!storage) return false;\n\tconst include = await chooseSetupContent(ctx, signal);\n\tif (!include) return false;\n\tconst automatic = await chooseAutomaticSync(ctx, signal);\n\tif (automatic === undefined) return false;\n\tconst connection = await readSetupConnection(profile, signal);\n\tif (connection.type !== \"webdav\") throw new Error(\"Storage connection changed; reopen setup.\");\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review WebDAV sync setup\",\n\t\t[\n\t\t\t`Sync setup: ${safe(name)}`,\n\t\t\t`Storage connection: ${safe(profile)}`,\n\t\t\t`URL: ${safe(connection.url)}`,\n\t\t\t`Storage location: ${safe(storage.path)}`,\n\t\t\t...includedContentLines(include),\n\t\t\t`Automatic sync: ${automaticSyncSummary(automatic)}`,\n\t\t\t\"Adding this setup does not sync or modify remote data.\",\n\t\t],\n\t\t\"Add sync setup\",\n\t\t(saveSignal) =>\n\t\t\taddSyncSetup(name, { storage, sync: { include, automatic } }, saveSignal, connection),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted) ctx.ui.notify(`Added sync setup \u201C${safe(name)}\u201D.`, \"info\");\n\treturn saved;\n}\n\nexport async function showEditWebDavTarget(\n\tctx: ExtensionCommandContext,\n\tpartial: PartialConfig,\n\tsignal?: AbortSignal,\n) {\n\tconst remotePath = await chooseDestination(ctx, signal, partial.storagePath);\n\tif (!remotePath) return false;\n\tconst connection = await readSetupConnection(partial.connectionName, signal);\n\tif (connection.type !== \"webdav\") throw new Error(\"Storage connection changed; reopen setup.\");\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review sync setup\",\n\t\t[\n\t\t\t`Sync setup: ${safe(partial.setupName)}`,\n\t\t\t`Storage connection: ${safe(partial.connectionName)}`,\n\t\t\t`URL: ${safe(connection.url)}`,\n\t\t\t`Storage path: ${safe(partial.storagePath)} \u2192 ${safe(remotePath)}`,\n\t\t\t\"Saving changes the future storage location only; it does not move or delete remote data.\",\n\t\t],\n\t\t\"Save sync setup\",\n\t\t(saveSignal) =>\n\t\t\tupdateSyncSetup(\n\t\t\t\tpartial.setupName,\n\t\t\t\t(setup) => ({\n\t\t\t\t\t...setup,\n\t\t\t\t\tstorage: { ...setup.storage, path: remotePath },\n\t\t\t\t}),\n\t\t\t\t{ expectedStorage: partial, expectedConnection: connection, signal: saveSignal },\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted)\n\t\tctx.ui.notify(`Saved sync setup \u201C${safe(partial.setupName)}\u201D.`, \"info\");\n\treturn saved;\n}\n\nexport async function showAddWebDavStorageProfile(\n\tctx: ExtensionCommandContext,\n\tsignal?: AbortSignal,\n) {\n\tconst name = await promptResourceName(ctx, \"storage connection\", \"webdav\", signal, true);\n\tif (!name) return false;\n\tconst url = await promptWebDavUrl(ctx, signal);\n\tif (!url) return false;\n\tconst username = await promptUsername(ctx, signal);\n\tif (!username) return false;\n\tconst password = await promptSecret(ctx, \"WebDAV password\", { signal });\n\tsignal?.throwIfAborted();\n\tif (password === undefined) return false;\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review storage connection\",\n\t\t[\n\t\t\t`Name: ${safe(name)}`,\n\t\t\t\"Type: WebDAV\",\n\t\t\t`URL: ${safe(url)}`,\n\t\t\t\"Username and password: stored privately (values hidden)\",\n\t\t\t\"Adding a connection does not contact the server or start syncing.\",\n\t\t],\n\t\t\"Add storage connection\",\n\t\t(saveSignal) =>\n\t\t\taddStorageConnection(\n\t\t\t\tname,\n\t\t\t\t{ type: \"webdav\", url, credentials: { username, password } },\n\t\t\t\tsaveSignal,\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted) ctx.ui.notify(`Added storage connection \u201C${safe(name)}\u201D.`, \"info\");\n\treturn saved;\n}\n\nexport async function showEditWebDavStorageProfile(\n\tctx: ExtensionCommandContext,\n\tname: string,\n\tprofile: Record<string, unknown>,\n\tsignal?: AbortSignal,\n\taffectedSetups?: string[],\n) {\n\tconst url = await promptWebDavUrl(\n\t\tctx,\n\t\tsignal,\n\t\ttypeof profile.url === \"string\" ? profile.url : undefined,\n\t);\n\tif (!url) return false;\n\tconst username = await promptUsername(ctx, signal);\n\tif (!username) return false;\n\tconst hasPassword = typeof profile.password === \"string\" && profile.password.length > 0;\n\tconst passwordAction = hasPassword\n\t\t? await select(\n\t\t\t\tctx,\n\t\t\t\t\"WebDAV password\",\n\t\t\t\t[\"Keep current password\", \"Replace password\", \"Cancel\"],\n\t\t\t\tsignal,\n\t\t\t)\n\t\t: \"Replace password\";\n\tif (!passwordAction || passwordAction === \"Cancel\") return false;\n\tconst replacePassword = passwordAction === \"Replace password\";\n\tconst password = replacePassword\n\t\t? await promptSecret(ctx, \"New WebDAV password\", { signal })\n\t\t: undefined;\n\tsignal?.throwIfAborted();\n\tif (replacePassword && password === undefined) return false;\n\tconst saved = await saveReviewedDraft(\n\t\tctx,\n\t\t\"Review storage connection\",\n\t\t[\n\t\t\t`Storage connection: ${safe(name)}`,\n\t\t\t`URL: ${safe(String(profile.url))} \u2192 ${safe(url)}`,\n\t\t\t\"Username: stored privately (value hidden)\",\n\t\t\t`Password: ${replacePassword ? \"will be replaced\" : \"unchanged\"} (value hidden)`,\n\t\t\t`Affected sync setups: ${affectedSetups?.length ? affectedSetups.map(safe).join(\", \") : \"None\"}`,\n\t\t\t\"Saving changes future storage access for every affected setup; it does not move remote data.\",\n\t\t],\n\t\t\"Save storage connection\",\n\t\t(saveSignal) =>\n\t\t\tupdateStorageConnection(\n\t\t\t\tname,\n\t\t\t\t(current) => {\n\t\t\t\t\tif (\n\t\t\t\t\t\tcurrent.type !== \"webdav\" ||\n\t\t\t\t\t\tcurrent.url !== profile.url ||\n\t\t\t\t\t\tcurrent.credentials.username !== profile.username ||\n\t\t\t\t\t\tcurrent.credentials.password !== profile.password\n\t\t\t\t\t)\n\t\t\t\t\t\tthrow new Error(\"Storage connection changed while it was open; reopen it.\");\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...current,\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tcredentials: {\n\t\t\t\t\t\t\t...current.credentials,\n\t\t\t\t\t\t\tusername,\n\t\t\t\t\t\t\tpassword: password ?? current.credentials.password,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\taffectedSetups,\n\t\t\t\tsaveSignal,\n\t\t\t),\n\t\tsignal,\n\t);\n\tif (saved && !signal?.aborted) ctx.ui.notify(`Saved storage connection \u201C${safe(name)}\u201D.`, \"info\");\n\treturn saved;\n}\n\nasync function chooseDestination(\n\tctx: ExtensionCommandContext,\n\tsignal?: AbortSignal,\n\tcurrent = \"./\",\n) {\n\treturn promptTextInput(\n\t\tctx,\n\t\t\"WebDAV storage path\\n\\nFolder relative to the collection URL, not your local filesystem.\\n./ uses the collection root. Use different folders for independent setups.\",\n\t\t{ defaultValue: current, validate: normalizeWebDavPath },\n\t\tsignal,\n\t);\n}\n\nasync function promptUsername(ctx: ExtensionCommandContext, signal?: AbortSignal) {\n\treturn promptTextInput(\n\t\tctx,\n\t\t\"WebDAV username\\n\\nEnter the account username; stored values remain hidden.\",\n\t\t{\n\t\t\texample: \"user\",\n\t\t\tvalidate: (value) => {\n\t\t\t\tvalidateWebDavCredentials(value);\n\t\t\t\treturn value;\n\t\t\t},\n\t\t},\n\t\tsignal,\n\t);\n}\n\nasync function promptWebDavUrl(\n\tctx: ExtensionCommandContext,\n\tsignal?: AbortSignal,\n\tcurrent?: string,\n) {\n\treturn promptTextInput(\n\t\tctx,\n\t\t\"WebDAV collection URL\\n\\nUse the HTTPS WebDAV URL from your provider, not its web login page.\",\n\t\t{\n\t\t\t...(current\n\t\t\t\t? { defaultValue: current }\n\t\t\t\t: { example: \"https://cloud.example.com/remote.php/dav/files/user\" }),\n\t\t\tvalidate: (value) => {\n\t\t\t\tconst url = normalizeWebDavUrl(value);\n\t\t\t\tif (!url) throw new Error(\"WebDAV URL is required.\");\n\t\t\t\treturn url;\n\t\t\t},\n\t\t},\n\t\tsignal,\n\t);\n}\n\nasync function select(\n\tctx: ExtensionCommandContext,\n\ttitle: string,\n\toptions: string[],\n\tsignal?: AbortSignal,\n) {\n\tconst value = await ctx.ui.select(title, options, { signal });\n\tsignal?.throwIfAborted();\n\treturn value;\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }