Skip to content

feat: add dump command for bulk session export#20

Open
commandlinetips wants to merge 3 commits intoyigitkonur:mainfrom
commandlinetips:main
Open

feat: add dump command for bulk session export#20
commandlinetips wants to merge 3 commits intoyigitkonur:mainfrom
commandlinetips:main

Conversation

@commandlinetips
Copy link

@commandlinetips commandlinetips commented Feb 28, 2026

Summary

Adds a new dump command to bulk export sessions to markdown or JSON files.

Usage

# Export all sessions to markdown (default)
continues dump all ./sessions

# Export specific tool's sessions
continues dump claude ./sessions/claude
continues dump gemini ./sessions/gemini

# Export as JSON instead of markdown
continues dump all ./sessions --json

# Control verbosity with presets
continues dump all ./sessions --preset full

# Limit number of sessions
continues dump all ./sessions --limit 50

Options

Flag Description
--preset <name> Verbosity: minimal, standard, verbose, full (default: standard)
--json Output raw session JSON instead of markdown
--limit <n> Limit number of sessions (default: no limit)
--rebuild Force rebuild session index before dumping

Implementation

  • New file: src/commands/dump.ts - dump command handler
  • Modified: src/cli.ts - register the command
  • Updated: README.md - documentation

File Naming

  • Markdown: {source}_{id}.md (e.g., claude_abc123def456.md)
  • JSON: {source}_{id}.json (e.g., gemini_def789ghi012.json)

Test plan

  • continues dump --help shows correct usage
  • continues dump all ./dir --limit 3 exports 3 markdown files
  • continues dump all ./dir --json exports JSON files
  • continues dump opencode ./dir filters by source
  • continues dump claude ./dir --preset full uses full verbosity

Review all of them with eye of John Carmack-like simplicity with elegeance approach and apply the one only if required

Greptile Summary

Adds bulk export command for sessions. Core feature is solid — reuses existing getAllSessions, getSessionsBySource, and adapter extractContext methods. Integrates naturally with the CLI's flag patterns and verbosity presets.

Critical bugs found:

  • Missing adapter null check causes crash on invalid session source
  • "By source" breakdown counts attempted exports, not successful ones — misleading when errors occur
  • No top-level try-catch, unlike other commands (see list.ts)
  • Unnecessary fs.existsSync check before mkdirSync with recursive flag

Feature itself fits well. Implementation needs tightening.

Confidence Score: 2/5

  • Not safe to merge — crashes on edge cases, misleading output
  • Two critical bugs that cause crashes or misleading output, plus inconsistent error handling. The missing adapter null check will crash the command if any session has corrupted metadata. The "by source" count bug makes error reporting confusing. Documentation and CLI integration are clean, but the core command needs fixes.
  • src/commands/dump.ts needs immediate fixes for crash bugs and error handling

Important Files Changed

Filename Overview
src/commands/dump.ts New bulk export command with critical bugs: missing adapter null check (crashes on invalid source), misleading source counts (includes failures), unnecessary existsSync check, no top-level error handling
src/cli.ts Clean command registration for dump - follows existing patterns, options match implementation
README.md Documentation accurately describes dump command usage, options, and examples

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    Start([continues dump source dir --options]) --> ValidateSource{Valid source?}
    ValidateSource -->|No| ErrorExit1[Exit with error]
    ValidateSource -->|Yes| LoadSessions[Load sessions from index]
    LoadSessions --> CheckEmpty{Sessions found?}
    CheckEmpty -->|No| InfoExit[Print 'No sessions found' & exit]
    CheckEmpty -->|Yes| ApplyLimit[Apply --limit if specified]
    ApplyLimit --> CreateDir[Create target directory recursive]
    CreateDir --> GetPreset[Load verbosity preset]
    GetPreset --> LoopStart[Start export loop]
    LoopStart --> LoopNext{More sessions?}
    LoopNext -->|No| PrintSummary[Print summary: success/errors/time]
    LoopNext -->|Yes| CheckFormat{--json flag?}
    CheckFormat -->|Yes| ExportJSON[Write session as JSON]
    CheckFormat -->|No| GetAdapter[Get adapter for session.source]
    GetAdapter --> ExtractContext[adapter.extractContext with preset]
    ExtractContext --> ExportMD[Write markdown file]
    ExportJSON --> IncrSuccess[Increment successCount]
    ExportMD --> IncrSuccess
    IncrSuccess --> LoopNext
    PrintSummary --> CountBySource[Count sessions by source]
    CountBySource --> PrintBreakdown[Print source breakdown table]
    PrintBreakdown --> End([Exit with code 0 or 1])
Loading

Last reviewed commit: a2a51c2

(2/5) Greptile learns from your feedback when you react with thumbs up/down!

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

Comment on lines 62 to 65
try {
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir, { recursive: true });
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary check. mkdirSync with recursive: true already handles existing directories gracefully. Delete the existsSync check:

Suggested change
try {
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir, { recursive: true });
}
try {
fs.mkdirSync(targetDir, { recursive: true });
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/commands/dump.ts
Line: 62-65

Comment:
Unnecessary check. `mkdirSync` with `recursive: true` already handles existing directories gracefully. Delete the `existsSync` check:

```suggestion
  try {
    fs.mkdirSync(targetDir, { recursive: true });
```

How can I resolve this? If you propose a fix, please make it concise.

fs.writeFileSync(filepath, json, 'utf8');
} else {
// Markdown export - reuse adapter's extractContext
const adapter = adapters[session.source];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing null check. If session has corrupted/invalid source, adapters[session.source] returns undefined and line 107 crashes with "Cannot read property 'extractContext' of undefined".

Add guard:

Suggested change
const adapter = adapters[session.source];
const adapter = adapters[session.source];
if (!adapter) {
errorCount++;
continue;
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/commands/dump.ts
Line: 106

Comment:
Missing null check. If session has corrupted/invalid source, `adapters[session.source]` returns undefined and line 107 crashes with "Cannot read property 'extractContext' of undefined".

Add guard:
```suggestion
        const adapter = adapters[session.source];
        if (!adapter) {
          errorCount++;
          continue;
        }
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines 135 to 141
const bySource = sessions.reduce(
(acc, s) => {
acc[s.source] = (acc[s.source] || 0) + 1;
return acc;
},
{} as Record<string, number>,
);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"By source" count includes failed exports. If 10 claude sessions were attempted and 3 failed, this shows "claude: 10" when only 7 actually exported. Track which sessions succeeded and count those instead.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/commands/dump.ts
Line: 135-141

Comment:
"By source" count includes failed exports. If 10 claude sessions were attempted and 3 failed, this shows "claude: 10" when only 7 actually exported. Track which sessions succeeded and count those instead.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +17 to +27
export async function dumpCommand(
sourceOrAll: string,
directory: string,
options: {
preset?: string;
json?: boolean;
limit?: string;
rebuild?: boolean;
},
context: { isTTY: boolean },
): Promise<void> {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No top-level error handler. If getAllSessions or getSessionsBySource throws, the command crashes ungracefully. See list.ts:15-60 which wraps everything in try-catch and sets process.exitCode = 1 on error.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/commands/dump.ts
Line: 17-27

Comment:
No top-level error handler. If `getAllSessions` or `getSessionsBySource` throws, the command crashes ungracefully. See `list.ts:15-60` which wraps everything in try-catch and sets `process.exitCode = 1` on error.

How can I resolve this? If you propose a fix, please make it concise.

- Add adapter null check to prevent crash on invalid source
- Fix 'by source' count to only include successful exports
- Add top-level try-catch for consistent error handling
- Remove unnecessary existsSync before mkdirSync with recursive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant