monomind 1.10.21 → 1.10.23

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.
@@ -126,14 +126,18 @@ node "$SCRIPT" \
126
126
 
127
127
  The script will:
128
128
  1. Read all file nodes from the monograph DB
129
- 2. For each file, call the Anthropic API (via `ANTHROPIC_API_KEY`) to get summaries, tags, and complexity
130
- 3. Detect architectural layers (LLM-based if API key available, heuristic fallback otherwise)
131
- 4. Write enrichment data back to `monograph.db` (community_id + properties JSON)
132
- 5. Emit a `graph.json` to `$DIR/.understand/knowledge-graph.json`
133
-
134
- If `ANTHROPIC_API_KEY` is not set, the script automatically falls back to `--no-llm` mode — heuristic layer detection from file paths, no per-file summaries. Tell the user this happened.
135
-
136
- Wait for the script to complete before proceeding.
129
+ 2. Pick the best available LLM path automatically (no env vars to set):
130
+ - `claude -p` CLI passthrough reuses the active Claude Code authentication
131
+ - direct Anthropic API if `ANTHROPIC_API_KEY` happens to be set (faster for bulk runs)
132
+ - heuristic-only fallback if neither is reachable
133
+ 3. For each file, generate summaries, tags, and complexity
134
+ 4. Detect architectural layers
135
+ 5. Write enrichment data back to `monograph.db` (community_id + properties JSON)
136
+ 6. Emit a `graph.json` to `$DIR/.understand/knowledge-graph.json`
137
+
138
+ Wait for the script to complete before proceeding. Do NOT pre-check or advise about
139
+ `ANTHROPIC_API_KEY` — the script picks its path silently and prints the chosen mode
140
+ on stdout. Report only what the script actually reports.
137
141
 
138
142
  ---
139
143
 
@@ -173,17 +177,19 @@ Then tell the user:
173
177
  > Open the Monomind control panel and click **Monograph → GRAPH** to see multi-color layers.
174
178
  > Each color represents an architectural layer (API, Service, Data, UI, etc.).
175
179
  >
176
- > To re-run with full LLM analysis: `/monomind:understand --full`
177
- > To only refresh layer detection: `/monomind:understand --layers-only`
178
- > To run without API calls: `/monomind:understand --no-llm`
179
- > To re-analyze only changed files: `/monomind:understand --incremental`
180
- > To generate an onboarding guide: `/monomind:understand --onboard`
180
+ > Common follow-ups:
181
+ > - `/monomind:understand --full` — full re-analysis from scratch
182
+ > - `/monomind:understand --layers-only` — refresh only layer detection
183
+ > - `/monomind:understand --incremental` — re-analyze only changed files
184
+ > - `/monomind:understand --onboard` — generate an onboarding guide
181
185
 
182
186
  ---
183
187
 
184
188
  ## Error Handling
185
189
 
186
- - If `ANTHROPIC_API_KEY` is not set, automatically use heuristic mode report this clearly but do NOT stop.
190
+ - The script auto-selects an LLM path (`claude -p` CLI API key heuristic). Do not
191
+ prompt the user to set `ANTHROPIC_API_KEY`. Monomind is designed to run inside an
192
+ authenticated Claude Code session — the CLI passthrough is the default path.
187
193
  - If the script exits non-zero, show stderr and suggest `npm install -g monomind@latest`.
188
194
  - If monograph.db has no file nodes, tell the user to run `npx monomind monograph build` first.
189
195
  - All errors are non-fatal to the main session — report and return cleanly.
@@ -1470,6 +1470,60 @@ const handlers = {
1470
1470
  console.log('[OK] Session restored: session-' + Date.now());
1471
1471
  }
1472
1472
  } catch (e) { console.log('[WARN] Session restore failed: ' + e.message); }
