@imunitic/synapse 0.1.2 → 0.2.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.
@@ -69,7 +69,7 @@ function readObsidianPluginData() {
69
69
  const { resolveVaultDir } = require("../lib/obsidian-mcp-refresh.cjs");
70
70
  const vault = resolveVaultDir();
71
71
  if (!vault || !fs.existsSync(vault)) {
72
- fail("no OBSIDIAN_VAULT_DIR resolvable (see synapse.conf) -- can't configure the obsidian MCP connection");
72
+ fail("no SYNAPSE_VAULT_DIR resolvable (see synapse.conf) -- can't configure the obsidian MCP connection");
73
73
  }
74
74
  const pluginDataPath = path.join(vault, ".obsidian", "plugins", "obsidian-local-rest-api", "data.json");
75
75
  if (!fs.existsSync(pluginDataPath)) {
@@ -17,14 +17,14 @@ Not every design discussion ends with something to build. See `Status: Reference
17
17
  ```
18
18
  /synapse-design-note "topic" # Start or resume a design discussion
19
19
  /synapse-design-note --continue # Resume an incomplete design note
20
- /synapse-design-note --list # List every Obsidian design note, regardless of status
20
+ /synapse-design-note --list # List every design note in the vault, regardless of status
21
21
  ```
22
22
 
23
23
  ## Prerequisites
24
24
 
25
- - Requires the `obsidian` MCP server (`mcp__obsidian__*` tools). If unreachable, say so and stop —
26
- there is no local-file fallback for this command.
27
- - If `designs/` doesn't exist in the vault yet, `mcp__obsidian__vault_write` creates it implicitly on
25
+ - Requires the `synapse` CLI on `PATH`. If it errors (no vault configured), say so and stop —
26
+ there is no other fallback for this command.
27
+ - If `designs/` doesn't exist in the vault yet, `synapse vault-write` creates it implicitly on
28
28
  first write — but add a `designs/` entry to the vault's `Index.md` folder layout in the same
29
29
  action (per the Synapse Vault folder-layout rule: a new top-level folder must never fall behind the
30
30
  index).
@@ -34,7 +34,7 @@ Not every design discussion ends with something to build. See `Status: Reference
34
34
  Every design note is tagged with the project it belongs to — both in the title
35
35
  (`{PROJECT} — {Topic}`) and as `project: {prefix}` in frontmatter (the same short prefix
36
36
  `/synapse-note --task` uses for task IDs) — so a flat `designs/` folder still reads clearly, and
37
- both note kinds can be filtered together via `search_query`.
37
+ both note kinds can be filtered together via `synapse vault-search`.
38
38
 
39
39
  Same resolution `/synapse-note` uses for a missing task ID (its "Resolving a missing task ID"),
40
40
  reading the same file:
@@ -59,15 +59,22 @@ unrelated contexts (e.g. personal vs. work) never end up in the same place.
59
59
  ## Handling Arguments
60
60
 
61
61
  **No arguments:**
62
- 1. Check for incomplete design notes: search `designs/` (via `mcp__obsidian__vault_list` +
63
- `vault_read`, or `search_query` scoped to the `designs/` path) for notes whose `## Status` line
64
- reads `Discussing`.
62
+ 1. Check for incomplete design notes: `synapse vault-search --fields frontmatter.title` with the
63
+ query below on stdin one call, no separate read needed:
64
+
65
+ ```
66
+ {"and": [
67
+ {"glob": ["designs/*", {"var": "path"}]},
68
+ {"regexp": ["## Status\\nDiscussing", {"var": "content"}]}
69
+ ]}
70
+ ```
65
71
  2. If found: show a short state summary — title and current section — and offer to resume.
66
72
  3. If none: ask "What are we designing?"
67
73
 
68
74
  **With a topic:**
69
- 1. Search first — `mcp__obsidian__search_simple` for the topic text across `designs/` (per the
70
- Synapse Vault rule: link/reuse over duplicate). Also check for an obvious title match.
75
+ 1. Search first — `synapse vault-search-text "{topic}"` for the topic text, then filter matches to
76
+ `designs/` paths (per the Synapse Vault rule: link/reuse over duplicate). Also check for an
77
+ obvious title match.
71
78
  2. If found with `Status: Discussing` → ask "Resume this design?" or "Start fresh?"
72
79
  3. If found with `Status: Ready` → ask "Already marked Ready. Reopen to revise, or start a new note?"
73
80
  4. If found with `Status: Reference` → ask "This concluded as Reference (no implementation intended).
@@ -82,8 +89,9 @@ unrelated contexts (e.g. personal vs. work) never end up in the same place.
82
89
  4. None → "No incomplete design note found. Start one with `/synapse-design-note \"topic\"`."
83
90
 
84
91
  **--list:**
85
- 1. `mcp__obsidian__vault_list` on `designs/`, then `vault_read` each (or a `search_query` scoped to
86
- that path) to pull title and `## Status`.
92
+ 1. `synapse vault-search --fields frontmatter.title,content` with `{"glob": ["designs/*", {"var":
93
+ "path"}]}` on stdin — every design note regardless of status, title and `## Status` line both in
94
+ the same row.
87
95
  2. None found → "No design notes yet. Start one with `/synapse-design-note \"topic\"`."
88
96
  3. Group into **Active** (`Discussing`, `Ready`) and **Closed** (`Reference`) — active first, title
89
97
  and status in backticks, not bold.
@@ -23,7 +23,7 @@ No arguments — always operates on the repo containing the current working dire
23
23
 
24
24
  ## Prerequisites
25
25
 
26
- - Requires the `obsidian` MCP server (`mcp__obsidian__*` tools). If unreachable, say so and stop.
26
+ - Requires the `synapse` CLI on `PATH`. If it errors (no vault configured), say so and stop.
27
27
  - Must be run from inside a git repository. Synapse assumes git throughout (source hashing uses
28
28
  `git hash-object`, file enumeration uses `git ls-files`) — if `git rev-parse --show-toplevel`
29
29
  fails, stop and say this only works inside a git repo.
@@ -65,8 +65,8 @@ Every step below needs the same three facts, resolved once up front:
65
65
 
66
66
  ## Already initialized?
67
67
 
68
- Check whether `synapse/{repo}@{branch}/Index.md` exists (`mcp__obsidian__vault_list` on
69
- `synapse/{repo}@{branch}/`, or a direct `vault_read` attempt).
68
+ Check whether `synapse/{repo}@{branch}/Index.md` exists: `synapse vault-read
69
+ "synapse/{repo}@{branch}/Index.md"` and see whether it succeeds or reports "no such note".
70
70
 
71
71
  - **Doesn't exist** → this is a first-time build. Go to "First-time build" below.
72
72
  - **Exists, `remote` frontmatter matches** the resolved remote/path → this namespace already
@@ -26,7 +26,7 @@ If no match is found, **don't just leave it blank** — see "Resolving a missing
26
26
 
27
27
  ## List mode
28
28
 
29
- Use `mcp__obsidian__search_query` with the JsonLogic query `{"var": "frontmatter.task_id"}` — this returns every file that has a `task_id` set, along with that file's `task_id` value as `result`. For each match, also read the file's `status` and `title` (either via a second query `{"var": "frontmatter.status"}` / `{"var": "frontmatter.title"}`, or via `mcp__obsidian__vault_read` on the handful of matched files — whichever is fewer round-trips for the count involved).
29
+ Run `synapse vault-search --fields frontmatter.task_id,frontmatter.status,frontmatter.title` with the JsonLogic query `{"var": "frontmatter.task_id"}` on stdin one call returns every file that has a `task_id` set, each row already carrying `task_id`/`status`/`title` together, no second query or extra read needed.
30
30
 
31
31
  Categorize:
32
32
  - **Prefixed notes**: `task_id` matches `{prefix}-\d+`. Group by the distinct prefix found (whatever
@@ -43,8 +43,8 @@ Do not modify any files in list mode.
43
43
 
44
44
  Everything after `--search` (trimmed, quotes stripped) is the query.
45
45
 
46
- 1. Run `mcp__obsidian__search_simple` with the query — this gives full-text relevance-ranked matches with context, the closest equivalent to a title/body search.
47
- 2. If the query looks like it's targeting metadata specifically (a tag, a task ID, a status value) rather than free text, also run `mcp__obsidian__search_query` with an appropriate JsonLogic filter (e.g. `{"==": [{"var": "frontmatter.task_id"}, "proj-032"]}`).
46
+ 1. Run `synapse vault-search-text "{query}"` — this gives full-text relevance-ranked matches with context, the closest equivalent to a title/body search.
47
+ 2. If the query looks like it's targeting metadata specifically (a tag, a task ID, a status value) rather than free text, also run `synapse vault-search --fields frontmatter.title` with an appropriate JsonLogic filter on stdin (e.g. `{"==": [{"var": "frontmatter.task_id"}, "proj-032"]}`).
48
48
  3. Report matches as `{title} — {file path relative to vault root}`, deduped across both. If nothing matches, say so plainly — the caller (agent or user) needs a clear "no existing note" signal to proceed with `--task`-less creation.
49
49
 
50
50
  Do not modify any files in search mode.
@@ -54,8 +54,8 @@ Do not modify any files in search mode.
54
54
  Triggered when `--task` is given but the title doesn't match `{prefix}-\d+`.
55
55
 
56
56
  The known project/prefix pairs live in a plain local file named `synapse-projects.conf` (one
57
- `project-name=prefix` line each) — read/appended with the Read/Edit tools, not the `obsidian`
58
- MCP server, since it's outside the vault. It is deliberately **not** part of the portable
57
+ `project-name=prefix` line each) — read/appended with the Read/Edit tools, not the `vault-*` subcommands,
58
+ since it's outside the vault. It is deliberately **not** part of the portable
59
59
  Synapse package and never copied between machines, so contexts that shouldn't mix (e.g.
60
60
  personal vs. work projects) never end up in the same file. It's self-managed — this command appends
61
61
  newly resolved pairs to it — but also plain text, so the user can add, fix, or remove a line by hand
@@ -77,8 +77,8 @@ unchanged for anyone who has never touched an XDG config directory.
77
77
  2. Check the resolved `synapse-projects.conf` for a line whose project name matches (loosely —
78
78
  case/whitespace-insensitive). If found, use that prefix directly — no need to ask.
79
79
  3. If the file doesn't have it yet, fall back to deducing from the vault itself (useful the first
80
- time this runs, or for a project whose notes predate this file): `search_simple` for the
81
- project/repo name across existing notes, and/or `search_query` on
80
+ time this runs, or for a project whose notes predate this file): `synapse vault-search-text` for
81
+ the project/repo name across existing notes, and/or `synapse vault-search` on
82
82
  `{"var": "frontmatter.task_id"}` to see which prefixes exist, then check whether any of those
