@savestate/cli 0.7.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.
Files changed (89) hide show
  1. package/dist/cli/__tests__/progress.test.d.ts +5 -0
  2. package/dist/cli/__tests__/progress.test.d.ts.map +1 -0
  3. package/dist/cli/__tests__/progress.test.js +212 -0
  4. package/dist/cli/__tests__/progress.test.js.map +1 -0
  5. package/dist/cli/__tests__/signal-handler.test.d.ts +5 -0
  6. package/dist/cli/__tests__/signal-handler.test.d.ts.map +1 -0
  7. package/dist/cli/__tests__/signal-handler.test.js +99 -0
  8. package/dist/cli/__tests__/signal-handler.test.js.map +1 -0
  9. package/dist/cli/__tests__/summary.test.d.ts +5 -0
  10. package/dist/cli/__tests__/summary.test.d.ts.map +1 -0
  11. package/dist/cli/__tests__/summary.test.js +242 -0
  12. package/dist/cli/__tests__/summary.test.js.map +1 -0
  13. package/dist/cli/index.d.ts +10 -0
  14. package/dist/cli/index.d.ts.map +1 -0
  15. package/dist/cli/index.js +10 -0
  16. package/dist/cli/index.js.map +1 -0
  17. package/dist/cli/progress.d.ts +86 -0
  18. package/dist/cli/progress.d.ts.map +1 -0
  19. package/dist/cli/progress.js +205 -0
  20. package/dist/cli/progress.js.map +1 -0
  21. package/dist/cli/prompts.d.ts +49 -0
  22. package/dist/cli/prompts.d.ts.map +1 -0
  23. package/dist/cli/prompts.js +266 -0
  24. package/dist/cli/prompts.js.map +1 -0
  25. package/dist/cli/signal-handler.d.ts +63 -0
  26. package/dist/cli/signal-handler.d.ts.map +1 -0
  27. package/dist/cli/signal-handler.js +165 -0
  28. package/dist/cli/signal-handler.js.map +1 -0
  29. package/dist/cli/summary.d.ts +33 -0
  30. package/dist/cli/summary.d.ts.map +1 -0
  31. package/dist/cli/summary.js +296 -0
  32. package/dist/cli/summary.js.map +1 -0
  33. package/dist/cli.js +7 -1
  34. package/dist/cli.js.map +1 -1
  35. package/dist/commands/migrate.d.ts +18 -4
  36. package/dist/commands/migrate.d.ts.map +1 -1
  37. package/dist/commands/migrate.js +324 -163
  38. package/dist/commands/migrate.js.map +1 -1
  39. package/dist/migrate/__tests__/capabilities.test.d.ts +7 -0
  40. package/dist/migrate/__tests__/capabilities.test.d.ts.map +1 -0
  41. package/dist/migrate/__tests__/capabilities.test.js +90 -0
  42. package/dist/migrate/__tests__/capabilities.test.js.map +1 -0
  43. package/dist/migrate/__tests__/chatgpt-loader.test.d.ts +7 -0
  44. package/dist/migrate/__tests__/chatgpt-loader.test.d.ts.map +1 -0
  45. package/dist/migrate/__tests__/chatgpt-loader.test.js +889 -0
  46. package/dist/migrate/__tests__/chatgpt-loader.test.js.map +1 -0
  47. package/dist/migrate/__tests__/edge-cases.test.d.ts +7 -0
  48. package/dist/migrate/__tests__/edge-cases.test.d.ts.map +1 -0
  49. package/dist/migrate/__tests__/edge-cases.test.js +787 -0
  50. package/dist/migrate/__tests__/edge-cases.test.js.map +1 -0
  51. package/dist/migrate/__tests__/error-recovery.test.d.ts +7 -0
  52. package/dist/migrate/__tests__/error-recovery.test.d.ts.map +1 -0
  53. package/dist/migrate/__tests__/error-recovery.test.js +461 -0
  54. package/dist/migrate/__tests__/error-recovery.test.js.map +1 -0
  55. package/dist/migrate/__tests__/integration.test.d.ts +7 -0
  56. package/dist/migrate/__tests__/integration.test.d.ts.map +1 -0
  57. package/dist/migrate/__tests__/integration.test.js +536 -0
  58. package/dist/migrate/__tests__/integration.test.js.map +1 -0
  59. package/dist/migrate/__tests__/performance.test.d.ts +7 -0
  60. package/dist/migrate/__tests__/performance.test.d.ts.map +1 -0
  61. package/dist/migrate/__tests__/performance.test.js +478 -0
  62. package/dist/migrate/__tests__/performance.test.js.map +1 -0
  63. package/dist/migrate/__tests__/registry.test.d.ts +7 -0
  64. package/dist/migrate/__tests__/registry.test.d.ts.map +1 -0
  65. package/dist/migrate/__tests__/registry.test.js +167 -0
  66. package/dist/migrate/__tests__/registry.test.js.map +1 -0
  67. package/dist/migrate/compatibility.d.ts +47 -0
  68. package/dist/migrate/compatibility.d.ts.map +1 -0
  69. package/dist/migrate/compatibility.js +468 -0
  70. package/dist/migrate/compatibility.js.map +1 -0
  71. package/dist/migrate/extractors/__tests__/claude.test.d.ts +12 -0
  72. package/dist/migrate/extractors/__tests__/claude.test.d.ts.map +1 -0
  73. package/dist/migrate/extractors/__tests__/claude.test.js +789 -0
  74. package/dist/migrate/extractors/__tests__/claude.test.js.map +1 -0
  75. package/dist/migrate/extractors/claude.d.ts +69 -0
  76. package/dist/migrate/extractors/claude.d.ts.map +1 -0
  77. package/dist/migrate/extractors/claude.js +1136 -0
  78. package/dist/migrate/extractors/claude.js.map +1 -0
  79. package/dist/migrate/extractors/registry.js +3 -2
  80. package/dist/migrate/extractors/registry.js.map +1 -1
  81. package/dist/migrate/loaders/chatgpt.d.ts +72 -0
  82. package/dist/migrate/loaders/chatgpt.d.ts.map +1 -0
  83. package/dist/migrate/loaders/chatgpt.js +691 -0
  84. package/dist/migrate/loaders/chatgpt.js.map +1 -0
  85. package/dist/migrate/loaders/registry.js +3 -2
  86. package/dist/migrate/loaders/registry.js.map +1 -1
  87. package/dist/migrate/types.d.ts +2 -0
  88. package/dist/migrate/types.d.ts.map +1 -1
  89. package/package.json +2 -1
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Progress Display Tests
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=progress.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.test.d.ts","sourceRoot":"","sources":["../../../src/cli/__tests__/progress.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,212 @@
1
+ /**
2
+ * Progress Display Tests
3
+ */
4
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
5
+ import { ProgressDisplay, createSpinner, success, warning, error, info, } from '../progress.js';
6
+ // Mock ora
7
+ vi.mock('ora', () => {
8
+ const mockSpinner = {
9
+ start: vi.fn().mockReturnThis(),
10
+ stop: vi.fn().mockReturnThis(),
11
+ succeed: vi.fn().mockReturnThis(),
12
+ fail: vi.fn().mockReturnThis(),
13
+ text: '',
14
+ };
15
+ return {
16
+ default: vi.fn(() => mockSpinner),
17
+ };
18
+ });
19
+ describe('ProgressDisplay', () => {
20
+ let consoleSpy;
21
+ beforeEach(() => {
22
+ consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
23
+ });
24
+ afterEach(() => {
25
+ consoleSpy.mockRestore();
26
+ vi.clearAllMocks();
27
+ });
28
+ describe('constructor', () => {
29
+ it('should create with default options', () => {
30
+ const progress = new ProgressDisplay();
31
+ expect(progress).toBeDefined();
32
+ });
33
+ it('should accept noColor option', () => {
34
+ const progress = new ProgressDisplay({ noColor: true });
35
+ expect(progress).toBeDefined();
36
+ });
37
+ it('should accept verbose option', () => {
38
+ const progress = new ProgressDisplay({ verbose: true });
39
+ expect(progress).toBeDefined();
40
+ });
41
+ });
42
+ describe('handleEvent', () => {
43
+ it('should handle phase:start event', () => {
44
+ const progress = new ProgressDisplay();
45
+ const event = {
46
+ type: 'phase:start',
47
+ phase: 'extracting',
48
+ message: 'Starting extraction...',
49
+ };
50
+ progress.handleEvent(event);
51
+ // Spinner should be started (mocked)
52
+ });
53
+ it('should handle phase:complete event', () => {
54
+ const progress = new ProgressDisplay();
55
+ // Start phase first
56
+ progress.handleEvent({
57
+ type: 'phase:start',
58
+ phase: 'extracting',
59
+ });
60
+ // Complete phase
61
+ progress.handleEvent({
62
+ type: 'phase:complete',
63
+ phase: 'extracting',
64
+ message: 'Extraction complete',
65
+ });
66
+ });
67
+ it('should handle progress event', () => {
68
+ const progress = new ProgressDisplay();
69
+ // Start phase first
70
+ progress.handleEvent({
71
+ type: 'phase:start',
72
+ phase: 'extracting',
73
+ });
74
+ // Update progress
75
+ progress.handleEvent({
76
+ type: 'progress',
77
+ progress: 50,
78
+ message: 'Processing...',
79
+ });
80
+ });
81
+ it('should handle checkpoint event in verbose mode', () => {
82
+ const progress = new ProgressDisplay({ verbose: true });
83
+ progress.handleEvent({
84
+ type: 'phase:start',
85
+ phase: 'extracting',
86
+ });
87
+ progress.handleEvent({
88
+ type: 'checkpoint',
89
+ message: 'Checkpoint saved',
90
+ });
91
+ // In verbose mode, checkpoint should be logged
92
+ });
93
+ it('should handle complete event', () => {
94
+ const progress = new ProgressDisplay();
95
+ progress.handleEvent({
96
+ type: 'complete',
97
+ data: { success: true },
98
+ });
99
+ const output = consoleSpy.mock.calls.map((c) => c[0]).join('\n');
100
+ expect(output).toContain('Complete');
101
+ });
102
+ it('should handle error event', () => {
103
+ const progress = new ProgressDisplay();
104
+ progress.handleEvent({
105
+ type: 'error',
106
+ error: new Error('Test error'),
107
+ });
108
+ const output = consoleSpy.mock.calls.map((c) => c[0]).join('\n');
109
+ expect(output).toContain('Failed');
110
+ });
111
+ });
112
+ describe('startPhase', () => {
113
+ it('should start a new spinner', () => {
114
+ const progress = new ProgressDisplay();
115
+ progress.startPhase('extracting', 'Extracting data...');
116
+ });
117
+ it('should stop previous spinner before starting new one', () => {
118
+ const progress = new ProgressDisplay();
119
+ progress.startPhase('extracting', 'Extracting...');
120
+ progress.startPhase('transforming', 'Transforming...');
121
+ });
122
+ });
123
+ describe('completePhase', () => {
124
+ it('should show success message', () => {
125
+ const progress = new ProgressDisplay();
126
+ progress.startPhase('extracting');
127
+ progress.completePhase('extracting', 'Done!');
128
+ });
129
+ });
130
+ describe('failPhase', () => {
131
+ it('should show error message', () => {
132
+ const progress = new ProgressDisplay();
133
+ progress.startPhase('extracting');
134
+ progress.failPhase('Something went wrong');
135
+ });
136
+ });
137
+ describe('updateProgress', () => {
138
+ it('should update spinner text with progress bar', () => {
139
+ const progress = new ProgressDisplay();
140
+ progress.startPhase('extracting');
141
+ progress.updateProgress(50, 'Processing items...');
142
+ });
143
+ it('should handle undefined progress', () => {
144
+ const progress = new ProgressDisplay();
145
+ progress.startPhase('extracting');
146
+ progress.updateProgress(undefined, 'Working...');
147
+ });
148
+ });
149
+ describe('stop', () => {
150
+ it('should stop the spinner', () => {
151
+ const progress = new ProgressDisplay();
152
+ progress.startPhase('extracting');
153
+ progress.stop();
154
+ });
155
+ it('should handle stop when no spinner active', () => {
156
+ const progress = new ProgressDisplay();
157
+ progress.stop(); // Should not throw
158
+ });
159
+ });
160
+ });
161
+ describe('Convenience Functions', () => {
162
+ let consoleSpy;
163
+ beforeEach(() => {
164
+ consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
165
+ });
166
+ afterEach(() => {
167
+ consoleSpy.mockRestore();
168
+ });
169
+ describe('createSpinner', () => {
170
+ it('should create and start a spinner', () => {
171
+ const spinner = createSpinner('Loading...');
172
+ expect(spinner).toBeDefined();
173
+ });
174
+ });
175
+ describe('success', () => {
176
+ it('should log success message with checkmark', () => {
177
+ success('Operation completed');
178
+ expect(consoleSpy).toHaveBeenCalled();
179
+ const output = consoleSpy.mock.calls[0][0];
180
+ expect(output).toContain('✓');
181
+ expect(output).toContain('Operation completed');
182
+ });
183
+ });
184
+ describe('warning', () => {
185
+ it('should log warning message', () => {
186
+ warning('Something might be wrong');
187
+ expect(consoleSpy).toHaveBeenCalled();
188
+ const output = consoleSpy.mock.calls[0][0];
189
+ expect(output).toContain('⚠');
190
+ expect(output).toContain('might be wrong');
191
+ });
192
+ });
193
+ describe('error', () => {
194
+ it('should log error message', () => {
195
+ error('Something went wrong');
196
+ expect(consoleSpy).toHaveBeenCalled();
197
+ const output = consoleSpy.mock.calls[0][0];
198
+ expect(output).toContain('✗');
199
+ expect(output).toContain('went wrong');
200
+ });
201
+ });
202
+ describe('info', () => {
203
+ it('should log info message', () => {
204
+ info('Here is some information');
205
+ expect(consoleSpy).toHaveBeenCalled();
206
+ const output = consoleSpy.mock.calls[0][0];
207
+ expect(output).toContain('ℹ');
208
+ expect(output).toContain('information');
209
+ });
210
+ });
211
+ });
212
+ //# sourceMappingURL=progress.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.test.js","sourceRoot":"","sources":["../../../src/cli/__tests__/progress.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Signal Handler Tests
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=signal-handler.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal-handler.test.d.ts","sourceRoot":"","sources":["../../../src/cli/__tests__/signal-handler.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Signal Handler Tests
3
+ */
4
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
5
+ import { SignalHandler, setupSignalHandler, cleanupSignalHandler, getSignalHandler, } from '../signal-handler.js';
6
+ describe('SignalHandler', () => {
7
+ let processOnSpy;
8
+ let processOffSpy;
9
+ let consoleSpy;
10
+ beforeEach(() => {
11
+ processOnSpy = vi.spyOn(process, 'on').mockImplementation(() => process);
12
+ processOffSpy = vi.spyOn(process, 'off').mockImplementation(() => process);
13
+ consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
14
+ });
15
+ afterEach(() => {
16
+ processOnSpy.mockRestore();
17
+ processOffSpy.mockRestore();
18
+ consoleSpy.mockRestore();
19
+ cleanupSignalHandler();
20
+ });
21
+ describe('register', () => {
22
+ it('should register signal handlers', () => {
23
+ const handler = new SignalHandler();
24
+ handler.register();
25
+ expect(processOnSpy).toHaveBeenCalledWith('SIGINT', expect.any(Function));
26
+ expect(processOnSpy).toHaveBeenCalledWith('SIGTERM', expect.any(Function));
27
+ expect(processOnSpy).toHaveBeenCalledWith('uncaughtException', expect.any(Function));
28
+ expect(processOnSpy).toHaveBeenCalledWith('unhandledRejection', expect.any(Function));
29
+ });
30
+ });
31
+ describe('unregister', () => {
32
+ it('should unregister signal handlers', () => {
33
+ const handler = new SignalHandler();
34
+ handler.register();
35
+ handler.unregister();
36
+ expect(processOffSpy).toHaveBeenCalledWith('SIGINT', expect.any(Function));
37
+ expect(processOffSpy).toHaveBeenCalledWith('SIGTERM', expect.any(Function));
38
+ });
39
+ });
40
+ describe('setupSignalHandler', () => {
41
+ it('should create and register a global handler', () => {
42
+ const handler = setupSignalHandler();
43
+ expect(handler).toBeInstanceOf(SignalHandler);
44
+ expect(getSignalHandler()).toBe(handler);
45
+ expect(processOnSpy).toHaveBeenCalledWith('SIGINT', expect.any(Function));
46
+ });
47
+ it('should replace existing handler', () => {
48
+ const handler1 = setupSignalHandler();
49
+ const handler2 = setupSignalHandler();
50
+ expect(getSignalHandler()).toBe(handler2);
51
+ expect(getSignalHandler()).not.toBe(handler1);
52
+ });
53
+ });
54
+ describe('cleanupSignalHandler', () => {
55
+ it('should unregister and clear global handler', () => {
56
+ setupSignalHandler();
57
+ expect(getSignalHandler()).not.toBeNull();
58
+ cleanupSignalHandler();
59
+ expect(getSignalHandler()).toBeNull();
60
+ });
61
+ });
62
+ describe('setOrchestrator', () => {
63
+ it('should allow updating orchestrator reference', () => {
64
+ const handler = new SignalHandler();
65
+ const mockOrchestrator = {
66
+ getState: () => ({
67
+ id: 'test',
68
+ phase: 'extracting',
69
+ progress: 50,
70
+ }),
71
+ };
72
+ // Should not throw
73
+ handler.setOrchestrator(mockOrchestrator);
74
+ });
75
+ });
76
+ describe('options', () => {
77
+ it('should respect showResumeHint option', () => {
78
+ const handler = new SignalHandler({
79
+ showResumeHint: false,
80
+ });
81
+ // Internal state check - showResumeHint should be false
82
+ expect(handler.showResumeHint).toBe(false);
83
+ });
84
+ it('should use custom message', () => {
85
+ const handler = new SignalHandler({
86
+ message: 'Custom interrupt message',
87
+ });
88
+ expect(handler.message).toBe('Custom interrupt message');
89
+ });
90
+ it('should accept cleanup function', () => {
91
+ const cleanup = vi.fn();
92
+ const handler = new SignalHandler({
93
+ cleanup,
94
+ });
95
+ expect(handler.cleanup).toBe(cleanup);
96
+ });
97
+ });
98
+ });
99
+ //# sourceMappingURL=signal-handler.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal-handler.test.js","sourceRoot":"","sources":["../../../src/cli/__tests__/signal-handler.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Summary Display Tests
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=summary.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.test.d.ts","sourceRoot":"","sources":["../../../src/cli/__tests__/summary.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,242 @@
1
+ /**
2
+ * Summary Display Tests
3
+ */
4
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
5
+ import { showMigrationSummary, showCompatibilityReport, showReviewItems, showResumableMigrations, showFailedMigration, } from '../summary.js';
6
+ describe('Summary Display', () => {
7
+ let consoleSpy;
8
+ beforeEach(() => {
9
+ consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
10
+ });
11
+ afterEach(() => {
12
+ consoleSpy.mockRestore();
13
+ });
14
+ describe('showMigrationSummary', () => {
15
+ it('should display successful migration summary', () => {
16
+ const state = {
17
+ id: 'mig_test123',
18
+ phase: 'complete',
19
+ source: 'chatgpt',
20
+ target: 'claude',
21
+ startedAt: new Date().toISOString(),
22
+ phaseStartedAt: new Date().toISOString(),
23
+ completedAt: new Date().toISOString(),
24
+ checkpoints: [],
25
+ progress: 100,
26
+ options: {},
27
+ };
28
+ const result = {
29
+ success: true,
30
+ loaded: {
31
+ instructions: true,
32
+ memories: 42,
33
+ files: 3,
34
+ customBots: 1,
35
+ },
36
+ created: {
37
+ projectId: 'proj_abc',
38
+ projectUrl: 'https://claude.ai/project/proj_abc',
39
+ },
40
+ warnings: [],
41
+ errors: [],
42
+ };
43
+ showMigrationSummary(state, result);
44
+ expect(consoleSpy).toHaveBeenCalled();
45
+ // Verify key output was shown
46
+ const output = consoleSpy.mock.calls.map((c) => c[0]).join('\n');
47
+ expect(output).toContain('Complete');
48
+ expect(output).toContain('ChatGPT');
49
+ expect(output).toContain('Claude');
50
+ });
51
+ it('should show warnings when present', () => {
52
+ const state = {
53
+ id: 'mig_test123',
54
+ phase: 'complete',
55
+ source: 'chatgpt',
56
+ target: 'claude',
57
+ startedAt: new Date().toISOString(),
58
+ phaseStartedAt: new Date().toISOString(),
59
+ checkpoints: [],
60
+ progress: 100,
61
+ options: {},
62
+ };
63
+ const result = {
64
+ success: true,
65
+ loaded: {
66
+ instructions: true,
67
+ memories: 10,
68
+ files: 0,
69
+ customBots: 0,
70
+ },
71
+ warnings: ['Some memories were truncated'],
72
+ errors: [],
73
+ };
74
+ showMigrationSummary(state, result);
75
+ const output = consoleSpy.mock.calls.map((c) => c[0]).join('\n');
76
+ expect(output).toContain('Warnings');
77
+ expect(output).toContain('truncated');
78
+ });
79
+ });
80
+ describe('showCompatibilityReport', () => {
81
+ it('should display dry-run report', () => {
82
+ const report = {
83
+ source: 'chatgpt',
84
+ target: 'claude',
85
+ generatedAt: new Date().toISOString(),
86
+ summary: {
87
+ perfect: 5,
88
+ adapted: 2,
89
+ incompatible: 1,
90
+ total: 8,
91
+ },
92
+ items: [
93
+ {
94
+ type: 'instructions',
95
+ name: 'Custom Instructions',
96
+ status: 'perfect',
97
+ reason: 'Will transfer without modification',
98
+ },
99
+ {
100
+ type: 'memory',
101
+ name: 'Memory Entries (42 entries)',
102
+ status: 'adapted',
103
+ reason: 'Claude uses project knowledge instead',
104
+ action: 'Memories will be converted to project knowledge files',
105
+ },
106
+ ],
107
+ recommendations: ['Review adapted items'],
108
+ feasibility: 'easy',
109
+ };
110
+ showCompatibilityReport(report);
111
+ const output = consoleSpy.mock.calls.map((c) => c[0]).join('\n');
112
+ expect(output).toContain('Compatibility Report');
113
+ expect(output).toContain('Dry Run');
114
+ expect(output).toContain('5 items will transfer perfectly');
115
+ expect(output).toContain('2 items require adaptation');
116
+ });
117
+ });
118
+ describe('showReviewItems', () => {
119
+ it('should show items needing attention', () => {
120
+ const report = {
121
+ source: 'chatgpt',
122
+ target: 'claude',
123
+ generatedAt: new Date().toISOString(),
124
+ summary: {
125
+ perfect: 3,
126
+ adapted: 2,
127
+ incompatible: 1,
128
+ total: 6,
129
+ },
130
+ items: [
131
+ {
132
+ type: 'feature',
133
+ name: 'DALL-E Integration',
134
+ status: 'incompatible',
135
+ reason: 'Not available in Claude',
136
+ action: 'Use MCP image generation tools',
137
+ },
138
+ {
139
+ type: 'memory',
140
+ name: 'Memory Entries',
141
+ status: 'adapted',
142
+ reason: 'Claude uses project knowledge',
143
+ },
144
+ ],
145
+ recommendations: [],
146
+ feasibility: 'moderate',
147
+ };
148
+ showReviewItems(report);
149
+ const output = consoleSpy.mock.calls.map((c) => c[0]).join('\n');
150
+ expect(output).toContain('Review');
151
+ expect(output).toContain('DALL-E');
152
+ expect(output).toContain('Memory Entries');
153
+ });
154
+ it('should show success message when no items need attention', () => {
155
+ const report = {
156
+ source: 'chatgpt',
157
+ target: 'claude',
158
+ generatedAt: new Date().toISOString(),
159
+ summary: {
160
+ perfect: 5,
161
+ adapted: 0,
162
+ incompatible: 0,
163
+ total: 5,
164
+ },
165
+ items: [
166
+ {
167
+ type: 'instructions',
168
+ name: 'Custom Instructions',
169
+ status: 'perfect',
170
+ reason: 'Will transfer without modification',
171
+ },
172
+ ],
173
+ recommendations: [],
174
+ feasibility: 'easy',
175
+ };
176
+ showReviewItems(report);
177
+ const output = consoleSpy.mock.calls.map((c) => c[0]).join('\n');
178
+ expect(output).toContain('All items transfer perfectly');
179
+ });
180
+ });
181
+ describe('showResumableMigrations', () => {
182
+ it('should list resumable migrations', () => {
183
+ const migrations = [
184
+ {
185
+ id: 'mig_abc123',
186
+ phase: 'transforming',
187
+ source: 'chatgpt',
188
+ target: 'claude',
189
+ startedAt: new Date().toISOString(),
190
+ phaseStartedAt: new Date().toISOString(),
191
+ checkpoints: [],
192
+ progress: 45,
193
+ options: {},
194
+ },
195
+ {
196
+ id: 'mig_def456',
197
+ phase: 'complete',
198
+ source: 'claude',
199
+ target: 'chatgpt',
200
+ startedAt: new Date().toISOString(),
201
+ phaseStartedAt: new Date().toISOString(),
202
+ completedAt: new Date().toISOString(),
203
+ checkpoints: [],
204
+ progress: 100,
205
+ options: {},
206
+ },
207
+ ];
208
+ showResumableMigrations(migrations);
209
+ const output = consoleSpy.mock.calls.map((c) => c[0]).join('\n');
210
+ expect(output).toContain('Interrupted');
211
+ expect(output).toContain('mig_abc123');
212
+ expect(output).toContain('45%');
213
+ });
214
+ it('should show message when no migrations to resume', () => {
215
+ showResumableMigrations([]);
216
+ const output = consoleSpy.mock.calls.map((c) => c[0]).join('\n');
217
+ expect(output).toContain('No interrupted migrations');
218
+ });
219
+ });
220
+ describe('showFailedMigration', () => {
221
+ it('should display failure details', () => {
222
+ const state = {
223
+ id: 'mig_failed',
224
+ phase: 'failed',
225
+ source: 'chatgpt',
226
+ target: 'claude',
227
+ startedAt: new Date().toISOString(),
228
+ phaseStartedAt: new Date().toISOString(),
229
+ checkpoints: [],
230
+ progress: 67,
231
+ error: 'Authentication failed: Invalid API key',
232
+ options: {},
233
+ };
234
+ showFailedMigration(state);
235
+ const output = consoleSpy.mock.calls.map((c) => c[0]).join('\n');
236
+ expect(output).toContain('Failed');
237
+ expect(output).toContain('Authentication failed');
238
+ expect(output).toContain('--resume');
239
+ });
240
+ });
241
+ });
242
+ //# sourceMappingURL=summary.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.test.js","sourceRoot":"","sources":["../../../src/cli/__tests__/summary.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * CLI Utilities
3
+ *
4
+ * Common utilities for the SaveState CLI.
5
+ */
6
+ export * from './prompts.js';
7
+ export * from './progress.js';
8
+ export * from './summary.js';
9
+ export * from './signal-handler.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * CLI Utilities
3
+ *
4
+ * Common utilities for the SaveState CLI.
5
+ */
6
+ export * from './prompts.js';
7
+ export * from './progress.js';
8
+ export * from './summary.js';
9
+ export * from './signal-handler.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC"}