@imunitic/synapse 0.13.14 → 0.13.16
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/commands/synapse-note.md +1 -1
- package/commands/synapse-rebuild-diff.md +3 -3
- package/harness/codex/skills/synapse-note/SKILL.md +1 -1
- package/harness/codex/skills/synapse-rebuild-diff/SKILL.md +3 -3
- package/package.json +4 -4
- package/skills/synapse-node/SKILL.md +9 -6
- package/skills/synapse-query/SKILL.md +6 -5
- package/skills/synapse-vault/SKILL.md +4 -2
- package/synapse-claude.md +5 -2
package/commands/synapse-note.md
CHANGED
|
@@ -43,7 +43,7 @@ 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 `synapse vault-search-text "{query}"` — this gives full-text relevance-ranked matches
|
|
46
|
+
1. Run `synapse vault-search-text "{query}"` — this gives full-text relevance-ranked matches (path, score, matching line ranges), the closest equivalent to a title/body search.
|
|
47
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
|
|
|
@@ -187,7 +187,7 @@ against the node's own line count, and use `synapse query sources "{Node}" --cou
|
|
|
187
187
|
count drift's numbers are relative to. Then pick one of three strategies and **say which one you
|
|
188
188
|
picked and why**:
|
|
189
189
|
|
|
190
|
-
**Restore the crux directive before writing any node back.** `synapse query body` returns the
|
|
190
|
+
**Restore the crux directive before writing any node back.** `synapse query body --full` returns the
|
|
191
191
|
*expanded* crux — the fenced code the writer sliced — not the directive that produced it. Writing that
|
|
192
192
|
straight back stores a quote of a file as it looked at the old baseline, presented as if it were
|
|
193
193
|
current. So rebuild the directive from the pointer the writer recorded:
|
|
@@ -218,7 +218,7 @@ the summary claims — which is a better reason to re-read a node than any perce
|
|
|
218
218
|
the sentence at risk rather than the volume of change around it.
|
|
219
219
|
|
|
220
220
|
**Reseat** — renames only, no content change. No reading at all. Recover the existing prose with
|
|
221
|
-
`synapse query body "{Node}"`, drop its trailing `## Sources` block (the writer regenerates that),
|
|
221
|
+
`synapse query body "{Node}" --full`, drop its trailing `## Sources` block (the writer regenerates that),
|
|
222
222
|
re-enumerate so the list holds the new paths, and write it back. Repeating this is safe: the writer
|
|
223
223
|
trims the body's leading and trailing blank lines, so a reseat is idempotent rather than accreting
|
|
224
224
|
padding each time. The concept did not change; only paths moved. This also
|
|
@@ -228,7 +228,7 @@ than from a work-dir file.
|
|
|
228
228
|
**Patch from the diff** — a small fraction of the node's *lines* changed (rule of thumb: under ~15%),
|
|
229
229
|
and the file its `crux` quotes still exists. Read three things and nothing else:
|
|
230
230
|
|
|
231
|
-
1. the current prose — `synapse query body "{Node}"`;
|
|
231
|
+
1. the current prose — `synapse query body "{Node}" --full`;
|
|
232
232
|
2. `git diff --name-status -M <commit>..HEAD` restricted to that node's paths, for *which* files moved;
|
|
233
233
|
3. hunks for a **bounded** selection of those files — always including any file the `crux` quotes.
|
|
234
234
|
|
|
@@ -63,7 +63,7 @@ Do not modify any files in list mode.
|
|
|
63
63
|
|
|
64
64
|
The user's search text is the query — whatever they named after asking to search, quotes stripped.
|
|
65
65
|
|
|
66
|
-
1. Run `synapse vault-search-text "{query}"` — this gives full-text relevance-ranked matches
|
|
66
|
+
1. Run `synapse vault-search-text "{query}"` — this gives full-text relevance-ranked matches (path, score, matching line ranges), the closest equivalent to a title/body search.
|
|
67
67
|
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"]}`).
|
|
68
68
|
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.
|
|
69
69
|
|
|
@@ -187,7 +187,7 @@ against the node's own line count, and use `synapse query sources "{Node}" --cou
|
|
|
187
187
|
count drift's numbers are relative to. Then pick one of three strategies and **say which one you
|
|
188
188
|
picked and why**:
|
|
189
189
|
|
|
190
|
-
**Restore the crux directive before writing any node back.** `synapse query body` returns the
|
|
190
|
+
**Restore the crux directive before writing any node back.** `synapse query body --full` returns the
|
|
191
191
|
*expanded* crux — the fenced code the writer sliced — not the directive that produced it. Writing that
|
|
192
192
|
straight back stores a quote of a file as it looked at the old baseline, presented as if it were
|
|
193
193
|
current. So rebuild the directive from the pointer the writer recorded:
|
|
@@ -218,7 +218,7 @@ the summary claims — which is a better reason to re-read a node than any perce
|
|
|
218
218
|
the sentence at risk rather than the volume of change around it.
|
|
219
219
|
|
|
220
220
|
**Reseat** — renames only, no content change. No reading at all. Recover the existing prose with
|
|
221
|
-
`synapse query body "{Node}"`, drop its trailing `## Sources` block (the writer regenerates that),
|
|
221
|
+
`synapse query body "{Node}" --full`, drop its trailing `## Sources` block (the writer regenerates that),
|
|
222
222
|
re-enumerate so the list holds the new paths, and write it back. Repeating this is safe: the writer
|
|
223
223
|
trims the body's leading and trailing blank lines, so a reseat is idempotent rather than accreting
|
|
224
224
|
padding each time. The concept did not change; only paths moved. This also
|
|
@@ -228,7 +228,7 @@ than from a work-dir file.
|
|
|
228
228
|
**Patch from the diff** — a small fraction of the node's *lines* changed (rule of thumb: under ~15%),
|
|
229
229
|
and the file its `crux` quotes still exists. Read three things and nothing else:
|
|
230
230
|
|
|
231
|
-
1. the current prose — `synapse query body "{Node}"`;
|
|
231
|
+
1. the current prose — `synapse query body "{Node}" --full`;
|
|
232
232
|
2. `git diff --name-status -M <commit>..HEAD` restricted to that node's paths, for *which* files moved;
|
|
233
233
|
3. hunks for a **bounded** selection of those files — always including any file the `crux` quotes.
|
|
234
234
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@imunitic/synapse",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.16",
|
|
4
4
|
"description": "Memory for Claude Code, Codex CLI, and OpenCode: a durable markdown vault plus a per-repo code graph.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"*.conf.template"
|
|
24
24
|
],
|
|
25
25
|
"optionalDependencies": {
|
|
26
|
-
"@imunitic/synapse-darwin-arm64": "0.13.
|
|
27
|
-
"@imunitic/synapse-linux-x64": "0.13.
|
|
28
|
-
"@imunitic/synapse-linux-arm64": "0.13.
|
|
26
|
+
"@imunitic/synapse-darwin-arm64": "0.13.16",
|
|
27
|
+
"@imunitic/synapse-linux-x64": "0.13.16",
|
|
28
|
+
"@imunitic/synapse-linux-arm64": "0.13.16"
|
|
29
29
|
},
|
|
30
30
|
"license": "SEE LICENSE IN LICENSE"
|
|
31
31
|
}
|
|
@@ -53,16 +53,19 @@ needs one.
|
|
|
53
53
|
synapse query body "{Node title}"
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
That prints
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
That prints a brief — the node's one-line `summary`, a `crux_path:crux_lines` pointer and the
|
|
57
|
+
`## Links` block — and costs ~150 tokens whether the node covers 5 files or 941. `--full` prints
|
|
58
|
+
everything between the generated fences (so `## Notes` and the frontmatter are still excluded,
|
|
59
|
+
which a raw offset read would not); `--lines <a-b>[,<c-d>]` prints just those lines of the node
|
|
60
|
+
file, for the ranges a `vault-search-text` hit gave. **A full `synapse vault-read`
|
|
59
61
|
of a hub node is a mistake, not merely expensive** — it spends tens of thousands of tokens on a
|
|
60
62
|
path list you are not going to use. Use `vault-read` only when you specifically need the
|
|
61
63
|
frontmatter itself.
|
|
62
64
|
|
|
63
65
|
Finding *which* node to read is a separate job, and search does it: because `sources` is
|
|
64
66
|
exhaustive, `synapse vault-search-text` on a class or file name locates the owning node even
|
|
65
|
-
when that name appears nowhere in any node's prose, and returns
|
|
67
|
+
when that name appears nowhere in any node's prose, and returns the matching line ranges rather
|
|
68
|
+
than the text.
|
|
66
69
|
|
|
67
70
|
For the other questions about a node, use the same tool rather than reading frontmatter:
|
|
68
71
|
`synapse query sources "{Node}" --count|--modules|--filter <p>` for what it covers, and
|
|
@@ -93,7 +96,7 @@ needs one.
|
|
|
93
96
|
this repo, and the negative results (searches that came back empty) worth not re-deriving.
|
|
94
97
|
- **Prefer patching the prose from the diff over re-reading the node's sources.** If the node has a
|
|
95
98
|
`commit` and only a small fraction of its files changed, read the current prose
|
|
96
|
-
(`synapse query body`), get `git diff --name-status -M <commit>..HEAD` for its paths, and read
|
|
99
|
+
(`synapse query body --full`), get `git diff --name-status -M <commit>..HEAD` for its paths, and read
|
|
97
100
|
hunks only for a bounded selection — always including `crux_path`, the file the crux was cut from.
|
|
98
101
|
Amend the sentences the diff contradicts and keep the rest verbatim. A node covering 15,000 files
|
|
99
102
|
where 12
|
|
@@ -110,7 +113,7 @@ needs one.
|
|
|
110
113
|
- Re-author `## Summary`, `## Crux` and `## Links` to match what the files contain now, into
|
|
111
114
|
`$W/body.md`. Re-check the node's one-line `summary` as well; keep the existing one with
|
|
112
115
|
`synapse query field "{Node title}" summary` if it still fits.
|
|
113
|
-
- **`## Crux` goes back as a directive, never as the code you just read.** `synapse query body`
|
|
116
|
+
- **`## Crux` goes back as a directive, never as the code you just read.** `synapse query body --full`
|
|
114
117
|
returns the *expanded* crux — the fenced block the writer sliced last time — so copying it forward
|
|
115
118
|
stores a quote of an older version of the file as though it were current. Emit
|
|
116
119
|
`<!-- crux: <path> <start>-<end> -->` and let the writer cut it out again. Reuse the recorded
|
|
@@ -33,8 +33,8 @@ instead of asking Synapse first. If you catch yourself about to grep the whole r
|
|
|
33
33
|
`synapse/{project}/Index.md`, stop and check the index instead.
|
|
34
34
|
|
|
35
35
|
**Why the cost difference is real, not just tidiness.** `synapse query body <node>` is a direct disk
|
|
36
|
-
read that
|
|
37
|
-
entirely. Reading the whole note instead would move that node's entire frontmatter — megabytes — to
|
|
36
|
+
read that prints a brief (the node's summary, crux pointer and Links) and skips the node's `sources`
|
|
37
|
+
list entirely; `--full` prints the prose between the generated fences. Reading the whole note instead would move that node's entire frontmatter — megabytes — to
|
|
38
38
|
print a few hundred words. On a large
|
|
39
39
|
repo (dozens to hundreds of thousands of tracked files), that difference is the entire reason a
|
|
40
40
|
query stays cheap instead of dominating the turn.
|
|
@@ -47,14 +47,15 @@ required:
|
|
|
47
47
|
|
|
48
48
|
| Need | Reach for | Why |
|
|
49
49
|
|---|---|---|
|
|
50
|
-
| "Where does X live?" (ranked, natural-language) | `synapse vault-search-text
|
|
50
|
+
| "Where does X live?" (ranked, natural-language) | `synapse vault-search-text "<words>" --namespace <repo>@<branch>` (this checkout's graph included; quote the words, the query is one argument), plus a first read of `synapse/{project}/Index.md` | Full-text, relevance-ranked; each row is `node ⇥ score ⇥ line ranges`, no text. Without `--namespace` the search covers the whole vault and task/design/research notes outrank graph nodes. Read the hit with `query body "{Node}"` (brief) or `query body "{Node}" --lines <ranges>`. Not semantic ranking, but genuinely comparable for locating a concept. |
|
|
51
51
|
| Every occurrence of a pattern | native `grep`/`rg`, **scoped to a file Synapse already named** | Not a repo-wide first move — the deterred, last-resort case. See "Why this exists" above. |
|
|
52
52
|
| A file's API surface | read the file directly | Claude already has direct, cheap filesystem access — no separate view needed. |
|
|
53
53
|
| Who depends on a subsystem, or what it depends on | `synapse query links "{Node}" --inbound` / `--closure` | Real transitive-closure traversal over the typed relations, at node granularity. |
|
|
54
54
|
| **Who calls this method/class, repo-wide** | `synapse callers <name>` | Every call site as `path:line ⇥ calling expression`, off the flat index `synapse build-refs` projects from the tags cache. Well under a second even against a multi-gigabyte index. Needs **no node and no graph** — it works in a repo `/synapse-init` has never touched, as long as the cache is filled. Still name-based rather than type-resolved, so hits are candidates with evidence: the calling expression is on the line, which usually settles the receiver without opening the file. |
|
|
55
55
|
| **Where a symbol is defined, or every definition and reference of a name** | `synapse query symbol <name> "{Node}"`, or repo-wide `synapse callers <name> --all` | `symbol` gives `path:line` plus the defining expression inside one node's files. `callers --all` needs no node: every def and ref repo-wide from the Code Cache, the first move when you don't know the owning node yet. |
|
|
56
56
|
| One frontmatter scalar (`stale`, `built_at`, `commit`, ...) | `synapse query field "{Node}" <key>` | Cheap, targeted extraction — never reads the rest of the node. |
|
|
57
|
-
|
|
|
57
|
+
| What a node is and what it links to | `synapse query body "{Node}"` | A brief: the node's summary, a `path:lines` pointer to its crux and its Links, about 600 characters. This is the first read for "how does X work" too; it says which files to open next. Disk read, never the API. See the cost note above. |
|
|
58
|
+
| A node's whole prose and crux code, or specific lines of it | `synapse query body "{Node}" --full`, or `--lines <a-b>[,<c-d>]` | Only when the brief did not answer: `--full` is about 8k characters, which every later turn re-reads. `--lines` takes the ranges a `vault-search-text` hit gave. |
|
|
58
59
|
| Every file a node covers | `synapse query sources "{Node}" [--count\|--modules\|--filter <p>]` | Filtered/counted/grouped, never the raw megabyte-scale list. |
|
|
59
60
|
| Is this node's understanding still accurate? | `synapse query stale` / `drift` / `grounding` | Hand off to the `synapse-node` skill's procedure — this skill doesn't re-explain that. |
|
|
60
61
|
| A node in a *different* checkout's graph, from a repo with no namespace of its own (or the wrong one) | `synapse query --namespace <repo>@<branch> body "{Node}"` (any subcommand takes it) | Names the target namespace directly instead of deriving it from cwd. `stale`/`drift`/`grounding`/`symbol` still need that checkout's real files on disk and refuse without `SYNAPSE_REPO_ROOT` set to it — `body`/`sources`/`field`/`links` don't. |
|
|
@@ -65,7 +66,7 @@ required:
|
|
|
65
66
|
|---|---|---|
|
|
66
67
|
| Orienting on an unfamiliar repo | `synapse/{project}/Index.md`, then the relevant node's `body` | grepping around to build a mental map by hand |
|
|
67
68
|
| Understanding a flow ("how does X work") | `synapse query body "{Node}"` for the node that covers it | reading every file the flow touches, cold |
|
|
68
|
-
| Finding where a change belongs | `vault-search-text
|
|
69
|
+
| Finding where a change belongs | `vault-search-text --namespace <repo>@<branch>`/`Index.md` to find the owning node, then that node's `sources`/`crux_path` for the exact file(s) | a repo-wide grep for a guessed symbol name |
|
|
69
70
|
| Judging blast radius before an edit | `synapse query links "{Node}" --inbound` (or `--closure` for transitive) | assuming nothing else depends on it |
|
|
70
71
|
| You already know the exact file and line range | just fetch it (`sed`, or a direct file read) | asking Synapse a question you can already answer |
|
|
71
72
|
| Finding every occurrence of a literal pattern | native `grep`/`rg`, scoped to files Synapse already named | an unscoped repo-wide grep before consulting Synapse at all |
|
|
@@ -27,7 +27,7 @@ Search before you answer when the question is about:
|
|
|
27
27
|
- anything that starts "I think it works like…"
|
|
28
28
|
|
|
29
29
|
```
|
|
30
|
-
synapse vault-search-text <query> full-text, relevance-ranked,
|
|
30
|
+
synapse vault-search-text <query> full-text, relevance-ranked: path, score, matching line ranges
|
|
31
31
|
synapse vault-search --fields <f1,f2,...> JsonLogic over frontmatter, tags, content, path globs
|
|
32
32
|
synapse vault-list when you already know roughly where it is
|
|
33
33
|
synapse vault-read <path> the whole note -- no partial/targeted read, except one path shape below
|
|
@@ -46,7 +46,9 @@ exactly what you need with `--fields` instead of over-fetching, and pull a speci
|
|
|
46
46
|
returns the same whole-note body as any other path — frontmatter included, which on a hub node can
|
|
47
47
|
run to megabytes just to reach a few hundred words of prose. `synapse query body <node>` (add
|
|
48
48
|
`--namespace <repo>@<branch>` to reach a different checkout's graph) is the targeted read for that
|
|
49
|
-
one path shape:
|
|
49
|
+
one path shape: a brief by default (summary, crux pointer, Links), `--full` for the whole prose,
|
|
50
|
+
`--lines <a-b>` for the line ranges a `vault-search-text` hit gave. None of them print frontmatter
|
|
51
|
+
unless the range asks for it. Reach for it instead of `vault-read` for anything under
|
|
50
52
|
`synapse/` — see the `synapse-query` skill for the rest of its subcommands.
|
|
51
53
|
|
|
52
54
|
A search that returns nothing is a real result and worth one line in the note you then write —
|
package/synapse-claude.md
CHANGED
|
@@ -198,8 +198,11 @@ the `synapse` CLI's `vault-*` subcommands — none of them writes to the vault f
|
|
|
198
198
|
Prefer `synapse vault-search-text`/`vault-search` over raw file grepping — they read the vault
|
|
199
199
|
directly and don't require re-deriving paths:
|
|
200
200
|
|
|
201
|
-
- `synapse vault-search-text <query>` — full-text search with relevance scoring
|
|
202
|
-
|
|
201
|
+
- `synapse vault-search-text <query>` — full-text search with relevance scoring, for "does a note
|
|
202
|
+
about X already exist" checks. Each row is the note, its score and the line ranges of the matches,
|
|
203
|
+
never the matched text: read the ranges with `synapse query body <node> --lines <ranges>` for a
|
|
204
|
+
graph node, or `vault-read` for any other note. `--namespace <repo>@<branch>` limits the search to
|
|
205
|
+
that graph's nodes, which a code question should always pass.
|
|
203
206
|
- `synapse vault-search --fields <f1,f2,...>` — JsonLogic queries over note metadata (frontmatter
|
|
204
207
|
fields, tags, content, path globs — not `links`/`backlinks`, which no CLI subcommand exposes yet)
|
|
205
208
|
when you need a structured filter rather than free text, e.g. finding all notes with a given
|