83
83
  prefixed notes reference this project. If exactly one prefix confidently matches, use it.
84
84
  4. If nothing confidently matches (new project, or an ambiguous/multiple match), ask the user
@@ -87,11 +87,10 @@ unchanged for anyone who has never touched an XDG config directory.
87
87
  5. Whenever step 3 or step 4 resolves a pair not already in the conf file (including a fresh
88
88
  `project-name=prefix` line matching what was just deduced or asked), append it — so the next task
89
89
  for this project resolves from step 2 without a search or a question.
90
- 6. Once the prefix is known, find the next number: run
91
- `mcp__obsidian__search_query` with `{"var": "frontmatter.task_id"}`,
92
- filter the returned `result` values client-side for ones matching
93
- `{prefix}-\d+`, take the highest number found, add 1. If none exist yet
94
- for that prefix, start at 1.
90
+ 6. Once the prefix is known, find the next number: run `synapse vault-search --fields
91
+ frontmatter.task_id` with `{"var": "frontmatter.task_id"}` on stdin, filter the returned values
92
+ client-side for ones matching `{prefix}-\d+`, take the highest number found, add 1. If none exist
93
+ yet for that prefix, start at 1.
95
94
  7. Format the new task ID **zero-padded to 3 digits** (`{prefix}-001`, `{prefix}-030`,
96
95
  `{prefix}-037`, ...), matching the org-roam-era convention — widening
