opencode-sessions-explorer 0.1.3 → 0.1.4

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 CHANGED
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.1.4] - 2026-06-14
11
+
12
+ ### Fixed
13
+ - `search-text` now preserves requested `sem`/`hybrid` modes when the `ck` semantic
14
+ index is missing, allowing `ck` to perform its normal lazy auto-indexing instead
15
+ of falling back to regex.
16
+
10
17
  ## [0.1.3] - 2026-06-14
11
18
 
12
19
  ### Fixed
package/README.md CHANGED
@@ -71,7 +71,9 @@ bunx opencode-sessions-explorer-check-deps
71
71
  bunx opencode-sessions-explorer-bulk-export
72
72
  ```
73
73
 
74
- 1. (Optional) Build the `ck` index from the export root, not the repo root:
74
+ 1. (Optional) Prewarm the `ck` index from the export root, not the repo root.
75
+ Normal `lex`, `sem`, and `hybrid` searches ask `ck` to build or refresh indexes
76
+ lazily, so this step is only for avoiding first-search latency or troubleshooting:
75
77
 
76
78
  ```bash
77
79
  cd ~/.local/share/opencode-sessions-explorer
@@ -125,9 +127,10 @@ full first-run walkthrough, see [docs/install.md](docs/install.md) and
125
127
  ### Export and Maintenance
126
128
 
127
129
  - **One-time export.** `bulk-export` materializes searchable session content for `ck`.
128
- - **Stay current.** The plugin auto-syncs new parts before each search call; rebuild
129
- the optional semantic index explicitly (`ck --reindex .` / `ck --index .`) when
130
- `sem` or `hybrid` warnings report stale or partial coverage.
130
+ - **Stay current.** The plugin auto-syncs new parts before each search call, then
131
+ lets normal `lex`, `sem`, and `hybrid` `ck` searches lazily build or refresh their
132
+ indexes. Explicit `ck --index .` / `ck --reindex .` runs are optional prewarm or
133
+ troubleshooting steps for stale or partial coverage warnings.
131
134
  - **Health probe.** `check-deps` and the `db-stats` tool report dependency and schema
132
135
  health.
133
136
  - See [docs/guides/export-and-maintenance.md](docs/guides/export-and-maintenance.md).
@@ -1581,7 +1581,7 @@ try {
1581
1581
  if (idx.present)
1582
1582
  pass("ck index", idx.embedded_chunks != null ? `present (${idx.embedded_chunks} embedded chunks)` : "present");
1583
1583
  else
1584
- warn("ck index", "not built", "For semantic search: `cd " + root + " && ck --index .` (slow, one-time, ~5h for ~150k parts)");
1584
+ warn("ck index", "not built", "Semantic search will ask ck to lazily build the index; optionally prewarm with `cd " + root + " && ck --index .`.");
1585
1585
  }
