mercury-agent 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +438 -0
- package/container/Dockerfile +127 -0
- package/container/Dockerfile.base +109 -0
- package/container/Dockerfile.power +17 -0
- package/container/agent-package.json +8 -0
- package/container/build.sh +54 -0
- package/docs/TODOS.md +147 -0
- package/docs/auth/dashboard.md +28 -0
- package/docs/auth/overview.md +109 -0
- package/docs/auth/whatsapp.md +173 -0
- package/docs/configuration.md +54 -0
- package/docs/container-lifecycle.md +349 -0
- package/docs/context-architecture.md +87 -0
- package/docs/deployment.md +199 -0
- package/docs/extensions.md +375 -0
- package/docs/graceful-shutdown.md +62 -0
- package/docs/kb-distillation.md +77 -0
- package/docs/media/overview.md +140 -0
- package/docs/media/whatsapp.md +171 -0
- package/docs/memory.md +137 -0
- package/docs/permissions.md +217 -0
- package/docs/pipeline.md +228 -0
- package/docs/prd-chat-memory.md +76 -0
- package/docs/prd-config-load.md +82 -0
- package/docs/rate-limiting.md +166 -0
- package/docs/scheduler.md +288 -0
- package/docs/setup-discord.md +100 -0
- package/docs/setup-slack.md +119 -0
- package/docs/setup-whatsapp.md +94 -0
- package/docs/subagents.md +166 -0
- package/docs/web-search.md +62 -0
- package/examples/extensions/README.md +12 -0
- package/examples/extensions/charts/index.ts +13 -0
- package/examples/extensions/charts/skill/SKILL.md +98 -0
- package/examples/extensions/gws/README.md +52 -0
- package/examples/extensions/gws/index.ts +106 -0
- package/examples/extensions/gws/skill/SKILL.md +57 -0
- package/examples/extensions/gws/skill/references/calendar.md +101 -0
- package/examples/extensions/gws/skill/references/docs.md +65 -0
- package/examples/extensions/gws/skill/references/drive.md +79 -0
- package/examples/extensions/gws/skill/references/gmail.md +85 -0
- package/examples/extensions/gws/skill/references/sheets.md +60 -0
- package/examples/extensions/napkin/index.ts +821 -0
- package/examples/extensions/napkin/prompts/consolidation-monthly.md +73 -0
- package/examples/extensions/napkin/prompts/consolidation-weekly.md +67 -0
- package/examples/extensions/napkin/prompts/kb-distillation.md +176 -0
- package/examples/extensions/napkin/skill/SKILL.md +728 -0
- package/examples/extensions/pdf/index.ts +23 -0
- package/examples/extensions/pdf/skill/LICENSE.txt +30 -0
- package/examples/extensions/pdf/skill/SKILL.md +314 -0
- package/examples/extensions/pdf/skill/forms.md +294 -0
- package/examples/extensions/pdf/skill/reference.md +612 -0
- package/examples/extensions/pdf/skill/scripts/check_bounding_boxes.py +65 -0
- package/examples/extensions/pdf/skill/scripts/check_fillable_fields.py +11 -0
- package/examples/extensions/pdf/skill/scripts/convert_pdf_to_images.py +33 -0
- package/examples/extensions/pdf/skill/scripts/create_validation_image.py +37 -0
- package/examples/extensions/pdf/skill/scripts/extract_form_field_info.py +122 -0
- package/examples/extensions/pdf/skill/scripts/extract_form_structure.py +115 -0
- package/examples/extensions/pdf/skill/scripts/fill_fillable_fields.py +98 -0
- package/examples/extensions/pdf/skill/scripts/fill_pdf_form_with_annotations.py +107 -0
- package/examples/extensions/permission-guard/index.ts +65 -0
- package/examples/extensions/pinchtab/index.ts +199 -0
- package/examples/extensions/pinchtab/lib/session-injector.ts +144 -0
- package/examples/extensions/pinchtab/skill/SKILL.md +224 -0
- package/examples/extensions/pinchtab/skill/TRUST.md +69 -0
- package/examples/extensions/pinchtab/skill/references/api.md +297 -0
- package/examples/extensions/pinchtab/skill/references/env.md +45 -0
- package/examples/extensions/pinchtab/skill/references/profiles.md +107 -0
- package/examples/extensions/tradestation/host/refresh.ts +102 -0
- package/examples/extensions/tradestation/index.ts +153 -0
- package/examples/extensions/tradestation/skill/SKILL.md +67 -0
- package/examples/extensions/tradestation/skill/scripts/ts-cli.ts +111 -0
- package/examples/extensions/voice-synth/index.ts +94 -0
- package/examples/extensions/voice-synth/skill/SKILL.md +38 -0
- package/examples/extensions/voice-transcribe/index.ts +381 -0
- package/examples/extensions/voice-transcribe/requirements.txt +8 -0
- package/examples/extensions/voice-transcribe/scripts/transcribe.py +179 -0
- package/examples/extensions/voice-transcribe/skill/SKILL.md +53 -0
- package/examples/extensions/web-search/index.ts +22 -0
- package/examples/extensions/web-search/skill/SKILL.md +114 -0
- package/examples/extensions/web-search/skill/references/apartments.md +178 -0
- package/examples/extensions/web-search/skill/references/car-purchase.md +132 -0
- package/examples/extensions/web-search/skill/references/car-rental.md +113 -0
- package/examples/extensions/web-search/skill/references/flights.md +133 -0
- package/examples/extensions/web-search/skill/references/hotels.md +148 -0
- package/examples/extensions/yahoo-mail/cli/bun.lock +66 -0
- package/examples/extensions/yahoo-mail/cli/package.json +13 -0
- package/examples/extensions/yahoo-mail/cli/ymail.mjs +353 -0
- package/examples/extensions/yahoo-mail/index.ts +57 -0
- package/examples/extensions/yahoo-mail/skill/SKILL.md +78 -0
- package/package.json +106 -0
- package/resources/agents/explore.md +50 -0
- package/resources/agents/worker.md +24 -0
- package/resources/builtin-extensions.txt +3 -0
- package/resources/connection-env-vars.json +25 -0
- package/resources/extensions/.gitkeep +0 -0
- package/resources/pi-extensions/subagent/agents.ts +126 -0
- package/resources/pi-extensions/subagent/index.ts +964 -0
- package/resources/profiles/coding/AGENTS.md +43 -0
- package/resources/profiles/coding/mercury-profile.yaml +15 -0
- package/resources/profiles/general/AGENTS.md +31 -0
- package/resources/profiles/general/mercury-profile.yaml +15 -0
- package/resources/profiles/research/AGENTS.md +40 -0
- package/resources/profiles/research/mercury-profile.yaml +15 -0
- package/resources/skills/config/SKILL.md +25 -0
- package/resources/skills/context/SKILL.md +33 -0
- package/resources/skills/conversation-recap/SKILL.md +19 -0
- package/resources/skills/media/SKILL.md +27 -0
- package/resources/skills/mutes/SKILL.md +31 -0
- package/resources/skills/permissions/SKILL.md +19 -0
- package/resources/skills/preferences/SKILL.md +31 -0
- package/resources/skills/recall/SKILL.md +24 -0
- package/resources/skills/roles/SKILL.md +18 -0
- package/resources/skills/spaces/SKILL.md +18 -0
- package/resources/skills/tasks/SKILL.md +45 -0
- package/resources/templates/AGENTS.md +157 -0
- package/resources/templates/env.template +34 -0
- package/resources/templates/mercury.example.yaml +75 -0
- package/src/adapters/discord-native.ts +534 -0
- package/src/adapters/discord.ts +38 -0
- package/src/adapters/setup.ts +89 -0
- package/src/adapters/slack.ts +9 -0
- package/src/adapters/whatsapp-media.ts +337 -0
- package/src/adapters/whatsapp.ts +629 -0
- package/src/agent/api-socket.ts +127 -0
- package/src/agent/container-entry.ts +967 -0
- package/src/agent/container-error.ts +49 -0
- package/src/agent/container-runner.ts +1272 -0
- package/src/agent/model-capabilities-core.ts +23 -0
- package/src/agent/model-capabilities.ts +231 -0
- package/src/agent/pi-failure-class.ts +83 -0
- package/src/agent/pi-jsonl-parser.ts +306 -0
- package/src/agent/preferences-prompt.ts +20 -0
- package/src/agent/user-error-messages.ts +78 -0
- package/src/bridges/discord.ts +171 -0
- package/src/bridges/slack.ts +177 -0
- package/src/bridges/teams.ts +160 -0
- package/src/bridges/telegram.ts +571 -0
- package/src/bridges/whatsapp.ts +290 -0
- package/src/chat-shim.ts +259 -0
- package/src/cli/mercury.ts +2508 -0
- package/src/cli/mrctl-http.ts +27 -0
- package/src/cli/mrctl.ts +611 -0
- package/src/cli/whatsapp-auth.ts +260 -0
- package/src/config-file.ts +397 -0
- package/src/config-model-chain.ts +30 -0
- package/src/config.ts +316 -0
- package/src/core/api-types.ts +58 -0
- package/src/core/api.ts +105 -0
- package/src/core/commands.ts +76 -0
- package/src/core/conversation.ts +47 -0
- package/src/core/handler.ts +206 -0
- package/src/core/media.ts +200 -0
- package/src/core/mute-duration.ts +22 -0
- package/src/core/outbox.ts +76 -0
- package/src/core/permissions.ts +192 -0
- package/src/core/profiles.ts +245 -0
- package/src/core/rate-limiter.ts +127 -0
- package/src/core/router.ts +191 -0
- package/src/core/routes/chat.ts +172 -0
- package/src/core/routes/config-builtin.ts +107 -0
- package/src/core/routes/config.ts +81 -0
- package/src/core/routes/connections.ts +190 -0
- package/src/core/routes/console.ts +668 -0
- package/src/core/routes/control.ts +46 -0
- package/src/core/routes/conversations.ts +66 -0
- package/src/core/routes/dashboard.ts +2491 -0
- package/src/core/routes/extensions.ts +37 -0
- package/src/core/routes/index.ts +14 -0
- package/src/core/routes/media.ts +72 -0
- package/src/core/routes/messages.ts +37 -0
- package/src/core/routes/mutes.ts +89 -0
- package/src/core/routes/prefs.ts +95 -0
- package/src/core/routes/roles.ts +125 -0
- package/src/core/routes/spaces.ts +60 -0
- package/src/core/routes/storage.ts +126 -0
- package/src/core/routes/tasks.ts +189 -0
- package/src/core/routes/tradestation.ts +268 -0
- package/src/core/routes/tts.ts +51 -0
- package/src/core/runtime.ts +1140 -0
- package/src/core/space-queue.ts +103 -0
- package/src/core/storage-cleanup.ts +140 -0
- package/src/core/storage-guard.ts +24 -0
- package/src/core/task-scheduler.ts +132 -0
- package/src/core/telegram-format.ts +178 -0
- package/src/core/trigger.ts +142 -0
- package/src/dashboard/index.html +729 -0
- package/src/dashboard/tokens.css +53 -0
- package/src/extensions/api.ts +252 -0
- package/src/extensions/catalog.ts +117 -0
- package/src/extensions/config-registry.ts +83 -0
- package/src/extensions/context.ts +36 -0
- package/src/extensions/hooks.ts +156 -0
- package/src/extensions/image-builder.ts +617 -0
- package/src/extensions/installer.ts +306 -0
- package/src/extensions/jobs.ts +122 -0
- package/src/extensions/loader.ts +271 -0
- package/src/extensions/permission-guard.ts +52 -0
- package/src/extensions/reserved.ts +28 -0
- package/src/extensions/skills.ts +123 -0
- package/src/extensions/types.ts +462 -0
- package/src/logger.ts +174 -0
- package/src/main.ts +586 -0
- package/src/server.ts +391 -0
- package/src/storage/db.ts +1624 -0
- package/src/storage/memory.ts +45 -0
- package/src/storage/pi-auth.ts +95 -0
- package/src/text/markdown.ts +117 -0
- package/src/text/rtl.ts +38 -0
- package/src/tradestation/host-api.ts +77 -0
- package/src/tradestation/pending-orders.ts +69 -0
- package/src/tts/azure.ts +52 -0
- package/src/tts/google.ts +128 -0
- package/src/tts/index.ts +8 -0
- package/src/tts/language.ts +20 -0
- package/src/tts/synthesize.ts +133 -0
- package/src/types.ts +295 -0
|
@@ -0,0 +1,728 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: napkin
|
|
3
|
+
description: Read, create, search, and manage notes in Obsidian vaults using the napkin CLI. Works directly on markdown files and canvas files — no Obsidian app required. Use when the user asks to interact with their Obsidian vault, manage notes, search vault content, work with tasks, tags, properties, daily notes, templates, bases, bookmarks, aliases, or canvas files from the command line.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# napkin
|
|
7
|
+
|
|
8
|
+
CLI for Obsidian vaults. Operates directly on markdown files — no Obsidian app, no Electron, no Catalyst license.
|
|
9
|
+
|
|
10
|
+
Install: `npm install -g napkin-ai`
|
|
11
|
+
|
|
12
|
+
**IMPORTANT**: Always pass `--vault $NAPKIN_VAULT` to every napkin command. The vault lives in the `knowledge/` subdirectory, not the workspace root.
|
|
13
|
+
|
|
14
|
+
## Reading this vault's memory notes
|
|
15
|
+
|
|
16
|
+
This vault is maintained by an automatic distillation loop. Entity notes (under `people/`, `projects/`, `references/`) follow a temporal convention — read them this way:
|
|
17
|
+
|
|
18
|
+
- **`NAPKIN.md`** is the map of the vault. Start here for a quick overview of who and what is remembered.
|
|
19
|
+
- **Frontmatter + `## Current View`** hold the **authoritative present value** of every fact. When the user asks "what is X now?", answer from here.
|
|
20
|
+
- **`## History`** is append-only past context. A bullet ending with `*(superseded YYYY-MM-DD — reason)*` is an **old** value that has been replaced — never quote it as current. Use History only to answer "what did X used to think / when did this change?".
|
|
21
|
+
|
|
22
|
+
One file per entity, one directory per category — a person is always a file inside `people/`, never a section in a flat `people.md`.
|
|
23
|
+
|
|
24
|
+
### Episodes (`episodes/`)
|
|
25
|
+
|
|
26
|
+
Episodes are **time-bounded events or topics** — distinct from entity files which capture permanent knowledge. An episode tracks a developing situation (a market event, a personal search, a conflict) that starts, heats up, and eventually resolves or fades.
|
|
27
|
+
|
|
28
|
+
- Episodes may appear in your context as `<active_episodes>` XML — these are automatically injected when the user's message is relevant.
|
|
29
|
+
- You can **create** episodes during conversation using the `write` tool: `write episodes/car-search.md` with the episode frontmatter format (type, status, started, last_mentioned, mentions, keywords, summary).
|
|
30
|
+
- You can **resolve** episodes when the user indicates closure: set `status: resolved` in the frontmatter.
|
|
31
|
+
- Episode `status` values: `active` (current), `cooling` (not mentioned recently — set by consolidation, not by you), `resolved` (explicitly closed), `faded` (long-dormant — set by consolidation).
|
|
32
|
+
- `## History` in episodes is append-only, same as entity files.
|
|
33
|
+
|
|
34
|
+
### Memory suggestions (`.memory-suggestions.md`)
|
|
35
|
+
|
|
36
|
+
If the file `knowledge/.memory-suggestions.md` exists, it contains recommendations from the weekly/monthly consolidation about topics worth adding to `MEMORY.md`. Read it, decide whether the suggestions are relevant, update `MEMORY.md` if appropriate, then delete the file.
|
|
37
|
+
|
|
38
|
+
## Syntax
|
|
39
|
+
|
|
40
|
+
napkin uses standard CLI flags. Quote values with spaces:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
napkin --vault $NAPKIN_VAULT create --name "My Note" --content "Hello world"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Global flags
|
|
47
|
+
|
|
48
|
+
| Flag | Description |
|
|
49
|
+
|------|-------------|
|
|
50
|
+
| `--json` | Output as JSON (use this for programmatic access) |
|
|
51
|
+
| `-q, --quiet` | Suppress output |
|
|
52
|
+
| `--vault <path>` | Vault path (default: auto-detect by walking up from cwd looking for `.obsidian/`) |
|
|
53
|
+
| `--copy` | Copy output to clipboard |
|
|
54
|
+
|
|
55
|
+
### File targeting
|
|
56
|
+
|
|
57
|
+
- `--file <name>` — resolves like a wikilink (name only, no path or extension needed)
|
|
58
|
+
- `--path <path>` — exact path from vault root, e.g. `Projects/note.md`
|
|
59
|
+
|
|
60
|
+
## Commands
|
|
61
|
+
|
|
62
|
+
### Vault
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
napkin --vault $NAPKIN_VAULT vault # Vault info (name, path, files, folders, size)
|
|
66
|
+
napkin --vault $NAPKIN_VAULT version # CLI version
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Files & folders — `napkin file`
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
napkin --vault $NAPKIN_VAULT file info <name> # File info (path, size, dates)
|
|
73
|
+
napkin --vault $NAPKIN_VAULT file list # List all files
|
|
74
|
+
napkin --vault $NAPKIN_VAULT file list --ext md # Filter by extension
|
|
75
|
+
napkin --vault $NAPKIN_VAULT file list --folder Projects # Filter by folder
|
|
76
|
+
napkin --vault $NAPKIN_VAULT file list --total # Count files
|
|
77
|
+
napkin --vault $NAPKIN_VAULT file folder <path> # Folder info (files, folders, size)
|
|
78
|
+
napkin --vault $NAPKIN_VAULT file folder <path> --info files # Just the file count
|
|
79
|
+
napkin --vault $NAPKIN_VAULT file folders # List all folders
|
|
80
|
+
napkin --vault $NAPKIN_VAULT file folders --total # Count folders
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Read & write
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
napkin --vault $NAPKIN_VAULT read <file> # Read file contents
|
|
87
|
+
napkin --vault $NAPKIN_VAULT create --name "Note" --content "# Hello"
|
|
88
|
+
napkin --vault $NAPKIN_VAULT create --name "Note" --path "Projects" --template "Meeting Note"
|
|
89
|
+
napkin --vault $NAPKIN_VAULT append --file "Note" --content "New line at end"
|
|
90
|
+
napkin --vault $NAPKIN_VAULT prepend --file "Note" --content "New line after frontmatter"
|
|
91
|
+
napkin --vault $NAPKIN_VAULT move --file "Note" --to Archive
|
|
92
|
+
napkin --vault $NAPKIN_VAULT rename --file "Note" --name "Renamed Note"
|
|
93
|
+
napkin --vault $NAPKIN_VAULT delete --file "Note" # Move to .trash
|
|
94
|
+
napkin --vault $NAPKIN_VAULT delete --file "Note" --permanent # Delete permanently
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Daily notes — `napkin daily`
|
|
98
|
+
|
|
99
|
+
Reads config from `.obsidian/daily-notes.json` (folder, format, template).
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
napkin --vault $NAPKIN_VAULT daily today # Create today's daily note (from template if configured)
|
|
103
|
+
napkin --vault $NAPKIN_VAULT daily path # Print daily note path
|
|
104
|
+
napkin --vault $NAPKIN_VAULT daily read # Print daily note contents
|
|
105
|
+
napkin --vault $NAPKIN_VAULT daily append --content "- [ ] Buy groceries"
|
|
106
|
+
napkin --vault $NAPKIN_VAULT daily prepend --content "## Morning"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Search
|
|
110
|
+
|
|
111
|
+
Full-text search with relevance ranking (fuzzy matching, prefix search, filename boosting).
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
napkin --vault $NAPKIN_VAULT search "meeting" # Find files matching text
|
|
115
|
+
napkin --vault $NAPKIN_VAULT search --query "meeting" # Same, using flag
|
|
116
|
+
napkin --vault $NAPKIN_VAULT search "TODO" --path Projects # Limit to folder
|
|
117
|
+
napkin --vault $NAPKIN_VAULT search "bug" --total # Count matches
|
|
118
|
+
napkin --vault $NAPKIN_VAULT search "deploy" --limit 5 # Top 5 results
|
|
119
|
+
napkin --vault $NAPKIN_VAULT search "TODO" --context # Grep-style file:line:text output
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Tasks — `napkin task`
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
napkin --vault $NAPKIN_VAULT task list # List all tasks
|
|
126
|
+
napkin --vault $NAPKIN_VAULT task list --todo # Incomplete only
|
|
127
|
+
napkin --vault $NAPKIN_VAULT task list --done # Completed only
|
|
128
|
+
napkin --vault $NAPKIN_VAULT task list --daily # Today's daily note tasks
|
|
129
|
+
napkin --vault $NAPKIN_VAULT task list --file "Project A" # Tasks in specific file
|
|
130
|
+
napkin --vault $NAPKIN_VAULT task list --verbose # Group by file with line numbers
|
|
131
|
+
napkin --vault $NAPKIN_VAULT task list --total # Count tasks
|
|
132
|
+
napkin --vault $NAPKIN_VAULT task show --file "note" --line 3 # Show task info
|
|
133
|
+
napkin --vault $NAPKIN_VAULT task show --file "note" --line 3 --toggle # Toggle ✓/○
|
|
134
|
+
napkin --vault $NAPKIN_VAULT task show --file "note" --line 3 --done # Mark done
|
|
135
|
+
napkin --vault $NAPKIN_VAULT task show --ref "note.md:3" --todo # Mark todo (file:line shorthand)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Tags — `napkin tag`
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
napkin --vault $NAPKIN_VAULT tag list # List all tags
|
|
142
|
+
napkin --vault $NAPKIN_VAULT tag list --counts # With occurrence counts
|
|
143
|
+
napkin --vault $NAPKIN_VAULT tag list --sort count # Sort by frequency
|
|
144
|
+
napkin --vault $NAPKIN_VAULT tag info --name "project" # Tag info (count)
|
|
145
|
+
napkin --vault $NAPKIN_VAULT tag info --name "project" --verbose # With file list
|
|
146
|
+
napkin --vault $NAPKIN_VAULT tag aliases # List all aliases in vault
|
|
147
|
+
napkin --vault $NAPKIN_VAULT tag aliases --file "note" # Aliases for a file
|
|
148
|
+
napkin --vault $NAPKIN_VAULT tag aliases --total # Count aliases
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Properties — `napkin property`
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
napkin --vault $NAPKIN_VAULT property list # List all property names in vault
|
|
155
|
+
napkin --vault $NAPKIN_VAULT property list --file "note" # Properties for a specific file
|
|
156
|
+
napkin --vault $NAPKIN_VAULT property list --counts # With occurrence counts
|
|
157
|
+
napkin --vault $NAPKIN_VAULT property read --file "note" --name title
|
|
158
|
+
napkin --vault $NAPKIN_VAULT property set --file "note" --name status --value done
|
|
159
|
+
napkin --vault $NAPKIN_VAULT property remove --file "note" --name status
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Links — `napkin link`
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
napkin --vault $NAPKIN_VAULT link back --file "note" # Files linking TO this file
|
|
166
|
+
napkin --vault $NAPKIN_VAULT link out --file "note" # Outgoing links FROM this file
|
|
167
|
+
napkin --vault $NAPKIN_VAULT link unresolved # Broken links (target doesn't exist)
|
|
168
|
+
napkin --vault $NAPKIN_VAULT link orphans # Files with no incoming links
|
|
169
|
+
napkin --vault $NAPKIN_VAULT link deadends # Files with no outgoing links
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Outline
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
napkin --vault $NAPKIN_VAULT outline --file "note" # Heading tree
|
|
176
|
+
napkin --vault $NAPKIN_VAULT outline --file "note" --format md # Markdown list
|
|
177
|
+
napkin --vault $NAPKIN_VAULT outline --file "note" --format json # JSON array
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Templates — `napkin template`
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
napkin --vault $NAPKIN_VAULT template list # List templates
|
|
184
|
+
napkin --vault $NAPKIN_VAULT template read --name "Daily Note" # Read template content
|
|
185
|
+
napkin --vault $NAPKIN_VAULT template read --name "Meeting" --resolve --title "Standup" # Resolve variables
|
|
186
|
+
napkin --vault $NAPKIN_VAULT template insert --file "note" --name "Template" # Insert template into file
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Bookmarks — `napkin bookmark`
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
napkin --vault $NAPKIN_VAULT bookmark list # List bookmarks
|
|
193
|
+
napkin --vault $NAPKIN_VAULT bookmark list --total # Count bookmarks
|
|
194
|
+
napkin --vault $NAPKIN_VAULT bookmark add --file "note" # Bookmark a file
|
|
195
|
+
napkin --vault $NAPKIN_VAULT bookmark add --folder "Projects" # Bookmark a folder
|
|
196
|
+
napkin --vault $NAPKIN_VAULT bookmark add --search "TODO" # Bookmark a search
|
|
197
|
+
napkin --vault $NAPKIN_VAULT bookmark add --url "https://example.com" --title "Example"
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Bases — `napkin base`
|
|
201
|
+
|
|
202
|
+
Query vault files using Obsidian Bases `.base` files (YAML-defined filters over frontmatter properties, powered by SQLite in-memory).
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
napkin --vault $NAPKIN_VAULT base list # List .base files
|
|
206
|
+
napkin --vault $NAPKIN_VAULT base views --file "projects" # List views in a base
|
|
207
|
+
napkin --vault $NAPKIN_VAULT base query --file "projects" # Query default view
|
|
208
|
+
napkin --vault $NAPKIN_VAULT base query --file "projects" --view "Active" # Query named view
|
|
209
|
+
napkin --vault $NAPKIN_VAULT base query --file "projects" --format paths # Just file paths
|
|
210
|
+
napkin --vault $NAPKIN_VAULT base query --file "projects" --format csv # CSV output
|
|
211
|
+
napkin --vault $NAPKIN_VAULT base create --file "projects" --name "New Item" # Create item in base
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Canvas — `napkin canvas`
|
|
215
|
+
|
|
216
|
+
Read and write JSON Canvas files (`.canvas`) — nodes, edges, groups.
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
napkin --vault $NAPKIN_VAULT canvas list # List .canvas files
|
|
220
|
+
napkin --vault $NAPKIN_VAULT canvas list --total # Count canvases
|
|
221
|
+
napkin --vault $NAPKIN_VAULT canvas read --file "Board" # Dump canvas (nodes + edges)
|
|
222
|
+
napkin --vault $NAPKIN_VAULT canvas nodes --file "Board" # List all nodes
|
|
223
|
+
napkin --vault $NAPKIN_VAULT canvas nodes --file "Board" --type text # Filter by type
|
|
224
|
+
napkin --vault $NAPKIN_VAULT canvas create --file "Board" # Create empty canvas
|
|
225
|
+
napkin --vault $NAPKIN_VAULT canvas create --file "Board" --path "Projects"
|
|
226
|
+
napkin --vault $NAPKIN_VAULT canvas add-node --file "Board" --type text --text "# Hello"
|
|
227
|
+
napkin --vault $NAPKIN_VAULT canvas add-node --file "Board" --type file --note-file "Notes/note.md"
|
|
228
|
+
napkin --vault $NAPKIN_VAULT canvas add-node --file "Board" --type link --url "https://example.com"
|
|
229
|
+
napkin --vault $NAPKIN_VAULT canvas add-node --file "Board" --type group --label "My Group"
|
|
230
|
+
napkin --vault $NAPKIN_VAULT canvas add-node --file "Board" --type text --text "Positioned" --x 100 --y 200
|
|
231
|
+
napkin --vault $NAPKIN_VAULT canvas add-edge --file "Board" --from abc1 --to def2 --label "relates to"
|
|
232
|
+
napkin --vault $NAPKIN_VAULT canvas remove-node --file "Board" --id abc1 # Removes node + connected edges
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Node IDs are 16-char hex. `--from`/`--to`/`--id` accept ID prefixes for convenience.
|
|
236
|
+
Node types: `text`, `file`, `link`, `group`. Colors: `1`-`6` or hex.
|
|
237
|
+
New nodes auto-position to the right of existing content.
|
|
238
|
+
|
|
239
|
+
### Word count
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
napkin --vault $NAPKIN_VAULT wordcount --file "note" # Words + characters
|
|
243
|
+
napkin --vault $NAPKIN_VAULT wordcount --file "note" --words # Words only
|
|
244
|
+
napkin --vault $NAPKIN_VAULT wordcount --file "note" --characters # Characters only
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Agent onboarding
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
napkin --vault $NAPKIN_VAULT onboard # Print instructions for CLAUDE.md/AGENTS.md
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## JSON output
|
|
254
|
+
|
|
255
|
+
Every command supports `--json`. Always use `--json` for programmatic access:
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
napkin --vault $NAPKIN_VAULT task list --todo --json
|
|
259
|
+
# {"tasks": [{"text": "Buy groceries", "done": false, "file": "Daily/2024-01-15.md", "line": 5}, ...]}
|
|
260
|
+
|
|
261
|
+
napkin --vault $NAPKIN_VAULT search "deploy" --json
|
|
262
|
+
# {"files": ["Projects/Deploy Guide.md", "Notes/CI-CD.md"]}
|
|
263
|
+
|
|
264
|
+
napkin --vault $NAPKIN_VAULT property read --file "note" --name status --json
|
|
265
|
+
# {"value": "done"}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Common workflows
|
|
269
|
+
|
|
270
|
+
### Morning standup prep
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
napkin --vault $NAPKIN_VAULT daily read --json # What did I write yesterday?
|
|
274
|
+
napkin --vault $NAPKIN_VAULT task list --todo --json # What's pending?
|
|
275
|
+
napkin --vault $NAPKIN_VAULT search "blocker" --json # Any blockers?
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Project overview
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
napkin --vault $NAPKIN_VAULT file list --folder Projects --json # List project files
|
|
282
|
+
napkin --vault $NAPKIN_VAULT tag list --counts --json # Tag distribution
|
|
283
|
+
napkin --vault $NAPKIN_VAULT link orphans --json # Forgotten files
|
|
284
|
+
napkin --vault $NAPKIN_VAULT link unresolved --json # Broken links to fix
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Note management
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
napkin --vault $NAPKIN_VAULT create --name "Meeting Notes" --template "Meeting Note" --path "Meetings"
|
|
291
|
+
napkin --vault $NAPKIN_VAULT property set --file "Meeting Notes" --name attendees --value "Alice, Bob"
|
|
292
|
+
napkin --vault $NAPKIN_VAULT append --file "Meeting Notes" --content "- [ ] Follow up on deployment"
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
# Obsidian Markdown Reference
|
|
298
|
+
|
|
299
|
+
napkin operates on Obsidian Flavored Markdown files. This section covers the syntax for creating valid content.
|
|
300
|
+
|
|
301
|
+
## Properties (frontmatter)
|
|
302
|
+
|
|
303
|
+
YAML frontmatter at the start of a note:
|
|
304
|
+
|
|
305
|
+
```yaml
|
|
306
|
+
---
|
|
307
|
+
title: My Note
|
|
308
|
+
date: 2024-01-15
|
|
309
|
+
tags:
|
|
310
|
+
- project
|
|
311
|
+
- important
|
|
312
|
+
aliases:
|
|
313
|
+
- My Note
|
|
314
|
+
- Alternative Name
|
|
315
|
+
cssclasses:
|
|
316
|
+
- custom-class
|
|
317
|
+
status: in-progress
|
|
318
|
+
rating: 4.5
|
|
319
|
+
completed: false
|
|
320
|
+
---
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Property types
|
|
324
|
+
|
|
325
|
+
| Type | Example |
|
|
326
|
+
|------|---------|
|
|
327
|
+
| Text | `title: My Title` |
|
|
328
|
+
| Number | `rating: 4.5` |
|
|
329
|
+
| Checkbox | `completed: true` |
|
|
330
|
+
| Date | `date: 2024-01-15` |
|
|
331
|
+
| Date & Time | `due: 2024-01-15T14:30:00` |
|
|
332
|
+
| List | `tags: [one, two]` or YAML list |
|
|
333
|
+
| Links | `related: "[[Other Note]]"` |
|
|
334
|
+
|
|
335
|
+
Default properties: `tags`, `aliases`, `cssclasses`
|
|
336
|
+
|
|
337
|
+
## Internal links (wikilinks)
|
|
338
|
+
|
|
339
|
+
```markdown
|
|
340
|
+
[[Note Name]] Link to note
|
|
341
|
+
[[Note Name|Display Text]] Custom display text
|
|
342
|
+
[[Note Name#Heading]] Link to heading
|
|
343
|
+
[[Note Name#^block-id]] Link to block
|
|
344
|
+
[[#Heading in same note]] Same-file heading link
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Embeds
|
|
348
|
+
|
|
349
|
+
```markdown
|
|
350
|
+
![[Note Name]] Embed entire note
|
|
351
|
+
![[Note Name#Heading]] Embed section
|
|
352
|
+
![[image.png]] Embed image
|
|
353
|
+
![[image.png|300]] Image with width
|
|
354
|
+
![[document.pdf]] Embed PDF
|
|
355
|
+
![[document.pdf#page=3]] PDF at page
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Tags
|
|
359
|
+
|
|
360
|
+
```markdown
|
|
361
|
+
#tag
|
|
362
|
+
#nested/tag
|
|
363
|
+
#tag-with-dashes
|
|
364
|
+
|
|
365
|
+
# In frontmatter:
|
|
366
|
+
tags:
|
|
367
|
+
- tag1
|
|
368
|
+
- nested/tag2
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Tags can contain letters, numbers (not first), underscores, hyphens, forward slashes.
|
|
372
|
+
|
|
373
|
+
## Task lists
|
|
374
|
+
|
|
375
|
+
```markdown
|
|
376
|
+
- [ ] Incomplete task
|
|
377
|
+
- [x] Completed task
|
|
378
|
+
- [ ] Parent task
|
|
379
|
+
- [ ] Subtask
|
|
380
|
+
- [x] Done subtask
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## Callouts
|
|
384
|
+
|
|
385
|
+
```markdown
|
|
386
|
+
> [!note]
|
|
387
|
+
> This is a note callout.
|
|
388
|
+
|
|
389
|
+
> [!warning] Custom Title
|
|
390
|
+
> Warning with custom title.
|
|
391
|
+
|
|
392
|
+
> [!faq]- Collapsed by default
|
|
393
|
+
> Hidden until expanded.
|
|
394
|
+
|
|
395
|
+
> [!tip]+ Expanded by default
|
|
396
|
+
> Visible but collapsible.
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
Callout types: `note`, `abstract`/`summary`/`tldr`, `info`, `todo`, `tip`/`hint`/`important`, `success`/`check`/`done`, `question`/`help`/`faq`, `warning`/`caution`/`attention`, `failure`/`fail`/`missing`, `danger`/`error`, `bug`, `example`, `quote`/`cite`
|
|
400
|
+
|
|
401
|
+
## Text formatting
|
|
402
|
+
|
|
403
|
+
| Style | Syntax |
|
|
404
|
+
|-------|--------|
|
|
405
|
+
| Bold | `**text**` |
|
|
406
|
+
| Italic | `*text*` |
|
|
407
|
+
| Bold + Italic | `***text***` |
|
|
408
|
+
| Strikethrough | `~~text~~` |
|
|
409
|
+
| Highlight | `==text==` |
|
|
410
|
+
| Inline code | `` `code` `` |
|
|
411
|
+
|
|
412
|
+
## Code blocks
|
|
413
|
+
|
|
414
|
+
````markdown
|
|
415
|
+
```javascript
|
|
416
|
+
function hello() {
|
|
417
|
+
console.log("Hello");
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
````
|
|
421
|
+
|
|
422
|
+
## Math (LaTeX)
|
|
423
|
+
|
|
424
|
+
```markdown
|
|
425
|
+
Inline: $e^{i\pi} + 1 = 0$
|
|
426
|
+
|
|
427
|
+
Block:
|
|
428
|
+
$$
|
|
429
|
+
\sum_{i=1}^{n} x_i
|
|
430
|
+
$$
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
## Block references
|
|
434
|
+
|
|
435
|
+
```markdown
|
|
436
|
+
This paragraph can be linked to. ^my-block-id
|
|
437
|
+
|
|
438
|
+
Link to it: [[Note#^my-block-id]]
|
|
439
|
+
Embed it: ![[Note#^my-block-id]]
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
## Comments
|
|
443
|
+
|
|
444
|
+
```markdown
|
|
445
|
+
This is visible %%but this is hidden%% text.
|
|
446
|
+
|
|
447
|
+
%%
|
|
448
|
+
This entire block is hidden.
|
|
449
|
+
%%
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
# Bases Reference
|
|
455
|
+
|
|
456
|
+
Bases are YAML-defined views that query vault files using their frontmatter properties. Saved as `.base` files.
|
|
457
|
+
|
|
458
|
+
## Structure
|
|
459
|
+
|
|
460
|
+
```yaml
|
|
461
|
+
filters:
|
|
462
|
+
and:
|
|
463
|
+
- file.hasTag("project")
|
|
464
|
+
- 'status != "done"'
|
|
465
|
+
formulas:
|
|
466
|
+
days_left: '(date(due) - today()).days'
|
|
467
|
+
properties:
|
|
468
|
+
status:
|
|
469
|
+
displayName: Status
|
|
470
|
+
views:
|
|
471
|
+
- type: table
|
|
472
|
+
name: "Active"
|
|
473
|
+
order:
|
|
474
|
+
- file.name
|
|
475
|
+
- status
|
|
476
|
+
limit: 20
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
## Filters
|
|
480
|
+
|
|
481
|
+
```yaml
|
|
482
|
+
# Single filter
|
|
483
|
+
filters:
|
|
484
|
+
file.hasTag("project")
|
|
485
|
+
|
|
486
|
+
# AND
|
|
487
|
+
filters:
|
|
488
|
+
and:
|
|
489
|
+
- file.hasTag("project")
|
|
490
|
+
- 'status != "done"'
|
|
491
|
+
|
|
492
|
+
# OR
|
|
493
|
+
filters:
|
|
494
|
+
or:
|
|
495
|
+
- file.hasTag("book")
|
|
496
|
+
- file.hasTag("article")
|
|
497
|
+
|
|
498
|
+
# NOT
|
|
499
|
+
filters:
|
|
500
|
+
not:
|
|
501
|
+
- file.hasTag("archived")
|
|
502
|
+
|
|
503
|
+
# Nested
|
|
504
|
+
filters:
|
|
505
|
+
or:
|
|
506
|
+
- file.hasTag("urgent")
|
|
507
|
+
- and:
|
|
508
|
+
- file.hasTag("project")
|
|
509
|
+
- 'priority >= 3'
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Filter operators
|
|
513
|
+
|
|
514
|
+
| Operator | Description |
|
|
515
|
+
|----------|-------------|
|
|
516
|
+
| `==` | equals |
|
|
517
|
+
| `!=` | not equal |
|
|
518
|
+
| `>` | greater than |
|
|
519
|
+
| `<` | less than |
|
|
520
|
+
| `>=` | greater than or equal |
|
|
521
|
+
| `<=` | less than or equal |
|
|
522
|
+
|
|
523
|
+
### File functions for filters
|
|
524
|
+
|
|
525
|
+
| Function | Description |
|
|
526
|
+
|----------|-------------|
|
|
527
|
+
| `file.hasTag("tag1", "tag2")` | Has any of the tags (includes nested) |
|
|
528
|
+
| `file.hasLink("Note")` | Has link to note |
|
|
529
|
+
| `file.hasProperty("name")` | Has frontmatter property |
|
|
530
|
+
| `file.inFolder("Projects")` | In folder or subfolder |
|
|
531
|
+
|
|
532
|
+
### File properties
|
|
533
|
+
|
|
534
|
+
| Property | Type | Description |
|
|
535
|
+
|----------|------|-------------|
|
|
536
|
+
| `file.name` | String | File name |
|
|
537
|
+
| `file.basename` | String | Name without extension |
|
|
538
|
+
| `file.path` | String | Full path from vault root |
|
|
539
|
+
| `file.folder` | String | Parent folder path |
|
|
540
|
+
| `file.ext` | String | File extension |
|
|
541
|
+
| `file.size` | Number | Size in bytes |
|
|
542
|
+
| `file.ctime` | Date | Created time |
|
|
543
|
+
| `file.mtime` | Date | Modified time |
|
|
544
|
+
| `file.tags` | List | All tags |
|
|
545
|
+
| `file.links` | List | Internal links |
|
|
546
|
+
|
|
547
|
+
### Note properties
|
|
548
|
+
|
|
549
|
+
Frontmatter properties accessed as `note.property` or just `property`:
|
|
550
|
+
|
|
551
|
+
```yaml
|
|
552
|
+
filters:
|
|
553
|
+
and:
|
|
554
|
+
- 'status == "active"' # shorthand
|
|
555
|
+
- 'note.priority >= 3' # explicit
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
## Formulas
|
|
559
|
+
|
|
560
|
+
```yaml
|
|
561
|
+
formulas:
|
|
562
|
+
total: "price * quantity"
|
|
563
|
+
status_icon: 'if(done, "✅", "⏳")'
|
|
564
|
+
formatted_price: 'if(price, price.toFixed(2) + " dollars")'
|
|
565
|
+
created: 'file.ctime.format("YYYY-MM-DD")'
|
|
566
|
+
days_old: '(now() - file.ctime).days'
|
|
567
|
+
days_until_due: 'if(due_date, (date(due_date) - today()).days, "")'
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### Global functions
|
|
571
|
+
|
|
572
|
+
| Function | Description |
|
|
573
|
+
|----------|-------------|
|
|
574
|
+
| `date(string)` | Parse date (`YYYY-MM-DD HH:mm:ss`) |
|
|
575
|
+
| `now()` | Current datetime |
|
|
576
|
+
| `today()` | Current date (time = 00:00:00) |
|
|
577
|
+
| `if(cond, true, false?)` | Conditional |
|
|
578
|
+
| `min(n1, n2, ...)` | Smallest number |
|
|
579
|
+
| `max(n1, n2, ...)` | Largest number |
|
|
580
|
+
| `number(any)` | Convert to number |
|
|
581
|
+
| `link(path, display?)` | Create link |
|
|
582
|
+
| `list(element)` | Wrap in list |
|
|
583
|
+
|
|
584
|
+
### Date arithmetic
|
|
585
|
+
|
|
586
|
+
```yaml
|
|
587
|
+
"date + \"1M\"" # Add 1 month
|
|
588
|
+
"now() + \"1 day\"" # Tomorrow
|
|
589
|
+
"today() + \"7d\"" # Week from today
|
|
590
|
+
"(now() - file.ctime).days" # Days since created
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
Duration units: `y`/`year`/`years`, `M`/`month`/`months`, `d`/`day`/`days`, `w`/`week`/`weeks`, `h`/`hour`/`hours`, `m`/`minute`/`minutes`, `s`/`second`/`seconds`
|
|
594
|
+
|
|
595
|
+
### String functions
|
|
596
|
+
|
|
597
|
+
`contains()`, `startsWith()`, `endsWith()`, `lower()`, `trim()`, `replace()`, `split()`, `slice()`, `isEmpty()`, `.length`
|
|
598
|
+
|
|
599
|
+
### Number functions
|
|
600
|
+
|
|
601
|
+
`abs()`, `ceil()`, `floor()`, `round(digits?)`, `toFixed(precision)`
|
|
602
|
+
|
|
603
|
+
### List functions
|
|
604
|
+
|
|
605
|
+
`contains()`, `filter()`, `map()`, `join()`, `sort()`, `unique()`, `flat()`, `isEmpty()`, `.length`
|
|
606
|
+
|
|
607
|
+
## Views
|
|
608
|
+
|
|
609
|
+
```yaml
|
|
610
|
+
views:
|
|
611
|
+
- type: table # table, list, cards, map
|
|
612
|
+
name: "My View"
|
|
613
|
+
limit: 10
|
|
614
|
+
order:
|
|
615
|
+
- file.name
|
|
616
|
+
- status
|
|
617
|
+
- due_date
|
|
618
|
+
filters: # View-level filters (AND'd with global)
|
|
619
|
+
'status != "done"'
|
|
620
|
+
groupBy:
|
|
621
|
+
property: status
|
|
622
|
+
direction: ASC # or DESC
|
|
623
|
+
summaries:
|
|
624
|
+
price: Sum
|
|
625
|
+
count: Average
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### Summary functions
|
|
629
|
+
|
|
630
|
+
| Name | Input | Description |
|
|
631
|
+
|------|-------|-------------|
|
|
632
|
+
| `Average` | Number | Mean |
|
|
633
|
+
| `Min` | Number | Smallest |
|
|
634
|
+
| `Max` | Number | Largest |
|
|
635
|
+
| `Sum` | Number | Sum |
|
|
636
|
+
| `Range` | Number | Max - Min |
|
|
637
|
+
| `Median` | Number | Median |
|
|
638
|
+
| `Earliest` | Date | Earliest date |
|
|
639
|
+
| `Latest` | Date | Latest date |
|
|
640
|
+
| `Empty` | Any | Count of empty values |
|
|
641
|
+
| `Filled` | Any | Count of non-empty values |
|
|
642
|
+
| `Unique` | Any | Count of unique values |
|
|
643
|
+
|
|
644
|
+
## Example: Task tracker
|
|
645
|
+
|
|
646
|
+
```yaml
|
|
647
|
+
filters:
|
|
648
|
+
and:
|
|
649
|
+
- file.hasTag("task")
|
|
650
|
+
- 'file.ext == "md"'
|
|
651
|
+
formulas:
|
|
652
|
+
days_until_due: 'if(due, (date(due) - today()).days, "")'
|
|
653
|
+
priority_label: 'if(priority == 1, "🔴 High", if(priority == 2, "🟡 Medium", "🟢 Low"))'
|
|
654
|
+
views:
|
|
655
|
+
- type: table
|
|
656
|
+
name: "Active Tasks"
|
|
657
|
+
filters:
|
|
658
|
+
and:
|
|
659
|
+
- 'status != "done"'
|
|
660
|
+
order:
|
|
661
|
+
- file.name
|
|
662
|
+
- status
|
|
663
|
+
- formula.priority_label
|
|
664
|
+
- due
|
|
665
|
+
- formula.days_until_due
|
|
666
|
+
groupBy:
|
|
667
|
+
property: status
|
|
668
|
+
direction: ASC
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
---
|
|
672
|
+
|
|
673
|
+
# JSON Canvas Reference
|
|
674
|
+
|
|
675
|
+
Canvas files (`.canvas`) are JSON following the [JSON Canvas Spec 1.0](https://jsoncanvas.org/spec/1.0/).
|
|
676
|
+
|
|
677
|
+
```json
|
|
678
|
+
{
|
|
679
|
+
"nodes": [
|
|
680
|
+
{"id": "aabb11223344", "type": "text", "x": 0, "y": 0, "width": 300, "height": 150, "text": "# Hello\nMarkdown content"},
|
|
681
|
+
{"id": "ccdd55667788", "type": "file", "x": 400, "y": 0, "width": 300, "height": 200, "file": "Notes/note.md"},
|
|
682
|
+
{"id": "eeff99001122", "type": "link", "x": 0, "y": 300, "width": 300, "height": 100, "url": "https://example.com"},
|
|
683
|
+
{"id": "1122334455667788", "type": "group", "x": -50, "y": -50, "width": 800, "height": 500, "label": "My Group", "color": "4"}
|
|
684
|
+
],
|
|
685
|
+
"edges": [
|
|
686
|
+
{"id": "aabbccddeeff0011", "fromNode": "aabb11223344", "fromSide": "right", "toNode": "ccdd55667788", "toSide": "left", "label": "links to"}
|
|
687
|
+
]
|
|
688
|
+
}
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
### Node types
|
|
692
|
+
|
|
693
|
+
| Type | Required fields | Description |
|
|
694
|
+
|------|----------------|-------------|
|
|
695
|
+
| `text` | `text` | Markdown content |
|
|
696
|
+
| `file` | `file`, optional `subpath` | Reference to vault file |
|
|
697
|
+
| `link` | `url` | External URL |
|
|
698
|
+
| `group` | optional `label`, `background`, `backgroundStyle` | Visual container |
|
|
699
|
+
|
|
700
|
+
### Common fields
|
|
701
|
+
|
|
702
|
+
All nodes: `id` (16-char hex), `type`, `x`, `y`, `width`, `height`, optional `color` (1-6 or hex).
|
|
703
|
+
Edges: `id`, `fromNode`, `toNode`, optional `fromSide`/`toSide` (top/right/bottom/left), `fromEnd`/`toEnd` (none/arrow), `label`, `color`.
|
|
704
|
+
|
|
705
|
+
---
|
|
706
|
+
|
|
707
|
+
## Example: Project notes
|
|
708
|
+
|
|
709
|
+
```yaml
|
|
710
|
+
filters:
|
|
711
|
+
and:
|
|
712
|
+
- file.inFolder("Projects")
|
|
713
|
+
- 'file.ext == "md"'
|
|
714
|
+
formulas:
|
|
715
|
+
last_updated: 'file.mtime.relative()'
|
|
716
|
+
link_count: 'file.links.length'
|
|
717
|
+
views:
|
|
718
|
+
- type: table
|
|
719
|
+
name: "All Projects"
|
|
720
|
+
order:
|
|
721
|
+
- file.name
|
|
722
|
+
- status
|
|
723
|
+
- formula.last_updated
|
|
724
|
+
- formula.link_count
|
|
725
|
+
groupBy:
|
|
726
|
+
property: status
|
|
727
|
+
direction: ASC
|
|
728
|
+
```
|