memtrace 0.1.5 → 0.1.20

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 (3) hide show
  1. package/README.md +3 -3
  2. package/install.js +183 -11
  3. package/package.json +4 -6
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="https://raw.githubusercontent.com/syncable-dev/memtrace/main/assets/logo.svg" alt="Memtrace" width="120" height="120" />
2
+ <img src="https://raw.githubusercontent.com/syncable-dev/memtrace-public/main/assets/logo.svg" alt="Memtrace" width="120" height="120" />
3
3
  </p>
4
4
 
5
5
  <h1 align="center">Memtrace</h1>
@@ -12,8 +12,8 @@
12
12
  <p align="center">
13
13
  <a href="https://www.npmjs.com/package/memtrace"><img src="https://img.shields.io/npm/v/memtrace?style=flat-square&color=00D4B8&label=npm" alt="npm version" /></a>
14
14
  <a href="https://www.npmjs.com/package/memtrace"><img src="https://img.shields.io/npm/dm/memtrace?style=flat-square&color=0A1628&label=downloads" alt="npm downloads" /></a>
15
- <a href="https://github.com/syncable-dev/memtrace/stargazers"><img src="https://img.shields.io/github/stars/syncable-dev/memtrace?style=flat-square&color=00D4B8" alt="GitHub stars" /></a>
16
- <a href="https://github.com/syncable-dev/memtrace/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-FSL--1.1--MIT-0A1628?style=flat-square" alt="license" /></a>
15
+ <a href="https://github.com/syncable-dev/memtrace-public/stargazers"><img src="https://img.shields.io/github/stars/syncable-dev/memtrace-public?style=flat-square&color=00D4B8" alt="GitHub stars" /></a>
16
+ <a href="https://github.com/syncable-dev/memtrace-public/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-FSL--1.1--MIT-0A1628?style=flat-square" alt="license" /></a>
17
17
  <a href="https://memtrace.dev"><img src="https://img.shields.io/badge/docs-memtrace.dev-00D4B8?style=flat-square" alt="docs" /></a>
18
18
  </p>
19
19
 
package/install.js CHANGED
@@ -4,6 +4,13 @@
4
4
  const os = require("os");
5
5
  const path = require("path");
6
6
  const fs = require("fs");
7
+ const { execSync } = require("child_process");
8
+
9
+ // ── Constants ─────────────────────────────────────────────────────────────────
10
+
11
+ const PLUGIN_NAME = "memtrace-skills";
12
+ const MARKETPLACE_NAME = "memtrace";
13
+ const MARKETPLACE_REPO = "syncable-dev/memtrace-public";
7
14
 
