cursor-history 0.5.1 → 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/LICENSE +7 -0
- package/README.md +385 -2
- package/dist/cli/commands/backup.d.ts +9 -0
- package/dist/cli/commands/backup.d.ts.map +1 -0
- package/dist/cli/commands/backup.js +168 -0
- package/dist/cli/commands/backup.js.map +1 -0
- package/dist/cli/commands/export.d.ts.map +1 -1
- package/dist/cli/commands/export.js +39 -7
- package/dist/cli/commands/export.js.map +1 -1
- package/dist/cli/commands/list-backups.d.ts +9 -0
- package/dist/cli/commands/list-backups.d.ts.map +1 -0
- package/dist/cli/commands/list-backups.js +166 -0
- package/dist/cli/commands/list-backups.js.map +1 -0
- package/dist/cli/commands/list.d.ts.map +1 -1
- package/dist/cli/commands/list.js +44 -9
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/migrate-session.d.ts +12 -0
- package/dist/cli/commands/migrate-session.d.ts.map +1 -0
- package/dist/cli/commands/migrate-session.js +125 -0
- package/dist/cli/commands/migrate-session.js.map +1 -0
- package/dist/cli/commands/migrate.d.ts +13 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -0
- package/dist/cli/commands/migrate.js +122 -0
- package/dist/cli/commands/migrate.js.map +1 -0
- package/dist/cli/commands/restore.d.ts +9 -0
- package/dist/cli/commands/restore.d.ts.map +1 -0
- package/dist/cli/commands/restore.js +192 -0
- package/dist/cli/commands/restore.js.map +1 -0
- package/dist/cli/commands/search.d.ts.map +1 -1
- package/dist/cli/commands/search.js +31 -3
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/show.d.ts.map +1 -1
- package/dist/cli/commands/show.js +32 -4
- package/dist/cli/commands/show.js.map +1 -1
- package/dist/cli/errors.d.ts +56 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/errors.js +90 -0
- package/dist/cli/errors.js.map +1 -0
- package/dist/cli/index.js +11 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/core/backup.d.ts +89 -0
- package/dist/core/backup.d.ts.map +1 -0
- package/dist/core/backup.js +709 -0
- package/dist/core/backup.js.map +1 -0
- package/dist/core/migrate.d.ts +40 -0
- package/dist/core/migrate.d.ts.map +1 -0
- package/dist/core/migrate.js +586 -0
- package/dist/core/migrate.js.map +1 -0
- package/dist/core/storage.d.ts +78 -6
- package/dist/core/storage.d.ts.map +1 -1
- package/dist/core/storage.js +327 -45
- package/dist/core/storage.js.map +1 -1
- package/dist/core/types.d.ts +280 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/lib/backup.d.ts +98 -0
- package/dist/lib/backup.d.ts.map +1 -0
- package/dist/lib/backup.js +108 -0
- package/dist/lib/backup.js.map +1 -0
- package/dist/lib/config.d.ts +33 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +81 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/errors.d.ts +257 -30
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +404 -54
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/index.d.ts +219 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +520 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/platform.d.ts +11 -0
- package/dist/lib/platform.d.ts.map +1 -1
- package/dist/lib/platform.js +32 -0
- package/dist/lib/platform.js.map +1 -1
- package/dist/lib/types.d.ts +374 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +9 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/utils.d.ts +17 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +20 -0
- package/dist/lib/utils.js.map +1 -0
- package/package.json +32 -4
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI command for migrating all sessions between workspaces
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* cursor-history migrate <source> <destination>
|
|
6
|
+
* cursor-history migrate /old/project /new/project
|
|
7
|
+
* cursor-history migrate --copy /project /backup/project
|
|
8
|
+
* cursor-history migrate --dry-run /old/path /new/path
|
|
9
|
+
* cursor-history migrate --force /old/path /existing/path
|
|
10
|
+
*/
|
|
11
|
+
import pc from 'picocolors';
|
|
12
|
+
import { migrateWorkspace } from '../../core/migrate.js';
|
|
13
|
+
import { expandPath } from '../../lib/platform.js';
|
|
14
|
+
import { isWorkspaceNotFoundError, isSameWorkspaceError, isNoSessionsFoundError, isDestinationHasSessionsError, isNestedPathError, } from '../../lib/errors.js';
|
|
15
|
+
export function registerMigrateCommand(program) {
|
|
16
|
+
program
|
|
17
|
+
.command('migrate')
|
|
18
|
+
.description('Move or copy all sessions from one workspace to another')
|
|
19
|
+
.argument('<source>', 'Source workspace path')
|
|
20
|
+
.argument('<destination>', 'Destination workspace path')
|
|
21
|
+
.option('--dry-run', 'Preview migration without making changes')
|
|
22
|
+
.option('--copy', 'Copy sessions instead of moving (keeps originals)')
|
|
23
|
+
.option('-f, --force', 'Proceed even if destination has existing sessions')
|
|
24
|
+
.option('--debug', 'Show detailed path transformation logs')
|
|
25
|
+
.action(async (sourceArg, destinationArg, options) => {
|
|
26
|
+
const globalOptions = program.opts();
|
|
27
|
+
const dataPath = globalOptions.dataPath;
|
|
28
|
+
const jsonOutput = globalOptions.json || options.json;
|
|
29
|
+
try {
|
|
30
|
+
// Expand ~ in paths
|
|
31
|
+
const source = expandPath(sourceArg);
|
|
32
|
+
const destination = expandPath(destinationArg);
|
|
33
|
+
// Determine mode
|
|
34
|
+
const mode = options.copy ? 'copy' : 'move';
|
|
35
|
+
// Perform migration
|
|
36
|
+
const result = migrateWorkspace({
|
|
37
|
+
source,
|
|
38
|
+
destination,
|
|
39
|
+
mode,
|
|
40
|
+
dryRun: options.dryRun ?? false,
|
|
41
|
+
force: options.force ?? false,
|
|
42
|
+
dataPath,
|
|
43
|
+
debug: options.debug ?? false,
|
|
44
|
+
});
|
|
45
|
+
// Output results
|
|
46
|
+
if (jsonOutput) {
|
|
47
|
+
console.log(JSON.stringify(result, null, 2));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
outputResult(result);
|
|
51
|
+
}
|
|
52
|
+
// Exit with error code if any failures
|
|
53
|
+
if (!result.success) {
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
if (jsonOutput) {
|
|
59
|
+
console.log(JSON.stringify({ error: formatError(error) }, null, 2));
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
console.error(pc.red(formatError(error)));
|
|
63
|
+
}
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function outputResult(result) {
|
|
69
|
+
if (result.dryRun) {
|
|
70
|
+
console.log(pc.yellow('Dry run - no changes made\n'));
|
|
71
|
+
}
|
|
72
|
+
const action = result.dryRun ? 'Would migrate' : 'Migrated';
|
|
73
|
+
const modeLabel = result.mode === 'copy' ? 'copied' : 'moved';
|
|
74
|
+
console.log(`${action} ${pc.bold(result.totalSessions)} session(s) from:`);
|
|
75
|
+
console.log(` ${pc.cyan(result.source)}`);
|
|
76
|
+
console.log(`to:`);
|
|
77
|
+
console.log(` ${pc.cyan(result.destination)}\n`);
|
|
78
|
+
if (result.successCount > 0) {
|
|
79
|
+
const actionLabel = result.dryRun ? `would be ${modeLabel}` : modeLabel;
|
|
80
|
+
console.log(pc.green(`✓ ${result.successCount} session(s) ${actionLabel} successfully`));
|
|
81
|
+
}
|
|
82
|
+
if (result.failureCount > 0) {
|
|
83
|
+
console.log(pc.red(`✗ ${result.failureCount} session(s) failed to migrate:\n`));
|
|
84
|
+
for (const r of result.results.filter((r) => !r.success)) {
|
|
85
|
+
console.log(` ${pc.red('✗')} ${pc.cyan(r.sessionId.slice(0, 8))}...`);
|
|
86
|
+
console.log(` ${pc.red(r.error ?? 'Unknown error')}\n`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Overall status
|
|
90
|
+
if (result.success) {
|
|
91
|
+
console.log(pc.green('\n✓ Migration completed successfully'));
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
console.log(pc.red('\n✗ Migration completed with errors'));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function formatError(error) {
|
|
98
|
+
if (isWorkspaceNotFoundError(error)) {
|
|
99
|
+
return `Workspace not found: ${error.path}\nPlease open the project in Cursor first to create the workspace.`;
|
|
100
|
+
}
|
|
101
|
+
if (isSameWorkspaceError(error)) {
|
|
102
|
+
return `Source and destination are the same: ${error.path}\nSpecify different source and destination paths.`;
|
|
103
|
+
}
|
|
104
|
+
if (isNoSessionsFoundError(error)) {
|
|
105
|
+
return `No sessions found for workspace: ${error.path}\nRun 'cursor-history list --workspace "${error.path}"' to verify.`;
|
|
106
|
+
}
|
|
107
|
+
if (isDestinationHasSessionsError(error)) {
|
|
108
|
+
return `Destination already has ${error.sessionCount} session(s): ${error.path}\nUse --force to proceed (will add sessions alongside existing ones).`;
|
|
109
|
+
}
|
|
110
|
+
if (isNestedPathError(error)) {
|
|
111
|
+
return `Destination is nested within source: ${error.destination} is inside ${error.source}\nThis would cause infinite path replacement loops. Choose a different destination.`;
|
|
112
|
+
}
|
|
113
|
+
if (error instanceof Error) {
|
|
114
|
+
// Check for database lock error
|
|
115
|
+
if (error.message.includes('SQLITE_BUSY') || error.message.includes('database is locked')) {
|
|
116
|
+
return 'Database is locked. Please close Cursor and try again.';
|
|
117
|
+
}
|
|
118
|
+
return error.message;
|
|
119
|
+
}
|
|
120
|
+
return String(error);
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../../src/cli/commands/migrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Restore command - restore chat history from a backup file
|
|
3
|
+
*/
|
|
4
|
+
import type { Command } from 'commander';
|
|
5
|
+
/**
|
|
6
|
+
* Register the restore command
|
|
7
|
+
*/
|
|
8
|
+
export declare function registerRestoreCommand(program: Command): void;
|
|
9
|
+
//# sourceMappingURL=restore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restore.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/restore.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqGzC;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiH7D"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Restore command - restore chat history from a backup file
|
|
3
|
+
*/
|
|
4
|
+
import pc from 'picocolors';
|
|
5
|
+
import { existsSync } from 'node:fs';
|
|
6
|
+
import { restoreBackup, validateBackup } from '../../core/backup.js';
|
|
7
|
+
import { handleError, ExitCode } from '../errors.js';
|
|
8
|
+
import { expandPath, contractPath } from '../../lib/platform.js';
|
|
9
|
+
/**
|
|
10
|
+
* Format duration for display
|
|
11
|
+
*/
|
|
12
|
+
function formatDuration(ms) {
|
|
13
|
+
if (ms < 1000) {
|
|
14
|
+
return `${ms}ms`;
|
|
15
|
+
}
|
|
16
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* T050: Progress display for restore command
|
|
20
|
+
*/
|
|
21
|
+
function displayProgress(progress) {
|
|
22
|
+
const phases = {
|
|
23
|
+
validating: '🔍 Validating backup integrity...',
|
|
24
|
+
extracting: '📦 Extracting files...',
|
|
25
|
+
finalizing: '✨ Finalizing restore...',
|
|
26
|
+
};
|
|
27
|
+
const phaseText = phases[progress.phase];
|
|
28
|
+
const fileProgress = progress.totalFiles > 0
|
|
29
|
+
? ` [${progress.filesCompleted}/${progress.totalFiles}]`
|
|
30
|
+
: '';
|
|
31
|
+
const currentFile = progress.currentFile ? ` ${pc.dim(progress.currentFile)}` : '';
|
|
32
|
+
// Show integrity status during validation
|
|
33
|
+
const integrityText = progress.phase === 'validating' && progress.integrityStatus === 'warnings'
|
|
34
|
+
? pc.yellow(' (some files have warnings)')
|
|
35
|
+
: '';
|
|
36
|
+
// Clear line and print progress
|
|
37
|
+
process.stdout.write(`\r${phaseText}${fileProgress}${currentFile}${integrityText}`.padEnd(80));
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Format restore result for JSON output
|
|
41
|
+
*/
|
|
42
|
+
function formatRestoreResultJson(result) {
|
|
43
|
+
return JSON.stringify({
|
|
44
|
+
success: result.success,
|
|
45
|
+
targetPath: result.targetPath,
|
|
46
|
+
filesRestored: result.filesRestored,
|
|
47
|
+
durationMs: result.durationMs,
|
|
48
|
+
...(result.warnings.length > 0 && { warnings: result.warnings }),
|
|
49
|
+
...(result.error && { error: result.error }),
|
|
50
|
+
}, null, 2);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Format restore result for human-readable output
|
|
54
|
+
*/
|
|
55
|
+
function formatRestoreResult(result) {
|
|
56
|
+
const lines = [];
|
|
57
|
+
if (result.success) {
|
|
58
|
+
lines.push(pc.green('✓ Backup restored successfully!'));
|
|
59
|
+
lines.push('');
|
|
60
|
+
lines.push(` ${pc.bold('Target:')} ${contractPath(result.targetPath)}`);
|
|
61
|
+
lines.push(` ${pc.bold('Files restored:')} ${result.filesRestored}`);
|
|
62
|
+
lines.push(` ${pc.bold('Duration:')} ${formatDuration(result.durationMs)}`);
|
|
63
|
+
if (result.warnings.length > 0) {
|
|
64
|
+
lines.push('');
|
|
65
|
+
lines.push(pc.yellow(' Warnings:'));
|
|
66
|
+
for (const warning of result.warnings) {
|
|
67
|
+
lines.push(` ${pc.dim('•')} ${warning}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
lines.push(pc.red('✗ Restore failed'));
|
|
73
|
+
lines.push('');
|
|
74
|
+
if (result.error) {
|
|
75
|
+
lines.push(` ${pc.bold('Error:')} ${result.error}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return lines.join('\n');
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Register the restore command
|
|
82
|
+
*/
|
|
83
|
+
export function registerRestoreCommand(program) {
|
|
84
|
+
program
|
|
85
|
+
.command('restore <backup>')
|
|
86
|
+
.description('Restore chat history from a backup file')
|
|
87
|
+
.option('-t, --target <path>', 'Target Cursor data path (default: platform-specific Cursor data directory)')
|
|
88
|
+
.option('-f, --force', 'Overwrite existing data without prompting')
|
|
89
|
+
.action(async (backupArg, options, command) => {
|
|
90
|
+
const globalOptions = command.parent?.opts();
|
|
91
|
+
const useJson = options.json ?? globalOptions?.json ?? false;
|
|
92
|
+
const customPath = options.dataPath ?? globalOptions?.dataPath;
|
|
93
|
+
// Resolve backup path
|
|
94
|
+
const backupPath = expandPath(backupArg);
|
|
95
|
+
try {
|
|
96
|
+
// T051: Check if backup file exists
|
|
97
|
+
if (!existsSync(backupPath)) {
|
|
98
|
+
if (useJson) {
|
|
99
|
+
console.log(JSON.stringify({ error: 'Backup file not found', path: backupPath }));
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
console.error(pc.red('Backup file not found:'));
|
|
103
|
+
console.error(pc.dim(` ${backupPath}`));
|
|
104
|
+
}
|
|
105
|
+
process.exit(ExitCode.USAGE_ERROR);
|
|
106
|
+
}
|
|
107
|
+
// T052: Validate backup before attempting restore
|
|
108
|
+
const validation = validateBackup(backupPath);
|
|
109
|
+
if (validation.status === 'invalid') {
|
|
110
|
+
if (useJson) {
|
|
111
|
+
console.log(JSON.stringify({
|
|
112
|
+
error: 'Invalid or corrupted backup',
|
|
113
|
+
errors: validation.errors
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
console.error(pc.red('Invalid or corrupted backup file:'));
|
|
118
|
+
for (const err of validation.errors) {
|
|
119
|
+
console.error(pc.dim(` ${err}`));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
process.exit(ExitCode.NOT_FOUND);
|
|
123
|
+
}
|
|
124
|
+
// Show warning for backups with integrity issues
|
|
125
|
+
if (validation.status === 'warnings' && !useJson) {
|
|
126
|
+
console.log(pc.yellow(`Warning: Backup has ${validation.corruptedFiles.length} file(s) with checksum mismatches.`));
|
|
127
|
+
console.log(pc.dim('These files will be restored but may be corrupted.\n'));
|
|
128
|
+
}
|
|
129
|
+
// Resolve target path if provided
|
|
130
|
+
const targetPath = options.target
|
|
131
|
+
? expandPath(options.target)
|
|
132
|
+
: (customPath ? expandPath(customPath) : undefined);
|
|
133
|
+
// Show progress if not JSON mode
|
|
134
|
+
const onProgress = useJson ? undefined : displayProgress;
|
|
135
|
+
// Perform restore
|
|
136
|
+
const result = restoreBackup({
|
|
137
|
+
backupPath,
|
|
138
|
+
targetPath,
|
|
139
|
+
force: options.force ?? false,
|
|
140
|
+
onProgress,
|
|
141
|
+
});
|
|
142
|
+
// Clear progress line
|
|
143
|
+
if (!useJson) {
|
|
144
|
+
process.stdout.write('\r'.padEnd(80) + '\r');
|
|
145
|
+
}
|
|
146
|
+
// Handle different error cases with appropriate exit codes
|
|
147
|
+
if (!result.success) {
|
|
148
|
+
// T053: Target exists without --force
|
|
149
|
+
if (result.error?.includes('already has Cursor data')) {
|
|
150
|
+
if (useJson) {
|
|
151
|
+
console.log(formatRestoreResultJson(result));
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
console.error(pc.red('Target directory already has Cursor data.'));
|
|
155
|
+
console.error(pc.dim('Use --force to overwrite existing data.'));
|
|
156
|
+
}
|
|
157
|
+
process.exit(ExitCode.IO_ERROR);
|
|
158
|
+
}
|
|
159
|
+
// T054: Integrity check failures
|
|
160
|
+
if (result.error?.includes('integrity') || result.error?.includes('checksum')) {
|
|
161
|
+
if (useJson) {
|
|
162
|
+
console.log(formatRestoreResultJson(result));
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
console.error(pc.red('Backup integrity check failed.'));
|
|
166
|
+
console.error(pc.dim(result.error));
|
|
167
|
+
}
|
|
168
|
+
process.exit(5); // Special exit code for integrity failures
|
|
169
|
+
}
|
|
170
|
+
// Generic error
|
|
171
|
+
if (useJson) {
|
|
172
|
+
console.log(formatRestoreResultJson(result));
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
console.error(formatRestoreResult(result));
|
|
176
|
+
}
|
|
177
|
+
process.exit(ExitCode.GENERAL_ERROR);
|
|
178
|
+
}
|
|
179
|
+
// Success
|
|
180
|
+
if (useJson) {
|
|
181
|
+
console.log(formatRestoreResultJson(result));
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
console.log(formatRestoreResult(result));
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
handleError(error);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=restore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restore.js","sourceRoot":"","sources":["../../../src/cli/commands/restore.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/search.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/search.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBzC;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwE5D"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Search command - search across chat sessions
|
|
3
3
|
*/
|
|
4
|
+
import pc from 'picocolors';
|
|
4
5
|
import { searchSessions } from '../../core/storage.js';
|
|
6
|
+
import { validateBackup } from '../../core/backup.js';
|
|
5
7
|
import { formatSearchResultsTable, formatSearchResultsJson } from '../formatters/index.js';
|
|
6
|
-
import { NoSearchResultsError, handleError } from '
|
|
7
|
-
import { expandPath } from '../../lib/platform.js';
|
|
8
|
+
import { NoSearchResultsError, handleError } from '../errors.js';
|
|
9
|
+
import { expandPath, contractPath } from '../../lib/platform.js';
|
|
8
10
|
/**
|
|
9
11
|
* Register the search command
|
|
10
12
|
*/
|
|
@@ -14,15 +16,37 @@ export function registerSearchCommand(program) {
|
|
|
14
16
|
.description('Search chat history for a keyword')
|
|
15
17
|
.option('-n, --limit <number>', 'Maximum results to show', '10')
|
|
16
18
|
.option('-c, --context <chars>', 'Context characters around match', '50')
|
|
19
|
+
.option('-b, --backup <path>', 'Search in backup file instead of live data')
|
|
17
20
|
.action(async (query, options, command) => {
|
|
18
21
|
const globalOptions = command.parent?.opts();
|
|
19
22
|
const useJson = options.json ?? globalOptions?.json ?? false;
|
|
20
23
|
const customPath = options.dataPath ?? globalOptions?.dataPath;
|
|
21
24
|
const workspaceFilter = options.workspace ?? globalOptions?.workspace;
|
|
25
|
+
const backupPath = options.backup ? expandPath(options.backup) : undefined;
|
|
22
26
|
const limit = parseInt(options.limit ?? '10', 10);
|
|
23
27
|
const contextChars = parseInt(options.context ?? '50', 10);
|
|
28
|
+
// T036: Validate backup if searching from backup
|
|
29
|
+
if (backupPath) {
|
|
30
|
+
const validation = validateBackup(backupPath);
|
|
31
|
+
if (validation.status === 'invalid') {
|
|
32
|
+
if (useJson) {
|
|
33
|
+
console.log(JSON.stringify({ error: 'Invalid backup', errors: validation.errors }));
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
console.error(pc.red('Invalid backup file:'));
|
|
37
|
+
for (const err of validation.errors) {
|
|
38
|
+
console.error(pc.dim(` ${err}`));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
process.exit(3);
|
|
42
|
+
}
|
|
43
|
+
if (validation.status === 'warnings' && !useJson) {
|
|
44
|
+
console.error(pc.yellow(`Warning: Backup has integrity issues (${validation.corruptedFiles.length} corrupted files)`));
|
|
45
|
+
console.error(pc.dim('Continuing with intact files...\n'));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
24
48
|
try {
|
|
25
|
-
const results = searchSessions(query, { limit, contextChars, workspacePath: workspaceFilter }, customPath ? expandPath(customPath) : undefined);
|
|
49
|
+
const results = searchSessions(query, { limit, contextChars, workspacePath: workspaceFilter }, customPath ? expandPath(customPath) : undefined, backupPath);
|
|
26
50
|
if (results.length === 0) {
|
|
27
51
|
if (useJson) {
|
|
28
52
|
console.log(JSON.stringify({ query, count: 0, totalMatches: 0, results: [] }));
|
|
@@ -32,6 +56,10 @@ export function registerSearchCommand(program) {
|
|
|
32
56
|
}
|
|
33
57
|
return;
|
|
34
58
|
}
|
|
59
|
+
// Show backup source indicator if searching from backup
|
|
60
|
+
if (backupPath && !useJson) {
|
|
61
|
+
console.log(pc.dim(`Searching in backup: ${contractPath(backupPath)}\n`));
|
|
62
|
+
}
|
|
35
63
|
if (useJson) {
|
|
36
64
|
console.log(formatSearchResultsJson(results, query));
|
|
37
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/cli/commands/search.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/cli/commands/search.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAWjE;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,OAAO,CAAC,gBAAgB,CAAC;SACzB,WAAW,CAAC,mCAAmC,CAAC;SAChD,MAAM,CAAC,sBAAsB,EAAE,yBAAyB,EAAE,IAAI,CAAC;SAC/D,MAAM,CAAC,uBAAuB,EAAE,iCAAiC,EAAE,IAAI,CAAC;SACxE,MAAM,CAAC,qBAAqB,EAAE,4CAA4C,CAAC;SAC3E,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,OAA6B,EAAE,OAAgB,EAAE,EAAE;QAC/E,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,EAIzC,CAAC;QACF,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,IAAI,aAAa,EAAE,IAAI,IAAI,KAAK,CAAC;QAC7D,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,IAAI,aAAa,EAAE,QAAQ,CAAC;QAC/D,MAAM,eAAe,GAAG,OAAO,CAAC,SAAS,IAAI,aAAa,EAAE,SAAS,CAAC;QACtE,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAE3E,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QAClD,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QAE3D,iDAAiD;QACjD,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,UAAU,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;YAC9C,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACpC,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;gBACtF,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAC;oBAC9C,KAAK,MAAM,GAAG,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;wBACpC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;oBACpC,CAAC;gBACH,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,IAAI,UAAU,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,yCAAyC,UAAU,CAAC,cAAc,CAAC,MAAM,mBAAmB,CAAC,CAAC,CAAC;gBACvH,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,cAAc,CAC5B,KAAK,EACL,EAAE,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,EACvD,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,EAC/C,UAAU,CACX,CAAC;YAEF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;gBACjF,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,oBAAoB,CAAC,KAAK,CAAC,CAAC;gBACxC,CAAC;gBACD,OAAO;YACT,CAAC;YAED,wDAAwD;YACxD,IAAI,UAAU,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC3B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,wBAAwB,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5E,CAAC;YAED,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;YACvD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"show.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/show.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"show.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/show.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBzC;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+E1D"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Show command - display a single chat session in detail
|
|
3
3
|
*/
|
|
4
|
+
import pc from 'picocolors';
|
|
4
5
|
import { getSession, listSessions } from '../../core/storage.js';
|
|
6
|
+
import { validateBackup } from '../../core/backup.js';
|
|
5
7
|
import { formatSessionDetail, formatSessionJson } from '../formatters/index.js';
|
|
6
|
-
import { SessionNotFoundError, handleError } from '
|
|
7
|
-
import { expandPath } from '../../lib/platform.js';
|
|
8
|
+
import { SessionNotFoundError, handleError } from '../errors.js';
|
|
9
|
+
import { expandPath, contractPath } from '../../lib/platform.js';
|
|
8
10
|
/**
|
|
9
11
|
* Register the show command
|
|
10
12
|
*/
|
|
@@ -16,21 +18,47 @@ export function registerShowCommand(program) {
|
|
|
16
18
|
.option('-t, --think', 'Show full thinking/reasoning text')
|
|
17
19
|
.option('--tool', 'Show full tool call details (commands, content, results)')
|
|
18
20
|
.option('-e, --error', 'Show full error messages (default: truncated)')
|
|
21
|
+
.option('-b, --backup <path>', 'Read from backup file instead of live data')
|
|
19
22
|
.action(async (indexArg, options, command) => {
|
|
20
23
|
const globalOptions = command.parent?.opts();
|
|
21
24
|
const useJson = options.json ?? globalOptions?.json ?? false;
|
|
22
25
|
const customPath = options.dataPath ?? globalOptions?.dataPath;
|
|
26
|
+
const backupPath = options.backup ? expandPath(options.backup) : undefined;
|
|
23
27
|
const index = parseInt(indexArg, 10);
|
|
24
28
|
if (isNaN(index) || index < 1) {
|
|
25
29
|
handleError(new Error(`Invalid index: ${indexArg}. Must be a positive number.`));
|
|
26
30
|
}
|
|
31
|
+
// T035: Validate backup if reading from backup
|
|
32
|
+
if (backupPath) {
|
|
33
|
+
const validation = validateBackup(backupPath);
|
|
34
|
+
if (validation.status === 'invalid') {
|
|
35
|
+
if (useJson) {
|
|
36
|
+
console.log(JSON.stringify({ error: 'Invalid backup', errors: validation.errors }));
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
console.error(pc.red('Invalid backup file:'));
|
|
40
|
+
for (const err of validation.errors) {
|
|
41
|
+
console.error(pc.dim(` ${err}`));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
process.exit(3);
|
|
45
|
+
}
|
|
46
|
+
if (validation.status === 'warnings' && !useJson) {
|
|
47
|
+
console.error(pc.yellow(`Warning: Backup has integrity issues (${validation.corruptedFiles.length} corrupted files)`));
|
|
48
|
+
console.error(pc.dim('Continuing with intact files...\n'));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
27
51
|
try {
|
|
28
|
-
const session = getSession(index, customPath ? expandPath(customPath) : undefined);
|
|
52
|
+
const session = getSession(index, customPath ? expandPath(customPath) : undefined, backupPath);
|
|
29
53
|
if (!session) {
|
|
30
54
|
// Get max index for error message
|
|
31
|
-
const sessions = listSessions({ limit: 0, all: true }, customPath ? expandPath(customPath) : undefined);
|
|
55
|
+
const sessions = listSessions({ limit: 0, all: true }, customPath ? expandPath(customPath) : undefined, backupPath);
|
|
32
56
|
throw new SessionNotFoundError(index, sessions.length);
|
|
33
57
|
}
|
|
58
|
+
// Show backup source indicator if reading from backup
|
|
59
|
+
if (backupPath && !useJson) {
|
|
60
|
+
console.log(pc.dim(`Reading from backup: ${contractPath(backupPath)}\n`));
|
|
61
|
+
}
|
|
34
62
|
if (useJson) {
|
|
35
63
|
console.log(formatSessionJson(session, session.workspacePath));
|
|
36
64
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"show.js","sourceRoot":"","sources":["../../../src/cli/commands/show.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"show.js","sourceRoot":"","sources":["../../../src/cli/commands/show.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error handling utilities and exit codes
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* CLI exit codes following Unix conventions
|
|
6
|
+
*/
|
|
7
|
+
export declare const ExitCode: {
|
|
8
|
+
readonly SUCCESS: 0;
|
|
9
|
+
readonly GENERAL_ERROR: 1;
|
|
10
|
+
readonly USAGE_ERROR: 2;
|
|
11
|
+
readonly NOT_FOUND: 3;
|
|
12
|
+
readonly IO_ERROR: 4;
|
|
13
|
+
};
|
|
14
|
+
export type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];
|
|
15
|
+
/**
|
|
16
|
+
* Custom error class for CLI errors with exit codes
|
|
17
|
+
*/
|
|
18
|
+
export declare class CliError extends Error {
|
|
19
|
+
readonly exitCode: ExitCode;
|
|
20
|
+
constructor(message: string, exitCode?: ExitCode);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Error for when no Cursor installation is found
|
|
24
|
+
*/
|
|
25
|
+
export declare class CursorNotFoundError extends CliError {
|
|
26
|
+
constructor(searchPath: string);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Error for when no chat history exists
|
|
30
|
+
*/
|
|
31
|
+
export declare class NoHistoryError extends CliError {
|
|
32
|
+
constructor();
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Error for invalid session index
|
|
36
|
+
*/
|
|
37
|
+
export declare class SessionNotFoundError extends CliError {
|
|
38
|
+
constructor(index: number, maxIndex: number);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Error for file already exists
|
|
42
|
+
*/
|
|
43
|
+
export declare class FileExistsError extends CliError {
|
|
44
|
+
constructor(path: string);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Error for search with no results
|
|
48
|
+
*/
|
|
49
|
+
export declare class NoSearchResultsError extends CliError {
|
|
50
|
+
constructor(query: string);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Handle an error and exit with appropriate code
|
|
54
|
+
*/
|
|
55
|
+
export declare function handleError(error: unknown): never;
|
|
56
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/cli/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,eAAO,MAAM,QAAQ;;;;;;CAMX,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,OAAO,QAAQ,CAAC,CAAC;AAEhE;;GAEG;AACH,qBAAa,QAAS,SAAQ,KAAK;aAGf,QAAQ,EAAE,QAAQ;gBADlC,OAAO,EAAE,MAAM,EACC,QAAQ,GAAE,QAAiC;CAK9D;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,QAAQ;gBACnC,UAAU,EAAE,MAAM;CAS/B;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,QAAQ;;CAQ3C;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,QAAQ;gBACpC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAQ5C;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,QAAQ;gBAC/B,IAAI,EAAE,MAAM;CAIzB;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,QAAQ;gBACpC,KAAK,EAAE,MAAM;CAI1B;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAajD"}
|