@aabadin/project-memory-context 0.1.1 → 0.1.3
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 +21 -5
- package/package.json +1 -1
- package/src/doctor.mjs +1 -1
- package/src/platform.mjs +13 -0
- package/src/setup-bootstrap.mjs +32 -11
- package/src/template-installer.mjs +1 -1
package/cli/setup.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import { spawnSync } from 'node:child_process';
|
|
|
7
7
|
|
|
8
8
|
import { bootstrapProjectInstall } from '../src/setup-bootstrap.mjs';
|
|
9
9
|
import { runDoctor } from '../src/doctor.mjs';
|
|
10
|
-
import {
|
|
10
|
+
import { detectSetupAgentType, resolveConfigDirs, resolvePythonBin } from '../src/platform.mjs';
|
|
11
11
|
import { installAgentTemplates } from '../src/template-installer.mjs';
|
|
12
12
|
|
|
13
13
|
const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
@@ -18,7 +18,10 @@ function installGraphify() {
|
|
|
18
18
|
const result = spawnSync(command, ['-m', 'pip', 'install', 'graphifyy'], { stdio: 'inherit' });
|
|
19
19
|
if (result.status === 0) return command;
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
const pythonUrl = 'https://www.python.org/downloads/';
|
|
22
|
+
console.warn(`\n⚠ Could not install graphifyy automatically.`);
|
|
23
|
+
console.warn(` Python not found? Download it from: ${pythonUrl}`);
|
|
24
|
+
console.warn(` Then run: pip install graphifyy\n`);
|
|
22
25
|
return null;
|
|
23
26
|
}
|
|
24
27
|
|
|
@@ -27,11 +30,22 @@ function spawnCheck(bin, args) {
|
|
|
27
30
|
return { exitCode: result.status ?? 1, stdout: result.stdout ?? '', stderr: result.stderr ?? '' };
|
|
28
31
|
}
|
|
29
32
|
|
|
33
|
+
function parseArgs(args) {
|
|
34
|
+
const parsed = { agent: null };
|
|
35
|
+
for (let i = 0; i < args.length; i++) {
|
|
36
|
+
if (args[i] === '--agent' && args[i + 1]) {
|
|
37
|
+
parsed.agent = args[++i];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return parsed;
|
|
41
|
+
}
|
|
42
|
+
|
|
30
43
|
const rl = createInterface({ input, output });
|
|
31
44
|
const cwd = resolve(process.cwd());
|
|
32
45
|
|
|
33
46
|
try {
|
|
34
47
|
console.log('\n─── pmc setup ───────────────────────────────────────\n');
|
|
48
|
+
const { agent: requestedAgent } = parseArgs(process.argv.slice(2));
|
|
35
49
|
|
|
36
50
|
const ollamaBaseUrl =
|
|
37
51
|
(await rl.question('Ollama base URL [http://localhost:11434]: ')).trim() ||
|
|
@@ -43,16 +57,18 @@ try {
|
|
|
43
57
|
|
|
44
58
|
installGraphify();
|
|
45
59
|
|
|
60
|
+
const agent = detectSetupAgentType(cwd, { requestedAgent });
|
|
61
|
+
const { globalConfig } = resolveConfigDirs(cwd);
|
|
62
|
+
console.log(`\n Detected agent: ${agent}`);
|
|
63
|
+
|
|
46
64
|
const result = await bootstrapProjectInstall({
|
|
47
65
|
projectRoot: cwd,
|
|
48
66
|
packageRoot,
|
|
49
67
|
ollamaBaseUrl,
|
|
50
68
|
ollamaModel,
|
|
69
|
+
agent,
|
|
51
70
|
});
|
|
52
71
|
|
|
53
|
-
const agent = detectAgentType(cwd);
|
|
54
|
-
const { globalConfig } = resolveConfigDirs(cwd);
|
|
55
|
-
console.log(`\n Detected agent: ${agent}`);
|
|
56
72
|
await installAgentTemplates({
|
|
57
73
|
projectRoot: cwd,
|
|
58
74
|
agent,
|
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/platform.mjs
CHANGED
|
@@ -33,6 +33,19 @@ export function detectAgentType(projectRoot) {
|
|
|
33
33
|
return 'generic';
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
export function detectSetupAgentType(projectRoot, options = {}) {
|
|
37
|
+
if (options.requestedAgent) return options.requestedAgent;
|
|
38
|
+
|
|
39
|
+
const projectAgent = detectAgentType(projectRoot);
|
|
40
|
+
if (projectAgent !== 'generic') return projectAgent;
|
|
41
|
+
|
|
42
|
+
const exists = options.exists ?? existsSync;
|
|
43
|
+
const homeDir = options.homeDir ?? homedir();
|
|
44
|
+
if (exists(join(homeDir, '.config', 'opencode'))) return 'opencode';
|
|
45
|
+
|
|
46
|
+
return projectAgent;
|
|
47
|
+
}
|
|
48
|
+
|
|
36
49
|
export function resolveConfigDirs(projectRoot = process.cwd(), options = {}) {
|
|
37
50
|
const root = resolve(projectRoot);
|
|
38
51
|
const exists = options.exists ?? existsSync;
|
package/src/setup-bootstrap.mjs
CHANGED
|
@@ -31,6 +31,24 @@ function buildMcpConfig(installState) {
|
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
function buildOpencodeMcpConfig(installState) {
|
|
35
|
+
return {
|
|
36
|
+
mcp: {
|
|
37
|
+
'agent-memory': {
|
|
38
|
+
type: 'local',
|
|
39
|
+
command: ['npx', '-y', '@aabadin/agent-memory-mcp'],
|
|
40
|
+
enabled: true,
|
|
41
|
+
environment: {
|
|
42
|
+
MEMORY_DB_PATH: installState.memoryDbPath,
|
|
43
|
+
...(installState.embeddingCachePath
|
|
44
|
+
? { EMBEDDING_CACHE_PATH: installState.embeddingCachePath }
|
|
45
|
+
: {}),
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
34
52
|
async function writeMcpJson(projectRoot, installState) {
|
|
35
53
|
const mcpPath = join(projectRoot, '.mcp.json');
|
|
36
54
|
const existing = await readJson(mcpPath, {});
|
|
@@ -45,28 +63,31 @@ async function writeMcpJson(projectRoot, installState) {
|
|
|
45
63
|
return mcpPath;
|
|
46
64
|
}
|
|
47
65
|
|
|
48
|
-
async function ensureAgentConfigRegistration(projectRoot, installState) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const configPath = join(projectConfig, 'opencode.json');
|
|
66
|
+
async function ensureAgentConfigRegistration(projectRoot, installState, agentType) {
|
|
67
|
+
if (agentType === 'opencode') {
|
|
68
|
+
const opencodeDir = join(projectRoot, '.opencode');
|
|
69
|
+
await mkdir(opencodeDir, { recursive: true });
|
|
70
|
+
const configPath = join(opencodeDir, 'opencode.json');
|
|
54
71
|
const config = await readJson(configPath, { $schema: 'https://opencode.ai/config.json' });
|
|
55
72
|
const existing = Array.isArray(config.plugin) ? config.plugin : [];
|
|
56
73
|
if (!existing.includes('@aabadin/project-memory-context')) {
|
|
57
74
|
config.plugin = [...existing, '@aabadin/project-memory-context'];
|
|
58
75
|
}
|
|
76
|
+
config.mcp = {
|
|
77
|
+
...(config.mcp ?? {}),
|
|
78
|
+
...buildOpencodeMcpConfig(installState).mcp,
|
|
79
|
+
};
|
|
59
80
|
await mkdir(dirname(configPath), { recursive: true });
|
|
60
81
|
await writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`, 'utf8');
|
|
61
|
-
// Also write .mcp.json so agent-memory is available immediately
|
|
62
82
|
await writeMcpJson(projectRoot, installState);
|
|
63
83
|
return configPath;
|
|
64
84
|
}
|
|
65
85
|
|
|
86
|
+
const { projectConfig } = resolveConfigDirs(projectRoot);
|
|
87
|
+
const agentDir = basename(projectConfig);
|
|
88
|
+
|
|
66
89
|
if (agentDir === '.claude' || agentDir === '.cursor' || agentDir === '.pmc') {
|
|
67
|
-
// For Claude Code, Cursor, and generic PMC setups: write .mcp.json directly
|
|
68
90
|
const mcpPath = await writeMcpJson(projectRoot, installState);
|
|
69
|
-
// Also persist enrichment config
|
|
70
91
|
const enrichPath = join(projectConfig, PMC_ENRICHMENT_CONFIG_FILE);
|
|
71
92
|
const existingConfig = await readJson(enrichPath, {});
|
|
72
93
|
const config = {
|
|
@@ -85,7 +106,6 @@ async function ensureAgentConfigRegistration(projectRoot, installState) {
|
|
|
85
106
|
return mcpPath;
|
|
86
107
|
}
|
|
87
108
|
|
|
88
|
-
// Fallback: no agent dir detected — write .mcp.json at project root
|
|
89
109
|
return writeMcpJson(projectRoot, installState);
|
|
90
110
|
}
|
|
91
111
|
|
|
@@ -104,6 +124,7 @@ export async function bootstrapProjectInstall({
|
|
|
104
124
|
ollamaBaseUrl,
|
|
105
125
|
ollamaModel,
|
|
106
126
|
embeddingCachePath,
|
|
127
|
+
agent,
|
|
107
128
|
}) {
|
|
108
129
|
const dirs = await ensureProjectMemoryContextDirs(projectRoot);
|
|
109
130
|
const memoryDbPath = join(dirs.base, 'memory-db');
|
|
@@ -118,7 +139,7 @@ export async function bootstrapProjectInstall({
|
|
|
118
139
|
|
|
119
140
|
await mkdir(memoryDbPath, { recursive: true });
|
|
120
141
|
await writeJsonArtifact(join(dirs.base, 'install.json'), installState);
|
|
121
|
-
const configPath = await ensureAgentConfigRegistration(projectRoot, installState);
|
|
142
|
+
const configPath = await ensureAgentConfigRegistration(projectRoot, installState, agent);
|
|
122
143
|
const commandPath = await copyTemplate(packageRoot, 'project-memory-context.md', projectRoot);
|
|
123
144
|
const workflowPath = await copyTemplate(packageRoot, 'project-memory-context workflow.md', projectRoot);
|
|
124
145
|
|
|
@@ -107,7 +107,7 @@ async function installOpencode({ projectRoot, packageRoot, placeholders, globalC
|
|
|
107
107
|
await readTemplate(packageRoot, 'opencode/agent/enrich.md'),
|
|
108
108
|
placeholders,
|
|
109
109
|
);
|
|
110
|
-
await writeIfMissingOrForced(join(globalDir, '
|
|
110
|
+
await writeIfMissingOrForced(join(globalDir, 'agents', 'enrich.md'), enrichTemplate, { force: true });
|
|
111
111
|
|
|
112
112
|
const agentsMdPath = join(projectRoot, 'AGENTS.md');
|
|
113
113
|
const autostartBlock = renderTemplate(
|