97
96
  naturally past 3 digits if a prefix ever needs it.
@@ -181,7 +180,7 @@ or supplied directly by a caller like `/synapse-task-note`):
181
180
  ## Notes
182
181
 
183
182
  ```
184
- 4. Write it with `mcp__obsidian__vault_write`. Task mode: path
183
+ 4. Write it with `synapse vault-write <path>` (content on stdin). Task mode: path
185
184
  `tasks/{project}/{filename}.md` (project resolved in "Resolving the
186
185
  project folder" above). Bare mode: path `{category}/{filename}.md`
187
186
  (category resolved above).
@@ -29,7 +29,7 @@ No arguments — always operates on the repo and branch containing the current w
29
29
 
30
30
  ## Prerequisites
31
31
 
32
- - Requires the `obsidian` MCP server (`mcp__obsidian__*` tools). If unreachable, say so and stop —
32
+ - Requires the `synapse` CLI on `PATH`. If it errors (no vault configured), say so and stop —
33
33
  same requirement `/synapse-init` has.
34
34
  - Must be run from inside a git repository, on a named branch (not detached `HEAD`) — same
35
35
  requirement `/synapse-init` has, since `synapse_namespace` needs a branch to key on.
@@ -6,12 +6,11 @@ description: Print a read-only report of what in Synapse Vault currently needs a
6
6
 
7
7
  A read-only sweep over Synapse Vault answering one question: what currently needs a human decision?
8
8
  Five categories, one pass, printed as plain chat text -- an org-agenda-style check-in, not a document
9
- to hand to someone else and not a live dashboard (a published Artifact has no route to the local
10
- Obsidian REST API, so nothing here is ever presented that way). Run it on demand, or from a
11
- scheduled `/loop`/cron invocation of this same command -- never wired into `SessionStart`: two of
12
- the five categories need a per-note body read, not just a frontmatter check, and unlike `Index.md`
13
- this report is a periodic human check-in, not something the agent needs injected every session to
14
- behave correctly.
9
+ to hand to someone else and not a live dashboard (a published Artifact has no route to the vault, so
10
+ nothing here is ever presented that way). Run it on demand, or from a scheduled `/loop`/cron
11
+ invocation of this same command -- never wired into `SessionStart`: some of the five categories need
12
+ a per-note content read, not just a frontmatter check, and unlike `Index.md` this report is a
13
+ periodic human check-in, not something the agent needs injected every session to behave correctly.
15
14
 
16
15
  Scoped to `designs/`/`tasks/` only -- the two folders `/synapse-design-note`/`/synapse-note --task`
17
16
  structurally require, so every Synapse install has them in the same shape. The free-form taxonomy
@@ -27,79 +26,93 @@ periodic look on their own schedule -- this report doesn't cover it.
27
26
 
28
27
  ## Prerequisites
29
28
 
30
- Requires the `obsidian` MCP server (`mcp__obsidian__*` tools). If unreachable, say so and stop --
31
- there is no local-file fallback.
29
+ Requires the `synapse` CLI on `PATH`. Backend-agnostic -- every query below goes through `synapse
30
+ vault-search`, so it works the same whether the vault is Obsidian-backed or plain-disk-backed. If the
31
+ CLI errors (no vault configured), say so and stop -- there is no other fallback.
32
32
 
33
33
  ## Producing the report
34
34
 
35
- Run all five queries in parallel where the tool call shape allows it; none depends on another's
36
- result.
35
+ Run each query below via `synapse vault-search --fields <fields>`, with the JsonLogic query on stdin.
36
+ `--fields` asks for exactly the columns the query needs back -- no separate read per match required,
37
+ since a matched row already carries them.
37
38
 
38
39
  **1. Design notes still `Discussing`.** Design notes carry status in-body under `## Status`, not in
