Commit Graph
4 Commits
Author SHA1 Message Date
bvandeusenandClaude Opus 4.8 1417479729 Graph: label hubs cluster notes; unlinked notes float by default
CI & Build / Python lint (push) Successful in 3s
CI & Build / TypeScript typecheck (push) Successful in 6s
CI & Build / Python tests (push) Successful in 9s
CI & Build / Build & push image (push) Successful in 35s
Add labels as first-class nodes in the graph so tags act as visual
clustering hubs, and let unlinked notes float in the space by default —
per operator request (the graph is a light auxiliary lens, not a focal
surface).

Backend (graph.py):
- Emit a label-hub node (id "label:<uuid>", kind "label", #name, label
  color) for every label attached to a live note.
- Emit note -> label membership edges (kind "label") alongside the
  existing wiki-link edges (now kind "link").

Frontend (GraphView.vue):
- Render hubs as larger ringed nodes; membership edges dashed with a
  slightly longer spring rest so notes ring their hub.
- Default showAll (unlinked notes float) to true; add a Show labels
  toggle (default on) that hides hubs + membership edges.
- Click a label hub -> that label's board lens (/label/<id>); note
  clicks still open the editor.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm
2026-07-22 21:16:16 -04:00
bvandeusenandClaude Opus 4.8 2b6a353666 m4.5: titles optional — every note gets an auto display name
CI & Build / Python lint (push) Successful in 3s
CI & Build / TypeScript typecheck (push) Successful in 5s
CI & Build / Python tests (push) Successful in 8s
CI & Build / Build & push image (push) Successful in 33s
Capture starts in the body, so forcing a title feels odd and body-only
notes had no name — which made them unlinkable. Fix both: persist a
display_title = explicit title if set, else the note's first non-empty
body line (deterministic, no AI). The title field stays optional.

- migration 0012: notes.display_title (NOT NULL, best-effort backfill;
  the app recomputes precisely on next save)
- derive_display_title() helper, set on create + update
- drive the /titles index, backlinks, graph edges + node labels, and
  [[wiki-link]] resolution off display_title so body-only notes are
  nameable, findable (command palette / [[ autocomplete), and linkable
- rename-repoint generalized: inbound [[Old Name]] links now survive a
  name change via the first body line too, not just an explicit title
- unit tests for the derivation (explicit wins, first non-empty line,
  blank/empty, length cap)
- frontend: display_title on the Note type; title field placeholder now
  reads "Title (optional)"

First item of M4.5 (frictionless input & recall); unblocks the linking
work. Card rendering unchanged (no first-line duplication).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm
2026-07-22 08:00:01 -04:00
bvandeusenandClaude Opus 4.8 894dd4ac42 graph: interactive liveliness (drag/pan/zoom, unlinked toggle, label colors)
CI & Build / Python lint (push) Successful in 3s
CI & Build / TypeScript typecheck (push) Successful in 7s
CI & Build / Python tests (push) Successful in 11s
CI & Build / Build & push image (push) Successful in 35s
Backend /api/graph now returns ALL non-trashed notes as nodes, each with its
first label's color; edges unchanged. GraphView reworked: drag a node to
reposition it (pins to cursor + reheats the sim), pan the background, wheel-
zoom toward the cursor, a "Show unlinked notes" toggle (connected-only by
default), a Reset view button, and nodes filled by label color. Click (a
press without a drag) still opens the note; re-fetches on view open.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm
2026-07-20 22:40:28 -04:00
bvandeusenandClaude Opus 4.8 ad006ccb58 M3 graph view: /api/graph + force-directed SVG
CI & Build / Python lint (push) Successful in 3s
CI & Build / TypeScript typecheck (push) Successful in 5s
CI & Build / Python tests (push) Successful in 8s
CI & Build / Build & push image (push) Successful in 28s
- graph blueprint: GET /api/graph resolves note_links to target notes by
  normalized title (owner-scoped, non-trashed, self-excluded) → {nodes, edges}
  of connected notes.
- GraphView: hand-rolled force simulation (repulsion + edge springs + centering,
  cooling over ~400 frames), SVG nodes/edges, click a node to open it (reuses the
  editor with link navigation). Sidebar Graph entry + route; empty state.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm
2026-07-20 08:05:45 -04:00