Skip to content

bobthearsonist/visual-notes

Repository files navigation

Visual Notes

Turn Obsidian notes and AI session summaries into living concept maps.

Visual Notes watches configured markdown folders, asks Claude to extract the main concepts and relationships, writes a JSON graph sidecar, and renders an interactive Cytoscape.js graph directly inside Obsidian.

The markdown note stays the source of truth. Daily notes, AI session summaries, manual notes, mobile edits, Templater output, and synced changes all flow through the same plugin pipeline: if a watched note changes, it can be extracted and rendered.

Why it is useful

  • A visual daily recap: see the day's work, decisions, blockers, and cross-domain connections at a glance.
  • Works with any note source: Claude Code, OpenCode, Copilot, manual typing, and mobile edits all become ordinary markdown input.
  • No separate graph editor: edit the note; Visual Notes regenerates the graph sidecar.
  • Useful for memory and navigation: nodes summarize important concepts; labeled edges explain why they matter.

Standalone capabilities

flowchart TB
    classDef input fill:#eef2ff,stroke:#4f46e5,stroke-width:2px,color:#111827
    classDef plugin fill:#ecfeff,stroke:#0891b2,stroke-width:2px,color:#0f172a
    classDef ai fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#111827
    classDef data fill:#f0fdf4,stroke:#16a34a,stroke-width:2px,color:#052e16
    classDef render fill:#fae8ff,stroke:#c026d3,stroke-width:2px,color:#111827
    classDef optional fill:#fff7ed,stroke:#ea580c,stroke-width:2px,stroke-dasharray: 5,5,color:#111827

    subgraph Vault["Obsidian vault"]
        Note[("Any watched markdown note")]
        Sidecar[("Sibling graph sidecar<br/>{note-basename}-overview.json")]
    end

    subgraph Plugin["Visual Notes Obsidian plugin"]
        Watch["Watch + debounce"]
        Source["Choose source<br/>raw note by default"]
        Hash["Hash + skip unchanged"]
        Extract["Extract graph with Claude"]
        Validate["Validate schema"]
        Render["Render inline"]
    end

    DailyContext["Optional Daily Context provider<br/>structured day sources"]
    DateTags["Optional Date Tags provider<br/>date tag convention/API"]
    Claude(("Anthropic Claude"))
    Pane["Interactive Cytoscape visual<br/>inside the note"]

    Note --> Watch
    DateTags -. can feed .-> DailyContext
    DailyContext -. optional source adapter .-> Source
    Watch --> Source --> Hash --> Extract --> Claude
    Claude --> Validate --> Sidecar --> Render --> Pane
    Sidecar -. read by .-> Render
    Pane -. rendered in .-> Note

    class Note input
    class Watch,Source,Hash,Extract,Validate,Render plugin
    class Claude ai
    class Sidecar data
    class Pane render
    class DateTags,DailyContext optional
Loading

Visual Notes is useful by itself: configure any folder of markdown notes, provide an Anthropic key, and it can extract/render a graph for those notes. Daily Context and Date Tags are optional providers/adapters, not required runtime dependencies.

Component Standalone responsibility Optional integrations
Visual Notes plugin Watches markdown, calls Claude, writes graph sidecars, renders Cytoscape inline. Can consume Daily Context when present; can render explicit visual-notes blocks in templates.
Daily Context plugin Exposes structured date-scoped source lists through a versioned Obsidian API. Can use Date Tags as its date-tag provider; can be consumed by Visual Notes or any other plugin/automation.
Date Tags plugin Maintains created/modified metadata and date tags. Can provide tag-building semantics to Daily Context.
AI session summary skill/template Not part of the public plugin core; an integration recipe that writes ordinary markdown notes Visual Notes can watch. Useful for AI-client session logging, but Visual Notes does not require it.

Optional integration: AI session summaries

One useful composition is AI session logging. In that workflow an AI-client skill creates an ordinary markdown session note from a vault template, then Visual Notes treats it like any other watched note.