39
- frontmatter (unlike task notes) -- a content match, scoped to `designs/`:
40
+ frontmatter (unlike task notes) -- a content match, scoped to `designs/`. Needs only the title:
40
41
 
41
42
  ```
43
+ synapse vault-search --fields frontmatter.title <<'EOF'
42
44
  {"and": [
43
45
  {"glob": ["designs/*", {"var": "path"}]},
44
46
  {"regexp": ["## Status\\nDiscussing", {"var": "content"}]}
45
47
  ]}
48
+ EOF
46
49
  ```
47
50
 
48
51
  **2. `Ready` design notes with no compiled task yet.** `/synapse-task-note`'s own "Linking back"
49
52
  step patches a compiled design note with a `> Compiled task: [[...]]` line right after its title --
50
- "`Ready` and missing that line" is a direct signal, not fuzzy title-matching against `tasks/`:
53
+ "`Ready` and missing that line" is a direct signal, not fuzzy title-matching against `tasks/`. Needs
54
+ only the title:
51
55
 
52
56
  ```
57
+ synapse vault-search --fields frontmatter.title <<'EOF'
53
58
  {"and": [
54
59
  {"glob": ["designs/*", {"var": "path"}]},
55
60
  {"regexp": ["## Status\\nReady", {"var": "content"}]},
56
61
  {"!": [{"regexp": ["Compiled task:", {"var": "content"}]}]}
57
62
  ]}
63
+ EOF
58
64
  ```
59
65
 
60
66
  **3. Design notes (any status) with a non-empty `## Open Questions`.** Match the heading followed by
61
67
  at least one bullet -- a heading with nothing under it (fully pruned, per the Ready-gate convention
62
68
  `/synapse-design-note` now follows) doesn't count as open. Since this section spans every status,
63
69
  each line in the composed report also shows *which* status the note is currently in, and whether it
64
- has a compiled task note:
70
+ has a compiled task note -- request `content` too, and pull both directly out of the returned text
71
+ rather than reading the note again:
65
72
 
66
73
  ```
74
+ synapse vault-search --fields frontmatter.title,content <<'EOF'
67
75
  {"and": [
68
76
  {"glob": ["designs/*", {"var": "path"}]},
69
77
  {"regexp": ["## Open Questions\\n- ", {"var": "content"}]}
70
78
  ]}
79
+ EOF
71
80
  ```
72
81
 
73
82
  Do not chain further `and`/`regexp` conditions onto this query to sort matches by status -- compound
74
83
  `regexp` conditions against `content` have been observed to return results that are logically
75
84
  impossible (a query with strictly more AND-ed conditions returning *more* matches than one with
76
85
  fewer), so any query beyond a single `glob` + single `regexp` pair is unverified and not to be
