Commands
pconv list
Section titled “pconv list”List conversations discoverable on this machine. Surfaces each
distinct sessionId — a single JSONL may hold several when /compact
writes a continuation to the same file.
pconv list # table (default), newest firstpconv list --format jsonpconv list --min-messages 5 # hide short placeholder sessionspconv list --workspace-toml auto # scope to current portagenty workspacepconv list --show-duplicates # keep WSL- + Windows-encoded copies--workspace-toml reads both projects and previous_paths from the
TOML; the latter is how a moved workspace keeps surfacing sessions from
its pre-move cwd without any out-of-band state.
Filtering, sorting, limiting
Section titled “Filtering, sorting, limiting”# Time window — relative or absolutepconv list --since 2d # last 2 dayspconv list --since 6hpconv list --since 2026-04-01 # from a date
# Substring search on title + cwd (NOT full content)pconv list --grep reactpconv list --grep /work/api
# Sort by column; use --reverse to flip directionpconv list --sort msgs # chattiest firstpconv list --sort title # A → Zpconv list --sort started --reverse # oldest first
# Cap outputpconv list --limit 10
# Compose: last week, containing "refactor", in the current workspace, top 5pconv list --workspace-toml auto --since 7d --grep refactor --limit 5Sort keys: updated (default), started, msgs, title, id.
Time and count keys default to newest/biggest first; title and id
default to ascending alphabetic. --reverse flips whichever default
applies.
Output columns (table): session-id · msgs · updated · cwd · title.
Title is derived from the first user message; cwd is truncated with a
leading … when long (the project’s tail is usually more
recognizable than its home-dir prefix).
Subagent JSONLs are filtered by path pattern and do not appear in the list — see the concepts page for the rule.
pconv dump [<session-id>]
Section titled “pconv dump [<session-id>]”Render one session to stdout. Markdown is the default (paste-ready);
use --format json for the raw normalized model.
pconv dump 01234567-89ab-cdef-0123-456789abcdef
# Skip the list + copy step entirelypconv dump --latest # most recent session on this machinepconv dump --latest --workspace-toml auto # most recent in this workspacepconv dump --latest --rewrite wsl-to-win # compose with rewrite for cross-OS paste
# Markdown knobspconv dump <id> --include-thinking # show assistant reasoning blockspconv dump <id> --full-results # emit full tool-result bodiespconv dump <id> --include-system-events # append the system_events section
# Path rewriting — content only, not cwd metadatapconv dump <id> --rewrite wsl-to-win # /mnt/c/… → C:\…pconv dump <id> --rewrite win-to-wsl # C:\… → /mnt/c/…pconv dump <id> --rewrite strip # replace absolute paths with <path>
# Length control — keep only the most-recent N messagespconv dump <id> --tail 50 # last 50 msgs; earlier ones droppedpconv dump --latest --workspace-toml auto --tail 30# (the output records how many were dropped: markdown header line,# or JSON extensions.truncated = { tail, original_message_count, dropped })
# Explicit backing-file override — manually pick which duplicatepconv dump <id> --file <path> # bypass corpus walk, load this exact JSONLpconv dump --file <path> # if file has a single session, id is optionalpconv dump --latest --file <path> # newest session within this file
# Machine formatpconv dump <id> --format jsonManually selecting among duplicate sessionIds
Section titled “Manually selecting among duplicate sessionIds”When a workspace has been opened from both WSL and Windows (or the folder has
moved), the same sessionId can exist in two physical JSONLs — one per
encoded-path bucket under ~/.claude/projects/. pconv dump <id> picks one
automatically (basename-stem match first, then largest file), which is usually
right but occasionally not. Use --file <path> to override:
# Discover the paths for a duplicated idpconv list --show-duplicates --format json | jq '.[] | select(.id == "<id>") | .source_path'
# Load the one you actually wantpconv dump <id> --file "/home/you/.claude/projects/C--your-project/<id>.jsonl"--file conflicts with --workspace-toml (workspace scope applies to the
corpus walk, which --file bypasses by design). If the file contains multiple
sessions (common after /compact), pair --file with a positional <id> or
--latest to pick one; otherwise an error lists the ids available in the file.
--latest and a positional <session-id> are mutually exclusive.
--latest alone surfaces the most recent session on the whole
machine; combined with --workspace-toml it scopes to that
workspace. The portagenty one-liner is:
pconv dump --latest --workspace-toml auto | clip.exeMarkdown output shape
Section titled “Markdown output shape”Each message becomes a heading (## User / ## Assistant) followed by:
- plain text (rendered verbatim)
- tool calls as tool call: label + a fenced
jsonblock with pretty-printed input - tool results as tool result: label + a fenced code block (truncated to 600 chars by default;
--full-resultsto expand) - thinking blocks hidden by default (
--include-thinkingto show) - unknown content blocks surface an HTML comment + inline note rather than silently dropping
Rewrite scope
Section titled “Rewrite scope”| Rewritten | Left alone |
|---|---|
ContentBlock::Text.text (prose) | Conversation.cwd (authoring env metadata) |
ContentBlock::ToolUse.input (all strings inside the JSON, recursively) | Message.extensions (adapter-preserved raw bits) |
ContentBlock::ToolResult.output (result bodies) | ContentBlock::ToolUse.id / tool_use_id (opaque handles) |
ContentBlock::Thinking.text (internal reasoning) |
Windows → WSL regex is bounded to avoid URL-scheme false positives
(https:// doesn’t match s://). WSL → Windows only matches the
/mnt/<letter>/… form, so bare Linux paths like /home/alice/…
stay untouched.
pconv mcp serve
Section titled “pconv mcp serve”Stdio MCP server speaking JSON-RPC 2.0 (protocol version 2024-11-05).
Line-delimited framing — one JSON object per line on stdin/stdout.
Tools:
list_conversations { min_messages?, show_duplicates?, workspace_toml?, since?, sort?, reverse?, limit?, grep? }— same surface aspconv list.get_conversation { id?, latest?, workspace_toml?, format?, rewrite?, include_thinking?, full_results?, tail?, file? }— same surface aspconv dump. Passlatest: true(optionally withworkspace_toml) to resolve the most recent session in scope without a priorlist_conversationscall.tail: Nkeeps only the most-recent N messages and records the drop count.file: "<path>"bypasses the corpus walk and loads from that specific JSONL — the manual-selection escape hatch for duplicate sessionIds (fileandworkspace_tomlconflict).
Resources: one URI template convos://conversation/{id}.
resources/read returns the session rendered as markdown with default options.
Wiring into an MCP client (~/.claude/mcp.json or equivalent):
{ "mcpServers": { "portaconv": { "command": "pconv", "args": ["mcp", "serve"] } }}See agents + portagenty for usage patterns (post-compact recovery, cross-tool handoff, committed recovery artifacts).
Non-goals for v0.1
Section titled “Non-goals for v0.1”- No
pconv copy(clipboard integration — v0.2). Pipe toclip.exe/pbcopy/wl-copyyourself. - No
pconv export --to <file>(committable handoff docs — v0.2). Redirect stdout. - No full-content search —
--grepis substring-over-title-and-cwd only. Full-content FTS stays deferred (separate verb if / when it lands). - No writes back to any tool’s storage. Ever. Read-only by design.