opencode-sesh 2.0.0 → 2.0.1

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/AGENTS.md CHANGED
@@ -11,10 +11,10 @@ territory: read this first, then the specific file you need.
11
11
  any terminal. Lists **all** sessions across **all** project directories,
12
12
  full-text searchable, with transcript preview and resume/fork/delete.
13
13
  2. **`tui-plugins/sesh-panel/tui.tsx`** — a SolidJS/OpenTUI plugin for the opencode TUI: a
14
- recent-sessions section in the sidebar plus an `alt+o` / `/sesh` picker.
14
+ sessions section in the sidebar plus an `option+o` / `/sesh` picker.
15
15
  3. **`plugins/sesh-list.ts`** — the `sesh_list` custom tool, so the agent
16
- can list sessions across every directory by querying the global `opencode
17
- db` store (the native `opencode session list` is project-scoped).
16
+ can list sessions across every directory by querying the global opencode
17
+ SQLite store (the native `opencode session list` is project-scoped).
18
18
 
19
19
  No iTerm2, no AppleScript, no panes, no window management — **never add any.**
20
20
  The one exception is the TUI's right-click action, which shells out to
@@ -57,7 +57,7 @@ The tool name in opencode is `sesh_list`. Do not rename it without updating the
57
57
  ## Data flow (fzf picker)
58
58
 
59
59
  `bin/sesh-list.sh` owns the fzf picker's session store access (opencode SQLite
60
- DB: `session_v2` / `session_message` tables); the `sesh-list` agent tool queries
60
+ DB: `session_v2` / `session_message` tables); the `sesh_list` agent tool queries
61
61
  the same store read-only through `bun:sqlite`. V2 discovers the tool from the
62
62
  global config directory's `plugins/`. Keep its SQL column names in sync with
63
63
  the schema below. Keystrokes never touch the database:
@@ -75,7 +75,8 @@ the schema below. Keystrokes never touch the database:
75
75
  the whole DB and pruning is always safe.
76
76
  - render (cheap, pure `jq`): reads the snapshot only. Filters on `searchText`
77
77
  (title + `fulltextLower`, both lowercased at extraction), groups by `cwd`,
78
- sorts groups/items by recency, renders the TSV. Notice rows (headers, a
78
+ sorts groups/items by pins and recency, with current-project and title-match
79
+ priority while searching, and renders the TSV. Notice rows (headers, a
79
80
  vanished selection, an empty store, a query matching nothing) carry an empty
80
81
  `sessionId` and a unique `trackingId`. `--header` prints the one-line
81
82
  scope/count/status that the picker uses as fzf's header, and a non-actionable
@@ -89,7 +90,9 @@ the schema below. Keystrokes never touch the database:
89
90
  The sidebar and home lists use Option-S / Option-R instead: opencode binds
90
91
  `ctrl+d` itself (composer delete-char, session delete), so ctrl pins would
91
92
  shadow the composer. Pinned directories sort before groups
92
- containing pinned sessions, with pinned sessions first inside each group.
93
+ containing pinned sessions. The terminal picker puts pinned sessions first
94
+ inside each group; the TUI picker and sidebar keep sessions recency-ordered
95
+ within each directory. The home list puts pinned sessions first.
93
96
 
94
97
  **Output contract** (TSV, 6 fields):
95
98
  `agentId sessionId liveState display cwd trackingId`. `display` is the only
@@ -105,7 +108,8 @@ live-agent API, so `liveState` is always `unknown` and rows render gray unless
105
108
  they are archived (opt-in, tagged `· archived`);
106
109
  dispatch is always `opencode --session <id>`; Ctrl-F or `--fork` first creates the
107
110
  fork with `opencode api session.fork` (the CLI has no fork flag) and resumes the new id.
108
- Resume happens in place (`exec` after `cd` to the session's cwd).
111
+ Resume runs opencode in a subshell at the session's cwd in the same terminal;
112
+ when opencode exits, the picker reopens with the query preserved.
109
113
 
110
114
  ## Conventions
111
115
 
package/CHANGELOG.md CHANGED
@@ -5,6 +5,12 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.0.1] - 2026-10-10
9
+
10
+ ### Fixed
11
+
12
+ - **packaging:** Add root export for opencode plugin and broaden opentui peer range
13
+
8
14
  ## [2.0.0] - 2026-10-10
9
15
 
10
16
  ### Breaking changes
@@ -482,6 +488,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
482
488
  - Fixture-database regression suite, TypeScript typechecking, and ShellCheck in
483
489
  CI.
484
490
 
491
+ [2.0.1]: https://github.com/ozandogrultan/opencode-sesh/compare/v2.0.0...v2.0.1
485
492
  [2.0.0]: https://github.com/ozandogrultan/opencode-sesh/compare/v1.1.0...v2.0.0
486
493
  [1.1.0]: https://github.com/ozandogrultan/opencode-sesh/compare/v1.0.8...v1.1.0
487
494
  [1.0.8]: https://github.com/ozandogrultan/opencode-sesh/compare/v1.0.7...v1.0.8
package/README.md CHANGED
@@ -12,7 +12,6 @@ The TUI plugin and agent tool require OpenCode V2 and are not compatible with V1
12
12
  `/sessions`) are scoped to the current project. `sesh` shows all of them —