1586
1586
  } else {
1587
1587
  warn("ck CLI", `${ckBin} returned ${r.status}: ${(r.stderr ?? "").slice(0, 120)}`, "Reinstall via `cargo install ck-search`.");
package/dist/plugin.js CHANGED
@@ -14991,13 +14991,13 @@ function statusFromProbe(explicit, embeddedChunks, indexUpdatedMs, exportMarkerM
14991
14991
  return "fresh";
14992
14992
  }
14993
14993
  function ckIndexWarning(status, root, probeFailure) {
14994
- const rebuild = `Run 'cd "${root}" && ck --reindex .' (or 'ck --index .') externally; opencode-sessions-explorer will not rebuild embeddings inline.`;
14994
+ const prewarm = `opencode-sessions-explorer will not call ck --index or ck --reindex inline; run 'cd "${root}" && ck --index .' or 'ck --reindex .' only to prewarm or troubleshoot.`;
14995
14995
  if (status === "missing")
14996
- return `ck semantic index is missing at ${root}/.ck. ${rebuild}`;
14996
+ return `ck semantic index is missing at ${root}/.ck. ck will lazily create or update the index during sem/hybrid search; the first run may be slow. ${prewarm}`;
14997
14997
  if (status === "stale")
14998
- return `ck semantic index appears stale relative to the export tree; sem/hybrid results may omit recently exported files. ${rebuild}`;
14998
+ return `ck semantic index appears stale relative to the export tree; ck will attempt a lazy refresh during sem/hybrid search. Results may be partial if refresh fails or times out. ${prewarm}`;
14999
14999
  const reason = probeFailure ? ` (${probeFailure})` : "";
15000
- return `ck semantic index freshness is partial/unverified${reason}; sem/hybrid results may cover only indexed files. ${rebuild}`;
15000
+ return `ck semantic index freshness is partial/unverified${reason}; ck will attempt lazy index refresh during sem/hybrid search. Results may cover only indexed files if refresh fails or times out. ${prewarm}`;
15001
15001
  }
15002
15002
  function exportMarkerMtime(root) {
15003
15003
  const markers = [".last_sync", ".channels_v1_complete"];
@@ -15661,7 +15661,7 @@ var searchSessionsMeta = tool({
15661
15661
  import { existsSync as existsSync9 } from "fs";
15662
15662
  import { join as join9 } from "path";
15663
15663
  var searchText = tool({
15664
- description: "opencode-sessions-explorer: full-text search across the BODIES of all your prior OpenCode sessions (the actual conversation content \u2014 user prompts, assistant responses, tool inputs/outputs, reasoning, file references, patches, subtask prompts). " + 'Answers any of: "where in my OpenCode history did I mention X", "find sessions about Y", "have I ever discussed Z", "look up earlier conversations about W", "all references to V across my OpenCode sessions", "did this topic come up before", "when did I last talk about Q", "find the session where I worked on R", "search my prior chat content for S", "grep across all OpenCode sessions for T", "have I asked about this before". ' + "Default surface is `recall`: session-first, channel-aware, and evidence-limited. It searches high-signal conversation/session-summary views first and returns ranked sessions with raw part refs. " + "Use `surface:'forensics'` (or explicit channels including `raw`) for exhaustive raw replay over tool output, reasoning, patches, and all exported bodies. " + "ARG `group_by_session`: when true, rolls hits up to one row per session with hit_count, first/last seen timestamps, evidence snippets, and channel counts. If omitted, unscoped recall defaults to true; scoped one-session searches default to flat hits. " + `CRITICAL ARG \`role\` (default 'any'): which message roles to search inside. **Default to 'any'** for natural-language questions like "where did I mention X", "find sessions about Y", "did I discuss Z" \u2014 these are asking about appearances ANYWHERE in your conversations (user prompts AND assistant text AND tool I/O AND reasoning). ` + `Only set role='user' when the user EXPLICITLY narrows to authored messages: "what prompts have I typed containing X", "my user-authored messages mentioning Y", "questions I sent OpenCode with Z". Phrases like "did I mention" / "in my history" / "have I discussed" do NOT imply role='user' \u2014 those are asking about the corpus as a whole. ` + `Only set role='assistant' for questions explicitly about what the AI said ("what has the assistant said about X"). ` + "Modes: 'regex' (default \u2014 drop-in grep, no index needed), 'lex' (BM25 phrase search, auto-builds Tantivy index), 'sem' (semantic embeddings, requires `ck --index .` to be run once outside this tool), 'hybrid' (regex + sem). " + "Pre-filter cross-session searches via session_ids[], project_id, agent, since_ms/until_ms \u2014 unscoped full-corpus search can take 10-30 seconds. Scoped searches return in <1s. " + "For grep INSIDE a single known session use grep-session instead (faster, narrower).",
15664
+ description: "opencode-sessions-explorer: full-text search across the BODIES of all your prior OpenCode sessions (the actual conversation content \u2014 user prompts, assistant responses, tool inputs/outputs, reasoning, file references, patches, subtask prompts). " + 'Answers any of: "where in my OpenCode history did I mention X", "find sessions about Y", "have I ever discussed Z", "look up earlier conversations about W", "all references to V across my OpenCode sessions", "did this topic come up before", "when did I last talk about Q", "find the session where I worked on R", "search my prior chat content for S", "grep across all OpenCode sessions for T", "have I asked about this before". ' + "Default surface is `recall`: session-first, channel-aware, and evidence-limited. It searches high-signal conversation/session-summary views first and returns ranked sessions with raw part refs. " + "Use `surface:'forensics'` (or explicit channels including `raw`) for exhaustive raw replay over tool output, reasoning, patches, and all exported bodies. " + "ARG `group_by_session`: when true, rolls hits up to one row per session with hit_count, first/last seen timestamps, evidence snippets, and channel counts. If omitted, unscoped recall defaults to true; scoped one-session searches default to flat hits. " + `CRITICAL ARG \`role\` (default 'any'): which message roles to search inside. **Default to 'any'** for natural-language questions like "where did I mention X", "find sessions about Y", "did I discuss Z" \u2014 these are asking about appearances ANYWHERE in your conversations (user prompts AND assistant text AND tool I/O AND reasoning). ` + `Only set role='user' when the user EXPLICITLY narrows to authored messages: "what prompts have I typed containing X", "my user-authored messages mentioning Y", "questions I sent OpenCode with Z". Phrases like "did I mention" / "in my history" / "have I discussed" do NOT imply role='user' \u2014 those are asking about the corpus as a whole. ` + `Only set role='assistant' for questions explicitly about what the AI said ("what has the assistant said about X"). ` + "Modes: 'regex' (default \u2014 drop-in grep, no index needed), 'lex' (BM25 phrase search, lets ck auto-build/update its Tantivy index), 'sem' (semantic embeddings, lets ck lazily build/refresh its index), 'hybrid' (regex + sem). " + "Pre-filter cross-session searches via session_ids[], project_id, agent, since_ms/until_ms \u2014 unscoped full-corpus search can take 10-30 seconds. Scoped searches return in <1s. " + "For grep INSIDE a single known session use grep-session instead (faster, narrower).",
15665
15665
  args: {
15666
15666
  q: tool.schema.string().describe("Search query (regex pattern, BM25 phrase, or natural-language depending on mode)"),
15667
15667
  mode: tool.schema.enum(["regex", "lex", "sem", "hybrid"]).default("regex"),
@@ -15709,24 +15709,18 @@ var searchText = tool({
15709
15709
  return groupBySession ? { sessions: table([]), hits_total: 0, mode: args.mode, surface, channels, scope_session_count: scopeIds.length, ck_duration_ms: 0, suppressed: emptySuppressed(channels) } : { hits: table([]), mode: args.mode, scope_session_count: scopeIds.length, ck_duration_ms: 0 };
15710
15710
  }
15711
15711
  let effectiveMode = args.mode;
15712
+ let preSearchFreshness = null;
15712
15713
  if (args.mode === "sem" || args.mode === "hybrid") {
15713
- const freshness = await ckIndexFreshness(root);
15714
- ctx.indexStatus = combineExportAndCkStatus(exportStatus, freshness.status);
15715
- if (freshness.warning)
15716
- ctx.warnings.push(freshness.warning);
15717
- if (freshness.status === "missing") {
15718
- ctx.warnings.push("ck semantic index missing; falling back to regex for this request.");
15719
- effectiveMode = "regex";
15720
- ctx.mode = "fallback-regex";
15721
- } else if (freshness.status !== "fresh") {
15722
- const chunks = freshness.embedded_chunks != null ? ` (${freshness.embedded_chunks} embedded chunks)` : "";
15723
- ctx.warnings.push(`ck semantic index status is ${freshness.status}${chunks}; sem/hybrid results are partial until an explicit ck rebuild is run.`);
15724
- }
15714
+ preSearchFreshness = await ckIndexFreshness(root);
15715
+ ctx.indexStatus = combineExportAndCkStatus(exportStatus, preSearchFreshness.status);
15725
15716
  }
15726
15717
  if (!ctx.mode)
15727
15718
  ctx.mode = effectiveMode;
15728
15719
  const ckTopk = groupBySession ? Math.min(Math.max(args.limit * 20, 100), 500) : Math.min(args.limit * (effectiveMode === "regex" ? 2 : 3), 150);
15729
- return await runWithCk(args, scopes, effectiveMode, ctx, scopeIds === "all" ? null : scopeIds.length, ckTopk, channels, surface, groupBySession);
15720
+ const result = await runWithCk(args, scopes, effectiveMode, ctx, scopeIds === "all" ? null : scopeIds.length, ckTopk, channels, surface, groupBySession);
15721
+ if (preSearchFreshness)
15722
+ await refreshCkStatusAfterSearch(ctx, root, exportStatus, preSearchFreshness);
15723
+ return result;
15730
15724
  });
15731
15725
  }
15732
15726
  });
@@ -15982,6 +15976,18 @@ function combineExportAndCkStatus(exportStatus, ckStatus) {
15982
15976
  return "stale";
15983
15977
  return ckStatus;
15984
15978
  }
15979
+ async function refreshCkStatusAfterSearch(ctx, root, exportStatus, preSearchFreshness) {
15980
+ try {
15981
+ const postSearchFreshness = await ckIndexFreshness(root);
15982
+ ctx.indexStatus = combineExportAndCkStatus(exportStatus, postSearchFreshness.status);
15983
+ if (postSearchFreshness.status !== "fresh") {
15984
+ ctx.warnings.push(postSearchFreshness.warning ?? preSearchFreshness.warning ?? "ck semantic index freshness is not verified after search; results may be partial.");
15985
+ }
15986
+ } catch (e) {
15987
+ ctx.indexStatus = combineExportAndCkStatus(exportStatus, preSearchFreshness.status);
15988
+ ctx.warnings.push(preSearchFreshness.warning ?? `ck semantic index freshness recheck failed after search: ${e.message}`);
15989
+ }
15990
+ }
15985
15991
  function warnOnPartialScopeCoverage2(ctx, coverage, timeoutMs) {
15986
15992
  if (!coverage.truncated)
15987
15993
  return;
@@ -54,13 +54,14 @@ history, then branch into the right workflow guide.
54
54
  bunx opencode-sessions-explorer-bulk-export
55
55
  ```
56
56
 
57
- 1. (Optional) Build the semantic index to enable `mode:'sem'` and `mode:'hybrid'`
58
- search. This is a slow, one-time pass. Run it in the export root, not in the
59
- repository checkout:
57
+ 1. (Optional) Prewarm the `ck` index. Normal `mode:'lex'`, `mode:'sem'`, and
58
+ `mode:'hybrid'` searches let `ck` lazily build or refresh indexes during the
59
+ search; prewarming only avoids first-search latency or helps troubleshooting.
60
+ Run it in the export root, not in the repository checkout:
60
61
 
61
62
  ```bash
62
63
  cd ~/.local/share/opencode-sessions-explorer
63
- ck --index . # run in the export root, not the repo root
64
+ ck --index . # optional prewarm in the export root
64
65
  ```
65
66
 
66
67
  1. Run the install health probe again and confirm there are no hard failures:
@@ -54,15 +54,16 @@ maintenance.
54
54
  bunx opencode-sessions-explorer-bulk-export --reset
55
55
  ```
56
56
 
57
- 1. (Optional) Build the semantic index to unlock `sem` and `hybrid` search modes.
58
- This is slow and runs outside the plugin. Run it from the export root, not from
59
- the repository checkout; use `ck --reindex .` when search warnings report a stale
60
- or partially verified index:
57
+ 1. (Optional) Prewarm the `ck` index. Normal `lex`, `sem`, and `hybrid` searches
58
+ invoke `ck` in the requested mode so `ck` can lazily build or refresh indexes
59
+ during the search. Run these commands only to avoid first-search latency or to
60
+ troubleshoot stale/partial coverage warnings, and run them from the export root,
61
+ not from the repository checkout:
61
62
 
62
63
  ```bash
63
64
  cd ~/.local/share/opencode-sessions-explorer
64
- ck --index . # run in the export root, not the repo root
65
- ck --reindex . # explicit rebuild when stale/partial warnings appear
65
+ ck --index . # optional prewarm in the export root
66
+ ck --reindex . # optional troubleshooting refresh
66
67
  ```
67
68
 
68
69
  1. Verify everything is wired up, and re-run after any OpenCode upgrade:
@@ -25,11 +25,12 @@ known session, and audit individual tool invocations by name, status, or substri
25
25
 
26
26
  `search-text` and `grep-session` shell out to the optional [`ck`](https://github.com/BeaconBay/ck)
27
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
- require an embedding index built outside the tool (`ck --index .` or
30
- `ck --reindex .` from the export root). Missing indexes fall back to `regex`; stale
31
- or partially verified indexes keep using `sem`/`hybrid` but warn that results may be
32
- incomplete. The tools never rebuild embeddings inline. See
28
+ `CK_NOT_FOUND` cleanly; the other 16 tools keep working without it. Normal `lex`,
29
+ `sem`, and `hybrid` searches invoke `ck` in that mode so `ck` can lazily build or
30
+ refresh its own indexes during the search. Explicit `ck --index .` or
31
+ `ck --reindex .` runs from the export root are optional prewarm/troubleshooting
32
+ steps, not required before first use. If an index is missing, stale, or partially
33
+ verified, the tools warn that the first/lazy-refresh run may be slow or partial. See
33
34
  [search surfaces](../reference/search-surfaces.md) for the surface/channel model.
34
35
 
35
36
  ## Controls
@@ -61,6 +61,9 @@ CLI, which walks the export tree. `ck` supports plain regex with no index, a BM2
61
61
  full-text index, and semantic embeddings; the index lives under `.ck/` in the export
62
62
  root and is incremental. `ck` is optional: when it is absent these two tools return
63
63
  `CK_NOT_FOUND` cleanly and the other 16 tools are unaffected.
64
+ The plugin invokes normal `lex`, `sem`, and `hybrid` `ck` searches and lets `ck`
65
+ perform its lazy index build/refresh; explicit index commands are optional prewarm
66
+ or troubleshooting steps, not a prerequisite for first use.
64
67
 
65
68
  ### L4 — Enriched Response
66
69
 
@@ -89,12 +92,12 @@ flag, so the direct database write is the only mechanism.
89
92
 
90
93
  ## Examples
91
94
 
92
- Materialize the export tree (L2), then build the optional `ck` index (L3):
95
+ Materialize the export tree (L2), then optionally prewarm the `ck` index (L3):
93
96
 
94
97
  ```bash
95
98
  bunx opencode-sessions-explorer-bulk-export
96
99
  cd ~/.local/share/opencode-sessions-explorer
97
- ck --index . # run in the export root, not the repository checkout
100
+ ck --index . # optional prewarm from the export root
98
101
  ```
99
102
 
100
103
  Verify all four layers are healthy:
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "opencode-sessions-explorer",
4
- "version": "0.1.3",
4
+ "version": "0.1.4",
5
5
  "description": "OpenCode plugin for recall and analysis of past OpenCode sessions: search, grep, and cost/usage insights across your session history via 18 LLM tools (17 read-only plus one write, unarchive-session).",
6
6
  "keywords": [
7
7
  "opencode",