Dreams are currently a black box — to benchmark Tier L models on dreamer
induction quality we need to see what each model produced. This adds a
workspace-scoped /dreams route that surfaces every dream run as a
group of conclusions split into explicit / deductive / inductive
columns, with click-to-expand premise trees.
What's here:
- `lib/dreams.ts`: pure helpers. `clusterConclusionsIntoDreams` groups a
raw conclusions list into per-pair bursts using a configurable time
window (default 60s). `expandPremiseTree` walks `reasoning_tree` first
and falls back to a flat `premises` ID list, with cycle detection and
a depth cap. Defines an `ExtendedConclusion` type that augments the
generated schema with `conclusion_type`, `premises`, and
`reasoning_tree` — Honcho's migration f1a2b3c4d5e6 added those
columns but `schema.d.ts` doesn't expose them yet, so the UI degrades
gracefully (unknown types fall into "explicit").
- `api/queries.ts`: new `useDreams` hook that paginates the conclusions
list endpoint up to a configurable cap (default 400) and hands the
raw list to the UI for clustering. New `dreams` query key.
- `components/dreams/`:
- `DreamList.tsx` — route entry. Shows recent dreams as rows with
timestamp, observer→observed pair, and per-type counts. Selecting
a row expands an inline detail panel above the list.
- `DreamDetail.tsx` — three-column view (explicit / deductive /
inductive). Each inductive conclusion has a "Show premises" button
that expands the reasoning chain.
- `PremiseTree.tsx` — recursive premise renderer with type badges,
cycle indicator, and graceful handling of premises that fall
outside the loaded page.
- Routing: `routes/workspaces_.$workspaceId_.dreams.tsx` registers the
page; routeTree.gen.ts regenerated.
- Sidebar: new "Dreams" entry between Conclusions and Webhooks
(MoonStar icon to distinguish from the dark-mode Moon).
- Breadcrumb: "dreams" added to SECTION_LABELS so the trail resolves.
Tests (vitest, 14 new):
- clustering: empty input; same-pair burst within window; gap exceeds
threshold → split; different pairs don't merge even with overlapping
timestamps; custom gap window; newest-first ordering; counts default
unknown types to explicit.
- premise tree: empty children for no premises; flat list → direct
children; multi-level reasoning_tree recursion; missing premise
flagged (not in loaded page); cycle detection halts recursion;
maxDepth cap; reasoning_tree preferred over flat premises.
Verified manually in the preview: route mounts, sidebar/breadcrumb
resolve, error path renders cleanly, typecheck + lint + dream tests
all clean. The unrelated `app.test.tsx` failure is pre-existing on
main.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
main.tsx wraps the app in DemoProvider > MetadataProvider, but the
app.test.tsx render helpers only wrapped with DemoProvider. Since
e490d91 added useMetadata() to Sidebar, the routed app threw
"useMetadataContext must be used within MetadataProvider" in tests;
the error boundary swallowed the tree and the first-load assertion
failed. CI has been red on main since that commit.
Mirror the production provider nesting in both render sites.
Introduce MetadataContext + useMetadata hook backed by localStorage and
wire a Braces button into the sidebar footer that toggles raw metadata
visibility across the app. Replace per-page collapsible metadata in
PeerDetail and WorkspaceDetail with a global animated reveal styled
distinctly (warning-colored card) to signal raw payload. Also adopts
the shared Breadcrumb in both detail pages.
Detect active workspace via fuzzy matchRoute against /workspaces/$workspaceId
and reveal an animated sub-nav with links to Peers, Sessions, Conclusions,
and Webhooks for that workspace. Sub-nav collapses smoothly when leaving
the workspace context.
Replace ad-hoc back-arrow and inline breadcrumb markup in PeerList,
SessionList, SessionDetail, ConclusionBrowser, and WebhookManager with a
single router-aware Breadcrumb. Demo-aware via useDemo() so workspace
and entity IDs render masked when demo mode is active.
Surfaces live connection health for the active instance in the sidebar
and probes localhost:8000 on the first-run choose-type screen so users
running Honcho locally can connect in one tap.
- useHealthStatus hook polls checkConnection every 30s via TanStack Query
- HealthDot component renders a colored status dot with tooltip
- choose-type screen silently probes http://localhost:8000 once; on
success it surfaces a "Detected Honcho at localhost:8000 — tap to
connect" banner that opens the self-hosted form
Adds a "choose-type" step to the settings flow so users can pick between
Honcho Cloud (https://api.honcho.dev, API key required) and Self-Hosted
(URL + optional token) when creating a connection. Multi-instance support
already exists in the data layer, so cloud and self-hosted instances can
coexist.
- new HONCHO_CLOUD_URL constant and isCloudInstance helper in config.ts
- SettingsForm accepts a preset prop; cloud variant locks the endpoint
and enforces an API key
- InstancesManager gains a ConnectionTypeChooser entry point and renders
a Cloud icon for cloud instances in the list
- unit tests for both preset paths and cloud edit-mode detection
Replace single localStorage config with a named-instance store
({ instances: Instance[], activeId }). Adds an instances manager on
the settings page (list / add / edit / delete / activate) and a
sidebar switcher for quick swaps. Existing single-config users are
migrated transparently on first load.
Switching or deleting an instance clears the TanStack Query cache so
data from another deployment never bleeds into the active view.
Add /explore redirect route that maps Honcho's deep-link shape
(?workspace=...&view=...&session=...) onto our existing flat routes,
so any app.honcho.dev URL works against a self-hosted instance by
swapping the host.
Wire tauri-plugin-deep-link to register the openconcho:// scheme on
desktop and forward incoming URLs into the router on launch and at
runtime.
Settings page was rendering Outlet directly, omitting the Sidebar nav.
Adds a playwright e2e test asserting sidebar visibility on both
dashboard and settings routes.
Bug 1: On a fresh load with no saved config, RootLayout returned `null`
while a useEffect-driven `router.navigate()` fired, leaving a blank screen
until the user manually refreshed. Move the redirect into the root route's
`beforeLoad` so it happens synchronously during route resolution and the
settings form renders on first paint.
Bug 2: `DemoProvider` was mounted inside `RootLayout` only on the
non-settings branch, so any component reading `useDemo()` outside that
branch would throw "useDemoContext must be used within DemoProvider".
Hoist `<DemoProvider>` to `main.tsx` so the context is available app-wide.
Adds vitest + RTL setup with regression tests for both behaviours.
Covers workspace IDs, session IDs, peer IDs in breadcrumbs and titles,
server base URL in sidebar, webhook URLs/IDs, and session metadata source
tags across all 11 components.
safari13 causes esbuild to fail on modern destructuring patterns
from TanStack Router/Query. In 2026, all WebKit versions that can
run Tauri v2 fully support esnext. Use chrome120 for Windows.