@aabadin/project-memory-context 0.2.4 → 0.2.6
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.
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { dirname, resolve } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const PACKAGE_ROOT = resolve(__dirname, '..');
|
|
8
|
+
|
|
9
|
+
const GRAPH_EXPLORER_PATH = resolve(PACKAGE_ROOT, '../pmc-graph-explorer/server.mjs');
|
|
10
|
+
|
|
11
|
+
const child = spawn(process.execPath, [GRAPH_EXPLORER_PATH], {
|
|
12
|
+
stdio: 'inherit',
|
|
13
|
+
detached: true,
|
|
14
|
+
shell: true,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
child.unref();
|
package/cli/context.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
3
3
|
import { dirname, join, resolve } from 'node:path';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
5
|
|
|
@@ -22,7 +22,7 @@ export async function findProjectRoot(startDir = process.cwd()) {
|
|
|
22
22
|
|
|
23
23
|
while (true) {
|
|
24
24
|
const installPath = join(currentDir, '.planning', 'project-memory-context', 'install.json');
|
|
25
|
-
if (
|
|
25
|
+
if (existsSync(installPath)) {
|
|
26
26
|
return currentDir;
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -35,6 +35,23 @@ export async function findProjectRoot(startDir = process.cwd()) {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
async function markContext(projectRoot, nodeIds) {
|
|
39
|
+
if (!nodeIds || nodeIds.length === 0) return;
|
|
40
|
+
const trackerPath = join(projectRoot, '.planning', 'project-memory-context', 'context-tracker.json');
|
|
41
|
+
let tracker = { activeNodeIds: [] };
|
|
42
|
+
try {
|
|
43
|
+
if (existsSync(trackerPath)) {
|
|
44
|
+
tracker = JSON.parse(readFileSync(trackerPath, 'utf-8'));
|
|
45
|
+
}
|
|
46
|
+
} catch {}
|
|
47
|
+
const existing = new Set(tracker.activeNodeIds || []);
|
|
48
|
+
nodeIds.forEach((id) => existing.add(id));
|
|
49
|
+
tracker.activeNodeIds = [...existing];
|
|
50
|
+
const dir = dirname(trackerPath);
|
|
51
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
52
|
+
writeFileSync(trackerPath, JSON.stringify(tracker, null, 2));
|
|
53
|
+
}
|
|
54
|
+
|
|
38
55
|
export function parseArgs(args) {
|
|
39
56
|
const DEPTH_VALUES = ['compact', 'extended', 'deep', 'disk'];
|
|
40
57
|
const FOCUS_VALUES = ['dependencies', 'callers', 'containment', 'impact', 'all'];
|
|
@@ -190,12 +207,12 @@ export function buildRenderInput(engine, resolved, { depth, focus }) {
|
|
|
190
207
|
};
|
|
191
208
|
}
|
|
192
209
|
|
|
193
|
-
export async function runTargetContext({ projectRoot, target, explicitMode, depth, focus }) {
|
|
194
|
-
const
|
|
210
|
+
export async function runTargetContext({ projectRoot, target, explicitMode, depth, focus, artifacts }) {
|
|
211
|
+
const artfs = artifacts ?? await loadArtifacts(projectRoot);
|
|
195
212
|
const engine = createQueryEngine({
|
|
196
|
-
graph:
|
|
197
|
-
symbolIndex:
|
|
198
|
-
worklist:
|
|
213
|
+
graph: artfs.graph,
|
|
214
|
+
symbolIndex: artfs.symbolIndex,
|
|
215
|
+
worklist: artfs.worklist,
|
|
199
216
|
enrichmentDir: join(projectRoot, '.planning', 'project-memory-context', 'enrichment'),
|
|
200
217
|
projectSlug: 'project',
|
|
201
218
|
});
|
|
@@ -205,7 +222,7 @@ export async function runTargetContext({ projectRoot, target, explicitMode, dept
|
|
|
205
222
|
const input = buildRenderInput(engine, resolved, { depth, focus });
|
|
206
223
|
const output = renderTargetContext(input);
|
|
207
224
|
|
|
208
|
-
return { output, resolved, input };
|
|
225
|
+
return { output, resolved, input, artifacts: artfs };
|
|
209
226
|
}
|
|
210
227
|
|
|
211
228
|
export async function runProjectContext(projectRoot = process.cwd(), refresh = false) {
|
|
@@ -301,7 +318,8 @@ export async function main(args = process.argv.slice(2)) {
|
|
|
301
318
|
return 1;
|
|
302
319
|
}
|
|
303
320
|
|
|
304
|
-
const
|
|
321
|
+
const artifacts = await loadArtifacts(projectRoot);
|
|
322
|
+
const { output, resolved } = await runTargetContext({
|
|
305
323
|
projectRoot,
|
|
306
324
|
target: parsed.target,
|
|
307
325
|
explicitMode: parsed.explicitMode,
|
|
@@ -309,6 +327,17 @@ export async function main(args = process.argv.slice(2)) {
|
|
|
309
327
|
focus: parsed.focus,
|
|
310
328
|
});
|
|
311
329
|
|
|
330
|
+
const nodeIdsToMark = [];
|
|
331
|
+
if (resolved.symbolKey) {
|
|
332
|
+
const entry = artifacts.symbolIndex[resolved.symbolKey];
|
|
333
|
+
if (entry?.graphNodeId) nodeIdsToMark.push(entry.graphNodeId);
|
|
334
|
+
} else if (resolved.target && (resolved.mode === 'file' || resolved.mode === 'symbol-missing')) {
|
|
335
|
+
const fileNodeId = resolved.target.replace(/[/\\]/g, '_').replace(/[:.]/g, '_');
|
|
336
|
+
nodeIdsToMark.push(fileNodeId);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
await markContext(projectRoot, nodeIdsToMark);
|
|
340
|
+
|
|
312
341
|
console.log(output);
|
|
313
342
|
return 0;
|
|
314
343
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aabadin/project-memory-context",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
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",
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
},
|
|
13
13
|
"bin": {
|
|
14
14
|
"pmc": "bin/pmc.mjs",
|
|
15
|
-
"pmc-query-server": "mcp/pmc-query-server.mjs"
|
|
15
|
+
"pmc-query-server": "mcp/pmc-query-server.mjs",
|
|
16
|
+
"pmc-view-context": "bin/pmc-view-context.mjs"
|
|
16
17
|
},
|
|
17
18
|
"scripts": {
|
|
18
19
|
"test": "node --test tests/*.test.mjs",
|
|
@@ -26,6 +27,7 @@
|
|
|
26
27
|
"plugin/",
|
|
27
28
|
"src/",
|
|
28
29
|
"templates/",
|
|
30
|
+
"tools/pmc-graph-explorer/",
|
|
29
31
|
"README.md",
|
|
30
32
|
"LICENSE"
|
|
31
33
|
],
|
package/src/command-dispatch.mjs
CHANGED
|
@@ -109,6 +109,7 @@ async function installOpencode({ projectRoot, packageRoot, placeholders, globalC
|
|
|
109
109
|
'opencode/commands/doctor.md',
|
|
110
110
|
'opencode/commands/init-project.md',
|
|
111
111
|
'opencode/commands/retry-errors.md',
|
|
112
|
+
'opencode/commands/view-context.md',
|
|
112
113
|
];
|
|
113
114
|
|
|
114
115
|
for (const tpl of commandTemplates) {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: view-context
|
|
3
|
+
description: Open the PMC Graph Explorer web UI to visualize the enrichment graph with active context highlighting.
|
|
4
|
+
argument-hint: ""
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Bash
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<objective>
|
|
10
|
+
Open the PMC Graph Explorer to visualize the enrichment graph. The server runs on port 3001 and shows nodes consulted via /get-context with a cyan glow.
|
|
11
|
+
</objective>
|
|
12
|
+
|
|
13
|
+
<execution>
|
|
14
|
+
Start the graph explorer server:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx @aabadin/project-memory-context view-context
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Or if PMC is installed globally:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pmc-view-context
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Then open http://localhost:3001 in your browser.
|
|
27
|
+
</execution>
|