sequenceDiagram
    participant User
    participant Skill as obsidian-notes skill
    participant Vault as Obsidian vault
    participant VN as Visual Notes plugin
    participant Claude as Anthropic Claude

    User->>Skill: "make/end session summary"
    Skill->>Vault: write AI session note from template
    Vault-->>VN: watched session note modified
    VN->>VN: raw-note extraction for non-date-named note
    VN->>Claude: graph extraction request
    Claude-->>VN: tool JSON graph
    VN->>Vault: write session-overview.json
    VN-->>User: render graph in visual-notes block
Loading

The template is an adapter detail, not a Visual Notes dependency. A good AI-session template can include:

> [!summary] Session Summary
> One-line summary.

## Session Visual

```visual-notes
```

## 2026-05-17

If you also use Date Tags/Daily Context, associate the session with a day via an explicit date/YYYY/MM/DD tag instead of adding a [[YYYYMMDD]] daily-note wikilink in the body.

Optional integration: daily overviews

sequenceDiagram
    participant Daily as Daily note
    participant DC as Daily Context
    participant DT as Date Tags
    participant VN as Visual Notes
    participant Claude as Anthropic Claude

    DT-->>DC: date tag convention/API
    Daily->>VN: watched daily note modified or manual extract
    VN->>DC: getDailyContext(date, include sources)
    DC-->>VN: daily sections + AI session sources
    VN->>Claude: graph extraction request
    Claude-->>VN: tool JSON graph
    VN->>Daily: render daily overview sidecar inline
Loading

What it looks like in Obsidian

Visual Notes renders as a card at the top of the note in both reading and edit views. The graph is interactive; the note remains normal markdown underneath.

Example Obsidian note with a Visual Notes concept map card

Feature overview:

  • Watches one or more configured markdown folders, including daily-note folders and AI session folders.
  • Debounces saves and skips unchanged content using a markdown hash.
  • Sends structured Daily Context sources to the Anthropic Messages API for date-named daily notes when the daily-context plugin is available, otherwise falls back to full note markdown.
  • Validates the returned graph against the shared sidecar schema.
  • Writes {note-basename}-overview.json next to the note.
  • Renders the sidecar inline in reading/source views or in an explicit visual-notes code block.
  • Supports pin/unpin/delete/regenerate commands for manual control.
  • Shows extraction count and status in the Obsidian status bar.
  • Tracks token usage and estimated cost metadata in the sidecar when the API response includes usage.

Project pieces

This repository contains two plugins and one shared schema:

Piece Purpose Status
plugins/obsidian-plugin Primary Obsidian plugin. Watches notes, calls Claude, writes sidecars, and renders Cytoscape inline. MVP implementation in progress
plugins/claude-code-plugin Optional companion for future agent-curated sidecars. Not required for automatic extraction. Scaffolded; migration pending
shared/schema.json JSON Schema contract for sidecar graph files. Defined
docs/design.md Living design document for open/future work. Maintained as decisions evolve

The Obsidian plugin is the standalone product. The Claude Code companion is an optional adapter: it can eventually pre-populate or pin curated sidecars, but Visual Notes does not depend on any AI-client plugin or skill.

File layout at a glance

Any watched folder/
├── note.md
└── note-overview.json

Daily folder example/
├── 20260517.md
└── 20260517-overview.json

AI session folder example/
└── 2026-05-17 plugin workflow/
    ├── 2026-05-17 plugin workflow.md
    └── 2026-05-17 plugin workflow-overview.json

Obsidian plugin
├── settings tab             # API key, watched folders, debounce, model, Daily Context
├── file watcher             # configured markdown folders
├── extractor                # requestUrl -> Anthropic Messages API
├── schema validation        # Zod + shared/schema.json
└── renderer                 # Cytoscape in MarkdownRenderChild

Important invariants:

  1. The .md note is the source of truth for extraction.
  2. The sidecar JSON is the source of truth for rendered graph data.
  3. _pinned: true on a sidecar suppresses automatic re-extraction unless the user runs force regenerate.
  4. The renderer tolerates unsupported future sidecar kinds by showing a placeholder instead of crashing.
  5. Daily Context integration is optional and applies automatically only to date-named daily notes. Other watched markdown files extract from their own content, so non-daily workflows stay standalone.

