opencode-extended-sidebar 0.2.90 → 0.2.91

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.
Files changed (108) hide show
  1. package/.oesignore +17 -17
  2. package/CHANGELOG.md +96 -95
  3. package/LICENSE +21 -21
  4. package/README.md +150 -235
  5. package/oes.json +13 -11
  6. package/package.json +100 -100
  7. package/scripts/install-git-hooks.mjs +29 -29
  8. package/src/pware.oc.core/constants/index.ts +18 -18
  9. package/src/pware.oc.core/constants/pware.oc.core.constants.eventKind.ts +29 -29
  10. package/src/pware.oc.core/constants/pware.oc.core.constants.eventName.ts +15 -13
  11. package/src/pware.oc.core/constants/pware.oc.core.constants.eventType.ts +241 -241
  12. package/src/pware.oc.core/constants/pware.oc.core.constants.myWork.ts +55 -55
  13. package/src/pware.oc.core/constants/pware.oc.core.constants.partType.ts +65 -65
  14. package/src/pware.oc.core/constants/pware.oc.core.constants.phase.ts +58 -58
  15. package/src/pware.oc.core/constants/pware.oc.core.constants.pulse.ts +63 -63
  16. package/src/pware.oc.core/constants/pware.oc.core.constants.rowKind.ts +34 -34
  17. package/src/pware.oc.core/constants/pware.oc.core.constants.status.ts +74 -74
  18. package/src/pware.oc.core/constants/pware.oc.core.constants.toolName.ts +69 -69
  19. package/src/pware.oc.core/git/index.ts +7 -7
  20. package/src/pware.oc.core/git/pware.oc.core.git.ts +237 -237
  21. package/src/pware.oc.core/git/pware.oc.core.gitignore.ts +87 -87
  22. package/src/pware.oc.core/index.ts +19 -18
  23. package/src/pware.oc.core/pware.oc.core.bus.ts +42 -42
  24. package/src/pware.oc.core/pware.oc.core.cache.ts +48 -48
  25. package/src/pware.oc.core/pware.oc.core.clipboard.ts +97 -97
  26. package/src/pware.oc.core/pware.oc.core.debug.ts +280 -280
  27. package/src/pware.oc.core/pware.oc.core.events.ts +79 -79
  28. package/src/pware.oc.core/pware.oc.core.glyph.ts +135 -135
  29. package/src/pware.oc.core/pware.oc.core.layout.ts +234 -234
  30. package/src/pware.oc.core/pware.oc.core.oes.ts +99 -89
  31. package/src/pware.oc.core/pware.oc.core.paths.ts +240 -240
  32. package/src/pware.oc.core/pware.oc.core.preview.ts +74 -74
  33. package/src/pware.oc.core/pware.oc.core.pulse.ts +726 -726
  34. package/src/pware.oc.core/pware.oc.core.runtimeConfig.ts +41 -0
  35. package/src/pware.oc.core/pware.oc.core.sqlite.ts +164 -175
  36. package/src/pware.oc.core/pware.oc.core.sqliteGateway.ts +89 -0
  37. package/src/pware.oc.core/pware.oc.core.status.ts +214 -214
  38. package/src/pware.oc.core/pware.oc.core.timing.ts +63 -63
  39. package/src/pware.oc.core/pware.oc.core.width.ts +215 -215
  40. package/src/pware.oc.omo/constants/index.ts +15 -15
  41. package/src/pware.oc.omo/constants/pware.oc.omo.constants.backgroundTask.ts +18 -18
  42. package/src/pware.oc.omo/constants/pware.oc.omo.constants.boulderStatus.ts +49 -49
  43. package/src/pware.oc.omo/constants/pware.oc.omo.constants.docKind.ts +29 -29
  44. package/src/pware.oc.omo/constants/pware.oc.omo.constants.eventName.ts +11 -11
  45. package/src/pware.oc.omo/constants/pware.oc.omo.constants.planStatus.ts +60 -60
  46. package/src/pware.oc.omo/constants/pware.oc.omo.constants.reviewStatus.ts +49 -49
  47. package/src/pware.oc.omo/constants/pware.oc.omo.constants.startWork.ts +25 -25
  48. package/src/pware.oc.omo/constants/pware.oc.omo.constants.verdict.ts +38 -38
  49. package/src/pware.oc.omo/index.ts +7 -7
  50. package/src/pware.oc.omo/resolver/index.ts +19 -19
  51. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.approval.ts +179 -179
  52. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.approvalGroup.ts +116 -116
  53. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.approvalState.ts +34 -34
  54. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.boulder.ts +503 -503
  55. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.config.ts +40 -40
  56. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.doc.ts +269 -269
  57. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.draftFile.ts +18 -18
  58. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.notepadsFile.ts +18 -18
  59. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.plan.ts +155 -155
  60. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.planFile.ts +363 -361
  61. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.proofFile.ts +18 -18
  62. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.rulesFile.ts +11 -11
  63. package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.runContinuationFile.ts +14 -14
  64. package/src/pware.oc.opencode/constants/index.ts +10 -10
  65. package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.eventName.ts +15 -15
  66. package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.fileTouch.ts +18 -18
  67. package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.questionKind.ts +45 -45
  68. package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.sessionStatus.ts +58 -58
  69. package/src/pware.oc.opencode/index.ts +8 -8
  70. package/src/pware.oc.opencode/pware.oc.opencode.events.ts +182 -182
  71. package/src/pware.oc.opencode/pware.oc.opencode.files.ts +399 -399
  72. package/src/pware.oc.opencode/resolver/index.ts +223 -170
  73. package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.file.ts +150 -162
  74. package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.question.ts +149 -185
  75. package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.session.ts +248 -211
  76. package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.todo.ts +22 -26
  77. package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.tool.ts +224 -236
  78. package/src/pware.oc.perf/index.ts +14 -14
  79. package/src/pware.oc.perf/pware.oc.perf.asciichart.d.ts +15 -15
  80. package/src/pware.oc.perf/pware.oc.perf.charts.ts +284 -284
  81. package/src/pware.oc.perf/pware.oc.perf.reader.ts +962 -927
  82. package/src/pware.oc.perf/pware.oc.perf.realtime.ts +88 -88
  83. package/src/pware.oc.perf/pware.oc.perf.realtimeBlock.ts +118 -118
  84. package/src/pware.oc.perf/pware.oc.perf.realtimeCpuRam.ts +79 -79
  85. package/src/pware.oc.perf/pware.oc.perf.realtimeSampler.ts +71 -71
  86. package/src/pware.oc.perf/pware.oc.perf.realtimeTimeline.ts +214 -214
  87. package/src/pware.oc.perf/pware.oc.perf.self.ts +179 -179
  88. package/src/pware.oc.perf/pware.oc.perf.view.tsx +463 -462
  89. package/src/pware.oc.runtime/index.ts +13 -13
  90. package/src/pware.oc.runtime/pware.oc.runtime.monitor.ts +142 -142
  91. package/src/pware.oc.runtime/pware.oc.runtime.mywork-enrich.ts +87 -79
  92. package/src/pware.oc.runtime/pware.oc.runtime.mywork.ts +282 -253
  93. package/src/pware.oc.runtime/pware.oc.runtime.omoRead.ts +37 -0
  94. package/src/pware.oc.runtime/pware.oc.runtime.questions.ts +83 -95
  95. package/src/pware.oc.runtime/pware.oc.runtime.snapshotClient.ts +130 -129
  96. package/src/pware.oc.runtime/pware.oc.runtime.source.ts +105 -105
  97. package/src/pware.oc.runtime/pware.oc.runtime.worker.ts +44 -43
  98. package/src/pware.oc.runtime/resolver/index.ts +268 -224
  99. package/src/pware.oc.runtime/resolver/pware.oc.runtime.resolver.delegate.ts +146 -146
  100. package/src/pware.oc.ui/index.ts +12 -12
  101. package/src/pware.oc.ui/pware.oc.ui.chrome.tsx +381 -339
  102. package/src/pware.oc.ui/pware.oc.ui.glyphs.tsx +144 -144
  103. package/src/pware.oc.ui/pware.oc.ui.host.tsx +111 -111
  104. package/src/pware.oc.ui/pware.oc.ui.live.tsx +82 -82
  105. package/src/pware.oc.ui/pware.oc.ui.menudialogs.tsx +843 -843
  106. package/src/pware.oc.ui/pware.oc.ui.sections.tsx +552 -526
  107. package/src/pware.oc.ui/pware.oc.ui.sidebar.tsx +1718 -1629
  108. package/src/pware.oc.ui.tsx +98 -98
