Skip to content

feat: Second Brain tab — project wiki as an interactive graph - #124

Draft
VasiHemanth wants to merge 5 commits into
mainfrom
feat/second-brain-graph
Draft

feat: Second Brain tab — project wiki as an interactive graph#124
VasiHemanth wants to merge 5 commits into
mainfrom
feat/second-brain-graph

Conversation

@VasiHemanth

Copy link
Copy Markdown
Owner

What

A new Second Brain tab on the project page that renders the project's compiled wiki (docs/wiki, built by the tokentelemetry Claude Code plugin) as an Obsidian-style interactive graph, with an import path for brains built elsewhere.

Graph view

  • Force-directed layout (d3-force, the only new dependency) with cluster hulls: pages group by wiki section (subsystems/, features/, ...), or by link communities for flat vaults; each hull is a padded smoothed convex hull tinted by its dominant page type.
  • Hover lights up a page's neighborhood and shows a description tooltip; everything else fades.
  • Click opens a page drawer: type, tags, timestamps, rendered markdown, inbound/outbound link chips that navigate the graph, and a freshness pill (git diff --stat <compiled_from_sha> -- <resource>, honest "unknown" when there's no manifest).
  • Drag nodes, pan, scroll-zoom (labels fade in with zoom), search, per-type legend toggles, orphan toggle, focus mode (selected node ± depth 1-2), force/display sliders, reset.
  • Node colors: categorical palette validated for both themes (lightness band, chroma, CVD separation, contrast vs app surfaces); types beyond the 8th fold to gray rather than cycling hues; identity is never color-alone (labels + legend).

States

  • No wiki → onboarding: what the plugin does, copyable /brain-init/brain-compile steps, and Import an existing brain (auto-detected candidates with honest tier labels, or a manual path). Import records a pointer in ~/.tokentelemetry/brains.json only; the repo is never written. Un-import is one click.
  • Compiling → amber partial-wiki banner (status contract: a half wiki is never presented as whole).
  • Obsidian/markdown vault → renders (incl. [[wikilinks]]) with a banner suggesting /brain adopt.

Backend

backend/second_brain.py + 6 read-only endpoints (/brain, /brain/graph, /brain/page, /brain/candidates, /brain/register, /brain/unregister), placed next to /config and reusing its safe-roots path validation. Graph parse is mtime+TTL cached. Clustering is deterministic (directory-based for OKF bundles, label propagation for flat vaults).

Verification

  • Node/edge counts cross-checked against okf_lint.py --json on two real wikis: this repo's 45-page wiki (45 nodes / 79 links / 8 clusters) and pcr-divergence's 11-page one (11 / 57).
  • Import round-trip via API: register → summary flips to source: registered → graph renders → non-wiki path rejected 422 → unregister leaves brains.json empty.
  • Clicked through in the browser (dark + light): hover highlight, drawer, link navigation, theme flip, onboarding with a detected candidate.
  • tsc --noEmit clean, npm run build passes with the new route, backend module imports.

🤖 Generated with Claude Code

VasiHemanth and others added 5 commits July 5, 2026 18:50
Obsidian-style force-directed graph of a project's compiled wiki
(docs/wiki, built by the tokentelemetry Claude Code plugin), plus
import of already-built brains.

Backend (backend/second_brain.py + 6 read-only /brain endpoints):
- detection ladder (plugin_wiki > okf_ish > obsidian_vault > markdown_wiki)
- graph builder: frontmatter + markdown links + [[wikilinks]], clusters
  by wiki directory (link-community fallback for flat vaults),
  mtime+TTL cached
- page detail with git-diff freshness vs compiled_from_sha
- import registry in ~/.tokentelemetry/brains.json (repo never written);
  candidates scan + register/unregister
- ?project= paths validated with the same safe-roots guard as /config

Frontend (projects/[path]/brain + Second Brain tab):
- d3-force SVG graph: cluster hulls (padded smoothed convex hulls),
  hover neighborhood highlight + tooltip, click-to-open page drawer,
  drag nodes / pan / zoom, search, type legend toggles, orphan toggle,
  focus mode (depth 1-2), force + display sliders
- page drawer: metadata, freshness pill, rendered markdown, in/out
  link chips that navigate the graph
- no-wiki onboarding: build-new commands + detected-candidate import
- node colors: validated categorical palette (light + dark), types
  beyond the 8th fold to gray, identity never color-alone
- states: compiling banner (partial wiki), untyped-vault banner,
  unreachable-project empty state

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- index.md joins the graph as the center hub: anchored to the middle,
  halo ring, always-labeled, its ties to every page rendered as faint
  dashed lines with loose physics. It stays out of degree counts and
  clustering so it cannot star-collapse the real link structure.
- +/-/reset zoom buttons above the stats pill.
- Wheel/pinch moved to a native non-passive listener: React attaches
  wheel handlers passively, so preventDefault() was ignored and a
  trackpad pinch zoomed the whole browser tab. Pinch (ctrlKey wheel)
  now zooms the graph, scaled for its smaller deltas.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e, telemetry

- Folder picker for importing an existing brain: GET /brain/browse lists one
  directory level (safe-roots confined, cheap wiki-shape hints) behind a
  browse modal in Onboarding, so users walk to the wiki instead of typing
  absolute paths (browsers can't hand over a path from a native dialog).
- 'Built with N tok' badge on the status strip: GET /brain/build-cost sums
  tokens (own + delegated subagents) of this project's /brain-init and
  /brain-compile sessions from the session scan; tooltip carries the split
  and cost. Verified against a raw-JSONL recompute (681,718 tok exact match).
- Drawer typography scoped down: .tt-brain-md scale (12.5px base, 15px h1)
  replaces the session-viewer .prose sizing; a leading H1 duplicating the
  page title is stripped.
- Filter/path inputs no longer double-highlight: suppress the global
  :focus-visible outline where the pill container already shows focus.
- Second Brain telemetry through the existing AE pipeline: route enum
  'brain', feature names 'brain-import' / 'brain-page-open' (existing event
  names only, so the deployed Worker needs no change); redaction tests pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…llback

'Choose folder…' now opens the real OS picker — Finder on macOS (osascript,
start dir passed via argv so paths can't inject), Explorer on Windows
(PowerShell FolderBrowserDialog, -STA), zenity/kdialog on Linux — served by
GET /brain/pick-folder on the local backend, since a browser page can't get
an absolute path out of a native dialog itself.

Loopback-only: remote (tailnet) viewers get 'unsupported' — the dialog would
open on the host's screen, not theirs — and the UI falls back to the in-app
folder browser, which also covers headless hosts, dialog failures, and
missing dialog tools. Single-flight lock so a second click can't stack a
second dialog; user cancel (AppleScript -128) is a quiet no-op.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ans tab

Hoist .tt-brain-md from PageDrawer's inline <style> into globals.css and
apply it to the Plans tab's plan markdown, which was still on the
full-width .prose sizing. One scale, two panel surfaces.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant