@zoer7788/mcp-nexus-node 0.1.7 → 0.1.9

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.
Files changed (2) hide show
  1. package/cli.js +23 -3
  2. package/package.json +13 -2
package/cli.js CHANGED
@@ -2,9 +2,9 @@
2
2
  import http from "node:http";
3
3
  import { createHash, randomBytes, randomUUID } from "node:crypto";
4
4
  import { spawn, spawnSync } from "node:child_process";
5
- import { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync, appendFileSync } from "node:fs";
5
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync, appendFileSync, readdirSync, statSync } from "node:fs";
6
6
  import { homedir, hostname } from "node:os";
7
- import { dirname, join } from "node:path";
7
+ import { dirname, join, resolve } from "node:path";
8
8
  import { fileURLToPath } from "node:url";
9
9
  import { createRequire } from "node:module";
10
10
 
@@ -17,6 +17,7 @@ const logDir = join(stateDir, "logs");
17
17
  const binDir = join(stateDir, "bin");
18
18
  const nodeIdPath = join(stateDir, "node-id");
19
19
  const packageDir = dirname(fileURLToPath(import.meta.url));
20
+ const NODE_VERSION = "0.1.9";
20
21
  const require = createRequire(import.meta.url);
21
22
 
22
23
  function ensureState() {
@@ -194,6 +195,21 @@ function findProject(name) {
194
195
  return projects().find((p) => p.name === name);
195
196
  }
196
197
 
198
+ function listDirectories(path) {
199
+ const current = resolve(String(path || home).replace(/^~(?=\/|$)/, home));
200
+ const entries = readdirSync(current, { withFileTypes: true })
201
+ .filter((entry) => entry.isDirectory())
202
+ .slice(0, 300)
203
+ .map((entry) => {
204
+ const fullPath = join(current, entry.name);
205
+ let writable = false;
206
+ try { writable = Boolean(statSync(fullPath).mode & 0o200); } catch {}
207
+ return { name: entry.name, path: fullPath, writable };
208
+ })
209
+ .sort((a, b) => a.name.localeCompare(b.name));
210
+ return { current, parent: dirname(current), entries };
211
+ }
212
+
197
213
  function devspaceCommand() {
198
214
  const explicit = process.env.DEVSPACE_CLI;
199
215
  if (explicit && existsSync(explicit)) return ["node", explicit];
@@ -448,10 +464,14 @@ function serve() {
448
464
  try {
449
465
  if (req.method === "OPTIONS") return json(res, 204, {});
450
466
  if (req.method === "GET" && req.url === "/api/health") {
451
- return json(res, 200, { ok: true, app: "mcp-nexus-node", nodeId: readFileSync(nodeIdPath, "utf8").trim(), name: cfg.name, version: "0.1.0" });
467
+ return json(res, 200, { ok: true, app: "mcp-nexus-node", nodeId: readFileSync(nodeIdPath, "utf8").trim(), name: cfg.name, version: NODE_VERSION });
452
468
  }
453
469
  if (!req.url?.startsWith("/api/")) return json(res, 404, { ok: false, error: "not found" });
454
470
  if (!requireAuth(req)) return json(res, 401, { ok: false, error: "unauthorized" });
471
+ const url = new URL(req.url, "http://localhost");
472
+ if (req.method === "GET" && url.pathname === "/api/fs/list") {
473
+ return json(res, 200, listDirectories(url.searchParams.get("path") || home));
474
+ }
455
475
  if (req.method === "GET" && req.url === "/api/projects") return json(res, 200, { projects: projects().map(projectStatus) });
456
476
  if (req.method === "POST" && req.url === "/api/projects") return json(res, 200, setupProject(await readJson(req)));
457
477
  const match = req.url.match(/^\/api\/projects\/([^/]+)(?:\/([^?]+))?/);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zoer7788/mcp-nexus-node",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Remote node for MCP Nexus pairing and DevSpace project control.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -15,7 +15,18 @@
15
15
  "scripts": {
16
16
  "check": "node --check cli.js"
17
17
  },
18
- "dependencies": {},
18
+ "dependencies": {
19
+ "@clack/prompts": "^1.5.1",
20
+ "@earendil-works/pi-coding-agent": "^0.80.1",
21
+ "@modelcontextprotocol/ext-apps": "^1.7.2",
22
+ "@modelcontextprotocol/sdk": "^1.29.0",
23
+ "@pierre/diffs": "^1.2.5",
24
+ "better-sqlite3": "^12.10.0",
25
+ "drizzle-orm": "^0.45.2",
26
+ "express": "^5.2.1",
27
+ "semver": "^7.8.4",
28
+ "zod": "^4.4.3"
29
+ },
19
30
  "publishConfig": {
20
31
  "access": "public"
21
32
  }