77
- trusted here. Instead, `mcp__obsidian__vault_read` each match directly and take two things from the
78
- result, no second query needed for either: the line following `## Status` in `content` (normally
79
- `Discussing`/`Ready`/`Reference`, but a note written before the three-word convention can carry free
80
- text instead, e.g. `Superseded by [[...]]` -- report that verbatim rather than forcing it into a
81
- bucket, surfacing an odd note beats losing it) and, from the `links` array, any path under `tasks/`
82
- -- that's the compiled task, if one exists, with no separate `Compiled task:` regex needed since a
83
- resolved wikilink already appears in `links` regardless of where in the body it's written.
86
+ trusted here. Instead, take two things from each row's `content` column directly, no second call
87
+ needed for either: the line following `## Status` (normally `Discussing`/`Ready`/`Reference`, but a
88
+ note written before the three-word convention can carry free text instead, e.g. `Superseded by
89
+ [[...]]` -- report that verbatim rather than forcing it into a bucket, surfacing an odd note beats
90
+ losing it) and the target of a `> Compiled task: [[...]]` line, if present -- that's the compiled
91
+ task, parsed straight out of the wikilink text rather than resolved through any vault-wide link
92
+ index.
84
93
 
85
94
  **4. Open task notes with at least one unchecked item.** Task notes carry `status:` in frontmatter,
86
- unlike design notes -- filter there first:
95
+ unlike design notes -- filter there first, and request `content` to count `- [ ]` lines directly from
96
+ the row rather than reading each match again:
87
97
 
88
98
  ```
99
+ synapse vault-search --fields frontmatter.title,content <<'EOF'
89
100
  {"in": [{"var": "frontmatter.status"}, ["TODO", "IN-PROGRESS"]]}
101
+ EOF
90
102
  ```
91
103
 
92
- Then `mcp__obsidian__vault_read` each match and count `- [ ]` lines in the body. A match with zero
93
- unchecked lines (a checklist that's fully checked but hasn't been promoted to `REVIEW` yet) is still
94
- worth surfacing -- report it under this section with its count shown as 0, rather than silently
95
- dropping it, since that state itself is worth a human noticing.
104
+ A match with zero unchecked lines (a checklist that's fully checked but hasn't been promoted to
105
+ `REVIEW` yet) is still worth surfacing -- report it under this section with its count shown as 0,
106
+ rather than silently dropping it, since that state itself is worth a human noticing.
96
107
 
97
- **5. Task notes stuck in `REVIEW`.** Frontmatter-only, no body read needed -- a fully-checked
98
- checklist waiting specifically on human sign-off, since `synapse-task` deliberately never promotes a
99
- note past `REVIEW` on its own:
108
+ **5. Task notes stuck in `REVIEW`.** Frontmatter-only, no body needed -- a fully-checked checklist
109
+ waiting specifically on human sign-off, since `synapse-task` deliberately never promotes a note past
110
+ `REVIEW` on its own:
100
111
 
101
112
  ```
113
+ synapse vault-search --fields frontmatter.title <<'EOF'
102
114
  {"==": [{"var": "frontmatter.status"}, "REVIEW"]}
115
+ EOF
103
116
  ```
104
117
 
105
118
  ## Composing the report
@@ -139,9 +152,8 @@ go dig for.
139
152
 
140
153
  ## Constraints
141
154
 
142
- - Read-only end to end. Never calls `vault_write`/`vault_patch`/`vault_move`/`vault_delete`/
143
- `vault_copy` -- if a step here ever seems to need one, that step is out of scope, not a case to
144
- special-case around.
155
+ - Read-only end to end. Never calls `vault-write`/`vault-patch` -- if a step here ever seems to need
156
+ one, that step is out of scope, not a case to special-case around.
145
157
  - No Artifact/web-UI output. No `SessionStart` wiring. Not a new binary CLI subcommand -- every
146
- category above is a plain mechanical query already reachable through `mcp__obsidian__*` tools.
158
+ category above is a plain mechanical query already reachable through `synapse vault-search`.
147
159
  - Scoped to `designs/`/`tasks/` only -- never `inbox/`/`research/`/`scratchpad/`.
@@ -89,12 +89,19 @@ duplicate that scaffolding here, just supply its inputs:
89
89
 
90
90
  ## Linking back
91
91
 
