@rubytech/create-realagent 1.0.634 → 1.0.636

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/dist/index.js CHANGED
@@ -8,6 +8,7 @@ const PAYLOAD_DIR = resolve(import.meta.dirname, "../payload");
8
8
  // The bundler stamps brand.json into the payload at build time.
9
9
  const BRAND_PATH = join(PAYLOAD_DIR, "platform", "config", "brand.json");
10
10
  if (!existsSync(BRAND_PATH)) {
11
+ console.error("Setup failed: brand.json not found in payload (package may be corrupted)");
11
12
  console.error("FATAL: brand.json not found in payload. Package may be corrupted.");
12
13
  process.exit(1);
13
14
  }
@@ -16,6 +17,7 @@ try {
16
17
  BRAND = JSON.parse(readFileSync(BRAND_PATH, "utf-8"));
17
18
  }
18
19
  catch (err) {
20
+ console.error(`Setup failed: failed to parse brand.json: ${err.message}`);
19
21
  console.error(`FATAL: Failed to parse brand.json: ${err.message}`);
20
22
  process.exit(1);
21
23
  }
@@ -1335,6 +1337,7 @@ function createTunnelSymlink(linkPath, target) {
1335
1337
  catch (err) {
1336
1338
  const code = err.code;
1337
1339
  if (code !== "ENOENT") {
1340
+ console.error(`Setup failed: ${linkPath} lstat failed: ${err.message}`);
1338
1341
  console.error(`[create-maxy:error] ${linkPath} lstat failed: ${err.message}`);
1339
1342
  process.exit(1);
1340
1343
  }
@@ -1346,6 +1349,7 @@ function createTunnelSymlink(linkPath, target) {
1346
1349
  return;
1347
1350
  }
1348
1351
  if (!lstat.isSymbolicLink()) {
1352
+ console.error(`Setup failed: ${linkPath} collision (regular file)`);
1349
1353
  console.error(`[create-maxy:collision] ${linkPath} already exists target=<regular-file>`);
1350
1354
  console.error(` Remove the file and re-run: npx -y @rubytech/create-maxy`);
1351
1355
  process.exit(1);
@@ -1356,6 +1360,7 @@ function createTunnelSymlink(linkPath, target) {
1356
1360
  resolvedTarget = resolve(dirname(linkPath), raw);
1357
1361
  }
1358
1362
  catch (err) {
1363
+ console.error(`Setup failed: ${linkPath} symlink unreadable: ${err.message}`);
1359
1364
  console.error(`[create-maxy:collision] ${linkPath} symlink unreadable: ${err.message}`);
1360
1365
  console.error(` Remove the file and re-run: npx -y @rubytech/create-maxy`);
1361
1366
  process.exit(1);
@@ -1386,6 +1391,7 @@ function createTunnelSymlink(linkPath, target) {
1386
1391
  logFile(` symlink repaired (dangling): ${linkPath} was ${resolvedTarget}, now ${targetAbs}`);
1387
1392
  return;
1388
1393
  }
1394
+ console.error(`Setup failed: ${linkPath} collision (symlink to ${resolvedTarget})`);
1389
1395
  console.error(`[create-maxy:collision] ${linkPath} already exists target=${resolvedTarget}`);
1390
1396
  console.error(` This symlink was created by a different install (not within ${INSTALL_DIR}).`);
1391
1397
  console.error(` Remove or relocate it, then re-run: npx -y @rubytech/create-maxy`);
@@ -1401,6 +1407,7 @@ function installTunnelScripts() {
1401
1407
  chmodSync(src, 0o755);
1402
1408
  }
1403
1409
  catch (err) {
1410
+ console.error(`Setup failed: tunnel script missing or chmod failed: ${src}`);
1404
1411
  console.error(`[create-maxy:error] tunnel script missing or chmod failed: ${src}`);
1405
1412
  console.error(` ${err.message}`);
1406
1413
  process.exit(1);
@@ -1578,6 +1585,7 @@ Environment=KEEP_ALIVE_TIMEOUT=61000
1578
1585
  Environment=DISPLAY=:99
1579
1586
  Environment=PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/chromium
1580
1587
  Environment=MAXY_PLATFORM_ROOT=${INSTALL_DIR}/platform
1588
+ Environment=PATH=%h/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
1581
1589
  EnvironmentFile=-${persistDir}/.env
1582
1590
  StandardOutput=append:${persistDir}/logs/server.log
1583
1591
  StandardError=append:${persistDir}/logs/server.log
@@ -1586,6 +1594,11 @@ StandardError=append:${persistDir}/logs/server.log
1586
1594
  WantedBy=default.target
1587
1595
  `;
1588
1596
  writeFileSync(join(serviceDir, BRAND.serviceName), serviceFile);
1597
+ // Task 560: the unit declares Environment=PATH=%h/.local/bin:... so the graph
1598
+ // MCP shim's spawn("uvx", ...) resolves against uv's install location. Without
1599
+ // this line, the service inherits the default systemd-user PATH — which
1600
+ // excludes ~/.local/bin — and the shim exits ENOENT before any query lands.
1601
+ logFile(` ${BRAND.serviceName}: PATH env includes %h/.local/bin for uvx resolution`);
1589
1602
  // WiFi AP provisioning service — system-level (requires root for hostapd/dnsmasq).
1590
1603
  // Runs at boot to check connectivity. If no saved WiFi and no ethernet, activates
1591
1604
  // a temporary AP with a captive portal for first-time WiFi configuration.
@@ -1678,6 +1691,7 @@ WantedBy=multi-user.target
1678
1691
  vncLog = `(no boot log found at ${vncLogPath})`;
1679
1692
  }
1680
1693
  console.error("");
1694
+ console.error("Setup failed: Browser automation unavailable — CDP port 9222 not responding");
1681
1695
  console.error(" ERROR: Browser automation unavailable — CDP port 9222 not responding.");
1682
1696
  console.error(" Chromium should be started by vnc.sh (ExecStartPre). Check the boot log:");
1683
1697
  console.error("");
@@ -1698,6 +1712,7 @@ WantedBy=multi-user.target
1698
1712
  }
1699
1713
  catch (err) {
1700
1714
  console.error("");
1715
+ console.error(`Setup failed: tunnel script symlink missing or not executable: ${linkPath}`);
1701
1716
  console.error(` [create-maxy:error] tunnel script symlink missing or not executable: ${linkPath}`);
1702
1717
  console.error(` ${err.message}`);
1703
1718
  process.exit(1);
@@ -1715,6 +1730,7 @@ if (_args.includes("--uninstall")) {
1715
1730
  const exportPath = exportIdx !== -1 ? _args[exportIdx + 1] : undefined;
1716
1731
  const skipConfirm = _args.includes("--yes");
1717
1732
  if (exportIdx !== -1 && !exportPath) {
1733
+ console.error("Setup failed: --export-data requires a path argument");
1718
1734
  console.error("--export-data requires a path argument.");
1719
1735
  process.exit(1);
1720
1736
  }
@@ -1735,6 +1751,7 @@ if (portIdx !== -1) {
1735
1751
  const raw = _args[portIdx + 1];
1736
1752
  const parsed = raw ? parseInt(raw, 10) : NaN;
1737
1753
  if (isNaN(parsed) || parsed < 1024 || parsed > 65535) {
1754
+ console.error(`Setup failed: --port requires a numeric value between 1024 and 65535 (got: ${raw ?? "nothing"})`);
1738
1755
  console.error(`Error: --port requires a numeric value between 1024 and 65535 (got: ${raw ?? "nothing"}).`);
1739
1756
  process.exit(1);
1740
1757
  }
@@ -1791,11 +1808,13 @@ const hostnameIdx = _args.indexOf("--hostname");
1791
1808
  if (hostnameIdx !== -1) {
1792
1809
  const raw = _args[hostnameIdx + 1];
1793
1810
  if (!raw || raw.startsWith("--")) {
1811
+ console.error("Setup failed: --hostname requires a value");
1794
1812
  console.error("Error: --hostname requires a value (e.g. --hostname muvin).");
1795
1813
  process.exit(1);
1796
1814
  }
1797
1815
  // RFC 1123: lowercase alphanumeric + hyphens, max 63 chars, no leading/trailing hyphen
1798
1816
  if (!/^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/.test(raw)) {
1817
+ console.error(`Setup failed: --hostname value '${raw}' is invalid`);
1799
1818
  console.error(`Error: --hostname value '${raw}' is invalid. Must be lowercase letters, digits, and hyphens only (max 63 chars, no leading/trailing hyphen).`);
1800
1819
  process.exit(1);
1801
1820
  }
@@ -1807,10 +1826,12 @@ const displayIdx = _args.indexOf("--display");
1807
1826
  if (displayIdx !== -1) {
1808
1827
  const raw = _args[displayIdx + 1];
1809
1828
  if (!raw || raw.startsWith("--")) {
1829
+ console.error("Setup failed: --display requires a value");
1810
1830
  console.error("Error: --display requires a value: native or virtual.");
1811
1831
  process.exit(1);
1812
1832
  }
1813
1833
  if (raw !== "native" && raw !== "virtual") {
1834
+ console.error(`Setup failed: --display value '${raw}' is invalid`);
1814
1835
  console.error(`Error: --display value '${raw}' is invalid. Must be 'native' or 'virtual'.`);
1815
1836
  process.exit(1);
1816
1837
  }
@@ -1858,12 +1879,14 @@ let EMBED_SOURCE = "default";
1858
1879
  const embedModelIdx = _args.indexOf("--embed-model");
1859
1880
  const embedDimsIdx = _args.indexOf("--embed-dimensions");
1860
1881
  if (embedDimsIdx !== -1 && embedModelIdx === -1) {
1882
+ console.error("Setup failed: --embed-dimensions requires --embed-model");
1861
1883
  console.error("Error: --embed-dimensions requires --embed-model (dimensions are model-specific).");
1862
1884
  process.exit(1);
1863
1885
  }
1864
1886
  if (embedModelIdx !== -1) {
1865
1887
  const raw = _args[embedModelIdx + 1];
1866
1888
  if (!raw || raw.startsWith("--")) {
1889
+ console.error("Setup failed: --embed-model requires a value");
1867
1890
  console.error("Error: --embed-model requires a value (e.g. --embed-model mxbai-embed-large).");
1868
1891
  process.exit(1);
1869
1892
  }
@@ -1874,6 +1897,7 @@ if (embedModelIdx !== -1) {
1874
1897
  const rawDims = _args[embedDimsIdx + 1];
1875
1898
  const parsed = rawDims ? parseInt(rawDims, 10) : NaN;
1876
1899
  if (isNaN(parsed) || parsed <= 0) {
1900
+ console.error(`Setup failed: --embed-dimensions requires a positive integer (got: ${rawDims ?? "nothing"})`);
1877
1901
  console.error(`Error: --embed-dimensions requires a positive integer (got: ${rawDims ?? "nothing"}).`);
1878
1902
  process.exit(1);
1879
1903
  }
@@ -1885,6 +1909,7 @@ if (embedModelIdx !== -1) {
1885
1909
  }
1886
1910
  else {
1887
1911
  // Unknown model without explicit dimensions — cannot proceed
1912
+ console.error(`Setup failed: unknown embedding model '${EMBED_MODEL}'`);
1888
1913
  console.error(`Error: Unknown embedding model '${EMBED_MODEL}'.`);
1889
1914
  console.error("Known models and their dimensions:");
1890
1915
  for (const [model, dims] of Object.entries(EMBED_MODEL_DIMS)) {
@@ -1937,6 +1962,7 @@ if (neo4jPortIdx !== -1) {
1937
1962
  const raw = _args[neo4jPortIdx + 1];
1938
1963
  const parsed = raw ? parseInt(raw, 10) : NaN;
1939
1964
  if (isNaN(parsed) || parsed < 1024 || parsed > 65535) {
1965
+ console.error(`Setup failed: --neo4j-port requires a numeric value between 1024 and 65535 (got: ${raw ?? "nothing"})`);
1940
1966
  console.error(`Error: --neo4j-port requires a numeric value between 1024 and 65535 (got: ${raw ?? "nothing"}).`);
1941
1967
  process.exit(1);
1942
1968
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-realagent",
3
- "version": "1.0.634",
3
+ "version": "1.0.636",
4
4
  "description": "Install Real Agent — Built for agents. By agents.",
5
5
  "bin": {
6
6
  "create-realagent": "./dist/index.js"
@@ -32,6 +32,46 @@ const index_js_1 = require("../../mcp-stderr-tee/dist/index.js");
32
32
  const SERVER_NAME = "graph";
33
33
  const UPSTREAM_PACKAGE = "mcp-neo4j-cypher@0.6.0";
34
34
  (0, index_js_1.initStderrTee)(SERVER_NAME);
35
+ // Sync-write failure line to the per-server raw file AND the per-conversation
36
+ // stream log. Used only on exit paths (missing password, uvx unresolvable,
37
+ // upstream spawn/exit error) where the async stderr tee's createWriteStream
38
+ // buffer will not flush before process.exit() outraces it. `appendFileSync`
39
+ // returns after the kernel has queued the write, so the line survives an
40
+ // immediate exit. Each destination is wrapped independently — an unwritable
41
+ // destination must not mask the primary failure. The final process.stderr.write
42
+ // goes through the patched writer installed by initStderrTee; any async tee
43
+ // writes it schedules are discarded by the subsequent process.exit, but its
44
+ // inline write to the original stderr still reaches Claude Code's consumer.
45
+ function syncEmit(line) {
46
+ const msg = `[graph-mcp] ${line}`;
47
+ const iso = new Date().toISOString();
48
+ const logDir = process.env.LOG_DIR;
49
+ if (logDir) {
50
+ try {
51
+ (0, node_fs_1.mkdirSync)(logDir, { recursive: true });
52
+ const date = iso.slice(0, 10);
53
+ (0, node_fs_1.appendFileSync)((0, node_path_1.resolve)(logDir, `mcp-${SERVER_NAME}-stderr-${date}.log`), `${msg}\n`);
54
+ }
55
+ catch {
56
+ /* unwritable destination — preserve primary failure */
57
+ }
58
+ }
59
+ const streamLogPath = process.env.STREAM_LOG_PATH;
60
+ if (streamLogPath) {
61
+ try {
62
+ (0, node_fs_1.appendFileSync)(streamLogPath, `[${iso}] [mcp:${SERVER_NAME}] ${msg}\n`);
63
+ }
64
+ catch {
65
+ /* unwritable destination — preserve primary failure */
66
+ }
67
+ }
68
+ try {
69
+ process.stderr.write(`${msg}\n`);
70
+ }
71
+ catch {
72
+ /* stderr closed — nothing else to do */
73
+ }
74
+ }
35
75
  function resolvePassword() {
36
76
  if (process.env.NEO4J_PASSWORD)
37
77
  return process.env.NEO4J_PASSWORD;
@@ -43,10 +83,57 @@ function resolvePassword() {
43
83
  return (0, node_fs_1.readFileSync)(file, "utf-8").trim();
44
84
  }
45
85
  catch {
46
- console.error(`[graph-mcp] password unavailable — file=${file} env=NEO4J_PASSWORD (neither set)`);
86
+ syncEmit(`password unavailable — file=${file} env=NEO4J_PASSWORD=unset`);
47
87
  process.exit(1);
48
88
  }
49
89
  }
90
+ function resolveUvxPath() {
91
+ const envPath = process.env.UVX_PATH ?? "";
92
+ if (envPath) {
93
+ try {
94
+ (0, node_fs_1.accessSync)(envPath, node_fs_1.constants.X_OK);
95
+ return { path: envPath, source: "env", envChecked: envPath, homeLocalChecked: "skipped", whichChecked: "skipped" };
96
+ }
97
+ catch {
98
+ /* fall through */
99
+ }
100
+ }
101
+ const home = process.env.HOME ?? "";
102
+ const homeLocalPath = home ? (0, node_path_1.resolve)(home, ".local/bin/uvx") : "";
103
+ if (homeLocalPath) {
104
+ try {
105
+ const stats = (0, node_fs_1.statSync)(homeLocalPath);
106
+ if (stats.isFile()) {
107
+ (0, node_fs_1.accessSync)(homeLocalPath, node_fs_1.constants.X_OK);
108
+ return { path: homeLocalPath, source: "home-local", envChecked: envPath || "unset", homeLocalChecked: homeLocalPath, whichChecked: "skipped" };
109
+ }
110
+ }
111
+ catch {
112
+ /* fall through */
113
+ }
114
+ }
115
+ let whichPath = "";
116
+ try {
117
+ whichPath = (0, node_child_process_1.execFileSync)("which", ["uvx"], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }).trim();
118
+ }
119
+ catch {
120
+ whichPath = "";
121
+ }
122
+ if (whichPath) {
123
+ // Verify the result is still executable. `which` prints the first PATH
124
+ // hit by name; if the target was removed or the symlink dangles, the
125
+ // spawn would ENOENT and reintroduce the silent-fail class Task 560
126
+ // closes.
127
+ try {
128
+ (0, node_fs_1.accessSync)(whichPath, node_fs_1.constants.X_OK);
129
+ return { path: whichPath, source: "which", envChecked: envPath || "unset", homeLocalChecked: homeLocalPath || "unset", whichChecked: whichPath };
130
+ }
131
+ catch {
132
+ return { path: null, source: null, envChecked: envPath || "unset", homeLocalChecked: homeLocalPath || "unset", whichChecked: `${whichPath} (not-executable)` };
133
+ }
134
+ }
135
+ return { path: null, source: null, envChecked: envPath || "unset", homeLocalChecked: homeLocalPath || "unset", whichChecked: "not-found" };
136
+ }
50
137
  const brand = process.env.BRAND ?? "maxy";
51
138
  const neo4jUri = process.env.NEO4J_URI ?? "bolt://localhost:7687";
52
139
  const neo4jUser = process.env.NEO4J_USERNAME ?? process.env.NEO4J_USER ?? "neo4j";
@@ -68,7 +155,14 @@ const childEnv = {
68
155
  };
69
156
  console.error(`[graph-mcp] boot brand=${brand} uri=${neo4jUri} user=${neo4jUser} ` +
70
157
  `namespace=${namespace} readOnly=${readOnly} tokenLimit=${responseTokenLimit}`);
71
- const child = (0, node_child_process_1.spawn)("uvx", [UPSTREAM_PACKAGE, "--transport", "stdio"], {
158
+ const uvx = resolveUvxPath();
159
+ if (!uvx.path) {
160
+ syncEmit(`uvx unresolvable — checked env=${uvx.envChecked} home-local=${uvx.homeLocalChecked} which=${uvx.whichChecked}`);
161
+ syncEmit("install uv (if missing): curl -LsSf https://astral.sh/uv/install.sh | sh");
162
+ process.exit(127);
163
+ }
164
+ console.error(`[graph-mcp] uvx resolved path=${uvx.path} source=${uvx.source}`);
165
+ const child = (0, node_child_process_1.spawn)(uvx.path, [UPSTREAM_PACKAGE, "--transport", "stdio"], {
72
166
  stdio: ["pipe", "pipe", "pipe"],
73
167
  env: childEnv,
74
168
  });
@@ -77,15 +171,11 @@ child.on("spawn", () => {
77
171
  });
78
172
  child.on("error", (err) => {
79
173
  const msg = err instanceof Error ? err.message : String(err);
80
- console.error(`[graph-mcp] spawn error: ${msg}`);
81
- if (err.code === "ENOENT") {
82
- console.error("[graph-mcp] uvx not found on PATH — install uv: " +
83
- "curl -LsSf https://astral.sh/uv/install.sh | sh -s -- -y");
84
- }
174
+ syncEmit(`spawn error: ${msg} uvx=${uvx.path ?? "unresolved"}`);
85
175
  process.exit(127);
86
176
  });
87
177
  child.on("exit", (code, signal) => {
88
- console.error(`[graph-mcp] uvx exited code=${code ?? "null"} signal=${signal ?? "null"}`);
178
+ syncEmit(`uvx exited code=${code ?? "null"} signal=${signal ?? "null"}`);
89
179
  process.exit(code ?? (signal ? 1 : 0));
90
180
  });
91
181
  // Forward child stderr to our own stderr so the stderr tee picks it up.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -23,8 +23,8 @@
23
23
  * own password. This shim trusts that — no query-layer tenant filtering.
24
24
  */
25
25
 
26
- import { spawn } from "node:child_process";
27
- import { readFileSync } from "node:fs";
26
+ import { execFileSync, spawn } from "node:child_process";
27
+ import { accessSync, appendFileSync, constants, mkdirSync, readFileSync, statSync } from "node:fs";
28
28
  import { resolve } from "node:path";
29
29
  import { StringDecoder } from "node:string_decoder";
30
30
  import { initStderrTee } from "../../mcp-stderr-tee/dist/index.js";
@@ -34,6 +34,44 @@ const UPSTREAM_PACKAGE = "mcp-neo4j-cypher@0.6.0";
34
34
 
35
35
  initStderrTee(SERVER_NAME);
36
36
 
37
+ // Sync-write failure line to the per-server raw file AND the per-conversation
38
+ // stream log. Used only on exit paths (missing password, uvx unresolvable,
39
+ // upstream spawn/exit error) where the async stderr tee's createWriteStream
40
+ // buffer will not flush before process.exit() outraces it. `appendFileSync`
41
+ // returns after the kernel has queued the write, so the line survives an
42
+ // immediate exit. Each destination is wrapped independently — an unwritable
43
+ // destination must not mask the primary failure. The final process.stderr.write
44
+ // goes through the patched writer installed by initStderrTee; any async tee
45
+ // writes it schedules are discarded by the subsequent process.exit, but its
46
+ // inline write to the original stderr still reaches Claude Code's consumer.
47
+ function syncEmit(line: string): void {
48
+ const msg = `[graph-mcp] ${line}`;
49
+ const iso = new Date().toISOString();
50
+ const logDir = process.env.LOG_DIR;
51
+ if (logDir) {
52
+ try {
53
+ mkdirSync(logDir, { recursive: true });
54
+ const date = iso.slice(0, 10);
55
+ appendFileSync(resolve(logDir, `mcp-${SERVER_NAME}-stderr-${date}.log`), `${msg}\n`);
56
+ } catch {
57
+ /* unwritable destination — preserve primary failure */
58
+ }
59
+ }
60
+ const streamLogPath = process.env.STREAM_LOG_PATH;
61
+ if (streamLogPath) {
62
+ try {
63
+ appendFileSync(streamLogPath, `[${iso}] [mcp:${SERVER_NAME}] ${msg}\n`);
64
+ } catch {
65
+ /* unwritable destination — preserve primary failure */
66
+ }
67
+ }
68
+ try {
69
+ process.stderr.write(`${msg}\n`);
70
+ } catch {
71
+ /* stderr closed — nothing else to do */
72
+ }
73
+ }
74
+
37
75
  function resolvePassword(): string {
38
76
  if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
39
77
  // __dirname points at `lib/graph-mcp/dist` after compilation; the platform
@@ -43,11 +81,70 @@ function resolvePassword(): string {
43
81
  try {
44
82
  return readFileSync(file, "utf-8").trim();
45
83
  } catch {
46
- console.error(`[graph-mcp] password unavailable — file=${file} env=NEO4J_PASSWORD (neither set)`);
84
+ syncEmit(`password unavailable — file=${file} env=NEO4J_PASSWORD=unset`);
47
85
  process.exit(1);
48
86
  }
49
87
  }
50
88
 
89
+ // Resolve `uvx` to an absolute path at boot so the systemd-user default PATH
90
+ // (which excludes ~/.local/bin where the installer's installUv drops uvx)
91
+ // does not ENOENT the spawn. Precedence: UVX_PATH env override > ~/.local/bin/uvx
92
+ // (direct filesystem check, skips PATH lookup) > `which uvx` (catches custom
93
+ // installs). Each source is recorded in the diagnostic log line so a later
94
+ // "uvx unresolvable" emission names every checked location, not just a bare
95
+ // "not found".
96
+ interface UvxResolution {
97
+ path: string | null;
98
+ source: "env" | "home-local" | "which" | null;
99
+ envChecked: string;
100
+ homeLocalChecked: string;
101
+ whichChecked: string;
102
+ }
103
+
104
+ function resolveUvxPath(): UvxResolution {
105
+ const envPath = process.env.UVX_PATH ?? "";
106
+ if (envPath) {
107
+ try {
108
+ accessSync(envPath, constants.X_OK);
109
+ return { path: envPath, source: "env", envChecked: envPath, homeLocalChecked: "skipped", whichChecked: "skipped" };
110
+ } catch {
111
+ /* fall through */
112
+ }
113
+ }
114
+ const home = process.env.HOME ?? "";
115
+ const homeLocalPath = home ? resolve(home, ".local/bin/uvx") : "";
116
+ if (homeLocalPath) {
117
+ try {
118
+ const stats = statSync(homeLocalPath);
119
+ if (stats.isFile()) {
120
+ accessSync(homeLocalPath, constants.X_OK);
121
+ return { path: homeLocalPath, source: "home-local", envChecked: envPath || "unset", homeLocalChecked: homeLocalPath, whichChecked: "skipped" };
122
+ }
123
+ } catch {
124
+ /* fall through */
125
+ }
126
+ }
127
+ let whichPath = "";
128
+ try {
129
+ whichPath = execFileSync("which", ["uvx"], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }).trim();
130
+ } catch {
131
+ whichPath = "";
132
+ }
133
+ if (whichPath) {
134
+ // Verify the result is still executable. `which` prints the first PATH
135
+ // hit by name; if the target was removed or the symlink dangles, the
136
+ // spawn would ENOENT and reintroduce the silent-fail class Task 560
137
+ // closes.
138
+ try {
139
+ accessSync(whichPath, constants.X_OK);
140
+ return { path: whichPath, source: "which", envChecked: envPath || "unset", homeLocalChecked: homeLocalPath || "unset", whichChecked: whichPath };
141
+ } catch {
142
+ return { path: null, source: null, envChecked: envPath || "unset", homeLocalChecked: homeLocalPath || "unset", whichChecked: `${whichPath} (not-executable)` };
143
+ }
144
+ }
145
+ return { path: null, source: null, envChecked: envPath || "unset", homeLocalChecked: homeLocalPath || "unset", whichChecked: "not-found" };
146
+ }
147
+
51
148
  const brand = process.env.BRAND ?? "maxy";
52
149
  const neo4jUri = process.env.NEO4J_URI ?? "bolt://localhost:7687";
53
150
  const neo4jUser = process.env.NEO4J_USERNAME ?? process.env.NEO4J_USER ?? "neo4j";
@@ -74,7 +171,19 @@ console.error(
74
171
  `namespace=${namespace} readOnly=${readOnly} tokenLimit=${responseTokenLimit}`,
75
172
  );
76
173
 
77
- const child = spawn("uvx", [UPSTREAM_PACKAGE, "--transport", "stdio"], {
174
+ const uvx = resolveUvxPath();
175
+ if (!uvx.path) {
176
+ syncEmit(
177
+ `uvx unresolvable — checked env=${uvx.envChecked} home-local=${uvx.homeLocalChecked} which=${uvx.whichChecked}`,
178
+ );
179
+ syncEmit(
180
+ "install uv (if missing): curl -LsSf https://astral.sh/uv/install.sh | sh",
181
+ );
182
+ process.exit(127);
183
+ }
184
+ console.error(`[graph-mcp] uvx resolved path=${uvx.path} source=${uvx.source}`);
185
+
186
+ const child = spawn(uvx.path, [UPSTREAM_PACKAGE, "--transport", "stdio"], {
78
187
  stdio: ["pipe", "pipe", "pipe"],
79
188
  env: childEnv,
80
189
  });
@@ -85,18 +194,12 @@ child.on("spawn", () => {
85
194
 
86
195
  child.on("error", (err) => {
87
196
  const msg = err instanceof Error ? err.message : String(err);
88
- console.error(`[graph-mcp] spawn error: ${msg}`);
89
- if ((err as NodeJS.ErrnoException).code === "ENOENT") {
90
- console.error(
91
- "[graph-mcp] uvx not found on PATH — install uv: " +
92
- "curl -LsSf https://astral.sh/uv/install.sh | sh -s -- -y",
93
- );
94
- }
197
+ syncEmit(`spawn error: ${msg} uvx=${uvx.path ?? "unresolved"}`);
95
198
  process.exit(127);
96
199
  });
97
200
 
98
201
  child.on("exit", (code, signal) => {
99
- console.error(`[graph-mcp] uvx exited code=${code ?? "null"} signal=${signal ?? "null"}`);
202
+ syncEmit(`uvx exited code=${code ?? "null"} signal=${signal ?? "null"}`);
100
203
  process.exit(code ?? (signal ? 1 : 0));
101
204
  });
102
205
 
@@ -1235,16 +1235,15 @@ server.tool("session-resume", "Resume a previous session. Loads the selected ses
1235
1235
  "and routes new messages to that conversation. Call after the user selects a session from the " +
1236
1236
  "session-list results. Pass the conversationId from the selected session.", { conversationId: z.string().uuid().describe("The conversationId of the session to resume") }, async () => ({ content: [{ type: "text", text: "resumed" }] }));
1237
1237
  server.tool("remote-auth-set-password", "Set the remote access password. Hashes with scrypt and writes to the platform's brand-specific config directory with mode 0600. " +
1238
- "Validates strength (8+ chars, digit, special character, no leading/trailing spaces). " +
1238
+ "Validates strength (8+ chars, digit, special character, no spaces anywhere). " +
1239
1239
  "Protects the admin interface when exposed over the tunnel — has no effect on the public endpoint or the tunnel itself. " +
1240
1240
  "Set before `setup-tunnel.sh` — the script's post-restart verification curls the admin hostname and fails if remote-auth is not configured.", { password: z.string() }, async ({ password }) => {
1241
- const trimmed = password.trim();
1242
1241
  // Validate strength — same rules as the web server's validatePasswordStrength
1243
1242
  const checks = [
1244
- { label: "at least 8 characters", met: trimmed.length >= 8 },
1245
- { label: "contains a number", met: /\d/.test(trimmed) },
1246
- { label: "contains a special character", met: /[^A-Za-z0-9]/.test(trimmed) },
1247
- { label: "no leading or trailing spaces", met: trimmed.length > 0 && trimmed === password.trim() },
1243
+ { label: "at least 8 characters", met: password.length >= 8 },
1244
+ { label: "contains a number", met: /\d/.test(password) },
1245
+ { label: "contains a special character", met: /[^A-Za-z0-9]/.test(password) },
1246
+ { label: "no spaces", met: password.length > 0 && !/\s/.test(password) },
1248
1247
  ];
1249
1248
  const failed = checks.filter((c) => !c.met);
1250
1249
  if (failed.length > 0) {
@@ -1257,7 +1256,7 @@ server.tool("remote-auth-set-password", "Set the remote access password. Hashes
1257
1256
  const { scrypt, randomBytes } = await import("node:crypto");
1258
1257
  const salt = randomBytes(32);
1259
1258
  const hash = await new Promise((res, rej) => {
1260
- scrypt(trimmed, salt, 64, { N: 16384, r: 8, p: 1 }, (err, key) => {
1259
+ scrypt(password, salt, 64, { N: 16384, r: 8, p: 1 }, (err, key) => {
1261
1260
  if (err)
1262
1261
  rej(err);
1263
1262
  else