devsmind-mcp 4.1.0 → 4.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.
@@ -55,6 +55,7 @@ const http = __importStar(require("http"));
55
55
  const fs = __importStar(require("fs"));
56
56
  const express_1 = __importDefault(require("express"));
57
57
  const database_1 = require("../db/database");
58
+ const config_1 = require("../utils/config");
58
59
  const visualizer_1 = require("./visualizer");
59
60
  const diff_1 = require("../utils/diff");
60
61
  const revert_1 = require("../db/revert");
@@ -162,19 +163,8 @@ function bindDevmindPath(devmindPath) {
162
163
  function getBoundDevmindPath() {
163
164
  return boundDevmindPath;
164
165
  }
165
- // Walk up from a start directory to find a .devmind folder containing config.json
166
- function findDevmindDir(startDir) {
167
- let current = path.resolve(startDir);
168
- while (true) {
169
- const candidate = path.join(current, '.devmind');
170
- if (fs.existsSync(path.join(candidate, 'config.json')))
171
- return candidate;
172
- const parent = path.dirname(current);
173
- if (parent === current)
174
- return null;
175
- current = parent;
176
- }
177
- }
166
+ // Walk up from a start directory to find a brain folder (`.devsmind`, or a legacy `.devmind`)
167
+ // containing config.json. Both names are tried at every level — see utils/config.ts.
178
168
  // Resolve devmind_path from args, falling back to auto-detect from cwd
179
169
  function resolveDevmindPath(rawPath) {
180
170
  // Bound (stateful) server: it already knows which brain it serves, resolved once at startup.
@@ -195,10 +185,10 @@ function resolveDevmindPath(rawPath) {
195
185
  throw new Error(`devmind_path does not exist: "${resolved}". Make sure you pass the exact DEVMIND_PATH from your workspace rules.`);
196
186
  }
197
187
  // Not provided — auto-detect from where devsmind start was run
198
- const autoDetected = findDevmindDir(process.cwd());
188
+ const autoDetected = (0, config_1.findBrainDir)(process.cwd());
199
189
  if (autoDetected)
200
190
  return autoDetected;
201
- throw new Error(`devmind_path was not provided and no .devmind directory was found by walking up from: "${process.cwd()}". Pass devmind_path explicitly.`);
191
+ throw new Error(`devmind_path was not provided and no .devsmind directory (nor a legacy .devmind one) was found by walking up from: "${process.cwd()}". Pass devmind_path explicitly.`);
202
192
  }
203
193
  /**
204
194
  * A required string argument, or a thrown error naming exactly what's missing.
@@ -3198,7 +3188,7 @@ function createHttpApp(port = exports.DEVSMIND_PORT) {
3198
3188
  // Graph Data API endpoint
3199
3189
  app.get('/api/graph-data', (req, res) => {
3200
3190
  try {
3201
- const devmindPath = req.query.path ? String(req.query.path) : path.join(process.cwd(), '.devmind');
3191
+ const devmindPath = req.query.path ? String(req.query.path) : (0, config_1.brainDirOrDefault)(process.cwd());
3202
3192
  if (!fs.existsSync(devmindPath)) {
3203
3193
  return res.status(400).json({ error: `Brain directory not found at: ${devmindPath}` });
3204
3194
  }
@@ -3222,7 +3212,7 @@ function createHttpApp(port = exports.DEVSMIND_PORT) {
3222
3212
  // Per-edit diffs for one history entry.
3223
3213
  app.get('/api/node-diff', (req, res) => {
3224
3214
  try {
3225
- const devmindPath = req.query.path ? String(req.query.path) : path.join(process.cwd(), '.devmind');
3215
+ const devmindPath = req.query.path ? String(req.query.path) : (0, config_1.brainDirOrDefault)(process.cwd());
3226
3216
  const historyId = req.query.history_id ? String(req.query.history_id) : '';
3227
3217
  if (!historyId)
3228
3218
  return res.status(400).json({ error: 'history_id is required' });
@@ -3259,7 +3249,7 @@ function createHttpApp(port = exports.DEVSMIND_PORT) {
3259
3249
  if (!req.is('application/json')) {
3260
3250
  return res.status(415).json({ error: 'expected application/json' });
3261
3251
  }
3262
- const devmindPath = req.body?.path ? String(req.body.path) : path.join(process.cwd(), '.devmind');
3252
+ const devmindPath = req.body?.path ? String(req.body.path) : (0, config_1.brainDirOrDefault)(process.cwd());
3263
3253
  const historyId = req.body?.history_id ? String(req.body.history_id) : '';
3264
3254
  if (!historyId)
3265
3255
  return res.status(400).json({ error: 'history_id is required' });
@@ -3285,7 +3275,7 @@ function createHttpApp(port = exports.DEVSMIND_PORT) {
3285
3275
  // /api/graph-data: this is one developer's whole history, fetched on every page load.
3286
3276
  app.get('/api/activity', (req, res) => {
3287
3277
  try {
3288
- const devmindPath = req.query.path ? String(req.query.path) : path.join(process.cwd(), '.devmind');
3278
+ const devmindPath = req.query.path ? String(req.query.path) : (0, config_1.brainDirOrDefault)(process.cwd());
3289
3279
  if (!fs.existsSync(devmindPath)) {
3290
3280
  return res.status(400).json({ error: `Brain directory not found at: ${devmindPath}` });
3291
3281
  }
@@ -3339,7 +3329,7 @@ function createHttpApp(port = exports.DEVSMIND_PORT) {
3339
3329
  // Per-edit diffs for one message, fetched only when a human expands it in the Activity page.
3340
3330
  app.get('/api/message-diff', (req, res) => {
3341
3331
  try {
3342
- const devmindPath = req.query.path ? String(req.query.path) : path.join(process.cwd(), '.devmind');
3332
+ const devmindPath = req.query.path ? String(req.query.path) : (0, config_1.brainDirOrDefault)(process.cwd());
3343
3333
  const messageId = req.query.message_id ? String(req.query.message_id) : '';
3344
3334
  if (!messageId)
3345
3335
  return res.status(400).json({ error: 'message_id is required' });
@@ -3370,7 +3360,7 @@ function createHttpApp(port = exports.DEVSMIND_PORT) {
3370
3360
  // already ships, so the message still renders something rather than a guessed-at diff.
3371
3361
  app.get('/api/message-file-diff', (req, res) => {
3372
3362
  try {
3373
- const devmindPath = req.query.path ? String(req.query.path) : path.join(process.cwd(), '.devmind');
3363
+ const devmindPath = req.query.path ? String(req.query.path) : (0, config_1.brainDirOrDefault)(process.cwd());
3374
3364
  const messageId = req.query.message_id ? String(req.query.message_id) : '';
3375
3365
  if (!messageId)
3376
3366
  return res.status(400).json({ error: 'message_id is required' });
@@ -3437,7 +3427,7 @@ function createHttpApp(port = exports.DEVSMIND_PORT) {
3437
3427
  if (!req.is('application/json')) {
3438
3428
  return res.status(415).json({ error: 'expected application/json' });
3439
3429
  }
3440
- const devmindPath = req.body?.path ? String(req.body.path) : path.join(process.cwd(), '.devmind');
3430
+ const devmindPath = req.body?.path ? String(req.body.path) : (0, config_1.brainDirOrDefault)(process.cwd());
3441
3431
  const messageId = req.body?.message_id ? String(req.body.message_id) : '';
3442
3432
  if (!messageId)
3443
3433
  return res.status(400).json({ error: 'message_id is required' });
@@ -3464,7 +3454,7 @@ function createHttpApp(port = exports.DEVSMIND_PORT) {
3464
3454
  if (!req.is('application/json')) {
3465
3455
  return res.status(415).json({ error: 'expected application/json' });
3466
3456
  }
3467
- const devmindPath = req.body?.path ? String(req.body.path) : path.join(process.cwd(), '.devmind');
3457
+ const devmindPath = req.body?.path ? String(req.body.path) : (0, config_1.brainDirOrDefault)(process.cwd());
3468
3458
  const messageId = req.body?.message_id ? String(req.body.message_id) : '';
3469
3459
  if (!messageId)
3470
3460
  return res.status(400).json({ error: 'message_id is required' });
@@ -3491,7 +3481,7 @@ function createHttpApp(port = exports.DEVSMIND_PORT) {
3491
3481
  return res.status(403).json({ error: 'forbidden' });
3492
3482
  if (!req.is('application/json'))
3493
3483
  return res.status(415).json({ error: 'expected application/json' });
3494
- const devmindPath = req.body?.path ? String(req.body.path) : path.join(process.cwd(), '.devmind');
3484
+ const devmindPath = req.body?.path ? String(req.body.path) : (0, config_1.brainDirOrDefault)(process.cwd());
3495
3485
  const messageId = req.body?.message_id ? String(req.body.message_id) : '';
3496
3486
  const filePath = req.body?.file_path ? String(req.body.file_path) : '';
3497
3487
  if (!messageId)
@@ -3517,7 +3507,7 @@ function createHttpApp(port = exports.DEVSMIND_PORT) {
3517
3507
  return res.status(403).json({ error: 'forbidden' });
3518
3508
  if (!req.is('application/json'))
3519
3509
  return res.status(415).json({ error: 'expected application/json' });
3520
- const devmindPath = req.body?.path ? String(req.body.path) : path.join(process.cwd(), '.devmind');
3510
+ const devmindPath = req.body?.path ? String(req.body.path) : (0, config_1.brainDirOrDefault)(process.cwd());
3521
3511
  const messageId = req.body?.message_id ? String(req.body.message_id) : '';
3522
3512
  const filePath = req.body?.file_path ? String(req.body.file_path) : '';
3523
3513
  if (!messageId)
@@ -3543,7 +3533,7 @@ function createHttpApp(port = exports.DEVSMIND_PORT) {
3543
3533
  return res.status(403).json({ error: 'forbidden' });
3544
3534
  if (!req.is('application/json'))
3545
3535
  return res.status(415).json({ error: 'expected application/json' });
3546
- const devmindPath = req.body?.path ? String(req.body.path) : path.join(process.cwd(), '.devmind');
3536
+ const devmindPath = req.body?.path ? String(req.body.path) : (0, config_1.brainDirOrDefault)(process.cwd());
3547
3537
  const messageId = req.body?.message_id ? String(req.body.message_id) : '';
3548
3538
  const editId = req.body?.edit_id ? String(req.body.edit_id) : '';
3549
3539
  if (!messageId)
@@ -3569,7 +3559,7 @@ function createHttpApp(port = exports.DEVSMIND_PORT) {
3569
3559
  return res.status(403).json({ error: 'forbidden' });
3570
3560
  if (!req.is('application/json'))
3571
3561
  return res.status(415).json({ error: 'expected application/json' });
3572
- const devmindPath = req.body?.path ? String(req.body.path) : path.join(process.cwd(), '.devmind');
3562
+ const devmindPath = req.body?.path ? String(req.body.path) : (0, config_1.brainDirOrDefault)(process.cwd());
3573
3563
  const messageId = req.body?.message_id ? String(req.body.message_id) : '';
3574
3564
  const editId = req.body?.edit_id ? String(req.body.edit_id) : '';
3575
3565
  if (!messageId)
@@ -3640,7 +3630,7 @@ function bindServerToProject(devmindPath) {
3640
3630
  console.error(`DevsMind: bound via --path/DEVSMIND_PATH → serving ${boundDevmindPath}`);
3641
3631
  return;
3642
3632
  }
3643
- const autoDetected = findDevmindDir(process.cwd());
3633
+ const autoDetected = (0, config_1.findBrainDir)(process.cwd());
3644
3634
  if (autoDetected) {
3645
3635
  bindDevmindPath(autoDetected);
3646
3636
  // The one line that makes auto-detect debuggable: a global (no --path) config relies on the
@@ -3651,7 +3641,7 @@ function bindServerToProject(devmindPath) {
3651
3641
  console.error(`DevsMind: started in ${process.cwd()} → serving ${boundDevmindPath}`);
3652
3642
  }
3653
3643
  else {
3654
- console.error(`⚠️ DevsMind: no .devmind directory found from ${process.cwd()} — starting UNBOUND. ` +
3644
+ console.error(`⚠️ DevsMind: no .devsmind directory (nor a legacy .devmind one) found from ${process.cwd()} — starting UNBOUND. ` +
3655
3645
  `Callers must pass devmind_path, or run 'devsmind start' from inside your project (or pass --path).`);
3656
3646
  }
3657
3647
  }