92
- After creation, patch the design note: add `> Compiled task: [[{task note title}]]` near the top
93
- (via `mcp__obsidian__vault_patch`) a small annotation line, same idea as any other cross-reference
94
- you'd drop near a note's title. This is a one-time link; the design note's `Status` itself does not
95
- change and does not need to track the task's progress — Obsidian's own backlinks panel already
96
- surfaces the live task note from the design note, and the task's `status:` frontmatter is the
97
- authoritative progress signal from here on.
92
+ After creation, patch the design note: add `> Compiled task: [[{task note title}]]` near the top
93
+ right after the `# {title}` heading, before `## Status`:
94
+
95
+ ```
96
+ printf '> Compiled task: [[%s]]\n\n' "{task note title}" | \
97
+ synapse vault-patch "{design note path}" --heading "{design note title}" --prepend
98
+ ```
99
+
100
+ A small annotation line, same idea as any other cross-reference you'd drop near a note's title. This
101
+ is a one-time link; the design note's `Status` itself does not change and does not need to track the
102
+ task's progress — Obsidian's own backlinks panel (or a plain `synapse vault-search-text` for the task
103
+ note's title, on a disk-backed vault) already surfaces the live task note from the design note, and
104
+ the task's `status:` frontmatter is the authoritative progress signal from here on.
98
105
 
99
106
  ## Confirm
100
107
 
@@ -89,7 +89,7 @@ instead of a silent edit:
89
89
  local git history to say *why* it's broken instead of leaving that to guesswork — the vault is
90
90
  usually a git repo (`db-sync` auto-commits every agent-driven edit into it, opt-in per vault, same
91
91
  precondition as that hook). Resolve the vault's filesystem path the same way `synapse.conf`
92
- already does (`OBSIDIAN_VAULT_DIR`), skip this sub-step entirely if `{vault}/.git` doesn't exist,
92
+ already does (`SYNAPSE_VAULT_DIR`), skip this sub-step entirely if `{vault}/.git` doesn't exist,
93
93
  and never let a missing/unreachable git repo block the rest of the finding — worst case it's
94
94
  reported with no history context, same as today.
95
95
  - `git -C {vault} log --all --diff-filter=A --name-only --pretty=format: -- "**/{target}.md"` — a
@@ -22,7 +22,7 @@
22
22
  ],
