opencode-sessions-explorer 0.1.0 → 0.1.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/CHANGELOG.md +18 -0
- package/README.md +130 -257
- package/dist/plugin.js +1 -1
- package/docs/README.md +45 -0
- package/docs/getting-started.md +96 -0
- package/docs/guides/cost-and-usage-analysis.md +75 -0
- package/docs/guides/export-and-maintenance.md +85 -0
- package/docs/guides/manage-archived-sessions.md +70 -0
- package/docs/guides/recall-and-navigation.md +90 -0
- package/docs/guides/search-and-grep.md +87 -0
- package/docs/install.md +140 -0
- package/docs/maintainers/development.md +140 -0
- package/docs/maintainers/docs-writing.md +86 -0
- package/docs/maintainers/release.md +72 -0
- package/docs/maintainers/triage.md +55 -0
- package/docs/reference/architecture.md +112 -0
- package/docs/reference/configuration.md +115 -0
- package/docs/reference/response-format.md +120 -0
- package/docs/reference/search-surfaces.md +106 -0
- package/docs/reference/tools.md +151 -0
- package/docs/support/troubleshooting.md +230 -0
- package/package.json +5 -4
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Cost And Usage Analysis Guide
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Quantify OpenCode spend and token usage across your session history, and surface
|
|
6
|
+
recurring failures and repeated prompts.
|
|
7
|
+
|
|
8
|
+
## Mental Model
|
|
9
|
+
|
|
10
|
+
All four tools aggregate the `session` and `part` tables directly — no export tree
|
|
11
|
+
or `ck` index required. Pick the tool by the shape of the answer you want:
|
|
12
|
+
|
|
13
|
+
- **Spend by dimension** — `cost-by-project` groups by project, directory, agent, or
|
|
14
|
+
model.
|
|
15
|
+
- **Spend over time** — `cost-by-period` buckets the same data by day, week, or month.
|
|
16
|
+
- **Failure signal** — `list-tool-failures` aggregates errored tool calls.
|
|
17
|
+
- **Repetition signal** — `list-repeated-prompts` clusters sessions by their first
|
|
18
|
+
user prompt.
|
|
19
|
+
|
|
20
|
+
### The `cost_known` Flag
|
|
21
|
+
|
|
22
|
+
Sessions created before OpenCode's `session_usage` migration store `cost = 0` even
|
|
23
|
+
though they were not actually free. `cost-by-project` reports `cost_known: false` for
|
|
24
|
+
any group whose sessions are all pre-migration, and `cost-by-period` hides
|
|
25
|
+
zero-valued buckets unless you pass `include_zero_buckets: true`. Treat a zero with
|
|
26
|
+
`cost_known: false` as "unknown", not "$0".
|
|
27
|
+
|
|
28
|
+
## Controls
|
|
29
|
+
|
|
30
|
+
| Tool | Use It For | Key Args |
|
|
31
|
+
| --- | --- | --- |
|
|
32
|
+
| `cost-by-project` | "Spend by project / agent / model", "which directory burned the most tokens" | `group_by` (`project_id`/`directory`/`agent`/`model`), `since_ms`/`until_ms`, `archived`, `min_cost`, `min_tokens`, `top` |
|
|
33
|
+
| `cost-by-period` | "Daily/weekly/monthly spend", "cost trend over time" | `bucket` (`day`/`week`/`month`), `since_ms`/`until_ms`, `project_id`, `agent`, `tz_offset_min`, `min_cost`, `include_zero_buckets`, `max_buckets` |
|
|
34
|
+
| `list-tool-failures` | "Which tool fails most", "what errors keep recurring", "sessions with the most failures" | `group_by` (`tool`/`error`/`session`), `tool`, `error_like`, `since_ms`/`until_ms`, `archived`, `limit`, `error_prefix_chars` |
|
|
35
|
+
| `list-repeated-prompts` | "Have I asked this before", "my most repeated prompts" | `min_count`, `prefix_chars`, `since_ms`/`until_ms`, `archived`, `limit`, `sample_per_group` |
|
|
36
|
+
|
|
37
|
+
## Recommended Flow
|
|
38
|
+
|
|
39
|
+
1. Start broad with a spend breakdown by project:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{ "group_by": "project_id", "top": 20 }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
1. Compare models or agents by switching `group_by`:
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{ "group_by": "model" }
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
1. Look at the trend over time, shifting bucket boundaries to your local day if
|
|
52
|
+
needed (`tz_offset_min` is positive when ahead of UTC):
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{ "bucket": "day", "tz_offset_min": 120 }
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
1. Find what breaks most often, then expand a group with `search-tool-calls`:
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{ "group_by": "tool", "limit": 20 }
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
1. Detect duplicated work by clustering opening prompts:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{ "min_count": 3, "prefix_chars": 80 }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Related Docs
|
|
71
|
+
|
|
72
|
+
- [Recall and navigation](recall-and-navigation.md)
|
|
73
|
+
- [Search and grep](search-and-grep.md)
|
|
74
|
+
- [Tool reference](../reference/tools.md)
|
|
75
|
+
- [Response format](../reference/response-format.md)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Export And Maintenance Guide
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Understand the searchable export tree that content search depends on, and keep it
|
|
6
|
+
healthy with the bundled command-line tools.
|
|
7
|
+
|
|
8
|
+
## Mental Model
|
|
9
|
+
|
|
10
|
+
Content search does not run against the database directly. The plugin maintains a
|
|
11
|
+
four-layer pipeline:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
SQLite DB (read-only source of truth)
|
|
15
|
+
-> filesystem export tree (~/.local/share/opencode-sessions-explorer; by-session + by-channel)
|
|
16
|
+
-> ck index (.ck/, BM25 + embeddings; optional)
|
|
17
|
+
-> enriched response (re-fetches session/part metadata from SQLite per hit)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The export tree materializes each searchable part as a small text file under
|
|
21
|
+
`by-session/<ses_…>/` plus curated `by-channel/` views (such as conversation and
|
|
22
|
+
session-summary). `ck` searches these files; the plugin then re-reads session and
|
|
23
|
+
part metadata from SQLite to enrich each hit. The export root is overridable via
|
|
24
|
+
`OPENCODE_SESSIONS_EXPLORER_EXPORT_ROOT`.
|
|
25
|
+
|
|
26
|
+
### Auto-Sync
|
|
27
|
+
|
|
28
|
+
`search-text` and `grep-session` delta-sync new parts into the export tree before
|
|
29
|
+
each call (a few-second best-effort budget), so day-to-day search stays current
|
|
30
|
+
without manual steps. The CLIs below are for the initial backfill and occasional
|
|
31
|
+
maintenance.
|
|
32
|
+
|
|
33
|
+
## Controls
|
|
34
|
+
|
|
35
|
+
| Command / Tool | Use It For | Notes |
|
|
36
|
+
| --- | --- | --- |
|
|
37
|
+
| `opencode-sessions-explorer-bulk-export` | Build or resume the export tree | Idempotent and resumable via `.last_sync`; `--reset` starts from scratch and rebuilds curated `by-channel/` views; `--root <path>` targets a non-default export root |
|
|
38
|
+
| `opencode-sessions-explorer-dedupe-export` | Remove duplicate part files from an older cursor-migration bug | Dry-run by default (reports only); pass `--apply` to actually delete, keeping the lowest-seq file per part |
|
|
39
|
+
| `opencode-sessions-explorer-check-deps` | Probe install health | Checks DB, schema/drift, SQLite `json1`, `busy_timeout`, export tree, channel views, `ck` CLI, `ck` index, and tool-output dir; `--json` for machine output; exit codes `0` ok, `1` soft warning, `2` hard fail |
|
|
40
|
+
| `db-stats` (tool) | Inspect database health from inside OpenCode | Returns migration head, table counts, json1 status, `busy_timeout`, and schema-drift warnings |
|
|
41
|
+
|
|
42
|
+
## Recommended Flow
|
|
43
|
+
|
|
44
|
+
1. Run the one-time backfill so search has content to scan:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
bunx opencode-sessions-explorer-bulk-export
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
1. If curated channel views are reported as partial (for example by
|
|
51
|
+
`check-deps`), rebuild them once:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
bunx opencode-sessions-explorer-bulk-export --reset
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
1. (Optional) Build the semantic index to unlock `sem` and `hybrid` search modes.
|
|
58
|
+
This is slow and only needs to run once. Run `ck --index .` from the export root,
|
|
59
|
+
not from the repository checkout:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
cd ~/.local/share/opencode-sessions-explorer
|
|
63
|
+
ck --index . # run in the export root, not the repo root
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
1. Verify everything is wired up, and re-run after any OpenCode upgrade:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
bunx opencode-sessions-explorer-check-deps
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
1. If an older export shows duplicate part files, preview then apply a cleanup:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
bunx opencode-sessions-explorer-dedupe-export
|
|
76
|
+
bunx opencode-sessions-explorer-dedupe-export --apply
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Related Docs
|
|
80
|
+
|
|
81
|
+
- [Search and grep](search-and-grep.md)
|
|
82
|
+
- [Architecture](../reference/architecture.md)
|
|
83
|
+
- [Search surfaces](../reference/search-surfaces.md)
|
|
84
|
+
- [Configuration reference](../reference/configuration.md)
|
|
85
|
+
- [Troubleshooting](../support/troubleshooting.md)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Manage Archived Sessions Guide
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Restore a previously archived OpenCode session so it can be opened and prompted
|
|
6
|
+
again, using the one tool in this plugin that writes to the database.
|
|
7
|
+
|
|
8
|
+
## Mental Model
|
|
9
|
+
|
|
10
|
+
`unarchive-session` is the only write surface in an otherwise read-only plugin. It
|
|
11
|
+
does two things in a single isolated write:
|
|
12
|
+
|
|
13
|
+
1. **Clears `time_archived`** so the session is no longer marked archived.
|
|
14
|
+
2. **Refreshes `time_updated`** so the session resurfaces at the top of OpenCode's
|
|
15
|
+
recency-ordered list.
|
|
16
|
+
|
|
17
|
+
The `time_updated` bump is required, not cosmetic. OpenCode loads sessions ordered
|
|
18
|
+
by `time_updated DESC` with a default limit of ~100 per directory. Clearing
|
|
19
|
+
`time_archived` alone leaves a long-archived session buried below that window, so the
|
|
20
|
+
app still fails to retrieve it with "Unable to retrieve session". Refreshing
|
|
21
|
+
`time_updated` is also the intuitive meaning of "restore". Because it always
|
|
22
|
+
restores to a usable state, the tool also resurfaces an already-active-but-buried
|
|
23
|
+
session and is idempotent in effect (active and at the top).
|
|
24
|
+
|
|
25
|
+
### Why A Direct Database Write Is Required
|
|
26
|
+
|
|
27
|
+
OpenCode exposes no archive/unarchive endpoint that can clear the flag: the HTTP
|
|
28
|
+
`UpdatePayload` types `time.archived` as a finite number and the handler ignores
|
|
29
|
+
`undefined`, so a clear cannot be sent over the wire. The `opencode session` CLI
|
|
30
|
+
only offers list and delete. A direct database write is therefore the only
|
|
31
|
+
mechanism. Reads still go through the shared read-only handle; the write goes through
|
|
32
|
+
a separate, short-lived read-write connection used only by this tool.
|
|
33
|
+
|
|
34
|
+
## Controls
|
|
35
|
+
|
|
36
|
+
| Tool | Use It For | Key Args |
|
|
37
|
+
| --- | --- | --- |
|
|
38
|
+
| `unarchive-session` | "Unarchive `ses_…`", "restore an archived session so I can continue it" | `session_id` (must be an existing session; returns `NOT_FOUND` otherwise) |
|
|
39
|
+
| `list-sessions` / `search-sessions-meta` | Find archived sessions to restore | `archived: 'only'` |
|
|
40
|
+
|
|
41
|
+
## Recommended Flow
|
|
42
|
+
|
|
43
|
+
1. Find the archived session you want back:
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{ "archived": "only", "limit": 20 }
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
1. Restore it by id:
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{ "session_id": "ses_XYZ" }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The response reports `was_archived`, the new `now_active` and `resurfaced`
|
|
56
|
+
state, the session `directory`, and before/after `time_updated` values.
|
|
57
|
+
|
|
58
|
+
1. Make the restored session visible in the app. Because the write happens outside
|
|
59
|
+
OpenCode, it emits no `session.updated` event:
|
|
60
|
+
|
|
61
|
+
1. Reload or restart the OpenCode window.
|
|
62
|
+
1. Open OpenCode in the session's own `directory` — it is restored under that
|
|
63
|
+
directory and now sorts to the top of the recency-ordered list.
|
|
64
|
+
|
|
65
|
+
## Related Docs
|
|
66
|
+
|
|
67
|
+
- [Recall and navigation](recall-and-navigation.md)
|
|
68
|
+
- [Tool reference](../reference/tools.md)
|
|
69
|
+
- [Architecture](../reference/architecture.md)
|
|
70
|
+
- [Security policy](../../.github/SECURITY.md)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Recall And Navigation Guide
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Find a past OpenCode session, understand what it contains, and drill from a
|
|
6
|
+
high-level overview down to a single message or part — including the parent/child
|
|
7
|
+
chains created by subagent dispatch.
|
|
8
|
+
|
|
9
|
+
## Mental Model
|
|
10
|
+
|
|
11
|
+
Orient first, then drill down; walk the tree to follow subagent and
|
|
12
|
+
pair-execution chains.
|
|
13
|
+
|
|
14
|
+
- **Orient.** `current-session` tells the assistant which session it is running in
|
|
15
|
+
(id, agent, model, directory, counts, and useful filesystem paths). It is the
|
|
16
|
+
natural first call because the model has no native way to know its own session id.
|
|
17
|
+
- **Find and browse.** `list-sessions` and `search-sessions-meta` locate sessions by
|
|
18
|
+
recency or structured metadata (agent, directory, title, cost, tokens). Neither
|
|
19
|
+
returns message bodies.
|
|
20
|
+
- **Overview.** `get-session` returns one session's metadata and aggregate counts;
|
|
21
|
+
`session-summary` returns a human-readable overview (first/last prompt, top files
|
|
22
|
+
touched, top tools, errors, duration, cost).
|
|
23
|
+
- **Reconstruct.** `session-timeline` returns a chronological event stream (one
|
|
24
|
+
short line per part) without raw bodies.
|
|
25
|
+
- **Drill into detail.** `get-message` fetches one turn and its parts (bodies
|
|
26
|
+
capped); `get-part` fetches a single part and can dereference externalized
|
|
27
|
+
tool-output files.
|
|
28
|
+
- **Trace relationships.** `session-genealogy` walks the `parent_id` chain up to
|
|
29
|
+
ancestors and down to descendants — the graph that subagent dispatches create.
|
|
30
|
+
|
|
31
|
+
## Entry Points
|
|
32
|
+
|
|
33
|
+
| Tool | Answers | Key Args |
|
|
34
|
+
| --- | --- | --- |
|
|
35
|
+
| `current-session` | "What session am I in?", "where am I?", self-orientation | `detail` (`compact`/`full`), `include_suggestions` |
|
|
36
|
+
| `list-sessions` | "List my recent sessions", "sessions from last week", "sessions using agent X" | `limit`, `cursor`, `project_id`, `agent`, `model_id`, `directory_prefix`, `archived`, `since_ms`/`until_ms`, `title_like` |
|
|
37
|
+
| `search-sessions-meta` | "Sessions costing more than $5", "sessions with > 100K input tokens", "most expensive session" | `title_like`, `directory_like`, `project_id`, `agent`, `model_id`, `min_cost`, `min_tokens_input`, `since_ms`/`until_ms`, `archived` |
|
|
38
|
+
| `get-session` | "Metadata for `ses_X`", "how many messages/parts in `ses_Y`", "who is the parent of `ses_X`" | `session_id` |
|
|
39
|
+
| `session-summary` | "Summarize `ses_X`", "what files did I touch", "what tools did I use" | `session_id`, `max_prompt_bytes` |
|
|
40
|
+
| `session-timeline` | "Walk `ses_X` step by step", "show only the tool calls in order" | `session_id`, `types`, `granularity`, `from_ts`/`until_ts`, `limit`, `cursor` |
|
|
41
|
+
| `get-message` | "Fetch message `msg_X` with its parts" | `message_id`, `include_part_data`, `part_types`, `max_part_bytes` |
|
|
42
|
+
| `get-part` | "Show part `prt_X`", "dereference the externalized output of `prt_Z`" | `part_id`, `max_bytes`, `dereference_output_path` |
|
|
43
|
+
| `session-genealogy` | "Parent chain of `ses_X`", "what subagents did `ses_Y` spawn" | `session_id`, `direction` (`ancestors`/`descendants`/`both`), `max_depth`, `include_archived` |
|
|
44
|
+
|
|
45
|
+
## Recommended Flow
|
|
46
|
+
|
|
47
|
+
1. Start with `current-session` to capture your own `session_id` and context.
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{ "detail": "full" }
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
1. If you do not yet know the session, narrow with `list-sessions` (recency) or
|
|
54
|
+
`search-sessions-meta` (cost/token/title thresholds).
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{ "agent": "build", "since_ms": 1717200000000, "limit": 20 }
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
1. Get the gist with `session-summary`, or raw counts with `get-session`.
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{ "session_id": "ses_XYZ", "max_prompt_bytes": 2048 }
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
1. Reconstruct the flow with `session-timeline`, filtering `types` to keep it tight.
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{ "session_id": "ses_XYZ", "types": ["tool", "patch"], "limit": 100 }
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
1. Expand a specific event with `get-message` (whole turn) or `get-part` (one part).
|
|
73
|
+
For tool output that was externalized to a file, set `dereference_output_path`:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{ "part_id": "prt_ABC", "dereference_output_path": true }
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
1. Trace dispatch chains with `session-genealogy` when a session spawned subagents.
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{ "session_id": "ses_XYZ", "direction": "both", "max_depth": 5 }
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Related Docs
|
|
86
|
+
|
|
87
|
+
- [Search and grep](search-and-grep.md)
|
|
88
|
+
- [Tool reference](../reference/tools.md)
|
|
89
|
+
- [Response format](../reference/response-format.md)
|
|
90
|
+
- [Getting Started](../getting-started.md)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Search And Grep Guide
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Search across the bodies of your entire OpenCode session history, grep inside one
|
|
6
|
+
known session, and audit individual tool invocations by name, status, or substring.
|
|
7
|
+
|
|
8
|
+
## Default Behavior
|
|
9
|
+
|
|
10
|
+
- `search-text` is the canonical "where in my history did X happen?" tool. Its
|
|
11
|
+
default surface is `recall`: session-first, channel-aware, and evidence-limited,
|
|
12
|
+
searching high-signal conversation and session-summary views before raw replay.
|
|
13
|
+
- The default `mode` is `regex` (a drop-in grep that needs no index and always
|
|
14
|
+
works). `lex` adds BM25 phrase search (auto-builds a Tantivy index), while `sem`
|
|
15
|
+
and `hybrid` add semantic embeddings.
|
|
16
|
+
- The default `role` is `any`. Natural-language questions like "where did I mention
|
|
17
|
+
X" or "have I discussed Y" ask about appearances anywhere in the corpus — only set
|
|
18
|
+
`role:'user'` when the question is explicitly about prompts you authored.
|
|
19
|
+
- For unscoped recall, results default to one row per matching session
|
|
20
|
+
(`group_by_session`); scoped, single-session searches default to flat per-part hits.
|
|
21
|
+
- Snippets redact common secret shapes by default. Pass `redact:false` only for
|
|
22
|
+
local forensics.
|
|
23
|
+
|
|
24
|
+
### The `ck` Dependency
|
|
25
|
+
|
|
26
|
+
`search-text` and `grep-session` shell out to the optional [`ck`](https://github.com/BeaconBay/ck)
|
|
27
|
+
CLI over the filesystem export tree. If `ck` is not installed, both return
|
|
28
|
+
`CK_NOT_FOUND` cleanly; the other 16 tools keep working without it. Semantic modes
|
|
29
|
+
additionally require a one-time `ck --index .` inside the export root — without it,
|
|
30
|
+
`sem`/`hybrid` fall back to `regex` with a warning. See
|
|
31
|
+
[search surfaces](../reference/search-surfaces.md) for the surface/channel model.
|
|
32
|
+
|
|
33
|
+
## Controls
|
|
34
|
+
|
|
35
|
+
| Tool | Use It For | Key Args |
|
|
36
|
+
| --- | --- | --- |
|
|
37
|
+
| `search-text` | Cross-session content search across all bodies (prompts, responses, tool I/O, reasoning, patches) | `q`, `mode` (`regex`/`lex`/`sem`/`hybrid`), `surface`, `channels`, `group_by_session`, `role`, `session_ids`, `project_id`, `agent`, `since_ms`/`until_ms`, `archived`, `limit`, `redact` |
|
|
38
|
+
| `grep-session` | Fast regex/lex grep inside one known session | `session_id`, `pattern`, `surface`, `channels`, `mode` (`regex`/`lex`), `fixed_string`, `case_sensitive`, `whole_word`, `context_lines`, `limit`, `redact` |
|
|
39
|
+
| `search-tool-calls` | Find tool invocations by name, status, or input/output/error substring | `tool` (exact or `LIKE` wildcard), `status`, `input_like`, `output_like`, `error_like`, `session_id`, `project_id`, `since_ms`/`until_ms`, `archived`, `limit`, `cursor` |
|
|
40
|
+
|
|
41
|
+
## Recommended Flow
|
|
42
|
+
|
|
43
|
+
1. For a broad recall question, start with `search-text` and let the default
|
|
44
|
+
`recall` surface curate results:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{ "q": "export codec", "limit": 20 }
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
1. Speed up cross-session search by pre-filtering scope. Unscoped full-corpus search
|
|
51
|
+
can take 10-30 seconds; scoped searches return in under a second:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{ "q": "retry backoff", "project_id": "global", "since_ms": 1717200000000 }
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
1. For exhaustive raw replay over tool output, reasoning, and patches, switch the
|
|
58
|
+
surface:
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{ "q": "SQLITE_BUSY", "surface": "forensics" }
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
1. Once you know the session, grep inside it with `grep-session` (faster, narrower):
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{ "session_id": "ses_XYZ", "pattern": "TODO", "context_lines": 2 }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
1. To audit commands rather than prose, use `search-tool-calls` — for example every
|
|
71
|
+
failed `read`, or every Jira MCP call via a `LIKE` wildcard:
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{ "tool": "read", "status": "error", "limit": 20 }
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{ "tool": "mcp-atlassian_jira_%", "limit": 20 }
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Related Docs
|
|
82
|
+
|
|
83
|
+
- [Search surfaces](../reference/search-surfaces.md)
|
|
84
|
+
- [Recall and navigation](recall-and-navigation.md)
|
|
85
|
+
- [Export and maintenance](export-and-maintenance.md)
|
|
86
|
+
- [Tool reference](../reference/tools.md)
|
|
87
|
+
- [Troubleshooting](../support/troubleshooting.md)
|
package/docs/install.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Install
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Register `opencode-sessions-explorer` in OpenCode, optionally pin a version, and
|
|
6
|
+
grant the one permission it needs to read the OpenCode session database.
|
|
7
|
+
|
|
8
|
+
## Prerequisites
|
|
9
|
+
|
|
10
|
+
| Area | Requirement |
|
|
11
|
+
| --- | --- |
|
|
12
|
+
| OpenCode | A working OpenCode install with plugin host compatibility for `@opencode-ai/plugin >= 1.15.0` |
|
|
13
|
+
| Bun | `>= 1.0`; bundled with OpenCode, needed standalone only to run the CLIs directly. The plugin uses `bun:sqlite`, which should include SQLite `json1`; `check-deps` / `db-stats` verify it. |
|
|
14
|
+
| `ck` (optional) | `>= 0.7`, only for `search-text` and `grep-session` |
|
|
15
|
+
|
|
16
|
+
## Steps
|
|
17
|
+
|
|
18
|
+
1. Add the plugin to the `plugin` array in `~/.config/opencode/opencode.json`:
|
|
19
|
+
|
|
20
|
+
```jsonc
|
|
21
|
+
{
|
|
22
|
+
"$schema": "https://opencode.ai/config.json",
|
|
23
|
+
"plugin": ["opencode-sessions-explorer"]
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
OpenCode auto-installs npm plugins with Bun on startup and caches them under
|
|
28
|
+
`~/.cache/opencode/node_modules`, so there is no separate install command.
|
|
29
|
+
|
|
30
|
+
1. (Optional) Pin a version to avoid surprise upgrades by appending the version to
|
|
31
|
+
the package spec (for example, the current latest):
|
|
32
|
+
|
|
33
|
+
```jsonc
|
|
34
|
+
{
|
|
35
|
+
"plugin": ["opencode-sessions-explorer@0.1.1"]
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
1. Grant access to the OpenCode data directory. This is required because the
|
|
40
|
+
database lives outside your project workspace:
|
|
41
|
+
|
|
42
|
+
```jsonc
|
|
43
|
+
{
|
|
44
|
+
"permission": {
|
|
45
|
+
"external_directory": {
|
|
46
|
+
"~/.local/share/opencode/**": "allow"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
This default snippet covers the common macOS/Linux path. If `$XDG_DATA_HOME`,
|
|
53
|
+
Windows `%LOCALAPPDATA%`, or `OPENCODE_SESSIONS_EXPLORER_DB` points elsewhere,
|
|
54
|
+
allow the actual containing directory and restart OpenCode. Some current global
|
|
55
|
+
configs may use `external_directory: "allow"`; that works, but the scoped path
|
|
56
|
+
rule above is preferred for normal users.
|
|
57
|
+
|
|
58
|
+
1. Quit and restart OpenCode. All 18 tools auto-register on the next launch.
|
|
59
|
+
|
|
60
|
+
### From Source (Dev)
|
|
61
|
+
|
|
62
|
+
To run a local checkout instead of the published package, install dependencies in
|
|
63
|
+
the checkout first:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
bun install --frozen-lockfile
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Then choose one source-dev mode.
|
|
70
|
+
|
|
71
|
+
#### Option A: Source TypeScript For Iteration
|
|
72
|
+
|
|
73
|
+
Point the `plugin` array at the source entrypoint using an absolute path:
|
|
74
|
+
|
|
75
|
+
```jsonc
|
|
76
|
+
{
|
|
77
|
+
"plugin": ["/absolute/path/to/opencode-sessions-explorer/src/plugin.ts"]
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
This is the fastest iteration path because there is no `dist/` rebuild step, but a
|
|
82
|
+
full OpenCode restart is still required after config or code changes. Do not assume
|
|
83
|
+
hot reload.
|
|
84
|
+
|
|
85
|
+
#### Option B: Built JavaScript
|
|
86
|
+
|
|
87
|
+
Build the bundle, then point OpenCode at the built entrypoint:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
bun run build
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```jsonc
|
|
94
|
+
{
|
|
95
|
+
"plugin": ["/absolute/path/to/opencode-sessions-explorer/dist/plugin.js"]
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
When using `dist/`, rebuild and fully restart OpenCode after code changes. There is
|
|
100
|
+
no hot reload guarantee for local plugin paths.
|
|
101
|
+
|
|
102
|
+
For contributor commands, quality gates, and source-dev maintenance pointers, see
|
|
103
|
+
the [Development Guide](maintainers/development.md).
|
|
104
|
+
|
|
105
|
+
## Validate
|
|
106
|
+
|
|
107
|
+
Confirm the install resolved and the database is reachable:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
bunx opencode-sessions-explorer-check-deps
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
For source checkouts, run local checkout commands instead of `bunx` while iterating:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
bun src/bin/check-deps.ts
|
|
117
|
+
bun src/bin/bulk-export.ts
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
If you selected the built-JS option and have already run `bun run build`, you can
|
|
121
|
+
also validate the built CLI:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
bun dist/bin/check-deps.js
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
A `0` exit code is all green; `1` flags optional pieces (such as a missing export
|
|
128
|
+
tree or `ck`); `2` means a hard failure that must be fixed before the tools work.
|
|
129
|
+
|
|
130
|
+
## Next Steps
|
|
131
|
+
|
|
132
|
+
Continue with [getting-started.md](getting-started.md) to materialize the search
|
|
133
|
+
export and run a first query.
|
|
134
|
+
|
|
135
|
+
## Related Docs
|
|
136
|
+
|
|
137
|
+
- [Getting Started](getting-started.md)
|
|
138
|
+
- [Configuration reference](reference/configuration.md)
|
|
139
|
+
- [Development Guide](maintainers/development.md)
|
|
140
|
+
- [Troubleshooting](support/troubleshooting.md)
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Development Guide
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Define the local contributor workflow, quality gates, and project-specific
|
|
6
|
+
gotchas for `opencode-sessions-explorer`.
|
|
7
|
+
|
|
8
|
+
## Prerequisites
|
|
9
|
+
|
|
10
|
+
- [Bun](https://bun.sh) >= 1.0. OpenCode ships Bun; install it standalone only if
|
|
11
|
+
you run the bundled CLIs directly. The runtime is Bun, not Node — the plugin
|
|
12
|
+
uses `bun:sqlite`, which should include SQLite `json1`; `check-deps` / `db-stats`
|
|
13
|
+
verify it.
|
|
14
|
+
- An OpenCode plugin host compatible with `@opencode-ai/plugin >= 1.15.0`.
|
|
15
|
+
- [`ck`](https://github.com/BeaconBay/ck) >= 0.7 — required only when working on
|
|
16
|
+
`search-text` / `grep-session`; the other 16 tools work without it.
|
|
17
|
+
- A populated OpenCode SQLite DB at `~/.local/share/opencode/opencode.db` —
|
|
18
|
+
required only for live testing and the end-to-end verifier.
|
|
19
|
+
|
|
20
|
+
## Local Setup
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
bun install --frozen-lockfile
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Load the plugin into a running OpenCode while iterating by pointing the config at
|
|
27
|
+
your local checkout. Use the source TypeScript or built JavaScript options in
|
|
28
|
+
[Install: From Source (Dev)](../install.md#from-source-dev); that page is the
|
|
29
|
+
authoritative source-dev registration flow, including the full-restart requirement.
|
|
30
|
+
|
|
31
|
+
## Local Dev Loop
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bun run typecheck # tsc --noEmit (strict mode)
|
|
35
|
+
bun test # hermetic by default
|
|
36
|
+
bun run build # bundle to dist/
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
For changes that affect tool output, also run the end-to-end verifier, which
|
|
40
|
+
compares each tool against ground-truth SQL (this one needs a live DB):
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
bun tests/verify-end-to-end.ts
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Check install health any time:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
bun src/bin/check-deps.ts
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
For source-dev first-run validation, use the local checkout CLIs from
|
|
53
|
+
[Install](../install.md#validate) (`bun src/bin/check-deps.ts`,
|
|
54
|
+
`bun src/bin/bulk-export.ts`, or `bun dist/bin/check-deps.js` after a build) rather
|
|
55
|
+
than `bunx`, which exercises the published npm package.
|
|
56
|
+
|
|
57
|
+
## Architecture (pointer)
|
|
58
|
+
|
|
59
|
+
The plugin is a 4-layer pipeline:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
SQLite DB (read-only source of truth)
|
|
63
|
+
-> filesystem export tree (~/.local/share/opencode-sessions-explorer; by-session + by-channel)
|
|
64
|
+
-> ck index (.ck/; BM25 + embeddings; optional)
|
|
65
|
+
-> enriched response (re-fetches session/part metadata from SQLite per hit)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
See the [Architecture Reference](../reference/architecture.md) for the full layer
|
|
69
|
+
diagram and read-only / single-writer invariants, and the
|
|
70
|
+
[Export And Maintenance Guide](../guides/export-and-maintenance.md) for export/index
|
|
71
|
+
operations. `AGENTS.md` holds the authoritative per-tool contract.
|
|
72
|
+
|
|
73
|
+
## Environment Overrides
|
|
74
|
+
|
|
75
|
+
All paths are env-overridable, which is the easiest way to point tests or a dev
|
|
76
|
+
session at non-default locations:
|
|
77
|
+
|
|
78
|
+
| Env var | Purpose |
|
|
79
|
+
| --- | --- |
|
|
80
|
+
| `OPENCODE_SESSIONS_EXPLORER_DB` | Path to the OpenCode SQLite DB |
|
|
81
|
+
| `OPENCODE_SESSIONS_EXPLORER_EXPORT_ROOT` | Where searchable session content is materialized |
|
|
82
|
+
| `OPENCODE_SESSIONS_EXPLORER_TOOL_OUTPUT_DIR` | Whitelist root for `get-part` dereference |
|
|
83
|
+
| `OPENCODE_SESSIONS_EXPLORER_CK_BIN` | Override the `ck` binary location |
|
|
84
|
+
|
|
85
|
+
## Tests: Hermetic vs Live
|
|
86
|
+
|
|
87
|
+
- `bun test` is **hermetic by default** — it runs against a synthetic fixture DB
|
|
88
|
+
and does not need your real history. This is what CI runs.
|
|
89
|
+
- To exercise the suite against your real `~/.local/share/opencode/opencode.db`,
|
|
90
|
+
opt in:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
OPENCODE_SESSIONS_EXPLORER_LIVE=1 bun test
|
|
94
|
+
# or
|
|
95
|
+
bun run test:live
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Live runs read real `ses_/msg_/prt_` IDs and minimum counts from your OpenCode
|
|
99
|
+
database; failures there reflect your own data, not necessarily a regression.
|
|
100
|
+
|
|
101
|
+
## The `.js`-Import Gotcha (do not "fix" it)
|
|
102
|
+
|
|
103
|
+
Inside `src/`, sibling imports use a **`.js`** extension even though the files are
|
|
104
|
+
`.ts`:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
import { stmt } from "../lib/db.js"; // the file is db.ts — this is correct
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
This is required by `tsc` (`moduleResolution: bundler`) and `bun build`. Rewriting
|
|
111
|
+
these to `.ts` will break typecheck and the build. Files under `tests/` import
|
|
112
|
+
`src` with `.ts`; that is fine, because Bun runs them unbuilt.
|
|
113
|
+
|
|
114
|
+
## Adding or Editing a Tool
|
|
115
|
+
|
|
116
|
+
- One tool per file in `src/tools/`, exported as a **named const** (not default).
|
|
117
|
+
- Register it in `src/tools/index.ts` under the
|
|
118
|
+
`opencode-sessions-explorer-<name>` key and the re-export block.
|
|
119
|
+
- Wrap the body in `runWithEnvelope("<fn_name>", capKb, async (ctx) => { … })`.
|
|
120
|
+
- Raise recoverable errors via `fail(code, msg, hint)` using a code from
|
|
121
|
+
`src/lib/errors.ts`; do not invent ad-hoc error shapes.
|
|
122
|
+
- Wrap list-shaped results in `table(records, { dict: [...] })` (lossless
|
|
123
|
+
columnar + interning).
|
|
124
|
+
|
|
125
|
+
See `AGENTS.md` for the authoritative, fully detailed version of this contract.
|
|
126
|
+
|
|
127
|
+
## Change Checklist
|
|
128
|
+
|
|
129
|
+
- Run `bun run typecheck`, `bun test`, and `bun run build` locally.
|
|
130
|
+
- For tool-output changes, run `bun tests/verify-end-to-end.ts`.
|
|
131
|
+
- Update [`README.md`](../../README.md) for any user-facing change.
|
|
132
|
+
- Add a note under `## [Unreleased]` in [`CHANGELOG.md`](../../CHANGELOG.md).
|
|
133
|
+
- Keep commit scope focused.
|
|
134
|
+
|
|
135
|
+
## Related Docs
|
|
136
|
+
|
|
137
|
+
- [Docs Writing Standard](docs-writing.md)
|
|
138
|
+
- [Install Guide](../install.md)
|
|
139
|
+
- [Release Guide](release.md)
|
|
140
|
+
- [Triage Guide](triage.md)
|