@aabadin/project-memory-context 0.2.13 → 0.2.14

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.
@@ -1,25 +1,70 @@
1
1
  #!/usr/bin/env node
2
- import { spawn } from 'node:child_process';
2
+ import { spawn, execSync } from 'node:child_process';
3
3
  import { dirname, resolve, join } from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
5
  import { existsSync, readFileSync, writeFileSync } from 'node:fs';
6
6
  import { tmpdir } from 'node:os';
7
+ import { setTimeout as sleep } from 'node:timers/promises';
7
8
 
8
9
  const __dirname = dirname(fileURLToPath(import.meta.url));
9
10
  const PACKAGE_ROOT = resolve(__dirname, '..');
10
11
 
11
- // graph-explorer lives INSIDE the package: tools/pmc-graph-explorer/
12
12
  const GRAPH_EXPLORER_PATH = resolve(PACKAGE_ROOT, 'tools/pmc-graph-explorer/server.mjs');
13
13
  const PID_FILE = join(tmpdir(), 'pmc-graph-explorer.pid');
14
+ const PORT = 3001;
14
15
 
15
- // Kill previous server instance if running
16
- if (existsSync(PID_FILE)) {
16
+ function killByPidFile() {
17
+ if (!existsSync(PID_FILE)) return;
17
18
  try {
18
19
  const pid = parseInt(readFileSync(PID_FILE, 'utf8').trim(), 10);
19
- if (pid) process.kill(pid, 'SIGKILL');
20
- } catch { /* already dead or invalid pid */ }
20
+ if (pid) {
21
+ process.kill(pid, 'SIGKILL');
22
+ console.log(`[pmc] Killed previous instance (PID ${pid})`);
23
+ }
24
+ } catch (err) {
25
+ console.error(`[pmc] Could not kill previous instance by PID: ${err.message}`);
26
+ }
21
27
  }
22
28
 
29
+ function killPortProcess(port) {
30
+ try {
31
+ if (process.platform === 'win32') {
32
+ const output = execSync(`netstat -ano | findstr ":${port} "`, { encoding: 'utf8' });
33
+ const pids = new Set();
34
+ for (const line of output.trim().split('\n')) {
35
+ const match = line.trim().match(/\s+(\d+)$/);
36
+ if (match) pids.add(match[1]);
37
+ }
38
+ for (const pid of pids) {
39
+ try {
40
+ execSync(`taskkill /PID ${pid} /F`, { stdio: 'pipe' });
41
+ console.log(`[pmc] Killed process on port ${port} (PID ${pid})`);
42
+ } catch (e) {
43
+ console.error(`[pmc] Could not kill PID ${pid}: ${e.message}`);
44
+ }
45
+ }
46
+ } else {
47
+ const output = execSync(`lsof -ti :${port}`, { encoding: 'utf8' });
48
+ for (const pid of output.trim().split('\n').filter(Boolean)) {
49
+ try {
50
+ execSync(`kill -9 ${pid}`, { stdio: 'pipe' });
51
+ console.log(`[pmc] Killed process on port ${port} (PID ${pid})`);
52
+ } catch (e) {
53
+ console.error(`[pmc] Could not kill PID ${pid}: ${e.message}`);
54
+ }
55
+ }
56
+ }
57
+ } catch {
58
+ // No process on that port — fine
59
+ }
60
+ }
61
+
62
+ killByPidFile();
63
+ killPortProcess(PORT);
64
+
65
+ // Let the OS release the port before binding again
66
+ await sleep(300);
67
+
23
68
  const child = spawn(process.execPath, [GRAPH_EXPLORER_PATH], {
24
69
  env: { ...process.env, PMC_PROJECT_ROOT: process.cwd() },
25
70
  stdio: 'inherit',
@@ -27,5 +72,10 @@ const child = spawn(process.execPath, [GRAPH_EXPLORER_PATH], {
27
72
  shell: false,
28
73
  });
29
74
 
75
+ child.once('error', (err) => {
76
+ console.error(`[pmc] Failed to start graph explorer: ${err.message}`);
77
+ process.exit(1);
78
+ });
79
+
30
80
  writeFileSync(PID_FILE, String(child.pid), 'utf8');
31
81
  child.unref();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aabadin/project-memory-context",
3
- "version": "0.2.13",
3
+ "version": "0.2.14",
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",
@@ -73,4 +73,7 @@ app.post("/api/context", (req, res) => {
73
73
  app.listen(PORT, () => {
74
74
  console.log(`PMC Graph Explorer running at http://localhost:${PORT}`);
75
75
  console.log(`Project root: ${projectRoot}`);
76
+ }).on('error', (err) => {
77
+ console.error(`[pmc-server] Failed to start on port ${PORT}: ${err.message}`);
78
+ process.exit(1);
76
79
  });