23
23
  "PostToolUse": [
24
24
  {
25
- "matcher": "Write|Edit|mcp__obsidian__vault_(write|patch|append|delete|move)",
25
+ "matcher": "Write|Edit|Bash|mcp__obsidian__vault_(write|patch|append|delete|move)",
26
26
  "hooks": [
27
27
  {
28
28
  "type": "command",
@@ -22,7 +22,7 @@
22
22
  ],
23
23
  "PostToolUse": [
24
24
  {
25
- "matcher": "apply_patch|mcp__obsidian__vault_(write|patch|append|delete|move)",
25
+ "matcher": "apply_patch|Bash|mcp__obsidian__vault_(write|patch|append|delete|move)",
26
26
  "hooks": [
27
27
  {
28
28
  "type": "command",
@@ -29,9 +29,9 @@ There is no flag syntax here — read intent from how the user asks:
29
29
 
30
30
  ## Prerequisites
31
31
 
32
- - Requires the `obsidian` MCP server (`mcp__obsidian__*` tools). If unreachable, say so and stop —
33
- there is no local-file fallback for this skill.
34
- - If `designs/` doesn't exist in the vault yet, `mcp__obsidian__vault_write` creates it implicitly on
32
+ - Requires the `synapse` CLI on `PATH`. If it errors (no vault configured), say so and stop —
33
+ there is no other fallback for this skill.
34
+ - If `designs/` doesn't exist in the vault yet, `synapse vault-write` creates it implicitly on
35
35
  first write — but add a `designs/` entry to the vault's index note's folder layout in the same
36
36
  action (per the Synapse Vault folder-layout rule: a new top-level folder must never fall behind the
37
37
  index).
@@ -41,7 +41,7 @@ There is no flag syntax here — read intent from how the user asks:
41
41
  Every design note is tagged with the project it belongs to — both in the title
42
42
  (`{PROJECT} — {Topic}`) and as `project: {prefix}` in frontmatter (the same short prefix the
43
43
  synapse-note skill's task mode uses for task IDs) — so a flat `designs/` folder still reads clearly,
44
- and both note kinds can be filtered together via `search_query`.
44
+ and both note kinds can be filtered together via `synapse vault-search`.
45
45
 
46
46
  Same resolution the synapse-note skill uses for a missing task ID (its "Resolving a missing task
47
47
  ID"), reading the same file:
@@ -66,15 +66,22 @@ unrelated contexts (e.g. personal vs. work) never end up in the same place.
66
66
  ## Handling intent
67
67
 
68
68
  **No specific signal:**
69
- 1. Check for incomplete design notes: search `designs/` (via `mcp__obsidian__vault_list` +
70
- `vault_read`, or `search_query` scoped to the `designs/` path) for notes whose `## Status` line
71
- reads `Discussing`.
69
+ 1. Check for incomplete design notes: `synapse vault-search --fields frontmatter.title` with the
70
+ query below on stdin one call, no separate read needed:
71
+
72
+ ```
73
+ {"and": [
74
+ {"glob": ["designs/*", {"var": "path"}]},
75
+ {"regexp": ["## Status\\nDiscussing", {"var": "content"}]}
76
+ ]}
77
+ ```
72
78
  2. If found: show a short state summary — title and current section — and offer to resume.
73
79
  3. If none: ask "What are we designing?"
74
80
 
75
81
  **With a topic:**
76
- 1. Search first — `mcp__obsidian__search_simple` for the topic text across `designs/` (per the
77
- Synapse Vault rule: link/reuse over duplicate). Also check for an obvious title match.
82
+ 1. Search first — `synapse vault-search-text "{topic}"` for the topic text, then filter matches to
83
+ `designs/` paths (per the Synapse Vault rule: link/reuse over duplicate). Also check for an
84
+ obvious title match.
78
85
  2. If found with `Status: Discussing` → ask "Resume this design?" or "Start fresh?"
79
86
  3. If found with `Status: Ready` → ask "Already marked Ready. Reopen to revise, or start a new note?"
80
87
  4. If found with `Status: Reference` → ask "This concluded as Reference (no implementation intended).
@@ -89,8 +96,9 @@ unrelated contexts (e.g. personal vs. work) never end up in the same place.
89
96
  4. None → "No incomplete design note found. Tell me what you'd like to design and I'll start one."
90
97
 
91
98
  **Listing design notes:**
92
- 1. `mcp__obsidian__vault_list` on `designs/`, then `vault_read` each (or a `search_query` scoped to
93
- that path) to pull title and `## Status`.
99
+ 1. `synapse vault-search --fields frontmatter.title,content` with `{"glob": ["designs/*", {"var":
100
+ "path"}]}` on stdin — every design note regardless of status, title and `## Status` line both in
101
+ the same row.
94
102
  2. None found → "No design notes yet. Tell me what you'd like to design and I'll start one."
95
103
  3. Group into **Active** (`Discussing`, `Ready`) and **Closed** (`Reference`) — active first, title
96
104
  and status in backticks, not bold.
@@ -23,7 +23,7 @@ directory.
23
23
 
24
24
  ## Prerequisites
25
25
 
26
- - Requires the `obsidian` MCP server (`mcp__obsidian__*` tools). If unreachable, say so and stop.
26
+ - Requires the `synapse` CLI on `PATH`. If it errors (no vault configured), say so and stop.
27
27
  - Must be run from inside a git repository. Synapse assumes git throughout (source hashing uses
28
28
  `git hash-object`, file enumeration uses `git ls-files`) — if `git rev-parse --show-toplevel`
29
29
  fails, stop and say this only works inside a git repo.
@@ -65,8 +65,8 @@ Every step below needs the same three facts, resolved once up front:
65
65
 
66
66
  ## Already initialized?
67
67
 
68
- Check whether `synapse/{repo}@{branch}/Index.md` exists (`mcp__obsidian__vault_list` on
69
- `synapse/{repo}@{branch}/`, or a direct `vault_read` attempt).
68
+ Check whether `synapse/{repo}@{branch}/Index.md` exists: `synapse vault-read
69
+ "synapse/{repo}@{branch}/Index.md"` and see whether it succeeds or reports "no such note".
70
70
 
71
71
  - **Doesn't exist** → this is a first-time build. Go to "First-time build" below.
72
72
  - **Exists, `remote` frontmatter matches** the resolved remote/path → this namespace already
@@ -44,7 +44,7 @@ proceeding.
44
44
 
45
45
  ## List mode
46
46
 
47
- Use `mcp__obsidian__search_query` with the JsonLogic query `{"var": "frontmatter.task_id"}` — this returns every file that has a `task_id` set, along with that file's `task_id` value as `result`. For each match, also read the file's `status` and `title` (either via a second query `{"var": "frontmatter.status"}` / `{"var": "frontmatter.title"}`, or via `mcp__obsidian__vault_read` on the handful of matched files — whichever is fewer round-trips for the count involved).
47
+ Run `synapse vault-search --fields frontmatter.task_id,frontmatter.status,frontmatter.title` with the JsonLogic query `{"var": "frontmatter.task_id"}` on stdin one call returns every file that has a `task_id` set, each row already carrying `task_id`/`status`/`title` together, no second query or extra read needed.
48
48
 
49
49
  Categorize:
50
50
  - **Prefixed notes**: `task_id` matches `{prefix}-\d+`. Group by the distinct prefix found (whatever
@@ -61,8 +61,8 @@ Do not modify any files in list mode.
61
61
 
62
62
  The user's search text is the query — whatever they named after asking to search, quotes stripped.
63
63
 
64
- 1. Run `mcp__obsidian__search_simple` with the query — this gives full-text relevance-ranked matches with context, the closest equivalent to a title/body search.
65
- 2. If the query looks like it's targeting metadata specifically (a tag, a task ID, a status value) rather than free text, also run `mcp__obsidian__search_query` with an appropriate JsonLogic filter (e.g. `{"==": [{"var": "frontmatter.task_id"}, "proj-032"]}`).
64
+ 1. Run `synapse vault-search-text "{query}"` — this gives full-text relevance-ranked matches with context, the closest equivalent to a title/body search.
65
+ 2. If the query looks like it's targeting metadata specifically (a tag, a task ID, a status value) rather than free text, also run `synapse vault-search --fields frontmatter.title` with an appropriate JsonLogic filter on stdin (e.g. `{"==": [{"var": "frontmatter.task_id"}, "proj-032"]}`).
66
66
  3. Report matches as `{title} — {file path relative to vault root}`, deduped across both. If nothing matches, say so plainly — the caller (agent or user) needs a clear "no existing note" signal to proceed with task-mode-less creation.
67
67
 
68
68
  Do not modify any files in search mode.
@@ -72,8 +72,8 @@ Do not modify any files in search mode.
72
72
  Triggered when task mode is requested but the title doesn't match `{prefix}-\d+`.
73
73
 
74
74
  The known project/prefix pairs live in a plain local file named `synapse-projects.conf` (one
75
- `project-name=prefix` line each) — read/appended as a plain text file, not the `obsidian`
76
- MCP server, since it's outside the vault. It is deliberately **not** part of the portable
75
+ `project-name=prefix` line each) — read/appended as a plain text file, not the `vault-*` subcommands,
76
+ since it's outside the vault. It is deliberately **not** part of the portable
77
77
  Synapse package and never copied between machines, so contexts that shouldn't mix (e.g.
78
78
  personal vs. work projects) never end up in the same file. It's self-managed — this skill appends
79
79
  newly resolved pairs to it — but also plain text, so the user can add, fix, or remove a line by hand
@@ -95,8 +95,8 @@ unchanged for anyone who has never touched an XDG config directory.
95
95
  2. Check the resolved `synapse-projects.conf` for a line whose project name matches (loosely —
96
96
  case/whitespace-insensitive). If found, use that prefix directly — no need to ask.
97
97
  3. If the file doesn't have it yet, fall back to deducing from the vault itself (useful the first
98
- time this runs, or for a project whose notes predate this file): `search_simple` for the
99
- project/repo name across existing notes, and/or `search_query` on
98
+ time this runs, or for a project whose notes predate this file): `synapse vault-search-text` for
99
+ the project/repo name across existing notes, and/or `synapse vault-search` on
100
100
  `{"var": "frontmatter.task_id"}` to see which prefixes exist, then check whether any of those
101
101
  prefixed notes reference this project. If exactly one prefix confidently matches, use it.
102
102
  4. If nothing confidently matches (new project, or an ambiguous/multiple match), ask the user
@@ -105,9 +105,9 @@ unchanged for anyone who has never touched an XDG config directory.
105
105
  5. Whenever step 3 or step 4 resolves a pair not already in the conf file (including a fresh
106
106
  `project-name=prefix` line matching what was just deduced or asked), append it — so the next task
107
107
  for this project resolves from step 2 without a search or a question.
108
- 6. Once the prefix is known, find the next number: run
109
- `mcp__obsidian__search_query` with `{"var": "frontmatter.task_id"}`,
110
- filter the returned `result` values client-side for ones matching
108
+ 6. Once the prefix is known, find the next number: run `synapse vault-search --fields
109
+ frontmatter.task_id` with `{"var": "frontmatter.task_id"}` on stdin,
110
+ filter the returned values client-side for ones matching
111
111
  `{prefix}-\d+`, take the highest number found, add 1. If none exist yet
112
112
  for that prefix, start at 1.
113
113
  7. Format the new task ID **zero-padded to 3 digits** (`{prefix}-001`, `{prefix}-030`,
@@ -197,7 +197,7 @@ or supplied directly by a caller like the synapse-task-note skill):
197
197
  ## Notes
198
198
 
199
199
  ```
200
- 4. Write it with `mcp__obsidian__vault_write`. Task mode: path
200
+ 4. Write it with `synapse vault-write <path>` (content on stdin). Task mode: path
201
201
  `tasks/{project}/{filename}.md` (project resolved in "Resolving the
202
202
  project folder" above). Bare mode: path `{category}/{filename}.md`
203
203
  (category resolved above).
@@ -26,7 +26,7 @@ arguments to parse, always operates on the repo and branch containing the curren
26
26
 
27
27
  ## Prerequisites
28
28
 
29
- - Requires the `obsidian` MCP server (`mcp__obsidian__*` tools). If unreachable, say so and stop —
29
+ - Requires the `synapse` CLI on `PATH`. If it errors (no vault configured), say so and stop —
30
30
  same requirement the synapse-init skill has.
31
31
  - Must be run from inside a git repository, on a named branch (not detached `HEAD`) — same
32
32
  requirement the synapse-init skill has, since `synapse_namespace` needs a branch to key on.