ultimate-pi 0.13.0 → 0.14.0
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/{.pi → .agents}/skills/ccc/SKILL.md +1 -7
- package/.agents/skills/ccc/references/settings.md +126 -0
- package/.agents/skills/harness-debate-plan/SKILL.md +61 -21
- package/.agents/skills/harness-orchestration/SKILL.md +1 -1
- package/.pi/agents/harness/planning/plan-adversary.md +2 -2
- package/.pi/agents/harness/planning/plan-evaluator.md +3 -1
- package/.pi/agents/harness/planning/review-integrator.md +4 -2
- package/.pi/extensions/debate-orchestrator.ts +39 -435
- package/.pi/extensions/harness-debate-tools.ts +519 -0
- package/.pi/extensions/harness-plan-approval.ts +41 -17
- package/.pi/extensions/harness-run-context.ts +18 -0
- package/.pi/extensions/lib/debate-bus-core.ts +434 -0
- package/.pi/extensions/lib/debate-bus-state.ts +58 -0
- package/.pi/extensions/lib/harness-spawn-budget.ts +5 -25
- package/.pi/extensions/lib/plan-approval/dialog.ts +33 -272
- package/.pi/extensions/lib/plan-approval/format-plan.ts +12 -85
- package/.pi/extensions/lib/plan-approval/plan-review.ts +6 -6
- package/.pi/extensions/lib/plan-approval/render.ts +6 -0
- package/.pi/extensions/lib/plan-approval/validate.ts +1 -1
- package/.pi/extensions/lib/plan-debate-envelope.ts +2 -0
- package/.pi/extensions/lib/plan-debate-gate.ts +155 -0
- package/.pi/extensions/lib/plan-debate-id.ts +39 -0
- package/.pi/extensions/lib/plan-debate-lane.ts +220 -0
- package/.pi/extensions/lib/plan-debate-round-status.ts +94 -0
- package/.pi/extensions/lib/plan-debate-write-guard.ts +20 -0
- package/.pi/extensions/lib/plan-messenger.ts +276 -0
- package/.pi/extensions/lib/plan-review-integrator-rules.ts +119 -0
- package/.pi/extensions/lib/plan-scope-guard.ts +89 -0
- package/.pi/harness/agents.manifest.json +7 -7
- package/.pi/prompts/harness-plan.md +22 -12
- package/CHANGELOG.md +18 -0
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/package.json +3 -3
- package/.agents/skills/ck-search/SKILL.md +0 -23
- package/.agents/skills/cocoindex-search/SKILL.md +0 -35
- package/.agents/skills/obsidian-bases/SKILL.md +0 -299
- package/.agents/skills/obsidian-markdown/SKILL.md +0 -237
- package/.pi/extensions/lib/plan-approval/fallback.ts +0 -50
- /package/{.pi → .agents}/skills/ccc/references/management.md +0 -0
|
@@ -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`.
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import type { ExtensionUIContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { formatPlanPacketLines } from "./format-plan.js";
|
|
3
|
-
import type {
|
|
4
|
-
PlanApprovalDialogResult,
|
|
5
|
-
ValidatedApprovePlanParams,
|
|
6
|
-
} from "./types.js";
|
|
7
|
-
|
|
8
|
-
export async function runPlanApprovalFallback(
|
|
9
|
-
ui: ExtensionUIContext,
|
|
10
|
-
validated: ValidatedApprovePlanParams,
|
|
11
|
-
): Promise<PlanApprovalDialogResult> {
|
|
12
|
-
const lines = formatPlanPacketLines(validated.plan_packet, 80);
|
|
13
|
-
const body = lines.join("\n");
|
|
14
|
-
const summary = validated.human_summary
|
|
15
|
-
? `${validated.human_summary}\n\n`
|
|
16
|
-
: "";
|
|
17
|
-
const prompt = `${summary}${body}\n\nSelect: ${validated.options.map((o, i) => `${i + 1}. ${o.title}`).join(" | ")}`;
|
|
18
|
-
const raw = await ui.input("Plan approval", prompt);
|
|
19
|
-
if (!raw?.trim()) {
|
|
20
|
-
return { response: null, cancelled: true };
|
|
21
|
-
}
|
|
22
|
-
const pick = raw.trim();
|
|
23
|
-
const byIndex = Number.parseInt(pick, 10);
|
|
24
|
-
if (
|
|
25
|
-
Number.isFinite(byIndex) &&
|
|
26
|
-
byIndex >= 1 &&
|
|
27
|
-
byIndex <= validated.options.length
|
|
28
|
-
) {
|
|
29
|
-
return {
|
|
30
|
-
response: {
|
|
31
|
-
kind: "selection",
|
|
32
|
-
selections: [validated.options[byIndex - 1].title],
|
|
33
|
-
},
|
|
34
|
-
cancelled: false,
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
const match = validated.options.find(
|
|
38
|
-
(o) => o.title.toLowerCase() === pick.toLowerCase(),
|
|
39
|
-
);
|
|
40
|
-
if (match) {
|
|
41
|
-
return {
|
|
42
|
-
response: { kind: "selection", selections: [match.title] },
|
|
43
|
-
cancelled: false,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
return {
|
|
47
|
-
response: { kind: "freeform", text: pick },
|
|
48
|
-
cancelled: false,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
File without changes
|