@savestate/cli 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/__tests__/progress.test.d.ts +5 -0
- package/dist/cli/__tests__/progress.test.d.ts.map +1 -0
- package/dist/cli/__tests__/progress.test.js +212 -0
- package/dist/cli/__tests__/progress.test.js.map +1 -0
- package/dist/cli/__tests__/signal-handler.test.d.ts +5 -0
- package/dist/cli/__tests__/signal-handler.test.d.ts.map +1 -0
- package/dist/cli/__tests__/signal-handler.test.js +99 -0
- package/dist/cli/__tests__/signal-handler.test.js.map +1 -0
- package/dist/cli/__tests__/summary.test.d.ts +5 -0
- package/dist/cli/__tests__/summary.test.d.ts.map +1 -0
- package/dist/cli/__tests__/summary.test.js +242 -0
- package/dist/cli/__tests__/summary.test.js.map +1 -0
- package/dist/cli/index.d.ts +10 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +10 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/progress.d.ts +86 -0
- package/dist/cli/progress.d.ts.map +1 -0
- package/dist/cli/progress.js +205 -0
- package/dist/cli/progress.js.map +1 -0
- package/dist/cli/prompts.d.ts +49 -0
- package/dist/cli/prompts.d.ts.map +1 -0
- package/dist/cli/prompts.js +266 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/cli/signal-handler.d.ts +63 -0
- package/dist/cli/signal-handler.d.ts.map +1 -0
- package/dist/cli/signal-handler.js +165 -0
- package/dist/cli/signal-handler.js.map +1 -0
- package/dist/cli/summary.d.ts +33 -0
- package/dist/cli/summary.d.ts.map +1 -0
- package/dist/cli/summary.js +296 -0
- package/dist/cli/summary.js.map +1 -0
- package/dist/cli.js +7 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/migrate.d.ts +18 -4
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +324 -163
- package/dist/commands/migrate.js.map +1 -1
- package/dist/migrate/__tests__/capabilities.test.d.ts +7 -0
- package/dist/migrate/__tests__/capabilities.test.d.ts.map +1 -0
- package/dist/migrate/__tests__/capabilities.test.js +90 -0
- package/dist/migrate/__tests__/capabilities.test.js.map +1 -0
- package/dist/migrate/__tests__/chatgpt-loader.test.d.ts +7 -0
- package/dist/migrate/__tests__/chatgpt-loader.test.d.ts.map +1 -0
- package/dist/migrate/__tests__/chatgpt-loader.test.js +889 -0
- package/dist/migrate/__tests__/chatgpt-loader.test.js.map +1 -0
- package/dist/migrate/__tests__/claude-loader.test.d.ts +7 -0
- package/dist/migrate/__tests__/claude-loader.test.d.ts.map +1 -0
- package/dist/migrate/__tests__/claude-loader.test.js +544 -0
- package/dist/migrate/__tests__/claude-loader.test.js.map +1 -0
- package/dist/migrate/__tests__/edge-cases.test.d.ts +7 -0
- package/dist/migrate/__tests__/edge-cases.test.d.ts.map +1 -0
- package/dist/migrate/__tests__/edge-cases.test.js +787 -0
- package/dist/migrate/__tests__/edge-cases.test.js.map +1 -0
- package/dist/migrate/__tests__/error-recovery.test.d.ts +7 -0
- package/dist/migrate/__tests__/error-recovery.test.d.ts.map +1 -0
- package/dist/migrate/__tests__/error-recovery.test.js +461 -0
- package/dist/migrate/__tests__/error-recovery.test.js.map +1 -0
- package/dist/migrate/__tests__/integration.test.d.ts +7 -0
- package/dist/migrate/__tests__/integration.test.d.ts.map +1 -0
- package/dist/migrate/__tests__/integration.test.js +536 -0
- package/dist/migrate/__tests__/integration.test.js.map +1 -0
- package/dist/migrate/__tests__/orchestrator.test.d.ts +8 -0
- package/dist/migrate/__tests__/orchestrator.test.d.ts.map +1 -0
- package/dist/migrate/__tests__/orchestrator.test.js +355 -0
- package/dist/migrate/__tests__/orchestrator.test.js.map +1 -0
- package/dist/migrate/__tests__/performance.test.d.ts +7 -0
- package/dist/migrate/__tests__/performance.test.d.ts.map +1 -0
- package/dist/migrate/__tests__/performance.test.js +478 -0
- package/dist/migrate/__tests__/performance.test.js.map +1 -0
- package/dist/migrate/__tests__/registry.test.d.ts +7 -0
- package/dist/migrate/__tests__/registry.test.d.ts.map +1 -0
- package/dist/migrate/__tests__/registry.test.js +167 -0
- package/dist/migrate/__tests__/registry.test.js.map +1 -0
- package/dist/migrate/compatibility.d.ts +47 -0
- package/dist/migrate/compatibility.d.ts.map +1 -0
- package/dist/migrate/compatibility.js +468 -0
- package/dist/migrate/compatibility.js.map +1 -0
- package/dist/migrate/extractors/__tests__/chatgpt.test.d.ts +12 -0
- package/dist/migrate/extractors/__tests__/chatgpt.test.d.ts.map +1 -0
- package/dist/migrate/extractors/__tests__/chatgpt.test.js +522 -0
- package/dist/migrate/extractors/__tests__/chatgpt.test.js.map +1 -0
- package/dist/migrate/extractors/__tests__/claude.test.d.ts +12 -0
- package/dist/migrate/extractors/__tests__/claude.test.d.ts.map +1 -0
- package/dist/migrate/extractors/__tests__/claude.test.js +789 -0
- package/dist/migrate/extractors/__tests__/claude.test.js.map +1 -0
- package/dist/migrate/extractors/chatgpt.d.ts +70 -0
- package/dist/migrate/extractors/chatgpt.d.ts.map +1 -0
- package/dist/migrate/extractors/chatgpt.js +791 -0
- package/dist/migrate/extractors/chatgpt.js.map +1 -0
- package/dist/migrate/extractors/claude.d.ts +69 -0
- package/dist/migrate/extractors/claude.d.ts.map +1 -0
- package/dist/migrate/extractors/claude.js +1136 -0
- package/dist/migrate/extractors/claude.js.map +1 -0
- package/dist/migrate/extractors/registry.js +6 -4
- package/dist/migrate/extractors/registry.js.map +1 -1
- package/dist/migrate/index.d.ts +6 -1
- package/dist/migrate/index.d.ts.map +1 -1
- package/dist/migrate/index.js +12 -1
- package/dist/migrate/index.js.map +1 -1
- package/dist/migrate/loaders/chatgpt.d.ts +72 -0
- package/dist/migrate/loaders/chatgpt.d.ts.map +1 -0
- package/dist/migrate/loaders/chatgpt.js +691 -0
- package/dist/migrate/loaders/chatgpt.js.map +1 -0
- package/dist/migrate/loaders/claude.d.ts +61 -0
- package/dist/migrate/loaders/claude.d.ts.map +1 -0
- package/dist/migrate/loaders/claude.js +433 -0
- package/dist/migrate/loaders/claude.js.map +1 -0
- package/dist/migrate/loaders/registry.js +6 -4
- package/dist/migrate/loaders/registry.js.map +1 -1
- package/dist/migrate/orchestrator.d.ts +75 -1
- package/dist/migrate/orchestrator.d.ts.map +1 -1
- package/dist/migrate/orchestrator.js +215 -19
- package/dist/migrate/orchestrator.js.map +1 -1
- package/dist/migrate/testing/index.d.ts +28 -0
- package/dist/migrate/testing/index.d.ts.map +1 -0
- package/dist/migrate/testing/index.js +55 -0
- package/dist/migrate/testing/index.js.map +1 -0
- package/dist/migrate/testing/mock-extractor.d.ts +30 -0
- package/dist/migrate/testing/mock-extractor.d.ts.map +1 -0
- package/dist/migrate/testing/mock-extractor.js +137 -0
- package/dist/migrate/testing/mock-extractor.js.map +1 -0
- package/dist/migrate/testing/mock-loader.d.ts +36 -0
- package/dist/migrate/testing/mock-loader.d.ts.map +1 -0
- package/dist/migrate/testing/mock-loader.js +81 -0
- package/dist/migrate/testing/mock-loader.js.map +1 -0
- package/dist/migrate/testing/mock-transformer.d.ts +26 -0
- package/dist/migrate/testing/mock-transformer.d.ts.map +1 -0
- package/dist/migrate/testing/mock-transformer.js +185 -0
- package/dist/migrate/testing/mock-transformer.js.map +1 -0
- package/dist/migrate/transformers/__tests__/chatgpt-to-claude.test.d.ts +5 -0
- package/dist/migrate/transformers/__tests__/chatgpt-to-claude.test.d.ts.map +1 -0
- package/dist/migrate/transformers/__tests__/chatgpt-to-claude.test.js +333 -0
- package/dist/migrate/transformers/__tests__/chatgpt-to-claude.test.js.map +1 -0
- package/dist/migrate/transformers/__tests__/claude-to-chatgpt.test.d.ts +5 -0
- package/dist/migrate/transformers/__tests__/claude-to-chatgpt.test.d.ts.map +1 -0
- package/dist/migrate/transformers/__tests__/claude-to-chatgpt.test.js +333 -0
- package/dist/migrate/transformers/__tests__/claude-to-chatgpt.test.js.map +1 -0
- package/dist/migrate/transformers/__tests__/rules.test.d.ts +5 -0
- package/dist/migrate/transformers/__tests__/rules.test.d.ts.map +1 -0
- package/dist/migrate/transformers/__tests__/rules.test.js +375 -0
- package/dist/migrate/transformers/__tests__/rules.test.js.map +1 -0
- package/dist/migrate/transformers/chatgpt-to-claude.d.ts +40 -0
- package/dist/migrate/transformers/chatgpt-to-claude.d.ts.map +1 -0
- package/dist/migrate/transformers/chatgpt-to-claude.js +443 -0
- package/dist/migrate/transformers/chatgpt-to-claude.js.map +1 -0
- package/dist/migrate/transformers/claude-to-chatgpt.d.ts +41 -0
- package/dist/migrate/transformers/claude-to-chatgpt.d.ts.map +1 -0
- package/dist/migrate/transformers/claude-to-chatgpt.js +532 -0
- package/dist/migrate/transformers/claude-to-chatgpt.js.map +1 -0
- package/dist/migrate/transformers/registry.js +6 -4
- package/dist/migrate/transformers/registry.js.map +1 -1
- package/dist/migrate/transformers/rules.d.ts +168 -0
- package/dist/migrate/transformers/rules.d.ts.map +1 -0
- package/dist/migrate/transformers/rules.js +487 -0
- package/dist/migrate/transformers/rules.js.map +1 -0
- package/dist/migrate/types.d.ts +2 -0
- package/dist/migrate/types.d.ts.map +1 -1
- package/package.json +7 -2
|
@@ -0,0 +1,787 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge Case Tests for Migration Wizard
|
|
3
|
+
*
|
|
4
|
+
* Tests boundary conditions and unusual scenarios.
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
7
|
+
import { existsSync } from 'node:fs';
|
|
8
|
+
import { rm, mkdir } from 'node:fs/promises';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { tmpdir } from 'node:os';
|
|
11
|
+
import { MigrationOrchestrator } from '../orchestrator.js';
|
|
12
|
+
import { registerMockPlugins } from '../testing/index.js';
|
|
13
|
+
import { ChatGPTToClaudeTransformer } from '../transformers/chatgpt-to-claude.js';
|
|
14
|
+
import { registerTransformer } from '../transformers/registry.js';
|
|
15
|
+
describe('Edge Case Tests', () => {
|
|
16
|
+
let testWorkDir;
|
|
17
|
+
beforeEach(async () => {
|
|
18
|
+
testWorkDir = join(tmpdir(), `savestate-edge-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
19
|
+
await mkdir(testWorkDir, { recursive: true });
|
|
20
|
+
});
|
|
21
|
+
afterEach(async () => {
|
|
22
|
+
if (existsSync(testWorkDir)) {
|
|
23
|
+
await rm(testWorkDir, { recursive: true, force: true });
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
describe('Empty Source Account', () => {
|
|
27
|
+
it('should handle account with no data to migrate', async () => {
|
|
28
|
+
const emptyBundle = {
|
|
29
|
+
version: '1.0',
|
|
30
|
+
id: 'bundle_empty',
|
|
31
|
+
source: {
|
|
32
|
+
platform: 'chatgpt',
|
|
33
|
+
extractedAt: new Date().toISOString(),
|
|
34
|
+
extractorVersion: '1.0.0',
|
|
35
|
+
},
|
|
36
|
+
contents: {},
|
|
37
|
+
metadata: {
|
|
38
|
+
totalItems: 0,
|
|
39
|
+
itemCounts: {
|
|
40
|
+
instructions: 0,
|
|
41
|
+
memories: 0,
|
|
42
|
+
conversations: 0,
|
|
43
|
+
files: 0,
|
|
44
|
+
customBots: 0,
|
|
45
|
+
},
|
|
46
|
+
warnings: [],
|
|
47
|
+
errors: [],
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
registerMockPlugins({
|
|
51
|
+
extractors: { chatgpt: { customBundle: emptyBundle } },
|
|
52
|
+
});
|
|
53
|
+
registerTransformer('chatgpt', 'claude', () => new ChatGPTToClaudeTransformer());
|
|
54
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
55
|
+
workDir: join(testWorkDir, 'migration-empty'),
|
|
56
|
+
});
|
|
57
|
+
const result = await orchestrator.run();
|
|
58
|
+
expect(result.success).toBe(true);
|
|
59
|
+
expect(result.loaded.instructions).toBe(false);
|
|
60
|
+
expect(result.loaded.memories).toBe(0);
|
|
61
|
+
expect(result.loaded.files).toBe(0);
|
|
62
|
+
});
|
|
63
|
+
it('should handle account with only empty containers', async () => {
|
|
64
|
+
const emptyContainersBundle = {
|
|
65
|
+
version: '1.0',
|
|
66
|
+
id: 'bundle_empty_containers',
|
|
67
|
+
source: {
|
|
68
|
+
platform: 'chatgpt',
|
|
69
|
+
extractedAt: new Date().toISOString(),
|
|
70
|
+
extractorVersion: '1.0.0',
|
|
71
|
+
},
|
|
72
|
+
contents: {
|
|
73
|
+
memories: { entries: [], count: 0 },
|
|
74
|
+
files: { files: [], count: 0, totalSize: 0 },
|
|
75
|
+
customBots: { bots: [], count: 0 },
|
|
76
|
+
conversations: {
|
|
77
|
+
path: 'conversations/',
|
|
78
|
+
count: 0,
|
|
79
|
+
messageCount: 0,
|
|
80
|
+
summaries: [],
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
metadata: {
|
|
84
|
+
totalItems: 0,
|
|
85
|
+
itemCounts: {
|
|
86
|
+
instructions: 0,
|
|
87
|
+
memories: 0,
|
|
88
|
+
conversations: 0,
|
|
89
|
+
files: 0,
|
|
90
|
+
customBots: 0,
|
|
91
|
+
},
|
|
92
|
+
warnings: [],
|
|
93
|
+
errors: [],
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
registerMockPlugins({
|
|
97
|
+
extractors: { chatgpt: { customBundle: emptyContainersBundle } },
|
|
98
|
+
});
|
|
99
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
100
|
+
workDir: join(testWorkDir, 'migration-empty-containers'),
|
|
101
|
+
});
|
|
102
|
+
const result = await orchestrator.run();
|
|
103
|
+
expect(result.success).toBe(true);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
describe('Very Large Accounts', () => {
|
|
107
|
+
it('should handle 1000+ conversations', async () => {
|
|
108
|
+
const conversations = Array.from({ length: 1000 }, (_, i) => ({
|
|
109
|
+
id: `conv_${i}`,
|
|
110
|
+
title: `Conversation ${i}`,
|
|
111
|
+
messageCount: Math.floor(Math.random() * 50) + 5,
|
|
112
|
+
createdAt: new Date(Date.now() - i * 86400000).toISOString(),
|
|
113
|
+
updatedAt: new Date(Date.now() - i * 43200000).toISOString(),
|
|
114
|
+
keyPoints: i % 10 === 0 ? [`Key point from conversation ${i}`] : undefined,
|
|
115
|
+
}));
|
|
116
|
+
const largeBundle = {
|
|
117
|
+
version: '1.0',
|
|
118
|
+
id: 'bundle_large_conversations',
|
|
119
|
+
source: {
|
|
120
|
+
platform: 'chatgpt',
|
|
121
|
+
extractedAt: new Date().toISOString(),
|
|
122
|
+
extractorVersion: '1.0.0',
|
|
123
|
+
},
|
|
124
|
+
contents: {
|
|
125
|
+
conversations: {
|
|
126
|
+
path: 'conversations/',
|
|
127
|
+
count: 1000,
|
|
128
|
+
messageCount: conversations.reduce((sum, c) => sum + c.messageCount, 0),
|
|
129
|
+
summaries: conversations,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
metadata: {
|
|
133
|
+
totalItems: 1000,
|
|
134
|
+
itemCounts: {
|
|
135
|
+
instructions: 0,
|
|
136
|
+
memories: 0,
|
|
137
|
+
conversations: 1000,
|
|
138
|
+
files: 0,
|
|
139
|
+
customBots: 0,
|
|
140
|
+
},
|
|
141
|
+
warnings: [],
|
|
142
|
+
errors: [],
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
registerMockPlugins({
|
|
146
|
+
extractors: { chatgpt: { customBundle: largeBundle } },
|
|
147
|
+
});
|
|
148
|
+
registerTransformer('chatgpt', 'claude', () => new ChatGPTToClaudeTransformer());
|
|
149
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
150
|
+
workDir: join(testWorkDir, 'migration-large-convs'),
|
|
151
|
+
});
|
|
152
|
+
const result = await orchestrator.run();
|
|
153
|
+
expect(result.success).toBe(true);
|
|
154
|
+
const bundle = orchestrator.getBundle();
|
|
155
|
+
expect(bundle?.contents.conversations?.count).toBe(1000);
|
|
156
|
+
});
|
|
157
|
+
it('should handle 500+ memories', async () => {
|
|
158
|
+
const memories = Array.from({ length: 500 }, (_, i) => ({
|
|
159
|
+
id: `mem_${i}`,
|
|
160
|
+
content: `Memory entry ${i}: User learned about ${['TypeScript', 'React', 'Node.js', 'Python', 'Go'][i % 5]}`,
|
|
161
|
+
createdAt: new Date(Date.now() - i * 3600000).toISOString(),
|
|
162
|
+
category: ['preferences', 'facts', 'context', 'decisions'][i % 4],
|
|
163
|
+
}));
|
|
164
|
+
const largeMemoriesBundle = {
|
|
165
|
+
version: '1.0',
|
|
166
|
+
id: 'bundle_large_memories',
|
|
167
|
+
source: {
|
|
168
|
+
platform: 'chatgpt',
|
|
169
|
+
extractedAt: new Date().toISOString(),
|
|
170
|
+
extractorVersion: '1.0.0',
|
|
171
|
+
},
|
|
172
|
+
contents: {
|
|
173
|
+
memories: { entries: memories, count: 500 },
|
|
174
|
+
},
|
|
175
|
+
metadata: {
|
|
176
|
+
totalItems: 500,
|
|
177
|
+
itemCounts: {
|
|
178
|
+
instructions: 0,
|
|
179
|
+
memories: 500,
|
|
180
|
+
conversations: 0,
|
|
181
|
+
files: 0,
|
|
182
|
+
customBots: 0,
|
|
183
|
+
},
|
|
184
|
+
warnings: [],
|
|
185
|
+
errors: [],
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
registerMockPlugins({
|
|
189
|
+
extractors: { chatgpt: { customBundle: largeMemoriesBundle } },
|
|
190
|
+
});
|
|
191
|
+
registerTransformer('chatgpt', 'claude', () => new ChatGPTToClaudeTransformer());
|
|
192
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
193
|
+
workDir: join(testWorkDir, 'migration-large-memories'),
|
|
194
|
+
});
|
|
195
|
+
const result = await orchestrator.run();
|
|
196
|
+
expect(result.success).toBe(true);
|
|
197
|
+
// Should have a warning about large number of memories
|
|
198
|
+
const bundle = orchestrator.getBundle();
|
|
199
|
+
expect(bundle?.metadata.warnings.some((w) => w.includes('memories') || w.includes('500'))).toBe(true);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
describe('Files Exceeding Size Limits', () => {
|
|
203
|
+
it('should skip files exceeding Claude size limit', async () => {
|
|
204
|
+
const filesBundle = {
|
|
205
|
+
version: '1.0',
|
|
206
|
+
id: 'bundle_large_files',
|
|
207
|
+
source: {
|
|
208
|
+
platform: 'chatgpt',
|
|
209
|
+
extractedAt: new Date().toISOString(),
|
|
210
|
+
extractorVersion: '1.0.0',
|
|
211
|
+
},
|
|
212
|
+
contents: {
|
|
213
|
+
files: {
|
|
214
|
+
files: [
|
|
215
|
+
{
|
|
216
|
+
id: 'file_small',
|
|
217
|
+
filename: 'small.txt',
|
|
218
|
+
mimeType: 'text/plain',
|
|
219
|
+
size: 1024, // 1KB
|
|
220
|
+
path: 'files/small.txt',
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
id: 'file_huge',
|
|
224
|
+
filename: 'huge-database.sql',
|
|
225
|
+
mimeType: 'application/sql',
|
|
226
|
+
size: 150 * 1024 * 1024, // 150MB - exceeds limit
|
|
227
|
+
path: 'files/huge-database.sql',
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
id: 'file_medium',
|
|
231
|
+
filename: 'medium.pdf',
|
|
232
|
+
mimeType: 'application/pdf',
|
|
233
|
+
size: 5 * 1024 * 1024, // 5MB - within limit
|
|
234
|
+
path: 'files/medium.pdf',
|
|
235
|
+
},
|
|
236
|
+
],
|
|
237
|
+
count: 3,
|
|
238
|
+
totalSize: 155 * 1024 * 1024,
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
metadata: {
|
|
242
|
+
totalItems: 3,
|
|
243
|
+
itemCounts: {
|
|
244
|
+
instructions: 0,
|
|
245
|
+
memories: 0,
|
|
246
|
+
conversations: 0,
|
|
247
|
+
files: 3,
|
|
248
|
+
customBots: 0,
|
|
249
|
+
},
|
|
250
|
+
warnings: [],
|
|
251
|
+
errors: [],
|
|
252
|
+
},
|
|
253
|
+
};
|
|
254
|
+
registerMockPlugins({
|
|
255
|
+
extractors: { chatgpt: { customBundle: filesBundle } },
|
|
256
|
+
});
|
|
257
|
+
registerTransformer('chatgpt', 'claude', () => new ChatGPTToClaudeTransformer());
|
|
258
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
259
|
+
workDir: join(testWorkDir, 'migration-large-files'),
|
|
260
|
+
});
|
|
261
|
+
const result = await orchestrator.run();
|
|
262
|
+
expect(result.success).toBe(true);
|
|
263
|
+
// 2 files should be loaded (small + medium), 1 skipped
|
|
264
|
+
expect(result.loaded.files).toBe(2);
|
|
265
|
+
const bundle = orchestrator.getBundle();
|
|
266
|
+
expect(bundle?.contents.files?.count).toBe(2);
|
|
267
|
+
expect(bundle?.metadata.warnings.some((w) => w.includes('huge-database.sql'))).toBe(true);
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
describe('Unicode and Emoji in Content', () => {
|
|
271
|
+
it('should preserve Unicode characters in instructions', async () => {
|
|
272
|
+
const unicodeBundle = {
|
|
273
|
+
version: '1.0',
|
|
274
|
+
id: 'bundle_unicode',
|
|
275
|
+
source: {
|
|
276
|
+
platform: 'chatgpt',
|
|
277
|
+
extractedAt: new Date().toISOString(),
|
|
278
|
+
extractorVersion: '1.0.0',
|
|
279
|
+
},
|
|
280
|
+
contents: {
|
|
281
|
+
instructions: {
|
|
282
|
+
content: `## 关于我 (About Me) 🎯
|
|
283
|
+
|
|
284
|
+
I speak multiple languages:
|
|
285
|
+
- 日本語 (Japanese)
|
|
286
|
+
- 中文 (Chinese)
|
|
287
|
+
- العربية (Arabic)
|
|
288
|
+
- עברית (Hebrew)
|
|
289
|
+
- हिंदी (Hindi)
|
|
290
|
+
|
|
291
|
+
Emoji support: 🚀 💻 🎨 🔧 ⚡️ 🎸
|
|
292
|
+
|
|
293
|
+
Mathematical symbols: ∑ ∫ ∂ ∞ √ π
|
|
294
|
+
|
|
295
|
+
Special characters: © ® ™ € £ ¥`,
|
|
296
|
+
length: 300,
|
|
297
|
+
},
|
|
298
|
+
memories: {
|
|
299
|
+
entries: [
|
|
300
|
+
{
|
|
301
|
+
id: 'mem_unicode',
|
|
302
|
+
content: 'ユーザーは日本に住んでいます 🇯🇵',
|
|
303
|
+
createdAt: new Date().toISOString(),
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
id: 'mem_emoji',
|
|
307
|
+
content: 'Favorite foods: 🍕🍣🌮🍜',
|
|
308
|
+
createdAt: new Date().toISOString(),
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
id: 'mem_math',
|
|
312
|
+
content: 'User is studying calculus: ∫₀^∞ e^(-x²)dx = √π/2',
|
|
313
|
+
createdAt: new Date().toISOString(),
|
|
314
|
+
},
|
|
315
|
+
],
|
|
316
|
+
count: 3,
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
metadata: {
|
|
320
|
+
totalItems: 4,
|
|
321
|
+
itemCounts: {
|
|
322
|
+
instructions: 1,
|
|
323
|
+
memories: 3,
|
|
324
|
+
conversations: 0,
|
|
325
|
+
files: 0,
|
|
326
|
+
customBots: 0,
|
|
327
|
+
},
|
|
328
|
+
warnings: [],
|
|
329
|
+
errors: [],
|
|
330
|
+
},
|
|
331
|
+
};
|
|
332
|
+
registerMockPlugins({
|
|
333
|
+
extractors: { chatgpt: { customBundle: unicodeBundle } },
|
|
334
|
+
});
|
|
335
|
+
registerTransformer('chatgpt', 'claude', () => new ChatGPTToClaudeTransformer());
|
|
336
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
337
|
+
workDir: join(testWorkDir, 'migration-unicode'),
|
|
338
|
+
});
|
|
339
|
+
const result = await orchestrator.run();
|
|
340
|
+
expect(result.success).toBe(true);
|
|
341
|
+
const bundle = orchestrator.getBundle();
|
|
342
|
+
expect(bundle?.contents.instructions?.content).toContain('日本語');
|
|
343
|
+
expect(bundle?.contents.instructions?.content).toContain('🚀');
|
|
344
|
+
expect(bundle?.contents.instructions?.content).toContain('∑');
|
|
345
|
+
});
|
|
346
|
+
it('should handle filenames with Unicode characters', async () => {
|
|
347
|
+
const unicodeFilesBundle = {
|
|
348
|
+
version: '1.0',
|
|
349
|
+
id: 'bundle_unicode_files',
|
|
350
|
+
source: {
|
|
351
|
+
platform: 'chatgpt',
|
|
352
|
+
extractedAt: new Date().toISOString(),
|
|
353
|
+
extractorVersion: '1.0.0',
|
|
354
|
+
},
|
|
355
|
+
contents: {
|
|
356
|
+
files: {
|
|
357
|
+
files: [
|
|
358
|
+
{
|
|
359
|
+
id: 'file_jp',
|
|
360
|
+
filename: 'ドキュメント.pdf',
|
|
361
|
+
mimeType: 'application/pdf',
|
|
362
|
+
size: 1024,
|
|
363
|
+
path: 'files/ドキュメント.pdf',
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
id: 'file_emoji',
|
|
367
|
+
filename: '🚀 launch-plan.md',
|
|
368
|
+
mimeType: 'text/markdown',
|
|
369
|
+
size: 512,
|
|
370
|
+
path: 'files/🚀 launch-plan.md',
|
|
371
|
+
},
|
|
372
|
+
],
|
|
373
|
+
count: 2,
|
|
374
|
+
totalSize: 1536,
|
|
375
|
+
},
|
|
376
|
+
},
|
|
377
|
+
metadata: {
|
|
378
|
+
totalItems: 2,
|
|
379
|
+
itemCounts: {
|
|
380
|
+
instructions: 0,
|
|
381
|
+
memories: 0,
|
|
382
|
+
conversations: 0,
|
|
383
|
+
files: 2,
|
|
384
|
+
customBots: 0,
|
|
385
|
+
},
|
|
386
|
+
warnings: [],
|
|
387
|
+
errors: [],
|
|
388
|
+
},
|
|
389
|
+
};
|
|
390
|
+
registerMockPlugins({
|
|
391
|
+
extractors: { chatgpt: { customBundle: unicodeFilesBundle } },
|
|
392
|
+
});
|
|
393
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
394
|
+
workDir: join(testWorkDir, 'migration-unicode-files'),
|
|
395
|
+
});
|
|
396
|
+
const result = await orchestrator.run();
|
|
397
|
+
expect(result.success).toBe(true);
|
|
398
|
+
expect(result.loaded.files).toBe(2);
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
describe('Long Custom Instructions Requiring Truncation', () => {
|
|
402
|
+
it('should truncate instructions exceeding target limit', async () => {
|
|
403
|
+
// Claude has ~8000 char limit, create instructions that exceed it
|
|
404
|
+
const veryLongContent = Array.from({ length: 200 }, (_, i) => `Section ${i}: This is a detailed instruction about how to handle situation ${i}. `).join('\n\n');
|
|
405
|
+
const longInstructionsBundle = {
|
|
406
|
+
version: '1.0',
|
|
407
|
+
id: 'bundle_long_instructions',
|
|
408
|
+
source: {
|
|
409
|
+
platform: 'chatgpt',
|
|
410
|
+
extractedAt: new Date().toISOString(),
|
|
411
|
+
extractorVersion: '1.0.0',
|
|
412
|
+
},
|
|
413
|
+
contents: {
|
|
414
|
+
instructions: {
|
|
415
|
+
content: veryLongContent,
|
|
416
|
+
length: veryLongContent.length,
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
metadata: {
|
|
420
|
+
totalItems: 1,
|
|
421
|
+
itemCounts: {
|
|
422
|
+
instructions: 1,
|
|
423
|
+
memories: 0,
|
|
424
|
+
conversations: 0,
|
|
425
|
+
files: 0,
|
|
426
|
+
customBots: 0,
|
|
427
|
+
},
|
|
428
|
+
warnings: [],
|
|
429
|
+
errors: [],
|
|
430
|
+
},
|
|
431
|
+
};
|
|
432
|
+
registerMockPlugins({
|
|
433
|
+
extractors: { chatgpt: { customBundle: longInstructionsBundle } },
|
|
434
|
+
});
|
|
435
|
+
registerTransformer('chatgpt', 'claude', () => new ChatGPTToClaudeTransformer());
|
|
436
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
437
|
+
workDir: join(testWorkDir, 'migration-long-instructions'),
|
|
438
|
+
});
|
|
439
|
+
const result = await orchestrator.run();
|
|
440
|
+
expect(result.success).toBe(true);
|
|
441
|
+
const bundle = orchestrator.getBundle();
|
|
442
|
+
// Instructions should be truncated to fit within limit
|
|
443
|
+
expect(bundle?.contents.instructions?.length).toBeLessThanOrEqual(20000); // Claude's limit
|
|
444
|
+
// Should have a warning about truncation
|
|
445
|
+
expect(bundle?.metadata.warnings.some((w) => w.toLowerCase().includes('truncat') || w.toLowerCase().includes('summar'))).toBe(true);
|
|
446
|
+
});
|
|
447
|
+
it('should use summarize strategy when configured', async () => {
|
|
448
|
+
const longContent = 'x'.repeat(25000); // Exceeds limit
|
|
449
|
+
const bundle = {
|
|
450
|
+
version: '1.0',
|
|
451
|
+
id: 'bundle_summarize',
|
|
452
|
+
source: {
|
|
453
|
+
platform: 'chatgpt',
|
|
454
|
+
extractedAt: new Date().toISOString(),
|
|
455
|
+
extractorVersion: '1.0.0',
|
|
456
|
+
},
|
|
457
|
+
contents: {
|
|
458
|
+
instructions: { content: longContent, length: longContent.length },
|
|
459
|
+
},
|
|
460
|
+
metadata: {
|
|
461
|
+
totalItems: 1,
|
|
462
|
+
itemCounts: {
|
|
463
|
+
instructions: 1,
|
|
464
|
+
memories: 0,
|
|
465
|
+
conversations: 0,
|
|
466
|
+
files: 0,
|
|
467
|
+
customBots: 0,
|
|
468
|
+
},
|
|
469
|
+
warnings: [],
|
|
470
|
+
errors: [],
|
|
471
|
+
},
|
|
472
|
+
};
|
|
473
|
+
registerMockPlugins({
|
|
474
|
+
extractors: { chatgpt: { customBundle: bundle } },
|
|
475
|
+
});
|
|
476
|
+
registerTransformer('chatgpt', 'claude', () => new ChatGPTToClaudeTransformer());
|
|
477
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
478
|
+
workDir: join(testWorkDir, 'migration-summarize'),
|
|
479
|
+
});
|
|
480
|
+
const result = await orchestrator.run();
|
|
481
|
+
expect(result.success).toBe(true);
|
|
482
|
+
});
|
|
483
|
+
});
|
|
484
|
+
describe('Network Interruption Simulation', () => {
|
|
485
|
+
it('should handle network failure during extraction', async () => {
|
|
486
|
+
registerMockPlugins({
|
|
487
|
+
extractors: {
|
|
488
|
+
chatgpt: {
|
|
489
|
+
shouldFail: true,
|
|
490
|
+
failureMessage: 'Network error: Connection timed out',
|
|
491
|
+
},
|
|
492
|
+
},
|
|
493
|
+
});
|
|
494
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
495
|
+
workDir: join(testWorkDir, 'migration-network-extract'),
|
|
496
|
+
});
|
|
497
|
+
await expect(orchestrator.run()).rejects.toThrow('Connection timed out');
|
|
498
|
+
const state = orchestrator.getState();
|
|
499
|
+
expect(state.phase).toBe('failed');
|
|
500
|
+
expect(state.error).toContain('Connection timed out');
|
|
501
|
+
});
|
|
502
|
+
it('should handle network failure during load phase', async () => {
|
|
503
|
+
registerMockPlugins({
|
|
504
|
+
loaders: {
|
|
505
|
+
claude: {
|
|
506
|
+
shouldFail: true,
|
|
507
|
+
failureMessage: 'API Error: 503 Service Unavailable',
|
|
508
|
+
},
|
|
509
|
+
},
|
|
510
|
+
});
|
|
511
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
512
|
+
workDir: join(testWorkDir, 'migration-network-load'),
|
|
513
|
+
});
|
|
514
|
+
await expect(orchestrator.run()).rejects.toThrow('503 Service Unavailable');
|
|
515
|
+
const state = orchestrator.getState();
|
|
516
|
+
expect(state.phase).toBe('failed');
|
|
517
|
+
});
|
|
518
|
+
it('should handle partial load failure', async () => {
|
|
519
|
+
registerMockPlugins({
|
|
520
|
+
loaders: {
|
|
521
|
+
claude: {
|
|
522
|
+
partialFailure: {
|
|
523
|
+
memories: true,
|
|
524
|
+
files: true,
|
|
525
|
+
},
|
|
526
|
+
},
|
|
527
|
+
},
|
|
528
|
+
});
|
|
529
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
530
|
+
workDir: join(testWorkDir, 'migration-partial-failure'),
|
|
531
|
+
});
|
|
532
|
+
const result = await orchestrator.run();
|
|
533
|
+
// Should still succeed but with warnings
|
|
534
|
+
expect(result.success).toBe(true);
|
|
535
|
+
expect(result.warnings.length).toBeGreaterThan(0);
|
|
536
|
+
expect(result.errors.length).toBeGreaterThan(0);
|
|
537
|
+
});
|
|
538
|
+
});
|
|
539
|
+
describe('Auth Token Expiration Simulation', () => {
|
|
540
|
+
it('should handle auth failure during extraction', async () => {
|
|
541
|
+
registerMockPlugins({
|
|
542
|
+
extractors: {
|
|
543
|
+
chatgpt: {
|
|
544
|
+
canExtractResult: false,
|
|
545
|
+
},
|
|
546
|
+
},
|
|
547
|
+
});
|
|
548
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
549
|
+
workDir: join(testWorkDir, 'migration-auth-extract'),
|
|
550
|
+
});
|
|
551
|
+
await expect(orchestrator.run()).rejects.toThrow(/Cannot extract/);
|
|
552
|
+
});
|
|
553
|
+
it('should handle auth failure during load', async () => {
|
|
554
|
+
registerMockPlugins({
|
|
555
|
+
loaders: {
|
|
556
|
+
claude: {
|
|
557
|
+
canLoadResult: false,
|
|
558
|
+
},
|
|
559
|
+
},
|
|
560
|
+
});
|
|
561
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
562
|
+
workDir: join(testWorkDir, 'migration-auth-load'),
|
|
563
|
+
});
|
|
564
|
+
await expect(orchestrator.run()).rejects.toThrow(/Cannot load/);
|
|
565
|
+
});
|
|
566
|
+
it('should handle mid-migration auth expiration', async () => {
|
|
567
|
+
registerMockPlugins({
|
|
568
|
+
loaders: {
|
|
569
|
+
claude: {
|
|
570
|
+
shouldFail: true,
|
|
571
|
+
failureMessage: 'Authentication failed: Token expired',
|
|
572
|
+
},
|
|
573
|
+
},
|
|
574
|
+
});
|
|
575
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
576
|
+
workDir: join(testWorkDir, 'migration-token-expired'),
|
|
577
|
+
});
|
|
578
|
+
await expect(orchestrator.run()).rejects.toThrow('Token expired');
|
|
579
|
+
});
|
|
580
|
+
});
|
|
581
|
+
describe('Special Characters in Identifiers', () => {
|
|
582
|
+
it('should handle conversation IDs with special characters', async () => {
|
|
583
|
+
const specialIdBundle = {
|
|
584
|
+
version: '1.0',
|
|
585
|
+
id: 'bundle_special_ids',
|
|
586
|
+
source: {
|
|
587
|
+
platform: 'chatgpt',
|
|
588
|
+
extractedAt: new Date().toISOString(),
|
|
589
|
+
extractorVersion: '1.0.0',
|
|
590
|
+
},
|
|
591
|
+
contents: {
|
|
592
|
+
conversations: {
|
|
593
|
+
path: 'conversations/',
|
|
594
|
+
count: 3,
|
|
595
|
+
messageCount: 30,
|
|
596
|
+
summaries: [
|
|
597
|
+
{
|
|
598
|
+
id: 'conv-123-456-789',
|
|
599
|
+
title: 'Normal ID',
|
|
600
|
+
messageCount: 10,
|
|
601
|
+
createdAt: new Date().toISOString(),
|
|
602
|
+
updatedAt: new Date().toISOString(),
|
|
603
|
+
},
|
|
604
|
+
{
|
|
605
|
+
id: 'conv/with/slashes',
|
|
606
|
+
title: 'Slashed ID',
|
|
607
|
+
messageCount: 10,
|
|
608
|
+
createdAt: new Date().toISOString(),
|
|
609
|
+
updatedAt: new Date().toISOString(),
|
|
610
|
+
},
|
|
611
|
+
{
|
|
612
|
+
id: 'conv with spaces & special<>chars',
|
|
613
|
+
title: 'Special Chars ID',
|
|
614
|
+
messageCount: 10,
|
|
615
|
+
createdAt: new Date().toISOString(),
|
|
616
|
+
updatedAt: new Date().toISOString(),
|
|
617
|
+
},
|
|
618
|
+
],
|
|
619
|
+
},
|
|
620
|
+
},
|
|
621
|
+
metadata: {
|
|
622
|
+
totalItems: 3,
|
|
623
|
+
itemCounts: {
|
|
624
|
+
instructions: 0,
|
|
625
|
+
memories: 0,
|
|
626
|
+
conversations: 3,
|
|
627
|
+
files: 0,
|
|
628
|
+
customBots: 0,
|
|
629
|
+
},
|
|
630
|
+
warnings: [],
|
|
631
|
+
errors: [],
|
|
632
|
+
},
|
|
633
|
+
};
|
|
634
|
+
registerMockPlugins({
|
|
635
|
+
extractors: { chatgpt: { customBundle: specialIdBundle } },
|
|
636
|
+
});
|
|
637
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
638
|
+
workDir: join(testWorkDir, 'migration-special-ids'),
|
|
639
|
+
});
|
|
640
|
+
const result = await orchestrator.run();
|
|
641
|
+
expect(result.success).toBe(true);
|
|
642
|
+
});
|
|
643
|
+
});
|
|
644
|
+
describe('Malformed Data Handling', () => {
|
|
645
|
+
it('should handle instructions with null content', async () => {
|
|
646
|
+
const malformedBundle = {
|
|
647
|
+
version: '1.0',
|
|
648
|
+
id: 'bundle_malformed',
|
|
649
|
+
source: {
|
|
650
|
+
platform: 'chatgpt',
|
|
651
|
+
extractedAt: new Date().toISOString(),
|
|
652
|
+
extractorVersion: '1.0.0',
|
|
653
|
+
},
|
|
654
|
+
contents: {
|
|
655
|
+
instructions: {
|
|
656
|
+
content: '', // Empty content
|
|
657
|
+
length: 0,
|
|
658
|
+
},
|
|
659
|
+
},
|
|
660
|
+
metadata: {
|
|
661
|
+
totalItems: 0,
|
|
662
|
+
itemCounts: {
|
|
663
|
+
instructions: 0,
|
|
664
|
+
memories: 0,
|
|
665
|
+
conversations: 0,
|
|
666
|
+
files: 0,
|
|
667
|
+
customBots: 0,
|
|
668
|
+
},
|
|
669
|
+
warnings: [],
|
|
670
|
+
errors: [],
|
|
671
|
+
},
|
|
672
|
+
};
|
|
673
|
+
registerMockPlugins({
|
|
674
|
+
extractors: { chatgpt: { customBundle: malformedBundle } },
|
|
675
|
+
});
|
|
676
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
677
|
+
workDir: join(testWorkDir, 'migration-malformed'),
|
|
678
|
+
});
|
|
679
|
+
const result = await orchestrator.run();
|
|
680
|
+
expect(result.success).toBe(true);
|
|
681
|
+
});
|
|
682
|
+
it('should handle memories with missing required fields', async () => {
|
|
683
|
+
const incompleteMemoriesBundle = {
|
|
684
|
+
version: '1.0',
|
|
685
|
+
id: 'bundle_incomplete_memories',
|
|
686
|
+
source: {
|
|
687
|
+
platform: 'chatgpt',
|
|
688
|
+
extractedAt: new Date().toISOString(),
|
|
689
|
+
extractorVersion: '1.0.0',
|
|
690
|
+
},
|
|
691
|
+
contents: {
|
|
692
|
+
memories: {
|
|
693
|
+
entries: [
|
|
694
|
+
{
|
|
695
|
+
id: 'mem_complete',
|
|
696
|
+
content: 'Complete memory entry',
|
|
697
|
+
createdAt: new Date().toISOString(),
|
|
698
|
+
},
|
|
699
|
+
{
|
|
700
|
+
id: 'mem_no_content',
|
|
701
|
+
content: '', // Empty content
|
|
702
|
+
createdAt: new Date().toISOString(),
|
|
703
|
+
},
|
|
704
|
+
],
|
|
705
|
+
count: 2,
|
|
706
|
+
},
|
|
707
|
+
},
|
|
708
|
+
metadata: {
|
|
709
|
+
totalItems: 2,
|
|
710
|
+
itemCounts: {
|
|
711
|
+
instructions: 0,
|
|
712
|
+
memories: 2,
|
|
713
|
+
conversations: 0,
|
|
714
|
+
files: 0,
|
|
715
|
+
customBots: 0,
|
|
716
|
+
},
|
|
717
|
+
warnings: [],
|
|
718
|
+
errors: [],
|
|
719
|
+
},
|
|
720
|
+
};
|
|
721
|
+
registerMockPlugins({
|
|
722
|
+
extractors: { chatgpt: { customBundle: incompleteMemoriesBundle } },
|
|
723
|
+
});
|
|
724
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
725
|
+
workDir: join(testWorkDir, 'migration-incomplete-memories'),
|
|
726
|
+
});
|
|
727
|
+
const result = await orchestrator.run();
|
|
728
|
+
expect(result.success).toBe(true);
|
|
729
|
+
});
|
|
730
|
+
});
|
|
731
|
+
describe('Timestamp Edge Cases', () => {
|
|
732
|
+
it('should handle various date formats', async () => {
|
|
733
|
+
const dateBundle = {
|
|
734
|
+
version: '1.0',
|
|
735
|
+
id: 'bundle_dates',
|
|
736
|
+
source: {
|
|
737
|
+
platform: 'chatgpt',
|
|
738
|
+
extractedAt: new Date().toISOString(),
|
|
739
|
+
extractorVersion: '1.0.0',
|
|
740
|
+
},
|
|
741
|
+
contents: {
|
|
742
|
+
memories: {
|
|
743
|
+
entries: [
|
|
744
|
+
{
|
|
745
|
+
id: 'mem_iso',
|
|
746
|
+
content: 'ISO date memory',
|
|
747
|
+
createdAt: '2024-01-15T10:30:00.000Z',
|
|
748
|
+
},
|
|
749
|
+
{
|
|
750
|
+
id: 'mem_old',
|
|
751
|
+
content: 'Very old memory',
|
|
752
|
+
createdAt: '2020-01-01T00:00:00.000Z',
|
|
753
|
+
},
|
|
754
|
+
{
|
|
755
|
+
id: 'mem_future',
|
|
756
|
+
content: 'Future dated memory', // Edge case
|
|
757
|
+
createdAt: '2030-12-31T23:59:59.999Z',
|
|
758
|
+
},
|
|
759
|
+
],
|
|
760
|
+
count: 3,
|
|
761
|
+
},
|
|
762
|
+
},
|
|
763
|
+
metadata: {
|
|
764
|
+
totalItems: 3,
|
|
765
|
+
itemCounts: {
|
|
766
|
+
instructions: 0,
|
|
767
|
+
memories: 3,
|
|
768
|
+
conversations: 0,
|
|
769
|
+
files: 0,
|
|
770
|
+
customBots: 0,
|
|
771
|
+
},
|
|
772
|
+
warnings: [],
|
|
773
|
+
errors: [],
|
|
774
|
+
},
|
|
775
|
+
};
|
|
776
|
+
registerMockPlugins({
|
|
777
|
+
extractors: { chatgpt: { customBundle: dateBundle } },
|
|
778
|
+
});
|
|
779
|
+
const orchestrator = new MigrationOrchestrator('chatgpt', 'claude', {
|
|
780
|
+
workDir: join(testWorkDir, 'migration-dates'),
|
|
781
|
+
});
|
|
782
|
+
const result = await orchestrator.run();
|
|
783
|
+
expect(result.success).toBe(true);
|
|
784
|
+
});
|
|
785
|
+
});
|
|
786
|
+
});
|
|
787
|
+
//# sourceMappingURL=edge-cases.test.js.map
|