package/README.md CHANGED
@@ -1,235 +1,150 @@
1
- <p align="center">
2
- <img src="https://raw.githubusercontent.com/pleware/opencode-extended-sidebar/main/assets/branding.png" alt="OpenCode Extended Sidebar" width="720" />
3
- </p>
4
-
5
- # OpenCode Extended Sidebar | TUI Plugin
6
-
7
- **Mission control for your OpenCode agents right inside the TUI.**
8
-
9
- Switch sessions, watch tools run live, see which files changed, and where the time went. No browser, no dashboard, four tiny dependencies.
10
-
11
- ![OpenCode plugin](https://img.shields.io/badge/OpenCode-TUI%20plugin-000?style=flat-square) ![CI](https://github.com/pleware/opencode-extended-sidebar/actions/workflows/ci.yml/badge.svg) [![npm](https://img.shields.io/npm/v/opencode-extended-sidebar)](https://www.npmjs.com/package/opencode-extended-sidebar) [![codecov](https://codecov.io/gh/pleware/opencode-extended-sidebar/branch/main/graph/badge.svg)](https://codecov.io/gh/pleware/opencode-extended-sidebar) ![Runtime deps](https://img.shields.io/badge/runtime%20deps-4-brightgreen?style=flat-square) ![Read only](https://img.shields.io/badge/database-read--only-blue?style=flat-square) ![License](https://img.shields.io/badge/license-MIT-lightgrey?style=flat-square)
12
-
13
- ---
14
-
15
- ## Demo
16
-
17
- **[ demo recording goes here ]**
18
-
19
- *A short GIF showing session switching, live tool activity and file diffs.*
20
-
21
- ---
22
-
23
- ## Why
24
-
25
- OpenCode gives you one conversation at a time. Real work looks different: an orchestrator, delegates, tool calls, and a trail of edited files. Extended Sidebar puts that back on screen. It reads OpenCode's own database — nothing to sync, no daemon. Open the TUI and the panel is there.
26
-
27
- ## ⇄ Session switcher
28
-
29
- > Recent sessions, one click away, now live in the **My work** tab as the `Sessions` group. Title, age, and whether it is still alive. The current session is tagged `[C]`. The group header keeps two right-rail labels: `switch` opens the host session switcher (the same `/sessions` command) and `new` jumps to the home prompt — the native new-session composer with `/` slash autocomplete, `@` mentions and the agent/model picker; Enter creates the session and sends it. The command palette exposes `nw`, and slash autocomplete exposes `/nw` (alias `/new`); both jump to that same home prompt. Empty sessions that were never prompted are hidden from the list. A trimmed group ends in a clickable `… +N more`. **Project** still rolls up the tools and files from those same recent sessions.
30
-
31
- ## ⊚ Live activity pulse
32
-
33
- > Two glyphs per live row: a **state** glyph first — the braille spinner while working, `•` idle, `⧗` queued, `×` failed — then a **direction** glyph while one is active: **→** while a tool call is in flight, **←** while tokens stream in, **◷** while waiting on the model — blinking about twice a second and coloured by what is happening: green receiving tokens, yellow waiting on the model, accent a tool in flight. Idle rows keep the slot blank so the list stays aligned. Colours come from your OpenCode theme.
34
-
35
- ## Tool Calls feed that names things
36
-
37
- > Each row is labelled with what actually ran — command, file, pattern, or task — plus how long it took. Running calls tick live; failures show `×`. Click a tool for a metadata sheet (never args or output). **Project** carries the same feed rolled up from the recent sessions. The feed shows the latest `toolRows` (default 5) and ends in a `… +N more` control that reveals the next batch with each click, up to `toolFetch` (default 20) rows of history.
38
-
39
- ## ± File changes with diff stats
40
-
41
- > Files this session touched, with `+N −M` and git letters (`M` `A` `D` `R` `C` `U` `T` `?`). **V** means viewed — a session read with no git status. Click Markdown for a scrollable preview; other files open a native picker — **Preview** or **Copy relative path**. **Project** merges the same list across the recent sessions. A file list's header carries a `view all` action that opens a searchable picker of every file.
42
- >
43
- > Scratch dirs (`tmp/`, `.tmp/`, `.omo/`) and boilerplate filenames are hidden via the plugin's default `.oesignore`. The project's own `.oesignore` (gitignore format) is honoured automatically when present; set `skipGitignore` to also honour the project's `.gitignore`.
44
-
45
- ## ⋔ Delegates and sub-agents
46
-
47
- > When an orchestrator hands work off, delegates appear as their own rows — tokens, status, pulse, click to jump. **Project** lists the project's boulder. **Session** lists only this session's children.
48
-
49
- ## ? My work — what is waiting on you
50
-
51
- > One queue of things that need **your** action, shown first in the core group. Open `question` tools anywhere in the project appear as rows. Three states: `?` **Awaiting answer** (the agent is live and waiting — click to jump to the session and answer), `⊘` **Interrupted** (the question was aborted — answer never came, the reason shows on a muted line under the session name; once an interrupted question has terminated it is treated as resolved and hidden), and `×` **Errors** (the question tool genuinely failed — collapsed by default, expand for the error text on a muted line under the session name). Interrupted and Errors rows open a picker with **Navigate to session** and **Dismiss** — dismissing hides the row and is remembered for the project. Then a **Sessions** group (`◔`) — every recent session, live or idle, each showing the title, its live status mark and the `[C]` current tag, click to jump straight back in. A `Pinned` group (empty for now) sits ahead of the queue for sessions you pin. OMO plans and drafts appear in six foldable groups — four action queues plus two archives. Click a group header to fold it to its count line, and a trimmed group ends in a clickable `… +N more`: `Ready to review` (`!`, plans genuinely waiting for your sign-off), `Ready to start` (`▶`, approved plans you can launch), `Finished` (`✓`, done plans — an approved plan is auto-reconciled to Finished when its boulder work completed, or the writer session's todos are all done) and `Drafting` (`…` rows, drafts still being written — click for a picker: **Navigate to session** jumps to the session that wrote the draft, **Preview plan file** opens it as a preview) and `Draft docs` (`•` rows — draft files no action queue shows and whose plan file does not exist yet (a draft superseded by a plan of the same name is hidden entirely): approved or done drafts, unknown-status drafts, or notes with no status at all; click opens the file as a preview) and `Plans` (`▸` rows — plan files that no action queue shows: plans with an unknown or absent status). Clicking an archived plan opens the native, searchable picker: **Navigate to session** jumps to the session that wrote the plan (a muted reason is shown when no session is found), **Preview plan file** opens it as a preview, and the three **start work** rows (`start work`, `start work --make-pr`, `start work --ship`) launch the OMO plan in the current session. An archived plan can be started directly, not only previewed, and the archive offers no **Approve**. Rows are names only — no per-row age or session-status clutter; the right rail carries the review state when present. Review-required plans add the ulw-plan review state `R<round> <momus><independent>`, with per-lane glyphs `✓` approved, `!` changes requested, `?` inconclusive, `…` review live, `·` waiting. A session row carries a clickable `P` pin link (placeholder until the pinned backend is wired). When `.omo/` is absent the approval section is simply gone; the question queue works on OpenCode alone.
52
-
53
- ## ◴ Where the time actually goes
54
-
55
- > **Perf** splits the wall clock into wait, think, stream and tools, then ranks models and slow calls. Click a phase, a section title, or a tool row for a dated column log. The scan runs only while this tab is open.
56
- >
57
- > The top row is the **OES bar**: a braille spinner while a tab loads or a session switch is in flight and `×` on a real error (with the message). When the status is quiet it shows an 8-column block bar plus an integer **tok/s** estimate from streaming deltas (≈ code points ÷ 4 over a 5 s window) — the same live reading the old bar used before the realtime widget. The bar is an inline trend, so it renders at 30% opacity; the number beside it takes full contrast only while tokens are actually moving, and fades with the bar at `0 tok/s`. A **`C`** link on the right opens the **charts** popup: Tok / Cache / Proc / Net category tabs, row selectors, and one 8-row ASCII trend at a time (sized to the dialog, live on the shared timeline); dismiss with **esc** or the header link, same as native OpenCode dialogs. The sidebar itself no longer carries inline category tabs or a braille chart. On a cold start the first line is briefly taken by a one-row `engage` boot line — a braille spinner plus a block fill that completes in about a second — which ends when the first snapshot lands and hands over to the `Loaded. Engage!` success toast. No prompt or output text ever leaves the panel — only the count.
58
- >
59
- > A muted **self** line above the tab row — `self 0.4ms/ev · 1.2ms/sc · 59fps` — shows what the plugin itself costs: average event-handler ms, average scan (fingerprint + snapshot) ms, and the TUI renderer's FPS. It measures the plugin's own runtime, not the model's. The line is diagnostic: it renders — and its timing runs — only while `OES_DEBUG_OPENCODE` or `OES_DEBUG_PROFILE` is active, so a normal session pays nothing for it. `OES_DEBUG_OPENCODE=1` additionally writes `self`-tagged JSON lines to the debug log.
60
-
61
- ## ▣ One group, four views
62
-
63
- > ```
64
- > • My work • Session • Project • Stats
65
- > ```
66
- >
67
- > **Session** is this agent, its delegates, tools, files and — with OMO — the drafts this session wrote (last five inline behind a `view all` picker). **My work** is the queue of things waiting on you — open questions, the recent sessions list (with `switch`/`new`), OMO plan approvals grouped by the action they need, and the `Draft docs` + `Plans` archives of leftover draft/plan files. **Project** is the project-wide view — the tools and files every recent session touched. **Stats** is timing. Each tab is led by a status light in place of a separator: `Session`, `Project` and `Stats` always show a muted `•`, while the **My work** light turns into `?` / `×` / `!` / `▶` / `⊘` whenever something is waiting on you **right now** — a live open question, a still-open failed question, a plan to review or start, an interrupted question. An *ended* failure is history (the Errors group still lists it once My work is open) and never lights the tab. The scan is project-wide and re-runs whenever the DB snapshot changes (≈1 s) with a 5-second periodic floor, so a freshly asked question lights the tab almost immediately. Tabs and folds are remembered. Clickable labels underline on hover. While a tab waits for its data a transient status row sits at its top — a braille spinner with `switching · <id>` while a session switch is in flight, `loading` on a cold tab, or an error/empty note (`no turns yet` on Stats) — and disappears the moment the data lands, so a switch never reads as a broken panel.
68
-
69
- ## ⇕ Rows that fit the window
70
-
71
- > `oes.json` row counts are ceilings. A short terminal trims live activity last, then Files, then Delegates. Every list ends in a clickable `… +N more`: the Tool Calls feed reveals another `toolRows` per click (up to `toolFetch`); My work groups and Delegates reveal more with each click too. File lists (Files, Drafts) drop the inline revealer for a header `view all` that opens a searchable picker of the full list.
72
- >
73
- > Row text is clipped to the measured column width (wcwidth), not to code units — a wide glyph (CJK, emoji) is cut off cleanly instead of wrapping the line to a second row.
74
-
75
- ## ⊘ Privacy first
76
-
77
- > The panel never shows prompts, tool arguments, outputs, patch bodies, or absolute paths. The database is opened read-only. What you see is names, counts, statuses and durations.
78
-
79
- ## ∅ Four dependencies
80
-
81
- > Four runtime packages — [`ignore`](https://www.npmjs.com/package/ignore), [`asciichart`](https://www.npmjs.com/package/asciichart), [`simple-statistics`](https://www.npmjs.com/package/simple-statistics), [`@crafter/charts`](https://www.npmjs.com/package/@crafter/charts) — each with zero transitive dependencies. SQLite comes from `bun:sqlite` or `node:sqlite`; everything else is an OpenCode peer you already have.
82
-
83
- ## Legend
84
-
85
- The glyph says *what* is happening; the colour says *how fresh* it is. Both come from your OpenCode theme.
86
-
87
- **Glyphs**
88
-
89
- | Glyph | Meaning |
90
- | ------------------------------- | ------------------------------------------------------------- |
91
- | `⠋ ⠙ ⠹ ⠸ ⠼ …` | working the same braille spinner OpenCode uses for thinking |
92
- | `◷` | waiting on the model (direction glyph blinks) |
93
- | `→` | tool in flight (direction glyph — blinks) |
94
- | `←` | tokens streaming in (direction glyph blinks) |
95
- | `•` | idle — finished or archived |
96
- | `⧗` | queued — waiting for a concurrency slot |
97
- | `▾` | group header (`▼` is the section fold) |
98
- | `×` | failed |
99
- | `?` `⊘` `×` `◔` `!` `…` `•` `▸` `▶` `✓` | My work: awaiting an answer / interrupted / errors / running / ready to review / drafting / draft docs (muted document rows) / plans (muted document rows) / ready to start / finished |
100
- | `✓` `!` `?` `·` | Review lanes: approved / changes requested / inconclusive / waiting |
101
- | `M` `A` `D` `R` `C` `U` `T` `?` | Files: git status — same letters as `git status --short` |
102
- | `V` | Files: viewed (session read only) |
103
- | `[C]` | Sessions: the current session label |
104
- | `∴` | Perf: thinking |
105
- | `█░` | Perf: share of the wall clock — `@crafter/charts` bar, filled `█` + partial blocks, space-empty |
106
- | `▁▂▃▄▅▆▇█` | Perf: trend line chart — `asciichart`, nulls interpolated |
107
-
108
- The working spinner animates on a separate fast glyph tick (80 ms) while rows and ages stay on the coarse 50 ms / 1 s clocks, and a direction glyph fades in and out on the tick cadence, expiring on its own — it stops after ~2 s receiving tokens, ~15 s waiting on the model, ~30 s after a tool call — unless the session is still busy. The state glyph shows `×` on a failed row and `•` on a finished one; the direction slot shows the glyph only while it is active, staying blank otherwise so every row aligns. A queued delegate shows `⧗` in warning yellow — it is waiting for a slot, not done.
109
-
110
- **Colours**
111
-
112
- | Colour | Theme key | Meaning |
113
- | ---------------------- | --------------------------- | ------------------------------------------------ |
114
- | green | `success` | receiving tokens, or active within the last 5 s |
115
- | yellow | `warning` | waiting on the model, queued work, or last seen 5–10 s ago |
116
- | accent | `primary` | tool in flight also the current row |
117
- | red | `error` | failed |
118
- | muted | `textMuted` | idle, done or archived |
119
- | green `+N` / red `−M` | `diffAdded` / `diffRemoved` | added and removed lines |
120
- | `A` green / `D` red / `M` yellow | `success` / `error` / `warning` | Files: git-status letter by state; other letters muted |
121
- | accent `∴` | `primary` | Perf: thinking |
122
-
123
- While an arrow is lit it drives the colour. The current session is **bold** and tagged `[C]` in the Sessions list. Clickable labels **underline on hover**. On Perf the same arrows mean measured time: wait, stream, tools.
124
-
125
- ## Install
126
-
127
- This is a TUI plugin. It belongs in `tui.json`, not `opencode.json`.
128
-
129
- ```sh
130
- opencode plugin opencode-extended-sidebar --global
131
- ```
132
-
133
- Or add the npm name in `~/.config/opencode/tui.json`:
134
-
135
- ```json
136
- {
137
- "$schema": "https://opencode.ai/tui.json",
138
- "plugin": ["opencode-extended-sidebar"]
139
- }
140
- ```
141
-
142
- Restart the OpenCode TUI. OpenCode installs the package from npm and the panel starts reading your existing session history.
143
-
144
- For local development, point `plugin` at a `file:///` path to this checkout instead.
145
-
146
- ## Configuration
147
-
148
- Later files win:
149
-
150
- 1. the plugin's own `oes.json` (defaults)
151
- 2. `~/.config/opencode/oes.json` (respects `XDG_CONFIG_HOME`)
152
- 3. `<project>/oes.json`
153
-
154
- ```json
155
- {
156
- "fileRows": 8,
157
- "perfHistory": 3,
158
- "perfRows": 5,
159
- "perfTurns": 120,
160
- "questionReconcileSec": 15,
161
- "sessionFetch": 20,
162
- "skipGitignore": false,
163
- "toolRows": 5,
164
- "toolFetch": 20
165
- }
166
- ```
167
-
168
- | Key | Default | What it controls |
169
- | ------------------------ | -------------------------------- | ----------------------------------------------------- |
170
- | `fileRows` | `8` | most file rows shown |
171
- | `perfHistory` | `3` | sessions under Perf → History; `0` hides it |
172
- | `perfRows` | `5` | rows per Perf section |
173
- | `perfTurns` | `120` | recent turns Perf measures |
174
- | `questionReconcileSec` | `15` | seconds between full open-question rescans when no live hint arrives |
175
- | `sessionFetch` | `20` | recent sessions fetched for the My work `Sessions` group |
176
- | `skipGitignore` | `false` | also honour the project's root `.gitignore` (`.oesignore` is always honoured) |
177
- | `toolRows` | `5` | most tool-call rows shown; the `… +N more` control reveals another `toolRows` per click |
178
- | `toolFetch` | `20` | tool-call history kept behind the `… +N more` revealer; distinct from `toolRows` |
179
-
180
- Row counts are ceilings: a short terminal trims below them. Changes apply on the next refresh — no restart.
181
-
182
- Ignored files come from `.oesignore` and, when enabled, `.gitignore` — both at the project root, both in gitignore format. The plugin ships a default `.oesignore`.
183
-
184
- ## Debug
185
-
186
- Set `OES_DEBUG_OPENCODE` in the environment **before** starting OpenCode, then restart the TUI. While either logger is active the sidebar shows the muted `self` cost line with a yellow flag row above it — `debug mode` and/or `profile` — plus a second muted row that prints the **resolved log directory** (`logs <path>`) so you can see exactly where files are being written. Below everything the panel then also draws a read-only **debug console**: short event labels (`db open`, …) newest first, only 5 visible rows over a 200-line in-memory ring that wheel-scrolls to older events. The console is fed only while a logger is on — with no logger active the `self` line, its measurement, and the console are off entirely.
187
-
188
- ```bash
189
- # writes to <plugin>/logs/oes-debug-YYYY-MM-DD.log
190
- OES_DEBUG_OPENCODE=1 opencode
191
- ```
192
-
193
- ```powershell
194
- $env:OES_DEBUG_OPENCODE = "1"
195
- opencode
196
- ```
197
-
198
- `1`, `true`, `yes`, or `on` use the plugin's `logs/` directory. Any other non-empty value is treated as a directory path. `0`, `false`, `no`, or `off` turns it off. Lines are JSON (`ts`, `tag`, `msg`, optional `data`) — path resolution, monitor emits, Perf reads, and the `self` tag logs the plugin's own measured latencies. Logging never crashes the panel.
199
-
200
- SQLite reads fail fast: `busy_timeout` is 100 ms, so a transient WAL lock no longer freezes the panel — the previous snapshot is kept on screen and a `sql.busy` debug line (with the SQL in `data.q`) is appended so lock contention is visible in the log.
201
-
202
- The same semantics power `OES_DEBUG_PROFILE`, which times **every plugin entry point and hotspot** and writes one line per call to `<plugin>/logs/oes-profile-YYYY-MM-DD.log`: `{ ts, tag, ms, data? }`. In this local repo checkout, `<plugin>/logs` means `./logs` at the repository root (not `./src/logs`). Tags: `event` (per event type), `tick`, `render` (the re-render trigger), `requestRender`, `row` (per row built), `scan`, `monitor.emit` (fingerprint + snapshot), `db.snapshot` / `db.feed` / `db.questions` / `perf.read`, `sql` (every query, with its SQL in `data.q`), `omo.read` / `omo.stamp` / `omo.config` / `omo.approvals` / `omo.docs`, `mywork.approvals` (the per-approval session lookup), `files.decorate` (git marks), `git`, `remount`, `hydrate`, and the async host calls `rpc.diff` / `rpc.selectSession` / `rpc.startWork` / `rpc.approve`. When the panel unmounts, one `summary` line with per-tag `{ n, total, avg, max }` is appended — the whole wall-clock split in a single line.
203
-
204
- ## How it works
205
-
206
- The panel is a read-only view of data OpenCode already stores.
207
-
208
- | Source | Path | Used for |
209
- | --------------- | ------------------------------------------------------------- | -------------------------------- |
210
- | OpenCode SQLite | `~/.local/share/opencode/opencode.db` (or `OPENCODE_DB`) | sessions, tools, files, timings |
211
- | OMO | `<project>/.omo/` | plan approvals (My work) — optional |
212
- | `oes.json` | plugin / user config / project | display limits |
213
- | ignore files | `<project>/.oesignore` (always) · `.gitignore` (with `skipGitignore`) | files hidden from the panel |
214
-
215
- It refreshes from database stamps, file watches, and OpenCode events. The always-on runtime snapshot is read off the TUI main thread in a Bun worker (with a synchronous fallback if the worker is unavailable), so SQLite reads never block the UI. Cost is shown only when the provider reports it. The `self` line measures the plugin's own runtime with `performance.now()` and the TUI renderer's native frame stats — no extra data source — and it runs only while a debug or profile logger is active.
216
-
217
- ## Contributing
218
-
219
- Issues and pull requests are welcome. Constraints: read-only OpenCode data, no prompts or tool I/O in the UI, every row must survive a narrow terminal.
220
-
221
- Every commit patch-bumps `package.json` and prepends one English sentence to [CHANGELOG.md](CHANGELOG.md). Write that sentence as the first line of the commit message. A green CI run on `main` publishes that version to npm.
222
-
223
- `bun test` runs unit and fixture tests. `bun run typecheck` checks types with `tsc --noEmit`. `bun run bench` times the 5k-part scan.
224
-
225
- ## License
226
-
227
- MIT. Copyright © 2026 [pleware](https://github.com/pleware).
228
-
229
- <p>
230
- <a href="https://github.com/pleware"><img src="https://raw.githubusercontent.com/pleware/opencode-extended-sidebar/main/assets/branding.pware.png" alt="pware" width="72" /></a>
231
- </p>
232
-
233
- ## Acknowledgements
234
-
235
- This plugin started as a TUI take on the same idea as [Phrouros](https://github.com/disaeye/phrouros) — a live view of OpenCode agents, delegates and session activity, only inside the sidebar instead of a browser. Thank you to [disaeye](https://github.com/disaeye) for Phrouros.
1
+ ![OpenCode Extended Sidebar](https://raw.githubusercontent.com/pleware/opencode-extended-sidebar/main/assets/branding.png)
2
+
3
+ # OpenCode Extended Sidebar | TUI Plugin
4
+
5
+ **Mission control for your OpenCode agents right inside the TUI.**
6
+
7
+ Switch sessions, watch tools run live, see which files changed, and where the time went. No browser, no dashboard, four tiny dependencies.
8
+
9
+ ![OpenCode plugin](https://img.shields.io/badge/OpenCode-TUI%20plugin-000?style=flat-square) ![CI](https://github.com/pleware/opencode-extended-sidebar/actions/workflows/ci.yml/badge.svg) ![npm](https://img.shields.io/npm/v/opencode-extended-sidebar) ![codecov](https://codecov.io/gh/pleware/opencode-extended-sidebar/branch/main/graph/badge.svg) ![Runtime deps](https://img.shields.io/badge/runtime%20deps-4-brightgreen?style=flat-square) ![Read only](https://img.shields.io/badge/database-read--only-blue?style=flat-square) ![License](https://img.shields.io/badge/license-MIT-lightgrey?style=flat-square)
10
+
11
+ OpenCode shows one conversation at a time. This panel puts the rest of the work on screen. It reads OpenCode's own database — nothing to sync, no daemon.
12
+
13
+ ## Features
14
+
15
+
16
+ | Feature | What you get |
17
+ | ------------------- | ----------------------------------------------------------------------------------------- |
18
+ | **My work** | Questions, recent sessions, and (with OMO) plan queues waiting on you |
19
+ | **Sessions** | Title, age, live mark, `[C]` current. Header `switch` / `new`; palette `nw` / slash `/nw` |
20
+ | **Live pulse** | State + direction glyphs (working, queued, failed, streaming, waiting) |
21
+ | **Tool calls** | Named rows with duration; click for metadata — never args or output |
22
+ | **Files** | `+N −M` and git letters; Markdown preview; `view all` picker |
23
+ | **Delegates** | Tokens, status, pulse; click to jump |
24
+ | **Stats** | Wait / think / stream / tools, plus a tok/s bar and charts popup (`C`) |
25
+ | **Privacy** | Read-only database. No prompts, tool I/O, patches, or absolute paths |
26
+ | **Fits the window** | `oes.json` counts are ceilings; lists end in `… +N more` |
27
+
28
+
29
+ Four tabs: **My work** · **Session** · **Project** · **Stats**. Glyphs, colours, and per-row behaviour: [docs/panel.md](docs/panel.md).
30
+
31
+
32
+ | Tab | Shows |
33
+ | ----------- | ---------------------------------------------------------------------------------------------------- |
34
+ | **My work** | Open questions, recent sessions (`switch` / `new`), OMO plan queues, `Draft docs` + `Plans` archives |
35
+ | **Session** | This agent, its delegates, tools, files, and (with OMO) drafts it wrote |
36
+ | **Project** | Tools and files every recent session touched |
37
+ | **Stats** | Timing |
38
+
39
+
40
+ OMO (Oh My OpenAgent) is optional. Without `.omo/` the plan groups are gone; questions and sessions still work.
41
+
42
+ ## Install
43
+
44
+ This is a TUI plugin. It belongs in `tui.json`, not `opencode.json`.
45
+
46
+ ```sh
47
+ opencode plugin opencode-extended-sidebar --global
48
+ ```
49
+
50
+ Or add the npm name in `~/.config/opencode/tui.json`:
51
+
52
+ ```json
53
+ {
54
+ "$schema": "https://opencode.ai/tui.json",
55
+ "plugin": ["opencode-extended-sidebar"]
56
+ }
57
+ ```
58
+
59
+ Restart the OpenCode TUI. OpenCode installs the package from npm. For local development, point `plugin` at a `file:///` path to this checkout.
60
+
61
+ ## Configuration
62
+
63
+ Later files win: plugin defaults → `~/.config/opencode/oes.json` → `<project>/oes.json`.
64
+
65
+ ```json
66
+ {
67
+ "fileRows": 8,
68
+ "perfHistory": 3,
69
+ "perfRows": 5,
70
+ "perfTurns": 120,
71
+ "questionReconcileSec": 15,
72
+ "sessionDimHours": 48,
73
+ "sessionFetch": 10,
74
+ "sessionVisibleHours": 72,
75
+ "skipGitignore": false,
76
+ "toolRows": 5,
77
+ "toolFetch": 20
78
+ }
79
+ ```
80
+
81
+
82
+ | Key | Default | What it controls |
83
+ | ---------------------- | ------- | --------------------------------------------------- |
84
+ | `fileRows` | `8` | most file rows shown |
85
+ | `perfHistory` | `3` | sessions under Perf History; `0` hides it |
86
+ | `perfRows` | `5` | rows per Perf section |
87
+ | `perfTurns` | `120` | recent turns Perf measures |
88
+ | `questionReconcileSec` | `15` | seconds between full open-question rescans |
89
+ | `sessionDimHours` | `48` | hours after which a still-visible session is dimmed |
90
+ | `sessionFetch` | `10` | recent sessions in the My work `Sessions` group |
91
+ | `sessionVisibleHours` | `72` | hours a session stays visible after its last update |
92
+ | `skipGitignore` | `false` | also honour the project's root `.gitignore` |
93
+ | `toolRows` | `5` | most tool-call rows shown |
94
+ | `toolFetch` | `20` | tool-call history behind `… +N more` |
95
+
96
+
97
+ Row counts are ceilings. Changes apply on the next refresh. Hidden files come from `.oesignore` (always) and, when enabled, `.gitignore`.
98
+
99
+ ## Debug
100
+
101
+ Set the variable **before** starting OpenCode, then restart the TUI.
102
+
103
+ ```bash
104
+ OES_DEBUG_OPENCODE=1 opencode
105
+ ```
106
+
107
+ ```powershell
108
+ $env:OES_DEBUG_OPENCODE = "1"
109
+ opencode
110
+ ```
111
+
112
+
113
+ | Variable | Role |
114
+ | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
115
+ | `OES_DEBUG_OPENCODE` | `1` / `true` / `yes` / `on` writes to the plugin `logs/` directory. Any other non-empty value is a path. `0` / `false` / `no` / `off` turns it off |
116
+ | `OES_DEBUG_PROFILE` | Times plugin entry points; writes `oes-profile-YYYY-MM-DD.log` |
117
+
118
+
119
+ While a logger is on, the sidebar shows a `self` cost line and a short debug console. Logging never crashes the panel.
120
+
121
+ ## How it works
122
+
123
+ A read-only view of data OpenCode already stores.
124
+
125
+
126
+ | Source | Path | Used for |
127
+ | --------------- | ------------------------------------------------------------ | ----------------------------------- |
128
+ | OpenCode SQLite | `~/.local/share/opencode/opencode.db` (or `OPENCODE_DB`) | sessions, tools, files, timings |
129
+ | OMO | `<project>/.omo/` | plan approvals (My work) — optional |
130
+ | `oes.json` | plugin / user config / project | display limits |
131
+ | ignore files | `<project>/.oesignore` · `.gitignore` (with `skipGitignore`) | files hidden from the panel |
132
+
133
+
134
+ Runtime snapshot runs in a Bun worker so SQLite reads do not block the UI. Four runtime packages — `[ignore](https://www.npmjs.com/package/ignore)`, `[asciichart](https://www.npmjs.com/package/asciichart)`, `[simple-statistics](https://www.npmjs.com/package/simple-statistics)`, `[@crafter/charts](https://www.npmjs.com/package/@crafter/charts)` — each with zero transitive dependencies. Everything else is an OpenCode peer.
135
+
136
+ ## Contributing
137
+
138
+ Issues and pull requests are welcome. Constraints: read-only OpenCode data, no prompts or tool I/O in the UI, every row must survive a narrow terminal.
139
+
140
+ Every commit patch-bumps `package.json` and prepends one English sentence to [CHANGELOG.md](CHANGELOG.md). Write that sentence as the first line of the commit message. A green CI run on `main` publishes that version to npm.
141
+
142
+ `bun test` runs unit and fixture tests. `bun run typecheck` checks types. `bun run bench` times the 5k-part scan.
143
+
144
+ ## License
145
+
146
+ MIT. Copyright © 2026 [pleware](https://github.com/pleware) | pware.ai
147
+
148
+ ## Acknowledgements
149
+
150
+ This plugin started as a TUI take on the same idea as [Phrouros](https://github.com/disaeye/phrouros). Thank you to [disaeye](https://github.com/disaeye).
package/oes.json CHANGED
@@ -1,11 +1,13 @@
1
- {
2
- "fileRows": 8,
3
- "perfHistory": 3,
4
- "perfRows": 5,
5
- "perfTurns": 120,
6
- "questionReconcileSec": 15,
7
- "sessionFetch": 20,
8
- "skipGitignore": false,
9
- "toolRows": 5,
10
- "toolFetch": 20
11
- }
1
+ {
2
+ "fileRows": 8,
3
+ "perfHistory": 3,
4
+ "perfRows": 5,
5
+ "perfTurns": 120,
6
+ "questionReconcileSec": 15,
7
+ "sessionDimHours": 48,
8
+ "sessionFetch": 10,
9
+ "sessionVisibleHours": 72,
10
+ "skipGitignore": false,
11
+ "toolRows": 5,
12
+ "toolFetch": 20
13
+ }