1473
+
1474
+ // Stale helper detection — compare local helper hashes against the
1475
+ // bundled (npm-installed) monomind copy and warn if they drift. This
1476
+ // is what alerts the user that 'monomind init upgrade' would pick up
1477
+ // new features (graph fallback routing, telemetry counters, etc).
1478
+ try {
1479
+ var crypto = require('crypto');
1480
+ // Walk up from this file to find the monomind package root (looks for
1481
+ // package.json with name === 'monomind' or '@monomind/cli').
1482
+ function _findBundledHelpers() {
1483
+ var helperPaths = [
1484
+ path.join(__dirname),
1485
+ path.join(CWD, 'node_modules', 'monomind', '.claude', 'helpers'),
1486
+ path.join(CWD, 'node_modules', '@monoes', 'monomindcli', '.claude', 'helpers'),
1487
+ ];
1488
+ try {
1489
+ var globalRoot = require('child_process')
1490
+ .execSync('npm root -g 2>/dev/null', { encoding: 'utf-8', timeout: 2000 })
1491
+ .trim();
1492
+ if (globalRoot) {
1493
+ helperPaths.push(path.join(globalRoot, 'monomind', '.claude', 'helpers'));
1494
+ helperPaths.push(path.join(globalRoot, '@monoes', 'monomindcli', '.claude', 'helpers'));
1495
+ }
1496
+ } catch (_) {}
1497
+ for (var i = 0; i < helperPaths.length; i++) {
1498
+ if (fs.existsSync(path.join(helperPaths[i], 'hook-handler.cjs')) &&
1499
+ helperPaths[i] !== path.join(CWD, '.claude', 'helpers')) {
1500
+ return helperPaths[i];
1501
+ }
1502
+ }
1503
+ return null;
1504
+ }
1505
+
1506
+ var bundledDir = _findBundledHelpers();
1507
+ if (bundledDir) {
1508
+ var helpersToCheck = ['hook-handler.cjs', 'statusline.cjs'];
1509
+ var stale = [];
1510
+ for (var hi = 0; hi < helpersToCheck.length; hi++) {
1511
+ var hName = helpersToCheck[hi];
1512
+ var localF = path.join(CWD, '.claude', 'helpers', hName);
1513
+ var bundledF = path.join(bundledDir, hName);
1514
+ if (!fs.existsSync(localF) || !fs.existsSync(bundledF)) continue;
1515
+ try {
1516
+ var hashL = crypto.createHash('sha256').update(fs.readFileSync(localF)).digest('hex');
1517
+ var hashB = crypto.createHash('sha256').update(fs.readFileSync(bundledF)).digest('hex');
1518
+ if (hashL !== hashB) stale.push(hName);
1519
+ } catch (_) {}
1520
+ }
1521
+ if (stale.length > 0) {
1522
+ console.log('[STALE_HELPERS] Project helpers differ from bundled version: ' + stale.join(', '));
1523
+ console.log(' Run `npx monomind@latest init upgrade` to refresh and pick up the latest features.');
1524
+ }
1525
+ }
1526
+ } catch (e) { /* non-fatal */ }
1473
1527
  // Initialize intelligence (with timeout — #1530)
1474
1528
  // Respects monomind.neural.enabled kill switch from settings.json
1475
1529
  var neuralEnabled = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "monomind",
3
- "version": "1.10.21",
3
+ "version": "1.10.23",
4
4
  "description": "Monomind - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -411,6 +411,86 @@ async function checkMonograph() {
411
411
  }
412
412
  }
413
413
  // Check agentic-flow v1 integration (filesystem-based to avoid slow WASM/DB init)
