Skip to content

Release v5.0.0#156

Merged
Arylmera merged 15 commits into
mainfrom
develop
Jun 1, 2026
Merged

Release v5.0.0#156
Arylmera merged 15 commits into
mainfrom
develop

Conversation

@Arylmera

@Arylmera Arylmera commented Jun 1, 2026

Copy link
Copy Markdown
Owner

@

Release v5.0.0

Promotes developmain. The merge-commit auto-tags v5.0.0 (release-tauri reads the version from tauri.conf.json).

Headline: native Live tab (Praetorium integration)

  • Port praetorium-core + live backend into the workspace (84c909f)
  • Mount Praetorium UI as the Live tab + pop-out window (8b2fef2) — bumps to 5.0.0
  • Scope Tauri capabilities to the live window + dialog (13a810a)
  • Native Live tab: IPC fix, view rewrite, pop-out, vault support (6f71f5f)
  • Fill the viewport for console/cockpit/explorer views (eb8b49e)

Performance & design

  • 37x faster Calendar, correct-plan Tags, no idle refetch (122e7fe)
  • perf_probe: first_prompts timing (e6dadfc)
  • Correct No-Hero-Metric rule + spec-compliant side-stripes (5324af5)
  • DESIGN.md/json refreshed to 19 themes + Live tab (476611d)

CI / docs

  • License praetorium-core + node20-safe frontend test glob (a08d868)
  • V5 Praetorium merge plan + develop→main release procedure docs

🤖 Generated with Claude Code
@

github-actions Bot and others added 15 commits May 29, 2026 15:37
Record the two-branch model and the release flow in CLAUDE.md and
docs/DEVELOPMENT.md: bump the version in the four spots, open a
develop->main PR, and merge it as a merge-commit. Emphasize that
release-tauri auto-tags from Cargo.toml on the main push, so tags must
never be created manually (pre-tagging stalls the build chain).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Design doc capturing the decisions for merging Praetorium into Token
Dashboard as a single v5.0 desktop app: drop the Praetorium CLI, port
praetorium-core + the live tauri modules, mount Live as one rail item
with a Console/Cockpit/Explorer sub-switcher and an optional pop-out
window, keep the read-only framing with Live as opt-in.

https://claude.ai/code/session_015h2hEjpj6S2pisDcdsc9nH
Stage 1 of the V5 Praetorium merge (backend).

- Add praetorium-core as a workspace member (pure parser/vault library,
  its 26 unit + 4 integration tests come along and pass).
- Port the live Tauri modules into token-dashboard-tauri under src/live/:
  process.rs (spawns the claude CLI, streams events over an IPC Channel),
  session_watch.rs (notify watcher on ~/.claude/projects/), plus the
  sessions/vault command wrappers. Drop praetorium-cli (desktop only).
- Register the live commands + shell/dialog/opener plugins + RunRegistry
  in the Tauri builder; add tokio process/io-util + notify deps.
- Add open_live_window/close_live_window/is_live_window_open commands and
  a #live-window route for the pop-out window, mirroring the existing
  widget/setup-help secondary-window pattern. Emits live-window-opened/
  -closed to the main window so the docked tab can re-dock.

Workspace builds clean; cargo clippy -D warnings, cargo fmt --check, and
cargo test --workspace all pass.

https://claude.ai/code/session_015h2hEjpj6S2pisDcdsc9nH
Stage 2 of the V5 Praetorium merge (frontend + version).

- Port Praetorium's frontend under frontend/src/live/ (components, stores,
  lib, themes, assets), preserving internal structure so relative imports
  stay valid. Add d3-force/d3-hierarchy/marked/@tauri-apps deps.
- New frontend/src/live/index.jsx wraps Praetorium's Console/Cockpit/
  Explorer view-switcher as a Token Dashboard sub-surface, with a pop-out
  control. LiveTab (docked) collapses to a placeholder while the standalone
  window is open; LiveWindow is mounted by entry.jsx on #live-window.
- Register the 'live' route (app.jsx), nav rail item (nav-items.js, gated
  at level 2 in levels.js), and update the nav-order test.
- session_watch: make watch_sessions idempotent (single owning watcher
  stored in a startup-managed handle) so the pop-out re-dock cycle can't
  double-manage and panic.
