@aabadin/project-memory-context 0.1.2 → 0.1.4
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/cli/setup.mjs +39 -18
- package/package.json +1 -1
- package/src/doctor.mjs +1 -1
- package/src/setup-bootstrap.mjs +60 -44
package/cli/setup.mjs
CHANGED
|
@@ -12,13 +12,22 @@ import { installAgentTemplates } from '../src/template-installer.mjs';
|
|
|
12
12
|
|
|
13
13
|
const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
14
14
|
|
|
15
|
+
const AGENT_FLAGS = {
|
|
16
|
+
'--opencode': 'opencode',
|
|
17
|
+
'--claude': 'claude-code',
|
|
18
|
+
'--cursor': 'cursor',
|
|
19
|
+
'--generic': 'generic',
|
|
20
|
+
};
|
|
21
|
+
|
|
15
22
|
function installGraphify() {
|
|
16
23
|
const candidates = process.platform === 'win32' ? ['python', 'py'] : ['python3', 'python'];
|
|
17
24
|
for (const command of candidates) {
|
|
18
25
|
const result = spawnSync(command, ['-m', 'pip', 'install', 'graphifyy'], { stdio: 'inherit' });
|
|
19
26
|
if (result.status === 0) return command;
|
|
20
27
|
}
|
|
21
|
-
console.warn(
|
|
28
|
+
console.warn(`\n⚠ Could not install graphifyy automatically.`);
|
|
29
|
+
console.warn(` Python not found? Download it from: https://www.python.org/downloads/`);
|
|
30
|
+
console.warn(` Then run: pip install graphifyy\n`);
|
|
22
31
|
return null;
|
|
23
32
|
}
|
|
24
33
|
|
|
@@ -28,13 +37,13 @@ function spawnCheck(bin, args) {
|
|
|
28
37
|
}
|
|
29
38
|
|
|
30
39
|
function parseArgs(args) {
|
|
31
|
-
const
|
|
32
|
-
for (
|
|
33
|
-
if (
|
|
34
|
-
|
|
40
|
+
const agents = [];
|
|
41
|
+
for (const arg of args) {
|
|
42
|
+
if (AGENT_FLAGS[arg]) {
|
|
43
|
+
agents.push(AGENT_FLAGS[arg]);
|
|
35
44
|
}
|
|
36
45
|
}
|
|
37
|
-
return
|
|
46
|
+
return { agents };
|
|
38
47
|
}
|
|
39
48
|
|
|
40
49
|
const rl = createInterface({ input, output });
|
|
@@ -42,7 +51,17 @@ const cwd = resolve(process.cwd());
|
|
|
42
51
|
|
|
43
52
|
try {
|
|
44
53
|
console.log('\n─── pmc setup ───────────────────────────────────────\n');
|
|
45
|
-
const {
|
|
54
|
+
const { agents: requestedAgents } = parseArgs(process.argv.slice(2));
|
|
55
|
+
|
|
56
|
+
let agents;
|
|
57
|
+
if (requestedAgents.length > 0) {
|
|
58
|
+
agents = [...new Set(requestedAgents)];
|
|
59
|
+
console.log(` Target agents: ${agents.join(', ')}`);
|
|
60
|
+
} else {
|
|
61
|
+
const detected = detectSetupAgentType(cwd);
|
|
62
|
+
agents = [detected];
|
|
63
|
+
console.log(` Auto-detected agent: ${detected}`);
|
|
64
|
+
}
|
|
46
65
|
|
|
47
66
|
const ollamaBaseUrl =
|
|
48
67
|
(await rl.question('Ollama base URL [http://localhost:11434]: ')).trim() ||
|
|
@@ -54,31 +73,33 @@ try {
|
|
|
54
73
|
|
|
55
74
|
installGraphify();
|
|
56
75
|
|
|
76
|
+
const { globalConfig } = resolveConfigDirs(cwd);
|
|
77
|
+
|
|
57
78
|
const result = await bootstrapProjectInstall({
|
|
58
79
|
projectRoot: cwd,
|
|
59
80
|
packageRoot,
|
|
60
81
|
ollamaBaseUrl,
|
|
61
82
|
ollamaModel,
|
|
83
|
+
agents,
|
|
62
84
|
});
|
|
63
85
|
|
|
64
|
-
const agent
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
console.log(` Installed ${agent} templates.`);
|
|
86
|
+
for (const agent of agents) {
|
|
87
|
+
await installAgentTemplates({
|
|
88
|
+
projectRoot: cwd,
|
|
89
|
+
agent,
|
|
90
|
+
packageRoot,
|
|
91
|
+
globalConfigDir: agent === 'opencode' ? globalConfig : undefined,
|
|
92
|
+
});
|
|
93
|
+
console.log(` ✓ Installed ${agent} templates.`);
|
|
94
|
+
}
|
|
74
95
|
|
|
75
96
|
console.log('\n─── Installation complete ───────────────────────────\n');
|
|
76
97
|
console.log(` Memory DB path: ${result.installState.memoryDbPath}`);
|
|
77
98
|
console.log(` Embedding cache: ${result.installState.embeddingCachePath}`);
|
|
78
99
|
console.log(` MCP config: ${result.configPath}`);
|
|
79
100
|
console.log(` Command template: ${result.commandPath}`);
|
|
101
|
+
console.log(` Agents configured: ${agents.join(', ')}`);
|
|
80
102
|
|
|
81
|
-
// Run doctor to surface any remaining issues
|
|
82
103
|
console.log('\n─── Environment check ───────────────────────────────\n');
|
|
83
104
|
const env = {
|
|
84
105
|
...process.env,
|
package/package.json
CHANGED
package/src/doctor.mjs
CHANGED
|
@@ -34,7 +34,7 @@ async function checkNodeVersion() {
|
|
|
34
34
|
async function checkPython(resolvePythonBin, spawnCheck) {
|
|
35
35
|
const bin = resolvePythonBin?.() ?? null;
|
|
36
36
|
if (!bin) {
|
|
37
|
-
return { name: 'python', status: 'fail', message: 'Python 3 not found
|
|
37
|
+
return { name: 'python', status: 'fail', message: 'Python 3 not found — download from https://www.python.org/downloads/ or set PATH' };
|
|
38
38
|
}
|
|
39
39
|
if (!spawnCheck) {
|
|
40
40
|
return { name: 'python', status: 'ok', message: `${bin} found (not verified — no spawn check provided)` };
|
package/src/setup-bootstrap.mjs
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
|
-
import {
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
3
|
|
|
4
4
|
import { ensureProjectMemoryContextDirs, writeJsonArtifact } from './artifacts.mjs';
|
|
5
5
|
import { PMC_ENRICHMENT_CONFIG_FILE } from './enrichment-config.mjs';
|
|
6
|
-
import { resolveConfigDirs } from './platform.mjs';
|
|
7
6
|
|
|
8
7
|
async function readJson(filePath, fallback) {
|
|
9
8
|
try {
|
|
@@ -63,52 +62,65 @@ async function writeMcpJson(projectRoot, installState) {
|
|
|
63
62
|
return mcpPath;
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
async function
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (!existing.includes('@aabadin/project-memory-context')) {
|
|
75
|
-
config.plugin = [...existing, '@aabadin/project-memory-context'];
|
|
76
|
-
}
|
|
77
|
-
config.mcp = {
|
|
78
|
-
...(config.mcp ?? {}),
|
|
79
|
-
...buildOpencodeMcpConfig(installState).mcp,
|
|
80
|
-
};
|
|
81
|
-
await mkdir(dirname(configPath), { recursive: true });
|
|
82
|
-
await writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`, 'utf8');
|
|
83
|
-
// Also write .mcp.json so agent-memory is available immediately
|
|
84
|
-
await writeMcpJson(projectRoot, installState);
|
|
85
|
-
return configPath;
|
|
65
|
+
async function ensureOpencodeConfig(projectRoot, installState) {
|
|
66
|
+
const opencodeDir = join(projectRoot, '.opencode');
|
|
67
|
+
await mkdir(opencodeDir, { recursive: true });
|
|
68
|
+
const configPath = join(opencodeDir, 'opencode.json');
|
|
69
|
+
const config = await readJson(configPath, { $schema: 'https://opencode.ai/config.json' });
|
|
70
|
+
const existing = Array.isArray(config.plugin) ? config.plugin : [];
|
|
71
|
+
if (!existing.includes('@aabadin/project-memory-context')) {
|
|
72
|
+
config.plugin = [...existing, '@aabadin/project-memory-context'];
|
|
86
73
|
}
|
|
74
|
+
config.mcp = {
|
|
75
|
+
...(config.mcp ?? {}),
|
|
76
|
+
...buildOpencodeMcpConfig(installState).mcp,
|
|
77
|
+
};
|
|
78
|
+
await mkdir(dirname(configPath), { recursive: true });
|
|
79
|
+
await writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`, 'utf8');
|
|
80
|
+
return configPath;
|
|
81
|
+
}
|
|
87
82
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
...existingConfig.enrichment?.localModel,
|
|
100
|
-
baseUrl: installState.ollamaBaseUrl,
|
|
101
|
-
model: installState.ollamaModel,
|
|
102
|
-
},
|
|
83
|
+
async function ensureEnrichmentConfig(projectRoot, configDir, installState) {
|
|
84
|
+
const enrichPath = join(configDir, PMC_ENRICHMENT_CONFIG_FILE);
|
|
85
|
+
const existingConfig = await readJson(enrichPath, {});
|
|
86
|
+
const config = {
|
|
87
|
+
...existingConfig,
|
|
88
|
+
enrichment: {
|
|
89
|
+
...existingConfig.enrichment,
|
|
90
|
+
localModel: {
|
|
91
|
+
...existingConfig.enrichment?.localModel,
|
|
92
|
+
baseUrl: installState.ollamaBaseUrl,
|
|
93
|
+
model: installState.ollamaModel,
|
|
103
94
|
},
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
await mkdir(dirname(enrichPath), { recursive: true });
|
|
98
|
+
await writeFile(enrichPath, `${JSON.stringify(config, null, 2)}\n`, 'utf8');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function ensureAgentConfigs(projectRoot, installState, agents) {
|
|
102
|
+
let primaryConfigPath = null;
|
|
103
|
+
|
|
104
|
+
for (const agent of agents) {
|
|
105
|
+
if (agent === 'opencode') {
|
|
106
|
+
primaryConfigPath = primaryConfigPath ?? await ensureOpencodeConfig(projectRoot, installState);
|
|
107
|
+
}
|
|
108
|
+
if (agent === 'claude-code') {
|
|
109
|
+
const claudeDir = join(projectRoot, '.claude');
|
|
110
|
+
await mkdir(claudeDir, { recursive: true });
|
|
111
|
+
await ensureEnrichmentConfig(projectRoot, claudeDir, installState);
|
|
112
|
+
primaryConfigPath = primaryConfigPath ?? join(projectRoot, '.mcp.json');
|
|
113
|
+
}
|
|
114
|
+
if (agent === 'cursor') {
|
|
115
|
+
const cursorDir = join(projectRoot, '.cursor');
|
|
116
|
+
await mkdir(cursorDir, { recursive: true });
|
|
117
|
+
await ensureEnrichmentConfig(projectRoot, cursorDir, installState);
|
|
118
|
+
primaryConfigPath = primaryConfigPath ?? join(projectRoot, '.mcp.json');
|
|
119
|
+
}
|
|
108
120
|
}
|
|
109
121
|
|
|
110
|
-
|
|
111
|
-
return
|
|
122
|
+
await writeMcpJson(projectRoot, installState);
|
|
123
|
+
return primaryConfigPath ?? join(projectRoot, '.mcp.json');
|
|
112
124
|
}
|
|
113
125
|
|
|
114
126
|
async function copyTemplate(packageRoot, templateName, projectRoot) {
|
|
@@ -126,7 +138,10 @@ export async function bootstrapProjectInstall({
|
|
|
126
138
|
ollamaBaseUrl,
|
|
127
139
|
ollamaModel,
|
|
128
140
|
embeddingCachePath,
|
|
141
|
+
agents = [],
|
|
142
|
+
agent,
|
|
129
143
|
}) {
|
|
144
|
+
const resolvedAgents = agents.length > 0 ? agents : (agent ? [agent] : ['generic']);
|
|
130
145
|
const dirs = await ensureProjectMemoryContextDirs(projectRoot);
|
|
131
146
|
const memoryDbPath = join(dirs.base, 'memory-db');
|
|
132
147
|
const installState = {
|
|
@@ -140,7 +155,7 @@ export async function bootstrapProjectInstall({
|
|
|
140
155
|
|
|
141
156
|
await mkdir(memoryDbPath, { recursive: true });
|
|
142
157
|
await writeJsonArtifact(join(dirs.base, 'install.json'), installState);
|
|
143
|
-
const configPath = await
|
|
158
|
+
const configPath = await ensureAgentConfigs(projectRoot, installState, resolvedAgents);
|
|
144
159
|
const commandPath = await copyTemplate(packageRoot, 'project-memory-context.md', projectRoot);
|
|
145
160
|
const workflowPath = await copyTemplate(packageRoot, 'project-memory-context workflow.md', projectRoot);
|
|
146
161
|
|
|
@@ -149,5 +164,6 @@ export async function bootstrapProjectInstall({
|
|
|
149
164
|
configPath,
|
|
150
165
|
commandPath,
|
|
151
166
|
workflowPath,
|
|
167
|
+
agents: resolvedAgents,
|
|
152
168
|
};
|
|
153
169
|
}
|