claude-code-history 0.2.2
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/README.md +400 -0
- package/dist/cli/commands/export.d.ts +11 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +119 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/list.d.ts +11 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +79 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/migrate.d.ts +11 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -0
- package/dist/cli/commands/migrate.js +144 -0
- package/dist/cli/commands/migrate.js.map +1 -0
- package/dist/cli/commands/search.d.ts +11 -0
- package/dist/cli/commands/search.d.ts.map +1 -0
- package/dist/cli/commands/search.js +94 -0
- package/dist/cli/commands/search.js.map +1 -0
- package/dist/cli/commands/view.d.ts +11 -0
- package/dist/cli/commands/view.d.ts.map +1 -0
- package/dist/cli/commands/view.js +67 -0
- package/dist/cli/commands/view.js.map +1 -0
- package/dist/cli/formatters/pager.d.ts +25 -0
- package/dist/cli/formatters/pager.d.ts.map +1 -0
- package/dist/cli/formatters/pager.js +119 -0
- package/dist/cli/formatters/pager.js.map +1 -0
- package/dist/cli/formatters/search.d.ts +38 -0
- package/dist/cli/formatters/search.d.ts.map +1 -0
- package/dist/cli/formatters/search.js +119 -0
- package/dist/cli/formatters/search.js.map +1 -0
- package/dist/cli/formatters/session.d.ts +24 -0
- package/dist/cli/formatters/session.d.ts.map +1 -0
- package/dist/cli/formatters/session.js +247 -0
- package/dist/cli/formatters/session.js.map +1 -0
- package/dist/cli/formatters/table.d.ts +25 -0
- package/dist/cli/formatters/table.d.ts.map +1 -0
- package/dist/cli/formatters/table.js +126 -0
- package/dist/cli/formatters/table.js.map +1 -0
- package/dist/cli/index.d.ts +14 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +50 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/config.d.ts +62 -0
- package/dist/cli/utils/config.d.ts.map +1 -0
- package/dist/cli/utils/config.js +65 -0
- package/dist/cli/utils/config.js.map +1 -0
- package/dist/cli/utils/errors.d.ts +86 -0
- package/dist/cli/utils/errors.d.ts.map +1 -0
- package/dist/cli/utils/errors.js +129 -0
- package/dist/cli/utils/errors.js.map +1 -0
- package/dist/cli/utils/output.d.ts +74 -0
- package/dist/cli/utils/output.d.ts.map +1 -0
- package/dist/cli/utils/output.js +113 -0
- package/dist/cli/utils/output.js.map +1 -0
- package/dist/lib/config.d.ts +44 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +60 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/errors.d.ts +40 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +61 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/export.d.ts +70 -0
- package/dist/lib/export.d.ts.map +1 -0
- package/dist/lib/export.js +241 -0
- package/dist/lib/export.js.map +1 -0
- package/dist/lib/index.d.ts +16 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +33 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/migrate.d.ts +50 -0
- package/dist/lib/migrate.d.ts.map +1 -0
- package/dist/lib/migrate.js +274 -0
- package/dist/lib/migrate.js.map +1 -0
- package/dist/lib/parser.d.ts +67 -0
- package/dist/lib/parser.d.ts.map +1 -0
- package/dist/lib/parser.js +321 -0
- package/dist/lib/parser.js.map +1 -0
- package/dist/lib/platform.d.ts +51 -0
- package/dist/lib/platform.d.ts.map +1 -0
- package/dist/lib/platform.js +94 -0
- package/dist/lib/platform.js.map +1 -0
- package/dist/lib/search.d.ts +39 -0
- package/dist/lib/search.d.ts.map +1 -0
- package/dist/lib/search.js +217 -0
- package/dist/lib/search.js.map +1 -0
- package/dist/lib/session.d.ts +59 -0
- package/dist/lib/session.d.ts.map +1 -0
- package/dist/lib/session.js +326 -0
- package/dist/lib/session.js.map +1 -0
- package/dist/lib/types.d.ts +280 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +7 -0
- package/dist/lib/types.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migrate command implementation
|
|
3
|
+
*
|
|
4
|
+
* Copies or moves sessions between workspaces.
|
|
5
|
+
*/
|
|
6
|
+
import { migrateSession, migrateWorkspace, isSessionNotFoundError, isWorkspaceNotFoundError, isDataNotFoundError, } from '../../lib/index.js';
|
|
7
|
+
import { resolveConfig, toLibraryConfig, parseSessionRef, } from '../utils/config.js';
|
|
8
|
+
import { ioError, notFoundError } from '../utils/errors.js';
|
|
9
|
+
import { successResult, output, handleError } from '../utils/output.js';
|
|
10
|
+
/**
|
|
11
|
+
* Validate and normalize mode option
|
|
12
|
+
*/
|
|
13
|
+
function normalizeMode(mode) {
|
|
14
|
+
const normalized = mode.toLowerCase();
|
|
15
|
+
if (normalized === 'copy' || normalized === 'move') {
|
|
16
|
+
return normalized;
|
|
17
|
+
}
|
|
18
|
+
throw new Error(`Invalid mode: ${mode}. Use 'copy' or 'move'.`);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Format migration result for display
|
|
22
|
+
*/
|
|
23
|
+
function formatMigrateResult(result, mode) {
|
|
24
|
+
const action = mode === 'copy' ? 'Copied' : 'Moved';
|
|
25
|
+
const lines = [];
|
|
26
|
+
if (result.successCount > 0) {
|
|
27
|
+
lines.push(`${action} ${result.successCount} session${result.successCount !== 1 ? 's' : ''} successfully.`);
|
|
28
|
+
}
|
|
29
|
+
if (result.failedCount > 0) {
|
|
30
|
+
lines.push(`Failed to migrate ${result.failedCount} session${result.failedCount !== 1 ? 's' : ''}:`);
|
|
31
|
+
for (const error of result.errors) {
|
|
32
|
+
lines.push(` - ${error.sessionId}: ${error.error}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return lines.join('\n');
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Execute the migrate command
|
|
39
|
+
*/
|
|
40
|
+
async function executeMigrate(sessionArg, options) {
|
|
41
|
+
const config = resolveConfig(options);
|
|
42
|
+
const libConfig = toLibraryConfig(config);
|
|
43
|
+
// Validate mode
|
|
44
|
+
let mode;
|
|
45
|
+
try {
|
|
46
|
+
mode = normalizeMode(options.mode);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
const exitCode = handleError(error, options.json);
|
|
50
|
+
process.exit(exitCode);
|
|
51
|
+
}
|
|
52
|
+
// Validate destination is provided
|
|
53
|
+
if (!options.destination) {
|
|
54
|
+
const exitCode = handleError(new Error("Destination required. Use --destination or -D to specify the target workspace.\n\nUsage: cch migrate <session> --destination <path>\n cch migrate --all --source <path> --destination <path>"), options.json);
|
|
55
|
+
process.exit(exitCode);
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
let result;
|
|
59
|
+
if (options.all) {
|
|
60
|
+
// Migrate all sessions from source workspace
|
|
61
|
+
if (!options.source) {
|
|
62
|
+
const exitCode = handleError(new Error("Source workspace required when using --all.\n\nUsage: cch migrate --all --source <path> --destination <path>"), options.json);
|
|
63
|
+
process.exit(exitCode);
|
|
64
|
+
}
|
|
65
|
+
result = await migrateWorkspace({
|
|
66
|
+
source: options.source,
|
|
67
|
+
destination: options.destination,
|
|
68
|
+
mode,
|
|
69
|
+
}, libConfig);
|
|
70
|
+
}
|
|
71
|
+
else if (sessionArg) {
|
|
72
|
+
// Migrate specific session(s)
|
|
73
|
+
const sessionParts = sessionArg.split(',').map((s) => s.trim());
|
|
74
|
+
const sessions = sessionParts.map((s) => parseSessionRef(s));
|
|
75
|
+
result = await migrateSession({
|
|
76
|
+
sessions,
|
|
77
|
+
destination: options.destination,
|
|
78
|
+
mode,
|
|
79
|
+
}, libConfig);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
// No session specified and --all not set
|
|
83
|
+
const exitCode = handleError(new Error("Session identifier required. Provide a session index/UUID or use --all.\n\nUsage: cch migrate <session> --destination <path>\n cch migrate --all --source <path> --destination <path>"), options.json);
|
|
84
|
+
process.exit(exitCode);
|
|
85
|
+
}
|
|
86
|
+
// Output result
|
|
87
|
+
if (options.json) {
|
|
88
|
+
const commandResult = successResult({
|
|
89
|
+
successCount: result.successCount,
|
|
90
|
+
failedCount: result.failedCount,
|
|
91
|
+
mode,
|
|
92
|
+
destination: options.destination,
|
|
93
|
+
errors: result.errors,
|
|
94
|
+
});
|
|
95
|
+
output(commandResult, true);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
console.log(formatMigrateResult(result, mode));
|
|
99
|
+
}
|
|
100
|
+
// Exit with error if there were failures
|
|
101
|
+
if (result.failedCount > 0 && result.successCount === 0) {
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
if (isSessionNotFoundError(error)) {
|
|
107
|
+
const exitCode = handleError(notFoundError(`Session not found: ${sessionArg}`, "Try 'cch list' to see available sessions."), options.json);
|
|
108
|
+
process.exit(exitCode);
|
|
109
|
+
}
|
|
110
|
+
if (isWorkspaceNotFoundError(error)) {
|
|
111
|
+
const exitCode = handleError(notFoundError(`Workspace not found: ${options.source}`, "Make sure the source workspace path exists and contains sessions."), options.json);
|
|
112
|
+
process.exit(exitCode);
|
|
113
|
+
}
|
|
114
|
+
if (isDataNotFoundError(error)) {
|
|
115
|
+
const exitCode = handleError(ioError('Claude Code data directory not found', 'Make sure Claude Code is installed and has been used at least once.'), options.json);
|
|
116
|
+
process.exit(exitCode);
|
|
117
|
+
}
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Register the migrate command
|
|
123
|
+
*/
|
|
124
|
+
export function registerMigrateCommand(program) {
|
|
125
|
+
program
|
|
126
|
+
.command('migrate [session]')
|
|
127
|
+
.description('Copy or move session(s) to a different workspace')
|
|
128
|
+
.option('-D, --destination <path>', 'Destination workspace path (required)')
|
|
129
|
+
.option('-S, --source <path>', 'Source workspace path (required with --all)')
|
|
130
|
+
.option('-m, --mode <mode>', 'Migration mode: copy or move', 'copy')
|
|
131
|
+
.option('-a, --all', 'Migrate all sessions from source workspace', false)
|
|
132
|
+
.action(async (sessionArg, cmdOptions) => {
|
|
133
|
+
const globalOptions = program.opts();
|
|
134
|
+
const options = { ...globalOptions, ...cmdOptions };
|
|
135
|
+
try {
|
|
136
|
+
await executeMigrate(sessionArg, options);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
const exitCode = handleError(error, options.json);
|
|
140
|
+
process.exit(exitCode);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
//# 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,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search command implementation
|
|
3
|
+
*
|
|
4
|
+
* Searches for text across all sessions or within a specific session.
|
|
5
|
+
*/
|
|
6
|
+
import type { Command } from 'commander';
|
|
7
|
+
/**
|
|
8
|
+
* Register the search command
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerSearchCommand(program: Command): void;
|
|
11
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/search.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+GzC;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmB5D"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search command implementation
|
|
3
|
+
*
|
|
4
|
+
* Searches for text across all sessions or within a specific session.
|
|
5
|
+
*/
|
|
6
|
+
import { searchSessions, searchInSession, isDataNotFoundError, } from '../../lib/index.js';
|
|
7
|
+
import { resolveConfig, toLibraryConfig, parseSessionRef, } from '../utils/config.js';
|
|
8
|
+
import { ioError } from '../utils/errors.js';
|
|
9
|
+
import { successResult, output, handleError } from '../utils/output.js';
|
|
10
|
+
import { formatSearchResults, formatSearchResultsForJson, } from '../formatters/search.js';
|
|
11
|
+
import { outputWithPager } from '../formatters/pager.js';
|
|
12
|
+
/**
|
|
13
|
+
* Execute the search command
|
|
14
|
+
*/
|
|
15
|
+
async function executeSearch(query, options) {
|
|
16
|
+
const config = resolveConfig(options);
|
|
17
|
+
const contextLines = parseInt(options.context, 10) || 2;
|
|
18
|
+
const limit = parseInt(options.limit, 10) || 20;
|
|
19
|
+
const offset = parseInt(options.offset, 10) || 0;
|
|
20
|
+
const libConfig = toLibraryConfig(config, {
|
|
21
|
+
context: contextLines,
|
|
22
|
+
limit,
|
|
23
|
+
offset,
|
|
24
|
+
});
|
|
25
|
+
try {
|
|
26
|
+
if (options.session) {
|
|
27
|
+
// Search within a specific session
|
|
28
|
+
const sessionRef = parseSessionRef(options.session);
|
|
29
|
+
const matches = await searchInSession(sessionRef, query, libConfig);
|
|
30
|
+
// Manual pagination for single session search
|
|
31
|
+
const total = matches.length;
|
|
32
|
+
const paginatedMatches = matches.slice(offset, offset + limit);
|
|
33
|
+
const pagination = {
|
|
34
|
+
total,
|
|
35
|
+
offset,
|
|
36
|
+
limit,
|
|
37
|
+
hasMore: offset + limit < total,
|
|
38
|
+
};
|
|
39
|
+
if (options.json) {
|
|
40
|
+
const jsonData = formatSearchResultsForJson(paginatedMatches, pagination);
|
|
41
|
+
const commandResult = successResult(jsonData);
|
|
42
|
+
output(commandResult, true);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const formatted = formatSearchResults(paginatedMatches, query, contextLines, pagination);
|
|
46
|
+
await outputWithPager(formatted, options.full);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
// Search across all sessions
|
|
51
|
+
const result = await searchSessions(query, libConfig);
|
|
52
|
+
if (options.json) {
|
|
53
|
+
const jsonData = formatSearchResultsForJson(result.data, result.pagination);
|
|
54
|
+
const commandResult = successResult(jsonData);
|
|
55
|
+
output(commandResult, true);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
const formatted = formatSearchResults(result.data, query, contextLines, result.pagination);
|
|
59
|
+
await outputWithPager(formatted, options.full);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (isDataNotFoundError(error)) {
|
|
65
|
+
const exitCode = handleError(ioError('Claude Code data directory not found', 'Make sure Claude Code is installed and has been used at least once.'), options.json);
|
|
66
|
+
process.exit(exitCode);
|
|
67
|
+
}
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Register the search command
|
|
73
|
+
*/
|
|
74
|
+
export function registerSearchCommand(program) {
|
|
75
|
+
program
|
|
76
|
+
.command('search <query>')
|
|
77
|
+
.description('Search for text across sessions')
|
|
78
|
+
.option('-s, --session <session>', 'Search within a specific session (index or UUID)')
|
|
79
|
+
.option('-c, --context <lines>', 'Number of context lines around matches', '2')
|
|
80
|
+
.option('-l, --limit <count>', 'Maximum number of results', '20')
|
|
81
|
+
.option('-o, --offset <count>', 'Skip first N results', '0')
|
|
82
|
+
.action(async (query, cmdOptions) => {
|
|
83
|
+
const globalOptions = program.opts();
|
|
84
|
+
const options = { ...globalOptions, ...cmdOptions };
|
|
85
|
+
try {
|
|
86
|
+
await executeSearch(query, options);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
const exitCode = handleError(error, options.json);
|
|
90
|
+
process.exit(exitCode);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/cli/commands/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* View command implementation
|
|
3
|
+
*
|
|
4
|
+
* Views the full content of a specific session.
|
|
5
|
+
*/
|
|
6
|
+
import type { Command } from 'commander';
|
|
7
|
+
/**
|
|
8
|
+
* Register the view command
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerViewCommand(program: Command): void;
|
|
11
|
+
//# sourceMappingURL=view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/view.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoFzC;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAc1D"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* View command implementation
|
|
3
|
+
*
|
|
4
|
+
* Views the full content of a specific session.
|
|
5
|
+
*/
|
|
6
|
+
import { getSession, isSessionNotFoundError, isDataNotFoundError, } from '../../lib/index.js';
|
|
7
|
+
import { resolveConfig, toLibraryConfig, parseSessionRef, } from '../utils/config.js';
|
|
8
|
+
import { notFoundError, ioError, usageError } from '../utils/errors.js';
|
|
9
|
+
import { successResult, output, handleError } from '../utils/output.js';
|
|
10
|
+
import { formatSession, formatSessionForJson } from '../formatters/session.js';
|
|
11
|
+
import { outputWithPager } from '../formatters/pager.js';
|
|
12
|
+
/**
|
|
13
|
+
* Execute the view command
|
|
14
|
+
*/
|
|
15
|
+
async function executeView(sessionArg, options) {
|
|
16
|
+
if (!sessionArg) {
|
|
17
|
+
const exitCode = handleError(usageError('Session identifier required', "Usage: cch view <session>\n\nProvide a session index (e.g., '0') or UUID."), options.json);
|
|
18
|
+
process.exit(exitCode);
|
|
19
|
+
}
|
|
20
|
+
const config = resolveConfig(options);
|
|
21
|
+
const sessionRef = parseSessionRef(sessionArg);
|
|
22
|
+
const libConfig = toLibraryConfig(config);
|
|
23
|
+
try {
|
|
24
|
+
const session = await getSession(sessionRef, libConfig);
|
|
25
|
+
if (options.json) {
|
|
26
|
+
// JSON output
|
|
27
|
+
const jsonData = formatSessionForJson(session);
|
|
28
|
+
const commandResult = successResult(jsonData);
|
|
29
|
+
output(commandResult, true);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
// Human-readable output
|
|
33
|
+
const formattedSession = formatSession(session);
|
|
34
|
+
await outputWithPager(formattedSession, options.full);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (isSessionNotFoundError(error)) {
|
|
39
|
+
const exitCode = handleError(notFoundError(`Session not found: ${sessionArg}`, "Try 'cch list' to see available sessions."), options.json);
|
|
40
|
+
process.exit(exitCode);
|
|
41
|
+
}
|
|
42
|
+
if (isDataNotFoundError(error)) {
|
|
43
|
+
const exitCode = handleError(ioError('Claude Code data directory not found', 'Make sure Claude Code is installed and has been used at least once.'), options.json);
|
|
44
|
+
process.exit(exitCode);
|
|
45
|
+
}
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Register the view command
|
|
51
|
+
*/
|
|
52
|
+
export function registerViewCommand(program) {
|
|
53
|
+
program
|
|
54
|
+
.command('view <session>')
|
|
55
|
+
.description("View a session's contents")
|
|
56
|
+
.action(async (sessionArg) => {
|
|
57
|
+
const globalOptions = program.opts();
|
|
58
|
+
try {
|
|
59
|
+
await executeView(sessionArg, globalOptions);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
const exitCode = handleError(error, globalOptions.json);
|
|
63
|
+
process.exit(exitCode);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.js","sourceRoot":"","sources":["../../../src/cli/commands/view.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pager utility for paginated output
|
|
3
|
+
*
|
|
4
|
+
* Handles interactive output pagination using system pager (less/more)
|
|
5
|
+
* or direct stdout when --full flag is used or stdout is not a TTY.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Output content with optional pagination
|
|
9
|
+
*
|
|
10
|
+
* Behavior:
|
|
11
|
+
* - If full=true: Output directly to stdout (for piping)
|
|
12
|
+
* - If stdout is not a TTY: Output directly (for piping)
|
|
13
|
+
* - Otherwise: Use system pager for interactive scrolling
|
|
14
|
+
*
|
|
15
|
+
* @param content - Content to output
|
|
16
|
+
* @param full - Whether to bypass pagination (--full flag)
|
|
17
|
+
* @returns Promise that resolves when output is complete
|
|
18
|
+
*/
|
|
19
|
+
export declare function outputWithPager(content: string, full: boolean): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Simple synchronous output without pager
|
|
22
|
+
* Used for JSON output or when async pager is not appropriate
|
|
23
|
+
*/
|
|
24
|
+
export declare function outputDirect(content: string): void;
|
|
25
|
+
//# sourceMappingURL=pager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pager.d.ts","sourceRoot":"","sources":["../../../src/cli/formatters/pager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA6BH;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC,IAAI,CAAC,CAqEf;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKlD"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pager utility for paginated output
|
|
3
|
+
*
|
|
4
|
+
* Handles interactive output pagination using system pager (less/more)
|
|
5
|
+
* or direct stdout when --full flag is used or stdout is not a TTY.
|
|
6
|
+
*/
|
|
7
|
+
import { spawn } from 'child_process';
|
|
8
|
+
import { ENV_VARS } from '../utils/config.js';
|
|
9
|
+
/**
|
|
10
|
+
* Get the system pager command
|
|
11
|
+
*
|
|
12
|
+
* Priority:
|
|
13
|
+
* 1. PAGER environment variable
|
|
14
|
+
* 2. 'less' on Unix-like systems
|
|
15
|
+
* 3. 'more' on Windows
|
|
16
|
+
*/
|
|
17
|
+
function getSystemPager() {
|
|
18
|
+
const envPager = process.env[ENV_VARS.PAGER];
|
|
19
|
+
if (envPager) {
|
|
20
|
+
return envPager;
|
|
21
|
+
}
|
|
22
|
+
return process.platform === 'win32' ? 'more' : 'less';
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Check if stdout is interactive (TTY)
|
|
26
|
+
*/
|
|
27
|
+
function isInteractive() {
|
|
28
|
+
return process.stdout.isTTY === true;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Output content with optional pagination
|
|
32
|
+
*
|
|
33
|
+
* Behavior:
|
|
34
|
+
* - If full=true: Output directly to stdout (for piping)
|
|
35
|
+
* - If stdout is not a TTY: Output directly (for piping)
|
|
36
|
+
* - Otherwise: Use system pager for interactive scrolling
|
|
37
|
+
*
|
|
38
|
+
* @param content - Content to output
|
|
39
|
+
* @param full - Whether to bypass pagination (--full flag)
|
|
40
|
+
* @returns Promise that resolves when output is complete
|
|
41
|
+
*/
|
|
42
|
+
export async function outputWithPager(content, full) {
|
|
43
|
+
// Direct output if --full flag or not interactive
|
|
44
|
+
if (full || !isInteractive()) {
|
|
45
|
+
process.stdout.write(content);
|
|
46
|
+
if (!content.endsWith('\n')) {
|
|
47
|
+
process.stdout.write('\n');
|
|
48
|
+
}
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// Use system pager for interactive output
|
|
52
|
+
return new Promise((resolve, _reject) => {
|
|
53
|
+
const pager = getSystemPager();
|
|
54
|
+
let child;
|
|
55
|
+
try {
|
|
56
|
+
child = spawn(pager, [], {
|
|
57
|
+
stdio: ['pipe', 'inherit', 'inherit'],
|
|
58
|
+
shell: process.platform === 'win32', // Use shell on Windows for 'more'
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
// Fallback to direct output if pager fails to spawn
|
|
63
|
+
// Log error to stderr for debugging (e.g., pager not found)
|
|
64
|
+
if (process.env.DEBUG) {
|
|
65
|
+
process.stderr.write(`Pager error: ${error instanceof Error ? error.message : error}\n`);
|
|
66
|
+
}
|
|
67
|
+
process.stdout.write(content);
|
|
68
|
+
if (!content.endsWith('\n')) {
|
|
69
|
+
process.stdout.write('\n');
|
|
70
|
+
}
|
|
71
|
+
resolve();
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
child.on('error', () => {
|
|
75
|
+
// Fallback to direct output if pager errors
|
|
76
|
+
process.stdout.write(content);
|
|
77
|
+
if (!content.endsWith('\n')) {
|
|
78
|
+
process.stdout.write('\n');
|
|
79
|
+
}
|
|
80
|
+
resolve();
|
|
81
|
+
});
|
|
82
|
+
child.on('close', (code) => {
|
|
83
|
+
if (code === 0 || code === null) {
|
|
84
|
+
resolve();
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
// Pager exited with error, but content was likely displayed
|
|
88
|
+
resolve();
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
if (child.stdin) {
|
|
92
|
+
child.stdin.on('error', () => {
|
|
93
|
+
// Ignore broken pipe errors (user quit pager early)
|
|
94
|
+
resolve();
|
|
95
|
+
});
|
|
96
|
+
child.stdin.write(content);
|
|
97
|
+
child.stdin.end();
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
// No stdin available, fall back to direct output
|
|
101
|
+
process.stdout.write(content);
|
|
102
|
+
if (!content.endsWith('\n')) {
|
|
103
|
+
process.stdout.write('\n');
|
|
104
|
+
}
|
|
105
|
+
resolve();
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Simple synchronous output without pager
|
|
111
|
+
* Used for JSON output or when async pager is not appropriate
|
|
112
|
+
*/
|
|
113
|
+
export function outputDirect(content) {
|
|
114
|
+
process.stdout.write(content);
|
|
115
|
+
if (!content.endsWith('\n')) {
|
|
116
|
+
process.stdout.write('\n');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=pager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pager.js","sourceRoot":"","sources":["../../../src/cli/formatters/pager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search result formatter for CLI display
|
|
3
|
+
*
|
|
4
|
+
* Formats SearchMatch arrays into human-readable search results.
|
|
5
|
+
*/
|
|
6
|
+
import type { SearchMatch } from '../../lib/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* Format search results for human-readable display
|
|
9
|
+
*
|
|
10
|
+
* @param matches - Array of search matches
|
|
11
|
+
* @param query - The search query (for display)
|
|
12
|
+
* @param contextLines - Number of context lines shown
|
|
13
|
+
* @param pagination - Pagination info
|
|
14
|
+
* @returns Formatted search results string
|
|
15
|
+
*/
|
|
16
|
+
export declare function formatSearchResults(matches: SearchMatch[], query: string, contextLines: number, pagination: {
|
|
17
|
+
total: number;
|
|
18
|
+
offset: number;
|
|
19
|
+
limit: number;
|
|
20
|
+
hasMore: boolean;
|
|
21
|
+
}): string;
|
|
22
|
+
/**
|
|
23
|
+
* Format search results for JSON output
|
|
24
|
+
*
|
|
25
|
+
* @param matches - Array of search matches
|
|
26
|
+
* @param pagination - Pagination info
|
|
27
|
+
* @returns Structured data for JSON serialization
|
|
28
|
+
*/
|
|
29
|
+
export declare function formatSearchResultsForJson(matches: SearchMatch[], pagination: {
|
|
30
|
+
total: number;
|
|
31
|
+
offset: number;
|
|
32
|
+
limit: number;
|
|
33
|
+
hasMore: boolean;
|
|
34
|
+
}): {
|
|
35
|
+
matches: SearchMatch[];
|
|
36
|
+
pagination: typeof pagination;
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/cli/formatters/search.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAoFtD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,WAAW,EAAE,EACtB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAC7E,MAAM,CAiCR;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,WAAW,EAAE,EACtB,UAAU,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAC7E;IAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAAC,UAAU,EAAE,OAAO,UAAU,CAAA;CAAE,CAK3D"}
|