Install and setup

Obsidian plugin

Until a release is published, use the development workflow:

pnpm install
pnpm --filter @visual-notes/obsidian-plugin build

Then copy or symlink plugins/obsidian-plugin into your vault's .obsidian/plugins/visual-notes directory and enable Visual Notes in Obsidian's Community plugins settings.

After enabling:

  1. Open Settings → Visual Notes.
  2. Paste an Anthropic API key.
  3. Add watched folders, such as Daily Notes, Captains Log, 0 AI Sessions, or 0 Profisee/AI Sessions.
  4. Choose a debounce and model, or keep the defaults.
  5. Save or manually extract a note with Visual Notes: Extract from current note.

See the plugin README for detailed Obsidian-specific instructions: plugins/obsidian-plugin/README.md.

Claude Code companion plugin

The Claude Code companion is scaffolded but not yet migrated from the original private workflow. Its intended install path is:

/plugin install bobthearsonist/visual-notes/plugins/claude-code-plugin

See plugins/claude-code-plugin/README.md.

Commands

The Obsidian command palette exposes:

  • Visual Notes: Extract from current note — manually extract the active markdown file unless its sidecar is pinned.
  • Visual Notes: Extract from current note using Daily Context — manually extract through the Daily Context provider and do not fall back to raw markdown if that provider is unavailable.
  • Visual Notes: Regenerate (force) — bypasses cached hash and pin state, with a per-file cooldown.
  • Visual Notes: Pin this overview — preserves the current sidecar from automatic replacement.
  • Visual Notes: Unpin this overview — resumes automatic extraction.
  • Visual Notes: Delete sidecar — removes the generated graph sidecar.

Privacy and cost

Visual Notes sends either the configured Daily Context sources or the active note markdown to the Anthropic API when extraction runs. Do not add folders or Daily Context sources containing notes you do not want sent to a third-party API.

Bring your own API key; this project does not proxy requests or aggregate usage. At the default Haiku model, a typical extraction is designed to cost only a few fractions of a cent, but actual spend depends on note length, model, save frequency, and retries. The plugin shows today's extraction count and stores usage metadata when available.

Legacy artifacts in older vaults

If you have a vault that already contains *-overview.html files alongside their *-overview.json sidecars (typically under work folders), those HTMLs were produced by a previous agent-curated workflow and are not regenerated by the Obsidian plugin. The plugin renders the same JSON inline; the legacy HTMLs are reference artifacts only. See docs/design.md — Legacy hook artifacts vs. plugin renderer for the full story.

Development

Requirements:

  • Node.js 20+
  • pnpm

Common commands:

pnpm install
pnpm build
pnpm typecheck
pnpm lint

Repository layout:

visual-notes/
├── README.md                         # this file
├── LICENSE                           # MIT
├── manifest.json                     # marketplace metadata mirror
├── versions.json                     # marketplace compatibility mirror
├── docs/
│   ├── design.md
│   └── marketplace-readiness.md      # release/submission checklist
├── scripts/
│   └── package-obsidian-plugin.mjs   # builds release-ready Obsidian assets
├── shared/
│   ├── package.json
│   └── schema.json
└── plugins/
    ├── obsidian-plugin/
    │   ├── README.md
    │   ├── manifest.json
    │   ├── prompts/extract-graph.md
    │   └── src/
    └── claude-code-plugin/
        ├── README.md
        ├── .claude-plugin/plugin.json
        ├── hooks/
        └── skills/visual-notes/

Deeper docs and planning

Marketplace readiness is tracked in docs/marketplace-readiness.md. To produce release-ready Obsidian assets, run pnpm package:obsidian from the repo root. The root manifest.json/versions.json files are marketplace-facing mirrors of the Obsidian plugin metadata under plugins/obsidian-plugin.

License

MIT — see LICENSE.

About

Living concept map of your daily notes — Obsidian plugin + Claude Code plugin sharing a sidecar JSON schema.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors