@imunitic/synapse 0.0.1-test.1 → 0.1.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.
- package/bin/synapse-setup.cjs +52 -13
- package/package.json +8 -4
package/bin/synapse-setup.cjs
CHANGED
|
@@ -80,10 +80,43 @@ function readObsidianPluginData() {
|
|
|
80
80
|
return data;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
// The manifest recording exactly which names this tool wrote into a given
|
|
84
|
+
// destination on the prior run -- diffed against the current run's names
|
|
85
|
+
// so a renamed or removed skill/command is deleted instead of left behind
|
|
86
|
+
// as an orphan forever. Scoped strictly to names a previous manifest
|
|
87
|
+
// actually listed: anything else living in the same directory (a skill
|
|
88
|
+
// from a different source, or the user's own) was never in that manifest
|
|
89
|
+
// and is never touched. Lives inside `destRoot` itself, as a dotfile --
|
|
90
|
+
// no `.md` extension and not a `{name}/SKILL.md` subdirectory, so no
|
|
91
|
+
// harness's own skill/command discovery mistakes it for one of ours.
|
|
92
|
+
const MANAGED_MANIFEST = ".synapse-managed.json";
|
|
93
|
+
|
|
94
|
+
function pruneStale(destRoot, currentNames) {
|
|
95
|
+
const manifestPath = path.join(destRoot, MANAGED_MANIFEST);
|
|
96
|
+
let previous = [];
|
|
97
|
+
if (fs.existsSync(manifestPath)) {
|
|
98
|
+
try {
|
|
99
|
+
previous = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
100
|
+
} catch {
|
|
101
|
+
previous = [];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const current = new Set(currentNames);
|
|
105
|
+
for (const name of previous) {
|
|
106
|
+
if (current.has(name)) continue;
|
|
107
|
+
fs.rmSync(path.join(destRoot, name), { recursive: true, force: true });
|
|
108
|
+
}
|
|
109
|
+
fs.mkdirSync(destRoot, { recursive: true });
|
|
110
|
+
fs.writeFileSync(manifestPath, JSON.stringify(currentNames, null, 2) + "\n");
|
|
111
|
+
}
|
|
112
|
+
|
|
83
113
|
// Copies every shared SKILL.md into `destRoot/{name}/SKILL.md`, verbatim
|
|
84
114
|
// unless `transform` is given. Each skill gets its own uniquely-named
|
|
85
115
|
// subdirectory, so overwriting ours on every run never touches anything a
|
|
86
116
|
// harness's own skill discovery also finds there under a different name.
|
|
117
|
+
// Returns the names written -- pruning stale ones is the caller's job,
|
|
118
|
+
// since a destRoot shared with another source (Codex's own skills, on top
|
|
119
|
+
// of these) needs the combined set before it can prune safely.
|
|
87
120
|
function copySkills(destRoot, transform) {
|
|
88
121
|
const src = path.join(PKG_ROOT, "skills");
|
|
89
122
|
const names = fs
|
|
@@ -96,7 +129,7 @@ function copySkills(destRoot, transform) {
|
|
|
96
129
|
fs.mkdirSync(destDir, { recursive: true });
|
|
97
130
|
writeMaybeTransformed(path.join(src, name, "SKILL.md"), path.join(destDir, "SKILL.md"), transform);
|
|
98
131
|
}
|
|
99
|
-
return names
|
|
132
|
+
return names;
|
|
100
133
|
}
|
|
101
134
|
|
|
102
135
|
function copyCommands(destRoot, transform) {
|
|
@@ -106,7 +139,7 @@ function copyCommands(destRoot, transform) {
|
|
|
106
139
|
for (const name of names) {
|
|
107
140
|
writeMaybeTransformed(path.join(src, name), path.join(destRoot, name), transform);
|
|
108
141
|
}
|
|
109
|
-
return names
|
|
142
|
+
return names;
|
|
110
143
|
}
|
|
111
144
|
|
|
112
145
|
function writeMaybeTransformed(srcPath, destPath, transform) {
|
|
@@ -177,9 +210,13 @@ function mergeHooksInto(existingHooks, rendered, hookBin) {
|
|
|
177
210
|
function configureClaude() {
|
|
178
211
|
const hookBin = resolveHookBin();
|
|
179
212
|
|
|
180
|
-
const
|
|
181
|
-
const
|
|
182
|
-
|
|
213
|
+
const skillsDest = path.join(os.homedir(), ".claude", "skills");
|
|
214
|
+
const skillNames = copySkills(skillsDest);
|
|
215
|
+
pruneStale(skillsDest, skillNames);
|
|
216
|
+
const commandsDest = path.join(os.homedir(), ".claude", "commands");
|
|
217
|
+
const commandNames = copyCommands(commandsDest);
|
|
218
|
+
pruneStale(commandsDest, commandNames);
|
|
219
|
+
console.log(`installed ${skillNames.length} skills, ${commandNames.length} commands to ~/.claude`);
|
|
183
220
|
|
|
184
221
|
const settingsPath = path.join(os.homedir(), ".claude", "settings.json");
|
|
185
222
|
let settings = {};
|
|
@@ -283,7 +320,7 @@ function configureCodex() {
|
|
|
283
320
|
console.log(`configured ${hooksPath}`);
|
|
284
321
|
|
|
285
322
|
const skillsDestRoot = path.join(os.homedir(), ".codex", "skills");
|
|
286
|
-
const
|
|
323
|
+
const sharedNames = copySkills(skillsDestRoot);
|
|
287
324
|
const codexSkillsSrc = path.join(PKG_ROOT, "harness", "codex", "skills");
|
|
288
325
|
const codexNames = fs
|
|
289
326
|
.readdirSync(codexSkillsSrc, { withFileTypes: true })
|
|
@@ -293,7 +330,8 @@ function configureCodex() {
|
|
|
293
330
|
for (const name of codexNames) {
|
|
294
331
|
fs.cpSync(path.join(codexSkillsSrc, name), path.join(skillsDestRoot, name), { recursive: true, force: true });
|
|
295
332
|
}
|
|
296
|
-
|
|
333
|
+
pruneStale(skillsDestRoot, [...sharedNames, ...codexNames]);
|
|
334
|
+
console.log(`installed ${sharedNames.length + codexNames.length} skills to ${skillsDestRoot}`);
|
|
297
335
|
|
|
298
336
|
const pluginData = readObsidianPluginData();
|
|
299
337
|
if (!pluginData.enableInsecureServer || !pluginData.insecurePort) {
|
|
@@ -365,12 +403,13 @@ function configureOpencode() {
|
|
|
365
403
|
fs.writeFileSync(pluginDest, pluginSource);
|
|
366
404
|
console.log(`installed ${pluginDest}`);
|
|
367
405
|
|
|
368
|
-
const
|
|
369
|
-
const
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
);
|
|
373
|
-
|
|
406
|
+
const skillsDest = path.join(os.homedir(), ".config", "opencode", "skill");
|
|
407
|
+
const skillNames = copySkills(skillsDest, opencodeToolNameTransform);
|
|
408
|
+
pruneStale(skillsDest, skillNames);
|
|
409
|
+
const commandsDest = path.join(os.homedir(), ".config", "opencode", "command");
|
|
410
|
+
const commandNames = copyCommands(commandsDest, opencodeToolNameTransform);
|
|
411
|
+
pruneStale(commandsDest, commandNames);
|
|
412
|
+
console.log(`installed ${skillNames.length} skills, ${commandNames.length} commands to ~/.config/opencode`);
|
|
374
413
|
|
|
375
414
|
const pluginData = readObsidianPluginData();
|
|
376
415
|
if (!pluginData.enableInsecureServer || !pluginData.insecurePort) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@imunitic/synapse",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Memory for Claude Code, Codex CLI, and OpenCode: a durable Obsidian vault plus a per-repo code graph.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/imunitic/synapse"
|
|
8
|
+
},
|
|
5
9
|
"bin": {
|
|
6
10
|
"synapse-setup": "bin/synapse-setup.cjs",
|
|
7
11
|
"synapse": "bin/synapse.cjs",
|
|
@@ -18,9 +22,9 @@
|
|
|
18
22
|
"*.conf.template"
|
|
19
23
|
],
|
|
20
24
|
"optionalDependencies": {
|
|
21
|
-
"@imunitic/synapse-darwin-arm64": "0.
|
|
22
|
-
"@imunitic/synapse-linux-x64": "0.
|
|
23
|
-
"@imunitic/synapse-linux-arm64": "0.
|
|
25
|
+
"@imunitic/synapse-darwin-arm64": "0.1.1",
|
|
26
|
+
"@imunitic/synapse-linux-x64": "0.1.1",
|
|
27
|
+
"@imunitic/synapse-linux-arm64": "0.1.1"
|
|
24
28
|
},
|
|
25
29
|
"license": "SEE LICENSE IN LICENSE"
|
|
26
30
|
}
|