codex-multi-auth 0.1.7 → 0.1.8

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 (57) hide show
  1. package/LICENSE +21 -1
  2. package/README.md +13 -0
  3. package/assets/readme-hero.svg +31 -31
  4. package/dist/index.d.ts +1 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -2
  7. package/dist/index.js.map +1 -1
  8. package/dist/lib/codex-cli/sync.d.ts +9 -16
  9. package/dist/lib/codex-cli/sync.d.ts.map +1 -1
  10. package/dist/lib/codex-cli/sync.js +51 -284
  11. package/dist/lib/codex-cli/sync.js.map +1 -1
  12. package/dist/lib/codex-manager/settings-hub.d.ts +44 -2
  13. package/dist/lib/codex-manager/settings-hub.d.ts.map +1 -1
  14. package/dist/lib/codex-manager/settings-hub.js +746 -117
  15. package/dist/lib/codex-manager/settings-hub.js.map +1 -1
  16. package/dist/lib/codex-manager.d.ts.map +1 -1
  17. package/dist/lib/codex-manager.js +3 -8
  18. package/dist/lib/codex-manager.js.map +1 -1
  19. package/dist/lib/context-overflow.js +10 -10
  20. package/dist/lib/named-backup-export.d.ts +69 -0
  21. package/dist/lib/named-backup-export.d.ts.map +1 -0
  22. package/dist/lib/named-backup-export.js +207 -0
  23. package/dist/lib/named-backup-export.js.map +1 -0
  24. package/dist/lib/oc-chatgpt-import-adapter.d.ts +64 -0
  25. package/dist/lib/oc-chatgpt-import-adapter.d.ts.map +1 -0
  26. package/dist/lib/oc-chatgpt-import-adapter.js +506 -0
  27. package/dist/lib/oc-chatgpt-import-adapter.js.map +1 -0
  28. package/dist/lib/oc-chatgpt-orchestrator.d.ts +80 -0
  29. package/dist/lib/oc-chatgpt-orchestrator.d.ts.map +1 -0
  30. package/dist/lib/oc-chatgpt-orchestrator.js +130 -0
  31. package/dist/lib/oc-chatgpt-orchestrator.js.map +1 -0
  32. package/dist/lib/oc-chatgpt-target-detection.d.ts +59 -0
  33. package/dist/lib/oc-chatgpt-target-detection.d.ts.map +1 -0
  34. package/dist/lib/oc-chatgpt-target-detection.js +327 -0
  35. package/dist/lib/oc-chatgpt-target-detection.js.map +1 -0
  36. package/dist/lib/prompts/codex.js +2 -2
  37. package/dist/lib/runtime-paths.d.ts.map +1 -1
  38. package/dist/lib/runtime-paths.js +21 -1
  39. package/dist/lib/runtime-paths.js.map +1 -1
  40. package/dist/lib/storage.d.ts +42 -3
  41. package/dist/lib/storage.d.ts.map +1 -1
  42. package/dist/lib/storage.js +519 -51
  43. package/dist/lib/storage.js.map +1 -1
  44. package/dist/lib/ui/copy.d.ts +15 -1
  45. package/dist/lib/ui/copy.d.ts.map +1 -1
  46. package/dist/lib/ui/copy.js +15 -1
  47. package/dist/lib/ui/copy.js.map +1 -1
  48. package/package.json +132 -133
  49. package/scripts/bench-format/hashline-v2.mjs +642 -642
  50. package/scripts/bench-format/render.mjs +496 -496
  51. package/scripts/bench-format/stats.mjs +54 -54
  52. package/scripts/bench-format/tasks.mjs +151 -151
  53. package/scripts/benchmark-render-dashboard.mjs +49 -49
  54. package/scripts/install-codex-auth.js +9 -9
  55. package/scripts/test-all-models.sh +7 -7
  56. package/scripts/test-model-matrix.js +138 -46
  57. package/scripts/validate-model-map.sh +7 -7
