
Product
Introducing Reports: An Extensible Reporting Framework for Socket Data
Explore exportable charts for vulnerabilities, dependencies, and usage with Reports, Socket’s new extensible reporting framework.
opencode-manager
Advanced tools
Note: This is an independent, community-maintained project created by fans of OpenCode. We are not affiliated with SST Corp. or the official OpenCode project. For the official OpenCode CLI, visit opencode.ai.
Terminal UI for inspecting, filtering, and pruning OpenCode metadata stored on disk. The app is written in TypeScript, runs on Bun, and renders with @opentui/react.
Main workspace with Projects (left) and Sessions (right) panels.
Alternate home view with project/session context.
Fuzzy search across sessions with ranked results.
Scriptable CLI output for listing projects and sessions.
/ to focus, results ranked by relevance).V to open viewer).F to search).Shift+R) with title validation.M) preserving session ID.P) with new session ID generation.? or H).bunx so even CI shells can run it without cloning.--experimental-sqlite.The TUI displays token telemetry from OpenCode's stored message data at three levels:
| Field | Description |
|---|---|
| Input | Tokens in the prompt sent to the model |
| Output | Tokens generated by the model |
| Reasoning | Tokens used for chain-of-thought reasoning (some models) |
| Cache Read | Tokens read from provider cache |
| Cache Write | Tokens written to provider cache |
| Total | Sum of all token fields |
storage/message/<sessionId>/*.json files (assistant messages only).? instead of 0.R to reload.# Clone the repo and install deps
git clone git@github.com:kcrommett/oc-manager.git
cd oc-manager
bun install
# Or run on demand without cloning
bunx opencode-manager --help
The repository ships with a focused .gitignore, keeping node_modules/, caches, and logs out of Git history.
The manager provides both a Terminal UI (TUI) and a scriptable CLI interface.
The TUI is the default interface when no subcommand is provided:
# Preferred: zero-install command
bunx opencode-manager --root ~/.local/share/opencode
# Local dev run (forwards extra args after --)
bun run tui -- --root ~/.local/share/opencode
# Legacy Python wrapper (still used by some automation)
./manage_opencode_projects.py --root ~/.local/share/opencode -- --help
Keyboard reference:
Tab/1/2 switch tabs, / search (fuzzy), X clear search, R reload, Q quit, ?/H help.Space toggle selection, A select all, M missing-only filter, D delete, Enter jump to Sessions, Esc clear selection.Space select, A select all, S toggle sort, V view chat, F search chats, D delete, Y copy ID, Shift+R rename, M move, P copy, C clear filter, Enter details, Esc clear selection.Enter to search, Up/Down navigate, Enter opens result, Esc close.Esc close, Up/Down navigate, PgUp/PgDn jump 10, Home/End first/last, Y copy message.The CLI provides scriptable access to all management operations. Use subcommands to list, search, and modify metadata.
| Option | Default | Description |
|---|---|---|
-r, --root <path> | ~/.local/share/opencode | Root path to OpenCode metadata store |
-f, --format <fmt> | table | Output format: json, ndjson, or table |
-l, --limit <n> | 200 | Maximum number of records to return |
--sort <order> | updated | Sort order: updated or created |
-y, --yes | false | Skip confirmation prompts for destructive operations |
-n, --dry-run | false | Preview changes without executing |
-q, --quiet | false | Suppress non-essential output |
-c, --clipboard | false | Copy output to clipboard |
--backup-dir <path> | — | Directory for backup copies before deletion |
--experimental-sqlite | false | Use SQLite database instead of JSONL files (experimental) |
--db <path> | ~/.local/share/opencode/opencode.db | Path to SQLite database (implies --experimental-sqlite) |
--sqlite-strict | false | Fail on any SQLite warning or malformed data |
--force-write | false | Wait for SQLite write locks to clear before failing |
OpenCode can store metadata in SQLite databases. The CLI supports this mode with --experimental-sqlite or by pointing directly at a database with --db <path>.
Key behaviors:
--force-write to wait for the lock to clear.--sqlite-strict to fail fast.When to use SQLite vs JSONL:
Known limitations and differences:
sqlite:project:proj_123) instead of JSON file paths.Examples:
# List projects using the default SQLite database
opencode-manager projects list --experimental-sqlite
# List sessions using an explicit SQLite database path
opencode-manager sessions list --db ~/.local/share/opencode/opencode.db
# Fail fast on malformed SQLite data
opencode-manager projects list --db ~/.local/share/opencode/opencode.db --sqlite-strict
# Wait for locks before destructive operations
opencode-manager projects delete --id proj_missing --db ~/.local/share/opencode/opencode.db --yes --force-write
opencode-manager
├── projects
│ ├── list List projects (--missing-only, --search)
│ └── delete Delete project metadata (--id, --yes, --dry-run, --backup-dir)
├── sessions
│ ├── list List sessions (--project, --search)
│ ├── delete Delete session metadata (--session, --yes, --dry-run, --backup-dir)
│ ├── rename Rename a session (--session, --title)
│ ├── move Move session to another project (--session, --to)
│ └── copy Copy session to another project (--session, --to)
├── chat
│ ├── list List messages in a session (--session, --include-parts)
│ ├── show Show a specific message (--session, --message or --index, --clipboard)
│ └── search Search chat content across sessions (--query, --project)
├── tokens
│ ├── session Show token usage for a session (--session)
│ ├── project Show token usage for a project (--project)
│ └── global Show global token usage
└── tui Launch the Terminal UI
The tui subcommand explicitly launches the Terminal UI. This is equivalent to running opencode-manager with no subcommand:
# These are equivalent:
opencode-manager
opencode-manager tui
opencode-manager tui --root ~/.local/share/opencode
Use the explicit tui subcommand when you want to be clear about intent in scripts or when combining with other options. Note that tui --help shows the TUI help screen (key bindings), not Commander CLI help.
The manager uses a dual help system depending on context:
| Command | Help Type | Content |
|---|---|---|
opencode-manager --help | TUI help | Key bindings and TUI usage |
opencode-manager -h | TUI help | Same as --help |
opencode-manager tui --help | TUI help | Key bindings (routes to TUI help) |
opencode-manager projects --help | CLI help | Commander subcommand help |
opencode-manager sessions --help | CLI help | Commander subcommand help |
opencode-manager chat --help | CLI help | Commander subcommand help |
opencode-manager tokens --help | CLI help | Commander subcommand help |
Why? The root command defaults to launching the TUI, so --help shows TUI-relevant information (key bindings). CLI subcommands use standard Commander.js help showing options and usage.
To see all CLI subcommands, use any subcommand with --help:
# Shows TUI key bindings
opencode-manager --help
# Shows CLI subcommand help with options
opencode-manager projects --help
opencode-manager projects list --help
The CLI supports three output formats via --format:
Table (default) — Human-readable columnar output:
$ bunx opencode-manager projects list --limit 3
# State Path Project ID Created
---- ----- -------------------------------------------------- ------------------------ ----------------
1 ✓ /home/user/repos/my-app a1b2c3d4e5f6g7h8i9j0k1l2 2026-01-04 09:20
2 ✓ /home/user/repos/api-server b2c3d4e5f6g7h8i9j0k1l2m3 2026-01-03 14:15
3 ✗ /home/user/repos/deleted-project c3d4e5f6g7h8i9j0k1l2m3n4 2025-12-28 10:30
JSON — Structured output with metadata envelope:
$ bunx opencode-manager sessions list --project prj_abc123 --format json --limit 2
{
"ok": true,
"data": [
{
"index": 1,
"sessionId": "sess_xyz789",
"projectId": "prj_abc123",
"directory": "/home/user/repos/my-app",
"title": "Refactor auth module",
"version": "1.1.4",
"updatedAt": "2026-01-05T14:32:00.000Z",
"createdAt": "2026-01-03T09:15:00.000Z"
},
{
"index": 2,
"sessionId": "sess_uvw456",
"projectId": "prj_abc123",
"directory": "/home/user/repos/my-app",
"title": "Add unit tests",
"version": "1.1.4",
"updatedAt": "2026-01-04T16:45:00.000Z",
"createdAt": "2026-01-02T11:20:00.000Z"
}
],
"meta": {
"count": 2,
"limit": 2
}
}
JSON output auto-detects your terminal: pretty-printed with indentation when output goes to a TTY, compact single-line when piped to another command.
The meta object contains:
count — Number of items in the data arraylimit — The limit that was applied (if --limit was specified)NDJSON — Newline-delimited JSON for streaming/piping:
$ bunx opencode-manager sessions list --format ndjson --limit 2
{"index":1,"sessionId":"ses_abc123","projectId":"prj_xyz789","title":"Feature implementation","createdAt":"2026-01-06T10:30:00.000Z"}
{"index":2,"sessionId":"ses_def456","projectId":"prj_xyz789","title":"Bug fix session","createdAt":"2026-01-06T11:15:00.000Z"}
Each line is a complete JSON object, ideal for piping to jq or line-by-line processing. For single-record commands like tokens global, NDJSON outputs one line with the same structure as the JSON data field.
Piping examples:
# Count sessions per project
bunx opencode-manager sessions list --format ndjson | jq -s 'group_by(.projectId) | map({project: .[0].projectId, count: length})'
# Get all session IDs as plain text
bunx opencode-manager sessions list --format json | jq -r '.data[].sessionId'
# Export chat history to file
bunx opencode-manager chat list --session sess_xyz789 --include-parts --format json > chat-export.json
# Dry-run delete to preview affected files
bunx opencode-manager projects delete --id prj_old --dry-run --format json
Token commands (tokens session, tokens project, tokens global) return structured summaries of token usage.
Session tokens — Single session summary with kind discriminator:
$ bunx opencode-manager tokens session --session sess_xyz789 --format json
# When token data is available (kind: "known"):
{
"ok": true,
"data": {
"kind": "known",
"tokens": {
"input": 12500,
"output": 8750,
"reasoning": 2100,
"cacheRead": 4200,
"cacheWrite": 950,
"total": 28500
}
}
}
# When token data is unavailable (kind: "unknown"):
{
"ok": true,
"data": {
"kind": "unknown",
"reason": "no_messages"
}
}
The reason field indicates why tokens are unavailable:
"missing" — Session metadata file not found"parse_error" — Token data couldn't be parsed"no_messages" — Session has no messages with token dataProject/Global tokens — Aggregate summary across multiple sessions:
$ bunx opencode-manager tokens project --project prj_abc123 --format json
{
"ok": true,
"data": {
"total": {
"kind": "known",
"tokens": { "input": 125000, "output": 98000, "reasoning": 32000, "cacheRead": 15000, "cacheWrite": 6500, "total": 276500 }
},
"knownOnly": { "input": 125000, "output": 98000, "reasoning": 32000, "cacheRead": 15000, "cacheWrite": 6500, "total": 276500 },
"unknownSessions": 2
}
}
Aggregate summary fields:
total — Combined TokenSummary (same structure as session tokens)knownOnly — Token breakdown from sessions with available data only (omitted if all unknown)unknownSessions — Count of sessions where token data was unavailableNote: The tokens commands require exact IDs (no prefix matching). Use full session/project IDs as shown in sessions list or projects list output.
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Usage error (missing required options, invalid arguments) |
| 3 | Resource not found (invalid project/session/message ID) |
| 4 | File operation error (backup or delete failure) |
Most commands accept ID prefixes for convenience. The CLI will match the prefix to a unique ID:
# Full ID
opencode-manager sessions delete --session sess_01JGNPE16DT1JX1YA8KTPMDRW3
# Prefix match (if unique)
opencode-manager sessions delete --session sess_01JGN
# Ambiguous prefix (fails with error listing matches)
opencode-manager sessions delete --session sess_01
# Error: Multiple sessions match prefix 'sess_01': sess_01JGN..., sess_01ABC...
Commands supporting prefix matching:
projects delete --idsessions delete --session, sessions rename --session, sessions move --session, sessions copy --sessionsessions move --to, sessions copy --to (project ID)chat list --session, chat show --sessionchat show --message (also supports 1-based --index)Commands requiring exact IDs:
tokens session --session — requires full session IDtokens project --project — requires full project IDThe --clipboard flag (or Y key in the TUI) copies content to the system clipboard. Platform support:
| Platform | Tool Required | Notes |
|---|---|---|
| macOS | None | Uses built-in pbcopy |
| Linux | xclip | Install via apt install xclip or equivalent |
| Windows | — | Not currently supported |
On Linux, if xclip is not installed, clipboard operations will fail silently in the TUI or show an error message in the CLI.
Delete commands (projects delete, sessions delete) remove metadata files only:
| Command | Deletes | Preserves |
|---|---|---|
projects delete | Project metadata (storage/project/<id>.json) | Sessions, messages, parts |
sessions delete | Session metadata (storage/sessions/<projectId>.json entry) | Message and part files |
Safety features:
Confirmation required — Destructive operations require --yes flag or interactive confirmation:
# Will prompt for confirmation (interactive)
opencode-manager projects delete --id prj_abc123
# Skip confirmation (scripts)
opencode-manager projects delete --id prj_abc123 --yes
Dry-run preview — Use --dry-run to see what would be deleted without making changes:
opencode-manager sessions delete --session sess_xyz789 --dry-run
# Output shows files that would be affected
Backup before delete — Use --backup-dir to copy files before deletion:
opencode-manager projects delete --id prj_abc123 --backup-dir ./backups --yes
# Creates backup, then deletes original
Note: Session deletion leaves associated chat message files intact. To fully remove a session's data, you would need to manually delete the message files from storage/message/<sessionId>/.
bun install.bun run tui (pass storage flags after --).bun run dev for watch mode.bun run typecheck (tsc --noEmit).src/
bin/opencode-manager.ts # Bun-native CLI shim exposed as the bin entry
cli/
index.ts # Commander program with global options
commands/ # Subcommand implementations (projects, sessions, chat, tokens)
resolvers.ts # ID prefix resolution helpers
lib/
opencode-data.ts # JSONL file-based data access
opencode-data-sqlite.ts # SQLite backend (experimental)
opencode-data-provider.ts # Unified DataProvider abstraction
tui/
app.tsx # Main TUI implementation (panels, search, help)
index.tsx # TUI entrypoint with launchTUI(), parseArgs(), bootstrap()
tests/
fixtures/ # Test data (JSONL and SQLite fixtures)
lib/ # Unit tests for data modules
cli/ # CLI integration tests
manage_opencode_projects.py # Legacy Python launcher for backwards compatibility
PROJECT-SUMMARY.md # Extended design notes & roadmap
bun installbun run typecheckversion in package.jsonnpm publish (package exposes the opencode-manager bin with public access)/tmp. Run bun run tui directly if tmux refuses to start.<text> nodes. When adding UI components, follow the existing helpers (e.g., KeyChip, Bullet).Esc while the search bar is focused, or hit X while in normal navigation.Issues and pull requests are welcome. Please include reproduction steps for metadata edge cases and run bun run typecheck before submitting patches.
MIT © OpenCode contributors. See LICENSE.
FAQs
Terminal UI for inspecting OpenCode metadata stores.
We found that opencode-manager demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Explore exportable charts for vulnerabilities, dependencies, and usage with Reports, Socket’s new extensible reporting framework.

Product
Socket for Jira lets teams turn alerts into Jira tickets with manual creation, automated ticketing rules, and two-way sync.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.