@monoes/monomindcli 1.10.22 → 1.10.24
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.
|
@@ -1,191 +1,139 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: monomind:understand
|
|
3
|
-
description: "Monomind — Run semantic enrichment on the current project's monograph knowledge graph.
|
|
3
|
+
description: "Monomind — Run semantic enrichment on the current project's monograph knowledge graph. Uses the active Claude Code session for LLM work — no API key needed."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# /monomind:understand — Semantic Enrichment
|
|
7
7
|
|
|
8
|
-
Enriches the current project's monograph knowledge graph with
|
|
9
|
-
|
|
8
|
+
Enriches the current project's monograph knowledge graph with summaries, architectural
|
|
9
|
+
layers, and semantic relationships.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
**Designed to run inside Claude Code** — uses YOUR current session for LLM work via
|
|
12
|
+
the Task tool. No `ANTHROPIC_API_KEY` required. The script handles layer detection
|
|
13
|
+
and DB writes; you (Claude) handle per-file summarization.
|
|
12
14
|
|
|
13
15
|
## Parse Arguments
|
|
14
16
|
|
|
15
|
-
Parse `$ARGUMENTS` for these
|
|
16
|
-
|
|
17
|
-
- `--dir <path>` — project directory
|
|
18
|
-
- `--db <path>` —
|
|
19
|
-
- `--
|
|
20
|
-
- `--
|
|
21
|
-
- `--
|
|
22
|
-
- `--no-llm` — heuristic-only mode: detect layers from file paths, no API calls
|
|
23
|
-
- `--layers-only` — skip per-file analysis, only (re-)detect architectural layers
|
|
24
|
-
- `--incremental` — re-analyze only files changed since the last run (uses git diff)
|
|
25
|
-
- `--onboard` — generate an ONBOARDING.md guide from the enriched graph
|
|
26
|
-
- `--onboard-out <path>` — where to write the onboarding guide (default: `<dir>/ONBOARDING.md`)
|
|
27
|
-
- `--batch-size <N>` — files per LLM batch (default: 5, increase for faster analysis)
|
|
17
|
+
Parse `$ARGUMENTS` for these flags:
|
|
18
|
+
|
|
19
|
+
- `--dir <path>` — project directory (default: cwd)
|
|
20
|
+
- `--db <path>` — monograph.db path (default: `<dir>/.monomind/monograph.db`)
|
|
21
|
+
- `--full` — force full re-analysis
|
|
22
|
+
- `--no-llm` — heuristic-only mode (no per-file summaries)
|
|
23
|
+
- `--layers-only` — skip per-file analysis, only re-detect layers
|
|
28
24
|
- `--max-files <N>` — stop after N files (0 = all)
|
|
29
|
-
- `--dry-run` — show what would happen
|
|
25
|
+
- `--dry-run` — show what would happen, don't write
|
|
30
26
|
|
|
31
|
-
|
|
27
|
+
Bare path argument → `--dir`.
|
|
32
28
|
|
|
33
29
|
---
|
|
34
30
|
|
|
35
|
-
## Step 1: Locate project and
|
|
31
|
+
## Step 1: Locate project, DB, and script
|
|
36
32
|
|
|
37
33
|
```bash
|
|
38
34
|
DIR="${ARGUMENTS_dir:-$(pwd)}"
|
|
39
35
|
DB="${ARGUMENTS_db:-$DIR/.monomind/monograph.db}"
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
1. Resolve `DIR` to an absolute path.
|
|
43
|
-
2. Check that `$DB` exists. If not, tell the user:
|
|
44
|
-
> monograph.db not found at `$DB`. Build the graph first:
|
|
45
|
-
> ```bash
|
|
46
|
-
> npx monomind monograph build
|
|
47
|
-
> ```
|
|
48
|
-
> Then re-run `/monomind:understand`.
|
|
49
|
-
And STOP.
|
|
50
|
-
|
|
51
|
-
---
|
|
52
36
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
The `understand-analyze.mjs` script ships with `@monomind/cli`. Find it:
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
# Try npm root (global install / homebrew)
|
|
37
|
+
# Find understand-analyze.mjs (ships with monomind globally)
|
|
59
38
|
GLOBAL_ROOT=$(npm root -g 2>/dev/null)
|
|
60
|
-
SCRIPT="$GLOBAL_ROOT/@monomind/cli/scripts/understand-analyze.mjs"
|
|
61
|
-
|
|
62
|
-
# If not found globally, try npx resolve
|
|
63
|
-
if [ ! -f "$SCRIPT" ]; then
|
|
64
|
-
SCRIPT=$(node -e "try{console.log(require.resolve('@monomind/cli/scripts/understand-analyze.mjs'))}catch{}" 2>/dev/null)
|
|
65
|
-
fi
|
|
66
|
-
|
|
67
|
-
# Fallback: walk up from the running CLI's __dirname
|
|
68
|
-
if [ ! -f "$SCRIPT" ]; then
|
|
69
|
-
SCRIPT=$(node -e "
|
|
70
|
-
const {createRequire} = require('module');
|
|
71
|
-
const r = createRequire(require.resolve('monomind'));
|
|
72
|
-
try { console.log(r.resolve('@monomind/cli/scripts/understand-analyze.mjs')); } catch {}
|
|
73
|
-
" 2>/dev/null)
|
|
74
|
-
fi
|
|
39
|
+
SCRIPT="$GLOBAL_ROOT/monomind/packages/@monomind/cli/scripts/understand-analyze.mjs"
|
|
40
|
+
[ ! -f "$SCRIPT" ] && SCRIPT="$GLOBAL_ROOT/@monoes/monomindcli/scripts/understand-analyze.mjs"
|
|
75
41
|
```
|
|
76
42
|
|
|
77
|
-
If
|
|
78
|
-
>
|
|
79
|
-
> Update monomind: `npm install -g monomind@latest`
|
|
43
|
+
If `$DB` does not exist:
|
|
44
|
+
> monograph.db not found at `$DB`. Build it first: `npx monomind monograph build`
|
|
80
45
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
---
|
|
46
|
+
If `$SCRIPT` does not exist:
|
|
47
|
+
> understand engine missing. Update: `npm install -g monomind@latest`
|
|
84
48
|
|
|
85
|
-
|
|
49
|
+
In either case, STOP.
|
|
86
50
|
|
|
87
|
-
|
|
88
|
-
- `$DIR/.understand/knowledge-graph.json`
|
|
89
|
-
- `$DIR/.understand/graph.json`
|
|
90
|
-
- `$DIR/.ua/graph.json`
|
|
51
|
+
---
|
|
91
52
|
|
|
92
|
-
|
|
53
|
+
## Step 2: Run the script in heuristic mode (always — fast and deterministic)
|
|
93
54
|
|
|
94
|
-
|
|
55
|
+
This step is non-negotiable. The script handles:
|
|
56
|
+
- File node discovery from monograph.db
|
|
57
|
+
- Heuristic layer detection from file paths
|
|
58
|
+
- DB writes (community_id + properties)
|
|
59
|
+
- graph.json emission to `.understand/knowledge-graph.json`
|
|
60
|
+
- Auto-shadowing the DB to `/tmp` when it lives on a network FS
|
|
95
61
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
Found graph.json (X hours old) — importing into monograph…
|
|
62
|
+
```bash
|
|
63
|
+
node "$SCRIPT" --dir "$DIR" --db "$DB" --no-llm
|
|
99
64
|
```
|
|
100
65
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
**Otherwise:**
|
|
105
|
-
Proceed to **Step 4: Run analysis**.
|
|
66
|
+
Wait for completion. Capture stdout. Note how many file nodes were found and how
|
|
67
|
+
many layers were detected. Do NOT advise the user about API keys.
|
|
106
68
|
|
|
107
69
|
---
|
|
108
70
|
|
|
109
|
-
## Step
|
|
110
|
-
|
|
111
|
-
Run the built-in engine. Build the command from parsed flags:
|
|
71
|
+
## Step 3: Per-file summarization (ONLY if `--no-llm` and `--layers-only` are both UNSET)
|
|
112
72
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
--dir "$DIR" \
|
|
116
|
-
--db "$DB" \
|
|
117
|
-
[--no-llm] # if --no-llm was set
|
|
118
|
-
[--layers-only] # if --layers-only was set
|
|
119
|
-
[--incremental] # if --incremental was set
|
|
120
|
-
[--onboard] # if --onboard was set
|
|
121
|
-
[--onboard-out PATH] # if --onboard-out was set
|
|
122
|
-
[--dry-run] # if --dry-run was set
|
|
123
|
-
[--batch-size N] # if --batch-size was set
|
|
124
|
-
[--max-files N] # if --max-files was set
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
The script will:
|
|
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`
|
|
73
|
+
This is where YOU (the current Claude session) do the LLM work. The script left
|
|
74
|
+
behind a fresh `.understand/knowledge-graph.json` with placeholder summaries.
|
|
133
75
|
|
|
134
|
-
|
|
76
|
+
1. Read `.understand/knowledge-graph.json`. For each node where `properties.fileSummary`
|
|
77
|
+
is empty or marked `[heuristic]`, do the following:
|
|
78
|
+
- Use the `Read` tool on `node.file_path` (relative to `$DIR`).
|
|
79
|
+
- Produce a JSON object: `{ id, fileSummary, tags, complexity, functionSummaries, classSummaries }`
|
|
80
|
+
where:
|
|
81
|
+
- `fileSummary`: 1-2 sentences explaining what the file does
|
|
82
|
+
- `tags`: array of 2-5 short tags
|
|
83
|
+
- `complexity`: "simple" | "moderate" | "complex"
|
|
84
|
+
- `functionSummaries`: top-5 functions → 1-sentence each
|
|
85
|
+
- `classSummaries`: classes → 1-sentence each
|
|
86
|
+
2. Process files in batches of 5 for efficiency. Use `--max-files` to cap if set.
|
|
87
|
+
3. Collect all analyses into an `analyses` array.
|
|
135
88
|
|
|
136
|
-
|
|
89
|
+
If `$ARGUMENTS` includes `--no-llm` or `--layers-only`, SKIP this step entirely.
|
|
137
90
|
|
|
138
91
|
---
|
|
139
92
|
|
|
140
|
-
## Step
|
|
93
|
+
## Step 4: Write analyses back to the DB
|
|
141
94
|
|
|
142
|
-
|
|
95
|
+
Pipe the collected analyses to a small re-import:
|
|
143
96
|
|
|
144
97
|
```bash
|
|
145
|
-
|
|
146
|
-
IMPORT_SCRIPT="$REPO_ROOT/scripts/ua-import.mjs"
|
|
147
|
-
# fallback: alongside understand-analyze.mjs
|
|
148
|
-
[ ! -f "$IMPORT_SCRIPT" ] && IMPORT_SCRIPT="$(dirname $SCRIPT)/../../../scripts/ua-import.mjs"
|
|
149
|
-
node "$IMPORT_SCRIPT" "$GRAPH_JSON" "$DB"
|
|
98
|
+
echo "$ANALYSES_JSON" | node "$SCRIPT" --dir "$DIR" --db "$DB" --import-analyses-stdin
|
|
150
99
|
```
|
|
151
100
|
|
|
152
|
-
If
|
|
101
|
+
(If your `analyses` array is empty, skip this step.)
|
|
153
102
|
|
|
154
103
|
---
|
|
155
104
|
|
|
156
|
-
## Step
|
|
157
|
-
|
|
158
|
-
After the analysis or import completes, show a summary:
|
|
105
|
+
## Step 5: Report
|
|
159
106
|
|
|
160
107
|
```
|
|
161
108
|
╔══════════════════════════════════════════════════╗
|
|
162
109
|
║ /monomind:understand — Enrichment Done ║
|
|
163
110
|
╠══════════════════════════════════════════════════╣
|
|
164
111
|
║ DB: .monomind/monograph.db ║
|
|
165
|
-
║
|
|
166
|
-
║
|
|
112
|
+
║ Files analyzed: <N> ║
|
|
113
|
+
║ LLM summaries: <N> (via active session) ║
|
|
114
|
+
║ Layers: <N> ║
|
|
167
115
|
║ graph.json: .understand/knowledge-graph.json║
|
|
168
116
|
╚══════════════════════════════════════════════════╝
|
|
169
117
|
```
|
|
170
118
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
>
|
|
119
|
+
If LLM summaries = 0 (because `--no-llm` was set), say "heuristic-only mode — no per-file summaries written".
|
|
120
|
+
|
|
121
|
+
Then:
|
|
122
|
+
> Open the Monomind control panel and click **Monograph → GRAPH** to see layers.
|
|
123
|
+
> Each color = one architectural layer (API, Service, Data, UI, etc.).
|
|
175
124
|
>
|
|
176
|
-
>
|
|
177
|
-
>
|
|
178
|
-
>
|
|
179
|
-
>
|
|
180
|
-
> To generate an onboarding guide: `/monomind:understand --onboard`
|
|
125
|
+
> Follow-ups:
|
|
126
|
+
> - `/monomind:understand --full` — re-run from scratch
|
|
127
|
+
> - `/monomind:understand --layers-only` — refresh only layers
|
|
128
|
+
> - `/monomind:understand --no-llm` — heuristic-only mode
|
|
181
129
|
|
|
182
130
|
---
|
|
183
131
|
|
|
184
132
|
## Error Handling
|
|
185
133
|
|
|
186
|
-
-
|
|
187
|
-
- If the script exits non-zero
|
|
188
|
-
- If monograph.db has no file nodes
|
|
189
|
-
- All errors are non-fatal
|
|
134
|
+
- Do NOT prompt the user to set `ANTHROPIC_API_KEY`. LLM work happens in this session.
|
|
135
|
+
- If the script exits non-zero: show stderr and suggest `npm install -g monomind@latest`.
|
|
136
|
+
- If monograph.db has no file nodes: tell the user to run `npx monomind monograph build` first.
|
|
137
|
+
- All errors are non-fatal — report and return cleanly.
|
|
190
138
|
|
|
191
|
-
To
|
|
139
|
+
To re-run on a schedule: wrap with `/monomind:repeat`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monoes/monomindcli",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.24",
|
|
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",
|
|
@@ -129,58 +129,16 @@ function detectLayersHeuristic(fileNodes) {
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
// ── Anthropic API helpers ─────────────────────────────────────────────────────
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
//
|
|
136
|
-
//
|
|
132
|
+
// LLM enrichment requires ANTHROPIC_API_KEY. When the script is invoked from
|
|
133
|
+
// inside a Claude Code session via /monomind:understand, the slash command
|
|
134
|
+
// orchestrates the LLM work inline (using the active session) — the script
|
|
135
|
+
// itself runs in --no-llm heuristic mode in that flow. Attempting to spawn
|
|
136
|
+
// `claude -p` from a nested subprocess does NOT work (the nested CLI hangs
|
|
137
|
+
// indefinitely), so we no longer try that path.
|
|
137
138
|
const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
|
|
138
139
|
const ANTHROPIC_URL = 'https://api.anthropic.com/v1/messages';
|
|
139
140
|
const MODEL = 'claude-haiku-4-5-20251001'; // cheapest for bulk analysis
|
|
140
141
|
|
|
141
|
-
// Detect `claude` CLI once at startup.
|
|
142
|
-
let _claudeCliPath = null;
|
|
143
|
-
function _detectClaudeCli() {
|
|
144
|
-
if (_claudeCliPath !== null) return _claudeCliPath;
|
|
145
|
-
try {
|
|
146
|
-
const out = execSync('command -v claude 2>/dev/null', { encoding: 'utf-8' }).trim();
|
|
147
|
-
_claudeCliPath = out || '';
|
|
148
|
-
} catch { _claudeCliPath = ''; }
|
|
149
|
-
return _claudeCliPath;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const USE_CLAUDE_CLI = !ANTHROPIC_API_KEY && !!_detectClaudeCli();
|
|
153
|
-
|
|
154
|
-
async function callClaudeViaCli(systemPrompt, userPrompt, maxTokens = 1024) {
|
|
155
|
-
return new Promise((resolveP, reject) => {
|
|
156
|
-
const args = [
|
|
157
|
-
'-p',
|
|
158
|
-
'--model', 'haiku',
|
|
159
|
-
'--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
|
|
162
|
-
`${systemPrompt}\n\n---\n\n${userPrompt}`,
|
|
163
|
-
];
|
|
164
|
-
const child = spawn(_claudeCliPath, args, {
|
|
165
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
166
|
-
env: { ...process.env },
|
|
167
|
-
});
|
|
168
|
-
let out = '', err = '';
|
|
169
|
-
child.stdout.on('data', d => out += d.toString());
|
|
170
|
-
child.stderr.on('data', d => err += d.toString());
|
|
171
|
-
const timeout = setTimeout(() => {
|
|
172
|
-
child.kill('SIGKILL');
|
|
173
|
-
reject(new Error('claude -p timed out after 60s'));
|
|
174
|
-
}, 60000);
|
|
175
|
-
child.on('close', code => {
|
|
176
|
-
clearTimeout(timeout);
|
|
177
|
-
if (code !== 0) return reject(new Error(`claude -p exited ${code}: ${err.slice(0, 200)}`));
|
|
178
|
-
resolveP(out.trim());
|
|
179
|
-
});
|
|
180
|
-
child.on('error', e => { clearTimeout(timeout); reject(e); });
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
|
|
184
142
|
async function callClaudeViaApi(systemPrompt, userPrompt, maxTokens = 1024) {
|
|
185
143
|
const body = JSON.stringify({
|
|
186
144
|
model: MODEL,
|
|
@@ -223,10 +181,7 @@ async function callClaude(systemPrompt, userPrompt, maxTokens = 1024) {
|
|
|
223
181
|
if (ANTHROPIC_API_KEY) {
|
|
224
182
|
return callClaudeViaApi(systemPrompt, userPrompt, maxTokens);
|
|
225
183
|
}
|
|
226
|
-
|
|
227
|
-
return callClaudeViaCli(systemPrompt, userPrompt, maxTokens);
|
|
228
|
-
}
|
|
229
|
-
throw new Error('No LLM path available: set ANTHROPIC_API_KEY or install `claude` CLI');
|
|
184
|
+
throw new Error('No LLM path available: set ANTHROPIC_API_KEY (or use the /monomind:understand slash command, which orchestrates LLM work via the active Claude Code session)');
|
|
230
185
|
}
|
|
231
186
|
|
|
232
187
|
function parseJson(text) {
|
|
@@ -630,10 +585,36 @@ async function main() {
|
|
|
630
585
|
process.exit(1);
|
|
631
586
|
}
|
|
632
587
|
|
|
588
|
+
// Detect non-local filesystems where better-sqlite3 can't acquire file locks
|
|
589
|
+
// (NFS, SMB, FUSE volumes — typically /Volumes/* on macOS or /mnt/* on Linux).
|
|
590
|
+
// When detected, copy the DB to /tmp, work there, copy back atomically at end.
|
|
591
|
+
let workingDbPath = dbPathArg;
|
|
592
|
+
let dbWasShadowed = false;
|
|
593
|
+
let originalDbPath = dbPathArg;
|
|
594
|
+
const isNetworkFs = /^\/Volumes\//.test(dbPathArg) ||
|
|
595
|
+
/^\/mnt\//.test(dbPathArg) ||
|
|
596
|
+
/^\/media\//.test(dbPathArg) ||
|
|
597
|
+
/^\\\\/.test(dbPathArg); // UNC paths on Windows
|
|
598
|
+
if (isNetworkFs && !dryRun) {
|
|
599
|
+
const os = await import('node:os');
|
|
600
|
+
const crypto = await import('node:crypto');
|
|
601
|
+
const tmpName = 'monograph-work-' + crypto.randomBytes(6).toString('hex') + '.db';
|
|
602
|
+
workingDbPath = join(os.tmpdir(), tmpName);
|
|
603
|
+
try {
|
|
604
|
+
console.log(`[understand] DB is on a non-local filesystem (${dbPathArg}). Copying to ${workingDbPath} to avoid SQLite lock issues...`);
|
|
605
|
+
const { copyFileSync } = await import('node:fs');
|
|
606
|
+
copyFileSync(originalDbPath, workingDbPath);
|
|
607
|
+
dbWasShadowed = true;
|
|
608
|
+
} catch (e) {
|
|
609
|
+
console.warn(`[understand] Could not copy to /tmp (${e.message}). Trying in place...`);
|
|
610
|
+
workingDbPath = dbPathArg;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
633
614
|
// Retry openDb against SQLite BUSY when monograph is building in the background
|
|
634
615
|
let db;
|
|
635
616
|
for (let attempt = 0; attempt < 5; attempt++) {
|
|
636
|
-
try { db = mg.openDb(
|
|
617
|
+
try { db = mg.openDb(workingDbPath); break; }
|
|
637
618
|
catch (e) {
|
|
638
619
|
if (attempt === 4) throw e;
|
|
639
620
|
const msg = String(e?.message || e);
|
|
@@ -697,11 +678,19 @@ async function main() {
|
|
|
697
678
|
const batch = toAnalyze.slice(0, limit);
|
|
698
679
|
console.log(`[understand] Analyzing ${batch.length} files (${toAnalyze.length - batch.length} skipped/already enriched)`);
|
|
699
680
|
|
|
700
|
-
|
|
681
|
+
// LLM path: direct Anthropic API only. The script does NOT try to spawn
|
|
682
|
+
// `claude -p` from within Claude Code subprocesses — that hangs because
|
|
683
|
+
// nested CLI sessions aren't supported. For LLM enrichment without an API
|
|
684
|
+
// key, use the /monomind:understand slash command which orchestrates LLM
|
|
685
|
+
// work via the active Claude Code session inline.
|
|
686
|
+
const llmPath = ANTHROPIC_API_KEY ? 'api' : 'none';
|
|
701
687
|
if (llmPath === 'none' && !noLlm) {
|
|
702
|
-
console.
|
|
703
|
-
|
|
704
|
-
console.log('[understand]
|
|
688
|
+
console.log('[understand] No ANTHROPIC_API_KEY — running in heuristic mode for layer detection.');
|
|
689
|
+
console.log('[understand] For per-file summaries: either set ANTHROPIC_API_KEY for direct API,');
|
|
690
|
+
console.log('[understand] or use the /monomind:understand slash command from inside Claude Code');
|
|
691
|
+
console.log('[understand] (the slash command does inline analysis via the active session, no key needed).');
|
|
692
|
+
} else if (llmPath === 'api' && !noLlm) {
|
|
693
|
+
console.log('[understand] LLM path: direct Anthropic API');
|
|
705
694
|
}
|
|
706
695
|
const useLlm = !noLlm && llmPath !== 'none';
|
|
707
696
|
|
|
@@ -850,13 +839,27 @@ async function main() {
|
|
|
850
839
|
console.log(`║ ONBOARDING.md: ${relative(CWD, onboardOut).padEnd(31)}║`);
|
|
851
840
|
}
|
|
852
841
|
console.log('╚══════════════════════════════════════════════════╝');
|
|
842
|
+
|
|
843
|
+
// Copy DB back if we shadowed it on /tmp due to network FS
|
|
844
|
+
if (dbWasShadowed && !dryRun) {
|
|
845
|
+
try {
|
|
846
|
+
const { copyFileSync, unlinkSync } = await import('node:fs');
|
|
847
|
+
try { db.close(); } catch {}
|
|
848
|
+
console.log(`[understand] Copying enriched DB back to ${originalDbPath}...`);
|
|
849
|
+
copyFileSync(workingDbPath, originalDbPath);
|
|
850
|
+
try { unlinkSync(workingDbPath); } catch {}
|
|
851
|
+
} catch (e) {
|
|
852
|
+
console.error(`[understand] Failed to copy DB back: ${e.message}`);
|
|
853
|
+
console.error(`[understand] Enriched DB is at ${workingDbPath} — copy manually if needed.`);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
853
856
|
}
|
|
854
857
|
|
|
855
858
|
// ── Detect layers and write communities to DB ────────────────────────────────
|
|
856
859
|
async function detectAndWriteLayers(db, fileNodes, forceHeuristic, dryRun, dir) {
|
|
857
860
|
let layers;
|
|
858
861
|
|
|
859
|
-
if (!forceHeuristic &&
|
|
862
|
+
if (!forceHeuristic && ANTHROPIC_API_KEY) {
|
|
860
863
|
console.log('[understand] Detecting architectural layers via LLM...');
|
|
861
864
|
const filePaths = fileNodes.map(n => n.file_path).filter(Boolean);
|
|
862
865
|
try {
|