414
+ // Resolve the path to the bundled (npm-installed) copy of a helper file.
415
+ // Walks up from this module's location to find the package root, then joins
416
+ // the relative path. Returns null if not found.
417
+ function _resolveBundledHelper(relativePath) {
418
+ try {
419
+ const thisFile = fileURLToPath(import.meta.url);
420
+ let dir = dirname(thisFile);
421
+ for (;;) {
422
+ const candidate = join(dir, 'package.json');
423
+ if (existsSync(candidate)) {
424
+ try {
425
+ const pkg = JSON.parse(readFileSync(candidate, 'utf8'));
426
+ if (pkg.name === '@monomind/cli' || pkg.name === 'monomind') {
427
+ const helperPath = join(dir, relativePath);
428
+ return existsSync(helperPath) ? helperPath : null;
429
+ }
430
+ }
431
+ catch { /* keep walking */ }
432
+ }
433
+ const parent = dirname(dir);
434
+ if (parent === dir)
435
+ return null;
436
+ dir = parent;
437
+ }
438
+ }
439
+ catch {
440
+ return null;
441
+ }
442
+ }
443
+ // Compare per-project helper file content vs the bundled (npm) version.
444
+ // Returns the list of files that drifted.
445
+ async function _detectStaleHelpers() {
446
+ const stale = [];
447
+ const missing = [];
448
+ const helpers = ['hook-handler.cjs', 'statusline.cjs', 'router.cjs', 'graphify-freshen.cjs'];
449
+ const crypto = await import('node:crypto');
450
+ for (const name of helpers) {
451
+ const local = join(process.cwd(), '.claude', 'helpers', name);
452
+ if (!existsSync(local))
453
+ continue;
454
+ const bundled = _resolveBundledHelper(join('.claude', 'helpers', name));
455
+ if (!bundled) {
456
+ missing.push(name);
457
+ continue;
458
+ }
459
+ try {
460
+ const hashLocal = crypto.createHash('sha256').update(readFileSync(local)).digest('hex');
461
+ const hashBundled = crypto.createHash('sha256').update(readFileSync(bundled)).digest('hex');
462
+ if (hashLocal !== hashBundled)
463
+ stale.push(name);
464
+ }
465
+ catch { /* skip */ }
466
+ }
467
+ return { stale, missing };
468
+ }
469
+ async function checkHelpersFresh() {
470
+ try {
471
+ const { stale, missing } = await _detectStaleHelpers();
472
+ if (stale.length === 0 && missing.length === 0) {
473
+ return { name: 'Helper Files', status: 'pass', message: 'Project helpers match bundled version' };
474
+ }
475
+ if (stale.length > 0) {
476
+ return {
477
+ name: 'Helper Files',
478
+ status: 'warn',
479
+ message: `${stale.length} stale helper(s) in .claude/helpers/: ${stale.join(', ')}`,
480
+ fix: 'monomind init upgrade',
481
+ };
482
+ }
483
+ return {
484
+ name: 'Helper Files',
485
+ status: 'warn',
486
+ message: `Could not locate bundled copies of: ${missing.join(', ')}`,
487
+ fix: 'Reinstall monomind or run `monomind init upgrade`',
488
+ };
489
+ }
490
+ catch (e) {
491
+ return { name: 'Helper Files', status: 'warn', message: `check failed: ${e instanceof Error ? e.message : 'unknown'}` };
492
+ }
493
+ }
414
494
  async function checkAgenticFlow() {
415
495
  try {
416
496
  // Walk common node_modules paths to find agentic-flow/package.json
@@ -523,6 +603,7 @@ export const doctorCommand = {
523
603
  checkDiskSpace,
524
604
  checkBuildTools,
525
605
  checkMonograph,
606
+ checkHelpersFresh,
526
607
  checkAgenticFlow
527
608
  ];
528
609
  const componentMap = {
@@ -540,6 +621,7 @@ export const doctorCommand = {
540
621
  'disk': checkDiskSpace,
541
622
  'typescript': checkBuildTools,
542
623
  'monograph': checkMonograph,
624
+ 'helpers': checkHelpersFresh,
543
625
  'agentic-flow': checkAgenticFlow
544
626
  };
545
627
  let checksToRun = allChecks;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monoes/monomindcli",
3
- "version": "1.10.21",
3
+ "version": "1.10.23",
4
4
  "type": "module",
5
5
  "description": "Monomind CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
6
6
  "main": "dist/src/index.js",
@@ -153,12 +153,14 @@ const USE_CLAUDE_CLI = !ANTHROPIC_API_KEY && !!_detectClaudeCli();
153
153
 
154
154
  async function callClaudeViaCli(systemPrompt, userPrompt, maxTokens = 1024) {
155
155
  return new Promise((resolveP, reject) => {
156
+ // NOTE: do NOT pass --bare here. --bare disables OAuth/keychain reads
157
+ // and forces ANTHROPIC_API_KEY — which is exactly what we're avoiding.
158
+ // We want the CLI to use the user's logged-in Claude Code session.
156
159
  const args = [
157
160
  '-p',
158
161
  '--model', 'haiku',
159
162
  '--output-format', 'text',
160
- '--bare', // skip hooks/skills/auto-memory — we want a fast, clean call
161
- // Combine system + user into a single prompt argument
163
+ '--disable-slash-commands', // skip skill auto-resolution overhead
162
164
  `${systemPrompt}\n\n---\n\n${userPrompt}`,
163
165
  ];
164
166
  const child = spawn(_claudeCliPath, args, {
@@ -170,8 +172,8 @@ async function callClaudeViaCli(systemPrompt, userPrompt, maxTokens = 1024) {
170
172
  child.stderr.on('data', d => err += d.toString());
171
173
  const timeout = setTimeout(() => {
172
174
  child.kill('SIGKILL');
173
- reject(new Error('claude -p timed out after 60s'));
174
- }, 60000);
175
+ reject(new Error('claude -p timed out after 120s'));
176
+ }, 120000);
175
177
  child.on('close', code => {
176
178
  clearTimeout(timeout);
177
179
  if (code !== 0) return reject(new Error(`claude -p exited ${code}: ${err.slice(0, 200)}`));
@@ -697,11 +699,22 @@ async function main() {
697
699
  const batch = toAnalyze.slice(0, limit);
698
700
  console.log(`[understand] Analyzing ${batch.length} files (${toAnalyze.length - batch.length} skipped/already enriched)`);
699
701
 
700
- const llmPath = ANTHROPIC_API_KEY ? 'api' : (USE_CLAUDE_CLI ? 'claude-cli' : 'none');
702
+ // Prefer the CLI passthrough when available monomind is designed to run
703
+ // inside an authenticated Claude Code session and the CLI reuses that auth
704
+ // without prompting for an API key. Direct API only takes precedence when
705
+ // explicitly opted into (MONOMIND_PREFER_API=1).
706
+ const preferApi = process.env.MONOMIND_PREFER_API === '1';
707
+ const llmPath = (preferApi && ANTHROPIC_API_KEY) ? 'api'
708
+ : USE_CLAUDE_CLI ? 'claude-cli'
709
+ : ANTHROPIC_API_KEY ? 'api'
710
+ : 'none';
701
711
  if (llmPath === 'none' && !noLlm) {
702
- console.warn('[understand] No LLM path available (no ANTHROPIC_API_KEY and no `claude` CLI) falling back to --no-llm heuristic mode');
712
+ console.warn('[understand] No LLM path available `claude` CLI not found on PATH and ANTHROPIC_API_KEY not set. Running in heuristic mode.');
713
+ console.warn('[understand] Tip: install Claude Code or set ANTHROPIC_API_KEY to enable per-file summaries.');
703
714
  } else if (llmPath === 'claude-cli' && !noLlm) {
704
- console.log('[understand] Using `claude -p` CLI passthrough (no API key needed; reusing Claude Code auth)');
715
+ console.log('[understand] LLM path: `claude -p` CLI passthrough (reusing Claude Code session, no key needed)');
716
+ } else if (llmPath === 'api' && !noLlm) {
717
+ console.log('[understand] LLM path: direct Anthropic API (ANTHROPIC_API_KEY set)');
705
718
  }
706
719
  const useLlm = !noLlm && llmPath !== 'none';
707
720