@@ -32,16 +32,16 @@ export function isContextOverflowError(status, bodyText) {
32
32
  /**
33
33
  * The message shown to users when context overflow occurs
34
34
  */
35
- const CONTEXT_OVERFLOW_MESSAGE = `[Plugin Notice] Context is too long for this model.
36
-
37
- Please use one of these commands to reduce context size:
38
-
39
- • **/compact** - Compress conversation history (recommended)
40
- • **/clear** - Start fresh with empty context
41
- • **/undo** - Remove recent messages
42
-
43
- Then retry your request.
44
-
35
+ const CONTEXT_OVERFLOW_MESSAGE = `[Plugin Notice] Context is too long for this model.
36
+
37
+ Please use one of these commands to reduce context size:
38
+
39
+ • **/compact** - Compress conversation history (recommended)
40
+ • **/clear** - Start fresh with empty context
41
+ • **/undo** - Remove recent messages
42
+
43
+ Then retry your request.
44
+
45
45
  Alternatively, you can switch to a model with a larger context window.`;
46
46
  /**
47
47
  * Creates a synthetic SSE response for context overflow errors.
@@ -0,0 +1,69 @@
1
+ export interface NamedBackupExportDependencies {
2
+ getStoragePath: () => string;
3
+ exportAccounts: (filePath: string, force?: boolean, beforeCommit?: (resolvedPath: string) => Promise<void> | void) => Promise<void>;
4
+ }
5
+ /**
6
+ * Validate and normalize a user-provided backup name into a safe `<name>.json` filename.
7
+ *
8
+ * Performs trimming, rejects path separators and traversal tokens, forbids rotation-style
9
+ * substrings and temporary suffixes, and enforces that the base name contains only
10
+ * letters, numbers, hyphens, and underscores. Checks that a resulting base name is non-empty
11
+ * and returns the base name with a `.json` extension appended.
12
+ *
13
+ * Notes:
14
+ * - Validation checks that are sensitive to case are performed using a lowercased form;
15
+ * this mirrors Windows case-insensitive filesystem behavior for prohibited patterns.
16
+ * - The function is synchronous and safe for concurrent use (pure string validation/normalization).
17
+ * - Token redaction: traversal tokens (`..`), path separators, rotation-style substrings,
18
+ * and temporary suffixes are rejected rather than sanitized.
19
+ *
20
+ * @param name - The user-provided filename or identifier (may include a `.json` extension)
21
+ * @returns The validated filename with a `.json` extension appended
22
+ * @throws Error if the name is empty, contains separators or traversal tokens, contains
23
+ * prohibited substrings, ends with an invalid temporary suffix, contains disallowed
24
+ * characters, or would result in an empty base name
25
+ */
26
+ export declare function normalizeNamedBackupFileName(name: string): string;
27
+ /**
28
+ * Compute the absolute path for the "backups" directory placed alongside the given storage path.
29
+ *
30
+ * This performs only path resolution and string manipulation; it does not access the filesystem and is insensitive to concurrent filesystem changes. It does not redact or sanitize tokens or sensitive substrings in `storagePath`. Note: other functions in this module handle Windows case-insensitive comparisons when validating paths.
31
+ *
32
+ * @param storagePath - Storage file or directory path (may be relative or absolute)
33
+ * @returns The resolved path to the backups directory adjacent to `storagePath` (i.e. dirname(storagePath)/backups)
34
+ */
35
+ export declare function getNamedBackupRoot(storagePath: string): string;
36
+ /**
37
+ * Resolve and validate a safe backup file path for a named backup inside the storage path's backups directory.
38
+ *
39
+ * @param name - User-provided backup name; will be normalized and validated (disallows path separators, `..`, prohibited substrings, and invalid suffixes such as `.tmp`/`.wal`) and the canonical filename (`*.json`) will be produced.
40
+ * @param storagePath - Base storage path used to locate the backups directory; path comparisons treat Windows paths case-insensitively.
41
+ * @returns The absolute, validated path to the backup file within the backups directory.
42
+ *
43
+ * Concurrency: this function only computes and validates the path and does not create files or directories; callers must handle concurrent filesystem operations (e.g., directory creation or file writes).
44
+ */
45
+ export declare function resolveNamedBackupPath(name: string, storagePath: string): string;
46
+ /**
47
+ * Create a named backup file inside the storage path's backups directory and return its resolved path.
48
+ *
49
+ * The provided `name` is validated and normalized (suffix, allowed characters, and prohibited substrings) and the
50
+ * backup root directory is created if missing. The export operation will be asked to write to the resolved path; a
51
+ * safety check ensures the final resolved path stays within the backups root.
52
+ * The delegated `beforeCommit` hook re-validates containment immediately before
53
+ * the storage layer commits the final rename, but callers should still serialize
54
+ * backup-root mutations rather than relying on path checks alone.
55
+ *
56
+ * Concurrency: callers should avoid concurrent exports that target the same `name` as behavior is unspecified.
57
+ * Windows behavior: file-name/path comparisons are case-insensitive and names are normalized to lowercase.
58
+ * Token rules: input `name` is checked to prevent path traversal, separators, rotation-style substrings, and certain
59
+ * invalid suffixes (e.g., `.tmp`, `.wal`); the final returned path always includes the `.json` extension.
60
+ *
61
+ * @param name - The desired backup file name (validated and normalized).
62
+ * @param dependencies - Object providing storage path resolution and the exportAccounts implementation.
63
+ * @param options.force - When true, request overwriting an existing backup.
64
+ * @returns The absolute path to the created backup file (including `.json`).
65
+ */
66
+ export declare function exportNamedBackupFile(name: string, dependencies: NamedBackupExportDependencies, options?: {
67
+ force?: boolean;
68
+ }): Promise<string>;
69
+ //# sourceMappingURL=named-backup-export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"named-backup-export.d.ts","sourceRoot":"","sources":["../../lib/named-backup-export.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,6BAA6B;IAC7C,cAAc,EAAE,MAAM,MAAM,CAAC;IAC7B,cAAc,EAAE,CACf,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,OAAO,EACf,YAAY,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,KACzD,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB;AA6ED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAwCjE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAK9D;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACrC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GACjB,MAAM,CAMR;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,qBAAqB,CAC1C,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,6BAA6B,EAC3C,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC3B,OAAO,CAAC,MAAM,CAAC,CAuBjB"}
@@ -0,0 +1,207 @@
1
+ import { existsSync, promises as fs, lstatSync, realpathSync } from "node:fs";
2
+ import { basename, dirname, isAbsolute, join, relative, resolve, } from "node:path";
3
+ import { resolvePath } from "./storage/paths.js";
4
+ const BACKUP_EXPORT_DIR_NAME = "backups";
5
+ const BACKUP_FILE_EXTENSION = ".json";
6
+ const BACKUP_SAFE_NAME_REGEX = /^[a-zA-Z0-9_-]+$/;
7
+ const BACKUP_WINDOWS_RESERVED_NAME_REGEX = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;
8
+ const BACKUP_INVALID_SUFFIXES = [".tmp", ".wal"];
9
+ const BACKUP_PROHIBITED_SUBSTRINGS = [".rotate."];
10
+ const inFlightNamedBackupExports = new Set();
11
+ /**
12
+ * Compute a canonical, comparison-ready filesystem path for the given input.
13
+ *
14
+ * Resolves the input to an absolute path, resolves symlinks (realpath) if the path exists, and on Windows converts the resulting canonical path to lowercase for case-insensitive comparisons. The function does not mask or redact any sensitive tokens contained in the path. Note: the returned value may become stale if the filesystem changes after this call (race conditions are possible).
15
+ *
16
+ * @param pathValue - The input filesystem path to normalize.
17
+ * @returns The canonicalized path suitable for equality or containment comparisons; on Windows the result is returned in lowercase.
18
+ */
19
+ function normalizePathForComparison(pathValue) {
20
+ const resolvedPath = resolve(pathValue);
21
+ const canonicalPath = existsSync(resolvedPath)
22
+ ? realpathSync(resolvedPath)
23
+ : resolvedPath;
24
+ return process.platform === "win32"
25
+ ? canonicalPath.toLowerCase()
26
+ : canonicalPath;
27
+ }
28
+ /**
29
+ * Ensures the resolved target path is located inside the resolved base directory.
30
+ *
31
+ * Validates that `baseDir` is not a symbolic link and that the canonical/resolved
32
+ * forms of `baseDir` and `targetPath` keep `targetPath` rooted under `baseDir`.
33
+ * On Windows, comparisons are performed in a case-insensitive manner via the
34
+ * normalization helper. Errors do not include the original path values.
35
+ *
36
+ * Concurrency: callers must avoid concurrently mutating the filesystem (for example
37
+ * creating/removing/moving symlinks or directories) between calling this function
38
+ * and any subsequent operations that rely on its result. `exportNamedBackupFile`
39
+ * performs a second containment check through the `beforeCommit` hook, but that
40
+ * revalidation narrows rather than eliminates time-of-check/time-of-use windows.
41
+ *
42
+ * @param baseDir - The directory to treat as the backup root; must remain stable during validation.
43
+ * @param targetPath - The candidate target file path that must reside within `baseDir`.
44
+ * @throws Error with message "Named backup path escapes the backup root" if `baseDir` is a symlink,
45
+ * if the canonical and resolved base paths differ, or if `targetPath` is not contained
46
+ * within `baseDir`.
47
+ */
48
+ function assertWithinDirectory(baseDir, targetPath) {
49
+ const resolvedBase = resolve(baseDir);
50
+ let baseStat = null;
51
+ try {
52
+ baseStat = lstatSync(resolvedBase);
53
+ }
54
+ catch (error) {
55
+ const code = error.code;
56
+ if (code !== "ENOENT") {
57
+ throw error;
58
+ }
59
+ }
60
+ if (baseStat) {
61
+ if (baseStat.isSymbolicLink()) {
62
+ throw new Error("Named backup path escapes the backup root");
63
+ }
64
+ const canonicalBase = realpathSync(resolvedBase);
65
+ const comparableCanonicalBase = process.platform === "win32"
66
+ ? canonicalBase.toLowerCase()
67
+ : canonicalBase;
68
+ const comparableResolvedBase = process.platform === "win32" ? resolvedBase.toLowerCase() : resolvedBase;
69
+ if (comparableCanonicalBase !== comparableResolvedBase) {
70
+ throw new Error("Named backup path escapes the backup root");
71
+ }
72
+ }
73
+ const normalizedBase = normalizePathForComparison(baseDir);
74
+ const targetParent = dirname(targetPath);
75
+ const normalizedTargetParent = normalizePathForComparison(targetParent);
76
+ const normalizedTarget = join(normalizedTargetParent, basename(targetPath));
77
+ const rel = relative(normalizedBase, normalizedTarget);
78
+ if (rel === "" || (!rel.startsWith("..") && !isAbsolute(rel))) {
79
+ return;
80
+ }
81
+ throw new Error("Named backup path escapes the backup root");
82
+ }
83
+ /**
84
+ * Validate and normalize a user-provided backup name into a safe `<name>.json` filename.
85
+ *
86
+ * Performs trimming, rejects path separators and traversal tokens, forbids rotation-style
87
+ * substrings and temporary suffixes, and enforces that the base name contains only
88
+ * letters, numbers, hyphens, and underscores. Checks that a resulting base name is non-empty
89
+ * and returns the base name with a `.json` extension appended.
90
+ *
91
+ * Notes:
92
+ * - Validation checks that are sensitive to case are performed using a lowercased form;
93
+ * this mirrors Windows case-insensitive filesystem behavior for prohibited patterns.
94
+ * - The function is synchronous and safe for concurrent use (pure string validation/normalization).
95
+ * - Token redaction: traversal tokens (`..`), path separators, rotation-style substrings,
96
+ * and temporary suffixes are rejected rather than sanitized.
97
+ *
98
+ * @param name - The user-provided filename or identifier (may include a `.json` extension)
99
+ * @returns The validated filename with a `.json` extension appended
100
+ * @throws Error if the name is empty, contains separators or traversal tokens, contains
101
+ * prohibited substrings, ends with an invalid temporary suffix, contains disallowed
102
+ * characters, or would result in an empty base name
103
+ */
104
+ export function normalizeNamedBackupFileName(name) {
105
+ const trimmed = (name ?? "").trim();
106
+ if (trimmed.length === 0) {
107
+ throw new Error("Named backup requires a non-empty filename");
108
+ }
109
+ if (/[\\/]/.test(trimmed)) {
110
+ throw new Error("Backup filename must not contain path separators");
111
+ }
112
+ if (trimmed.includes("..")) {
113
+ throw new Error("Backup filename must not contain traversal tokens");
114
+ }
115
+ const lower = trimmed.toLowerCase();
116
+ if (BACKUP_PROHIBITED_SUBSTRINGS.some((value) => lower.includes(value))) {
117
+ throw new Error("Backup filename may not contain rotation-style sequences");
118
+ }
119
+ const hasJsonExtension = lower.endsWith(BACKUP_FILE_EXTENSION);
120
+ const baseName = hasJsonExtension
121
+ ? trimmed.slice(0, trimmed.length - BACKUP_FILE_EXTENSION.length)
122
+ : trimmed;
123
+ if (baseName.length === 0) {
124
+ throw new Error("Backup filename cannot be just an extension");
125
+ }
126
+ const baseLower = baseName.toLowerCase();
127
+ if (BACKUP_INVALID_SUFFIXES.some((value) => baseLower.endsWith(value))) {
128
+ throw new Error("Backup filename may not end with temporary suffixes");
129
+ }
130
+ if (BACKUP_WINDOWS_RESERVED_NAME_REGEX.test(baseName)) {
131
+ throw new Error("Backup filename may not use a reserved Windows device name");
132
+ }
133
+ if (!BACKUP_SAFE_NAME_REGEX.test(baseName)) {
134
+ throw new Error("Backup filename may only contain letters, numbers, hyphens, and underscores; dots (.) are not allowed");
135
+ }
136
+ return `${baseName}${BACKUP_FILE_EXTENSION}`;
137
+ }
138
+ /**
139
+ * Compute the absolute path for the "backups" directory placed alongside the given storage path.
140
+ *
141
+ * This performs only path resolution and string manipulation; it does not access the filesystem and is insensitive to concurrent filesystem changes. It does not redact or sanitize tokens or sensitive substrings in `storagePath`. Note: other functions in this module handle Windows case-insensitive comparisons when validating paths.
142
+ *
143
+ * @param storagePath - Storage file or directory path (may be relative or absolute)
144
+ * @returns The resolved path to the backups directory adjacent to `storagePath` (i.e. dirname(storagePath)/backups)
145
+ */
146
+ export function getNamedBackupRoot(storagePath) {
147
+ const resolvedStoragePath = resolvePath(storagePath);
148
+ return resolvePath(join(dirname(resolvedStoragePath), BACKUP_EXPORT_DIR_NAME));
149
+ }
150
+ /**
151
+ * Resolve and validate a safe backup file path for a named backup inside the storage path's backups directory.
152
+ *
153
+ * @param name - User-provided backup name; will be normalized and validated (disallows path separators, `..`, prohibited substrings, and invalid suffixes such as `.tmp`/`.wal`) and the canonical filename (`*.json`) will be produced.
154
+ * @param storagePath - Base storage path used to locate the backups directory; path comparisons treat Windows paths case-insensitively.
155
+ * @returns The absolute, validated path to the backup file within the backups directory.
156
+ *
157
+ * Concurrency: this function only computes and validates the path and does not create files or directories; callers must handle concurrent filesystem operations (e.g., directory creation or file writes).
158
+ */
159
+ export function resolveNamedBackupPath(name, storagePath) {
160
+ const fileName = normalizeNamedBackupFileName(name);
161
+ const backupRoot = getNamedBackupRoot(storagePath);
162
+ const candidate = resolvePath(join(backupRoot, fileName));
163
+ assertWithinDirectory(backupRoot, candidate);
164
+ return candidate;
165
+ }
166
+ /**
167
+ * Create a named backup file inside the storage path's backups directory and return its resolved path.
168
+ *
169
+ * The provided `name` is validated and normalized (suffix, allowed characters, and prohibited substrings) and the
170
+ * backup root directory is created if missing. The export operation will be asked to write to the resolved path; a
171
+ * safety check ensures the final resolved path stays within the backups root.
172
+ * The delegated `beforeCommit` hook re-validates containment immediately before
173
+ * the storage layer commits the final rename, but callers should still serialize
174
+ * backup-root mutations rather than relying on path checks alone.
175
+ *
176
+ * Concurrency: callers should avoid concurrent exports that target the same `name` as behavior is unspecified.
177
+ * Windows behavior: file-name/path comparisons are case-insensitive and names are normalized to lowercase.
178
+ * Token rules: input `name` is checked to prevent path traversal, separators, rotation-style substrings, and certain
179
+ * invalid suffixes (e.g., `.tmp`, `.wal`); the final returned path always includes the `.json` extension.
180
+ *
181
+ * @param name - The desired backup file name (validated and normalized).
182
+ * @param dependencies - Object providing storage path resolution and the exportAccounts implementation.
183
+ * @param options.force - When true, request overwriting an existing backup.
184
+ * @returns The absolute path to the created backup file (including `.json`).
185
+ */
186
+ export async function exportNamedBackupFile(name, dependencies, options) {
187
+ const storagePath = dependencies.getStoragePath();
188
+ const destination = resolveNamedBackupPath(name, storagePath);
189
+ const backupRoot = getNamedBackupRoot(storagePath);
190
+ const exportKey = normalizePathForComparison(destination);
191
+ if (!options?.force && inFlightNamedBackupExports.has(exportKey)) {
192
+ throw new Error(`File already exists: ${destination}`);
193
+ }
194
+ assertWithinDirectory(dirname(backupRoot), backupRoot);
195
+ await fs.mkdir(backupRoot, { recursive: true });
196
+ inFlightNamedBackupExports.add(exportKey);
197
+ try {
198
+ await dependencies.exportAccounts(destination, options?.force === true, (resolvedPath) => {
199
+ assertWithinDirectory(backupRoot, resolvedPath);
200
+ });
201
+ return destination;
202
+ }
203
+ finally {
204
+ inFlightNamedBackupExports.delete(exportKey);
205
+ }
206
+ }
207
+ //# sourceMappingURL=named-backup-export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"named-backup-export.js","sourceRoot":"","sources":["../../lib/named-backup-export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import { type AccountStorageV3 } from "./storage.js";
2
+ type MatchStrategy = "accountId" | "email" | "refreshToken";
3
+ export type OcChatgptImportPayload = AccountStorageV3;
4
+ export type OcChatgptPreviewPayload = {
5
+ version: 3;
6
+ activeIndex: number;
7
+ activeIndexByFamily?: AccountStorageV3["activeIndexByFamily"];
8
+ accounts: OcChatgptAccountRef[];
9
+ };
10
+ export type OcChatgptAccountRef = {
11
+ accountId?: string;
12
+ email?: string;
13
+ refreshTokenLast4: string;
14
+ };
15
+ export type OcChatgptMergePreview = {
16
+ payload: OcChatgptPreviewPayload;
17
+ merged: AccountStorageV3;
18
+ toAdd: OcChatgptAccountRef[];
19
+ toUpdate: Array<{
20
+ previous: OcChatgptAccountRef;
21
+ next: OcChatgptAccountRef;
22
+ matchedBy: MatchStrategy;
23
+ }>;
24
+ toSkip: Array<{
25
+ source: OcChatgptAccountRef;
26
+ reason: string;
27
+ }>;
28
+ unchangedDestinationOnly: OcChatgptAccountRef[];
29
+ activeSelectionBehavior: "preserve-destination";
30
+ };
31
+ /**
32
+ * Produce a normalized AccountStorageV3 payload suitable for OC ChatGPT import.
33
+ *
34
+ * Normalizes and sanitizes the provided source storage for the target importer.
35
+ *
36
+ * @param source - The source AccountStorageV3 to normalize, or `null` to normalize an empty input.
37
+ * @returns A normalized AccountStorageV3 ready for import. WARNING: this object may include raw `refreshToken` values; redact or mask tokens before logging, persisting to logs, or transmitting to external systems.
38
+ *
39
+ * Concurrency notes: the function does not perform synchronization; callers are responsible for coordinating concurrent access to the source data.
40
+ *
41
+ * Filesystem note: the function performs in-memory transformations only and has no special behavior for Windows filesystem semantics.
42
+ */
43
+ export declare function buildOcChatgptImportPayload(source: AccountStorageV3 | null): OcChatgptImportPayload;
44
+ /**
45
+ * Produces a detailed merge preview and merged storage that reconciles a source and destination AccountStorageV3.
46
+ *
47
+ * Normalizes source and destination inputs, identifies accounts to add, update, or skip (with reasons), preserves
48
+ * destination-only unchanged accounts, and returns a merged AccountStorageV3 plus a preview payload. Refresh tokens
49
+ * in preview entries are redacted (masked to last four characters). The function is synchronous, stateless, performs
50
+ * no filesystem I/O (no Windows-specific behavior), and is safe to call concurrently from multiple callers.
51
+ *
52
+ * @param options.source - Source storage to import from; may be `null`.
53
+ * @param options.destination - Destination storage to merge into; may be `null`.
54
+ * @returns An OcChatgptMergePreview describing the normalized source preview (`payload`), the resulting merged storage
55
+ * (`merged`), lists of accounts to add (`toAdd`), accounts updated with previous/next summaries (`toUpdate`),
56
+ * skipped accounts with reasons (`toSkip`), destination-only unchanged accounts (`unchangedDestinationOnly`),
57
+ * and an `activeSelectionBehavior` hint.
58
+ */
59
+ export declare function previewOcChatgptImportMerge(options: {
60
+ source: AccountStorageV3 | null;
61
+ destination: AccountStorageV3 | null;
62
+ }): OcChatgptMergePreview;
63
+ export {};
64
+ //# sourceMappingURL=oc-chatgpt-import-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oc-chatgpt-import-adapter.d.ts","sourceRoot":"","sources":["../../lib/oc-chatgpt-import-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,KAAK,gBAAgB,EAErB,MAAM,cAAc,CAAC;AAEtB,KAAK,aAAa,GAAG,WAAW,GAAG,OAAO,GAAG,cAAc,CAAC;AAE5D,MAAM,MAAM,sBAAsB,GAAG,gBAAgB,CAAC;AAEtD,MAAM,MAAM,uBAAuB,GAAG;IACrC,OAAO,EAAE,CAAC,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;IAC9D,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IACnC,OAAO,EAAE,uBAAuB,CAAC;IACjC,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,EAAE,mBAAmB,EAAE,CAAC;IAC7B,QAAQ,EAAE,KAAK,CAAC;QACf,QAAQ,EAAE,mBAAmB,CAAC;QAC9B,IAAI,EAAE,mBAAmB,CAAC;QAC1B,SAAS,EAAE,aAAa,CAAC;KACzB,CAAC,CAAC;IACH,MAAM,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,mBAAmB,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/D,wBAAwB,EAAE,mBAAmB,EAAE,CAAC;IAChD,uBAAuB,EAAE,sBAAsB,CAAC;CAChD,CAAC;AA8dF;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CAC1C,MAAM,EAAE,gBAAgB,GAAG,IAAI,GAC7B,sBAAsB,CAGxB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE;IACpD,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAChC,WAAW,EAAE,gBAAgB,GAAG,IAAI,CAAC;CACrC,GAAG,qBAAqB,CA2ExB"}