@imunitic/synapse 0.0.1-test.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Index.md.template +23 -0
- package/bin/synapse-hook.cjs +19 -0
- package/bin/synapse-setup.cjs +420 -0
- package/bin/synapse.cjs +20 -0
- package/commands/synapse-design-note.md +229 -0
- package/commands/synapse-init.md +354 -0
- package/commands/synapse-note.md +196 -0
- package/commands/synapse-rebuild-diff.md +314 -0
- package/commands/synapse-rebuild-full.md +152 -0
- package/commands/synapse-status.md +144 -0
- package/commands/synapse-task-note.md +133 -0
- package/commands/synapse-vault-tidy.md +187 -0
- package/harness/claude/hooks.json +54 -0
- package/harness/codex/hooks.json +54 -0
- package/harness/codex/skills/synapse-design-note/SKILL.md +236 -0
- package/harness/codex/skills/synapse-init/SKILL.md +354 -0
- package/harness/codex/skills/synapse-note/SKILL.md +212 -0
- package/harness/codex/skills/synapse-rebuild-diff/SKILL.md +315 -0
- package/harness/codex/skills/synapse-rebuild-full/SKILL.md +149 -0
- package/harness/codex/skills/synapse-status/SKILL.md +146 -0
- package/harness/codex/skills/synapse-task-note/SKILL.md +133 -0
- package/harness/codex/skills/synapse-vault-tidy/SKILL.md +187 -0
- package/harness/opencode/plugin/synapse.js +164 -0
- package/lib/obsidian-mcp-refresh.cjs +303 -0
- package/lib/resolve-binaries.cjs +54 -0
- package/package.json +26 -0
- package/skills/synapse-node/SKILL.md +211 -0
- package/skills/synapse-node-authoring/SKILL.md +188 -0
- package/skills/synapse-node-format/SKILL.md +205 -0
- package/skills/synapse-orientation/SKILL.md +468 -0
- package/skills/synapse-query/SKILL.md +99 -0
- package/skills/synapse-task/SKILL.md +261 -0
- package/skills/synapse-vault/SKILL.md +107 -0
- package/synapse-claude.md +220 -0
- package/synapse-fence-languages.conf.template +24 -0
- package/synapse-ignore-files.conf.template +45 -0
- package/synapse-module-boilerplate.conf.template +24 -0
- package/synapse-projects.conf.template +14 -0
- package/synapse-prompt-stopwords.conf.template +594 -0
- package/synapse.conf.template +23 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"hooks": [
|
|
6
|
+
{
|
|
7
|
+
"type": "command",
|
|
8
|
+
"command": "synapse-hook session-start"
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"UserPromptSubmit": [
|
|
14
|
+
{
|
|
15
|
+
"hooks": [
|
|
16
|
+
{
|
|
17
|
+
"type": "command",
|
|
18
|
+
"command": "synapse-hook prompt-context"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"PostToolUse": [
|
|
24
|
+
{
|
|
25
|
+
"matcher": "Write|Edit|mcp__obsidian__vault_(write|patch|append|delete|move)",
|
|
26
|
+
"hooks": [
|
|
27
|
+
{
|
|
28
|
+
"type": "command",
|
|
29
|
+
"command": "synapse-hook db-sync"
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"matcher": "Write|Edit|MultiEdit",
|
|
35
|
+
"hooks": [
|
|
36
|
+
{
|
|
37
|
+
"type": "command",
|
|
38
|
+
"command": "synapse-hook staleness"
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"Stop": [
|
|
44
|
+
{
|
|
45
|
+
"hooks": [
|
|
46
|
+
{
|
|
47
|
+
"type": "command",
|
|
48
|
+
"command": "synapse-hook stop-nudge"
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"hooks": [
|
|
6
|
+
{
|
|
7
|
+
"type": "command",
|
|
8
|
+
"command": "synapse-hook session-start"
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"UserPromptSubmit": [
|
|
14
|
+
{
|
|
15
|
+
"hooks": [
|
|
16
|
+
{
|
|
17
|
+
"type": "command",
|
|
18
|
+
"command": "synapse-hook prompt-context"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"PostToolUse": [
|
|
24
|
+
{
|
|
25
|
+
"matcher": "apply_patch|mcp__obsidian__vault_(write|patch|append|delete|move)",
|
|
26
|
+
"hooks": [
|
|
27
|
+
{
|
|
28
|
+
"type": "command",
|
|
29
|
+
"command": "synapse-hook db-sync"
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"matcher": "apply_patch",
|
|
35
|
+
"hooks": [
|
|
36
|
+
{
|
|
37
|
+
"type": "command",
|
|
38
|
+
"command": "synapse-hook staleness"
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"Stop": [
|
|
44
|
+
{
|
|
45
|
+
"hooks": [
|
|
46
|
+
{
|
|
47
|
+
"type": "command",
|
|
48
|
+
"command": "synapse-hook stop-nudge"
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: synapse-design-note
|
|
3
|
+
description: Start or continue a free-form, cross-project design discussion, written to Synapse Vault rather than tied to one repo — thinking through a problem/approach/tradeoffs out loud before anything is built. Use whenever the user wants to open, resume, or reason through a design ("let's create/write a design note", "let's think through X", "let's design this", "let's talk this through"). Not for a note that's already ready to become tracked work (that's the synapse-task-note skill), or a plain vault note with no design framing (that's the synapse-note skill, whose project-resolution logic this skill reuses).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Synapse Design Note: Cross-Project Personal Design Discussion
|
|
7
|
+
|
|
8
|
+
A free-form "think it through out loud" pipeline for a design conversation, written to Synapse
|
|
9
|
+
Vault rather than any one repo. Use it when the design conversation isn't (or shouldn't be) tied
|
|
10
|
+
to one repo's lifecycle — it's findable from any project immediately, with no separate
|
|
11
|
+
pointer-note step, because the vault itself is already the cross-project store.
|
|
12
|
+
|
|
13
|
+
Not every design discussion ends with something to build. See `Status: Reference` below for the
|
|
14
|
+
"no implementation attached" ending.
|
|
15
|
+
|
|
16
|
+
## When this runs, and what the user means
|
|
17
|
+
|
|
18
|
+
There is no flag syntax here — read intent from how the user asks:
|
|
19
|
+
|
|
20
|
+
- **A topic named or described** ("let's design X", "let's think through Y"): go to "With a topic"
|
|
21
|
+
below.
|
|
22
|
+
- **Asking to pick up where a design left off** ("let's continue the design note", "resume that
|
|
23
|
+
design"): go to "Resuming an incomplete design" below.
|
|
24
|
+
- **Asking what design notes exist** ("what design notes are there", "list the designs"): go to
|
|
25
|
+
"Listing design notes" below.
|
|
26
|
+
- **No specific signal, just "let's write a design note"**: check for incomplete design notes first
|
|
27
|
+
(same lookup as "Resuming an incomplete design"); if one exists, offer to resume it; if none,
|
|
28
|
+
ask "What are we designing?"
|
|
29
|
+
|
|
30
|
+
## Prerequisites
|
|
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
|
|
35
|
+
first write — but add a `designs/` entry to the vault's index note's folder layout in the same
|
|
36
|
+
action (per the Synapse Vault folder-layout rule: a new top-level folder must never fall behind the
|
|
37
|
+
index).
|
|
38
|
+
|
|
39
|
+
## Determining the project
|
|
40
|
+
|
|
41
|
+
Every design note is tagged with the project it belongs to — both in the title
|
|
42
|
+
(`{PROJECT} — {Topic}`) and as `project: {prefix}` in frontmatter (the same short prefix the
|
|
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`.
|
|
45
|
+
|
|
46
|
+
Same resolution the synapse-note skill uses for a missing task ID (its "Resolving a missing task
|
|
47
|
+
ID"), reading the same file:
|
|
48
|
+
|
|
49
|
+
1. Infer the project from the current repo: check its project `CLAUDE.md` (title/"About" section) or
|
|
50
|
+
`git remote`.
|
|
51
|
+
2. Check the resolved `synapse-projects.conf` (plain `project-name=prefix` lines, read/appended
|
|
52
|
+
as a plain file, not the vault — resolve which file that is with the same tiered lookup as the
|
|
53
|
+
synapse-note skill's "Resolving a missing task ID": `$XDG_CONFIG_HOME/synapse/synapse-projects.conf`
|
|
54
|
+
or `~/.config/synapse/synapse-projects.conf`, then `~/.claude/synapse-projects.conf`, first one
|
|
55
|
+
that exists) for a loosely-matching project name. If found, use that prefix directly.
|
|
56
|
+
3. If not in the file yet, fall back to searching the vault for a prefix already in use for this
|
|
57
|
+
project. If exactly one confidently matches, use it — and append the pair to the conf file.
|
|
58
|
+
4. If nothing confidently matches, ask the user for a short project tag — plain free-text, not a
|
|
59
|
+
multiple-choice list, never hinting at any other project's tag as an example — then append the
|
|
60
|
+
resolved pair to the conf file.
|
|
61
|
+
|
|
62
|
+
Never hardcode a specific project/prefix pair in this skill's own instructions — the conf file is
|
|
63
|
+
machine-local and deliberately outside the portable Synapse package, so projects from
|
|
64
|
+
unrelated contexts (e.g. personal vs. work) never end up in the same place.
|
|
65
|
+
|
|
66
|
+
## Handling intent
|
|
67
|
+
|
|
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`.
|
|
72
|
+
2. If found: show a short state summary — title and current section — and offer to resume.
|
|
73
|
+
3. If none: ask "What are we designing?"
|
|
74
|
+
|
|
75
|
+
**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.
|
|
78
|
+
2. If found with `Status: Discussing` → ask "Resume this design?" or "Start fresh?"
|
|
79
|
+
3. If found with `Status: Ready` → ask "Already marked Ready. Reopen to revise, or start a new note?"
|
|
80
|
+
4. If found with `Status: Reference` → ask "This concluded as Reference (no implementation intended).
|
|
81
|
+
Reopen to revise, or is that still accurate?"
|
|
82
|
+
5. Otherwise: start a new design note (see "Determining the project" above for the title/frontmatter
|
|
83
|
+
tag).
|
|
84
|
+
|
|
85
|
+
**Resuming an incomplete design:**
|
|
86
|
+
1. Find notes with `Status: Discussing` (same lookup as "No specific signal").
|
|
87
|
+
2. Multiple → list them, ask which to continue.
|
|
88
|
+
3. One → resume it.
|
|
89
|
+
4. None → "No incomplete design note found. Tell me what you'd like to design and I'll start one."
|
|
90
|
+
|
|
91
|
+
**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`.
|
|
94
|
+
2. None found → "No design notes yet. Tell me what you'd like to design and I'll start one."
|
|
95
|
+
3. Group into **Active** (`Discussing`, `Ready`) and **Closed** (`Reference`) — active first, title
|
|
96
|
+
and status in backticks, not bold.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Workflow
|
|
101
|
+
|
|
102
|
+
Free-form conversation, no fixed step order. Create the note on the first substantive answer and
|
|
103
|
+
update it after every meaningful exchange — don't wait until the end.
|
|
104
|
+
|
|
105
|
+
**Write it as settled understanding, not as a transcript of how it was reached.** Updating after
|
|
106
|
+
every exchange is about *when* to write, not license to narrate the conversation in the prose
|
|
107
|
+
itself. A section should read as if authored fresh today, stating the problem/approach/constraints
|
|
108
|
+
as they now stand — never as a log of what changed ("corrected during discussion," "reworked during
|
|
109
|
+
a live investigation," "the user pointed out," "originally X, now Y"). This applies strictly to
|
|
110
|
+
`## Problem`, `## Constraints`, and `## Open Questions` — always direct, current statements, no
|
|
111
|
+
exceptions.
|
|
112
|
+
|
|
113
|
+
`## Approach` is the one place a *trail* can be legitimate content — a rejected alternative and why
|
|
114
|
+
it failed is real, useful information for whoever reads this later, worth keeping even once the
|
|
115
|
+
working approach makes it moot. But phrase it as a fact about the solution space ("X fails because
|
|
116
|
+
Y, confirmed by Z"), never as commentary on the discussion that found it ("investigation showed,"
|
|
117
|
+
"the first attempt was"). Test: would the sentence still make sense to someone who wasn't in the
|
|
118
|
+
conversation and has no idea anything was ever revised? If not, rewrite it as a direct statement.
|
|
119
|
+
|
|
120
|
+
**Prune `## Open Questions` the moment a question resolves — every time the note is touched, not
|
|
121
|
+
just at conclusion.** This section must only ever contain what is currently, actually unresolved:
|
|
122
|
+
a reader (or the agent checking for a blocking question before marking `Ready`, below) has to be
|
|
123
|
+
able to tell in one pass whether anything is still open, not read through a history of past answers
|
|
124
|
+
to find the one real one. When a question is answered during discussion, delete its bullet outright
|
|
125
|
+
— if the answer matters going forward, fold it into `## Approach` (as a direct settled fact, same
|
|
126
|
+
rule as above) or `### Alternatives considered` (if something specific was tried and rejected along
|
|
127
|
+
the way). Never leave a "Resolved on {date}" or "Revised ({review}): ..." bullet parked under Open
|
|
128
|
+
Questions as a historical record — that is exactly the changelog-as-current-state failure the rule
|
|
129
|
+
above already prohibits, just easier to miss here because the section reads as a list either way.
|
|
130
|
+
|
|
131
|
+
Angles worth covering (skip whatever's not relevant):
|
|
132
|
+
- What problem are we solving, and why now?
|
|
133
|
+
- What's the chosen approach? If there were real alternatives, a one-line "why not" for each.
|
|
134
|
+
- What are the hard constraints?
|
|
135
|
+
- Anything risky, or that needs deciding now vs. can be deferred?
|
|
136
|
+
|
|
137
|
+
### Concluding: Discussing, Ready, or Reference
|
|
138
|
+
|
|
139
|
+
A design note starts `Discussing` and stays there by default — reaching `Ready` is a deliberate
|
|
140
|
+
judgment call, not the automatic result of an `## Approach` section existing. Before marking
|
|
141
|
+
`Ready`, check both explicitly:
|
|
142
|
+
- Is `## Approach` complete and actionable as written, with no hedge language standing in for a
|
|
143
|
+
decision that hasn't actually been made ("a plausible shape," "TBD," "leaning toward," "something
|
|
144
|
+
like")? If the approach still contains that kind of placeholder, it isn't `Ready` yet regardless
|
|
145
|
+
of how much has been discussed.
|
|
146
|
+
- Does every `## Open Questions` bullet, if any survive the pruning above, sit off the critical
|
|
147
|
+
path — genuinely deferred, not something the synapse-task-note skill would need answered to turn
|
|
148
|
+
this into real work? A `Ready` note is not required to have zero open questions (a deferred, non-
|
|
149
|
+
blocking question is fine to carry forward), but a note with a *blocking* open question is not
|
|
150
|
+
`Ready`, no matter how developed the rest of it is.
|
|
151
|
+
|
|
152
|
+
- **Both hold** → `Status: Ready`. Confirm: "Design note ready: `designs/{title}.md`.
|
|
153
|
+
Whenever you're ready to implement, ask me to compile it into a task note — no rush, nothing
|
|
154
|
+
here expires."
|
|
155
|
+
- **Genuinely nothing to build** → `Status: Reference`. Confirm: "Design note concluded as
|
|
156
|
+
Reference: `designs/{title}.md`. No task note needed."
|
|
157
|
+
- **Anything else** (the approach is still hedged, or an open question blocks it) → stays
|
|
158
|
+
`Status: Discussing`. This is the default outcome, not a fallback to apologize for — most
|
|
159
|
+
conversations end here, and that's fine; nothing here expires either.
|
|
160
|
+
|
|
161
|
+
If genuinely unsure which, ask the user directly.
|
|
162
|
+
|
|
163
|
+
There is no closing/renaming step here — nothing reads these notes automatically at session start,
|
|
164
|
+
so the `## Status` line is the only lifecycle marker that matters. It simply stays
|
|
165
|
+
`Ready`/`Reference` indefinitely.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Design Note Format
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
---
|
|
173
|
+
title: "{PROJECT} — {Topic}"
|
|
174
|
+
project: {prefix}
|
|
175
|
+
created: "{now}"
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
# {PROJECT} — {Topic}
|
|
179
|
+
|
|
180
|
+
## Status
|
|
181
|
+
Discussing | Ready | Reference
|
|
182
|
+
|
|
183
|
+
## Problem
|
|
184
|
+
{What are we solving, why does it matter, why now}
|
|
185
|
+
|
|
186
|
+
## Approach
|
|
187
|
+
{Chosen approach}
|
|
188
|
+
|
|
189
|
+
### Alternatives considered (optional)
|
|
190
|
+
- {Option}: why not
|
|
191
|
+
|
|
192
|
+
## Constraints
|
|
193
|
+
{Hard constraints, non-negotiables}
|
|
194
|
+
|
|
195
|
+
## Open Questions (optional)
|
|
196
|
+
- {Anything deferred or unresolved}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Fetch machine local time for `created` (`date '+%Y-%m-%d %H:%M'`) — never infer it.
|
|
200
|
+
|
|
201
|
+
No `Notes`/changelog section — it stays a small, single-conclusion note; there's no long-running
|
|
202
|
+
edit history here worth tracking separately.
|
|
203
|
+
|
|
204
|
+
## Filename
|
|
205
|
+
|
|
206
|
+
`designs/{PROJECT} — {Topic}.md` — sanitize filesystem-illegal characters (`/ : * ? " < > |`). No
|
|
207
|
+
slug, no numbering — Obsidian filenames are the title itself.
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Integration
|
|
212
|
+
|
|
213
|
+
- The synapse-task-note skill reads the matching `Ready` note as its only input.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Example
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
User: let's design "rollup direct storage"
|
|
221
|
+
|
|
222
|
+
Codex: [searches designs/ for existing matches — none found]
|
|
223
|
+
|
|
224
|
+
What are we designing?
|
|
225
|
+
|
|
226
|
+
User: Replacing the AggregatingMergeTree rollup resolution with direct-value storage.
|
|
227
|
+
|
|
228
|
+
Codex: [creates designs/{PROJECT} — Rollup direct storage.md, Status: Discussing]
|
|
229
|
+
|
|
230
|
+
What's driving this over just tuning the current argMaxMerge query?
|
|
231
|
+
...
|
|
232
|
+
User: The resolution cost alone dominates the query, tuning won't fix that. Mark it ready.
|
|
233
|
+
|
|
234
|
+
Codex: Design note ready: designs/{PROJECT} — Rollup direct storage.md.
|
|
235
|
+
Ask me to compile the task note whenever you're ready to implement.
|
|
236
|
+
```
|