13
13
  grouped by directory, full-text searchable, and previewable from anywhere.
14
14
 
15
- [![CI](https://github.com/ozandogrultan/opencode-sesh/actions/workflows/ci.yml/badge.svg)](https://github.com/ozandogrultan/opencode-sesh/actions/workflows/ci.yml)
16
15
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
17
16
  [![PRs welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](#contributing)
18
17
  [![GitHub stars](https://img.shields.io/github/stars/ozandogrultan/opencode-sesh?style=social)](https://github.com/ozandogrultan/opencode-sesh/stargazers)
@@ -35,26 +34,49 @@ search…
35
34
  ## Why sesh
36
35
 
37
36
  - **Every session, everywhere.** Sessions are grouped by project directory and
38
- sorted by pins, then recency — across *all* your projects, not just the current one.
37
+ shown across *all* your projects, not just the current one. Archived and
38
+ subagent child sessions are hidden by default.
39
39
  - **Pin what matters.** Ctrl-S pins a session and Ctrl-D pins its directory in
40
- either picker. Pins are shared across the terminal and opencode TUI and
41
- persist across restarts; pinned directories and sessions sort first.
40
+ either picker; the TUI sidebar and home list use Option-S and Option-R.
41
+ Pins are shared and persist across restarts. Pinned directories rise first;
42
+ pinned sessions sort first in the terminal picker and home list. The TUI picker
43
+ and sidebar keep sessions within each directory recency-ordered.
42
44
  - **Full-text search.** Type to match against session titles *and* the text of
43
45
  the conversation itself. Reasoning and tool output are excluded, so the index
44
46
  stays clean.
45
- - **Transcript preview.** Space shows the most recent messages first, rendered as
46
- Markdown (with `glow` if you have it).
47
- - **Resume in place.** Enter `exec`s `opencode --session <id>` in the session's
48
- own directory. Ctrl-F forks instead. Your terminal becomes the session — no
49
- tabs, no panes, no window management.
50
- - **Native TUI, too.** A recent-sessions section in the opencode sidebar plus an
47
+ - **Transcript preview.** Ctrl-P in the terminal picker or Option-P in the TUI
48
+ shows the most recent messages first, rendered as Markdown (with `glow` in
49
+ the terminal if you have it).
50
+ - **Resume in place.** Enter runs `opencode --session <id>` in the session's
51
+ own directory. Ctrl-F forks instead. The session opens in the same terminal,
52
+ and exiting opencode returns to the picker — no tabs, panes, or window management.
53
+ - **Native TUI, too.** A sessions section in the opencode sidebar plus an
51
54
  `option+o` picker, both themed by your opencode theme.
52
55
  - **Fast.** The database is scanned once per refresh and cached; keystrokes only
53
56
  re-render the last snapshot, so typing never triggers a query storm.
54
57
 
55
58
  ## Install
56
59
 
57
- With npm:
60
+ ### OpenCode plugin
61
+
62
+ Add the package to `plugins` in your OpenCode V2 `opencode.json` or
63
+ `opencode.jsonc`:
64
+
65
+ ```json
66
+ {
67
+ "$schema": "https://opencode.ai/config.json",
68
+ "plugins": ["opencode-sesh"]
69
+ }
70
+ ```
71
+
72
+ OpenCode installs the package and loads its server tool and TUI panel. Merge
73
+ this entry with your existing plugins. Remove the copied
74
+ `./tui-plugins/sesh-panel` registration and `plugins/sesh-list.ts` tool before
75
+ switching to avoid loading them twice.
76
+
77
+ ### Terminal picker
78
+
79
+ Install the CLI with npm:
58
80
 
59
81
  ```bash
60
82
  npm install -g opencode-sesh
@@ -71,7 +93,7 @@ bash install.sh
71
93
 
72
94
  `sesh install` (or `bash install.sh`) links `sesh` into `$XDG_BIN_HOME`
73
95
  (default `~/.local/bin`), copies
74
- the `sesh-list` tool and the TUI panel into
96
+ the `sesh_list` tool and the TUI panel into
75
97
  `${XDG_CONFIG_HOME:-~/.config}/opencode`, registers the panel in `opencode.json`, and
76
98
  declares the plugin dependencies (opencode installs them on next start). The
77
99
  panel registers the `/sesh` slash command. It never edits your shell rc, and any
@@ -139,7 +161,7 @@ Flags: `--cwd` (current directory only), `--limit N` (default: all),
139
161
 
140
162
  `sesh prune [--older-than 30d] [--dry-run] [--yes]` deletes stale
141
163
  sessions (not updated within the threshold) through `opencode session delete`, including their children.
142
- Pinned sessions, sessions waiting on you, subagent child sessions and already-archived
164
+ Pinned sessions and directories, sessions waiting on you, subagent child sessions and already-archived
143
165
  sessions are never selected. Without `--dry-run`, a TTY run
144
166
  confirms first and a non-TTY run needs `--yes`.
145
167
 
@@ -155,8 +177,8 @@ When searching, title matches outrank transcript-only matches and the current
155
177
  project rises, so the list answers "where was that thing I worked on" before it
156
178
  answers "what is newest". Pins still win outright.
157
179
 
158
- Because `--print` just emits the id and directory, `sesh` doubles as a scriptable
159
- session lookup:
180
+ `--print` still opens the interactive picker, but emits the selected id and
181
+ directory instead of resuming. `--query` supplies the initial search text:
160
182
 
161
183
  ```bash
162
184
  read -r id cwd < <(sesh --print --query "auth")
@@ -166,7 +188,7 @@ sesh --print --json --query "auth" | jq -r .cwd
166
188
  Deleting is irreversible, so the picker asks before dispatching it, and a
167
189
  non-interactive `sesh-delete.sh` refuses unless given `--yes`.
168
190
 
169
- ### TUI panel
191
+ ### TUI picker
170
192
 
171
193
  | Key | Action |
172
194
  | --- | --- |
@@ -178,13 +200,16 @@ non-interactive `sesh-delete.sh` refuses unless given `--yes`.
178
200
  | `↑`/`↓`, `PgUp`/`PgDn`, `Home`/`End` | Move the selection |
179
201
  | Option-P | Toggle the transcript preview |
180
202
  | Enter | Open the selected session |
181
- | Option-D | Delete the selected session (asks to confirm) |
203
+ | Option-D | Arm deletion; press Option-D again, `y`, or Enter to confirm |
182
204
  | Ctrl-F | Fork the selected session |
183
205
  | Ctrl-G | Toggle scope: the selected session's project, or every project |
184
206
  | Option-W / Option-S | Show only sessions needing input / pinned sessions |
185
207
  | Ctrl-S / Ctrl-D | Pin or unpin the selected session / directory |
186
208
  | Esc | Close the preview first, then the picker |
187
209
 
210
+ While deletion is armed, `n` or Esc cancels; it also cancels after five seconds.
211
+ Option-O opens the picker globally; the other keys above apply inside it.
212
+
188
213
  The picker groups sessions under collapsible directory headings (click ▾/▸).
189
214
  Mouse-wheel scrolling moves through the tree without changing the selection
190
215
  under a stationary pointer. Option-P opens a full-size transcript preview over
@@ -196,10 +221,14 @@ action, or Esc to dismiss the menu.
196
221
  Right-click a session in the home list or picker to open it in a new cmux
197
222
  workspace at its directory; outside cmux it shows a toast instead.
198
223
 
199
- Click the sidebar's `search…` box to filter recent sessions in place; click
224
+ ### TUI sidebar and home list
225
+
226
+ Click the sidebar's `search…` box to filter sessions in place; click
200
227
  elsewhere or press Esc to leave search. Click the **Sessions** heading to drive
201
228
  the list from the keyboard instead of the mouse (`↑`/`↓` to move, Enter to open,
202
- Option-P to preview, Option-S/Option-R to pin, Option-D to delete, Esc to leave). Pinned
229
+ Option-P to preview, Option-S to pin a session, Option-R to pin its directory,
230
+ Option-D to arm deletion, Esc to leave). Press Option-D again or `y` to confirm
231
+ an armed deletion; `n` or Esc cancels. Pinned
203
232
  directories rise first, while sessions within each directory are ordered by
204
233
  last update, newest first. The section lists every session and scrolls to fill
205
234
  the sidebar, so click **▾ hide** to collapse it when you need the room.
@@ -212,6 +241,12 @@ Hovering a row while keyboard navigation is active selects it for the next
212
241
  shortcut. Clicking (or Enter on) a session opens it here. The full picker is one
213
242
  keystroke away.
214
243
 
244
+ The home list also supports search and the Option-P, Option-S, Option-R, and
245
+ Option-D actions on the hovered session. These Option pin shortcuts do not
246
+ replace the picker's Ctrl-S/Ctrl-D bindings; Option-S in the picker filters pins.
247
+
248
+ ### Transcript search and needs-input triage
249
+
215
250
  The full picker pages through your whole global session list (no fixed window)
216
251
  and indexes transcript text for every session in the background, showing
217
252
  indexing progress under the search box. It only stops at a safety cap of 5,000
@@ -233,7 +268,7 @@ All variables are optional.
233
268
  | `SESH_JQ` / `SESH_FZF` | `PATH` | explicit executable overrides |
234
269
  | `SESH_GLOW` | first `glow` on `PATH` | optional Markdown preview renderer |
235
270
  | `SESH_OPENCODE` | `opencode` | opencode executable (resume / delete) |
236
- | `SESH_CACHE_DIR` | `~/.cache/sesh` | persistent search-index cache |
271
+ | `SESH_CACHE_DIR` | `${XDG_CACHE_HOME:-~/.cache}/sesh` | persistent search-index cache |
237
272
  | `SESH_PINS_FILE` | `${XDG_DATA_HOME:-~/.local/share}/sesh/pins.json` | shared persistent session/directory pins |
238
273
 
239
274
  ## Integrations
@@ -259,7 +294,7 @@ Flat scripts back the terminal UI — the picker (`sesh.sh`), the refresh engine
259
294
  scans), preview renderer (`sesh-preview.sh`), deleter (`sesh-delete.sh`) and
260
295
  shortcut help (`sesh-shortcuts.sh`). The TUI panel (`tui-plugins/sesh-panel/tui.tsx`) is a
261
296
  SolidJS OpenTUI plugin that talks to the opencode SDK over the same store; the
262
- `sesh-list` agent tool reads it read-only through `bun:sqlite`. V2 discovers
297
+ `sesh_list` agent tool reads it read-only through `bun:sqlite`. V2 discovers
263
298
  the installed tool automatically in the global config directory's `plugins/`.
264
299
 
265
300
  ## FAQ
@@ -267,12 +302,13 @@ the installed tool automatically in the global config directory's `plugins/`.
267
302
  **Does it replace opencode's native session list?** No. `<leader>l` and the
268
303
  native `/sessions` command are untouched; `sesh` is additive.
269
304
 
270
- **Is there an agent-facing list?** Yes — the `sesh-list` tool lets the model list
305
+ **Is there an agent-facing list?** Yes — the `sesh_list` tool lets the model list
271
306
  every session across all directories (the native `opencode session list` only
272
307
  covers the current project) and offer to resume one.
273
308
 
274
309
  **Where is my data?** It reads the opencode database read-only and caches
275
- extracted text under `~/.cache/sesh`. Nothing is uploaded anywhere.
310
+ extracted text under `${XDG_CACHE_HOME:-~/.cache}/sesh` (or `SESH_CACHE_DIR`).
311
+ Nothing is uploaded anywhere.
276
312
 
277
313
  **Does it work on Windows?** It targets macOS and Linux. WSL should work; native
278
314
  Windows is untested.
@@ -15,6 +15,11 @@ sesh shortcuts
15
15
  Escape Exit the picker
16
16
 
17
17
  Flags: --cwd (current directory only), --limit N (default: all),
18
- --archived (include archived), --print (print id instead of resuming),
19
- --json (with --print, emit JSON)
18
+ --archived (include archived and child sessions),
19
+ --print (print selected id<TAB>cwd instead of resuming),
20
+ --json (with --print, emit JSON), --fork (resume as a fork),
21
+ --query TEXT (initial search), --check (check dependencies),
22
+ --needs-input [--json] (list sessions waiting on you)
23
+
24
+ --print still opens the picker; select a session with Enter or Ctrl-F.
20
25
  HELP
@@ -20,7 +20,8 @@ Paste only the actions you want; the `ui.newWorkspace` block is optional.
20
20
 
21
21
  ## Resume a session in its own cmux workspace
22
22
 
23
- The picker resumes in place (it `cd`s and `exec`s opencode). To instead open a
23
+ The picker runs opencode in the selected session's directory and returns to the
24
+ picker when opencode exits. To instead open a
24
25
  session in a **new cmux workspace** at its directory, shell out to cmux after
25
26
  resolving the session with sesh's scriptable lookup:
26
27
 
@@ -57,9 +58,10 @@ sesh is a normal CLI, so any system-wide launcher works — a cmux `shortcut`, a
57
58
  cmd + shift - s : cmux new-workspace --command "sesh"
58
59
  ```
59
60
 
60
- Because `--print --json` resolves a session non-interactively, the same hook can
61
- resume a specific session without any UI:
61
+ `--print --json` still opens the interactive picker; `--query` initializes its
62
+ search and `--limit` caps the list rather than automatically accepting a result.
63
+ To resume a known session without the picker, use its id and directory directly:
62
64
 
63
65
  ```bash
64
- cmd + alt - r : cmux new-workspace --command "opencode --session $(sesh --print --json --limit 1 | jq -r .sessionId)"
66
+ cmd + alt - r : cmux new-workspace --cwd /path/to/project --command "opencode --session ses_EXAMPLE"
65
67
  ```
package/install.sh CHANGED
@@ -42,7 +42,7 @@ usage() {
42
42
  Usage: bash install.sh [--bin-dir DIR] [--no-tool] [--no-tui] [--uninstall]
43
43
 
44
44
  --bin-dir DIR Directory for the sesh launcher (default: ~/.local/bin).
45
- --no-tool Skip installing the sesh-list custom tool.
45
+ --no-tool Skip installing the sesh_list custom tool.
46
46
  --no-tui Skip installing the in-TUI sessions panel plugin.
47
47
  --uninstall Remove everything this script installed.
48
48
  --sync-panel Refresh an already-installed TUI panel only (used by postinstall).
@@ -314,7 +314,7 @@ fi
314
314
  "$LAUNCHER" --check || fail "post-install check failed."
315
315
  note "done"
316
316
  note " picker: run 'sesh' in any terminal, or '/sesh' inside opencode"
317
- note " sidebar: alt+o opens the full picker"
317
+ note " TUI: Option-O opens the full picker"
318
318
  note_restart
319
319
  case ":$PATH:" in
320
320
  *":$BIN_DIR:"*) ;;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-sesh",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Browse, search, preview and resume opencode sessions from the terminal and the TUI.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -22,6 +22,7 @@
22
22
  "cli"
23
23
  ],
24
24
  "exports": {
25
+ ".": "./plugins/sesh-list.ts",
25
26
  "./tui": "./tui-plugins/sesh-panel/tui.tsx",
26
27
  "./tool": "./plugins/sesh-list.ts"
27
28
  },
@@ -61,8 +62,8 @@
61
62
  },
62
63
  "peerDependencies": {
63
64
  "@opencode/plugin": ">=2.0.0",
64
- "@opentui/core": "^0.5.8",
65
- "@opentui/solid": "^0.5.8",
65
+ "@opentui/core": ">=0.5.8",
66
+ "@opentui/solid": ">=0.5.8",
66
67
  "solid-js": ">=1.9.0"
67
68
  },
68
69
  "devDependencies": {
@@ -74,7 +75,7 @@
74
75
  "@opentui/core": "^0.5.11",
75
76
  "@opentui/keymap": "^0.5.11",
76
77
  "@opentui/solid": "^0.5.11",
77
- "@types/node": "26.5.1",
78
+ "@types/node": "26.6.4",
78
79
  "husky": "^9.1.7",
79
80
  "solid-js": "1.9.15",
80
81
  "typescript": "7.0.2"
@@ -17,8 +17,8 @@ type ThemeColors = TuiPluginApi["theme"]["current"]
17
17
 
18
18
  let markdownStyleCache: { theme: ThemeColors; style: SyntaxStyle } | undefined
19
19
 
20
- function buildMarkdownStyle(theme: ThemeColors): SyntaxStyle {
21
- return SyntaxStyle.fromTheme([
20
+ function buildMarkdownStyle(theme: ThemeColors, owner?: unknown): SyntaxStyle {
21
+ return (SyntaxStyle as any).fromTheme([
22
22
  { scope: ["default"], style: { foreground: theme.text } },
23
23
  { scope: ["comment", "comment.documentation"], style: { foreground: theme.syntaxComment, italic: true } },
24
24
  { scope: ["string", "symbol", "character"], style: { foreground: theme.syntaxString } },
@@ -81,17 +81,17 @@ function buildMarkdownStyle(theme: ThemeColors): SyntaxStyle {
81
81
  },
82
82
  { scope: ["markup.link.label", "label"], style: { foreground: theme.markdownLinkText, underline: true } },
83
83
  { scope: ["conceal"], style: { foreground: theme.textMuted } },
84
- ])
84
+ ], owner)
85
85
  }
86
86
 
87
- function getMarkdownStyle(theme: ThemeColors): SyntaxStyle | undefined {
87
+ function getMarkdownStyle(theme: ThemeColors, owner?: unknown): SyntaxStyle | undefined {
88
88
  if (markdownStyleCache?.theme === theme) return markdownStyleCache?.style
89
89
  try {
90
- markdownStyleCache = { theme, style: buildMarkdownStyle(theme) }
90
+ markdownStyleCache = { theme, style: buildMarkdownStyle(theme, owner) }
91
91
  return markdownStyleCache?.style
92
92
  } catch {
93
93
  try {
94
- return SyntaxStyle.create()
94
+ return (SyntaxStyle as any).create(owner)
95
95
  } catch {
96
96
  return undefined
97
97
  }
@@ -907,10 +907,10 @@ function createTranscriptPreview(api: TuiPluginApi) {
907
907
  scrollbarOptions={{ visible: false }}
908
908
  maxHeight={Math.max(6, Math.floor(api.renderer.height / 2))}
909
909
  >
910
- {getMarkdownStyle(api.theme.current) ? (
910
+ {getMarkdownStyle(api.theme.current, (api.renderer as any)?.nativeSession) ? (
911
911
  <markdown
912
912
  content={previewText()}
913
- syntaxStyle={getMarkdownStyle(api.theme.current)!}
913
+ syntaxStyle={getMarkdownStyle(api.theme.current, (api.renderer as any)?.nativeSession)!}
914
914
  treeSitterClient={getTreeSitterClient()}
915
915
  />
916
916
  ) : (
@@ -2854,10 +2854,10 @@ const tui: TuiPlugin = async (api) => {
2854
2854
  <Show when={previewID()} fallback={<text style={{ fg: api.theme.current.textMuted }}>Select a session to preview</text>}>
2855
2855
  <Show when={previewText()} fallback={<text style={{ fg: api.theme.current.textMuted }}>Loading…</text>}>
2856
2856
  {(text: Accessor<string>) =>
2857
- getMarkdownStyle(api.theme.current) ? (
2857
+ getMarkdownStyle(api.theme.current, (api.renderer as any)?.nativeSession) ? (
2858
2858
  <markdown
2859
2859
  content={text()}
2860
- syntaxStyle={getMarkdownStyle(api.theme.current)!}
2860
+ syntaxStyle={getMarkdownStyle(api.theme.current, (api.renderer as any)?.nativeSession)!}
2861
2861
  treeSitterClient={getTreeSitterClient()}
2862
2862
  />
2863
2863
  ) : (
@@ -3294,6 +3294,9 @@ function createApi(ctx: Plugin.Context) {
3294
3294
  get currentFocusedEditor() {
3295
3295
  return ctx.renderer.currentFocusedEditor
3296
3296
  },
3297
+ get nativeSession() {
3298
+ return (ctx.renderer as any)?.nativeSession
3299
+ },
3297
3300
  on(event: string, handler: (...args: any[]) => void) {
3298
3301
  ctx.renderer.on(event, handler)
3299
3302
  },