- Ship live.css (Praetorium's stylesheet) with the few global/element rules
  (html/body, form controls, .a-ambient, reduce-motion banner) scoped under
  .pr-root so the Live subtree can't repaint the host dashboard; linked in
  index.html. Add the .pr-live-* container styles.
- Bump version to 5.0.0 (4 canonical spots); reframe the README so the
  analytics tabs stay read-only and Live's claude-launch is opt-in; note
  the live module + praetorium-core in CLAUDE.md.

cargo fmt/clippy -D warnings/test --workspace and the 192-test frontend
suite (TD + ported Praetorium) all pass. esbuild bundles clean.

https://claude.ai/code/session_015h2hEjpj6S2pisDcdsc9nH
- Add the 'live' pop-out window to the capability windows list so IPC
  (invoke/Channel/event) works from the detached window.
- Add dialog:allow-open for the vault / working-directory pickers.
- Drop the shell and opener plugins: claude is spawned via tokio::process
  (not the shell plugin) and the live frontend imports neither, so they
  were unused. Keeps the plugin surface minimal.

cargo clippy -D warnings clean.

https://claude.ai/code/session_015h2hEjpj6S2pisDcdsc9nH
Two CI failures from the merge:

- cargo-deny: praetorium-core had no license field -> error[unlicensed].
  Inherit the workspace package metadata (MIT) like the sibling crates and
  bump it to 5.0.0. 'cargo deny check advisories licenses sources bans'
  now passes.
- node --test: the 'src/**/*.node-test.mjs' glob relied on node's internal
  glob expansion, which only exists in node 21+. CI runs node 20, so the
  literal path matched nothing and failed. Use a find-based file list,
  which is node-version-agnostic and still recurses into src/live/.
  192/192 frontend tests pass.

https://claude.ai/code/session_015h2hEjpj6S2pisDcdsc9nH
Folds Praetorium in as the Live tab (Console/Cockpit/Explorer) with an optional pop-out window; analytics tabs stay passive/read-only. Ports praetorium-core + the live tauri modules, drops praetorium-cli, bumps to 5.0.0. All CI green; manual desktop QA still pending.
…ettings (#152)

Make the ported Praetorium "Live" feature a first-class native dashboard tab.

- Fix Live IPC: declare app commands in build.rs (AppManifest::commands) and
  grant them in the capability, so the remote-served webview can actually call
  them — sessions, chat and vault were all denied by the Tauri ACL. Resolve the
  claude binary path explicitly in process.rs so a stale PATH does not break runs.
- Rewrite Console/Cockpit/Explorer into native .a-* dashboard components; drop
  the embedded Praetorium shell for a secondary nav rail merged with the main bar.
- Pop-out window: pre-create it hidden during setup() (WebView2 will not navigate
  a window spawned later from a command), then show/hide on demand. Native
  titlebar with drag + minimize/maximize/close, plus active-theme and
  glass/acrylic parity with the main window.
- Add a vault-folder picker to Settings for the Live Explorer.
- Unify typography (weight-400 values/titles, plain JetBrains Mono glyphs).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
The three Live sub-views sized to content, leaving dead space below
and to the right. Make the shared .a-live-view a full-height flex column
and have each view fill it: console drops the magic calc(100vh - 130px)
for height:100%, cockpit's graph swaps the fixed 70vh for flex:1, and the
previously-unstyled .a-explorer gets a flex column + scrollable pane.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
DESIGN.md documented 4 themes (dark/light/forge/forest); theme.js
actually ships 19 (10 dark, 6 light, 3 special). Rewrote the §2 theme
tables by mode with real token anchors, added a Live-tab Components
subsection, and carved out the Live Cockpit's 48px metric as a scoped
exception to the No-Hero-Type rule. Regenerated the DESIGN.json sidecar
(themes 4->19 + live subsystem) and corrected the stale "14 themes"
line in CLAUDE.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
DESIGN.md's "22px apex / no font >24px" rule was fiction: .a-metric is
clamp(28px,4vw,36px), scaling to 56px in spacious density and special
themes by design. Renamed to the No-Hero-Metric Rule (the ban is the
SaaS centered-hero template, not large numerals) and fixed the metric
token + prose in DESIGN.md/DESIGN.json to match the real responsive scale.

Brought side-stripes into spec (<=1px colored left/right borders): main
dashboard .a-side-list/.a-banner/.a-budget-banner-row and the Live .pr-*
list/turn/answer/blockquote rows reduced 2-3px -> 1px; .pr-line-prompt
stripe dropped (tinted bg + ">" glyph carry it). Also #fff hover ->
var(--bone) and .a-api-group h2 uppercase -> 10px label tier.

Removed frontend/src/live/themes/styles.css: a dead, divergent copy of
the served frontend/live.css (nothing imports it; missing the pop-out
window palettes live.css carries). live.css is canonical.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* perf(db): tune connections (WAL/mmap/cache) and pool read connections

Tier 1 of the performance roadmap. The analytics read path opened a
fresh, untuned SQLite connection per query — the day view opened six
per click on a default-journal-mode DB.

- db::tune() applies WAL, synchronous=NORMAL, mmap_size=256MB,
  cache_size=64MB, temp_store=MEMORY on both the writer open() and the
  read-path open_ro(). WAL stops reader/scanner contention; mmap+cache
  keep the hot DB warm across opens.
- open_ro() now hands back a pooled, tuned connection via a Deref guard
  (PooledConn) that returns itself to a process-wide pool on drop, so
  the PRAGMA setup and page cache stay warm. Callsites compile unchanged
  thanks to Deref coercion.

Measured on a real 245MB / 147k-row DB: /api/day 477.7 -> 130.7 ms
(3.6x), tags-summary 73 -> 45 ms, daily 88 -> 65 ms. Adds a perf_probe
example to keep each tier honest with before/after numbers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* perf(db): index substr(timestamp) so date filters seek instead of scan

Tier 2 of the performance roadmap. Every day/* query filters
`WHERE substr(timestamp,1,10) = ?`, which made the plain timestamp
index unusable and full-scanned messages — six scans per calendar
day-click.

Add expression indexes idx_messages_day (substr(timestamp,1,10), type)
and idx_tools_day. SQLite uses an expression index when the WHERE
clause repeats the expression, so the existing SQL needs no rewrite.
Indexes ship in SCHEMA with IF NOT EXISTS, so init_db builds them once
on next launch for existing DBs.

day_by_model EXPLAIN: SCAN -> SEARCH ... USING INDEX idx_messages_day.
/api/day 130.7 -> 14.0 ms (34x vs baseline), under the 50ms target.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* perf(db): keep planner statistics fresh so tag aggregate seeks

Tier 3 of the performance roadmap. With no sqlite_stat1, the planner
drove tag_aggregates from messages (SCAN m over 147k rows) instead of
the small session_tags table. ANALYZE flips it to
SCAN st -> SEARCH m USING idx_messages_thread.

Rather than build precomputed rollup tables (write-path complexity +
drift risk), refresh stats in two cheap spots:
- scan_dir runs `PRAGMA analysis_limit=400; PRAGMA optimize` after any
  scan that added rows.
- init_db runs a one-time sampled ANALYZE when sqlite_stat1 is absent,
  so existing DBs get stats on next launch.

tags-summary 46 -> 39 ms here; much larger win for users with few
tagged sessions (no longer scans every message). All hot queries now
under the 50ms target, so no rollups needed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* perf(scan): only broadcast scan_complete when rows were ingested

Tier 4 of the performance roadmap. The background scan loop ticks every
10s and emitted scan_complete unconditionally, so every connected
frontend refetched its whole endpoint registry every 10s even when the
user generated no new transcripts.

Emit only when the scan ingested rows. Liveness is held up by the
server 15s keep-alive ping, the frontend watchdog is one-shot, and the
manual /api/scan route returns stats over HTTP, so suppressing idle
events is safe. The planned query cache and SSE debounce were dropped
as YAGNI: after T1-T3 every hot query is 13-40ms warm.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…bottleneck (#154)

Follow-up to PR #153 suspected first_prompts dominated /api/day (~95ms
of ~108ms end-to-end). Measured directly: first_prompts is ~6ms for
~188 sessions and the endpoint is ~31ms server-side (raw HTTP). The
earlier ~108ms was PowerShell Invoke-RestMethod deserializing the 4.6KB
response into objects — a client-side artifact absent in the app, whose
JS frontend parses the payload natively in <1ms.

No query change warranted: rewriting the windowed query to GROUP BY
MIN(timestamp) would risk the identical-timestamp tie case for ~4ms on
an endpoint already under the 50ms target. Add the first_prompts timing
+ EXPLAIN to perf_probe so the finding stays measurable.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@Arylmera Arylmera merged commit 322996d into main Jun 1, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants