ultimate-pi 0.13.0 → 0.13.1

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.
@@ -11,16 +11,10 @@ description: "This skill should be used when code search, file/directory summary
11
11
 
12
12
  The agent owns the `ccc` lifecycle for the current project — initialization, indexing, and searching. Do not ask the user to perform these steps; handle them automatically.
13
13
 
14
- - **Initialization**: If `ccc search` or `ccc index` fails with an initialization error (e.g., "Not in an initialized project directory"), run `bash "$UP_PKG/.pi/scripts/harness-cocoindex-bootstrap.sh"` from the project root (or `ccc init` + `ccc index` when not in ultimate-pi harness), then retry the original command.
14
+ - **Initialization**: If `ccc search` or `ccc index` fails with an initialization error (e.g., "Not in an initialized project directory"), run `ccc init` from the project root directory, then `ccc index` to build the index, then retry the original command.
15
15
  - **Index freshness**: Keep the index up to date by running `ccc index` (or `ccc search --refresh`) when the index may be stale — e.g., at the start of a session, or after making significant code changes (new files, refactors, renamed modules). There is no need to re-index between consecutive searches if no code was changed in between.
16
16
  - **Installation**: If `ccc` itself is not found (command not found), refer to [management.md](references/management.md) for installation instructions and inform the user.
17
17
 
18
- ### ultimate-pi harness
19
-
20
- - **Parent / main agents:** follow ownership above (`ccc index` when stale after large edits).
21
- - **`harness/planning/scout-semantic`:** use **`ccc search` only** — the harness runs incremental `ccc index` before subagent spawns. Never run `ccc index`, `ccc init`, or `ccc search --refresh` in scouts.
22
- - **Lane contract:** graphify = callers/communities/architecture; `ccc` = implementation-by-meaning (chunks). Do not use `ccc` for “who calls X” — use `graphify explain` / `graphify path`.
23
-
24
18
  ## Searching the Codebase
25
19
 
26
20
  To perform a semantic search:
