The TUI ships with no keybind for session.toggle.generic_tool_output
(the keymap in packages/tui/src/config/keybind.ts sets it to
keybind("none")), so users see collapsed tool cards and no output
at all unless they either open the command palette or rebind the key.
Adds a 'ctrl+t' binding to ~/.config/opencode/tui.json so toggling is
one keystroke away, and documents the palette path + the rebind path
in the README so the user has both. No plugin code change.
The OpenCode TUI renders tool output through a literal <text> node
(packages/tui/.../session/index.tsx, GenericTool), so a GFM table
becomes a wall of pipes. The web/desktop client passes the same output
through the markdown renderer and draws a proper grid, so a GFM table
is the most compact form there.
The previous fix emitted a markdown table and assumed the TUI would
render it. It does not. The fix: ship both. The ASCII table is space-
padded, word-wraps long cells, and stays aligned even when the TUI
shows only its collapsed 3-line preview; the markdown table follows
and is what the web/desktop client renders with a proper grid.
- New rowsToAsciiTable: cellToAscii, truncateForCell, wrapCell,
visibleWidth, padRight. NULL -> <null>, BLOB -> <BLOB nB>, Date ->
ISO, BigInt -> string. Cell width capped at 40 chars by default
(configurable). Single words longer than the cap are hard-wrapped.
- sqlite_query's format=table path now emits the ASCII table first
and the markdown table second, with a blank line between.
- README explains why the duplication and how to read both.
End-to-end verified via Code Mode (no model in the loop) after
opencode service restart picked up the new transform.
User asked what happens if the window is closed mid-task. Added a
'What happens if the process dies mid-task' section that tabulates
the four exit paths (TUI close, SIGTERM, SIGKILL, power loss) and
empirically confirms that anything past the last fsync'd commit is
on disk. The only ways to lose data are :memory:, an explicit
synchronous=OFF, or a network filesystem. Also corrects the earlier
'leak fd' framing — a dead process leaks no fds, the OS reclaims
them.
User asked what happens if the connection is never closed and whether
concurrent calls are safe. Adds a Lifecycle and concurrency section
to README.md covering:
- not closing only leaks fds; data is durable on commit
- 3-tier concurrency model: same service / multi-CLI same service /
multi-process, with the actual busy_timeout default (5s) and what
to do if a longer wait is needed (run PRAGMA busy_timeout via
sqlite_exec)
- :memory: semantics (gone on close, even within one process)
- NFS/SMB caveat
No code changes; current defaults (busy_timeout 5s, synchronous
FULL, locking normal) are sensible and the existing test sweep
already verified end-to-end.
Adds a single-file V2 plugin that exposes eight tools under the
`sqlite` namespace (open, close, list, query, exec, script, tables,
schema) so a model can read and write SQLite databases from a session.
- OpenCode discovers it automatically from ~/.config/opencode/plugins/.
- New runtime dependency: better-sqlite3 (installed in this repo's
node_modules so the host's module resolution picks it up).
- README documents install, copy-to-another-machine, options, and
troubleshooting; SETUP.md is a copy-paste checklist.
- Schema/options were trimmed down while authoring: the initial draft
registered a no-op SQLite function on every open as a 'future hook';
removed, it was dead code.