@jayjiang/byoao 1.1.2 → 2.0.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.
Files changed (156) hide show
  1. package/dist/__tests__/plugin-config.test.js +7 -10
  2. package/dist/__tests__/plugin-config.test.js.map +1 -1
  3. package/dist/assets/obsidian-skills/byoao-conventions.md +30 -54
  4. package/dist/assets/obsidian-skills/vault-thinking.md +6 -5
  5. package/dist/assets/presets/common/AGENTS.md.hbs +29 -46
  6. package/dist/assets/presets/common/SCHEMA.md.hbs +57 -0
  7. package/dist/assets/presets/common/Start Here.md.hbs +29 -40
  8. package/dist/assets/presets/minimal/preset.json +3 -3
  9. package/dist/assets/presets/pm-tpm/preset.json +2 -2
  10. package/{src/skills/ask.md → dist/assets/skills/ask/SKILL.md} +30 -27
  11. package/dist/assets/skills/ask.md +28 -27
  12. package/dist/assets/skills/challenge/SKILL.md +134 -0
  13. package/dist/assets/skills/challenge.md +79 -121
  14. package/dist/assets/skills/connect/SKILL.md +126 -0
  15. package/dist/assets/skills/connect.md +75 -163
  16. package/dist/assets/skills/cook/SKILL.md +170 -0
  17. package/dist/assets/skills/cook.md +167 -0
  18. package/dist/assets/skills/diagnose/SKILL.md +134 -0
  19. package/dist/assets/skills/diagnose.md +102 -43
  20. package/dist/assets/skills/drift/SKILL.md +123 -0
  21. package/dist/assets/skills/drift.md +64 -165
  22. package/dist/assets/skills/health/SKILL.md +65 -0
  23. package/dist/assets/skills/health.md +63 -0
  24. package/{src/skills/ideas.md → dist/assets/skills/ideas/SKILL.md} +11 -10
  25. package/dist/assets/skills/ideas.md +11 -10
  26. package/dist/assets/skills/organize/SKILL.md +109 -0
  27. package/dist/assets/skills/organize.md +56 -155
  28. package/dist/assets/skills/prep/SKILL.md +65 -0
  29. package/dist/assets/skills/prep.md +63 -0
  30. package/dist/assets/skills/trace/SKILL.md +143 -0
  31. package/dist/assets/skills/trace.md +75 -90
  32. package/dist/assets/skills/wiki/SKILL.md +127 -0
  33. package/dist/assets/skills/wiki.md +77 -178
  34. package/dist/cli/cli-program.js +18 -15
  35. package/dist/cli/cli-program.js.map +1 -1
  36. package/dist/cli/installer.js +54 -29
  37. package/dist/cli/installer.js.map +1 -1
  38. package/dist/hooks/idle-suggestions.js +4 -4
  39. package/dist/hooks/idle-suggestions.js.map +1 -1
  40. package/dist/hooks/system-transform.js +35 -1
  41. package/dist/hooks/system-transform.js.map +1 -1
  42. package/dist/index.js +455 -636
  43. package/dist/index.js.map +1 -1
  44. package/dist/plugin-config.js +6 -32
  45. package/dist/plugin-config.js.map +1 -1
  46. package/dist/tools/init-vault.js +8 -38
  47. package/dist/tools/init-vault.js.map +1 -1
  48. package/dist/tools/vault-doctor.js +1 -1
  49. package/dist/tools/vault-doctor.js.map +1 -1
  50. package/dist/tools/vault-status.js +1 -1
  51. package/dist/tools/vault-status.js.map +1 -1
  52. package/dist/vault/__tests__/create.test.js +48 -116
  53. package/dist/vault/__tests__/create.test.js.map +1 -1
  54. package/dist/vault/__tests__/doctor.test.js +14 -2
  55. package/dist/vault/__tests__/doctor.test.js.map +1 -1
  56. package/dist/vault/__tests__/manifest.test.js +2 -2
  57. package/dist/vault/__tests__/manifest.test.js.map +1 -1
  58. package/dist/vault/__tests__/status.test.js +12 -0
  59. package/dist/vault/__tests__/status.test.js.map +1 -1
  60. package/dist/vault/__tests__/upgrade.test.js +3 -3
  61. package/dist/vault/__tests__/upgrade.test.js.map +1 -1
  62. package/dist/vault/create.js +86 -196
  63. package/dist/vault/create.js.map +1 -1
  64. package/dist/vault/doctor.js +49 -0
  65. package/dist/vault/doctor.js.map +1 -1
  66. package/dist/vault/manifest.js +2 -2
  67. package/dist/vault/manifest.js.map +1 -1
  68. package/dist/vault/preset.js +10 -4
  69. package/dist/vault/preset.js.map +1 -1
  70. package/dist/vault/self-update.js +1 -1
  71. package/dist/vault/status.js +24 -0
  72. package/dist/vault/status.js.map +1 -1
  73. package/dist/vault/upgrade.js +165 -23
  74. package/dist/vault/upgrade.js.map +1 -1
  75. package/package.json +1 -1
  76. package/src/assets/obsidian-skills/byoao-conventions.md +9 -6
  77. package/src/assets/obsidian-skills/vault-thinking.md +6 -5
  78. package/src/assets/presets/common/AGENTS.md.hbs +23 -19
  79. package/src/assets/presets/common/SCHEMA.md.hbs +57 -0
  80. package/src/assets/presets/common/Start Here.md.hbs +29 -40
  81. package/src/assets/presets/minimal/preset.json +3 -3
  82. package/src/assets/presets/pm-tpm/preset.json +2 -2
  83. package/src/skills/ask/SKILL.md +135 -0
  84. package/src/skills/challenge/SKILL.md +134 -0
  85. package/src/skills/connect/SKILL.md +126 -0
  86. package/src/skills/cook/SKILL.md +170 -0
  87. package/src/skills/diagnose/SKILL.md +134 -0
  88. package/src/skills/drift/SKILL.md +123 -0
  89. package/src/skills/health/SKILL.md +65 -0
  90. package/src/skills/ideas/SKILL.md +173 -0
  91. package/src/skills/organize/SKILL.md +109 -0
  92. package/src/skills/prep/SKILL.md +65 -0
  93. package/src/skills/trace/SKILL.md +143 -0
  94. package/src/skills/wiki/SKILL.md +127 -0
  95. package/dist/assets/presets/common/Glossary.md.hbs +0 -16
  96. package/dist/assets/presets/common/obsidian/daily-notes.json +0 -5
  97. package/dist/assets/presets/common/obsidian/templates.json +0 -3
  98. package/dist/assets/presets/common/templates/Daily Note.md +0 -19
  99. package/dist/assets/presets/common/templates/Decision Record.md +0 -32
  100. package/dist/assets/presets/common/templates/Investigation.md +0 -34
  101. package/dist/assets/presets/common/templates/Meeting Notes.md +0 -25
  102. package/dist/assets/skills/emerge.md +0 -168
  103. package/dist/assets/skills/weave.md +0 -287
  104. package/dist/tools/add-glossary-term.js +0 -21
  105. package/dist/tools/add-glossary-term.js.map +0 -1
  106. package/dist/tools/add-person.js +0 -21
  107. package/dist/tools/add-person.js.map +0 -1
  108. package/dist/tools/add-project.js +0 -24
  109. package/dist/tools/add-project.js.map +0 -1
  110. package/dist/tools/graph-health.js +0 -25
  111. package/dist/tools/graph-health.js.map +0 -1
  112. package/dist/tools/note-read.js +0 -19
  113. package/dist/tools/note-read.js.map +0 -1
  114. package/dist/tools/search-vault.js +0 -22
  115. package/dist/tools/search-vault.js.map +0 -1
  116. package/dist/vault/__tests__/glossary.test.js +0 -68
  117. package/dist/vault/__tests__/glossary.test.js.map +0 -1
  118. package/dist/vault/__tests__/graph-health.test.js +0 -102
  119. package/dist/vault/__tests__/graph-health.test.js.map +0 -1
  120. package/dist/vault/__tests__/member.test.js +0 -85
  121. package/dist/vault/__tests__/member.test.js.map +0 -1
  122. package/dist/vault/__tests__/note-read.test.js +0 -71
  123. package/dist/vault/__tests__/note-read.test.js.map +0 -1
  124. package/dist/vault/__tests__/obsidian-cli.test.js +0 -108
  125. package/dist/vault/__tests__/obsidian-cli.test.js.map +0 -1
  126. package/dist/vault/__tests__/search-vault.test.js +0 -93
  127. package/dist/vault/__tests__/search-vault.test.js.map +0 -1
  128. package/dist/vault/glossary.js +0 -27
  129. package/dist/vault/glossary.js.map +0 -1
  130. package/dist/vault/graph-health.js +0 -83
  131. package/dist/vault/graph-health.js.map +0 -1
  132. package/dist/vault/member.js +0 -67
  133. package/dist/vault/member.js.map +0 -1
  134. package/dist/vault/note-read.js +0 -70
  135. package/dist/vault/note-read.js.map +0 -1
  136. package/dist/vault/project.js +0 -68
  137. package/dist/vault/project.js.map +0 -1
  138. package/dist/vault/retrieval-types.js +0 -5
  139. package/dist/vault/retrieval-types.js.map +0 -1
  140. package/dist/vault/search-vault.js +0 -87
  141. package/dist/vault/search-vault.js.map +0 -1
  142. package/src/assets/presets/common/obsidian/daily-notes.json +0 -5
  143. package/src/assets/presets/common/obsidian/templates.json +0 -3
  144. package/src/assets/presets/common/templates/Daily Note.md +0 -19
  145. package/src/assets/presets/common/templates/Decision Record.md +0 -32
  146. package/src/assets/presets/common/templates/Investigation.md +0 -34
  147. package/src/assets/presets/common/templates/Meeting Notes.md +0 -25
  148. package/src/skills/challenge.md +0 -174
  149. package/src/skills/connect.md +0 -213
  150. package/src/skills/diagnose.md +0 -72
  151. package/src/skills/drift.md +0 -223
  152. package/src/skills/emerge.md +0 -168
  153. package/src/skills/organize.md +0 -206
  154. package/src/skills/trace.md +0 -156
  155. package/src/skills/weave.md +0 -287
  156. package/src/skills/wiki.md +0 -227