@@ -0,0 +1,126 @@
1
+ # ccc Settings
2
+
3
+ Configuration lives in two YAML files, both created automatically by `ccc init`.
4
+
5
+ ## User-Level Settings (`~/.cocoindex_code/global_settings.yml`)
6
+
7
+ Shared across all projects. Controls the embedding model and extra environment variables for the daemon.
8
+
9
+ ```yaml
10
+ embedding:
11
+ provider: sentence-transformers # or "litellm" (default when provider is omitted)
12
+ model: Snowflake/snowflake-arctic-embed-xs
13
+ device: mps # optional: cpu, cuda, mps (auto-detected if omitted)
14
+ min_interval_ms: 300 # optional: pace LiteLLM embedding requests to reduce 429s; defaults to 5 for LiteLLM
15
+
16
+ envs: # extra environment variables for the daemon
17
+ OPENAI_API_KEY: your-key # only needed if not already in the shell environment
18
+ ```
19
+
20
+ ### Fields
21
+
22
+ | Field | Description |
23
+ |-------|-------------|
24
+ | `embedding.provider` | `sentence-transformers` for local models, `litellm` (or omit) for cloud/remote models |
25
+ | `embedding.model` | Model identifier — format depends on provider (see examples below) |
26
+ | `embedding.device` | Optional. `cpu`, `cuda`, or `mps`. Auto-detected if omitted. Only relevant for `sentence-transformers`. |
27
+ | `embedding.min_interval_ms` | Optional. Minimum delay between LiteLLM embedding requests in milliseconds. Defaults to `5` for LiteLLM and is ignored by `sentence-transformers`. Set explicitly to override the default. |
28
+ | `envs` | Key-value map of environment variables injected into the daemon. Use for API keys not already in the shell environment. |
29
+
30
+ ### Embedding Model Examples
31
+
32
+ **Local (sentence-transformers, no API key needed):**
33
+
34
+ ```yaml
35
+ embedding:
36
+ provider: sentence-transformers
37
+ model: Snowflake/snowflake-arctic-embed-xs # default, lightweight
38
+ ```
39
+
40
+ ```yaml
41
+ embedding:
42
+ provider: sentence-transformers
43
+ model: nomic-ai/CodeRankEmbed # better code retrieval, needs GPU (~1 GB VRAM)
44
+ ```
45
+
46
+ **Ollama (local):**
47
+
48
+ ```yaml
49
+ embedding:
50
+ model: ollama/nomic-embed-text
51
+ ```
52
+
53
+ **OpenAI:**
54
+
55
+ ```yaml
56
+ embedding:
57
+ model: text-embedding-3-small
58
+ min_interval_ms: 300
59
+ envs:
60
+ OPENAI_API_KEY: your-api-key
61
+ ```
62
+
63
+ **Gemini:**
64
+
65
+ ```yaml
66
+ embedding:
67
+ model: gemini/gemini-embedding-001
68
+ envs:
69
+ GEMINI_API_KEY: your-api-key
70
+ ```
71
+
72
+ **Voyage (code-optimized):**
73
+
74
+ ```yaml
75
+ embedding:
76
+ model: voyage/voyage-code-3
77
+ envs:
78
+ VOYAGE_API_KEY: your-api-key
79
+ ```
80
+
81
+ For the full list of supported cloud providers and model identifiers, see [LiteLLM Embedding Models](https://docs.litellm.ai/docs/embedding/supported_embedding).
82
+
83
+ ### Important
84
+
85
+ Switching embedding models changes vector dimensions — you must re-index after changing the model:
86
+
87
+ ```bash
88
+ ccc reset && ccc index
89
+ ```
90
+
91
+ ## Project-Level Settings (`<project>/.cocoindex_code/settings.yml`)
92
+
93
+ Per-project. Controls which files to index. Created by `ccc init` and automatically added to `.gitignore`.
94
+
95
+ ```yaml
96
+ include_patterns:
97
+ - "**/*.py"
98
+ - "**/*.js"
99
+ - "**/*.ts"
100
+ # ... (sensible defaults for 28+ file types)
101
+
102
+ exclude_patterns:
103
+ - "**/.*" # hidden directories
104
+ - "**/__pycache__"
105
+ - "**/node_modules"
106
+ - "**/dist"
107
+ # ...
108
+
109
+ language_overrides:
110
+ - ext: inc # treat .inc files as PHP
111
+ lang: php
112
+ ```
113
+
114
+ ### Fields
115
+
116
+ | Field | Description |
117
+ |-------|-------------|
118
+ | `include_patterns` | Glob patterns for files to index. Defaults cover common languages (Python, JS/TS, Rust, Go, Java, C/C++, C#, SQL, Shell, Markdown, PHP, Lua, etc.). |
119
+ | `exclude_patterns` | Glob patterns for files/directories to skip. Defaults exclude hidden dirs, `node_modules`, `dist`, `__pycache__`, `vendor`, etc. |
120
+ | `language_overrides` | List of `{ext, lang}` pairs to override language detection for specific file extensions. |
121
+
122
+ ### Editing Tips
123
+
124
+ - To index additional file types, append glob patterns to `include_patterns` (e.g. `"**/*.proto"`).
125
+ - To exclude a directory, append to `exclude_patterns` (e.g. `"**/generated"`).
126
+ - After editing, run `ccc index` to re-index with the new settings.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to this project are documented in this file.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [v0.13.1] — 2026-05-18
8
+
9
+ ### 🔧 Chores
10
+
11
+ - Consolidate vendored `ccc` skill under `.agents/skills/ccc`; remove redundant `cocoindex-search`, `ck-search`, and duplicate Obsidian skills from the package.
12
+
7
13
  ## [v0.13.0] — 2026-05-18
8
14
 
9
15
  ### ✨ Features
@@ -28,4 +28,4 @@
28
28
  - **Project:** https://github.com/cocoindex-io/cocoindex-code
29
29
  - **License:** Apache-2.0
30
30
  - **Install:** `uv tool install 'cocoindex-code[full]'` (see `/harness-setup` §2.4)
31
- - ultimate-pi vendors the upstream agent skill at [`.pi/skills/ccc/`](.pi/skills/ccc/) and bootstraps indexes via [`.pi/scripts/harness-cocoindex-bootstrap.sh`](.pi/scripts/harness-cocoindex-bootstrap.sh). Replaces deprecated `@beaconbay/ck-search`.
31
+ - ultimate-pi vendors the upstream agent skill at [`.agents/skills/ccc/`](.agents/skills/ccc/) and bootstraps indexes via [`.pi/scripts/harness-cocoindex-bootstrap.sh`](.pi/scripts/harness-cocoindex-bootstrap.sh). Replaces deprecated `@beaconbay/ck-search`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultimate-pi",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
4
4
  "description": "Ultimate AI coding harness for pi.dev — extensible skills, Obsidian wiki knowledge layer, compressed context, deterministic output",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -1,23 +0,0 @@
1
- ---
2
- name: ck-search
3
- description: "DEPRECATED — ck-search was removed from ultimate-pi. Use cocoindex-search or /skill:ccc instead. Triggers retained for backward compatibility: ck, ck-search, semantic search."
4
- ---
5
-
6
- # ck-search (deprecated)
7
-
8
- **`ck` / `@beaconbay/ck-search` is no longer used in this harness.**
9
-
10
- Use instead:
11
-
12
- - **`/skill:cocoindex-search`** or **`/skill:ccc`** — CocoIndex Code (`ccc search`)
13
- - **graphify** — architecture, callers, communities (`graphify query`, `explain`, `path`)
14
-
15
- ## Migration
16
-
17
- ```bash
18
- uv tool install 'cocoindex-code[full]'
19
- bash "$UP_PKG/.pi/scripts/harness-cocoindex-bootstrap.sh"
20
- ccc search --limit 10 "your query"
21
- ```
22
-
23
- Remove legacy index: `rm -rf .ck` (optional).
@@ -1,35 +0,0 @@
1
- ---
2
- name: cocoindex-search
3
- description: "Semantic code search using CocoIndex Code (ccc). Use when exploring codebases, finding related implementation by meaning, or replacing legacy ck-search. Triggers on: semantic code search, ccc, cocoindex, cocoindex-code, find code related to, search the codebase for implementation, /skill:ck-search."
4
- ---
5
-
6
- # cocoindex-search
7
-
8
- CocoIndex Code (`ccc`) provides offline, AST-aware semantic search over the project codebase.
9
-
10
- ## Quick start
11
-
12
- ```bash
13
- ccc search --limit 10 "harness subagent policy"
14
- ccc status
15
- ```
16
-
17
- ## Full reference
18
-
19
- Load the vendored skill: **`/skill:ccc`** (`.pi/skills/ccc/SKILL.md`).
20
-
21
- ## Harness lanes
22
-
23
- | Question type | Tool |
24
- |---------------|------|
25
- | Callers, callees, cross-module paths | `graphify explain` / `graphify path` |
26
- | Implementation by meaning | `ccc search --limit N "…"` |
27
- | Structural patterns | `sg -p '…'` |
28
-
29
- ## Setup
30
-
31
- ```bash
32
- bash "$UP_PKG/.pi/scripts/harness-cocoindex-bootstrap.sh"
33
- ```
34
-
35
- Indexing before harness scouts is automatic — do not run `ccc index` or `ccc search --refresh` in `scout-semantic`.
@@ -1,299 +0,0 @@
1
- ---
2
- name: obsidian-bases
3
- 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."
4
- allowed-tools: Read Write
5
- ---
6
-
7
- # obsidian-bases: Obsidian's Database Layer
8
-
9
- 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.
10
-
11
- **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
12
-
13
- ---
14
-
15
- ## Wiki Path Resolution
16
-
17
- All `wiki/` paths in this skill (in `.base` filter expressions like `file.inFolder("wiki/")`) are relative to the wiki directory inside the Obsidian vault. Obsidian Bases operate on the vault directly; the `wiki/` prefix in filter expressions reflects the folder name within the vault. If your wiki folder has a different name, adjust filter paths accordingly.
18
-
19
- ---
20
-
21
- ## File Format
22
-
23
- `.base` files contain valid YAML. The root keys are `filters`, `formulas`, `properties`, `summaries`, and `views`.
24
-
25
- ```yaml
26
- # Global filters: apply to ALL views
27
- filters:
28
- and:
29
- - file.hasTag("wiki")
30
- - 'status != "archived"'
31
-
32
- # Computed properties
33
- formulas:
34
- age_days: '(now() - file.ctime).days.round(0)'
35
- status_icon: 'if(status == "mature", "✅", "🔄")'
36
-
37
- # Display name overrides for properties panel
38
- properties:
39
- status:
40
- displayName: "Status"
41
- formula.age_days:
42
- displayName: "Age (days)"
43
-
44
- # One or more views
45
- views:
46
- - type: table
47
- name: "All Pages"
48
- order:
49
- - file.name
50
- - type
51
- - status
52
- - updated
53
- - formula.age_days
54
- ```
55
-
56
- ---
57
-
58
- ## Filters
59
-
60
- Filters select which notes appear. Applied globally or per-view.
61
-
62
- ```yaml
63
- # Single string filter
64
- filters: 'status == "current"'
65
-
66
- # AND: all must be true
67
- filters:
68
- and:
69
- - 'status != "archived"'
70
- - file.hasTag("wiki")
71
-
72
- # OR: any can be true
73
- filters:
74
- or:
75
- - file.hasTag("concept")
76
- - file.hasTag("entity")
77
-
78
- # NOT: exclude matches
79
- filters:
80
- not:
81
- - file.inFolder("wiki/meta")
82
-
83
- # Nested
84
- filters:
85
- and:
86
- - file.inFolder("wiki/")
87
- - or:
88
- - 'type == "concept"'
89
- - 'type == "entity"'
90
- ```
91
-
92
- ### Filter operators
93
-
94
- `==` `!=` `>` `<` `>=` `<=`
95
-
96
- ### Useful filter functions
97
-
98
- | Function | Example |
99
- |----------|---------|
100
- | `file.hasTag("x")` | Notes with tag `x` |
101
- | `file.inFolder("path/")` | Notes in folder |
102
- | `file.hasLink("Note")` | Notes linking to Note |
103
-
104
- ---
105
-
106
- ## Properties
107
-
108
- Three types:
109
- - **Note properties**: from frontmatter: `status`, `type`, `updated`
110
- - **File properties**: metadata: `file.name`, `file.mtime`, `file.size`, `file.ctime`, `file.tags`, `file.folder`
111
- - **Formula properties**: computed: `formula.age_days`
112
-
113
- ---
114
-
115
- ## Formulas
116
-
117
- Defined in `formulas:`. Referenced as `formula.name` in `order:` and `properties:`.
118
-
119
- ```yaml
120
- formulas:
121
- # Days since created
122
- age_days: '(now() - file.ctime).days.round(0)'
123
-
124
- # Days until a date property
125
- days_until: 'if(due_date, (date(due_date) - today()).days, "")'
126
-
127
- # Conditional label
128
- status_icon: 'if(status == "mature", "✅", if(status == "developing", "🔄", "🌱"))'
129
-
130
- # Word count estimate
131
- word_est: '(file.size / 5).round(0)'
132
- ```
133
-
134
- **Key rule**: Subtracting two dates returns a `Duration`. Not a number. Always access `.days` first:
135
- ```yaml
136
- # CORRECT
137
- age: '(now() - file.ctime).days'
138
-
139
- # WRONG: crashes
140
- age: '(now() - file.ctime).round(0)'
141
- ```
142
-
143
- **Always guard nullable properties with `if()`**:
144
- ```yaml
145
- # CORRECT
146
- days_left: 'if(due_date, (date(due_date) - today()).days, "")'
147
- ```
148
-
149
- ---
150
-
151
- ## View Types
152
-
153
- ### Table
154
- ```yaml
155
- views:
156
- - type: table
157
- name: "Wiki Index"
158
- limit: 100
159
- order:
160
- - file.name
161
- - type
162
- - status
163
- - updated
164
- groupBy:
165
- property: type
166
- direction: ASC
167
- ```
168
-
169
- ### Cards
170
- ```yaml
171
- views:
172
- - type: cards
173
- name: "Gallery"
174
- order:
175
- - file.name
176
- - tags
177
- - status
178
- ```
179
-
180
- ### List
181
- ```yaml
182
- views:
183
- - type: list
184
- name: "Quick List"
185
- order:
186
- - file.name
187
- - status
188
- ```
189
-
190
- ---
191
-
192
- ## Wiki Vault Templates
193
-
194
- ### Wiki content dashboard (all non-meta pages)
195
-
196
- ```yaml
197
- filters:
198
- and:
199
- - file.inFolder("wiki/")
200
- - not:
201
- - file.inFolder("wiki/meta")
202
-
203
- formulas:
204
- age: '(now() - file.ctime).days.round(0)'
205
-
206
- properties:
207
- formula.age:
208
- displayName: "Age (days)"
209
-
210
- views:
211
- - type: table
212
- name: "All Wiki Pages"
213
- order:
214
- - file.name
215
- - type
216
- - status
217
- - updated
218
- - formula.age
219
- groupBy:
220
- property: type
221
- direction: ASC
222
- ```
223
-
224
- ### Entity index (people, orgs, repos)
225
-
226
- ```yaml
227
- filters:
228
- and:
229
- - file.inFolder("wiki/entities/")
230
- - 'file.ext == "md"'
231
-
232
- views:
233
- - type: table
234
- name: "Entities"
235
- order:
236
- - file.name
237
- - entity_type
238
- - status
239
- - updated
240
- groupBy:
241
- property: entity_type
242
- direction: ASC
243
- ```
244
-
245
- ### Recent ingests
246
-
247
- ```yaml
248
- filters:
249
- and:
250
- - file.inFolder("wiki/sources/")
251
-
252
- views:
253
- - type: table
254
- name: "Sources"
255
- order:
256
- - file.name
257
- - source_type
258
- - created
259
- - status
260
- groupBy:
261
- property: source_type
262
- direction: ASC
263
- ```
264
-
265
- ---
266
-
267
- ## Embedding in Notes
268
-
269
- ```markdown
270
- ![[MyBase.base]]
271
-
272
- ![[MyBase.base#View Name]]
273
- ```
274
-
275
- ---
276
-
277
- ## Where to Save
278
-
279
- Store `.base` files in `wiki/meta/` for vault dashboards:
280
- - `wiki/meta/dashboard.base`: main content view
281
- - `wiki/meta/entities.base`: entity tracker
282
- - `wiki/meta/sources.base`: ingestion log
283
-
284
- ---
285
-
286
- ## YAML Quoting Rules
287
-
288
- - Formulas with double quotes → wrap in single quotes: `'if(done, "Yes", "No")'`
289
- - Strings with colons or special chars → wrap in double quotes: `"Status: Active"`
290
- - Unquoted strings with `:` break YAML parsing
291
-
292
- ---
293
-
294
- ## What Not to Do
295
-
296
- - Do not use `from:` or `where:`: those are Dataview syntax, not Obsidian Bases
297
- - Do not use `sort:` at the root level: sorting is per-view via `order:` and `groupBy:`
298
- - Do not put `.base` files outside the vault: they only render inside Obsidian
299
- - Do not reference `formula.X` in `order:` without defining `X` in `formulas:`
@@ -1,237 +0,0 @@
1
- ---
2
- name: obsidian-markdown
3
- 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."
4
- allowed-tools: Read Write Edit
5
- ---
6
-
7
- # obsidian-markdown: Obsidian Flavored Markdown
8
-
9
- 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.
10
-
11
- **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).
12
-
13
- ---
14
-
15
- ## Wiki Path Resolution
16
-
17
- This skill provides Obsidian syntax reference. It does NOT perform file operations itself. When invoked by other skills (wiki-ingest, wiki-save, etc.), those skills handle wiki path resolution via `VAULT_WIKI_PATH`.
18
-
19
- ---
20
-
21
- ## Wikilinks
22
-
23
- Internal links use double brackets. The filename without extension.
24
-
25
- | Syntax | What it does |
26
- |---|---|
27
- | `[[Note Name]]` | Basic link |
28
- | `[[Note Name\|Display Text]]` | Aliased link (shows "Display Text") |
29
- | `[[Note Name#Heading]]` | Link to a specific heading |
30
- | `[[Note Name#^block-id]]` | Link to a specific block |
31
-
32
- Rules:
33
- - Case-sensitive on some systems. Match the exact filename.
34
- - No path needed: Obsidian resolves by filename uniqueness.
35
- - If two files have the same name, use `[[Folder/Note Name]]` to disambiguate.
36
-
37
- ---
38
-
39
- ## Embeds
40
-
41
- Embeds use `!` before the wikilink. They display the content inline.
42
-
43
- | Syntax | What it does |
44
- |---|---|
45
- | `![[Note Name]]` | Embed a full note |
46
- | `![[Note Name#Heading]]` | Embed a section |
47
- | `![[image.png]]` | Embed an image |
48
- | `![[image.png\|300]]` | Embed image with width 300px |
49
- | `![[document.pdf]]` | Embed a PDF (Obsidian renders natively) |
50
- | `![[audio.mp3]]` | Embed audio |
51
-
52
- ---
53
-
54
- ## Callouts
55
-
56
- Callouts are blockquotes with a type keyword. They render as styled alert boxes.
57
-
58
- ```markdown
59
- > [!note]
60
- > Default informational callout.
61
-
62
- > [!note] Custom Title
63
- > Callout with a custom title.
64
-
65
- > [!note]- Collapsible (closed by default)
66
- > Click to expand.
67
-
68
- > [!note]+ Collapsible (open by default)
69
- > Click to collapse.
70
- ```
71
-
72
- ### All callout types
73
-
74
- | Type | Aliases | Use for |
75
- |------|---------|---------|
76
- | `note` |: | General notes |
77
- | `abstract` | `summary`, `tldr` | Summaries |
78
- | `info` |: | Information |
79
- | `todo` |: | Action items |
80
- | `tip` | `hint`, `important` | Tips and highlights |
81
- | `success` | `check`, `done` | Positive outcomes |
82
- | `question` | `help`, `faq` | Open questions |
83
- | `warning` | `caution`, `attention` | Warnings |
84
- | `failure` | `fail`, `missing` | Errors or failures |
85
- | `danger` | `error` | Critical issues |
86
- | `bug` |: | Known bugs |
87
- | `example` |: | Examples |
88
- | `quote` | `cite` | Quotations |
89
- | `contradiction` |: | Conflicting information (wiki convention) |
90
-
91
- ---
92
-
93
- ## Properties (Frontmatter)
94
-
95
- Obsidian renders YAML frontmatter as a Properties panel. Rules:
96
-
97
- ```yaml
98
- ---
99
- type: concept # plain string
100
- title: "Note Title" # quoted if it contains special chars
101
- created: 2026-04-08 # date as YYYY-MM-DD (not ISO datetime)
102
- updated: 2026-04-08
103
- tags:
104
- - tag-one # list items use - format
105
- - tag-two
106
- status: developing
107
- related:
108
- - "[[Other Note]]" # wikilinks must be quoted in YAML
109
- sources:
110
- - "[[source-page]]"
111
- ---
112
- ```
113
-
114
- Rules:
115
- - Flat YAML only. Never nest objects.
116
- - Dates as `YYYY-MM-DD`, not `2026-04-08T00:00:00`.
117
- - Lists as `- item`, not inline `[a, b, c]`.
118
- - Wikilinks in YAML must be quoted: `"[[Page]]"`.
119
- - `tags` field: Obsidian reads this as the tag list, searchable in vault.
120
-
121
- ---
122
-
123
- ## Tags
124
-
125
- Two valid forms:
126
-
127
- ```markdown
128
- #tag-name : inline tag anywhere in the body
129
- #parent/child-tag : nested tag (shows hierarchy in tag pane)
130
- ```
131
-
132
- In frontmatter:
133
- ```yaml
134
- tags:
135
- - research
136
- - ai/obsidian
137
- ```
138
-
139
- Do not use `#` inside frontmatter tag lists. Just the tag name.
140
-
141
- ---
142
-
143
- ## Text Formatting
144
-
145
- Standard Markdown plus Obsidian extensions:
146
-
147
- | Syntax | Result |
148
- |---|---|
149
- | `**bold**` | Bold |
150
- | `*italic*` | Italic |
151
- | `~~strikethrough~~` | Strikethrough |
152
- | `==highlight==` | Highlighted text (yellow in Obsidian) |
153
- | `` `inline code` `` | Inline code |
154
-
155
- ---
156
-
157
- ## Math
158
-
159
- Obsidian uses MathJax/KaTeX:
160
-
161
- Inline math:
162
- ```markdown
163
- $E = mc^2$
164
- ```
165
-
166
- Block math:
167
- ```markdown
168
- $$
169
- \int_0^\infty e^{-x} dx = 1
170
- $$
171
- ```
172
-
173
- ---
174
-
175
- ## Code Blocks
176
-
177
- Standard fenced code blocks. Obsidian highlights all common languages:
178
-
179
- ````markdown
180
- ```python
181
- def hello():
182
- return "world"
183
- ```
184
- ````
185
-
186
- ---
187
-
188
- ## Tables
189
-
190
- Standard Markdown tables:
191
-
192
- ```markdown
193
- | Column A | Column B | Column C |
194
- |----------|----------|----------|
195
- | Value | Value | Value |
196
- | Value | Value | Value |
197
- ```
198
-
199
- Obsidian renders tables natively. No plugin needed.
200
-
201
- ---
202
-
203
- ## Mermaid Diagrams
204
-
205
- Obsidian renders Mermaid natively:
206
-
207
- ````markdown
208
- ```mermaid
209
- graph TD
210
- A[Start] --> B{Decision}
211
- B -->|Yes| C[End]
212
- B -->|No| D[Loop]
213
- D --> A
214
- ```
215
- ````
216
-
217
- Supported: `graph`, `sequenceDiagram`, `gantt`, `classDiagram`, `pie`, `flowchart`.
218
-
219
- ---
220
-
221
- ## Footnotes
222
-
223
- ```markdown
224
- This sentence has a footnote.[^1]
225
-
226
- [^1]: The footnote text goes here.
227
- ```
228
-
229
- ---
230
-
231
- ## What NOT to Do
232
-
233
- - Do not use `[link text](path/to/note.md)` for internal links: use `[[Note Name]]` instead.
234
- - Do not use HTML inside callouts: stick to Markdown.
235
- - Do not use `##` inside a callout body: headings don't render inside callouts.
236
- - Do not write `tags: [a, b, c]` inline in frontmatter: Obsidian prefers the list format.
237
- - Do not write ISO datetimes in frontmatter (`2026-04-08T00:00:00Z`): use `2026-04-08`.