neohive 6.1.3 → 6.2.0

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/dashboard.js CHANGED
@@ -169,6 +169,7 @@ function readNeohiveDataDirFromMcpConfigs(projectRoot) {
169
169
  }
170
170
 
171
171
  function resolveDashboardDefaultDataDir() {
172
+ // 1. Explicit env var — highest priority
172
173
  let envData = process.env.NEOHIVE_DATA_DIR || process.env.NEOHIVE_DATA;
173
174
  if (envData && String(envData).trim()) {
174
175
  let s = String(envData).trim();
@@ -178,10 +179,10 @@ function resolveDashboardDefaultDataDir() {
178
179
  }
179
180
  return { path: path.resolve(s), source: 'environment' };
180
181
  }
181
- const fromWalk = bestNeohiveAmongAncestors(process.cwd());
182
- if (fromWalk) {
183
- return { path: fromWalk, source: 'walk-up' };
184
- }
182
+
183
+ // 2. Project MCP config — authoritative, written by `neohive init`
184
+ // Check this BEFORE the directory walk so a stale ~/.neohive/ from
185
+ // a previous session doesn't shadow the project's explicit config.
185
186
  let dir = path.resolve(process.cwd());
186
187
  const root = path.parse(dir).root;
187
188
  while (true) {
@@ -192,6 +193,14 @@ function resolveDashboardDefaultDataDir() {
192
193
  if (dir === root) break;
193
194
  dir = path.dirname(dir);
194
195
  }
196
+
197
+ // 3. Walk up looking for .neohive/ directories — best-effort fallback
198
+ const fromWalk = bestNeohiveAmongAncestors(process.cwd());
199
+ if (fromWalk) {
200
+ return { path: fromWalk, source: 'walk-up' };
201
+ }
202
+
203
+ // 4. cwd/.neohive — last resort
195
204
  return { path: path.join(process.cwd(), '.neohive'), source: 'cwd' };
196
205
  }
197
206
 
@@ -64,29 +64,49 @@ function readNeohiveDirFromUserCursorMcp() {
64
64
 
65
65
  /**
66
66
  * Neohive data directory for the MCP / CLI process.
67
- * Cursor often spawns MCP with cwd=user home and omits NEOHIVE_DATA_DIR in the child env.
68
- * We mirror dashboard resolution: walk ancestors of cwd for MCP configs, then package sibling,
69
- * then ~/.cursor/mcp.json with an absolute path, then cwd/.neohive.
67
+ *
68
+ * Resolution order:
69
+ * 1. NEOHIVE_DATA_DIR env var (set by `neohive init` in project .cursor/mcp.json)
70
+ * 2. Walk up from cwd looking for project MCP configs that define NEOHIVE_DATA_DIR
71
+ * 3. Sibling .neohive/ next to the package (for local dev)
72
+ * 4. User-level ~/.cursor/mcp.json (only if it has an absolute NEOHIVE_DATA_DIR)
73
+ * 5. cwd/.neohive (last resort)
74
+ *
75
+ * Cursor spawns MCP processes with cwd set to a fixed directory (often $HOME),
76
+ * NOT the project root. The only reliable way to identify the project is via
77
+ * NEOHIVE_DATA_DIR in the env. All other fallbacks are best-effort heuristics.
70
78
  *
71
79
  * @param {string} serverJsDir - __dirname of server.js (the agent-bridge folder)
72
80
  */
73
81
  function resolveDataDirForServer(serverJsDir) {
74
82
  const raw = process.env.NEOHIVE_DATA_DIR || process.env.NEOHIVE_DATA;
75
83
  if (raw != null && String(raw).trim() !== '') {
76
- return path.resolve(String(raw).trim());
84
+ const val = String(raw).trim();
85
+ if (/\$\{workspaceFolder\}/i.test(val)) {
86
+ // Cursor user-level configs don't expand ${workspaceFolder}.
87
+ // Don't use this broken value — fall through to cwd/.neohive so the
88
+ // data stays isolated to wherever the process is running.
89
+ console.error('[neohive] NEOHIVE_DATA_DIR contains unexpanded ${workspaceFolder}: ' + val);
90
+ console.error('[neohive] Run "npx neohive init --cursor" in your project to fix this.');
91
+ return path.join(process.cwd(), '.neohive');
92
+ }
93
+ return path.resolve(val);
77
94
  }
78
95
 
96
+ // No env var at all — IDE didn't pass one. Walk up from cwd looking for a
97
+ // project MCP config that defines NEOHIVE_DATA_DIR (first match wins).
79
98
  const fromWalk = findDataDirByWalkingUpFrom(process.cwd());
80
99
  if (fromWalk) return fromWalk;
81
100
 
101
+ // Local dev only: server.js lives inside a project repo (e.g. agent-bridge/).
102
+ // Use the repo's .neohive/ — but ONLY if we aren't inside node_modules
103
+ // (npm-installed copies must never resolve to the package author's project).
82
104
  const parent = path.join(serverJsDir, '..');
83
- if (fs.existsSync(path.join(parent, '.cursor', 'mcp.json'))) {
105
+ if (!serverJsDir.includes('node_modules') && fs.existsSync(path.join(parent, '.cursor', 'mcp.json'))) {
84
106
  return path.join(parent, '.neohive');
85
107
  }
86
- if (fs.existsSync(path.join(serverJsDir, '.cursor', 'mcp.json'))) {
87
- return path.join(serverJsDir, '.neohive');
88
- }
89
108
 
109
+ // User-level ~/.cursor/mcp.json — only if it defines an absolute path
90
110
  const fromUser = readNeohiveDirFromUserCursorMcp();
91
111
  if (fromUser) return fromUser;
92
112
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neohive",
3
- "version": "6.1.3",
3
+ "version": "6.2.0",
4
4
  "description": "The MCP collaboration layer for AI CLI tools. Turn Claude Code, Gemini CLI, and Codex CLI into a team.",
5
5
  "main": "server.js",
6
6
  "bin": {