@@ -1,34 +0,0 @@
1
- ---
2
- title: ""
3
- type: investigation
4
- status: draft
5
- date: {{date}}
6
- jira: ""
7
- hypothesis: ""
8
- conclusion: ""
9
- tags: [investigation, spike]
10
- ---
11
-
12
- ## Question
13
-
14
- What are we trying to find out?
15
-
16
- ## Hypothesis
17
-
18
- What we expect to find and why.
19
-
20
- ## Method
21
-
22
- How we investigated (queries, tools, data sources).
23
-
24
- ## Findings
25
-
26
- -
27
-
28
- ## Conclusion
29
-
30
- Summary of what we learned. Does it confirm or refute the hypothesis?
31
-
32
- ## Next Steps
33
-
34
- -
@@ -1,25 +0,0 @@
1
- ---
2
- title: ""
3
- type: meeting
4
- status: active
5
- date: {{date}}
6
- participants: []
7
- meeting-type: ""
8
- tags: [meeting]
9
- ---
10
-
11
- ## Agenda
12
-
13
- 1.
14
-
15
- ## Notes
16
-
17
- -
18
-
19
- ## Decisions
20
-
21
- -
22
-
23
- ## Action Items
24
-
25
- - [ ] @person — task — due date
@@ -1,168 +0,0 @@
1
- ---
2
- name: emerge
3
- description: Surface conclusions, patterns, and insights the vault implies but never explicitly states. Analyzes clusters, orphans, and cross-domain connections. Use when the user asks "what patterns do you see", "what am I missing", "analyze my vault", "find hidden connections", or wants a big-picture review of their knowledge base.
4
- ---
5
-
6
- # /emerge — Surface Hidden Patterns
7
-
8
- You are a pattern recognition analyst. Your job is to read across the user's vault and surface insights that the notes collectively imply but never explicitly state — hidden conclusions, recurring themes, unnoticed contradictions, and latent connections.
9
-
10
- ## Prerequisites Check
11
-
12
- ```bash
13
- obsidian --version
14
- ```
15
-
16
- If this fails, STOP and display the Obsidian CLI availability message (see /weave for the full error text).
17
-
18
- ## Tool Selection
19
-
20
- Use `obsidian` CLI for content operations (read, search, backlinks, properties, tags). Use BYOAO tools (`byoao_search_vault`, `byoao_graph_health`) when Obsidian CLI is unavailable or for graph-level structural queries.
21
-
22
- ## Parameters
23
-
24
- - **scope** (optional): Limit analysis to a folder, domain, or tag. Default: entire vault.
25
- - **depth** (optional): "quick" (top-level scan) or "deep" (read every note in scope). Default: "quick".
26
- - **output** (optional): If set, save findings as a note at this path.
27
-
28
- ## Process
29
-
30
- ### Sampling Strategy
31
-
32
- If a domain or search returns more than 30 notes, prioritize: (1) most recent 10, (2) most-linked 10 (highest backlink count), (3) notes with `status: active`. Read these first, then scan remaining titles and frontmatter to check for outliers before synthesizing.
33
-
34
- ### Step 1: Map the Vault
35
-
36
- Build a structural picture:
37
-
38
- ```bash
39
- obsidian list
40
- obsidian properties sort=count counts
41
- obsidian tags
42
- ```
43
-
44
- Identify:
45
- - Total notes and their distribution across folders/domains
46
- - Most-used tags and properties
47
- - Cluster density (which areas have many interconnected notes vs sparse ones)
48
-
49
- ### Step 2: Find Structural Signals
50
-
51
- Use graph-level queries to identify interesting patterns:
52
-
53
- **Orphan notes** — notes with no links in or out:
54
- Use `byoao_graph_health` or scan notes checking for those with zero wikilinks (no `[[` in content) and zero backlinks.
55
- Orphans may contain ideas the user hasn't connected yet.
56
-
57
- **Dead-end notes** — notes that link out but nobody links to them:
58
- Scan for notes with outgoing wikilinks but no backlinks.
59
-
60
- **Hub notes** — notes with unusually many backlinks:
61
- ```bash
62
- obsidian backlinks "<note>"
63
- ```
64
- Hubs reveal what the user's thinking centers around.
65
-
66
- **Tag clusters** — tags that always co-occur:
67
- If `#migration` and `#payments` always appear together, there's an implicit connection.
68
-
69
- ### Step 3: Cross-Domain Analysis
70
-
71
- For each domain (from frontmatter `domain` field or folder grouping):
72
-
73
- 1. **Read a sample of notes** (5-10 per domain, prioritizing recent and highly-linked)
74
- 2. **Extract key themes** — what topics recur within the domain?
75
- 3. **Look for cross-domain bridges** — concepts mentioned in multiple domains
76
- 4. **Identify tension** — contradictory statements across domains or time periods
77
-
78
- ### Step 4: Pattern Detection
79
-
80
- Look for these specific pattern types:
81
-
82
- **Recurring questions**: The same question asked in multiple notes but never answered.
83
- > "You've asked 'what's our rollback strategy?' in 4 different meeting notes but no note contains an answer."
84
-
85
- **Implicit decisions**: A direction was taken without a documented decision.
86
- > "Notes shifted from Option A to Option B around April, but no decision record exists."
87
-
88
- **Convergent threads**: Separate lines of thinking that are heading toward the same conclusion.
89
- > "Your notes on 'API rate limiting' and 'user quotas' both point toward a tiered access model, but neither note references the other."
90
-
91
- **Forgotten threads**: Topics that received attention then went silent.
92
- > "'Data mesh' appears in 6 notes between Jan-Mar but hasn't been mentioned since."
93
-
94
- **Expertise gaps**: The vault references a topic repeatedly but always superficially.
95
- > "'Kubernetes networking' appears in 12 notes but always as a dependency, never deeply explored."
96
-
97
- **Contradictions**: Conflicting statements across notes.
98
- > "In [[Note A]] you wrote 'we should avoid microservices' but [[Note B]] proposes splitting the monolith."
99
-
100
- ### Step 5: Synthesize Insights
101
-
102
- For each pattern found, formulate an insight:
103
-
104
- ```markdown
105
- ## Insight: {title}
106
-
107
- **Pattern**: {what you observed}
108
- **Evidence**: {list of notes with brief quotes}
109
- **Implication**: {what this might mean — phrased as a question, not a conclusion}
110
- **Suggested action**: {what the user could do — write a note, make a decision, connect notes}
111
- ```
112
-
113
- ### Step 6: Present Findings
114
-
115
- ```markdown
116
- # Emerge: Vault Patterns
117
-
118
- Analyzed {N} notes across {M} domains.
119
-
120
- ## Key Findings
121
-
122
- ### 1. {Insight title}
123
- {Pattern, evidence, implication, action}
124
-
125
- ### 2. {Insight title}
126
- ...
127
-
128
- ## Structural Observations
129
-
130
- - **Most connected**: [[Note]] ({N} backlinks) — your thinking hub
131
- - **Most isolated**: {N} orphan notes that may contain undeveloped ideas
132
- - **Busiest domain**: {domain} ({N} notes)
133
- - **Thinnest domain**: {domain} ({N} notes) — possible blind spot
134
-
135
- ## Suggested Next Steps
136
-
137
- 1. {Actionable suggestion — e.g. "Connect [[A]] and [[B]] — they discuss the same problem"}
138
- 2. {Actionable suggestion — e.g. "Write a decision record for the implicit choice between X and Y"}
139
- 3. {Actionable suggestion — e.g. "Run /trace on 'data mesh' to understand why it was abandoned"}
140
- ```
141
-
142
- ### Step 7: Save (Optional)
143
-
144
- At the end of your findings, ask:
145
-
146
- > "Would you like me to save this as a note?"
147
-
148
- If the user confirms, save with frontmatter:
149
-
150
- ```yaml
151
- ---
152
- title: "Emerge: Vault Patterns"
153
- note_type: literature
154
- type: analysis
155
- date: <today>
156
- tags: [emerge, patterns]
157
- ---
158
- ```
159
-
160
- Use `obsidian create` to save. Ask the user where they'd like it saved.
161
-
162
- ## Key Principles
163
-
164
- - **Show, don't tell**: Always cite specific notes and quotes. Never claim a pattern exists without evidence.
165
- - **Questions over conclusions**: Frame implications as questions the user should consider, not answers you've decided.
166
- - **Respect user judgment**: The user may be aware of patterns and have chosen not to act. Present findings neutrally.
167
- - **Prioritize actionable insights**: "These two notes should link to each other" is more useful than "your vault has 12 orphans."
168
- - **Deep mode means thorough**: In "deep" mode, read every note in scope. In "quick" mode, use structural signals and sampling.
@@ -1,287 +0,0 @@
1
- ---
2
- name: weave
3
- description: Scan vault notes, enrich with frontmatter + wikilinks, suggest permanent concept notes, and create a connected knowledge graph. Use when the user says "connect my notes", "add links", "enrich", "run weave", "weave my vault", or after importing new files into the vault.
4
- ---
5
-
6
- # /weave — Connect Your Notes
7
-
8
- You are a knowledge graph builder. Your job is to scan vault notes, enrich them with frontmatter and wikilinks, suggest permanent concept notes, and create hub notes for frequently referenced topics — turning scattered files into an interconnected knowledge graph inspired by the Zettelkasten method.
9
-
10
- ## Prerequisites Check
11
-
12
- **Before doing anything else**, verify Obsidian CLI is available:
13
-
14
- ```bash
15
- obsidian --version
16
- ```
17
-
18
- If this fails, STOP and display:
19
-
20
- ```
21
- Obsidian CLI is not available. Please ensure:
22
- 1. Obsidian is running
23
- 2. This vault is open in Obsidian
24
- 3. CLI is enabled: Settings → General → Advanced → Command-line interface
25
- ```
26
-
27
- Do NOT proceed with degraded results — graph queries are essential.
28
-
29
- ## Parameters
30
-
31
- - **file** (optional): Path to a single file to weave. If omitted, scan the entire vault.
32
- - **folder** (optional): Path to a folder to scan. If omitted, scan the entire vault.
33
- - **dry-run** (optional): If set, show proposed changes without applying them.
34
-
35
- ## File Exclusion Rules
36
-
37
- When scanning files, skip:
38
-
39
- | Pattern | Reason |
40
- |---------|--------|
41
- | `.obsidian/` | Obsidian internal config |
42
- | `.git/` | Git internals |
43
- | `.byoao/` | BYOAO internal data |
44
- | `node_modules/` | Dependencies |
45
- | `.env`, `credentials.*`, `*.key` | Sensitive files |
46
- | Binary files (images, PDFs, etc.) | Cannot add frontmatter/wikilinks |
47
- | `AGENTS.md` | BYOAO-managed file |
48
- | `*.base` | Obsidian Base files — not user content notes |
49
-
50
- Report skipped non-markdown files at the end: "Skipped N non-markdown files".
51
-
52
- ## Process
53
-
54
- Execute these steps in order. Be explicit about each tool call — different LLM providers must execute this consistently.
55
-
56
- ### Step 1: Build Vault Map
57
-
58
- ```bash
59
- obsidian list
60
- ```
61
-
62
- This gives you the full list of notes. Also run:
63
-
64
- ```bash
65
- obsidian properties sort=count counts
66
- ```
67
-
68
- This reveals the vault's structure — which properties are used, how many notes have frontmatter.
69
-
70
- ### Step 2: Scan Target Files
71
-
72
- For each markdown file in scope (respecting exclusion rules):
73
-
74
- #### 2a. Read the file
75
-
76
- ```bash
77
- obsidian read "<note name>"
78
- ```
79
-
80
- #### 2b. Identify entities
81
-
82
- Scan the content for concepts using semantic understanding (not a predefined list):
83
-
84
- - **People names** — proper nouns that appear to be people
85
- - **Project/product names** — capitalized multi-word phrases that recur
86
- - **Domain concepts** — technical terms, acronyms, recurring themes
87
- - **Tool/system names** — software, services, platforms mentioned
88
- - **Dates and events** — meetings, deadlines, milestones
89
- - **Methodologies/frameworks** — named approaches like "Zettelkasten", "Agile", etc.
90
-
91
- #### 2c. Cross-reference against existing notes
92
-
93
- For each entity found:
94
-
95
- 1. Does a vault note with this name exist? → Mark as wikilink candidate
96
- 2. Is it a new, unrecognized concept? → Track for permanent note suggestion (Step 4)
97
-
98
- #### 2d. Propose frontmatter
99
-
100
- If the file has no frontmatter, or has incomplete frontmatter, propose additions:
101
-
102
- ```yaml
103
- ---
104
- title: "<inferred from content or filename>"
105
- note_type: <fleeting | literature | permanent>
106
- type: "<inferred: meeting, idea, reference, daily, project, person, etc>"
107
- date: YYYY-MM-DD
108
- domain: "<knowledge area: analytics, infrastructure, design, etc>"
109
- references:
110
- - "[[Related Note]]"
111
- tags: [<relevant tags>]
112
- status: <draft | active | completed | archived>
113
- source: "<URL if this note originates from a cloud document>"
114
- ---
115
- ```
116
-
117
- **note_type classification (Zettelkasten):**
118
-
119
- | `note_type` | When to use |
120
- |-------------|-------------|
121
- | `fleeting` | Raw inputs: quick notes, meeting minutes, clipped articles, thoughts not yet processed |
122
- | `literature` | Processed references: summaries of papers, books, articles, or external sources |
123
- | `permanent` | Atomic concepts: single-idea notes that synthesize understanding from multiple sources |
124
-
125
- If unsure, default to `fleeting` — the user can reclassify later.
126
-
127
- **Date resolution (mandatory — never leave empty):**
128
-
129
- 1. Extract from content — explicit dates in the text, meeting dates, file name patterns (e.g. `2026-03-27-meeting.md`)
130
- 2. If no date in content, get the file creation time:
131
- ```bash
132
- stat -f '%SB' -t '%Y-%m-%d' "<file path>" # macOS
133
- stat -c '%w' "<file path>" # Linux (birth time)
134
- ```
135
- If birth time is unavailable (`-` or empty), fall back to modification time:
136
- ```bash
137
- stat -f '%Sm' -t '%Y-%m-%d' "<file path>" # macOS
138
- stat -c '%y' "<file path>" # Linux
139
- ```
140
- 3. Never leave `date` empty in the proposed frontmatter.
141
-
142
- **Source field (optional):**
143
-
144
- - Add `source` only when the note clearly originates from a cloud document (e.g. contains Confluence export markers, Google Docs formatting, or a URL in the content pointing to the original).
145
- - If the file already has a `source` field, always preserve it.
146
-
147
- **Frontmatter preservation rules:**
148
- - **Never overwrite** existing fields
149
- - **Only add** missing fields
150
- - **Merge arrays** — if file has `tags: [meeting]` and you suggest `tags: [meeting, migration]`, result is `[meeting, migration]`
151
- - **Warn on conflicts** — if existing value seems wrong, note it but don't change it
152
-
153
- #### 2e. Propose wikilinks
154
-
155
- Convert plain text mentions to `[[wikilinks]]`:
156
-
157
- - Existing note names → `[[Note Name]]`
158
- - People → `[[Person Name]]`
159
- - Domain concepts → `[[Concept Name]]`
160
-
161
- Rules:
162
- - Only link the **first occurrence** of each term in a file
163
- - Don't link inside code blocks, frontmatter, or existing wikilinks
164
- - Don't link common English words even if they happen to match a note name
165
- - Preserve the original text when the casing differs: `rate limiting` → `[[Rate Limiting|rate limiting]]`
166
-
167
- ### Step 3: Backup Before Modification
168
-
169
- Before modifying any file, create a backup:
170
-
171
- ```bash
172
- mkdir -p .byoao/backups/<timestamp>
173
- cp "<file path>" ".byoao/backups/<timestamp>/<filename>"
174
- ```
175
-
176
- Use the current date-time as the timestamp (e.g., `2026-03-27T20-45`).
177
-
178
- This is critical for existing folder adoption where files are user-created and irreplaceable.
179
-
180
- ### Step 4: Apply Changes
181
-
182
- For each file with proposed changes:
183
- 1. Show the user a summary of proposed changes (frontmatter additions, wikilinks to add)
184
- 2. Wait for confirmation before applying
185
- 3. Apply changes using file edit tools
186
-
187
- ### Step 5: Suggest Permanent Notes
188
-
189
- After scanning all files, analyze concept frequency across the vault:
190
-
191
- **When to suggest a permanent note:**
192
- - A concept appears in 3+ notes
193
- - No dedicated note exists for that concept
194
- - The concept has a clear, non-ambiguous definition
195
-
196
- For each candidate, present to the user:
197
-
198
- ```markdown
199
- ### Permanent Note Candidate: [[Concept Name]]
200
-
201
- **Appears in:** [[Note A]], [[Note B]], [[Note C]]
202
-
203
- **Proposed content:**
204
-
205
- ---
206
- title: "Concept Name"
207
- note_type: permanent
208
- type: reference
209
- domain: <inferred from source notes>
210
- date: <today>
211
- tags: [<inferred>]
212
- references:
213
- - "[[Note A]]"
214
- - "[[Note B]]"
215
- ---
216
-
217
- # Concept Name
218
-
219
- *Auto-generated by /weave — this concept appears across multiple notes. Review and refine.*
220
-
221
- ## Summary
222
- <1-2 sentence summary synthesized from source notes>
223
-
224
- ## References
225
- - [[Note A]] — <context>
226
- - [[Note B]] — <context>
227
- ```
228
-
229
- Ask the user: "Create this permanent note?" Only create if confirmed.
230
-
231
- ### Step 6: Suggest Note Splitting (Zettelkasten Atomicity)
232
-
233
- Check for notes that contain multiple independent concepts. For each candidate:
234
-
235
- ```markdown
236
- ### Split Suggestion: [[Multi-Concept Note]]
237
-
238
- This note appears to cover multiple distinct concepts:
239
- 1. **Concept A** — <brief description>
240
- 2. **Concept B** — <brief description>
241
- 3. **Concept C** — <brief description>
242
-
243
- Consider splitting these into separate atomic notes for better knowledge graph connectivity.
244
- ```
245
-
246
- **Do NOT split automatically.** Only suggest; the user decides.
247
-
248
- ### Step 7: Directory Organization (optional)
249
-
250
- If the vault has many files in flat or disorganized directories, suggest:
251
-
252
- "Your vault has files that could benefit from reorganization.
253
- Run `/organize` to see a proposed directory structure based on
254
- the frontmatter metadata we just added. It uses `obsidian move`
255
- to safely relocate files while automatically updating all links."
256
-
257
- Do NOT move files during /weave — directory reorganization is
258
- a separate step handled by `/organize`.
259
-
260
- ### Step 8: Report
261
-
262
- After all changes are applied, provide a summary:
263
-
264
- ```
265
- Weave complete:
266
- - Scanned: N files
267
- - Enriched: N files (frontmatter + wikilinks)
268
- - Wikilinks added: N
269
- - Permanent notes created: N
270
- - Split suggestions: N (pending user review)
271
- - Orphaned files (no links): N
272
- - Skipped: N non-markdown files
273
- - Backups: .byoao/backups/<timestamp>/
274
- ```
275
-
276
- ## Single File Mode
277
-
278
- When `file=` is provided, run the same process but only for that one file. Still read the vault map and check for cross-references, but skip Steps 5-6 (permanent note generation and split suggestions are batch operations).
279
-
280
- ## Important Guidelines
281
-
282
- - **Be conservative**: When in doubt about a wikilink or frontmatter value, skip it. False positives degrade trust.
283
- - **Ask, don't assume**: Always present changes for user confirmation before applying.
284
- - **Preserve user content**: Never delete, rewrite, or reorganize existing text. Only add metadata and convert mentions to links.
285
- - **Domain inference**: Use existing note domains to infer the domain for new notes. Consistency matters.
286
- - **Idempotent**: Running /weave twice on the same file should not add duplicate wikilinks or frontmatter fields.
287
- - **Zettelkasten principle**: Favor atomicity. One idea per note. Suggest splits for multi-concept notes.
@@ -1,21 +0,0 @@
1
- import { tool } from "@opencode-ai/plugin/tool";
2
- import { addGlossaryTerm } from "../vault/glossary.js";
3
- export const byoao_add_glossary_term = tool({
4
- description: "Add a new term to the vault's Glossary.md. Appends a row to the Core Terms table.",
5
- args: {
6
- vaultPath: tool.schema.string().describe("Path to the Obsidian vault"),
7
- term: tool.schema.string().describe("The domain term to add"),
8
- definition: tool.schema.string().describe("Brief definition (1-2 sentences)"),
9
- domain: tool.schema.string().optional().describe("Knowledge domain (e.g. analytics, infrastructure)"),
10
- },
11
- async execute(args) {
12
- const result = await addGlossaryTerm({
13
- vaultPath: args.vaultPath,
14
- term: args.term,
15
- definition: args.definition,
16
- domain: args.domain ?? "",
17
- });
18
- return `✓ Added glossary term: ${result.termAdded}\n File: ${result.glossaryPath}`;
19
- },
20
- });
21
- //# sourceMappingURL=add-glossary-term.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"add-glossary-term.js","sourceRoot":"","sources":["../../src/tools/add-glossary-term.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC;IAC1C,WAAW,EACT,mFAAmF;IACrF,IAAI,EAAE;QACJ,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;QACtE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;QAC7D,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;QAC7E,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mDAAmD,CAAC;KACtG;IACD,KAAK,CAAC,OAAO,CAAC,IAAI;QAChB,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC;YACnC,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;SAC1B,CAAC,CAAC;QAEH,OAAO,0BAA0B,MAAM,CAAC,SAAS,aAAa,MAAM,CAAC,YAAY,EAAE,CAAC;IACtF,CAAC;CACF,CAAC,CAAC"}
@@ -1,21 +0,0 @@
1
- import { tool } from "@opencode-ai/plugin/tool";
2
- import { addMember } from "../vault/member.js";
3
- export const byoao_add_person = tool({
4
- description: "Add a person note to an existing vault. Creates a person note in People/ and updates the team index and AGENTS.md wikilinks.",
5
- args: {
6
- vaultPath: tool.schema.string().describe("Path to the Obsidian vault"),
7
- name: tool.schema.string().describe("Person's full name"),
8
- role: tool.schema.string().optional().describe("Person's role/title"),
9
- team: tool.schema.string().optional().describe("Team or KB name"),
10
- },
11
- async execute(args) {
12
- const result = await addMember({
13
- vaultPath: args.vaultPath,
14
- name: args.name,
15
- role: args.role || "",
16
- team: args.team || "",
17
- });
18
- return `Added person: ${args.name}\n File: ${result.filePath}\n Wikilinks updated: ${result.wikilinksAdded}`;
19
- },
20
- });
21
- //# sourceMappingURL=add-person.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"add-person.js","sourceRoot":"","sources":["../../src/tools/add-person.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC;IACnC,WAAW,EACT,8HAA8H;IAChI,IAAI,EAAE;QACJ,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;QACtE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;QACzD,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;QACrE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;KAClE;IACD,KAAK,CAAC,OAAO,CAAC,IAAI;QAChB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC;YAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;SACtB,CAAC,CAAC;QAEH,OAAO,iBAAiB,IAAI,CAAC,IAAI,aAAa,MAAM,CAAC,QAAQ,0BAA0B,MAAM,CAAC,cAAc,EAAE,CAAC;IACjH,CAAC;CACF,CAAC,CAAC"}
@@ -1,24 +0,0 @@
1
- import { tool } from "@opencode-ai/plugin/tool";
2
- import { addProject } from "../vault/project.js";
3
- export const byoao_add_project = tool({
4
- description: "Add a new project note to an existing vault. Creates a project note in Projects/ and updates the team index and AGENTS.md wikilinks.",
5
- args: {
6
- vaultPath: tool.schema.string().describe("Path to the Obsidian vault"),
7
- name: tool.schema.string().describe("Project name"),
8
- description: tool.schema
9
- .string()
10
- .optional()
11
- .describe("One-line project description"),
12
- team: tool.schema.string().optional().describe("Team name"),
13
- },
14
- async execute(args) {
15
- const result = await addProject({
16
- vaultPath: args.vaultPath,
17
- name: args.name,
18
- description: args.description || "",
19
- team: args.team || "",
20
- });
21
- return `✓ Added project: ${args.name}\n File: ${result.filePath}\n Wikilinks updated: ${result.wikilinksAdded}`;
22
- },
23
- });
24
- //# sourceMappingURL=add-project.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"add-project.js","sourceRoot":"","sources":["../../src/tools/add-project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC;IACpC,WAAW,EACT,sIAAsI;IACxI,IAAI,EAAE;QACJ,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;QACtE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;QACnD,WAAW,EAAE,IAAI,CAAC,MAAM;aACrB,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,8BAA8B,CAAC;QAC3C,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;KAC5D;IACD,KAAK,CAAC,OAAO,CAAC,IAAI;QAChB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC;YAC9B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;YACnC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;SACtB,CAAC,CAAC;QAEH,OAAO,oBAAoB,IAAI,CAAC,IAAI,aAAa,MAAM,CAAC,QAAQ,0BAA0B,MAAM,CAAC,cAAc,EAAE,CAAC;IACpH,CAAC;CACF,CAAC,CAAC"}
@@ -1,25 +0,0 @@
1
- import { tool } from "@opencode-ai/plugin/tool";
2
- import { getGraphHealth } from "../vault/graph-health.js";
3
- export const byoao_graph_health = tool({
4
- description: "Diagnose Obsidian vault graph health — find orphan notes (no links in or out), unresolved links (broken wikilinks), and dead-end notes. Uses Obsidian CLI for vault-aware analysis.",
5
- args: {
6
- vaultPath: tool.schema.string().describe("Absolute path to the Obsidian vault"),
7
- check: tool.schema
8
- .enum(["all", "orphans", "unresolved", "deadends"])
9
- .optional()
10
- .describe("Which check to run: 'all' (default), 'orphans', 'unresolved', or 'deadends'"),
11
- limit: tool.schema
12
- .number()
13
- .optional()
14
- .describe("Maximum number of results to return (default: 20)"),
15
- },
16
- async execute(args) {
17
- const result = await getGraphHealth({
18
- vaultPath: args.vaultPath,
19
- check: args.check,
20
- limit: args.limit,
21
- });
22
- return JSON.stringify(result, null, 2);
23
- },
24
- });
25
- //# sourceMappingURL=graph-health.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"graph-health.js","sourceRoot":"","sources":["../../src/tools/graph-health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC;IACrC,WAAW,EACT,qLAAqL;IACvL,IAAI,EAAE;QACJ,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;QAC/E,KAAK,EAAE,IAAI,CAAC,MAAM;aACf,IAAI,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;aAClD,QAAQ,EAAE;aACV,QAAQ,CACP,6EAA6E,CAC9E;QACH,KAAK,EAAE,IAAI,CAAC,MAAM;aACf,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,mDAAmD,CAAC;KACjE;IACD,KAAK,CAAC,OAAO,CAAC,IAAI;QAChB,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC;YAClC,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,KAAK,EAAE,IAAI,CAAC,KAAkE;YAC9E,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACzC,CAAC;CACF,CAAC,CAAC"}
@@ -1,19 +0,0 @@
1
- import { tool } from "@opencode-ai/plugin/tool";
2
- import { readNote } from "../vault/note-read.js";
3
- export const byoao_note_read = tool({
4
- description: "Read a specific note from an Obsidian vault by name. Uses Obsidian CLI to resolve and read the note. Preferred over cat/Read for Obsidian vault notes.",
5
- args: {
6
- vaultPath: tool.schema.string().describe("Absolute path to the Obsidian vault"),
7
- file: tool.schema
8
- .string()
9
- .describe("Note name to read (without .md extension, e.g. 'Refund Automation')"),
10
- },
11
- async execute(args) {
12
- const result = await readNote({
13
- vaultPath: args.vaultPath,
14
- file: args.file,
15
- });
16
- return JSON.stringify(result, null, 2);
17
- },
18
- });
19
- //# sourceMappingURL=note-read.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"note-read.js","sourceRoot":"","sources":["../../src/tools/note-read.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;IAClC,WAAW,EACT,wJAAwJ;IAC1J,IAAI,EAAE;QACJ,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;QAC/E,IAAI,EAAE,IAAI,CAAC,MAAM;aACd,MAAM,EAAE;aACR,QAAQ,CAAC,qEAAqE,CAAC;KACnF;IACD,KAAK,CAAC,OAAO,CAAC,IAAI;QAChB,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC;YAC5B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACzC,CAAC;CACF,CAAC,CAAC"}
@@ -1,22 +0,0 @@
1
- import { tool } from "@opencode-ai/plugin/tool";
2
- import { searchVault } from "../vault/search-vault.js";
3
- export const byoao_search_vault = tool({
4
- description: "Search an Obsidian vault for notes matching a text query. Uses Obsidian CLI search:context for vault-aware results. Preferred over grep/rg for Obsidian vault knowledge queries about notes, tags, and content.",
5
- args: {
6
- vaultPath: tool.schema.string().describe("Absolute path to the Obsidian vault"),
7
- query: tool.schema.string().describe("Text query to search for in vault notes"),
8
- limit: tool.schema
9
- .number()
10
- .optional()
11
- .describe("Maximum number of results to return (default: 20)"),
12
- },
13
- async execute(args) {
14
- const result = await searchVault({
15
- vaultPath: args.vaultPath,
16
- query: args.query,
17
- limit: args.limit,
18
- });
19
- return JSON.stringify(result, null, 2);
20
- },
21
- });
22
- //# sourceMappingURL=search-vault.js.map