@monoes/monomindcli 1.10.23 → 1.10.25
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,197 +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`
|
|
80
|
-
|
|
81
|
-
And STOP.
|
|
43
|
+
If `$DB` does not exist:
|
|
44
|
+
> monograph.db not found at `$DB`. Build it first: `npx monomind monograph build`
|
|
82
45
|
|
|
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
|
|
71
|
+
## Step 3: Per-file summarization (ONLY if `--no-llm` and `--layers-only` are both UNSET)
|
|
110
72
|
|
|
111
|
-
|
|
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.
|
|
112
75
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
```
|
|
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.
|
|
126
88
|
|
|
127
|
-
|
|
128
|
-
1. Read all file nodes from the monograph DB
|
|
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.
|
|
89
|
+
If `$ARGUMENTS` includes `--no-llm` or `--layers-only`, SKIP this step entirely.
|
|
141
90
|
|
|
142
91
|
---
|
|
143
92
|
|
|
144
|
-
## Step
|
|
93
|
+
## Step 4: Write analyses back to the DB
|
|
145
94
|
|
|
146
|
-
|
|
95
|
+
Pipe the collected analyses to a small re-import:
|
|
147
96
|
|
|
148
97
|
```bash
|
|
149
|
-
|
|
150
|
-
IMPORT_SCRIPT="$REPO_ROOT/scripts/ua-import.mjs"
|
|
151
|
-
# fallback: alongside understand-analyze.mjs
|
|
152
|
-
[ ! -f "$IMPORT_SCRIPT" ] && IMPORT_SCRIPT="$(dirname $SCRIPT)/../../../scripts/ua-import.mjs"
|
|
153
|
-
node "$IMPORT_SCRIPT" "$GRAPH_JSON" "$DB"
|
|
98
|
+
echo "$ANALYSES_JSON" | node "$SCRIPT" --dir "$DIR" --db "$DB" --import-analyses-stdin
|
|
154
99
|
```
|
|
155
100
|
|
|
156
|
-
If
|
|
101
|
+
(If your `analyses` array is empty, skip this step.)
|
|
157
102
|
|
|
158
103
|
---
|
|
159
104
|
|
|
160
|
-
## Step
|
|
161
|
-
|
|
162
|
-
After the analysis or import completes, show a summary:
|
|
105
|
+
## Step 5: Report
|
|
163
106
|
|
|
164
107
|
```
|
|
165
108
|
╔══════════════════════════════════════════════════╗
|
|
166
109
|
║ /monomind:understand — Enrichment Done ║
|
|
167
110
|
╠══════════════════════════════════════════════════╣
|
|
168
111
|
║ DB: .monomind/monograph.db ║
|
|
169
|
-
║
|
|
170
|
-
║
|
|
112
|
+
║ Files analyzed: <N> ║
|
|
113
|
+
║ LLM summaries: <N> (via active session) ║
|
|
114
|
+
║ Layers: <N> ║
|
|
171
115
|
║ graph.json: .understand/knowledge-graph.json║
|
|
172
116
|
╚══════════════════════════════════════════════════╝
|
|
173
117
|
```
|
|
174
118
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
>
|
|
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.).
|
|
179
124
|
>
|
|
180
|
-
>
|
|
181
|
-
> - `/monomind:understand --full` —
|
|
182
|
-
> - `/monomind:understand --layers-only` — refresh only
|
|
183
|
-
> - `/monomind:understand --
|
|
184
|
-
> - `/monomind:understand --onboard` — generate an onboarding guide
|
|
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
|
|
185
129
|
|
|
186
130
|
---
|
|
187
131
|
|
|
188
132
|
## Error Handling
|
|
189
133
|
|
|
190
|
-
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
-
|
|
194
|
-
- If monograph.db has no file nodes, tell the user to run `npx monomind monograph build` first.
|
|
195
|
-
- All errors are non-fatal to the main session — report and return cleanly.
|
|
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.
|
|
196
138
|
|
|
197
|
-
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.25",
|
|
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",
|
|
@@ -22,8 +22,9 @@
|
|
|
22
22
|
* --no-llm Heuristic-only mode (layers + tags from paths, no API calls)
|
|
23
23
|
* --layers-only Skip per-file analysis, only (re-)detect layers
|
|
24
24
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
25
|
+
* Designed to be invoked by the /monomind:understand slash command. The
|
|
26
|
+
* slash command runs the script in --no-llm mode and orchestrates the
|
|
27
|
+
* per-file summarization through the active Claude Code session.
|
|
27
28
|
*/
|
|
28
29
|
|
|
29
30
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
@@ -129,60 +130,16 @@ function detectLayersHeuristic(fileNodes) {
|
|
|
129
130
|
}
|
|
130
131
|
|
|
131
132
|
// ── Anthropic API helpers ─────────────────────────────────────────────────────
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
//
|
|
136
|
-
//
|
|
133
|
+
// LLM enrichment requires ANTHROPIC_API_KEY. When the script is invoked from
|
|
134
|
+
// inside a Claude Code session via /monomind:understand, the slash command
|
|
135
|
+
// orchestrates the LLM work inline (using the active session) — the script
|
|
136
|
+
// itself runs in --no-llm heuristic mode in that flow. Attempting to spawn
|
|
137
|
+
// `claude -p` from a nested subprocess does NOT work (the nested CLI hangs
|
|
138
|
+
// indefinitely), so we no longer try that path.
|
|
137
139
|
const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
|
|
138
140
|
const ANTHROPIC_URL = 'https://api.anthropic.com/v1/messages';
|
|
139
141
|
const MODEL = 'claude-haiku-4-5-20251001'; // cheapest for bulk analysis
|
|
140
142
|
|
|
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
|
-
// 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.
|
|
159
|
-
const args = [
|
|
160
|
-
'-p',
|
|
161
|
-
'--model', 'haiku',
|
|
162
|
-
'--output-format', 'text',
|
|
163
|
-
'--disable-slash-commands', // skip skill auto-resolution overhead
|
|
164
|
-
`${systemPrompt}\n\n---\n\n${userPrompt}`,
|
|
165
|
-
];
|
|
166
|
-
const child = spawn(_claudeCliPath, args, {
|
|
167
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
168
|
-
env: { ...process.env },
|
|
169
|
-
});
|
|
170
|
-
let out = '', err = '';
|
|
171
|
-
child.stdout.on('data', d => out += d.toString());
|
|
172
|
-
child.stderr.on('data', d => err += d.toString());
|
|
173
|
-
const timeout = setTimeout(() => {
|
|
174
|
-
child.kill('SIGKILL');
|
|
175
|
-
reject(new Error('claude -p timed out after 120s'));
|
|
176
|
-
}, 120000);
|
|
177
|
-
child.on('close', code => {
|
|
178
|
-
clearTimeout(timeout);
|
|
179
|
-
if (code !== 0) return reject(new Error(`claude -p exited ${code}: ${err.slice(0, 200)}`));
|
|
180
|
-
resolveP(out.trim());
|
|
181
|
-
});
|
|
182
|
-
child.on('error', e => { clearTimeout(timeout); reject(e); });
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
|
|
186
143
|
async function callClaudeViaApi(systemPrompt, userPrompt, maxTokens = 1024) {
|
|
187
144
|
const body = JSON.stringify({
|
|
188
145
|
model: MODEL,
|
|
@@ -225,10 +182,7 @@ async function callClaude(systemPrompt, userPrompt, maxTokens = 1024) {
|
|
|
225
182
|
if (ANTHROPIC_API_KEY) {
|
|
226
183
|
return callClaudeViaApi(systemPrompt, userPrompt, maxTokens);
|
|
227
184
|
}
|
|
228
|
-
|
|
229
|
-
return callClaudeViaCli(systemPrompt, userPrompt, maxTokens);
|
|
230
|
-
}
|
|
231
|
-
throw new Error('No LLM path available: set ANTHROPIC_API_KEY or install `claude` CLI');
|
|
185
|
+
throw new Error('No LLM path available. Use /monomind:understand from inside Claude Code — the slash command orchestrates LLM work through the active session.');
|
|
232
186
|
}
|
|
233
187
|
|
|
234
188
|
function parseJson(text) {
|
|
@@ -632,10 +586,36 @@ async function main() {
|
|
|
632
586
|
process.exit(1);
|
|
633
587
|
}
|
|
634
588
|
|
|
589
|
+
// Detect non-local filesystems where better-sqlite3 can't acquire file locks
|
|
590
|
+
// (NFS, SMB, FUSE volumes — typically /Volumes/* on macOS or /mnt/* on Linux).
|
|
591
|
+
// When detected, copy the DB to /tmp, work there, copy back atomically at end.
|
|
592
|
+
let workingDbPath = dbPathArg;
|
|
593
|
+
let dbWasShadowed = false;
|
|
594
|
+
let originalDbPath = dbPathArg;
|
|
595
|
+
const isNetworkFs = /^\/Volumes\//.test(dbPathArg) ||
|
|
596
|
+
/^\/mnt\//.test(dbPathArg) ||
|
|
597
|
+
/^\/media\//.test(dbPathArg) ||
|
|
598
|
+
/^\\\\/.test(dbPathArg); // UNC paths on Windows
|
|
599
|
+
if (isNetworkFs && !dryRun) {
|
|
600
|
+
const os = await import('node:os');
|
|
601
|
+
const crypto = await import('node:crypto');
|
|
602
|
+
const tmpName = 'monograph-work-' + crypto.randomBytes(6).toString('hex') + '.db';
|
|
603
|
+
workingDbPath = join(os.tmpdir(), tmpName);
|
|
604
|
+
try {
|
|
605
|
+
console.log(`[understand] DB is on a non-local filesystem (${dbPathArg}). Copying to ${workingDbPath} to avoid SQLite lock issues...`);
|
|
606
|
+
const { copyFileSync } = await import('node:fs');
|
|
607
|
+
copyFileSync(originalDbPath, workingDbPath);
|
|
608
|
+
dbWasShadowed = true;
|
|
609
|
+
} catch (e) {
|
|
610
|
+
console.warn(`[understand] Could not copy to /tmp (${e.message}). Trying in place...`);
|
|
611
|
+
workingDbPath = dbPathArg;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
635
615
|
// Retry openDb against SQLite BUSY when monograph is building in the background
|
|
636
616
|
let db;
|
|
637
617
|
for (let attempt = 0; attempt < 5; attempt++) {
|
|
638
|
-
try { db = mg.openDb(
|
|
618
|
+
try { db = mg.openDb(workingDbPath); break; }
|
|
639
619
|
catch (e) {
|
|
640
620
|
if (attempt === 4) throw e;
|
|
641
621
|
const msg = String(e?.message || e);
|
|
@@ -699,22 +679,13 @@ async function main() {
|
|
|
699
679
|
const batch = toAnalyze.slice(0, limit);
|
|
700
680
|
console.log(`[understand] Analyzing ${batch.length} files (${toAnalyze.length - batch.length} skipped/already enriched)`);
|
|
701
681
|
|
|
702
|
-
//
|
|
703
|
-
//
|
|
704
|
-
|
|
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';
|
|
682
|
+
// LLM path determined automatically. The script does NOT advise on
|
|
683
|
+
// credentials — orchestration is the slash command's job.
|
|
684
|
+
const llmPath = ANTHROPIC_API_KEY ? 'api' : 'none';
|
|
711
685
|
if (llmPath === 'none' && !noLlm) {
|
|
712
|
-
console.
|
|
713
|
-
console.
|
|
714
|
-
|
|
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)');
|
|
686
|
+
console.log('[understand] Running in heuristic mode. For per-file summaries,');
|
|
687
|
+
console.log('[understand] use /monomind:understand from inside Claude Code — the slash');
|
|
688
|
+
console.log('[understand] command orchestrates summarization through the active session.');
|
|
718
689
|
}
|
|
719
690
|
const useLlm = !noLlm && llmPath !== 'none';
|
|
720
691
|
|
|
@@ -863,13 +834,27 @@ async function main() {
|
|
|
863
834
|
console.log(`║ ONBOARDING.md: ${relative(CWD, onboardOut).padEnd(31)}║`);
|
|
864
835
|
}
|
|
865
836
|
console.log('╚══════════════════════════════════════════════════╝');
|
|
837
|
+
|
|
838
|
+
// Copy DB back if we shadowed it on /tmp due to network FS
|
|
839
|
+
if (dbWasShadowed && !dryRun) {
|
|
840
|
+
try {
|
|
841
|
+
const { copyFileSync, unlinkSync } = await import('node:fs');
|
|
842
|
+
try { db.close(); } catch {}
|
|
843
|
+
console.log(`[understand] Copying enriched DB back to ${originalDbPath}...`);
|
|
844
|
+
copyFileSync(workingDbPath, originalDbPath);
|
|
845
|
+
try { unlinkSync(workingDbPath); } catch {}
|
|
846
|
+
} catch (e) {
|
|
847
|
+
console.error(`[understand] Failed to copy DB back: ${e.message}`);
|
|
848
|
+
console.error(`[understand] Enriched DB is at ${workingDbPath} — copy manually if needed.`);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
866
851
|
}
|
|
867
852
|
|
|
868
853
|
// ── Detect layers and write communities to DB ────────────────────────────────
|
|
869
854
|
async function detectAndWriteLayers(db, fileNodes, forceHeuristic, dryRun, dir) {
|
|
870
855
|
let layers;
|
|
871
856
|
|
|
872
|
-
if (!forceHeuristic &&
|
|
857
|
+
if (!forceHeuristic && ANTHROPIC_API_KEY) {
|
|
873
858
|
console.log('[understand] Detecting architectural layers via LLM...');
|
|
874
859
|
const filePaths = fileNodes.map(n => n.file_path).filter(Boolean);
|
|
875
860
|
try {
|