{
  "version": 3,
  "sources": ["../../src/sync-errors.ts", "../../src/sync-format.ts"],
  "sourcesContent": ["import type { SyncDecision } from \"./sync-decision.js\";\n\nexport class SetupPullRequiresUiError extends Error {}\n\nexport class SyncDecisionRequiredError extends Error {\n\treadonly decision: SyncDecision;\n\n\tconstructor(decision: SyncDecision) {\n\t\tsuper(decision.directMessage);\n\t\tthis.name = \"SyncDecisionRequiredError\";\n\t\tthis.decision = decision;\n\t}\n}\n\nexport function isSyncDecisionRequiredError(error: unknown): error is SyncDecisionRequiredError {\n\treturn error instanceof SyncDecisionRequiredError;\n}\n\nexport function errorMessage(error: unknown) {\n\tconst message = error instanceof Error ? error.message : String(error);\n\t// biome-ignore lint/suspicious/noControlCharactersInRegex: Escape untrusted terminal controls.\n\treturn message.replace(/[\\u0000-\\u001f\\u007f-\\u009f]/gu, \"?\");\n}\n", "import { agentDir } from \"./config.js\";\n\nexport { errorMessage } from \"./sync-errors.js\";\n\nimport type { PublicationCapability, RemoteHead } from \"./sync-backend.js\";\nimport { inspectRemoteSelection } from \"./sync-policy.js\";\nimport { fileHashMap } from \"./sync-state.js\";\nimport type { CommonSyncConfig, Snapshot } from \"./types.js\";\n\nexport function formatDiff(local: Snapshot, remote: Snapshot) {\n\tconst localMap = fileHashMap(local);\n\tconst remoteMap = fileHashMap(remote);\n\tconst allPaths = [...new Set([...Object.keys(localMap), ...Object.keys(remoteMap)])].sort();\n\tconst lines = [\n\t\t`local: ${local.files.length} files`,\n\t\t`remote: ${remote.id} (${remote.files.length} files)`,\n\t\t\"\",\n\t];\n\tlet changed = 0;\n\tfor (const filePath of allPaths) {\n\t\tif (!localMap[filePath]) {\n\t\t\tlines.push(`Remote only: ${filePath}`);\n\t\t\tchanged += 1;\n\t\t} else if (!remoteMap[filePath]) {\n\t\t\tlines.push(`Local only: ${filePath}`);\n\t\t\tchanged += 1;\n\t\t} else if (localMap[filePath] !== remoteMap[filePath]) {\n\t\t\tlines.push(`Different: ${filePath}`);\n\t\t\tchanged += 1;\n\t\t}\n\t}\n\tif (changed === 0) lines.push(\"No file differences.\");\n\treturn lines.join(\"\\n\");\n}\n\nexport function formatSnapshotOnlyDiff(title: string, snapshot: Snapshot) {\n\treturn [`${title}: ${snapshot.id}`, ...snapshot.files.map((file) => `Add: ${file.path}`)].join(\n\t\t\"\\n\",\n\t);\n}\n\nexport function formatPushSummary(\n\tconfig: CommonSyncConfig,\n\tdestination: string,\n\tupload: Snapshot,\n\thead: RemoteHead | undefined,\n\tpreservedRemoteFileCount = 0,\n\tremote?: Snapshot,\n) {\n\treturn [\n\t\t`Sync setup: ${safeTerminalText(config.setupName)}`,\n\t\t`Storage location: ${safeTerminalText(destination)}`,\n\t\t`Upload ${upload.files.length} files from ${safeTerminalText(agentDir())}.`,\n\t\t`Sessions: ${upload.syncSessions ? \"included \u2014 may contain private conversations\" : \"not included\"}`,\n\t\thead ? `Remote latest: ${head.snapshotId}` : \"Remote latest: empty\",\n\t\t\"Publication effect: the backend's active head will reference the new immutable snapshot.\",\n\t\t...(remote && inspectRemoteSelection(config.include, remote).kind === \"different\"\n\t\t\t? [\n\t\t\t\t\t\"Included-content policy effect: replace the differing remote selection with this setup's local selection.\",\n\t\t\t\t]\n\t\t\t: []),\n\t\tformatPublicationPreview(remote, upload),\n\t\tpreservedRemoteFileCount > 0\n\t\t\t? `Possible secrets in locally managed files were scanned before this prompt; ${preservedRemoteFileCount} preserved remote file(s) were not rescanned.`\n\t\t\t: \"Possible secrets were scanned before this prompt.\",\n\t].join(\"\\n\");\n}\n\nexport function formatApplyPreview(local: Snapshot, remote: Snapshot) {\n\treturn formatDirectionalChanges(local, remote, {\n\t\tadd: \"Add locally\",\n\t\tupdate: \"Update locally\",\n\t\tremove: \"Remove locally\",\n\t});\n}\n\nexport function formatPullSummary(\n\tconfig: CommonSyncConfig,\n\tdestination: string,\n\tlocal: Snapshot,\n\tremote: Snapshot,\n\tprotectedSessionCount: number,\n) {\n\treturn [\n\t\t`Sync setup: ${safeTerminalText(config.setupName)}`,\n\t\t`Storage location: ${safeTerminalText(destination)}`,\n\t\t`Snapshot: ${safeTerminalText(remote.id)}`,\n\t\t`Sessions: ${remote.syncSessions ? \"included \u2014 may contain private conversations\" : \"not included\"}`,\n\t\t`Protected live sessions: ${protectedSessionCount || \"none\"}`,\n\t\tformatApplyPreview(local, remote),\n\t\t\"A local backup is created before these writes/deletes. The remote active snapshot is unchanged.\",\n\t].join(\"\\n\");\n}\n\nexport function formatRollbackSummary(\n\tconfig: CommonSyncConfig,\n\tdestination: string,\n\tlocal: Snapshot,\n\tremote: Snapshot,\n\trequestedSnapshot: string,\n\tprotectedSessionCount: number,\n) {\n\treturn [\n\t\t`Sync setup: ${safeTerminalText(config.setupName)}`,\n\t\t`Storage location: ${safeTerminalText(destination)}`,\n\t\t`Snapshot: ${safeTerminalText(requestedSnapshot)}`,\n\t\t`Sessions: ${remote.syncSessions ? \"included \u2014 may contain private conversations\" : \"not included\"}`,\n\t\t`Protected live sessions: ${protectedSessionCount || \"none\"}`,\n\t\tformatApplyPreview(local, remote),\n\t\t\"A local backup is created before applying; the backend's active head will change.\",\n\t].join(\"\\n\");\n}\n\nfunction formatPublicationPreview(remote: Snapshot | undefined, upload: Snapshot) {\n\tif (!remote) {\n\t\treturn [\"Remote is empty.\", ...upload.files.map((file) => `Add remotely: ${file.path}`)].join(\n\t\t\t\"\\n\",\n\t\t);\n\t}\n\treturn formatDirectionalChanges(remote, upload, {\n\t\tadd: \"Add remotely\",\n\t\tupdate: \"Update remotely\",\n\t\tremove: \"Remove remotely\",\n\t});\n}\n\nfunction formatDirectionalChanges(\n\tbefore: Snapshot,\n\tafter: Snapshot,\n\tlabels: { add: string; update: string; remove: string },\n) {\n\tconst beforeMap = fileHashMap(before);\n\tconst afterMap = fileHashMap(after);\n\tconst paths = [...new Set([...Object.keys(beforeMap), ...Object.keys(afterMap)])].sort();\n\tconst lines: string[] = [];\n\tfor (const filePath of paths) {\n\t\tif (!beforeMap[filePath]) lines.push(`${labels.add}: ${filePath}`);\n\t\telse if (!afterMap[filePath]) lines.push(`${labels.remove}: ${filePath}`);\n\t\telse if (beforeMap[filePath] !== afterMap[filePath])\n\t\t\tlines.push(`${labels.update}: ${filePath}`);\n\t}\n\tif (lines.length === 0) lines.push(\"No file changes.\");\n\treturn lines.join(\"\\n\");\n}\n\nexport function countPreservedRemoteFiles(local: Snapshot, upload: Snapshot) {\n\tconst localPaths = new Set(local.files.map((file) => file.path));\n\treturn upload.files.filter((file) => !localPaths.has(file.path)).length;\n}\n\nexport function publicationCapabilityDescription(capability: PublicationCapability) {\n\tswitch (capability) {\n\t\tcase \"lease-protected\":\n\t\t\treturn \"lease-protected (exact expected-ref update)\";\n\t\tcase \"atomic-conditional\":\n\t\t\treturn \"atomic-conditional (verified atomic precondition)\";\n\t\tcase \"conditional-required\":\n\t\t\treturn \"conditional-required (read-only until atomic preconditions are verified)\";\n\t\tcase \"read-check-write-verify\":\n\t\t\treturn \"read-check-write-verify (visible races rejected; simultaneous unseen races remain possible)\";\n\t}\n}\n\nexport function safeTerminalText(value: string) {\n\t// biome-ignore lint/suspicious/noControlCharactersInRegex: Escape untrusted terminal controls.\n\treturn value.replace(/[\\u0000-\\u001f\\u007f-\\u009f]/gu, \"?\");\n}\n\nexport function redact(value: string) {\n\treturn value.length <= 8 ? \"configured\" : `${value.slice(0, 4)}\u2026${value.slice(-4)}`;\n}\n"],
  "mappings": "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",
  "names": []
}
