@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 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 { detectAgentType, resolveConfigDirs, resolvePythonBin } from '../src/platform.mjs';
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
- console.warn('\n⚠ Could not install graphifyy automatically. Run: pip install graphifyy\n');
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aabadin/project-memory-context",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Portable project memory context CLI — bootstraps semantic enrichment workflows for any AI coding agent.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "type": "module",
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 in PATH install python3 or set PATH' };
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;
@@ -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
- const { projectConfig } = resolveConfigDirs(projectRoot);
50
- const agentDir = basename(projectConfig);
51
-
52
- if (agentDir === '.opencode') {
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, 'agent', 'enrich.md'), enrichTemplate, { force: true });
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(