feat: v1.1 — URL ingestion, vision, delta tracking, 3 new skills, auto-commit
Skills (new): - skills/obsidian-markdown/ — full Obsidian Flavored Markdown syntax reference (wikilinks, embeds, callouts, properties, math, Mermaid) - skills/obsidian-bases/ — Obsidian Bases (.base files) with correct filters/views/ formulas syntax (sourced from kepano/obsidian-skills authoritative spec) - skills/defuddle/ — web page cleaner; strips ads/nav before URL ingestion, saves 40-60% tokens on web articles wiki-ingest upgrades: - URL ingestion: pass https:// directly, auto-fetches + runs defuddle if available - Image/vision ingestion: .png/.jpg/.gif etc → Claude reads → description saved to .raw/ → standard ingest pipeline - Delta tracking: .raw/.manifest.json tracks hash per source, skips unchanged files wiki-query upgrades: - Quick mode (query quick:) — hot.md + index only, ~1500 tokens - Standard mode — existing behaviour, 3-5 pages - Deep mode (query deep:) — full wiki + optional web search supplement hooks: - PostToolUse auto-commit: every Write/Edit to wiki/ or .raw/ triggers git add + commit automatically, vault always versioned fixes: - Removed invalid allowed-tools field from all 10 SKILL.md files (not a valid skill frontmatter attribute per spec; was silently ignored) - Canvas SKILL.md now references json-canvas open standard and kepano/obsidian-skills wiki research: - Ecosystem research: 16+ Claude+Obsidian projects mapped and filed - New pages: comparisons/claude-obsidian-ecosystem, concepts/cherry-picks, entities/ (6 new), sources/claude-obsidian-ecosystem-research - Cherry-picks roadmap filed at wiki/concepts/cherry-picks.md Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,7 +8,6 @@ description: >
|
||||
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", "WebSearch", "WebFetch", "Bash", "Glob", "Grep"]
|
||||
---
|
||||
|
||||
# autoresearch — Autonomous Research Loop
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
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", "Bash", "Glob"]
|
||||
---
|
||||
|
||||
# canvas — Visual Reference Layer
|
||||
@@ -11,7 +10,7 @@ The three knowledge capture layers:
|
||||
- `/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.
|
||||
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 `kepano/obsidian-skills` is installed, its `json-canvas` skill is the authoritative cross-platform reference.
|
||||
|
||||
---
|
||||
|
||||
|
||||
83
skills/defuddle/SKILL.md
Normal file
83
skills/defuddle/SKILL.md
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
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."
|
||||
---
|
||||
|
||||
# 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`
|
||||
292
skills/obsidian-bases/SKILL.md
Normal file
292
skills/obsidian-bases/SKILL.md
Normal file
@@ -0,0 +1,292 @@
|
||||
---
|
||||
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."
|
||||
---
|
||||
|
||||
# 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**: `kepano/obsidian-skills` publishes the canonical `obsidian-bases` skill with full syntax and function reference. Use this skill alongside that one. 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:`
|
||||
226
skills/obsidian-markdown/SKILL.md
Normal file
226
skills/obsidian-markdown/SKILL.md
Normal file
@@ -0,0 +1,226 @@
|
||||
---
|
||||
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."
|
||||
---
|
||||
|
||||
# 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**: `kepano/obsidian-skills` publishes the authoritative cross-platform version of this skill at [github.com/kepano/obsidian-skills](https://github.com/kepano/obsidian-skills). If installed, that skill is the canonical reference — use it alongside this one.
|
||||
|
||||
---
|
||||
|
||||
## Wikilinks
|
||||
|
||||
Internal links use double brackets. The filename without extension.
|
||||
|
||||
```markdown
|
||||
[[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.
|
||||
|
||||
```markdown
|
||||
![[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:
|
||||
|
||||
```markdown
|
||||
**bold** — bold
|
||||
*italic* — italic
|
||||
~~strikethrough~~ — strikethrough
|
||||
==highlight== — highlighted text (yellow in Obsidian)
|
||||
`inline code` — inline code
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Math
|
||||
|
||||
Obsidian uses MathJax/KaTeX:
|
||||
|
||||
```markdown
|
||||
$E = mc^2$ — inline math
|
||||
|
||||
$$
|
||||
\int_0^\infty e^{-x} dx = 1
|
||||
$$ — block math
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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`.
|
||||
@@ -7,7 +7,6 @@ description: >
|
||||
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", "Bash", "Glob"]
|
||||
---
|
||||
|
||||
# save — File Conversations Into the Wiki
|
||||
|
||||
@@ -1,17 +1,97 @@
|
||||
---
|
||||
name: wiki-ingest
|
||||
description: >
|
||||
Ingest sources into the Obsidian wiki vault. Reads a source, extracts entities
|
||||
and concepts, creates or updates wiki pages, cross-references, and logs the operation.
|
||||
Supports single sources and batch mode. Triggers on: "ingest", "process this source",
|
||||
"add this to the wiki", "read and file this", "batch ingest", "ingest all of these".
|
||||
allowed-tools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]
|
||||
description: "Ingest sources into the Obsidian wiki vault. Reads a source, extracts entities and concepts, creates or updates wiki pages, cross-references, and logs the operation. Supports files, URLs, and batch mode. Triggers on: ingest, process this source, add this to the wiki, read and file this, batch ingest, ingest all of these, ingest this url."
|
||||
---
|
||||
|
||||
# wiki-ingest — Source Ingestion
|
||||
|
||||
Read the source. Write the wiki. Cross-reference everything. A single source typically touches 8-15 wiki pages.
|
||||
|
||||
**Syntax standard**: Write all Obsidian Markdown using proper Obsidian Flavored Markdown — wikilinks as `[[Note Name]]`, callouts as `> [!type] Title`, embeds as `![[file]]`, properties as YAML frontmatter. If kepano/obsidian-skills is installed, its `obsidian-markdown` skill is the authoritative syntax reference.
|
||||
|
||||
---
|
||||
|
||||
## Delta Tracking
|
||||
|
||||
Before ingesting any file, check `.raw/.manifest.json` to avoid re-processing unchanged sources.
|
||||
|
||||
```bash
|
||||
# Check if manifest exists
|
||||
[ -f .raw/.manifest.json ] && echo "exists" || echo "no manifest yet"
|
||||
```
|
||||
|
||||
**Manifest format** (create if missing):
|
||||
```json
|
||||
{
|
||||
"sources": {
|
||||
".raw/articles/article-slug-2026-04-08.md": {
|
||||
"hash": "abc123",
|
||||
"ingested_at": "2026-04-08",
|
||||
"pages_created": ["wiki/sources/article-slug.md", "wiki/entities/Person.md"],
|
||||
"pages_updated": ["wiki/index.md"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Before ingesting a file:**
|
||||
1. Compute a hash: `md5sum [file] | cut -d' ' -f1` (or `sha256sum` on Linux).
|
||||
2. Check if the path exists in `.manifest.json` with the same hash.
|
||||
3. If hash matches — skip. Report: "Already ingested (unchanged). Use `force` to re-ingest."
|
||||
4. If missing or hash differs — proceed with ingest.
|
||||
|
||||
**After ingesting a file:**
|
||||
1. Record `{hash, ingested_at, pages_created, pages_updated}` in `.manifest.json`.
|
||||
2. Write the updated manifest back.
|
||||
|
||||
Skip delta checking if the user says "force ingest" or "re-ingest".
|
||||
|
||||
---
|
||||
|
||||
## URL Ingestion
|
||||
|
||||
Trigger: user passes a URL starting with `https://`.
|
||||
|
||||
Steps:
|
||||
|
||||
1. **Fetch** the page using WebFetch.
|
||||
2. **Clean** (optional): if `defuddle` is available (`which defuddle 2>/dev/null`), run `defuddle [url]` to strip ads, nav, and clutter — typically saves 40-60% tokens. Fall back to raw WebFetch output if not installed.
|
||||
3. **Derive slug** from the URL path (last segment, lowercased, spaces→hyphens, strip query strings).
|
||||
4. **Save** to `.raw/articles/[slug]-[YYYY-MM-DD].md` with a frontmatter header:
|
||||
```markdown
|
||||
---
|
||||
source_url: [url]
|
||||
fetched: [YYYY-MM-DD]
|
||||
---
|
||||
```
|
||||
5. Proceed with **Single Source Ingest** starting at step 2 (file is now in `.raw/`).
|
||||
|
||||
---
|
||||
|
||||
## Image / Vision Ingestion
|
||||
|
||||
Trigger: user passes an image file path (`.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`, `.svg`, `.avif`).
|
||||
|
||||
Steps:
|
||||
|
||||
1. **Read** the image file using the Read tool — Claude can process images natively.
|
||||
2. **Describe** the image contents: extract all text (OCR), identify key concepts, entities, diagrams, and data visible in the image.
|
||||
3. **Save** the description to `.raw/images/[slug]-[YYYY-MM-DD].md`:
|
||||
```markdown
|
||||
---
|
||||
source_type: image
|
||||
original_file: [original path]
|
||||
fetched: YYYY-MM-DD
|
||||
---
|
||||
# Image: [slug]
|
||||
|
||||
[Full description of image contents, transcribed text, entities visible, etc.]
|
||||
```
|
||||
4. Copy the image to `_attachments/images/[slug].[ext]` if it's not already in the vault.
|
||||
5. Proceed with **Single Source Ingest** on the saved description file.
|
||||
|
||||
Use cases: whiteboard photos, screenshots, diagrams, infographics, document scans.
|
||||
|
||||
---
|
||||
|
||||
## Single Source Ingest
|
||||
|
||||
@@ -5,7 +5,6 @@ description: >
|
||||
missing cross-references, frontmatter gaps, and empty sections. Creates or updates
|
||||
Dataview dashboards. Generates canvas maps. Triggers on: "lint", "health check",
|
||||
"clean up wiki", "check the wiki", "wiki maintenance", "find orphans", "wiki audit".
|
||||
allowed-tools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]
|
||||
---
|
||||
|
||||
# wiki-lint — Wiki Health Check
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
---
|
||||
name: wiki-query
|
||||
description: >
|
||||
Answer questions using the Obsidian wiki vault. Reads hot cache first, then index,
|
||||
then relevant pages. Synthesizes answers with citations. Files good answers back
|
||||
as wiki pages. Triggers on: "what do you know about", "query:", "what is", "explain",
|
||||
"summarize", "find in wiki", "search the wiki", "based on the wiki".
|
||||
allowed-tools: ["Read", "Write", "Bash", "Glob", "Grep"]
|
||||
description: "Answer questions using the Obsidian wiki vault. Reads hot cache first, then index, then relevant pages. Synthesizes answers with citations. Files good answers back as wiki pages. Supports quick, standard, and deep modes. Triggers on: what do you know about, query:, what is, explain, summarize, find in wiki, search the wiki, based on the wiki, wiki query quick, wiki query deep."
|
||||
---
|
||||
|
||||
# wiki-query — Query the Wiki
|
||||
@@ -14,7 +9,32 @@ The wiki has already done the synthesis work. Read strategically, answer precise
|
||||
|
||||
---
|
||||
|
||||
## Query Workflow
|
||||
## Query Modes
|
||||
|
||||
Three depths. Choose based on the question complexity.
|
||||
|
||||
| Mode | Trigger | Reads | Token cost | Best for |
|
||||
|------|---------|-------|------------|---------|
|
||||
| **Quick** | `query quick: ...` or simple factual Q | hot.md + index.md only | ~1,500 | "What is X?", date lookups, quick facts |
|
||||
| **Standard** | default (no flag) | hot.md + index + 3-5 pages | ~3,000 | Most questions |
|
||||
| **Deep** | `query deep: ...` or "thorough", "comprehensive" | Full wiki + optional web | ~8,000+ | "Compare A vs B across everything", synthesis, gap analysis |
|
||||
|
||||
---
|
||||
|
||||
## Quick Mode
|
||||
|
||||
Use when the answer is likely in the hot cache or index summary.
|
||||
|
||||
1. Read `wiki/hot.md`. If it answers the question — respond immediately.
|
||||
2. If not: read `wiki/index.md`. Scan descriptions for the answer.
|
||||
3. If found in index summary — respond. Do not open any pages.
|
||||
4. If not found — say "Not in quick cache. Run as standard query?"
|
||||
|
||||
Do not open individual wiki pages in quick mode.
|
||||
|
||||
---
|
||||
|
||||
## Standard Query Workflow
|
||||
|
||||
1. **Read** `wiki/hot.md` first. It may already have the answer or directly relevant context.
|
||||
2. **Read** `wiki/index.md` to find the most relevant pages (scan for titles and descriptions).
|
||||
@@ -25,6 +45,19 @@ The wiki has already done the synthesis work. Read strategically, answer precise
|
||||
|
||||
---
|
||||
|
||||
## Deep Mode
|
||||
|
||||
Use for synthesis questions, comparisons, or "tell me everything about X."
|
||||
|
||||
1. Read `wiki/hot.md` and `wiki/index.md`.
|
||||
2. Identify all relevant sections (concepts, entities, sources, comparisons).
|
||||
3. Read every relevant page — no skipping.
|
||||
4. If wiki coverage is thin, offer to supplement with web search.
|
||||
5. Synthesize a comprehensive answer with full citations.
|
||||
6. Always file the result back as a wiki page — deep answers are too valuable to lose.
|
||||
|
||||
---
|
||||
|
||||
## Token Discipline
|
||||
|
||||
Read the minimum needed:
|
||||
|
||||
@@ -7,7 +7,6 @@ description: >
|
||||
Triggers on: "set up wiki", "scaffold vault", "create knowledge base", "/wiki",
|
||||
"wiki setup", "obsidian vault", "knowledge base", "second brain setup",
|
||||
"running notetaker", "persistent memory", "llm wiki".
|
||||
allowed-tools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]
|
||||
---
|
||||
|
||||
# wiki — Claude + Obsidian Knowledge Companion
|
||||
|
||||
Reference in New Issue
Block a user