@narumitw/pi-sync 0.50.1 → 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.
Files changed (24) hide show
  1. package/README.md +5 -4
  2. package/dist/chunks/{chunk-S7YBZR42.ts → chunk-5B3FXBLE.ts} +29 -7
  3. package/dist/chunks/chunk-5B3FXBLE.ts.map +7 -0
  4. package/dist/chunks/{chunk-KW7YQEZN.ts → chunk-DHVFS4QK.ts} +16 -15
  5. package/dist/chunks/chunk-DHVFS4QK.ts.map +7 -0
  6. package/dist/chunks/{chunk-4CHTZMEO.ts → chunk-YDWUZVPN.ts} +14 -13
  7. package/dist/chunks/{chunk-4CHTZMEO.ts.map → chunk-YDWUZVPN.ts.map} +2 -2
  8. package/dist/chunks/{chunk-G4RNQQZS.ts → chunk-YHEMENKV.ts} +2 -2
  9. package/dist/chunks/{manager-result-dispatcher-FKIBM3GO.ts → manager-result-dispatcher-ASKGOSW5.ts} +3 -3
  10. package/dist/chunks/{manager-ui-R3XPUFFS.ts → manager-ui-IPAOAWZA.ts} +8 -8
  11. package/dist/chunks/{remote-selection-ui-D7RBRJNL.ts → remote-selection-ui-QDNR7WEI.ts} +2 -2
  12. package/dist/chunks/{setup-wizard-IUB6ESEU.ts → setup-wizard-JUJZYNNM.ts} +2 -2
  13. package/dist/index.ts +4 -4
  14. package/package.json +1 -1
  15. package/src/ui/cancellable-operation.ts +14 -22
  16. package/src/ui/secret-input.ts +15 -23
  17. package/src/ui/sync-attention.ts +37 -13
  18. package/dist/chunks/chunk-KW7YQEZN.ts.map +0 -7
  19. package/dist/chunks/chunk-S7YBZR42.ts.map +0 -7
  20. /package/dist/chunks/{chunk-G4RNQQZS.ts.map → chunk-YHEMENKV.ts.map} +0 -0
  21. /package/dist/chunks/{manager-result-dispatcher-FKIBM3GO.ts.map → manager-result-dispatcher-ASKGOSW5.ts.map} +0 -0
  22. /package/dist/chunks/{manager-ui-R3XPUFFS.ts.map → manager-ui-IPAOAWZA.ts.map} +0 -0
  23. /package/dist/chunks/{remote-selection-ui-D7RBRJNL.ts.map → remote-selection-ui-QDNR7WEI.ts.map} +0 -0
  24. /package/dist/chunks/{setup-wizard-IUB6ESEU.ts.map → setup-wizard-JUJZYNNM.ts.map} +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
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/ui/sync-attention.ts"],
4
- "sourcesContent": ["import type { ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { truncateToWidth } from \"@earendil-works/pi-tui\";\nimport { syncCheckConfigFingerprint, syncConfigReviewFingerprint } from \"../settings/config.js\";\nimport type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport type { StartupObservation } from \"../sync/sync-inspection.js\";\nimport {\n\tcompareSyncInclude,\n\ttype RemoteSelectionDecision,\n\tsameSyncInclude,\n} from \"../sync/sync-policy.js\";\nimport { safeTerminalText } from \"./terminal-text.js\";\n\nconst STATUS_KEY = \"sync\";\nconst WIDGET_KEY = \"sync:attention\";\n\nexport type SyncAttentionOrigin = \"sync\" | \"pull\" | \"push\";\n\nexport interface SyncAttentionState {\n\tdecision: RemoteSelectionDecision;\n\torigin: SyncAttentionOrigin;\n\toffered: boolean;\n}\n\nexport function syncAttentionMatchesConfig(attention: SyncAttentionState, config: AnySyncConfig) {\n\treturn (\n\t\tattention.decision.setupName === config.setupName &&\n\t\tattention.decision.configIdentity === syncConfigReviewFingerprint(config) &&\n\t\tsameSyncInclude(attention.decision.localInclude, config.include)\n\t);\n}\n\nexport interface SyncAttentionController {\n\tobserve(observation: StartupObservation): void;\n\tobservation(): StartupObservation | undefined;\n\tclearObservation(): void;\n\tnotifyObservation(ctx: ExtensionContext): void;\n\tset(decision: RemoteSelectionDecision, origin: SyncAttentionOrigin): void;\n\tcurrent(): SyncAttentionState | undefined;\n\tmarkOffered(): boolean;\n\tclear(ctx: ExtensionContext): void;\n\treset(ctx: ExtensionContext): void;\n\tpublish(ctx: ExtensionContext, signal?: AbortSignal): Promise<void>;\n}\n\nexport function createSyncAttentionController(): SyncAttentionController {\n\tlet state: SyncAttentionState | undefined;\n\tlet observation: StartupObservation | undefined;\n\tlet generation = 0;\n\n\treturn {\n\t\tobserve(value) {\n\t\t\tgeneration++;\n\t\t\tobservation = value;\n\t\t},\n\t\tobservation() {\n\t\t\treturn observation;\n\t\t},\n\t\tclearObservation() {\n\t\t\tgeneration++;\n\t\t\tobservation = undefined;\n\t\t},\n\t\tnotifyObservation(ctx) {\n\t\t\tif (observation && observationNeedsAttention(observation)) {\n\t\t\t\tctx.ui.notify(observationLines(observation).join(\"\\n\"), \"warning\");\n\t\t\t}\n\t\t},\n\t\tset(decision, origin) {\n\t\t\tgeneration++;\n\t\t\tstate = { decision, origin, offered: false };\n\t\t},\n\t\tcurrent() {\n\t\t\treturn state;\n\t\t},\n\t\tmarkOffered() {\n\t\t\tif (!state || state.offered) return false;\n\t\t\tstate = { ...state, offered: true };\n\t\t\treturn true;\n\t\t},\n\t\tclear(ctx) {\n\t\t\tgeneration++;\n\t\t\tstate = undefined;\n\t\t\tclearAttentionPresentation(ctx);\n\t\t},\n\t\treset(ctx) {\n\t\t\tgeneration++;\n\t\t\tstate = undefined;\n\t\t\tobservation = undefined;\n\t\t\tclearAttentionPresentation(ctx);\n\t\t},\n\t\tasync publish(ctx, signal) {\n\t\t\tconst currentGeneration = ++generation;\n\t\t\tif (signal?.aborted) return;\n\t\t\tif (!state && (!observation || !observationNeedsAttention(observation))) {\n\t\t\t\tclearAttentionPresentation(ctx);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst presentation = state\n\t\t\t\t? attentionPresentation(state.decision)\n\t\t\t\t: {\n\t\t\t\t\t\tstatus: \"changes to review\",\n\t\t\t\t\t\tlines: observationLines(observation as StartupObservation),\n\t\t\t\t\t};\n\t\t\tif (ctx.mode !== \"tui\") {\n\t\t\t\tctx.ui.setStatus(STATUS_KEY, presentation.status);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Keep Kit outside the eager startup graph; module loading owns no cancellable resources.\n\t\t\tconst { EditorStatusWidget } = await import(\"./attention-widget.js\");\n\t\t\tif (generation !== currentGeneration || signal?.aborted) return;\n\t\t\tctx.ui.setStatus(STATUS_KEY, presentation.status);\n\t\t\tctx.ui.setWidget(\n\t\t\t\tWIDGET_KEY,\n\t\t\t\t(_tui, theme) =>\n\t\t\t\t\tnew EditorStatusWidget({\n\t\t\t\t\t\ttheme,\n\t\t\t\t\t\trenderBody: (width) =>\n\t\t\t\t\t\t\tpresentation.lines.map((line, index) =>\n\t\t\t\t\t\t\t\twidth === 0\n\t\t\t\t\t\t\t\t\t? \"\"\n\t\t\t\t\t\t\t\t\t: truncateToWidth(theme.fg(index === 0 ? \"warning\" : \"muted\", line), width, \"\u2026\"),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t};\n}\n\nfunction attentionPresentation(decision: RemoteSelectionDecision) {\n\tconst setupName = safeTerminalText(decision.setupName);\n\tconst comparison = compareSyncInclude(decision.localInclude, decision.remoteInclude);\n\tconst difference =\n\t\tcomparison.remoteOnly.length === 0 && comparison.localOnly.length === 0\n\t\t\t? \"Only list order differs\"\n\t\t\t: `Remote ${comparison.remoteOnly.length} \u00B7 Device ${comparison.localOnly.length}`;\n\treturn {\n\t\tstatus: \"review needed\",\n\t\tlines: [`Pi Sync needs review \u00B7 ${setupName}`, difference, \"No changes \u00B7 Run /sync to review\"],\n\t};\n}\n\nexport function observationMatchesConfig(observation: StartupObservation, config: AnySyncConfig) {\n\treturn observation.configIdentity === syncCheckConfigFingerprint(config);\n}\n\nexport function observationSummary(observation: StartupObservation) {\n\tconst result = observation.inspection;\n\tif (result.emptyInclude) return \"No included content selected\";\n\tif (result.selectionState?.kind === \"different\")\n\t\treturn \"Synced-content list differs; review needed\";\n\tif (result.firstSync)\n\t\treturn result.head\n\t\t\t? \"No sync baseline; review remote and local content\"\n\t\t\t: \"Remote empty; no sync baseline\";\n\tif (!result.head) return \"Remote snapshot missing; review needed\";\n\tif (result.localChanged && result.remoteChanged)\n\t\treturn \"Local and remote changed since last sync; review needed\";\n\tif (result.remoteChanged) return \"Remote changed since last sync\";\n\tif (result.localChanged) return \"Local content changed since last sync\";\n\tif (result.selectionState?.kind === \"legacy\")\n\t\treturn \"Legacy remote has no authoritative content list\";\n\treturn \"No changes detected since last sync\";\n}\n\nexport function observationNeedsAttention(observation: StartupObservation) {\n\tconst result = observation.inspection;\n\treturn (\n\t\tresult.emptyInclude ||\n\t\tresult.firstSync ||\n\t\t!result.head ||\n\t\tresult.localChanged ||\n\t\tresult.remoteChanged ||\n\t\tresult.selectionState?.kind !== \"same\"\n\t);\n}\n\nfunction observationLines(observation: StartupObservation) {\n\treturn [\n\t\t`Pi Sync check \u00B7 ${safeTerminalText(observation.setupName)}`,\n\t\tobservationSummary(observation),\n\t\t\"No startup transfer \u00B7 Run /sync to review\",\n\t];\n}\n\nfunction clearAttentionPresentation(ctx: ExtensionContext) {\n\tctx.ui.setStatus(STATUS_KEY, undefined);\n\tctx.ui.setWidget(WIDGET_KEY, undefined);\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }