@hung319/opencode-hive 1.6.3 → 1.6.4
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/README.md +72 -39
- package/bin/doctor.ts +193 -190
- package/dist/index.js +81 -139
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -540,58 +540,91 @@ hive_doctor_quick()
|
|
|
540
540
|
|
|
541
541
|
**Standalone (before installing):**
|
|
542
542
|
```bash
|
|
543
|
-
bunx @hung319/opencode-hive doctor
|
|
543
|
+
bunx @hung319/opencode-hive doctor # Check system
|
|
544
|
+
bunx @hung319/opencode-hive doctor --fix # Auto-fix issues
|
|
544
545
|
```
|
|
545
546
|
|
|
546
547
|
### What it checks
|
|
547
548
|
|
|
548
|
-
1. **
|
|
549
|
-
-
|
|
550
|
-
-
|
|
551
|
-
- MCPs: `@paretools/search`, `@upstash/context7-mcp`, `exa-mcp-server`, `grep-mcp`
|
|
552
|
-
- Blockchain: `btca`, `opencode-model-selector`
|
|
549
|
+
1. **Agent Tools** (optional)
|
|
550
|
+
- `@sparkleideas/agent-booster` - 52x faster code editing
|
|
551
|
+
- `@sparkleideas/memory` - Vector memory for semantic search
|
|
553
552
|
|
|
554
|
-
2. **CLI Tools**
|
|
553
|
+
2. **CLI Tools** (optional)
|
|
555
554
|
- `dora` - Code navigation (SCIP-based)
|
|
556
555
|
- `auto-cr` - Automated code review (SWC)
|
|
557
556
|
- `scip-typescript` - TypeScript indexer
|
|
558
557
|
- `veil` - Code discovery
|
|
559
|
-
- `btca` - BTC/A blockchain agent
|
|
558
|
+
- `btca` - BTC/A blockchain agent
|
|
559
|
+
|
|
560
|
+
3. **MCPs** - Auto-installed with plugin
|
|
561
|
+
- websearch, context7, grep_app
|
|
562
|
+
- pare_search, veil
|
|
560
563
|
|
|
561
|
-
|
|
562
|
-
- snip, vectorMemory, agentBooster
|
|
563
|
-
- sandbox mode
|
|
564
|
-
- MCPs: veil, pare_search
|
|
564
|
+
4. **C++20 Tip** - For @ast-grep/napi native modules
|
|
565
565
|
|
|
566
566
|
### Example Output
|
|
567
567
|
|
|
568
|
-
```
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
568
|
+
```
|
|
569
|
+
╔═══════════════════════════════════════════════════════════╗
|
|
570
|
+
║ 🐝 Hive Doctor v1.6.4 - System Check ║
|
|
571
|
+
╚═══════════════════════════════════════════════════════════╝
|
|
572
|
+
|
|
573
|
+
Status: ⚠️ NEEDS SETUP
|
|
574
|
+
|
|
575
|
+
🚀 Agent Tools (0/2)
|
|
576
|
+
○ @sparkleideas/agent-booster not installed
|
|
577
|
+
○ @sparkleideas/memory not installed
|
|
578
|
+
|
|
579
|
+
🔧 CLI Tools (4/5)
|
|
580
|
+
✅ dora (via npx)
|
|
581
|
+
○ auto-cr not available
|
|
582
|
+
...
|
|
583
|
+
|
|
584
|
+
📦 MCPs: Auto-installed with plugin
|
|
585
|
+
|
|
586
|
+
⚡ C++20 for native modules:
|
|
587
|
+
○ Not set (needed for @ast-grep/napi)
|
|
588
|
+
Run with --fix to auto-configure
|
|
589
|
+
|
|
590
|
+
🚀 Quick Install
|
|
591
|
+
|
|
592
|
+
npx -y auto-cr-cmd && npm install @sparkleideas/agent-booster
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
### Auto-fix Mode
|
|
596
|
+
|
|
597
|
+
```bash
|
|
598
|
+
bunx @hung319/opencode-hive doctor --fix
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
This will:
|
|
602
|
+
1. Auto-add CXXFLAGS="-std=c++20" to ~/.bashrc
|
|
603
|
+
2. Install available CLI tools via npx
|
|
604
|
+
╔═══════════════════════════════════════════════════════════╗
|
|
605
|
+
║ 🐝 Hive Doctor v1.6.3 - System Check ║
|
|
606
|
+
╚═══════════════════════════════════════════════════════════╝
|
|
607
|
+
|
|
608
|
+
Status: ⚠️ NEEDS SETUP
|
|
609
|
+
|
|
610
|
+
🚀 Agent Tools (0/2)
|
|
611
|
+
○ @sparkleideas/agent-booster not installed
|
|
612
|
+
○ @sparkleideas/memory not installed
|
|
613
|
+
|
|
614
|
+
🔧 CLI Tools (1/5)
|
|
615
|
+
✅ dora (via npx)
|
|
616
|
+
○ auto-cr not available
|
|
617
|
+
...
|
|
618
|
+
|
|
619
|
+
📦 MCPs: Auto-installed with plugin
|
|
620
|
+
|
|
621
|
+
💡 Tip: Enable C++20 for native modules?
|
|
622
|
+
Not detected. Run to fix @ast-grep/napi build:
|
|
623
|
+
echo 'export CXXFLAGS="-std=c++20"' >> ~/.bashrc
|
|
624
|
+
|
|
625
|
+
🚀 Quick Install
|
|
626
|
+
|
|
627
|
+
npx -y auto-cr-cmd && npm install @sparkleideas/agent-booster
|
|
595
628
|
```
|
|
596
629
|
|
|
597
630
|
### Setup Workflow
|
package/bin/doctor.ts
CHANGED
|
@@ -8,10 +8,8 @@
|
|
|
8
8
|
* bunx @hung319/opencode-hive doctor
|
|
9
9
|
* npx @hung319/opencode-hive doctor
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* npm install @hung319/opencode-hive
|
|
14
|
-
* hive_doctor() // via OpenCode
|
|
11
|
+
* Auto-fix issues:
|
|
12
|
+
* bunx @hung319/opencode-hive doctor --fix
|
|
15
13
|
*/
|
|
16
14
|
|
|
17
15
|
import { execSync } from 'child_process';
|
|
@@ -26,7 +24,6 @@ interface CheckResult {
|
|
|
26
24
|
name: string;
|
|
27
25
|
installed: boolean;
|
|
28
26
|
version?: string;
|
|
29
|
-
reason?: string;
|
|
30
27
|
}
|
|
31
28
|
|
|
32
29
|
interface CliCheck {
|
|
@@ -46,7 +43,7 @@ interface DoctorOutput {
|
|
|
46
43
|
packageManager: string;
|
|
47
44
|
};
|
|
48
45
|
checks: {
|
|
49
|
-
|
|
46
|
+
agentTools: {
|
|
50
47
|
total: number;
|
|
51
48
|
installed: number;
|
|
52
49
|
items: CheckResult[];
|
|
@@ -56,26 +53,15 @@ interface DoctorOutput {
|
|
|
56
53
|
available: number;
|
|
57
54
|
items: CliCheck[];
|
|
58
55
|
};
|
|
59
|
-
nativeBinaries: {
|
|
60
|
-
status: 'native' | 'cli-mode';
|
|
61
|
-
reason?: string;
|
|
62
|
-
};
|
|
63
|
-
config: {
|
|
64
|
-
exists: boolean;
|
|
65
|
-
path?: string;
|
|
66
|
-
optimizations: string[];
|
|
67
|
-
};
|
|
68
56
|
};
|
|
69
57
|
actionItems: {
|
|
70
|
-
priority: '
|
|
58
|
+
priority: 'high' | 'medium' | 'low';
|
|
71
59
|
action: string;
|
|
72
60
|
command?: string;
|
|
73
61
|
reason: string;
|
|
74
62
|
}[];
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
cliTools: string;
|
|
78
|
-
};
|
|
63
|
+
quickInstall: string;
|
|
64
|
+
cxxflagsStatus: 'set' | 'not-set' | 'auto-fixed';
|
|
79
65
|
}
|
|
80
66
|
|
|
81
67
|
// ============================================================================
|
|
@@ -91,6 +77,18 @@ const colors = {
|
|
|
91
77
|
gray: (text: string) => `\x1b[90m${text}\x1b[0m`,
|
|
92
78
|
};
|
|
93
79
|
|
|
80
|
+
const noColors = {
|
|
81
|
+
green: (text: string) => text,
|
|
82
|
+
yellow: (text: string) => text,
|
|
83
|
+
red: (text: string) => text,
|
|
84
|
+
blue: (text: string) => text,
|
|
85
|
+
cyan: (text: string) => text,
|
|
86
|
+
gray: (text: string) => text,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const isTTY = process.stdout.isTTY;
|
|
90
|
+
const c = isTTY ? colors : noColors;
|
|
91
|
+
|
|
94
92
|
// ============================================================================
|
|
95
93
|
// Check functions
|
|
96
94
|
// ============================================================================
|
|
@@ -156,169 +154,194 @@ function checkCliTool(name: string, command: string, description: string): CliCh
|
|
|
156
154
|
return result;
|
|
157
155
|
}
|
|
158
156
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
157
|
+
// ============================================================================
|
|
158
|
+
// CXXFLAGS: Check and Auto-fix
|
|
159
|
+
// ============================================================================
|
|
160
|
+
|
|
161
|
+
function checkCxxFlags(): 'set' | 'not-set' {
|
|
162
|
+
const shellConfigs = [
|
|
163
|
+
path.join(process.env.HOME || '', '.bashrc'),
|
|
164
|
+
path.join(process.env.HOME || '', '.bash_profile'),
|
|
165
|
+
path.join(process.env.HOME || '', '.zshrc'),
|
|
166
|
+
path.join(process.env.HOME || '', '.profile'),
|
|
164
167
|
];
|
|
165
168
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
169
|
+
const pattern = 'CXXFLAGS="-std=c++20"';
|
|
170
|
+
|
|
171
|
+
for (const config of shellConfigs) {
|
|
172
|
+
if (fs.existsSync(config)) {
|
|
173
|
+
const content = fs.readFileSync(config, 'utf-8');
|
|
174
|
+
if (content.includes(pattern)) {
|
|
175
|
+
return 'set';
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return 'not-set';
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function autoFixCxxFlags(): boolean {
|
|
184
|
+
if (checkCxxFlags() === 'set') {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const exportLine = '\nexport CXXFLAGS="-std=c++20"\n';
|
|
189
|
+
const comment = '# For tree-sitter native modules (e.g., @ast-grep/napi)\n';
|
|
190
|
+
|
|
191
|
+
const bashrc = path.join(process.env.HOME || '', '.bashrc');
|
|
192
|
+
|
|
193
|
+
try {
|
|
194
|
+
// Check if bashrc exists
|
|
195
|
+
if (!fs.existsSync(bashrc)) {
|
|
196
|
+
fs.writeFileSync(bashrc, '');
|
|
197
|
+
}
|
|
174
198
|
|
|
175
|
-
const
|
|
199
|
+
const content = fs.readFileSync(bashrc, 'utf-8');
|
|
176
200
|
|
|
177
|
-
if
|
|
178
|
-
|
|
201
|
+
// Check if already set
|
|
202
|
+
if (content.includes('CXXFLAGS="-std=c++20"')) {
|
|
203
|
+
return true;
|
|
179
204
|
}
|
|
205
|
+
|
|
206
|
+
// Add to bashrc
|
|
207
|
+
fs.appendFileSync(bashrc, `\n${comment}${exportLine}`);
|
|
208
|
+
return true;
|
|
209
|
+
} catch {
|
|
210
|
+
return false;
|
|
180
211
|
}
|
|
181
|
-
|
|
182
|
-
return {
|
|
183
|
-
status: 'cli-mode',
|
|
184
|
-
reason: 'Native binaries not found (tree-sitter compilation may have failed)'
|
|
185
|
-
};
|
|
186
212
|
}
|
|
187
213
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
214
|
+
// ============================================================================
|
|
215
|
+
// Auto-install CLI tools
|
|
216
|
+
// ============================================================================
|
|
217
|
+
|
|
218
|
+
function autoInstallCliTools(tools: CliCheck[]): { success: string[]; failed: string[] } {
|
|
219
|
+
const result = { success: [] as string[], failed: [] as string[] };
|
|
193
220
|
|
|
194
|
-
for (const
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
221
|
+
for (const tool of tools) {
|
|
222
|
+
if (tool.installed) continue;
|
|
223
|
+
|
|
224
|
+
try {
|
|
225
|
+
console.log(c.cyan(` Installing ${tool.name}...`));
|
|
226
|
+
execSync(`npx -y ${tool.command} --version`, {
|
|
227
|
+
stdio: 'ignore',
|
|
228
|
+
timeout: 60000
|
|
229
|
+
});
|
|
230
|
+
result.success.push(tool.name);
|
|
231
|
+
console.log(c.green(` ✓ ${tool.name} ready`));
|
|
232
|
+
} catch {
|
|
233
|
+
result.failed.push(tool.name);
|
|
234
|
+
console.log(c.red(` ✗ ${tool.name} failed`));
|
|
208
235
|
}
|
|
209
236
|
}
|
|
210
237
|
|
|
211
|
-
return
|
|
238
|
+
return result;
|
|
212
239
|
}
|
|
213
240
|
|
|
214
241
|
// ============================================================================
|
|
215
242
|
// Main check
|
|
216
243
|
// ============================================================================
|
|
217
244
|
|
|
218
|
-
function runDoctor(): DoctorOutput {
|
|
245
|
+
function runDoctor(autoFix = false): DoctorOutput {
|
|
219
246
|
const output: DoctorOutput = {
|
|
220
247
|
status: 'ready',
|
|
221
|
-
version: '1.
|
|
248
|
+
version: '1.6.4',
|
|
222
249
|
summary: getSystemInfo(),
|
|
223
250
|
checks: {
|
|
224
|
-
|
|
251
|
+
agentTools: { total: 0, installed: 0, items: [] },
|
|
225
252
|
cliTools: { total: 0, available: 0, items: [] },
|
|
226
|
-
nativeBinaries: { status: 'cli-mode' },
|
|
227
|
-
config: { exists: false, optimizations: [] },
|
|
228
253
|
},
|
|
229
254
|
actionItems: [],
|
|
230
|
-
|
|
255
|
+
quickInstall: '',
|
|
256
|
+
cxxflagsStatus: checkCxxFlags(),
|
|
231
257
|
};
|
|
232
258
|
|
|
233
|
-
//
|
|
234
|
-
|
|
235
|
-
'
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
'
|
|
259
|
+
// Auto-fix CXXFLAGS if requested
|
|
260
|
+
if (autoFix && output.cxxflagsStatus === 'not-set') {
|
|
261
|
+
console.log(c.cyan('\n🔧 Auto-fixing C++20 configuration...\n'));
|
|
262
|
+
if (autoFixCxxFlags()) {
|
|
263
|
+
output.cxxflagsStatus = 'auto-fixed';
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Check optional agent tools
|
|
268
|
+
const agentToolsList = [
|
|
269
|
+
{ name: '@sparkleideas/agent-booster', desc: '52x faster code editing' },
|
|
270
|
+
{ name: '@sparkleideas/memory', desc: 'Vector memory for semantic search' },
|
|
244
271
|
];
|
|
245
272
|
|
|
246
|
-
output.checks.
|
|
247
|
-
output.checks.
|
|
248
|
-
output.checks.
|
|
273
|
+
output.checks.agentTools.items = agentToolsList.map(t => checkNpmPackage(t.name));
|
|
274
|
+
output.checks.agentTools.total = agentToolsList.length;
|
|
275
|
+
output.checks.agentTools.installed = output.checks.agentTools.items.filter(t => t.installed).length;
|
|
249
276
|
|
|
250
277
|
// Check CLI tools
|
|
251
|
-
const
|
|
252
|
-
{ name: 'dora', command: '@butttons/dora',
|
|
253
|
-
{ name: 'auto-cr', command: 'auto-cr-cmd',
|
|
254
|
-
{ name: '
|
|
255
|
-
{ name: '
|
|
256
|
-
{ name: 'btca', command: 'btca',
|
|
278
|
+
const cliToolsList = [
|
|
279
|
+
{ name: 'dora', command: '@butttons/dora', desc: 'SCIP-based code navigation' },
|
|
280
|
+
{ name: 'auto-cr', command: 'auto-cr-cmd', desc: 'SWC-based code review' },
|
|
281
|
+
{ name: 'scip-typescript', command: '@sourcegraph/scip-typescript', desc: 'TypeScript indexer' },
|
|
282
|
+
{ name: 'veil', command: '@ushiradineth/veil', desc: 'Code discovery' },
|
|
283
|
+
{ name: 'btca', command: 'btca', desc: 'BTC/A blockchain agent' },
|
|
257
284
|
];
|
|
258
285
|
|
|
259
|
-
output.checks.cliTools.items =
|
|
260
|
-
output.checks.cliTools.total =
|
|
286
|
+
output.checks.cliTools.items = cliToolsList.map(t => checkCliTool(t.name, t.command, t.desc));
|
|
287
|
+
output.checks.cliTools.total = cliToolsList.length;
|
|
261
288
|
output.checks.cliTools.available = output.checks.cliTools.items.filter(t => t.installed).length;
|
|
262
289
|
|
|
263
|
-
// Check native binaries
|
|
264
|
-
output.checks.nativeBinaries = checkAstGrepNative();
|
|
265
|
-
|
|
266
|
-
// Check config
|
|
267
|
-
output.checks.config = checkConfig();
|
|
268
|
-
|
|
269
290
|
// Generate action items
|
|
270
|
-
const missingDeps = output.checks.dependencies.items.filter(d => !d.installed);
|
|
271
291
|
const missingTools = output.checks.cliTools.items.filter(t => !t.installed);
|
|
292
|
+
const missingAgent = output.checks.agentTools.items.filter(t => !t.installed);
|
|
272
293
|
|
|
273
294
|
if (missingTools.length > 0) {
|
|
274
295
|
output.actionItems.push({
|
|
275
296
|
priority: 'high',
|
|
276
|
-
action: `Install
|
|
297
|
+
action: `Install CLI tools`,
|
|
277
298
|
command: missingTools.map(t => `npx -y ${t.command}`).join(' && '),
|
|
278
|
-
reason: 'CLI tools
|
|
299
|
+
reason: 'CLI tools enhance code navigation and review',
|
|
279
300
|
});
|
|
280
301
|
}
|
|
281
302
|
|
|
282
|
-
if (
|
|
283
|
-
const important = missingDeps.filter(d =>
|
|
284
|
-
['@ast-grep/napi', '@notprolands/ast-grep-mcp', '@paretools/search'].includes(d.name)
|
|
285
|
-
);
|
|
286
|
-
|
|
287
|
-
if (important.length > 0) {
|
|
288
|
-
output.actionItems.push({
|
|
289
|
-
priority: 'medium',
|
|
290
|
-
action: `Install ${important.length} important package(s)`,
|
|
291
|
-
command: important.map(d => `npm install ${d.name}`).join(' && '),
|
|
292
|
-
reason: 'These packages enable core functionality',
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
if (!output.checks.config.exists) {
|
|
303
|
+
if (missingAgent.length > 0) {
|
|
298
304
|
output.actionItems.push({
|
|
299
|
-
priority: '
|
|
300
|
-
action:
|
|
301
|
-
command:
|
|
302
|
-
reason: '
|
|
305
|
+
priority: 'medium',
|
|
306
|
+
action: `Install agent tools`,
|
|
307
|
+
command: missingAgent.map(t => `npm install ${t.name}`).join(' && '),
|
|
308
|
+
reason: 'Agent tools provide faster editing and memory',
|
|
303
309
|
});
|
|
304
310
|
}
|
|
305
311
|
|
|
306
|
-
// Generate install
|
|
307
|
-
|
|
308
|
-
|
|
312
|
+
// Generate quick install
|
|
313
|
+
const allCommands: string[] = [];
|
|
314
|
+
for (const tool of missingTools) {
|
|
315
|
+
allCommands.push(`npx -y ${tool.command}`);
|
|
309
316
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
output.installCommands.cliTools = `npx -y ${missingTools.map(t => t.command.split(' ')[0]).join(' ')}`;
|
|
317
|
+
for (const agent of missingAgent) {
|
|
318
|
+
allCommands.push(`npm install ${agent.name}`);
|
|
313
319
|
}
|
|
320
|
+
output.quickInstall = allCommands.join(' && ');
|
|
314
321
|
|
|
315
322
|
// Determine status
|
|
316
|
-
if (
|
|
323
|
+
if (missingTools.length >= 3) {
|
|
317
324
|
output.status = 'action-required';
|
|
318
|
-
} else if (
|
|
325
|
+
} else if (missingTools.length > 0 || missingAgent.length > 0) {
|
|
319
326
|
output.status = 'needs-setup';
|
|
320
327
|
}
|
|
321
328
|
|
|
329
|
+
// Auto-install if requested
|
|
330
|
+
if (autoFix && missingTools.length > 0) {
|
|
331
|
+
console.log(c.cyan('\n🔧 Auto-installing CLI tools...\n'));
|
|
332
|
+
const installResult = autoInstallCliTools(missingTools);
|
|
333
|
+
|
|
334
|
+
// Re-check after installation
|
|
335
|
+
if (installResult.success.length > 0) {
|
|
336
|
+
for (const name of installResult.success) {
|
|
337
|
+
const tool = output.checks.cliTools.items.find(t => t.name === name);
|
|
338
|
+
if (tool) tool.installed = true;
|
|
339
|
+
}
|
|
340
|
+
output.checks.cliTools.available = output.checks.cliTools.items.filter(t => t.installed).length;
|
|
341
|
+
missingTools.length; // Refresh
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
322
345
|
return output;
|
|
323
346
|
}
|
|
324
347
|
|
|
@@ -327,113 +350,93 @@ function runDoctor(): DoctorOutput {
|
|
|
327
350
|
// ============================================================================
|
|
328
351
|
|
|
329
352
|
function printDoctor(output: DoctorOutput) {
|
|
330
|
-
console.log('\n' +
|
|
331
|
-
console.log(
|
|
332
|
-
console.log(
|
|
353
|
+
console.log('\n' + c.blue('╔═══════════════════════════════════════════════════════════╗'));
|
|
354
|
+
console.log(c.blue('║') + ' 🐝 Hive Doctor v' + output.version + ' - System Check' + ' '.repeat(14) + c.blue('║'));
|
|
355
|
+
console.log(c.blue('╚═══════════════════════════════════════════════════════════╝'));
|
|
333
356
|
|
|
334
|
-
|
|
335
|
-
console.log('\n' + colors.gray('─'.repeat(55)));
|
|
357
|
+
console.log('\n' + c.gray('─'.repeat(55)));
|
|
336
358
|
console.log(` OS: ${output.summary.os}`);
|
|
337
359
|
console.log(` Node: ${output.summary.nodeVersion}`);
|
|
338
|
-
console.log(`
|
|
339
|
-
console.log(
|
|
360
|
+
console.log(` PM: ${output.summary.packageManager}`);
|
|
361
|
+
console.log(c.gray('─'.repeat(55)));
|
|
340
362
|
|
|
341
363
|
// Status
|
|
342
|
-
const statusColor = output.status === 'ready' ?
|
|
343
|
-
output.status === 'needs-setup' ?
|
|
364
|
+
const statusColor = output.status === 'ready' ? c.green :
|
|
365
|
+
output.status === 'needs-setup' ? c.yellow : c.red;
|
|
344
366
|
const statusText = output.status === 'ready' ? '✅ READY' :
|
|
345
367
|
output.status === 'needs-setup' ? '⚠️ NEEDS SETUP' : '❌ ACTION REQUIRED';
|
|
346
368
|
|
|
347
369
|
console.log('\n Status: ' + statusColor(statusText));
|
|
348
370
|
|
|
349
|
-
//
|
|
350
|
-
console.log('\n
|
|
351
|
-
for (const
|
|
352
|
-
const icon =
|
|
353
|
-
const version =
|
|
354
|
-
console.log(` ${icon} ${
|
|
371
|
+
// Agent tools
|
|
372
|
+
console.log('\n🚀 Agent Tools (' + output.checks.agentTools.installed + '/' + output.checks.agentTools.total + ')');
|
|
373
|
+
for (const tool of output.checks.agentTools.items) {
|
|
374
|
+
const icon = tool.installed ? c.green('✅') : c.yellow('○');
|
|
375
|
+
const version = tool.version ? c.gray(`v${tool.version}`) : c.red('not installed');
|
|
376
|
+
console.log(` ${icon} ${tool.name} ${version}`);
|
|
355
377
|
}
|
|
356
378
|
|
|
357
|
-
// CLI
|
|
379
|
+
// CLI tools
|
|
358
380
|
console.log('\n🔧 CLI Tools (' + output.checks.cliTools.available + '/' + output.checks.cliTools.total + ')');
|
|
359
381
|
for (const tool of output.checks.cliTools.items) {
|
|
360
|
-
const icon = tool.installed ?
|
|
361
|
-
const version = tool.version ?
|
|
382
|
+
const icon = tool.installed ? c.green('✅') : c.yellow('○');
|
|
383
|
+
const version = tool.version ? c.gray(`(${tool.version})`) : c.red('not available');
|
|
362
384
|
console.log(` ${icon} ${tool.name} - ${tool.description} ${version}`);
|
|
363
385
|
}
|
|
364
386
|
|
|
365
|
-
//
|
|
366
|
-
console.log('\n
|
|
367
|
-
if (output.checks.nativeBinaries.status === 'native') {
|
|
368
|
-
console.log(' ' + colors.green('✅ Native mode (fastest)'));
|
|
369
|
-
} else {
|
|
370
|
-
console.log(' ' + colors.yellow('○ CLI mode (falls back via npx)'));
|
|
371
|
-
if (output.checks.nativeBinaries.reason) {
|
|
372
|
-
console.log(' ' + colors.gray(output.checks.nativeBinaries.reason));
|
|
373
|
-
}
|
|
374
|
-
}
|
|
387
|
+
// Note about MCPs
|
|
388
|
+
console.log('\n📦 MCPs: ' + c.gray('Auto-installed with plugin'));
|
|
375
389
|
|
|
376
|
-
//
|
|
377
|
-
console.log('\n
|
|
378
|
-
if (output.
|
|
379
|
-
console.log(' ' +
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
}
|
|
390
|
+
// C++20 status
|
|
391
|
+
console.log('\n⚡ C++20 for native modules:');
|
|
392
|
+
if (output.cxxflagsStatus === 'set') {
|
|
393
|
+
console.log(' ' + c.green('✓ Already configured in shell'));
|
|
394
|
+
} else if (output.cxxflagsStatus === 'auto-fixed') {
|
|
395
|
+
console.log(' ' + c.green('✓ Auto-configured! (run "source ~/.bashrc" or restart terminal)'));
|
|
383
396
|
} else {
|
|
384
|
-
console.log(' ' +
|
|
397
|
+
console.log(' ' + c.yellow('○ Not set (needed for @ast-grep/napi)'));
|
|
398
|
+
console.log(' ' + c.gray(' Run with --fix to auto-configure'));
|
|
385
399
|
}
|
|
386
400
|
|
|
387
401
|
// Action items
|
|
388
402
|
if (output.actionItems.length > 0) {
|
|
389
|
-
console.log('\n' +
|
|
390
|
-
console.log('📋 Action Items\n');
|
|
403
|
+
console.log('\n' + c.gray('─'.repeat(55)));
|
|
404
|
+
console.log('\n📋 Action Items\n');
|
|
391
405
|
|
|
392
406
|
for (const item of output.actionItems) {
|
|
393
|
-
const priorityColor = item.priority === '
|
|
394
|
-
item.priority === '
|
|
395
|
-
item.priority === 'medium' ? colors.blue : colors.gray;
|
|
407
|
+
const priorityColor = item.priority === 'high' ? c.red :
|
|
408
|
+
item.priority === 'medium' ? c.yellow : c.gray;
|
|
396
409
|
|
|
397
410
|
console.log(` [${priorityColor(item.priority.toUpperCase())}] ${item.action}`);
|
|
398
|
-
console.log(` ${
|
|
411
|
+
console.log(` ${c.gray(item.reason)}`);
|
|
399
412
|
if (item.command) {
|
|
400
|
-
console.log(` ${
|
|
413
|
+
console.log(` ${c.green(item.command)}`);
|
|
401
414
|
}
|
|
402
415
|
console.log();
|
|
403
416
|
}
|
|
404
417
|
}
|
|
405
418
|
|
|
406
419
|
// Quick install
|
|
407
|
-
if (output.
|
|
408
|
-
console.log(
|
|
420
|
+
if (output.quickInstall) {
|
|
421
|
+
console.log(c.gray('─'.repeat(55)));
|
|
409
422
|
console.log('\n🚀 Quick Install\n');
|
|
410
|
-
|
|
411
|
-
if (output.installCommands.deps) {
|
|
412
|
-
console.log(' ' + colors.cyan('Dependencies:'));
|
|
413
|
-
console.log(' ' + colors.green(output.installCommands.deps));
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
if (output.installCommands.cliTools) {
|
|
417
|
-
console.log('\n ' + colors.cyan('CLI Tools:'));
|
|
418
|
-
console.log(' ' + colors.green(output.installCommands.cliTools));
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
// Note about C++20 for native modules
|
|
422
|
-
console.log('\n' + colors.yellow('💡 Tip: ') + colors.gray('If @ast-grep/napi fails to build, try:'));
|
|
423
|
-
console.log(' ' + colors.green('export CXXFLAGS="-std=c++20" && npm install'));
|
|
423
|
+
console.log(' ' + c.green(output.quickInstall));
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
-
console.log('\n' +
|
|
427
|
-
console.log(
|
|
428
|
-
console.log(
|
|
426
|
+
console.log('\n' + c.blue('═'.repeat(55)));
|
|
427
|
+
console.log(c.gray(' bunx @hung319/opencode-hive doctor'));
|
|
428
|
+
console.log(c.gray(' bunx @hung319/opencode-hive doctor --fix'));
|
|
429
|
+
console.log(c.blue('═'.repeat(55)) + '\n');
|
|
429
430
|
}
|
|
430
431
|
|
|
431
432
|
// ============================================================================
|
|
432
433
|
// Main
|
|
433
434
|
// ============================================================================
|
|
434
435
|
|
|
435
|
-
const
|
|
436
|
+
const args = process.argv.slice(2);
|
|
437
|
+
const autoFix = args.includes('--fix') || args.includes('-f');
|
|
438
|
+
|
|
439
|
+
const output = runDoctor(autoFix);
|
|
436
440
|
printDoctor(output);
|
|
437
441
|
|
|
438
|
-
// Exit with appropriate code
|
|
439
442
|
process.exit(output.status === 'ready' ? 0 : 1);
|
package/dist/index.js
CHANGED
|
@@ -17811,7 +17811,6 @@ import * as path6 from "path";
|
|
|
17811
17811
|
async function checkPackage(packageName) {
|
|
17812
17812
|
const result = {
|
|
17813
17813
|
name: packageName,
|
|
17814
|
-
package: packageName,
|
|
17815
17814
|
installed: false
|
|
17816
17815
|
};
|
|
17817
17816
|
try {
|
|
@@ -17846,183 +17845,126 @@ function checkCliTool(name, command, description) {
|
|
|
17846
17845
|
}
|
|
17847
17846
|
return result;
|
|
17848
17847
|
}
|
|
17849
|
-
function
|
|
17850
|
-
const
|
|
17851
|
-
|
|
17852
|
-
path6.join(process.env.HOME || "", ".
|
|
17853
|
-
path6.join(process.env.HOME || "", ".config/opencode/agent_hive.jsonc")
|
|
17848
|
+
function checkCxxFlags() {
|
|
17849
|
+
const configs = [
|
|
17850
|
+
path6.join(process.env.HOME || "", ".bashrc"),
|
|
17851
|
+
path6.join(process.env.HOME || "", ".zshrc")
|
|
17854
17852
|
];
|
|
17855
|
-
|
|
17856
|
-
|
|
17857
|
-
|
|
17858
|
-
|
|
17859
|
-
|
|
17860
|
-
|
|
17861
|
-
break;
|
|
17862
|
-
} catch {}
|
|
17853
|
+
for (const config2 of configs) {
|
|
17854
|
+
if (fs5.existsSync(config2)) {
|
|
17855
|
+
const content = fs5.readFileSync(config2, "utf-8");
|
|
17856
|
+
if (content.includes('CXXFLAGS="-std=c++20"')) {
|
|
17857
|
+
return "set";
|
|
17858
|
+
}
|
|
17863
17859
|
}
|
|
17864
17860
|
}
|
|
17865
|
-
|
|
17866
|
-
checks3.push({
|
|
17867
|
-
name: "snip",
|
|
17868
|
-
enabled: snipEnabled,
|
|
17869
|
-
value: config2?.snip,
|
|
17870
|
-
recommendation: snipEnabled ? "snip enabled for 60-90% token reduction" : 'Enable snip: Add { "snip": { "enabled": true } } to config'
|
|
17871
|
-
});
|
|
17872
|
-
const vectorEnabled = config2?.vectorMemory?.enabled === true;
|
|
17873
|
-
checks3.push({
|
|
17874
|
-
name: "vectorMemory",
|
|
17875
|
-
enabled: vectorEnabled,
|
|
17876
|
-
value: config2?.vectorMemory,
|
|
17877
|
-
recommendation: vectorEnabled ? "Vector memory enabled for semantic search" : 'Enable vector memory: Add { "vectorMemory": { "enabled": true } } to config'
|
|
17878
|
-
});
|
|
17879
|
-
const boosterEnabled = config2?.agentBooster?.enabled !== false;
|
|
17880
|
-
checks3.push({
|
|
17881
|
-
name: "agentBooster",
|
|
17882
|
-
enabled: boosterEnabled,
|
|
17883
|
-
value: config2?.agentBooster,
|
|
17884
|
-
recommendation: boosterEnabled ? "Agent booster enabled for 52x faster editing" : 'Agent booster disabled: Set { "agentBooster": { "enabled": true } } to enable'
|
|
17885
|
-
});
|
|
17886
|
-
const sandboxMode = config2?.sandbox?.mode || "none";
|
|
17887
|
-
const sandboxEnabled = sandboxMode !== "none";
|
|
17888
|
-
checks3.push({
|
|
17889
|
-
name: "sandbox",
|
|
17890
|
-
enabled: sandboxEnabled,
|
|
17891
|
-
value: sandboxMode,
|
|
17892
|
-
recommendation: sandboxEnabled ? `Sandbox enabled (${sandboxMode} mode)` : 'Enable sandbox: Add { "sandbox": { "mode": "docker" } } to config for isolated testing'
|
|
17893
|
-
});
|
|
17894
|
-
const disabledMcps = config2?.disableMcps || [];
|
|
17895
|
-
checks3.push({
|
|
17896
|
-
name: "veil MCP",
|
|
17897
|
-
enabled: !disabledMcps.includes("veil"),
|
|
17898
|
-
recommendation: !disabledMcps.includes("veil") ? "veil MCP enabled" : 'Enable veil: Remove "veil" from disableMcps array'
|
|
17899
|
-
});
|
|
17900
|
-
checks3.push({
|
|
17901
|
-
name: "pare_search MCP",
|
|
17902
|
-
enabled: !disabledMcps.includes("pare_search"),
|
|
17903
|
-
recommendation: !disabledMcps.includes("pare_search") ? "pare_search MCP enabled" : 'Enable pare_search: Remove "pare_search" from disableMcps array'
|
|
17904
|
-
});
|
|
17905
|
-
return checks3;
|
|
17861
|
+
return "not-set";
|
|
17906
17862
|
}
|
|
17907
17863
|
var hiveDoctorTool = tool({
|
|
17908
|
-
description: `Hive Doctor - System health check
|
|
17864
|
+
description: `Hive Doctor - System health check for Hive plugin.
|
|
17909
17865
|
|
|
17910
|
-
**Checks
|
|
17911
|
-
1.
|
|
17912
|
-
2. CLI Tools
|
|
17913
|
-
3.
|
|
17866
|
+
**Checks:**
|
|
17867
|
+
1. Agent Tools (optional): agent-booster, memory
|
|
17868
|
+
2. CLI Tools (optional): dora, auto-cr, scip-typescript, veil, btca
|
|
17869
|
+
3. C++20 config: For @ast-grep/napi native modules
|
|
17914
17870
|
|
|
17915
|
-
**
|
|
17916
|
-
-
|
|
17917
|
-
-
|
|
17918
|
-
-
|
|
17919
|
-
- Quick install commands for all missing items
|
|
17871
|
+
**Status:**
|
|
17872
|
+
- ready: All good
|
|
17873
|
+
- needs-setup: Some optional tools missing
|
|
17874
|
+
- action-required: Multiple tools missing
|
|
17920
17875
|
|
|
17921
|
-
**Tip:** Run standalone
|
|
17876
|
+
**Tip:** Run standalone for auto-fix: \`bunx @hung319/opencode-hive doctor --fix\``,
|
|
17922
17877
|
args: {},
|
|
17923
17878
|
async execute() {
|
|
17924
|
-
const
|
|
17879
|
+
const result = {
|
|
17880
|
+
status: "ready",
|
|
17881
|
+
version: "1.6.4",
|
|
17882
|
+
checks: {
|
|
17883
|
+
agentTools: { total: 0, installed: 0, items: [] },
|
|
17884
|
+
cliTools: { total: 0, available: 0, items: [] }
|
|
17885
|
+
},
|
|
17886
|
+
cxxflagsStatus: checkCxxFlags(),
|
|
17887
|
+
actionItems: [],
|
|
17888
|
+
quickInstall: ""
|
|
17889
|
+
};
|
|
17890
|
+
const agentTools = await Promise.all([
|
|
17925
17891
|
checkPackage("@sparkleideas/agent-booster"),
|
|
17926
|
-
checkPackage("@sparkleideas/memory")
|
|
17927
|
-
checkPackage("@paretools/search"),
|
|
17928
|
-
checkPackage("@upstash/context7-mcp"),
|
|
17929
|
-
checkPackage("exa-mcp-server"),
|
|
17930
|
-
checkPackage("grep-mcp"),
|
|
17931
|
-
checkPackage("btca"),
|
|
17932
|
-
checkPackage("opencode-model-selector")
|
|
17892
|
+
checkPackage("@sparkleideas/memory")
|
|
17933
17893
|
]);
|
|
17934
|
-
|
|
17894
|
+
result.checks.agentTools.items = agentTools;
|
|
17895
|
+
result.checks.agentTools.total = agentTools.length;
|
|
17896
|
+
result.checks.agentTools.installed = agentTools.filter((t) => t.installed).length;
|
|
17897
|
+
const cliTools = [
|
|
17935
17898
|
checkCliTool("dora", "@butttons/dora", "SCIP-based code navigation"),
|
|
17936
|
-
checkCliTool("auto-cr", "auto-cr-cmd", "SWC-based
|
|
17937
|
-
checkCliTool("scip-typescript", "@sourcegraph/scip-typescript", "TypeScript
|
|
17938
|
-
checkCliTool("veil", "@ushiradineth/veil", "Code discovery
|
|
17939
|
-
checkCliTool("btca", "btca", "BTC/A
|
|
17899
|
+
checkCliTool("auto-cr", "auto-cr-cmd", "SWC-based code review"),
|
|
17900
|
+
checkCliTool("scip-typescript", "@sourcegraph/scip-typescript", "TypeScript indexer"),
|
|
17901
|
+
checkCliTool("veil", "@ushiradineth/veil", "Code discovery"),
|
|
17902
|
+
checkCliTool("btca", "btca", "BTC/A blockchain agent")
|
|
17940
17903
|
];
|
|
17941
|
-
|
|
17942
|
-
|
|
17943
|
-
|
|
17944
|
-
const
|
|
17945
|
-
|
|
17946
|
-
if (missingTools.length
|
|
17947
|
-
|
|
17948
|
-
} else if (missingTools.length >= 1 || missingDeps.length >= 1 || disabledConfigs.length >= 2) {
|
|
17949
|
-
status = "warning";
|
|
17950
|
-
}
|
|
17951
|
-
const actionItems = [];
|
|
17952
|
-
for (const tool3 of missingTools) {
|
|
17953
|
-
actionItems.push({
|
|
17904
|
+
result.checks.cliTools.items = cliTools;
|
|
17905
|
+
result.checks.cliTools.total = cliTools.length;
|
|
17906
|
+
result.checks.cliTools.available = cliTools.filter((t) => t.installed).length;
|
|
17907
|
+
const missingTools = cliTools.filter((t) => !t.installed);
|
|
17908
|
+
const missingAgent = agentTools.filter((t) => !t.installed);
|
|
17909
|
+
if (missingTools.length > 0) {
|
|
17910
|
+
result.actionItems.push({
|
|
17954
17911
|
priority: "high",
|
|
17955
|
-
action:
|
|
17956
|
-
command: `npx -y ${
|
|
17957
|
-
reason:
|
|
17912
|
+
action: "Install CLI tools",
|
|
17913
|
+
command: missingTools.map((t) => `npx -y ${t.command}`).join(" && "),
|
|
17914
|
+
reason: "CLI tools enhance code navigation and review"
|
|
17958
17915
|
});
|
|
17959
17916
|
}
|
|
17960
|
-
if (
|
|
17961
|
-
actionItems.push({
|
|
17917
|
+
if (missingAgent.length > 0) {
|
|
17918
|
+
result.actionItems.push({
|
|
17962
17919
|
priority: "medium",
|
|
17963
|
-
action: "Install
|
|
17964
|
-
command: `npm install
|
|
17965
|
-
reason: "
|
|
17920
|
+
action: "Install agent tools",
|
|
17921
|
+
command: missingAgent.map((t) => `npm install ${t.name}`).join(" && "),
|
|
17922
|
+
reason: "Agent tools provide faster editing and memory"
|
|
17966
17923
|
});
|
|
17967
17924
|
}
|
|
17968
|
-
|
|
17969
|
-
actionItems.push({
|
|
17925
|
+
if (result.cxxflagsStatus === "not-set") {
|
|
17926
|
+
result.actionItems.push({
|
|
17970
17927
|
priority: "low",
|
|
17971
|
-
action:
|
|
17972
|
-
|
|
17928
|
+
action: "Enable C++20 for native modules",
|
|
17929
|
+
command: `echo 'export CXXFLAGS="-std=c++20"' >> ~/.bashrc`,
|
|
17930
|
+
reason: "Required for @ast-grep/napi tree-sitter build"
|
|
17973
17931
|
});
|
|
17974
17932
|
}
|
|
17975
|
-
const
|
|
17976
|
-
|
|
17977
|
-
|
|
17978
|
-
}
|
|
17979
|
-
const
|
|
17980
|
-
|
|
17981
|
-
|
|
17982
|
-
|
|
17983
|
-
|
|
17984
|
-
|
|
17985
|
-
|
|
17986
|
-
|
|
17987
|
-
|
|
17988
|
-
dependencies: {
|
|
17989
|
-
total: dependencyChecks.length,
|
|
17990
|
-
installed: dependencyChecks.filter((d) => d.installed).length,
|
|
17991
|
-
missing: missingDeps
|
|
17992
|
-
},
|
|
17993
|
-
cliTools: {
|
|
17994
|
-
total: cliToolChecks.length,
|
|
17995
|
-
available: cliToolChecks.filter((t) => t.installed).length,
|
|
17996
|
-
missing: missingTools
|
|
17997
|
-
},
|
|
17998
|
-
config: configChecks
|
|
17999
|
-
},
|
|
18000
|
-
actionItems,
|
|
18001
|
-
quickInstall
|
|
18002
|
-
};
|
|
17933
|
+
const allCommands = [];
|
|
17934
|
+
for (const tool3 of missingTools) {
|
|
17935
|
+
allCommands.push(`npx -y ${tool3.command}`);
|
|
17936
|
+
}
|
|
17937
|
+
for (const agent of missingAgent) {
|
|
17938
|
+
allCommands.push(`npm install ${agent.name}`);
|
|
17939
|
+
}
|
|
17940
|
+
result.quickInstall = allCommands.join(" && ");
|
|
17941
|
+
if (missingTools.length >= 3) {
|
|
17942
|
+
result.status = "action-required";
|
|
17943
|
+
} else if (missingTools.length > 0 || missingAgent.length > 0) {
|
|
17944
|
+
result.status = "needs-setup";
|
|
17945
|
+
}
|
|
18003
17946
|
return JSON.stringify(result, null, 2);
|
|
18004
17947
|
}
|
|
18005
17948
|
});
|
|
18006
17949
|
var hiveDoctorQuickTool = tool({
|
|
18007
|
-
description: `Quick health status - shows summary
|
|
17950
|
+
description: `Quick health status - shows summary only.
|
|
18008
17951
|
|
|
18009
17952
|
**Returns:**
|
|
18010
|
-
-
|
|
18011
|
-
-
|
|
18012
|
-
- action-required: Multiple
|
|
17953
|
+
- ready: All optional tools installed
|
|
17954
|
+
- needs-setup: Some tools missing (recommended)
|
|
17955
|
+
- action-required: Multiple tools missing`,
|
|
18013
17956
|
args: {},
|
|
18014
17957
|
async execute() {
|
|
18015
17958
|
const checks3 = await Promise.all([
|
|
18016
17959
|
checkPackage("@sparkleideas/agent-booster"),
|
|
18017
|
-
checkPackage("btca"),
|
|
18018
17960
|
checkCliTool("dora", "@butttons/dora", ""),
|
|
18019
17961
|
checkCliTool("auto-cr", "auto-cr-cmd", "")
|
|
18020
17962
|
]);
|
|
18021
17963
|
const missing = checks3.filter((c) => !c.installed).length;
|
|
18022
17964
|
return JSON.stringify({
|
|
18023
|
-
status: missing === 0 ? "
|
|
17965
|
+
status: missing === 0 ? "ready" : missing >= 2 ? "action-required" : "needs-setup",
|
|
18024
17966
|
missingCount: missing,
|
|
18025
|
-
|
|
17967
|
+
autoFix: "Run standalone: bunx @hung319/opencode-hive doctor --fix"
|
|
18026
17968
|
}, null, 2);
|
|
18027
17969
|
}
|
|
18028
17970
|
});
|