memtrace-skills 0.7.10
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/dist/commands/doctor.d.ts +16 -0
- package/dist/commands/doctor.js +199 -0
- package/dist/commands/enterprise-install.d.ts +7 -0
- package/dist/commands/enterprise-install.js +129 -0
- package/dist/commands/install.d.ts +9 -0
- package/dist/commands/install.js +104 -0
- package/dist/commands/picker.d.ts +6 -0
- package/dist/commands/picker.js +22 -0
- package/dist/commands/rail-install.d.ts +7 -0
- package/dist/commands/rail-install.js +37 -0
- package/dist/fs-safe.d.ts +21 -0
- package/dist/fs-safe.js +35 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +87 -0
- package/dist/rail-install.d.ts +20 -0
- package/dist/rail-install.js +183 -0
- package/dist/skills.d.ts +17 -0
- package/dist/skills.js +64 -0
- package/dist/transformers/claude.d.ts +71 -0
- package/dist/transformers/claude.js +702 -0
- package/dist/transformers/codex.d.ts +8 -0
- package/dist/transformers/codex.js +294 -0
- package/dist/transformers/cursor.d.ts +7 -0
- package/dist/transformers/cursor.js +124 -0
- package/dist/transformers/gemini.d.ts +3 -0
- package/dist/transformers/gemini.js +78 -0
- package/dist/transformers/hermes.d.ts +5 -0
- package/dist/transformers/hermes.js +136 -0
- package/dist/transformers/index.d.ts +14 -0
- package/dist/transformers/index.js +24 -0
- package/dist/transformers/kiro.d.ts +2 -0
- package/dist/transformers/kiro.js +69 -0
- package/dist/transformers/opencode.d.ts +2 -0
- package/dist/transformers/opencode.js +77 -0
- package/dist/transformers/rail-hooks.d.ts +56 -0
- package/dist/transformers/rail-hooks.js +303 -0
- package/dist/transformers/shared.d.ts +18 -0
- package/dist/transformers/shared.js +129 -0
- package/dist/transformers/types.d.ts +40 -0
- package/dist/transformers/types.js +1 -0
- package/dist/transformers/vscode.d.ts +3 -0
- package/dist/transformers/vscode.js +53 -0
- package/dist/transformers/windsurf.d.ts +3 -0
- package/dist/transformers/windsurf.js +43 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +22 -0
- package/package.json +50 -0
- package/plugins/memtrace-skills/.claude-plugin/plugin.json +23 -0
- package/plugins/memtrace-skills/references/mcp-parameters.md +302 -0
- package/plugins/memtrace-skills/skills/memtrace-api-topology/SKILL.md +58 -0
- package/plugins/memtrace-skills/skills/memtrace-change-impact-analysis/SKILL.md +75 -0
- package/plugins/memtrace-skills/skills/memtrace-cochange/SKILL.md +71 -0
- package/plugins/memtrace-skills/skills/memtrace-code-review/SKILL.md +41 -0
- package/plugins/memtrace-skills/skills/memtrace-codebase-exploration/SKILL.md +94 -0
- package/plugins/memtrace-skills/skills/memtrace-continuous-memory/SKILL.md +96 -0
- package/plugins/memtrace-skills/skills/memtrace-episode-replay/SKILL.md +94 -0
- package/plugins/memtrace-skills/skills/memtrace-evolution/SKILL.md +128 -0
- package/plugins/memtrace-skills/skills/memtrace-first/SKILL.md +194 -0
- package/plugins/memtrace-skills/skills/memtrace-fleet-coordination/SKILL.md +80 -0
- package/plugins/memtrace-skills/skills/memtrace-fleet-first/SKILL.md +125 -0
- package/plugins/memtrace-skills/skills/memtrace-fleet-publish-intent/SKILL.md +48 -0
- package/plugins/memtrace-skills/skills/memtrace-fleet-record-episode/SKILL.md +44 -0
- package/plugins/memtrace-skills/skills/memtrace-fleet-resolve/SKILL.md +54 -0
- package/plugins/memtrace-skills/skills/memtrace-graph/SKILL.md +67 -0
- package/plugins/memtrace-skills/skills/memtrace-impact/SKILL.md +58 -0
- package/plugins/memtrace-skills/skills/memtrace-incident-investigation/SKILL.md +112 -0
- package/plugins/memtrace-skills/skills/memtrace-index/SKILL.md +65 -0
- package/plugins/memtrace-skills/skills/memtrace-quality/SKILL.md +63 -0
- package/plugins/memtrace-skills/skills/memtrace-refactoring-guide/SKILL.md +103 -0
- package/plugins/memtrace-skills/skills/memtrace-relationships/SKILL.md +67 -0
- package/plugins/memtrace-skills/skills/memtrace-search/SKILL.md +93 -0
- package/plugins/memtrace-skills/skills/memtrace-session-continuity/SKILL.md +93 -0
- package/plugins/memtrace-skills/skills/memtrace-style-fingerprint/SKILL.md +105 -0
- package/skills/commands/memtrace-api-topology.md +65 -0
- package/skills/commands/memtrace-cochange.md +76 -0
- package/skills/commands/memtrace-evolution.md +135 -0
- package/skills/commands/memtrace-fleet-publish-intent.md +51 -0
- package/skills/commands/memtrace-fleet-record-episode.md +48 -0
- package/skills/commands/memtrace-fleet-resolve.md +59 -0
- package/skills/commands/memtrace-graph.md +75 -0
- package/skills/commands/memtrace-impact.md +64 -0
- package/skills/commands/memtrace-index.md +71 -0
- package/skills/commands/memtrace-quality.md +69 -0
- package/skills/commands/memtrace-relationships.md +73 -0
- package/skills/commands/memtrace-search.md +93 -0
- package/skills/workflows/memtrace-change-impact-analysis.md +85 -0
- package/skills/workflows/memtrace-code-review.md +48 -0
- package/skills/workflows/memtrace-codebase-exploration.md +108 -0
- package/skills/workflows/memtrace-continuous-memory.md +104 -0
- package/skills/workflows/memtrace-episode-replay.md +100 -0
- package/skills/workflows/memtrace-first.md +194 -0
- package/skills/workflows/memtrace-fleet-coordination.md +87 -0
- package/skills/workflows/memtrace-fleet-first.md +132 -0
- package/skills/workflows/memtrace-incident-investigation.md +125 -0
- package/skills/workflows/memtrace-refactoring-guide.md +116 -0
- package/skills/workflows/memtrace-session-continuity.md +98 -0
- package/skills/workflows/memtrace-style-fingerprint.md +111 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { safeReadJson, writeJsonAtomic } from '../fs-safe.js';
|
|
4
|
+
export const MCP_SERVER_NAME = 'memtrace';
|
|
5
|
+
// The binary reads its configuration (workspace anchors, mode) directly, so no
|
|
6
|
+
// env vars are required at MCP-registration time. Kept as an empty constant so
|
|
7
|
+
// any future env-var plumbing (e.g. RUST_LOG, MEMTRACE_DATA_DIR overrides) has
|
|
8
|
+
// one place to land. The upgrade migration in install.js also prunes stale env
|
|
9
|
+
// keys from pre-existing MCP entries.
|
|
10
|
+
export const MEMTRACE_MCP_ENV = {};
|
|
11
|
+
export function skillName(skill) {
|
|
12
|
+
return skill.filename.replace(/\.md$/, '');
|
|
13
|
+
}
|
|
14
|
+
export function skillMarkdown(skill, extraFrontmatter = {}) {
|
|
15
|
+
const name = skillName(skill);
|
|
16
|
+
const safeDesc = skill.frontmatter.description.replace(/"/g, '\\"').trim();
|
|
17
|
+
const extra = Object.entries(extraFrontmatter)
|
|
18
|
+
.map(([key, value]) => `${key}: ${value}`)
|
|
19
|
+
.join('\n');
|
|
20
|
+
return `---\nname: ${name}\ndescription: "${safeDesc}"${extra ? `\n${extra}` : ''}\n---\n\n${skill.body}`;
|
|
21
|
+
}
|
|
22
|
+
export function writeSkills(skills, rootDir, extraFrontmatter = {}) {
|
|
23
|
+
removeMemtraceSkills(rootDir);
|
|
24
|
+
for (const skill of skills) {
|
|
25
|
+
const name = skillName(skill);
|
|
26
|
+
const outDir = path.join(rootDir, name);
|
|
27
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
28
|
+
fs.writeFileSync(path.join(outDir, 'SKILL.md'), skillMarkdown(skill, extraFrontmatter));
|
|
29
|
+
}
|
|
30
|
+
return skills.length;
|
|
31
|
+
}
|
|
32
|
+
export function removeMemtraceSkills(rootDir) {
|
|
33
|
+
if (!fs.existsSync(rootDir))
|
|
34
|
+
return;
|
|
35
|
+
for (const entry of fs.readdirSync(rootDir)) {
|
|
36
|
+
if (entry.startsWith('memtrace-')) {
|
|
37
|
+
fs.rmSync(path.join(rootDir, entry), { recursive: true, force: true });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export function writeTextAtomic(filePath, content) {
|
|
42
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
43
|
+
const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
|
|
44
|
+
fs.writeFileSync(tmpPath, content);
|
|
45
|
+
fs.renameSync(tmpPath, filePath);
|
|
46
|
+
}
|
|
47
|
+
export function registerMcpServersJsonAt(filePath, binary) {
|
|
48
|
+
const { value, corrupted, backupPath } = safeReadJson(filePath);
|
|
49
|
+
if (corrupted)
|
|
50
|
+
return { registered: false, backupPath };
|
|
51
|
+
const cfg = (value ?? {});
|
|
52
|
+
cfg.mcpServers = cfg.mcpServers ?? {};
|
|
53
|
+
cfg.mcpServers[MCP_SERVER_NAME] = {
|
|
54
|
+
command: binary,
|
|
55
|
+
args: ['mcp'],
|
|
56
|
+
env: MEMTRACE_MCP_ENV,
|
|
57
|
+
};
|
|
58
|
+
writeJsonAtomic(filePath, cfg);
|
|
59
|
+
return { registered: true };
|
|
60
|
+
}
|
|
61
|
+
export function removeMcpServersJsonAt(filePath) {
|
|
62
|
+
const { value, corrupted } = safeReadJson(filePath);
|
|
63
|
+
if (corrupted || !value?.mcpServers?.[MCP_SERVER_NAME])
|
|
64
|
+
return;
|
|
65
|
+
delete value.mcpServers[MCP_SERVER_NAME];
|
|
66
|
+
if (Object.keys(value.mcpServers).length === 0)
|
|
67
|
+
delete value.mcpServers;
|
|
68
|
+
if (Object.keys(value).length === 0)
|
|
69
|
+
fs.unlinkSync(filePath);
|
|
70
|
+
else
|
|
71
|
+
writeJsonAtomic(filePath, value);
|
|
72
|
+
}
|
|
73
|
+
export function registerVsCodeMcpAt(filePath, binary) {
|
|
74
|
+
const { value, corrupted, backupPath } = safeReadJson(filePath);
|
|
75
|
+
if (corrupted)
|
|
76
|
+
return { registered: false, backupPath };
|
|
77
|
+
const cfg = (value ?? {});
|
|
78
|
+
cfg.servers = cfg.servers ?? {};
|
|
79
|
+
cfg.servers[MCP_SERVER_NAME] = {
|
|
80
|
+
type: 'stdio',
|
|
81
|
+
command: binary,
|
|
82
|
+
args: ['mcp'],
|
|
83
|
+
env: MEMTRACE_MCP_ENV,
|
|
84
|
+
};
|
|
85
|
+
writeJsonAtomic(filePath, cfg);
|
|
86
|
+
return { registered: true };
|
|
87
|
+
}
|
|
88
|
+
export function removeVsCodeMcpAt(filePath) {
|
|
89
|
+
const { value, corrupted } = safeReadJson(filePath);
|
|
90
|
+
if (corrupted || !value?.servers?.[MCP_SERVER_NAME])
|
|
91
|
+
return;
|
|
92
|
+
delete value.servers[MCP_SERVER_NAME];
|
|
93
|
+
if (Object.keys(value.servers).length === 0)
|
|
94
|
+
delete value.servers;
|
|
95
|
+
if (Object.keys(value).length === 0)
|
|
96
|
+
fs.unlinkSync(filePath);
|
|
97
|
+
else
|
|
98
|
+
writeJsonAtomic(filePath, value);
|
|
99
|
+
}
|
|
100
|
+
export function registerOpenCodeMcpAt(filePath, binary) {
|
|
101
|
+
const { value, corrupted, backupPath } = safeReadJson(filePath);
|
|
102
|
+
if (corrupted)
|
|
103
|
+
return { registered: false, backupPath };
|
|
104
|
+
const cfg = (value ?? {});
|
|
105
|
+
cfg.$schema = cfg.$schema ?? 'https://opencode.ai/config.json';
|
|
106
|
+
cfg.mcp = cfg.mcp ?? {};
|
|
107
|
+
cfg.mcp[MCP_SERVER_NAME] = {
|
|
108
|
+
type: 'local',
|
|
109
|
+
command: [binary, 'mcp'],
|
|
110
|
+
enabled: true,
|
|
111
|
+
environment: MEMTRACE_MCP_ENV,
|
|
112
|
+
};
|
|
113
|
+
writeJsonAtomic(filePath, cfg);
|
|
114
|
+
return { registered: true };
|
|
115
|
+
}
|
|
116
|
+
export function removeOpenCodeMcpAt(filePath) {
|
|
117
|
+
const { value, corrupted } = safeReadJson(filePath);
|
|
118
|
+
if (corrupted || !value?.mcp?.[MCP_SERVER_NAME])
|
|
119
|
+
return;
|
|
120
|
+
delete value.mcp[MCP_SERVER_NAME];
|
|
121
|
+
if (Object.keys(value.mcp).length === 0)
|
|
122
|
+
delete value.mcp;
|
|
123
|
+
const remainingKeys = Object.keys(value);
|
|
124
|
+
if (remainingKeys.length === 0 || (remainingKeys.length === 1 && remainingKeys[0] === '$schema')) {
|
|
125
|
+
fs.unlinkSync(filePath);
|
|
126
|
+
}
|
|
127
|
+
else
|
|
128
|
+
writeJsonAtomic(filePath, value);
|
|
129
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Skill } from '../skills.js';
|
|
2
|
+
/**
|
|
3
|
+
* A single file to write for a given agent.
|
|
4
|
+
*/
|
|
5
|
+
export interface TransformResult {
|
|
6
|
+
/** Relative path from the agent's root skill directory. */
|
|
7
|
+
relativePath: string;
|
|
8
|
+
/** File content (UTF-8 text). */
|
|
9
|
+
content: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Runtime context passed to every transformer during install/uninstall.
|
|
13
|
+
*/
|
|
14
|
+
export interface InstallContext {
|
|
15
|
+
/** 'global' = write user-level config; 'local' = write project-level config under cwd. */
|
|
16
|
+
scope: 'global' | 'local';
|
|
17
|
+
/** Used for local scope. Absolute path. */
|
|
18
|
+
cwd: string;
|
|
19
|
+
/** Command or absolute path used as the MCP server command. */
|
|
20
|
+
memtraceBinary: string;
|
|
21
|
+
/** When true, write skills but skip MCP registration. */
|
|
22
|
+
skipMcp?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface InstallResult {
|
|
25
|
+
agent: AgentName;
|
|
26
|
+
skillsWritten: number;
|
|
27
|
+
skillsDir: string;
|
|
28
|
+
mcpConfigPath?: string;
|
|
29
|
+
mcpRegistered: boolean;
|
|
30
|
+
warnings: string[];
|
|
31
|
+
}
|
|
32
|
+
export type AgentName = 'claude' | 'cursor' | 'codex' | 'gemini' | 'windsurf' | 'vscode' | 'hermes' | 'opencode' | 'kiro';
|
|
33
|
+
/**
|
|
34
|
+
* One transformer per supported AI coding agent.
|
|
35
|
+
*/
|
|
36
|
+
export interface Transformer {
|
|
37
|
+
name: AgentName;
|
|
38
|
+
install(skills: Skill[], ctx: InstallContext): Promise<InstallResult>;
|
|
39
|
+
uninstall(ctx: InstallContext): Promise<void>;
|
|
40
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import os from 'os';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { registerVsCodeMcpAt, removeMemtraceSkills, removeVsCodeMcpAt, writeSkills, } from './shared.js';
|
|
4
|
+
function skillsRoot(ctx) {
|
|
5
|
+
return ctx.scope === 'global'
|
|
6
|
+
? path.join(os.homedir(), '.copilot', 'skills')
|
|
7
|
+
: path.join(ctx.cwd, '.github', 'skills');
|
|
8
|
+
}
|
|
9
|
+
export function vscodeUserMcpPath() {
|
|
10
|
+
if (process.platform === 'win32') {
|
|
11
|
+
const appData = process.env.APPDATA ?? path.join(os.homedir(), 'AppData', 'Roaming');
|
|
12
|
+
return path.join(appData, 'Code', 'User', 'mcp.json');
|
|
13
|
+
}
|
|
14
|
+
if (process.platform === 'darwin') {
|
|
15
|
+
return path.join(os.homedir(), 'Library', 'Application Support', 'Code', 'User', 'mcp.json');
|
|
16
|
+
}
|
|
17
|
+
const xdg = process.env.XDG_CONFIG_HOME ?? path.join(os.homedir(), '.config');
|
|
18
|
+
return path.join(xdg, 'Code', 'User', 'mcp.json');
|
|
19
|
+
}
|
|
20
|
+
function mcpPath(ctx) {
|
|
21
|
+
return ctx.scope === 'global'
|
|
22
|
+
? vscodeUserMcpPath()
|
|
23
|
+
: path.join(ctx.cwd, '.vscode', 'mcp.json');
|
|
24
|
+
}
|
|
25
|
+
export const vscodeTransformer = {
|
|
26
|
+
name: 'vscode',
|
|
27
|
+
async install(skills, ctx) {
|
|
28
|
+
const rootDir = skillsRoot(ctx);
|
|
29
|
+
const count = writeSkills(skills, rootDir);
|
|
30
|
+
let mcpRegistered = false;
|
|
31
|
+
const warnings = [];
|
|
32
|
+
const mcpConfigPath = mcpPath(ctx);
|
|
33
|
+
if (!ctx.skipMcp) {
|
|
34
|
+
const result = registerVsCodeMcpAt(mcpConfigPath, ctx.memtraceBinary);
|
|
35
|
+
mcpRegistered = result.registered;
|
|
36
|
+
if (!mcpRegistered && result.backupPath) {
|
|
37
|
+
warnings.push(`VS Code MCP config was malformed; backed up to ${result.backupPath}.`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
agent: 'vscode',
|
|
42
|
+
skillsWritten: count,
|
|
43
|
+
skillsDir: rootDir,
|
|
44
|
+
mcpConfigPath,
|
|
45
|
+
mcpRegistered,
|
|
46
|
+
warnings,
|
|
47
|
+
};
|
|
48
|
+
},
|
|
49
|
+
async uninstall(ctx) {
|
|
50
|
+
removeMemtraceSkills(skillsRoot(ctx));
|
|
51
|
+
removeVsCodeMcpAt(mcpPath(ctx));
|
|
52
|
+
},
|
|
53
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import os from 'os';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { registerMcpServersJsonAt, removeMcpServersJsonAt, removeMemtraceSkills, writeSkills, } from './shared.js';
|
|
4
|
+
function skillsRoot(ctx) {
|
|
5
|
+
return ctx.scope === 'global'
|
|
6
|
+
? path.join(os.homedir(), '.codeium', 'windsurf', 'skills')
|
|
7
|
+
: path.join(ctx.cwd, '.windsurf', 'skills');
|
|
8
|
+
}
|
|
9
|
+
export function windsurfMcpPath() {
|
|
10
|
+
return path.join(os.homedir(), '.codeium', 'windsurf', 'mcp_config.json');
|
|
11
|
+
}
|
|
12
|
+
export const windsurfTransformer = {
|
|
13
|
+
name: 'windsurf',
|
|
14
|
+
async install(skills, ctx) {
|
|
15
|
+
const rootDir = skillsRoot(ctx);
|
|
16
|
+
const count = writeSkills(skills, rootDir);
|
|
17
|
+
const warnings = [];
|
|
18
|
+
let mcpRegistered = false;
|
|
19
|
+
const mcpConfigPath = windsurfMcpPath();
|
|
20
|
+
if (!ctx.skipMcp) {
|
|
21
|
+
const result = registerMcpServersJsonAt(mcpConfigPath, ctx.memtraceBinary);
|
|
22
|
+
mcpRegistered = result.registered;
|
|
23
|
+
if (!mcpRegistered && result.backupPath) {
|
|
24
|
+
warnings.push(`Windsurf MCP config was malformed; backed up to ${result.backupPath}.`);
|
|
25
|
+
}
|
|
26
|
+
if (ctx.scope === 'local') {
|
|
27
|
+
warnings.push('Windsurf MCP config is user-level only; wrote ~/.codeium/windsurf/mcp_config.json.');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
agent: 'windsurf',
|
|
32
|
+
skillsWritten: count,
|
|
33
|
+
skillsDir: rootDir,
|
|
34
|
+
mcpConfigPath,
|
|
35
|
+
mcpRegistered,
|
|
36
|
+
warnings,
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
async uninstall(ctx) {
|
|
40
|
+
removeMemtraceSkills(skillsRoot(ctx));
|
|
41
|
+
removeMcpServersJsonAt(windsurfMcpPath());
|
|
42
|
+
},
|
|
43
|
+
};
|
package/dist/utils.d.ts
ADDED
package/dist/utils.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { exec } from 'child_process';
|
|
2
|
+
export function execCommand(command, opts = {}) {
|
|
3
|
+
const timeout = opts.timeoutMs ?? 30_000;
|
|
4
|
+
return new Promise((resolve, reject) => {
|
|
5
|
+
exec(command, { timeout }, (error, stdout, stderr) => {
|
|
6
|
+
if (error)
|
|
7
|
+
reject(new Error(`Command failed: ${command}\n${stderr || error.message}`));
|
|
8
|
+
else
|
|
9
|
+
resolve(stdout.trim());
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export async function commandExists(cmd) {
|
|
14
|
+
try {
|
|
15
|
+
const which = process.platform === 'win32' ? 'where' : 'which';
|
|
16
|
+
await execCommand(`${which} ${cmd}`, { timeoutMs: 5_000 });
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "memtrace-skills",
|
|
3
|
+
"version": "0.7.10",
|
|
4
|
+
"description": "Memtrace skills for AI coding agents — codebase exploration, temporal evolution, impact analysis, and more.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"memtrace-skills": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist/",
|
|
11
|
+
"skills/",
|
|
12
|
+
"plugins/",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"prebuild": "node scripts/copy-skills.js",
|
|
17
|
+
"build": "tsc",
|
|
18
|
+
"prepublishOnly": "npm run build",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"commander": "^12.0.0",
|
|
24
|
+
"fs-extra": "^11.0.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/fs-extra": "^11.0.0",
|
|
28
|
+
"@types/node": "^20.0.0",
|
|
29
|
+
"@vitest/coverage-v8": "^4.1.4",
|
|
30
|
+
"fast-check": "^4.7.0",
|
|
31
|
+
"typescript": "^5.4.0",
|
|
32
|
+
"vitest": "^4.1.4"
|
|
33
|
+
},
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=18"
|
|
36
|
+
},
|
|
37
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/syncable-dev/memtrace.git"
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"memtrace",
|
|
44
|
+
"code-intelligence",
|
|
45
|
+
"mcp",
|
|
46
|
+
"skills",
|
|
47
|
+
"claude-code",
|
|
48
|
+
"ai-agent"
|
|
49
|
+
]
|
|
50
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "memtrace-skills",
|
|
3
|
+
"description": "Memtrace skills for codebase exploration, code search, relationship analysis, temporal evolution, blast radius impact, code quality, graph algorithms, API topology, GitHub PR code review, multi-agent fleet coordination (branch-scoped intents, conflict classification, and agent-judged Class C resolution), and multi-step workflows for change impact, incident investigation, refactoring, session continuity, co-change analysis, and episode replay.",
|
|
4
|
+
"version": "0.7.10",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Syncable",
|
|
7
|
+
"email": "support@syncable.dev"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://memtrace.io",
|
|
10
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"memtrace",
|
|
13
|
+
"code-intelligence",
|
|
14
|
+
"knowledge-graph",
|
|
15
|
+
"mcp",
|
|
16
|
+
"temporal-analysis",
|
|
17
|
+
"blast-radius",
|
|
18
|
+
"refactoring",
|
|
19
|
+
"architecture",
|
|
20
|
+
"multi-agent",
|
|
21
|
+
"fleet-coordination"
|
|
22
|
+
]
|
|
23
|
+
}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# Memtrace MCP tool parameters — authoritative reference
|
|
2
|
+
|
|
3
|
+
This file is the single source of truth for the name, type, required-ness,
|
|
4
|
+
default, and constraint of every argument accepted by every Memtrace MCP
|
|
5
|
+
tool. It's generated from the `#[derive(Deserialize, JsonSchema)] struct
|
|
6
|
+
*Params` declarations in `crates/memtrace-mcp/src/tools/*.rs`. If you're
|
|
7
|
+
wondering what to pass to a tool, check this table; if the live tool
|
|
8
|
+
rejects a call, the validator error message here explains why.
|
|
9
|
+
|
|
10
|
+
## Zeroth rule — JSON types are strict
|
|
11
|
+
|
|
12
|
+
The MCP validator does not coerce. `limit: "10"` is a type error even
|
|
13
|
+
though "10" parses as a number. Rejection surfaces as:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
MCP error -32602: invalid type: string "10", expected usize
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Pass JSON numbers as numbers, booleans as booleans, strings as strings,
|
|
20
|
+
arrays as arrays. No quoting numbers, no `"true"` for booleans.
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
// CORRECT
|
|
24
|
+
{ "repo_id": "memtrace", "depth": 3, "fuzzy": true, "include_tests": false }
|
|
25
|
+
|
|
26
|
+
// WRONG — every one of these fails validation
|
|
27
|
+
{ "repo_id": memtrace, "depth": "3", "fuzzy": "true", "include_tests": 0 }
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Conventions that appear across tools
|
|
31
|
+
|
|
32
|
+
| Param | Type | Meaning |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `repo_id` | string | Repository identifier from `list_indexed_repositories` (usually the repo folder name, e.g. `"memtrace"`) |
|
|
35
|
+
| `branch` *or* `branch_name` | string | Git branch. Default `"main"` across every tool. Both spellings occur historically — use whichever the specific tool's schema says |
|
|
36
|
+
| `limit` | integer | Cap on returned results. Always a JSON number, never a string |
|
|
37
|
+
| `depth` | integer | Graph traversal hops. 1–5 is reasonable; >8 explodes on wide graphs |
|
|
38
|
+
| `symbol_id` | string (UUID) | Node UUID from `find_symbol` / `find_code` results |
|
|
39
|
+
| `from` / `to` / `incident_time` | string (ISO-8601 with timezone) | e.g. `"2026-04-17T13:00:00Z"` — NOT a date like `"2026-04-17"` |
|
|
40
|
+
|
|
41
|
+
## Search & discovery
|
|
42
|
+
|
|
43
|
+
### `find_code`
|
|
44
|
+
| Field | Type | Required | Default | Notes |
|
|
45
|
+
|---|---|---|---|---|
|
|
46
|
+
| `query` | string | yes | — | Natural-language text |
|
|
47
|
+
| `repo_id` | string | no | all repos | Scope to one repo |
|
|
48
|
+
| `kind` | string | no | — | One of `Function`, `Class`, `Method`, `Interface`, `APIEndpoint`, `APICall` |
|
|
49
|
+
| `file_path` | string | no | — | Path substring filter |
|
|
50
|
+
| `limit` | integer | no | `20` | Capped at `100` |
|
|
51
|
+
| `as_of` | string (ISO-8601) | no | now | Time-travel search |
|
|
52
|
+
|
|
53
|
+
### `find_symbol`
|
|
54
|
+
| Field | Type | Required | Default | Notes |
|
|
55
|
+
|---|---|---|---|---|
|
|
56
|
+
| `name` | string | yes | — | Exact or partial identifier |
|
|
57
|
+
| `fuzzy` | boolean | no | `false` | Levenshtein tolerance |
|
|
58
|
+
| `edit_distance` | integer | no | `2` | Max 2. Only used when `fuzzy: true` |
|
|
59
|
+
| `repo_id` | string | no | all repos | |
|
|
60
|
+
| `kind` | string | no | — | Same enum as `find_code` |
|
|
61
|
+
| `file_path` | string | no | — | |
|
|
62
|
+
| `limit` | integer | no | `10` | Capped at `50` |
|
|
63
|
+
|
|
64
|
+
### `get_source_window`
|
|
65
|
+
| Field | Type | Required | Default | Notes |
|
|
66
|
+
|---|---|---|---|---|
|
|
67
|
+
| `file_path` | string | yes | — | Use the path returned by Memtrace search/context tools |
|
|
68
|
+
| `repo_id` | string | no | — | Helps resolve repo-relative and repo-prefixed paths |
|
|
69
|
+
| `start_line` | integer | no | `1` | 1-based line number from a Memtrace result |
|
|
70
|
+
| `end_line` | integer | no | `start_line` | 1-based line number from a Memtrace result |
|
|
71
|
+
| `before_lines` | integer | no | `8` | Context before the span |
|
|
72
|
+
| `after_lines` | integer | no | `24` | Context after the span |
|
|
73
|
+
| `max_lines` | integer | no | `120` | Hard-capped at `400` |
|
|
74
|
+
|
|
75
|
+
### `list_indexed_repositories`
|
|
76
|
+
No parameters. Call once at session start to get `repo_id` values.
|
|
77
|
+
|
|
78
|
+
## Relationships
|
|
79
|
+
|
|
80
|
+
### `get_symbol_context`
|
|
81
|
+
| Field | Type | Required | Default |
|
|
82
|
+
|---|---|---|---|
|
|
83
|
+
| `symbol_id` | string (UUID) | yes | — |
|
|
84
|
+
|
|
85
|
+
Returns: symbol, callers, callees, type_references, community, processes, api_callers_cross_repo.
|
|
86
|
+
|
|
87
|
+
### `analyze_relationships`
|
|
88
|
+
| Field | Type | Required | Default | Notes |
|
|
89
|
+
|---|---|---|---|---|
|
|
90
|
+
| `symbol_id` | string (UUID) | yes | — | |
|
|
91
|
+
| `query_type` | string enum | yes | — | `find_callers` \| `find_callees` \| `class_hierarchy` \| `overrides` \| `imports` \| `exporters` \| `type_usages` |
|
|
92
|
+
| `depth` | integer | no | `2` | |
|
|
93
|
+
| `limit` | integer | no | `50` | |
|
|
94
|
+
|
|
95
|
+
## Impact
|
|
96
|
+
|
|
97
|
+
### `get_impact`
|
|
98
|
+
| Field | Type | Required | Default | Notes |
|
|
99
|
+
|---|---|---|---|---|
|
|
100
|
+
| `symbol_id` | string (UUID) | yes | — | |
|
|
101
|
+
| `direction` | string enum | no | `"both"` | `"upstream"` \| `"downstream"` \| `"both"` |
|
|
102
|
+
| `depth` | integer | no | `3` | |
|
|
103
|
+
| `limit` | integer | no | `100` | |
|
|
104
|
+
|
|
105
|
+
### `detect_changes`
|
|
106
|
+
| Field | Type | Required | Default | Notes |
|
|
107
|
+
|---|---|---|---|---|
|
|
108
|
+
| `repo_id` | string | yes | — | |
|
|
109
|
+
| `diff` | string | no ‡ | — | Unified git diff text |
|
|
110
|
+
| `changed_files` | array of string | no ‡ | — | Alternative to `diff` |
|
|
111
|
+
| `branch` | string | no | `"main"` | |
|
|
112
|
+
|
|
113
|
+
‡ Exactly one of `diff` or `changed_files` must be provided.
|
|
114
|
+
|
|
115
|
+
## Temporal
|
|
116
|
+
|
|
117
|
+
### `get_evolution`
|
|
118
|
+
| Field | Type | Required | Default | Notes |
|
|
119
|
+
|---|---|---|---|---|
|
|
120
|
+
| `repo_id` | string | yes | — | |
|
|
121
|
+
| `from` | string (ISO-8601) | yes | — | Start of window |
|
|
122
|
+
| `to` | string (ISO-8601) | yes | — | End of window |
|
|
123
|
+
| `mode` | string enum | no | `"compound"` | `"compound"` \| `"impact"` \| `"novel"` \| `"recent"` \| `"directional"` \| `"overview"` |
|
|
124
|
+
| `incident_time` | string (ISO-8601) | no | — | Reference for `recent` mode |
|
|
125
|
+
| `branch` | string | no | `"main"` | |
|
|
126
|
+
| `max_symbols` | integer | no | `50` | Per category |
|
|
127
|
+
| `scope` | string | no | — | File / module prefix |
|
|
128
|
+
|
|
129
|
+
### `get_timeline`
|
|
130
|
+
| Field | Type | Required | Default | Notes |
|
|
131
|
+
|---|---|---|---|---|
|
|
132
|
+
| `repo_id` | string | yes | — | |
|
|
133
|
+
| `scope_path` | string | yes | — | e.g. `"AuthService::validateToken"` |
|
|
134
|
+
| `file_path` | string | yes | — | Containing file |
|
|
135
|
+
| `branch` | string | no | `"main"` | |
|
|
136
|
+
|
|
137
|
+
### `get_episode_replay`
|
|
138
|
+
| Field | Type | Required | Default | Notes |
|
|
139
|
+
|---|---|---|---|---|
|
|
140
|
+
| `repo_id` | string | yes | — | |
|
|
141
|
+
| `symbol` | string | yes | — | Symbol name, e.g. `"validateToken"` |
|
|
142
|
+
| `from` | string (ISO-8601) | yes | — | Window start |
|
|
143
|
+
| `to` | string (ISO-8601) | yes | — | Window end |
|
|
144
|
+
| `branch` | string | no | `"main"` | |
|
|
145
|
+
| `include_working_tree` | boolean | no | `true` | Include uncommitted file-save episodes |
|
|
146
|
+
|
|
147
|
+
### `get_changes_since`
|
|
148
|
+
| Field | Type | Required | Default | Notes |
|
|
149
|
+
|---|---|---|---|---|
|
|
150
|
+
| `repo_id` | string | yes | — | |
|
|
151
|
+
| `last_episode_id` | string | no † | — | Preferred anchor from previous response |
|
|
152
|
+
| `last_reference_time` | string (ISO-8601) | no † | — | Fallback when no episode ID |
|
|
153
|
+
| `branch` | string | no | `"main"` | |
|
|
154
|
+
|
|
155
|
+
† Pass exactly one.
|
|
156
|
+
|
|
157
|
+
### `get_cochange_context`
|
|
158
|
+
| Field | Type | Required | Default | Notes |
|
|
159
|
+
|---|---|---|---|---|
|
|
160
|
+
| `repo_id` | string | yes | — | |
|
|
161
|
+
| `symbol` | string | yes | — | Symbol name (not ID) |
|
|
162
|
+
| `branch` | string | no | `"main"` | |
|
|
163
|
+
| `limit` | integer | no | `20` | |
|
|
164
|
+
|
|
165
|
+
## Graph algorithms
|
|
166
|
+
|
|
167
|
+
### `find_central_symbols`
|
|
168
|
+
| Field | Type | Required | Default | Notes |
|
|
169
|
+
|---|---|---|---|---|
|
|
170
|
+
| `repo_id` | string | yes | — | |
|
|
171
|
+
| `branch` | string | no | `"main"` | |
|
|
172
|
+
| `algorithm` | string enum | no | `"pagerank"` | `"pagerank"` \| `"degree"` — falls back to degree if MAGE unavailable |
|
|
173
|
+
| `limit` | integer | no | `20` | Max 100 |
|
|
174
|
+
|
|
175
|
+
### `find_bridge_symbols`
|
|
176
|
+
| Field | Type | Required | Default | Notes |
|
|
177
|
+
|---|---|---|---|---|
|
|
178
|
+
| `repo_id` | string | yes | — | |
|
|
179
|
+
| `branch` | string | no | `"main"` | |
|
|
180
|
+
| `limit` | integer | no | `15` | Max 50 |
|
|
181
|
+
|
|
182
|
+
### `list_communities`
|
|
183
|
+
| Field | Type | Required | Default | Notes |
|
|
184
|
+
|---|---|---|---|---|
|
|
185
|
+
| `repo_id` | string | yes | — | |
|
|
186
|
+
| `branch` | string | no | `"main"` | |
|
|
187
|
+
| `min_size` | integer | no | `3` | |
|
|
188
|
+
| `limit` | integer | no | `50` | Max 200 |
|
|
189
|
+
|
|
190
|
+
### `list_processes`
|
|
191
|
+
| Field | Type | Required | Default |
|
|
192
|
+
|---|---|---|---|
|
|
193
|
+
| `repo_id` | string | yes | — |
|
|
194
|
+
| `branch` | string | no | `"main"` |
|
|
195
|
+
| `limit` | integer | no | `50` |
|
|
196
|
+
|
|
197
|
+
### `get_process_flow`
|
|
198
|
+
| Field | Type | Required | Default |
|
|
199
|
+
|---|---|---|---|
|
|
200
|
+
| `repo_id` | string | yes | — |
|
|
201
|
+
| `process` | string | yes | — |
|
|
202
|
+
| `branch` | string | no | `"main"` |
|
|
203
|
+
|
|
204
|
+
### `find_dependency_path`
|
|
205
|
+
| Field | Type | Required | Default | Notes |
|
|
206
|
+
|---|---|---|---|---|
|
|
207
|
+
| `repo_id` | string | yes | — | — |
|
|
208
|
+
| `from` | string | yes | — | Source symbol name |
|
|
209
|
+
| `to` | string | yes | — | Destination symbol name |
|
|
210
|
+
| `max_depth` | integer | no | `8` | BFS hop limit |
|
|
211
|
+
|
|
212
|
+
## Quality
|
|
213
|
+
|
|
214
|
+
### `get_repository_stats`
|
|
215
|
+
| Field | Type | Required | Default |
|
|
216
|
+
|---|---|---|---|
|
|
217
|
+
| `repo_id` | string | yes | — |
|
|
218
|
+
| `branch` | string | no | `"main"` |
|
|
219
|
+
|
|
220
|
+
### `find_dead_code`
|
|
221
|
+
| Field | Type | Required | Default | Notes |
|
|
222
|
+
|---|---|---|---|---|
|
|
223
|
+
| `repo_id` | string | yes | — | |
|
|
224
|
+
| `branch` | string | no | `"main"` | |
|
|
225
|
+
| `include_tests` | boolean | no | `false` | |
|
|
226
|
+
| `limit` | integer | no | `50` | |
|
|
227
|
+
| `kinds` | array of string | no | all | Filter, e.g. `["Function","Method"]` |
|
|
228
|
+
|
|
229
|
+
### `find_most_complex_functions`
|
|
230
|
+
| Field | Type | Required | Default |
|
|
231
|
+
|---|---|---|---|
|
|
232
|
+
| `repo_id` | string | yes | — |
|
|
233
|
+
| `branch` | string | no | `"main"` |
|
|
234
|
+
| `limit` | integer | no | `10` |
|
|
235
|
+
| `min_complexity` | integer | no | `0` |
|
|
236
|
+
|
|
237
|
+
### `calculate_cyclomatic_complexity`
|
|
238
|
+
| Field | Type | Required | Default |
|
|
239
|
+
|---|---|---|---|
|
|
240
|
+
| `symbol_id` | string (UUID) | yes | — |
|
|
241
|
+
|
|
242
|
+
## API topology
|
|
243
|
+
|
|
244
|
+
### `find_api_endpoints`
|
|
245
|
+
| Field | Type | Required | Default | Notes |
|
|
246
|
+
|---|---|---|---|---|
|
|
247
|
+
| `repo_id` | string | yes | — | The service that handles these endpoints |
|
|
248
|
+
| `method` | string | no | — | HTTP method filter, e.g. `"GET"` |
|
|
249
|
+
| `path_contains` | string | no | — | Substring filter, e.g. `"/users"` |
|
|
250
|
+
| `branch` | string | no | `"main"` | |
|
|
251
|
+
| `limit` | integer | no | `50` | |
|
|
252
|
+
|
|
253
|
+
### `find_api_calls`
|
|
254
|
+
| Field | Type | Required | Default | Notes |
|
|
255
|
+
|---|---|---|---|---|
|
|
256
|
+
| `repo_id` | string | yes | — | The service making the calls |
|
|
257
|
+
| `method` | string | no | — | |
|
|
258
|
+
| `path_contains` | string | no | — | |
|
|
259
|
+
| `branch` | string | no | `"main"` | |
|
|
260
|
+
| `limit` | integer | no | `50` | |
|
|
261
|
+
|
|
262
|
+
### `get_api_topology`
|
|
263
|
+
| Field | Type | Required | Default | Notes |
|
|
264
|
+
|---|---|---|---|---|
|
|
265
|
+
| `min_confidence` | number (float) | no | `0.7` | 0.0–1.0 — threshold for cross-repo HTTP edges |
|
|
266
|
+
| `include_external` | boolean | no | `false` | Include calls to services outside indexed repos |
|
|
267
|
+
| `repo_id` | string | no | — | Omit for full cross-service topology |
|
|
268
|
+
|
|
269
|
+
### `link_repositories`
|
|
270
|
+
Connects already-indexed repos so `get_api_topology` can stitch their HTTP graphs. Parameters vary — see `link_repositories` tool schema via the MCP `list_tools` call.
|
|
271
|
+
|
|
272
|
+
## Indexing
|
|
273
|
+
|
|
274
|
+
### `index_directory`
|
|
275
|
+
| Field | Type | Required | Default | Notes |
|
|
276
|
+
|---|---|---|---|---|
|
|
277
|
+
| `path` | string | yes | — | Absolute path to the repo root |
|
|
278
|
+
| `repo_id` | string | no | directory name | |
|
|
279
|
+
| `branch` | string | no | `"main"` | |
|
|
280
|
+
| `incremental` | boolean | no | `false` | Re-index only changed files |
|
|
281
|
+
| `clear_existing` | boolean | no | `false` | Wipe before indexing |
|
|
282
|
+
| `skip_embed` | boolean | no | `false` | Skip the embedding stage |
|
|
283
|
+
|
|
284
|
+
### `check_job_status`
|
|
285
|
+
| Field | Type | Required | Default |
|
|
286
|
+
|---|---|---|---|
|
|
287
|
+
| `job_id` | string (UUID) | yes | — |
|
|
288
|
+
|
|
289
|
+
### `delete_repository`
|
|
290
|
+
| Field | Type | Required | Default |
|
|
291
|
+
|---|---|---|---|
|
|
292
|
+
| `repo_id` | string | yes | — |
|
|
293
|
+
|
|
294
|
+
### `watch_directory` / `unwatch_directory` / `list_watched_paths`
|
|
295
|
+
File watcher control. See the tool schema via `list_tools` for current fields.
|
|
296
|
+
|
|
297
|
+
## When this file is wrong
|
|
298
|
+
|
|
299
|
+
It's drift-prone. Regenerate by grepping `crates/memtrace-mcp/src/tools/*.rs`
|
|
300
|
+
for `^pub struct.*Params` — the Rust declarations are the source of truth.
|
|
301
|
+
If a live tool call rejects with `-32602`, trust the Rust struct over this
|
|
302
|
+
doc and file a fix PR.
|