8
15
  const PLATFORM_MAP = {
9
16
  "darwin-arm64": "@memtrace/darwin-arm64",
@@ -13,10 +20,10 @@ const PLATFORM_MAP = {
13
20
  "win32-x64": "@memtrace/win32-x64",
14
21
  };
15
22
 
23
+ // ── Binary helpers ────────────────────────────────────────────────────────────
24
+
16
25
  function getPlatformKey() {
17
- const platform = os.platform(); // darwin, linux, win32
18
- const arch = os.arch(); // arm64, x64
19
- return `${platform}-${arch}`;
26
+ return `${os.platform()}-${os.arch()}`;
20
27
  }
21
28
 
22
29
  function getBinaryPath() {
@@ -43,22 +50,187 @@ function getBinaryPath() {
43
50
  }
44
51
  }
45
52
 
46
- // postinstall: verify the binary exists and is executable
53
+ // ── Skill installation ───────────────────────────────────────────────────────
54
+
55
+ function installSkills() {
56
+ const skillsSrc = path.join(__dirname, "skills");
57
+ if (!fs.existsSync(skillsSrc)) {
58
+ console.warn("memtrace: skills directory not found, skipping skill installation");
59
+ return;
60
+ }
61
+
62
+ const claudeSkillsDir = path.join(os.homedir(), ".claude", "skills");
63
+
64
+ // Collect all .md skill files from commands/ and workflows/
65
+ const skillDirs = ["commands", "workflows"];
66
+ let installed = 0;
67
+
68
+ for (const dir of skillDirs) {
69
+ const srcDir = path.join(skillsSrc, dir);
70
+ if (!fs.existsSync(srcDir)) continue;
71
+
72
+ const files = fs.readdirSync(srcDir).filter(f => f.endsWith(".md"));
73
+ for (const file of files) {
74
+ const skillName = file.replace(/\.md$/, "");
75
+ const destDir = path.join(claudeSkillsDir, skillName);
76
+ const srcFile = path.join(srcDir, file);
77
+
78
+ try {
79
+ fs.mkdirSync(destDir, { recursive: true });
80
+ fs.copyFileSync(srcFile, path.join(destDir, "SKILL.md"));
81
+ installed++;
82
+ } catch (e) {
83
+ console.warn(`memtrace: failed to install skill ${skillName}: ${e.message}`);
84
+ }
85
+ }
86
+ }
87
+
88
+ if (installed > 0) {
89
+ console.log(`memtrace: installed ${installed} skills to ${claudeSkillsDir}`);
90
+ }
91
+ }
92
+
93
+ // ── Settings.json helpers ────────────────────────────────────────────────────
94
+
95
+ function readSettings() {
96
+ const settingsFile = path.join(os.homedir(), ".claude", "settings.json");
97
+ if (fs.existsSync(settingsFile)) {
98
+ try {
99
+ return JSON.parse(fs.readFileSync(settingsFile, "utf-8"));
100
+ } catch {
101
+ return {};
102
+ }
103
+ }
104
+ return {};
105
+ }
106
+
107
+ function writeSettings(settings) {
108
+ const settingsFile = path.join(os.homedir(), ".claude", "settings.json");
109
+ fs.mkdirSync(path.dirname(settingsFile), { recursive: true });
110
+ fs.writeFileSync(settingsFile, JSON.stringify(settings, null, 2) + "\n");
111
+ }
112
+
113
+ // ── MCP server registration ─────────────────────────────────────────────────
114
+
115
+ function registerMcpServer(binaryPath) {
116
+ const settings = readSettings();
117
+
118
+ if (!settings.mcpServers || typeof settings.mcpServers !== "object") {
119
+ settings.mcpServers = {};
120
+ }
121
+
122
+ settings.mcpServers.memtrace = {
123
+ command: binaryPath,
124
+ args: ["mcp"],
125
+ env: {
126
+ MEMGRAPH_URL: "bolt://localhost:7687",
127
+ },
128
+ };
129
+
130
+ writeSettings(settings);
131
+ console.log("memtrace: registered MCP server in ~/.claude/settings.json");
132
+ }
133
+
134
+ // ── Plugin + marketplace registration ────────────────────────────────────────
135
+
136
+ function enablePlugin() {
137
+ const settings = readSettings();
138
+
139
+ // Enable plugin
140
+ if (!settings.enabledPlugins || typeof settings.enabledPlugins !== "object") {
141
+ settings.enabledPlugins = {};
142
+ }
143
+ const pluginKey = `${PLUGIN_NAME}@${MARKETPLACE_NAME}`;
144
+ settings.enabledPlugins[pluginKey] = true;
145
+
146
+ // Register marketplace
147
+ if (!settings.extraKnownMarketplaces || typeof settings.extraKnownMarketplaces !== "object") {
148
+ settings.extraKnownMarketplaces = {};
149
+ }
150
+ settings.extraKnownMarketplaces[MARKETPLACE_NAME] = {
151
+ source: {
152
+ source: "github",
153
+ repo: MARKETPLACE_REPO,
154
+ },
155
+ };
156
+
157
+ writeSettings(settings);
158
+ console.log(`memtrace: enabled plugin ${pluginKey}`);
159
+ console.log(`memtrace: registered marketplace ${MARKETPLACE_NAME}`);
160
+ }
161
+
162
+ // ── Try Claude CLI install first ─────────────────────────────────────────────
163
+
164
+ function commandExists(cmd) {
165
+ try {
166
+ execSync(`which ${cmd}`, { stdio: "ignore" });
167
+ return true;
168
+ } catch {
169
+ return false;
170
+ }
171
+ }
172
+
173
+ function tryClaudeCliInstall() {
174
+ if (!commandExists("claude")) return false;
175
+
176
+ try {
177
+ execSync(`claude plugin marketplace add ${MARKETPLACE_REPO}`, {
178
+ stdio: "ignore",
179
+ timeout: 15000,
180
+ });
181
+ execSync(`claude plugin install ${PLUGIN_NAME}@${MARKETPLACE_NAME} --scope user`, {
182
+ stdio: "ignore",
183
+ timeout: 15000,
184
+ });
185
+ console.log("memtrace: installed skills via Claude CLI");
186
+ return true;
187
+ } catch {
188
+ return false;
189
+ }
190
+ }
191
+
192
+ // ── Main postinstall ─────────────────────────────────────────────────────────
193
+
47
194
  if (require.main === module) {
195
+ // 1. Verify binary
196
+ let binaryPath = null;
48
197
  try {
49
- const bin = getBinaryPath();
50
- if (!fs.existsSync(bin)) {
51
- throw new Error(`Binary not found at: ${bin}`);
198
+ binaryPath = getBinaryPath();
199
+ if (!fs.existsSync(binaryPath)) {
200
+ throw new Error(`Binary not found at: ${binaryPath}`);
52
201
  }
53
- // Ensure executable on Unix
54
202
  if (os.platform() !== "win32") {
55
- fs.chmodSync(bin, 0o755);
203
+ fs.chmodSync(binaryPath, 0o755);
56
204
  }
57
- console.log(`memtrace: installed binary at ${bin}`);
205
+ console.log(`memtrace: binary installed at ${binaryPath}`);
58
206
  } catch (e) {
59
- // Non-fatal — optional deps may not be installed in all environments
60
207
  console.warn(`memtrace: ${e.message}`);
61
208
  }
209
+
210
+ // 2. Install skills to ~/.claude/skills/
211
+ try {
212
+ installSkills();
213
+ } catch (e) {
214
+ console.warn(`memtrace: skill installation failed: ${e.message}`);
215
+ }
216
+
217
+ // 3. Try Claude CLI first, fall back to manual settings
218
+ try {
219
+ if (!tryClaudeCliInstall()) {
220
+ enablePlugin();
221
+ }
222
+ } catch (e) {
223
+ console.warn(`memtrace: plugin registration failed: ${e.message}`);
224
+ }
225
+
226
+ // 4. Register MCP server
227
+ if (binaryPath) {
228
+ try {
229
+ registerMcpServer(binaryPath);
230
+ } catch (e) {
231
+ console.warn(`memtrace: MCP server registration failed: ${e.message}`);
232
+ }
233
+ }
62
234
  }
63
235
 
64
236
  module.exports = { getBinaryPath };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memtrace",
3
- "version": "0.1.5",
3
+ "version": "0.1.20",
4
4
  "description": "Code intelligence graph — MCP server + AI agent skills + visualization UI",
5
5
  "keywords": [
6
6
  "mcp",
@@ -29,11 +29,9 @@
29
29
  "postinstall": "node install.js"
30
30
  },
31
31
  "optionalDependencies": {
32
- "@memtrace/darwin-arm64": "0.1.0",
33
- "@memtrace/darwin-x64": "0.1.0",
34
- "@memtrace/linux-x64": "0.1.0",
35
- "@memtrace/linux-arm64": "0.1.0",
36
- "@memtrace/win32-x64": "0.1.0"
32
+ "@memtrace/darwin-arm64": "0.1.20",
33
+ "@memtrace/linux-x64": "0.1.20",
34
+ "@memtrace/win32-x64": "0.1.20"
37
35
  },
38
36
  "engines": {
39
37
  "node": ">=18"