USP
Unlike most Obsidian AI plugins that are just chat interfaces, claude-obsidian is a knowledge engine that autonomously creates, organizes, and maintains your notes. It features multi-agent support, persistent session memory, and comprehens…
Use cases
- 01Building a personal second brain
- 02Autonomous research and knowledge synthesis
- 03Maintaining a structured codebase wiki
- 04Organizing project documentation
Detected files (8)
skills/wiki-fold/SKILL.mdskillShow content (8909 bytes)
--- name: wiki-fold description: "Rollup of wiki log entries into meta-pages. Reads the last 2^k entries from wiki/log.md, writes a structurally-idempotent fold page to wiki/folds/ that links back to children. Extractive summarization (no invention). Dry-run by default, stdout-only; commit mode writes and accepts that the PostToolUse hook auto-commits. Triggers on: fold the log, run a fold, run wiki-fold, log rollup, roll up log entries." --- # wiki-fold: Extractive Log Rollup Implements a bounded subset of Mechanism 1 from [[DragonScale Memory]]: flat fold over raw `wiki/log.md` entries. Fold-of-folds (hierarchical level-stacking) is **out of scope for this skill**; see "Scope boundary" below. A fold is **additive**: child log entries and their referenced pages are never modified, moved, or deleted. A fold is **extractive**: every outcome and theme in the output must be traceable to a specific child log entry. No invented facts, no synthesis beyond what the child entries support. --- ## Scope boundary (explicit) This skill does **not** implement: - Fold-of-folds / hierarchical level stacking (DragonScale spec calls for it; deferred to a future skill). - Automatic triggering (folds are always human-invoked in Phase 1). - Semantic-tiling dedup (Mechanism 3; separate skill). It **does** implement: - Flat fold over raw log.md entries at a chosen batch exponent `k`. - Structural idempotency via a deterministic fold ID. - Extractive summarization with count-checking. When referring to level in frontmatter, use `batch_exponent: k` (not `level: k`), because this skill does not produce hierarchical levels. --- ## Modes | Mode | Writes? | Invocation | |---|---|---| | **dry-run (default)** | **No Write tool calls.** Emit fold content via Bash `cat`/`heredoc` to stdout only. | `fold the log, dry-run k=3` | | **commit** | Uses Write/Edit tools. Each Write fires the repo PostToolUse hook which auto-commits wiki changes. Accept this. Compose full content first, then sequence writes. | `fold the log, commit k=3` (only after a clean dry-run) | **Why stdout-only in dry-run**: the repo's `hooks/hooks.json` PostToolUse hook fires on any `Write|Edit` and runs `git add wiki/ .raw/`. Writing to `/tmp` does not stage /tmp, but it still triggers the hook, which will commit *any pending wiki changes* under a generic message. Dry-run must leave zero residue. Bash stdout does not fire the hook. --- ## Deterministic fold ID Every fold has an ID derived from its inputs: ``` fold-k{K}-from-{EARLIEST-DATE}-to-{LATEST-DATE}-n{COUNT} ``` Example: `fold-k3-from-2026-04-10-to-2026-04-23-n8`. The filename in commit mode is `wiki/folds/{FOLD-ID}.md`. No date-of-creation in the filename. No timestamp in the title. **Duplicate detection (required)**: before emitting any output, check if `wiki/folds/{FOLD-ID}.md` already exists. If so, report "Fold already exists at wiki/folds/{FOLD-ID}.md. Use --force to overwrite, or pick a different range." and stop. This is the no-op idempotency guarantee; byte-identical content is NOT guaranteed (LLM prose varies) but the filename and scope are. --- ## Parameters - `k` (default 4): batch exponent. Batch size = `2^k`. Typical values: k=3 (8), k=4 (16), k=5 (32). - `range` (optional): explicit entry range `entries 1-16`. Overrides k. - `--force`: overwrite an existing fold with the same ID. Default no. - `--commit`: write to wiki/. Without it, dry-run stdout-only. If fewer than `2^k` log entries exist, report the shortfall and stop. Do not silently fold a partial batch. --- ## Procedure ### 1. Parse log entries ``` grep -n "^## \[" wiki/log.md | head -{2^k} ``` Record for each entry: line number, date, operation, title, and the following bullet lines until the next `## [` or end-of-section. ### 2. Extract child page identifiers From each entry's bullet list, extract: - `Location: wiki/path/to/page.md` (the primary page) - `[[Wikilinks]]` inline - `Pages created:` and `Pages updated:` lists Build a structured children list: ```yaml children: - date: "2026-04-23" op: "save" title: "DragonScale Memory v0.2 — post-adversarial-review" page: "[[DragonScale Memory]]" - ... ``` One record per log entry. Do not dedupe by page: if two entries both point to `[[DragonScale Memory]]`, both records appear, distinguishable by date and title. ### 3. Read referenced pages (bounded) Read only the pages that are not already captured fully in the log entry's bullets. Budget: 0-10 page reads. Hard ceiling: 15. If an entry's referenced page is missing, record `page_missing: true` and proceed. ### 4. Extractive summarization with count checks Write the fold body per `references/fold-template.md`. **Rules**: - **Extractive only.** Every outcome bullet and theme bullet must cite a specific child entry (e.g., `(from 2026-04-14 session)`) or a quoted line from that entry. Do not introduce events, counts, or interpretations not present in a child entry. - **Log entry is the primary source.** If the log entry's bullets and the referenced meta-page disagree on a fact (e.g., a count), prefer the log-entry bullets and flag the mismatch as "source mismatch: log says X, meta says Y." - **Count checks.** If you write "N concept pages" or "M repos updated," grep the source entries for the number and verify. Numeric mismatches are dry-run blockers. - **No merging across entries without naming them.** A theme that spans multiple entries must name each contributing entry inline. - **Uncertainty is a feature.** If an entry is ambiguous, say "ambiguous in source: [[Entry]]" rather than picking one interpretation. ### 5. Self-check before emitting Before printing output, verify: - Every child in `children:` frontmatter appears exactly once in the Child Entries table. - Every entry in the table appears in the `children:` frontmatter. - Every numeric claim in Key Outcomes is grep-verifiable against a child entry. - The fold ID is deterministic and the file does not already exist (or `--force` is set). If any check fails, abort and report the specific failure. ### 6. Emit **Dry-run**: use Bash `cat <<'EOF' ... EOF` to stdout. Do not use Write. Print the fold ID and a one-line summary of what the commit step would do. **Commit** (only after user says "commit the fold"): 1. `Write` the fold page to `wiki/folds/{FOLD-ID}.md`. (PostToolUse hook will auto-commit this.) 2. `Edit` `wiki/index.md` to add the fold link under a `## Folds` section (create section if missing). (Hook auto-commits.) 3. `Edit` `wiki/log.md` to prepend one entry: ``` ## [YYYY-MM-DD] fold | batch-exponent-k{K} rollup of N entries - Location: wiki/folds/{FOLD-ID}.md - Range: {EARLIEST-DATE} to {LATEST-DATE} - Children: N log entries ``` (Hook auto-commits.) Three auto-commits result. The user sees three separate `wiki: auto-commit` entries in git log. This is expected; do not attempt to suppress the hook. --- ## Output schema See `references/fold-template.md` for the canonical frontmatter and body layout. --- ## Invariants 1. **Structural idempotency**: same range + same k → same fold ID → duplicate detection prevents double-writes. LLM prose may vary across runs; the *location and scope* are fixed. 2. **Additive**: children are never modified. 3. **Bounded reads**: 0-15 child-page reads per fold. 4. **Extractive**: zero invented facts. Count checks enforced. 5. **No chaining**: wiki-fold does not invoke wiki-lint, wiki-ingest, autoresearch, or save. --- ## What NOT to do - Do not use Write/Edit during dry-run. Bash stdout only. - Do not include the current date in the fold filename or title. Use the child entry range. - Do not silently dedupe children by page title. One record per log entry. - Do not write "emergent themes" that span entries without naming which entries contribute. - Do not claim byte-identical idempotency. Structural idempotency is the actual guarantee. - Do not suppress or bypass the PostToolUse auto-commit hook. - Do not update `wiki/hot.md`. Ownership stays with save/ingest skills. --- ## Reversal Committed fold reversal (three commits, land in this order): 1. Remove the log.md fold entry. 2. Remove the index.md entry. 3. Delete the fold page file. Or: `git revert` the three auto-commits. Child pages are untouched in either path. --- ## Example dry-run sequence User: "fold the log, dry-run k=3" 1. Parse `wiki/log.md` top 8 entries. 2. Build structured children list (8 records). 3. Read 0-10 referenced pages as needed. 4. Produce fold ID: `fold-k3-from-2026-04-10-to-2026-04-23-n8`. 5. Check `wiki/folds/fold-k3-from-2026-04-10-to-2026-04-23-n8.md` does not exist. 6. Write fold body following the template. 7. Run self-check (frontmatter/table consistency, count verification). 8. Emit via `cat <<'EOF' ... EOF` to stdout. 9. Report: "Dry-run complete. Fold ID: {FOLD-ID}. To commit: 'commit the fold'."skills/obsidian-bases/SKILL.mdskillShow content (5911 bytes)
--- name: obsidian-bases description: "Create and edit Obsidian Bases (.base files): Obsidian's native database layer for dynamic tables, card views, list views, filters, formulas, and summaries over vault notes. Triggers on: create a base, add a base file, obsidian bases, base view, filter notes, formula, database view, dynamic table, task tracker base, reading list base." allowed-tools: Read Write --- # obsidian-bases: Obsidian's Database Layer Obsidian Bases (launched 2025) turns vault notes into queryable, dynamic views. Tables, cards, lists, maps. Defined in `.base` files. No plugin required; it is a core Obsidian feature. **Authoritative reference**: If the kepano/obsidian-skills plugin is installed, prefer its canonical obsidian-bases skill. Otherwise, use the reference below. Official docs: https://help.obsidian.md/bases/syntax --- ## File Format `.base` files contain valid YAML. The root keys are `filters`, `formulas`, `properties`, `summaries`, and `views`. ```yaml # Global filters: apply to ALL views filters: and: - file.hasTag("wiki") - 'status != "archived"' # Computed properties formulas: age_days: '(now() - file.ctime).days.round(0)' status_icon: 'if(status == "mature", "✅", "🔄")' # Display name overrides for properties panel properties: status: displayName: "Status" formula.age_days: displayName: "Age (days)" # One or more views views: - type: table name: "All Pages" order: - file.name - type - status - updated - formula.age_days ``` --- ## Filters Filters select which notes appear. Applied globally or per-view. ```yaml # Single string filter filters: 'status == "current"' # AND: all must be true filters: and: - 'status != "archived"' - file.hasTag("wiki") # OR: any can be true filters: or: - file.hasTag("concept") - file.hasTag("entity") # NOT: exclude matches filters: not: - file.inFolder("wiki/meta") # Nested filters: and: - file.inFolder("wiki/") - or: - 'type == "concept"' - 'type == "entity"' ``` ### Filter operators `==` `!=` `>` `<` `>=` `<=` ### Useful filter functions | Function | Example | |----------|---------| | `file.hasTag("x")` | Notes with tag `x` | | `file.inFolder("path/")` | Notes in folder | | `file.hasLink("Note")` | Notes linking to Note | --- ## Properties Three types: - **Note properties**: from frontmatter: `status`, `type`, `updated` - **File properties**: metadata: `file.name`, `file.mtime`, `file.size`, `file.ctime`, `file.tags`, `file.folder` - **Formula properties**: computed: `formula.age_days` --- ## Formulas Defined in `formulas:`. Referenced as `formula.name` in `order:` and `properties:`. ```yaml formulas: # Days since created age_days: '(now() - file.ctime).days.round(0)' # Days until a date property days_until: 'if(due_date, (date(due_date) - today()).days, "")' # Conditional label status_icon: 'if(status == "mature", "✅", if(status == "developing", "🔄", "🌱"))' # Word count estimate word_est: '(file.size / 5).round(0)' ``` **Key rule**: Subtracting two dates returns a `Duration`. Not a number. Always access `.days` first: ```yaml # CORRECT age: '(now() - file.ctime).days' # WRONG: crashes age: '(now() - file.ctime).round(0)' ``` **Always guard nullable properties with `if()`**: ```yaml # CORRECT days_left: 'if(due_date, (date(due_date) - today()).days, "")' ``` --- ## View Types ### Table ```yaml views: - type: table name: "Wiki Index" limit: 100 order: - file.name - type - status - updated groupBy: property: type direction: ASC ``` ### Cards ```yaml views: - type: cards name: "Gallery" order: - file.name - tags - status ``` ### List ```yaml views: - type: list name: "Quick List" order: - file.name - status ``` --- ## Wiki Vault Templates ### Wiki content dashboard (all non-meta pages) ```yaml filters: and: - file.inFolder("wiki/") - not: - file.inFolder("wiki/meta") formulas: age: '(now() - file.ctime).days.round(0)' properties: formula.age: displayName: "Age (days)" views: - type: table name: "All Wiki Pages" order: - file.name - type - status - updated - formula.age groupBy: property: type direction: ASC ``` ### Entity index (people, orgs, repos) ```yaml filters: and: - file.inFolder("wiki/entities/") - 'file.ext == "md"' views: - type: table name: "Entities" order: - file.name - entity_type - status - updated groupBy: property: entity_type direction: ASC ``` ### Recent ingests ```yaml filters: and: - file.inFolder("wiki/sources/") views: - type: table name: "Sources" order: - file.name - source_type - created - status groupBy: property: source_type direction: ASC ``` --- ## Embedding in Notes ```markdown ![[MyBase.base]] ![[MyBase.base#View Name]] ``` --- ## Where to Save Store `.base` files in `wiki/meta/` for vault dashboards: - `wiki/meta/dashboard.base`: main content view - `wiki/meta/entities.base`: entity tracker - `wiki/meta/sources.base`: ingestion log --- ## YAML Quoting Rules - Formulas with double quotes → wrap in single quotes: `'if(done, "Yes", "No")'` - Strings with colons or special chars → wrap in double quotes: `"Status: Active"` - Unquoted strings with `:` break YAML parsing --- ## What Not to Do - Do not use `from:` or `where:`: those are Dataview syntax, not Obsidian Bases - Do not use `sort:` at the root level: sorting is per-view via `order:` and `groupBy:` - Do not put `.base` files outside the vault: they only render inside Obsidian - Do not reference `formula.X` in `order:` without defining `X` in `formulas:`skills/obsidian-markdown/SKILL.mdskillShow content (5742 bytes)
--- name: obsidian-markdown description: "Write correct Obsidian Flavored Markdown: wikilinks, embeds, callouts, properties, tags, highlights, math, and canvas syntax. Reference this when creating or editing any wiki page. Triggers on: write obsidian note, obsidian syntax, wikilink, callout, embed, obsidian markdown, wikilink format, callout syntax, embed syntax, obsidian formatting, how to write obsidian markdown." allowed-tools: Read Write Edit --- # obsidian-markdown: Obsidian Flavored Markdown Reference this skill when writing any wiki page. Obsidian extends standard Markdown with wikilinks, embeds, callouts, and properties. Getting syntax wrong causes broken links, invisible callouts, or malformed frontmatter. **Cross-reference**: If the kepano/obsidian-skills plugin is installed, prefer its canonical obsidian-markdown skill for authoritative Obsidian syntax reference. Otherwise, use the reference below. See also [github.com/kepano/obsidian-skills](https://github.com/kepano/obsidian-skills). --- ## Wikilinks Internal links use double brackets. The filename without extension. | Syntax | What it does | |---|---| | `[[Note Name]]` | Basic link | | `[[Note Name\|Display Text]]` | Aliased link (shows "Display Text") | | `[[Note Name#Heading]]` | Link to a specific heading | | `[[Note Name#^block-id]]` | Link to a specific block | Rules: - Case-sensitive on some systems. Match the exact filename. - No path needed: Obsidian resolves by filename uniqueness. - If two files have the same name, use `[[Folder/Note Name]]` to disambiguate. --- ## Embeds Embeds use `!` before the wikilink. They display the content inline. | Syntax | What it does | |---|---| | `![[Note Name]]` | Embed a full note | | `![[Note Name#Heading]]` | Embed a section | | `![[image.png]]` | Embed an image | | `![[image.png\|300]]` | Embed image with width 300px | | `![[document.pdf]]` | Embed a PDF (Obsidian renders natively) | | `![[audio.mp3]]` | Embed audio | --- ## Callouts Callouts are blockquotes with a type keyword. They render as styled alert boxes. ```markdown > [!note] > Default informational callout. > [!note] Custom Title > Callout with a custom title. > [!note]- Collapsible (closed by default) > Click to expand. > [!note]+ Collapsible (open by default) > Click to collapse. ``` ### All callout types | Type | Aliases | Use for | |------|---------|---------| | `note` |: | General notes | | `abstract` | `summary`, `tldr` | Summaries | | `info` |: | Information | | `todo` |: | Action items | | `tip` | `hint`, `important` | Tips and highlights | | `success` | `check`, `done` | Positive outcomes | | `question` | `help`, `faq` | Open questions | | `warning` | `caution`, `attention` | Warnings | | `failure` | `fail`, `missing` | Errors or failures | | `danger` | `error` | Critical issues | | `bug` |: | Known bugs | | `example` |: | Examples | | `quote` | `cite` | Quotations | | `contradiction` |: | Conflicting information (wiki convention) | --- ## Properties (Frontmatter) Obsidian renders YAML frontmatter as a Properties panel. Rules: ```yaml --- type: concept # plain string title: "Note Title" # quoted if it contains special chars created: 2026-04-08 # date as YYYY-MM-DD (not ISO datetime) updated: 2026-04-08 tags: - tag-one # list items use - format - tag-two status: developing related: - "[[Other Note]]" # wikilinks must be quoted in YAML sources: - "[[source-page]]" --- ``` Rules: - Flat YAML only. Never nest objects. - Dates as `YYYY-MM-DD`, not `2026-04-08T00:00:00`. - Lists as `- item`, not inline `[a, b, c]`. - Wikilinks in YAML must be quoted: `"[[Page]]"`. - `tags` field: Obsidian reads this as the tag list, searchable in vault. --- ## Tags Two valid forms: ```markdown #tag-name : inline tag anywhere in the body #parent/child-tag : nested tag (shows hierarchy in tag pane) ``` In frontmatter: ```yaml tags: - research - ai/obsidian ``` Do not use `#` inside frontmatter tag lists. Just the tag name. --- ## Text Formatting Standard Markdown plus Obsidian extensions: | Syntax | Result | |---|---| | `**bold**` | Bold | | `*italic*` | Italic | | `~~strikethrough~~` | Strikethrough | | `==highlight==` | Highlighted text (yellow in Obsidian) | | `` `inline code` `` | Inline code | --- ## Math Obsidian uses MathJax/KaTeX: Inline math: ```markdown $E = mc^2$ ``` Block math: ```markdown $$ \int_0^\infty e^{-x} dx = 1 $$ ``` --- ## Code Blocks Standard fenced code blocks. Obsidian highlights all common languages: ````markdown ```python def hello(): return "world" ``` ```` --- ## Tables Standard Markdown tables: ```markdown | Column A | Column B | Column C | |----------|----------|----------| | Value | Value | Value | | Value | Value | Value | ``` Obsidian renders tables natively. No plugin needed. --- ## Mermaid Diagrams Obsidian renders Mermaid natively: ````markdown ```mermaid graph TD A[Start] --> B{Decision} B -->|Yes| C[End] B -->|No| D[Loop] D --> A ``` ```` Supported: `graph`, `sequenceDiagram`, `gantt`, `classDiagram`, `pie`, `flowchart`. --- ## Footnotes ```markdown This sentence has a footnote.[^1] [^1]: The footnote text goes here. ``` --- ## What NOT to Do - Do not use `[link text](path/to/note.md)` for internal links: use `[[Note Name]]` instead. - Do not use HTML inside callouts: stick to Markdown. - Do not use `##` inside a callout body: headings don't render inside callouts. - Do not write `tags: [a, b, c]` inline in frontmatter: Obsidian prefers the list format. - Do not write ISO datetimes in frontmatter (`2026-04-08T00:00:00Z`): use `2026-04-08`.skills/save/SKILL.mdskillShow content (3861 bytes)
--- name: save description: > Save the current conversation, answer, or insight into the Obsidian wiki vault as a structured note. Analyzes the chat, determines the right note type, creates frontmatter, files it in the correct wiki folder, and updates index, log, and hot cache. Triggers on: "save this", "save that answer", "/save", "file this", "save to wiki", "save this session", "file this conversation", "keep this", "save this analysis", "add this to the wiki". allowed-tools: Read Write Edit Glob Grep --- # save: File Conversations Into the Wiki Good answers and insights shouldn't disappear into chat history. This skill takes what was just discussed and files it as a permanent wiki page. The wiki compounds. Save often. --- ## Note Type Decision Determine the best type from the conversation content: | Type | Folder | Use when | |------|--------|---------| | synthesis | wiki/questions/ | Multi-step analysis, comparison, or answer to a specific question | | concept | wiki/concepts/ | Explaining or defining an idea, pattern, or framework | | source | wiki/sources/ | Summary of external material discussed in the session | | decision | wiki/meta/ | Architectural, project, or strategic decision that was made | | session | wiki/meta/ | Full session summary: captures everything discussed | If the user specifies a type, use that. If not, pick the best fit based on the content. When in doubt, use `synthesis`. --- ## Save Workflow 1. **Scan** the current conversation. Identify the most valuable content to preserve. 2. **Ask** (if not already named): "What should I call this note?" Keep the name short and descriptive. 3. **Determine** note type using the table above. 4. **Extract** all relevant content from the conversation. Rewrite it in declarative present tense (not "the user asked" but the actual content itself). 5. **Create** the note in the correct folder with full frontmatter. 6. **Collect links**: identify any wiki pages mentioned in the conversation. Add them to `related` in frontmatter. 7. **Update** `wiki/index.md`. Add the new entry at the top of the relevant section. 8. **Append** to `wiki/log.md`. New entry at the TOP: ``` ## [YYYY-MM-DD] save | Note Title - Type: [note type] - Location: wiki/[folder]/Note Title.md - From: conversation on [brief topic description] ``` 9. **Update** `wiki/hot.md` to reflect the new addition. 10. **Confirm**: "Saved as [[Note Title]] in wiki/[folder]/." --- ## Frontmatter Template ```yaml --- type: <synthesis|concept|source|decision|session> title: "Note Title" created: YYYY-MM-DD updated: YYYY-MM-DD tags: - <relevant-tag> status: developing related: - "[[Any Wiki Page Mentioned]]" sources: - "[[.raw/source-if-applicable.md]]" --- ``` For `question` type, add: ```yaml question: "The original query as asked." answer_quality: solid ``` For `decision` type, add: ```yaml decision_date: YYYY-MM-DD status: active ``` --- ## Writing Style - Declarative, present tense. Write the knowledge, not the conversation. - Not: "The user asked about X and Claude explained..." - Yes: "X works by doing Y. The key insight is Z." - Include all relevant context. Future sessions should be able to read this page cold. - Link every mentioned concept, entity, or wiki page with wikilinks. - Cite sources where applicable: `(Source: [[Page]])`. --- ## What to Save vs. Skip Save: - Non-obvious insights or synthesis - Decisions with rationale - Analyses that took significant effort - Comparisons that are likely to be referenced again - Research findings Skip: - Mechanical Q&A (lookup questions with obvious answers) - Setup steps already documented elsewhere - Temporary debugging sessions with no lasting insight - Anything already in the wiki If it's already in the wiki, update the existing page instead of creating a duplicate.skills/autoresearch/SKILL.mdskillShow content (7383 bytes)
--- name: autoresearch description: > Autonomous iterative research loop. Takes a topic, runs web searches, fetches sources, synthesizes findings, and files everything into the wiki as structured pages. Based on Karpathy's autoresearch pattern: program.md configures objectives and constraints, the loop runs until depth is reached, output goes directly into the knowledge base. Triggers on: "/autoresearch", "autoresearch", "research [topic]", "deep dive into [topic]", "investigate [topic]", "find everything about [topic]", "research and file", "go research", "build a wiki on". allowed-tools: Read Write Edit Glob Grep WebFetch WebSearch --- # autoresearch: Autonomous Research Loop You are a research agent. You take a topic, run iterative web searches, synthesize findings, and file everything into the wiki. The user gets wiki pages, not a chat response. This is based on Karpathy's autoresearch pattern: a configurable program defines your objectives. You run the loop until depth is reached. Output goes into the knowledge base. --- ## Before Starting Read `references/program.md` to load the research objectives and constraints. This file is user-configurable. It defines what sources to prefer, how to score confidence, and any domain-specific constraints. --- ## Topic Selection Three paths to a topic: ### A. Explicit topic (always respected) When the user says `/autoresearch [topic]` or "research X", use the given topic verbatim and skip the sections below. ### B. Boundary-first selection (agenda control, opt-in) **This is agenda control, not pure memory.** DragonScale Memory.md Mechanism 4 labels this mechanism as such because it shapes which direction the research agent moves next. Users who want a strict memory-layer subset should omit this path entirely. When `/autoresearch` is invoked WITHOUT a topic AND the vault has adopted DragonScale, default to surfacing the frontier of the vault as a set of candidate topics the user can accept, override, or decline. Feature detection (shell): ```bash if [ -x ./scripts/boundary-score.py ] && [ -d ./.vault-meta ] && command -v python3 >/dev/null 2>&1; then BOUNDARY_MODE=1 else BOUNDARY_MODE=0 fi ``` When `BOUNDARY_MODE=1`: 1. Run `./scripts/boundary-score.py --json --top 5`. Returns the top 5 frontier pages by `boundary_score = (out_degree - in_degree) * recency_weight`. 2. **Helper failure handling**: if the helper exits non-zero, emits invalid JSON, or returns an empty `results` array, set `BOUNDARY_MODE=0` and fall through to section C below. Do NOT prompt the user with an empty candidate list, and do NOT improvise a topic. 3. Present the candidate list to the user: "Your top frontier pages are: [list]. Research which one? (1-5, or type a topic to override, or say 'cancel' to be asked normally.)" 4. If the user picks 1-5, use the selected page's title as the topic. 5. If the user types free text, use that. 6. If the user cancels or does not choose, fall through to C. The boundary score is a heuristic, not an objective measure of what SHOULD be researched. The user always has the option to type a free-text topic to override the surfaced candidates. **Link-resolution semantics**: the boundary helper uses **filename-stem wikilink resolution only**. `[[Foo]]` is counted as an edge to `Foo.md` anywhere in the vault. Aliases declared via frontmatter `aliases:` are **not** parsed. Folder-qualified links (e.g. `[[notes/Foo]]`) are resolved by stem only. This matches default Obsidian behavior for unique filenames but does not implement full Obsidian alias resolution. ### C. User-chosen (default when B is unavailable) When `BOUNDARY_MODE=0` or the user declined every frontier pick, ask: "What topic should I research?" --- ## Research Loop ``` Input: topic (from Topic Selection, above) Round 1. Broad search 1. Decompose topic into 3-5 distinct search angles 2. For each angle: run 2-3 WebSearch queries 3. For top 2-3 results per angle: WebFetch the page 4. Extract from each: key claims, entities, concepts, open questions Round 2. Gap fill 5. Identify what's missing or contradicted from Round 1 6. Run targeted searches for each gap (max 5 queries) 7. Fetch top results for each gap Round 3. Synthesis check (optional, if gaps remain) 8. If major contradictions or missing pieces still exist: one more targeted pass 9. Otherwise: proceed to filing Max rounds: 3 (as set in program.md). Stop when depth is reached or max rounds hit. ``` --- ## Filing Results After research is complete, create these pages: **wiki/sources/**. One page per major reference found - Use source frontmatter (type, source_type, author, date_published, url, confidence, key_claims) - Body: summary of the source, what it contributes to the topic **wiki/concepts/**. One page per significant concept extracted - Only create a page if the concept is substantive enough to stand alone - Check the index first: update existing concept pages rather than creating duplicates **wiki/entities/**. One page per significant person, org, or product identified - Check the index first: update existing entity pages **wiki/questions/**. One synthesis page titled "Research: [Topic]" - This is the master synthesis. Everything comes together here. - Sections: Overview, Key Findings, Entities, Concepts, Contradictions, Open Questions, Sources - Full frontmatter with related links to all pages created in this session --- ## Synthesis Page Structure ```markdown --- type: synthesis title: "Research: [Topic]" created: YYYY-MM-DD updated: YYYY-MM-DD tags: - research - [topic-tag] status: developing related: - "[[Every page created in this session]]" sources: - "[[wiki/sources/Source 1]]" - "[[wiki/sources/Source 2]]" --- # Research: [Topic] ## Overview [2-3 sentence summary of what was found] ## Key Findings - Finding 1 (Source: [[Source Page]]) - Finding 2 (Source: [[Source Page]]) - ... ## Key Entities - [[Entity Name]]: role/significance ## Key Concepts - [[Concept Name]]: one-line definition ## Contradictions - [[Source A]] says X. [[Source B]] says Y. [Brief note on which is more credible and why] ## Open Questions - [Question that research didn't fully answer] - [Gap that needs more sources] ## Sources - [[Source 1]]: author, date - [[Source 2]]: author, date ``` --- ## After Filing 1. Update `wiki/index.md`. Add all new pages to the right sections 2. Append to `wiki/log.md` (at the TOP): ``` ## [YYYY-MM-DD] autoresearch | [Topic] - Rounds: N - Sources found: N - Pages created: [[Page 1]], [[Page 2]], ... - Synthesis: [[Research: Topic]] - Key finding: [one sentence] ``` 3. Update `wiki/hot.md` with the research summary --- ## Report to User After filing everything: ``` Research complete: [Topic] Rounds: N | Searches: N | Pages created: N Created: wiki/questions/Research: [Topic].md (synthesis) wiki/sources/[Source 1].md wiki/concepts/[Concept 1].md wiki/entities/[Entity 1].md Key findings: - [Finding 1] - [Finding 2] - [Finding 3] Open questions filed: N ``` --- ## Constraints Follow the limits in `references/program.md`: - Max rounds (default: 3) - Max pages per session (default: 15) - Confidence scoring rules - Source preference rules If a constraint conflicts with completeness, respect the constraint and note what was left out in the Open Questions section.skills/canvas/SKILL.mdskillShow content (9474 bytes)
--- name: canvas description: "Visual layer of the wiki. Add images, text cards, PDFs, and wiki pages to Obsidian canvas files with auto-positioning inside zones. Integrates with /banana for image capture. Triggers on: /canvas, canvas new, canvas add image, canvas add text, canvas add pdf, canvas add note, canvas zone, canvas list, canvas from banana, add to canvas, put this on the canvas, open canvas, create canvas." allowed-tools: Read Write Edit Glob Grep --- # canvas: Visual Reference Layer The three knowledge capture layers: - `/save` → text synthesis (wiki/questions/, wiki/concepts/) - `/autoresearch` → structured knowledge (wiki/sources/, wiki/concepts/) - `/canvas` → visual references (wiki/canvases/) A canvas is a JSON file Obsidian renders as an infinite visual board. This skill reads and writes canvas JSON directly. Read `references/canvas-spec.md` for the full format reference before making any edits. This spec aligns with the [JSON Canvas open standard](https://jsoncanvas.org/). If the kepano/obsidian-skills plugin is installed, its json-canvas skill is the authoritative canvas spec reference. Otherwise, use the guidance below. --- ## Default Canvas `wiki/canvases/main.canvas` If it does not exist, create it: ```json { "nodes": [ { "id": "title", "type": "text", "text": "# Visual Reference\n\nDrop images, PDFs, and notes here.", "x": -400, "y": -300, "width": 400, "height": 120, "color": "6" }, { "id": "zone-default", "type": "group", "label": "General", "x": -400, "y": -140, "width": 800, "height": 400, "color": "4" } ], "edges": [] } ``` --- ## Operations ### open / status (`/canvas` with no args) 1. Check if `wiki/canvases/main.canvas` exists. 2. If yes: read it, count nodes by type, list all group node labels (zone names). Report: "Canvas has N nodes: X images, Y text cards, Z wiki pages. Zones: [list]" 3. If no: create it with the starter structure above. Report: "Created main.canvas with a General zone." 4. Tell user: "Open `wiki/canvases/main.canvas` in Obsidian to view." --- ### new (`/canvas new [name]`) 1. Slugify the name: lowercase, spaces → hyphens, strip special chars. 2. Create `wiki/canvases/[slug].canvas` with the starter structure, title updated to `# [Name]`. 3. Add entry to `wiki/overview.md` under a "## Canvases" subsection (append after the Current State section). Do not modify `wiki/index.md`. It uses a fixed section schema (Domains, Entities, Concepts, Sources, Questions, Comparisons). 4. Report: "Created wiki/canvases/[slug].canvas" --- ### add image (`/canvas add image [path or url]`) **Resolve the image:** - If URL (starts with `http`): download with `curl -sL [url] -o _attachments/images/canvas/[filename]` Derive filename from URL path, or use `img-[timestamp].jpg` if unclear. - If local path outside vault: `cp [path] _attachments/images/canvas/` - If already vault-relative: use as-is. Create `_attachments/images/canvas/` if it doesn't exist. **Detect aspect ratio:** Use `python3 -c "from PIL import Image; img=Image.open('[path]'); print(img.width, img.height)"` or `identify -format '%w %h' [path]`. See `references/canvas-spec.md` for the full aspect ratio → canvas size table (7 ratios including 4:3, 3:4, ultra-wide). Do not use an inline table here. The spec is the single source of truth for sizing. **Position using auto-layout** (see Auto-Positioning section below). **Append node to canvas JSON and write.** Report: "Added [filename] to [zone] zone at position ([x], [y])." --- ### add text (`/canvas add text [content]`) Create a text node: ```json { "id": "text-[timestamp]", "type": "text", "text": "[content]", "x": [auto], "y": [auto], "width": 300, "height": 120, "color": "4" } ``` Position using auto-layout. Write and report. --- ### add pdf (`/canvas add pdf [path]`) Same as add image. Obsidian renders PDFs natively as file nodes. - Copy to `_attachments/pdfs/canvas/` if outside vault. - Fixed size: width=400, height=520. - Report page count if you can determine it. --- ### add note (`/canvas add note [wiki-page]`) 1. Search `wiki/` for a file matching the page name (case-insensitive, partial match ok). 2. Use the vault-relative path as the `file` field. - Use `"type": "file"` (not `"type": "link"`): `.md` files use file nodes, not link nodes. - `"type": "link"` takes a `url: "https://..."`: it is for web URLs only. 3. Create a file node: width=300, height=100. 4. Position using auto-layout. ```json { "id": "note-[timestamp]", "type": "file", "file": "wiki/concepts/LLM Wiki Pattern.md", "x": [auto], "y": [auto], "width": 300, "height": 100 } ``` --- ### zone (`/canvas zone [name] [color]`) 1. Read canvas JSON. 2. Find max_y: `max(node.y + node.height for all nodes) + 60`. Use 280 if no nodes (leaves room above the starter title node). 3. Create a group node: ```json { "id": "zone-[slug]", "type": "group", "label": "[name]", "x": -400, "y": [max_y], "width": 1000, "height": 400, "color": "[color or '3']" } ``` Valid colors: `"1"`=red `"2"`=orange `"3"`=yellow `"4"`=green `"5"`=cyan `"6"`=purple Write and report. --- ### list (`/canvas list`) 1. `glob wiki/canvases/*.canvas` 2. For each canvas: read JSON, count nodes by type. 3. Report: ``` wiki/canvases/main.canvas . 14 nodes (8 images, 3 text, 2 file, 1 group) wiki/canvases/design-ideas.canvas. 42 nodes (30 images, 4 text, 8 groups) ``` --- ### from banana (`/canvas from banana`) (if the banana-claude plugin is installed) 1. Check `wiki/canvases/.recent-images.txt` first (session log of newly written images). 2. If not found or empty: use `find` with correct precedence (parentheses required. Without them `-newer` only binds to the last `-name` clause): ```bash python3 -c "import time,os; open('/tmp/ten-min-ago','w').close(); os.utime('/tmp/ten-min-ago',(time.time()-600,time.time()-600))" find _attachments/images -newer /tmp/ten-min-ago \( -name "*.png" -o -name "*.jpg" \) ``` Note: `/banana` is an optional external skill not shipped in this plugin. If the user has it installed, the `.recent-images.txt` log will be populated. If not, the `find` command above is the fallback. 3. If still none: show the 5 most recently modified images. 4. Present list: "Found N recent images: [list]. Add to canvas? Which zone? (zone name / 'new [name]' / 'skip')" 5. On confirmation: add each using the add image logic. --- ## Auto-Positioning Algorithm Read `references/canvas-spec.md` for the full coordinate system. ```python def next_position(canvas_nodes, target_zone_label, new_w, new_h): # Find zone group node zone = next((n for n in canvas_nodes if n.get('type') == 'group' and n.get('label') == target_zone_label), None) if zone is None: # No zone: place below all content max_y = max((n['y'] + n.get('height', 0) for n in canvas_nodes), default=-140) return -400, max_y + 60 zx, zy = zone['x'], zone['y'] zw, zh = zone['width'], zone['height'] # Nodes inside this zone inside = [n for n in canvas_nodes if n.get('type') != 'group' and zx <= n['x'] < zx + zw and zy <= n['y'] < zy + zh] if not inside: return zx + 20, zy + 20 rightmost_x = max(n['x'] + n.get('width', 0) for n in inside) next_x = rightmost_x + 40 if next_x + new_w > zx + zw: # New row max_row_y = max(n['y'] + n.get('height', 0) for n in inside) return zx + 20, max_row_y + 20 # Same row: align to the top of all existing nodes in the zone current_row_y = min(n['y'] for n in inside) return next_x, current_row_y ``` --- ## ID Generation Read the canvas, collect all existing IDs. Never reuse one. Safe ID pattern: `[type]-[content-slug]-[full-unix-timestamp]` Use the full Unix timestamp (10 digits) to avoid collisions in batch operations. Examples: `img-cover-1744032823`, `text-note-1744032845`, `zone-branding-1744032901` If a collision is detected (ID already exists in the canvas), append `-2`, `-3`, etc. --- ## Session Log (optional hook) If `wiki/canvases/.recent-images.txt` exists, append any new image path written to `_attachments/images/` during this session (one path per line, keep last 20). `/canvas from banana` reads this file first, making it instant without filesystem search. --- ## Banana Integration (if the banana-claude plugin is installed) After any `/banana` run in the same session, if the user says "add to canvas" or "put on canvas", treat it as `/canvas from banana`. When `/banana` finishes generating images, suggest: > "Add generated images to canvas? Run `/canvas from banana`" --- ## Summary 1. Read canvas-spec.md before editing any canvas JSON. 2. Always read the canvas file before writing. Parse existing nodes to avoid ID collisions and calculate auto-positions. 3. Create `_attachments/images/canvas/` for downloaded/copied images. 4. Update `wiki/index.md` when creating new canvases. 5. Report position and zone after every add operation. ## See Also For standalone visual production (12 templates, 6 layout algorithms, AI generation, presentations), see [claude-canvas](https://github.com/AgriciDaniel/claude-canvas). This skill handles wiki-scoped visual boards. claude-canvas handles full-featured canvas orchestration for any project.skills/defuddle/SKILL.mdskillShow content (2616 bytes)
--- name: defuddle description: "Strip clutter from web pages before ingesting into the wiki. Removes ads, navigation, headers, footers, and boilerplate: leaving clean readable markdown that saves 40-60% tokens. Triggers on: defuddle, clean this page, strip this url, fetch and clean, clean web content before ingesting, strip ads, remove clutter, clean URL content, readable markdown from URL." allowed-tools: Read Bash --- # defuddle: Web Page Cleaner Defuddle extracts the meaningful content from a web page and drops everything else: ads, cookie banners, nav bars, related articles, footers, social sharing buttons. What remains is the article body as clean markdown. Use this before any URL ingestion. It is optional but strongly recommended. It cuts token usage by 40-60% on typical web articles and produces cleaner wiki pages. --- ## Install ```bash npm install -g defuddle-cli ``` Verify: `defuddle --version` --- ## Usage ### Clean a URL directly ```bash defuddle https://example.com/article ``` Outputs clean markdown to stdout. ### Save to .raw/ ```bash defuddle https://example.com/article > .raw/articles/article-slug-$(date +%Y-%m-%d).md ``` ### Add frontmatter header after saving After running defuddle, prepend the source URL and fetch date: ```bash SLUG="article-slug-$(date +%Y-%m-%d)" { echo "---"; echo "source_url: https://example.com/article"; echo "fetched: $(date +%Y-%m-%d)"; echo "---"; echo ""; defuddle https://example.com/article; } > .raw/articles/$SLUG.md ``` ### Clean a local HTML file ```bash defuddle page.html ``` --- ## When to Use **Use defuddle when:** - Ingesting a news article, blog post, or documentation page from a URL - The page has a lot of surrounding content (most web pages do) - You want to stay within token budget on a long article **Skip defuddle when:** - The source is already a clean markdown or PDF file - The page is a dashboard, app, or structured data (defuddle expects article-style content) - defuddle is not installed and the article is short enough to process raw --- ## Fallback If defuddle is not installed, check: ```bash which defuddle 2>/dev/null || echo "not installed" ``` If not installed: use WebFetch directly. The content will be less clean but still workable. --- ## Integration with /wiki-ingest The `/wiki-ingest` skill checks for defuddle automatically when a URL is passed. You do not need to run defuddle manually before ingesting a URL. The ingest skill will call it if available. To manually clean a page and save before ingesting: 1. Run the save command above 2. Then: `ingest .raw/articles/[slug].md`.claude-plugin/marketplace.jsonmarketplaceShow content (1157 bytes)
{ "name": "claude-obsidian-marketplace", "owner": { "name": "AgriciDaniel", "url": "https://github.com/AgriciDaniel" }, "metadata": { "description": "claude-obsidian: Claude + Obsidian knowledge companion by AgriciDaniel", "version": "1.6.0" }, "plugins": [ { "name": "claude-obsidian", "source": { "source": "github", "repo": "AgriciDaniel/claude-obsidian", "ref": "main" }, "description": "Claude + Obsidian knowledge companion. Sets up a persistent, compounding wiki vault. Covers memory management, session notetaking, knowledge organization, and agent context across projects. Optional DragonScale Memory extension adds hierarchical log folds, deterministic page addresses, embedding-based semantic tiling lint, and boundary-first autoresearch topic selection.", "version": "1.6.0", "author": { "name": "AgriciDaniel", "url": "https://github.com/AgriciDaniel" }, "homepage": "https://github.com/AgriciDaniel/claude-obsidian", "repository": "https://github.com/AgriciDaniel/claude-obsidian", "license": "MIT" } ] }
README
claude-obsidian
Claude + Obsidian knowledge companion. A running notetaker that builds and maintains a persistent, compounding wiki vault. Every source you add gets integrated. Every question you ask pulls from everything that has been read. Knowledge compounds like interest.
Based on Andrej Karpathy's LLM Wiki pattern. 11 skills. Zero manual filing. Multi-agent support. Optional DragonScale Memory extension (log folds, deterministic page addresses, semantic tiling lint, boundary-first autoresearch).
What It Does
Youtube Demo
You drop sources. Claude reads them, extracts entities and concepts, updates cross-references, and files everything into a structured Obsidian vault. The wiki gets richer with every ingest.
You ask questions. Claude reads the hot cache (recent context), scans the index, drills into relevant pages, and synthesizes an answer. It cites specific wiki pages, not training data.
You lint. Claude finds orphans, dead links, stale claims, and missing cross-references. Your wiki stays healthy without manual cleanup.
At the end of every session, Claude updates a hot cache. The next session starts with full recent context, no recap needed.
Why claude-obsidian?
Most Obsidian AI plugins are chat interfaces - they answer questions about your existing notes. claude-obsidian is a knowledge engine - it creates, organizes, maintains, and evolves your notes autonomously.
| Capability | claude-obsidian | Smart Connections | Copilot |
|---|---|---|---|
| Auto-organize notes | Creates entities, concepts, cross-references | No | No |
| Contradiction flagging | [!contradiction] callouts with sources | No | No |
| Session memory | Hot cache persists between conversations | No | No |
| Vault maintenance | 8-category lint (orphans, dead links, gaps) | No | No |
| Autonomous research | 3-round web research with gap-filling | No | No |
| Multi-model support | Claude, Gemini, Codex, Cursor, Windsurf | Claude only | Multiple |
| Visual canvas | Via claude-canvas companion | No | No |
| Query with citations | Cites specific wiki pages | Cites similar notes | Cites notes |
| Batch ingestion | Parallel agents for multiple sources | No | No |
| Open source | MIT | MIT | Freemium |
Deep dive: I Turned Obsidian Into a Self-Organizing AI Brain - full breakdown with data visualizations, market context, and workflow demos.
Quick Start
Option 1: Clone as vault (recommended: full setup in 2 minutes)
git clone https://github.com/AgriciDaniel/claude-obsidian
cd claude-obsidian
bash bin/setup-vault.sh
Open the folder in Obsidian: Manage Vaults → Open folder as vault → select claude-obsidian/
Open Claude Code in the same folder. Type /wiki.
setup-vault.shconfiguresgraph.json(filter + colors),app.json(excludes plugin dirs), andappearance.json(enables CSS). Run it once before the first Obsidian open. You get the fully pre-configured graph view, color scheme, and wiki structure out of the box.
Option 2: Install as Claude Code plugin
Plugin installation is a two-step process in Claude Code. First add the marketplace catalog, then install the plugin from it.
# Step 1: add the marketplace
claude plugin marketplace add AgriciDaniel/claude-obsidian
# Step 2: install the plugin
claude plugin install claude-obsidian@claude-obsidian-marketplace
In any Claude Code session: /wiki. Claude walks you through vault setup.
To check it worked:
claude plugin list
Option 3: Add to an existing vault
Copy WIKI.md into your vault root. Paste into Claude:
Read WIKI.md in this project. Then:
1. Check if Obsidian is installed. If not, install it.
2. Check if the Local REST API plugin is running on port 27124.
3. Configure the MCP server.
4. Ask me ONE question: "What is this vault for?"
Then scaffold the full wiki structure.
Commands
| You say | Claude does |
|---|---|
/wiki | Setup check, scaffold, or continue where you left off |
ingest [file] | Read source, create 8-15 wiki pages, update index and log |
ingest all of these | Batch process multiple sources, then cross-reference |
what do you know about X? | Read index > relevant pages > synthesize answer |
/save | File the current conversation as a wiki note |
/save [name] | Save with a specific title (skips the naming question) |
/autoresearch [topic] | Run the autonomous research loop: search, fetch, synthesize, file |
/canvas | Open or create the visual canvas, list zones and nodes |
/canvas add image [path] | Add an image (URL or local path) to the canvas with auto-layout |
/canvas add text [content] | Add a markdown text card to the canvas |
/canvas add pdf [path] | Add a PDF document as a rendered preview node |
/canvas add note [page] | Pin a wiki page as a linked card on the canvas |
/canvas zone [name] | Add a new labeled zone to organize visual content |
/canvas from banana | Capture recently generated images onto the canvas |
lint the wiki | Health check: orphans, dead links, gaps, suggestions |
update hot cache | Refresh hot.md with latest context summary |
Want more? claude-canvas adds 12 templates, 6 layout algorithms, AI image generation, presentations, and full canvas orchestration. Install both — they complement each other.
Cross-Project Power Move
Point any Claude Code project at this vault. Add to that project's CLAUDE.md:
## Wiki Knowledge Base
Path: ~/path/to/vault
When you need context not already in this project:
1. Read wiki/hot.md first (recent context cache)
2. If not enough, read wiki/index.md
3. If you need domain details, read the relevant domain sub-index
4. Only then drill into specific wiki pages
Do NOT read the wiki for general coding questions or tasks unrelated to [domain].
Your executive assistant, coding projects, and content workflows all draw from the same knowledge base.
Six Wiki Modes
| Mode | Use when |
|---|---|
| A: Website | Sitemap, content audit, SEO wiki |
| B: GitHub | Codebase map, architecture wiki |
| C: Business | Project wiki, competitive intelligence |
| D: Personal | Second brain, goals, journal synthesis |
| E: Research | Papers, concepts, thesis |
| F: Book/Course | Chapter tracker, course notes |
Modes can be combined.
What Gets Created
A typical scaffold creates:
- Folder structure for your chosen mode
wiki/index.md: master catalogwiki/log.md: append-only operation logwiki/hot.md: recent context cachewiki/overview.md: executive summarywiki/meta/dashboard.base: Bases dashboard (primary, native Obsidian)wiki/meta/dashboard.md: Legacy Dataview dashboard (optional fallback)_templates/: Obsidian Templater templates for each note type.obsidian/snippets/vault-colors.css: color-coded file explorer- Vault
CLAUDE.md: auto-loaded project instructions
MCP Setup (Optional)
MCP lets Claude read and write vault notes directly without copy-paste.
Option A (REST API based):
- Install the Local REST API plugin in Obsidian
- Copy your API key
- Run:
claude mcp add-json obsidian-vault '{
"type": "stdio",
"command": "uvx",
"args": ["mcp-obsidian"],
"env": {
"OBSIDIAN_API_KEY": "your-key",
"OBSIDIAN_HOST": "127.0.0.1",
"OBSIDIAN_PORT": "27124",
"NODE_TLS_REJECT_UNAUTHORIZED": "0"
}
}' --scope user
Option B (filesystem based, no plugin needed):
claude mcp add-json obsidian-vault '{
"type": "stdio",
"command": "npx",
"args": ["-y", "@bitbonsai/mcpvault@latest", "/path/to/your/vault"]
}' --scope user
Plugins
Core Plugins (built into Obsidian: no install needed)
| Plugin | Purpose |
|---|---|
| Bases | Powers wiki/meta/dashboard.base: native database views. Available since Obsidian v1.9.10 (August 2025). Replaces Dataview for the primary dashboard. |
| Properties | Visual frontmatter editor |
| Backlinks, Outline, Graph view | Standard navigation |
Pre-installed Community Plugins (ship with this vault)
Enable in Settings → Community Plugins → enable:
| Plugin | Purpose | Notes |
|---|---|---|
| Calendar | Right-sidebar calendar with word count + task dots | Pre-installed |
| Thino | Quick memo capture panel | Pre-installed |
| Excalidraw | Freehand drawing canvas, annotate images | Pre-installed* |
| Banners | Notion-style header image via banner: frontmatter | Pre-installed |
* Excalidraw main.js (8MB) is downloaded automatically by setup-vault.sh. It is not tracked in git.
Also install from Community Plugins (not pre-installed)
| Plugin | Purpose |
|---|---|
| Templater | Auto-fills frontmatter from _templates/ |
| Obsidian Git | Auto-commits vault every 15 minutes |
| Dataview (optional/legacy) | Only needed for the legacy wiki/meta/dashboard.md queries. The primary dashboard now uses Bases. |
Also install the Obsidian Web Clipper browser extension. Sends web pages to .raw/ in one click.
CSS Snippets (auto-enabled by setup-vault.sh)
Three snippets ship with the vault and are enabled automatically:
| Snippet | Effect |
|---|---|
vault-colors | Color-codes wiki/ folders by type in the file explorer (blue = concepts, green = sources, purple = entities) |
ITS-Dataview-Cards | Turns Dataview TABLE queries into visual card grids: use ```dataviewjs with .cards class |
ITS-Image-Adjustments | Fine-grained image sizing in notes: append |100 to any image embed |
Banner Plugin
Add to any wiki page frontmatter:
banner: "_attachments/images/your-image.png"
banner_icon: "🧠"
The page renders a full-width header image in Obsidian. Works great for hub pages and overviews.
File Structure
claude-obsidian/
├── .claude-plugin/
│ ├── plugin.json # manifest
│ └── marketplace.json # distribution
├── skills/
│ ├── wiki/ # orchestrator + references (7 ref files)
│ ├── wiki-ingest/ # INGEST operation
│ ├── wiki-query/ # QUERY operation
│ ├── wiki-lint/ # LINT operation
│ ├── save/ # /save: file conversations to wiki
│ ├── autoresearch/ # /autoresearch: autonomous research loop
│ │ └── references/
│ │ └── program.md # configurable research objectives
│ └── canvas/ # /canvas: visual layer (images, PDFs, notes)
│ └── references/
│ └── canvas-spec.md # Obsidian canvas JSON format reference
├── agents/
│ ├── wiki-ingest.md # parallel ingestion agent
│ └── wiki-lint.md # health check agent
├── commands/
│ ├── wiki.md # /wiki bootstrap command
│ ├── save.md # /save command
│ ├── autoresearch.md # /autoresearch command
│ └── canvas.md # /canvas visual layer command
├── hooks/
│ └── hooks.json # SessionStart + Stop hot cache hooks
├── _templates/ # Obsidian Templater templates
├── wiki/
│ ├── Wiki Map.canvas # visual hub, central graph node
│ ├── canvases/ # welcome.canvas + main.canvas (visual demos)
│ ├── getting-started.md # onboarding walkthrough (inside the vault)
│ ├── concepts/ # seeded: LLM Wiki Pattern, Hot Cache, Compounding Knowledge
│ ├── entities/ # seeded: Andrej Karpathy
│ ├── sources/ # populated by your first ingest
│ └── meta/
│ ├── dashboard.base # Bases dashboard (primary)
│ └── dashboard.md # Legacy Dataview dashboard (optional)
├── .raw/ # source documents (hidden in Obsidian)
├── .obsidian/snippets/ # vault-colors.css (3-color scheme)
├── WIKI.md # full schema reference
├── CLAUDE.md # project instructions
└── README.md # this file
AutoResearch: program.md
The /autoresearch command is configurable. Edit skills/autoresearch/references/program.md to control:
- What sources to prefer (academic, official docs, news)
- Confidence scoring rules
- Max rounds and max pages per session
- Domain-specific constraints
The default program works for general research. Override it for your domain. A medical researcher would add "prefer PubMed". A business analyst would add "focus on market data and filings".
Seed Vault
This repo ships with a seeded vault. Open it in Obsidian and you'll see:
wiki/concepts/: LLM Wiki Pattern, Hot Cache, Compounding Knowledgewiki/entities/: Andrej Karpathywiki/sources/: empty until your first ingestwiki/meta/dashboard.base: Bases dashboard (works in any Obsidian v1.9.10+)wiki/meta/dashboard.md: Legacy Dataview dashboard (optional fallback)
The graph view will show a connected cluster of 5 pages. This is what the wiki looks like after one ingest. Add more sources and it grows from there.
Companion: claude-canvas
For the visual layer, claude-canvas adds AI-orchestrated canvas creation - knowledge graphs, presentations, flowcharts, mood boards with 12 templates and 6 layout algorithms. Auto-detects claude-obsidian vaults.
claude plugin install AgriciDaniel/claude-canvas
Community
- Blog post - deep dive with competitor analysis, data charts, and workflow demos
- AI Marketing Hub - 2,800+ members, free community
- YouTube - tutorials and demos
- All open-source tools - claude-seo, claude-ads, claude-blog, and more
Based on Andrej Karpathy's LLM Wiki pattern. Built by Agrici Daniel.