canvas
Skill0 starsChanged 3 months agoMITView on GitHub
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.
47 other projects use a version of this, 1 of them edited.
Adopted by
Most recently taken up by
- tboome33/obsidian-mcp-routertheir own version, first seen Nov 15, 2026
- arbrain-ai/arbraintheir own version, first seen Nov 15, 2026
- insight68/Skillstheir own version, first seen Nov 8, 2026
- iblai/higher-education-agentstheir own version, first seen Nov 8, 2026
- QVerisAI/QVerisBottheir own version, first seen Nov 1, 2026
- AgriciDaniel/claude-obsidiantheir own version, first seen Oct 25, 2026
Used with
Projects with it also use taskflow-inbox-triage, update-cli-config and 10 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
AtomicBot-aiSkilltaskflow-inbox-triage
Also in 5 projects that use this
PandelisZSkillupdate-cli-config
View and modify Cursor CLI configuration settings in ~/.cursor/cli-config.json. Use when the user wants to change CLI settings, configure permissions, switch approval mode, enable vim mode, toggle display options, configure sandbox, or manage any CLI preferences.
Also in 6 projects that use this
jiulingyunSkillBlueBubbles
为Clawdbot构建或更新BlueBubbles外部通道插件(扩展包,REST发送/探测,webhook入站)。
Also in 15 projects that use this
seedprodSkillvoice-call
Start voice calls via the OpenClaw voice-call plugin.
Also in 14 projects that use this
32103210Skillmigrate-to-skills
Convert 'Applied intelligently' Cursor rules (.cursor/rules/*.mdc) and slash commands (.cursor/commands/*.md) to Agent Skills format (.cursor/skills/). Use when you want to migrate rules or commands to skills, convert .mdc rules to SKILL.md format, or consolidate commands into the skills directory.
Also in 6 projects that use this
32103210Skillupdate-cursor-settings
Modify Cursor/VSCode user settings in settings.json. Use when you want to change editor settings, preferences, configuration, themes, font size, tab size, format on save, auto save, keybindings, or any settings.json values.
Also in 6 projects that use this
- +1 more from 32103210
Other versions47 projects use a version of this.
Word for word · 0
None found.
Edited · 1
- CarbeneAI/Forge★ 998% same
Wrote their own version · 46
- AgriciDaniel/claude-obsidian★ 16ksame name
- spinabot/brigade★ 11ksame name
- the-open-agent/openagent★ 5.7ksame name
- casibase/casibase★ 5.7ksame name
- linuxhsj/openclaw-zero-token★ 5.2ksame name
- jiulingyun/openclaw-cn★ 4.7ksame name
- Bitterbot-AI/bitterbot-desktop★ 2.5ksame name
- phodal/routa★ 1.8ksame name
- OpenBMB/EdgeClaw★ 1.2ksame name
- microsoft/vscode-dotnettools★ 331same name
36 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository18 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- .cursor/rules/maz-works-knowledge-vault.mdcCursor rule
- autoresearchSkill
- defuddleSkill
- obsidian-basesSkill
- obsidian-markdownSkill
- saveSkill
- thinkSkill
- wiki-cliSkill
- wiki-foldSkill
- wiki-ingestSkill
- wiki-lintSkill
- wiki-modeSkill
- wiki-querySkill
- wiki-retrieveSkill
- wikiSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
32 rules. 0 are common, 12 are distinctive, and 20 are very specific to this project.
0
Common
Most of the 44 edited versions we read keep these.
12
Distinctive
This author's own choices. Worth a look.
20
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 24
If it does not exist, create it:
- Very specific: line 52
Check if wiki/canvases/main.canvas exists.
- Distinctive: line 53
If yes: read it, count nodes by type, list all group node labels (zone names).
- Distinctive: line 55
If no: create it with the starter structure above.
- Very specific: line 64
Create wiki/canvases/[slug].canvas with the starter structure, title updated to # [Name].
- Very specific: line 65
Add entry to wiki/overview.md under a "## Canvases" subsection (append after the Current State section).
- Very specific: line 73
If URL (starts with http): download with curl -sL [url] -o _attachments/images/canvas/[filename] Derive filename from URL path, or use …
- Very specific: line 75
If local path outside vault: cp [path] _attachments/images/canvas/
- Distinctive: line 76
If already vault-relative: use as-is.
- Very specific: line 78
Create _attachments/images/canvas/ if it doesn't exist.
- Very specific: line 81
Use python3 -c "from PIL import Image.
- Distinctive: line 94
Create a text node:
- Very specific: line 121
Search wiki/ for a file matching the page name (case-insensitive, partial match ok).
- Very specific: line 122
Use the vault-relative path as the file field.
- Very specific: line 123
Use "type": "file" (not "type": "link"): .md files use file nodes, not link nodes.
- Distinctive: line 125
Create a file node: width=300, height=100.
- Distinctive: line 144
Create a group node:
- Very specific: line 180
Check wiki/canvases/.recent-images.txt first (session log of newly written images).
- Very specific: line 181
If not found or empty: use find with correct precedence (parentheses required.
- Distinctive: line 187
If still none: show the 5 most recently modified images.
- Very specific: line 195
Read references/canvas-spec.md for the full coordinate system.
- Distinctive: line 238
Read the canvas, collect all existing IDs.
- Distinctive: line 242
Use the full Unix timestamp (10 digits) to avoid collisions in batch operations.
- Very specific: line 246
If a collision is detected (ID already exists in the canvas), append -2, -3, etc.
- Very specific: line 252
If wiki/canvases/.recent-images.txt exists, append any new image path written to _attachments/images/ during this session (one path per …
- Very specific: line 260
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.
- Very specific: line 262
When /banana finishes generating images, suggest:
- Distinctive: line 269
Read canvas-spec.md before editing any canvas JSON.
- Distinctive: line 270
Always read the canvas file before writing.
- Very specific: line 271
Create _attachments/images/canvas/ for downloaded/copied images.
- Very specific: line 272
Update wiki/index.md when creating new canvases.
- Very specific: line 286
When working on this skill, apply the 10-principle loop.
“Common” is measured: kept by at least 6 in 10 of the 44 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
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.
Substrate preference (v1.7+): This skill is a self-contained fallback. Prefer kepano/obsidian-skills as the authoritative substrate — its json-canvas skill is the canonical spec reference. If a separate json-canvas skill is available, use it for spec questions. Continue to use this canvas skill for Maz Works vault workflows such as positioning into wiki/canvases/, image integration, and zone layout. Install kepano with claude plugin marketplace add kepano/obsidian-skills.
Default Canvas
wiki/canvases/main.canvas
If it does not exist, create it:
{
"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)
- Check if
wiki/canvases/main.canvasexists. - 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]"
- If no: create it with the starter structure above. Report: "Created main.canvas with a General zone."
- Tell user: "Open
wiki/canvases/main.canvasin Obsidian to view."
new (/canvas new [name])
- Slugify the name: lowercase, spaces → hyphens, strip special chars.
- Create
wiki/canvases/[slug].canvaswith the starter structure, title updated to# [Name]. - Add entry to
wiki/overview.mdunder a "## Canvases" subsection (append after the Current State section). Do not modifywiki/index.md. It uses a fixed section schema (Domains, Entities, Concepts, Sources, Questions, Comparisons). - Report: "Created wiki/canvases/[slug].canvas"
add image (/canvas add image [path or url])
Resolve the image:
- If URL (starts with
http): download withcurl -sL [url] -o _attachments/images/canvas/[filename]Derive filename from URL path, or useimg-[timestamp].jpgif 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:
{
"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])
- Search
wiki/for a file matching the page name (case-insensitive, partial match ok). - Use the vault-relative path as the
filefield.- Use
"type": "file"(not"type": "link"):.mdfiles use file nodes, not link nodes. "type": "link"takes aurl: "https://...": it is for web URLs only.
- Use
- Create a file node: width=300, height=100.
- Position using auto-layout.
{
"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])
- Read canvas JSON.
- Find max_y:
max(node.y + node.height for all nodes) + 60. Use 280 if no nodes (leaves room above the starter title node). - Create a group node:
{
"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)
glob wiki/canvases/*.canvas- For each canvas: read JSON, count nodes by type.
- 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)
- Check
wiki/canvases/.recent-images.txtfirst (session log of newly written images). - If not found or empty: use
findwith correct precedence (parentheses required. Without them-neweronly binds to the last-nameclause):
Note: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" \)/bananais an optional external skill not shipped in this plugin. If the user has it installed, the.recent-images.txtlog will be populated. If not, thefindcommand above is the fallback. - If still none: show the 5 most recently modified images.
- Present list: "Found N recent images: [list]. Add to canvas? Which zone? (zone name / 'new [name]' / 'skip')"
- On confirmation: add each using the add image logic.
Auto-Positioning Algorithm
Read references/canvas-spec.md for the full coordinate system.
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_yID 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
- Read canvas-spec.md before editing any canvas JSON.
- Always read the canvas file before writing. Parse existing nodes to avoid ID collisions and calculate auto-positions.
- Create
_attachments/images/canvas/for downloaded/copied images. - Update
wiki/index.mdwhen creating new canvases. - 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. This skill handles wiki-scoped visual boards. claude-canvas handles full-featured canvas orchestration for any project.
How to think (10-principle mapping)
When working on this skill, apply the 10-principle loop. See skills/think/SKILL.md for the canonical framework.
| # | Principle | Application here |
| 1 | OBSERVE (ext) | Which images, PDFs, notes belong on this canvas? Read each before adding. |
| 2 | OBSERVE (int) | Am I aestheticizing or actually communicating? Pretty canvases that don't inform are noise. |
| 3 | LISTEN | The user's mental model of how these items relate. The canvas should mirror that, not impose another. |
| 4 | THINK | Layout, group hierarchy, edge structure. Spatial reasoning matters; arbitrary positions confuse. |
| 5 | CONNECT (lat) | Edges between canvas nodes reveal hidden structure not visible in the linear wiki. |
| 6 | CONNECT (sys) | JSON Canvas 1.0 spec + Obsidian-native rendering + banana skill for AI image gen. |
| 7 | FEEL | A canvas should be readable at first glance, not a maze of arrows. |
| 8 | ACCEPT | Not every project needs a canvas. Admit when prose is enough. |
| 9 | CREATE | Write the .canvas JSON with stable IDs and sensible positions. |
| 10 | GROW | Which canvases get reopened? Which are abandoned? That signal informs canvas-worthiness over time. |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

