@hung319/opencode-hive 1.6.2 → 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.
Files changed (4) hide show
  1. package/README.md +72 -39
  2. package/bin/doctor.ts +194 -186
  3. package/dist/index.js +81 -139
  4. 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. **Dependencies** - npm packages installed?
549
- - Core: `@ast-grep/napi`
550
- - Agent: `@sparkleideas/agent-booster`, `@sparkleideas/memory`
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** - npx tools available?
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 (from npmx.dev)
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
- 3. **Config** - Features enabled?
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
- ```json
569
- {
570
- "status": "warning",
571
- "summary": {
572
- "dependencies": "⚠️ 2 missing: agent-booster, memory",
573
- "cliTools": "⚠️ 1 missing: auto-cr",
574
- "config": "💡 2 disabled: snip, vectorMemory"
575
- },
576
- "actionItems": [
577
- {
578
- "priority": "high",
579
- "action": "Install auto-cr",
580
- "command": "npx -y auto-cr-cmd",
581
- "reason": "SWC-based automated code review"
582
- },
583
- {
584
- "priority": "medium",
585
- "action": "Install agent-booster",
586
- "command": "npm install @sparkleideas/agent-booster",
587
- "reason": "52x faster code editing"
588
- }
589
- ],
590
- "quickInstall": {
591
- "deps": ["@sparkleideas/agent-booster", "@sparkleideas/memory"],
592
- "cliTools": ["auto-cr-cmd"]
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
- * Or install and run:
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
- dependencies: {
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: 'critical' | 'high' | 'medium' | 'low';
58
+ priority: 'high' | 'medium' | 'low';
71
59
  action: string;
72
60
  command?: string;
73
61
  reason: string;
74
62
  }[];
75
- installCommands: {
76
- deps: string;
77
- cliTools: string;
78
- };
63
+ quickInstall: string;
64
+ cxxflagsStatus: 'set' | 'not-set' | 'auto-fixed';
79
65
  }
80
66
 
81
67
  // ============================================================================
@@ -87,9 +73,22 @@ const colors = {
87
73
  yellow: (text: string) => `\x1b[33m${text}\x1b[0m`,
88
74
  red: (text: string) => `\x1b[31m${text}\x1b[0m`,
89
75
  blue: (text: string) => `\x1b[34m${text}\x1b[0m`,
76
+ cyan: (text: string) => `\x1b[36m${text}\x1b[0m`,
90
77
  gray: (text: string) => `\x1b[90m${text}\x1b[0m`,
91
78
  };
92
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
+
93
92
  // ============================================================================
94
93
  // Check functions
95
94
  // ============================================================================
@@ -155,169 +154,194 @@ function checkCliTool(name: string, command: string, description: string): CliCh
155
154
  return result;
156
155
  }
157
156
 
158
- function checkAstGrepNative(): { status: 'native' | 'cli-mode'; reason?: string } {
159
- // Check if @ast-grep/napi package exists with native binaries
160
- const napiDirs = [
161
- path.join(process.cwd(), 'node_modules/@ast-grep/napi'),
162
- path.join(process.env.HOME || '', '.npm-global/lib/node_modules/@ast-grep/napi'),
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'),
163
167
  ];
164
168
 
165
- for (const napiDir of napiDirs) {
166
- if (!fs.existsSync(napiDir)) continue;
167
-
168
- const binaryPaths = [
169
- path.join(napiDir, 'index.node'),
170
- path.join(napiDir, 'build/Release/ast_grep.node'),
171
- path.join(napiDir, 'dist/index.node'),
172
- ];
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
+ }
173
198
 
174
- const hasBinary = binaryPaths.some(p => fs.existsSync(p));
199
+ const content = fs.readFileSync(bashrc, 'utf-8');
175
200
 
176
- if (hasBinary) {
177
- return { status: 'native' };
201
+ // Check if already set
202
+ if (content.includes('CXXFLAGS="-std=c++20"')) {
203
+ return true;
178
204
  }
205
+
206
+ // Add to bashrc
207
+ fs.appendFileSync(bashrc, `\n${comment}${exportLine}`);
208
+ return true;
209
+ } catch {
210
+ return false;
179
211
  }
180
-
181
- return {
182
- status: 'cli-mode',
183
- reason: 'Native binaries not found (tree-sitter compilation may have failed)'
184
- };
185
212
  }
186
213
 
187
- function checkConfig(): { exists: boolean; path?: string; optimizations: string[] } {
188
- const configPaths = [
189
- path.join(process.env.HOME || '', '.config/opencode/agent_hive.json'),
190
- path.join(process.env.HOME || '', '.config/opencode/agent_hive.jsonc'),
191
- ];
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[] };
192
220
 
193
- for (const configPath of configPaths) {
194
- if (fs.existsSync(configPath)) {
195
- try {
196
- const content = fs.readFileSync(configPath, 'utf-8');
197
- const config = JSON.parse(content.replace(/\\/g, ''));
198
- const optimizations: string[] = [];
199
-
200
- if (config.snip?.enabled) optimizations.push('snip');
201
- if (config.vectorMemory?.enabled) optimizations.push('vectorMemory');
202
- if (config.agentBooster?.enabled !== false) optimizations.push('agentBooster');
203
- if (config.sandbox?.mode !== 'none') optimizations.push('sandbox');
204
-
205
- return { exists: true, path: configPath, optimizations };
206
- } catch {}
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`));
207
235
  }
208
236
  }
209
237
 
210
- return { exists: false, optimizations: [] };
238
+ return result;
211
239
  }
212
240
 
213
241
  // ============================================================================
214
242
  // Main check
215
243
  // ============================================================================
216
244
 
217
- function runDoctor(): DoctorOutput {
245
+ function runDoctor(autoFix = false): DoctorOutput {
218
246
  const output: DoctorOutput = {
219
247
  status: 'ready',
220
- version: '1.5.8',
248
+ version: '1.6.4',
221
249
  summary: getSystemInfo(),
222
250
  checks: {
223
- dependencies: { total: 0, installed: 0, items: [] },
251
+ agentTools: { total: 0, installed: 0, items: [] },
224
252
  cliTools: { total: 0, available: 0, items: [] },
225
- nativeBinaries: { status: 'cli-mode' },
226
- config: { exists: false, optimizations: [] },
227
253
  },
228
254
  actionItems: [],
229
- installCommands: { deps: '', cliTools: '' },
255
+ quickInstall: '',
256
+ cxxflagsStatus: checkCxxFlags(),
230
257
  };
231
258
 
232
- // Check dependencies
233
- const deps = [
234
- '@ast-grep/napi',
235
- '@sparkleideas/agent-booster',
236
- '@sparkleideas/memory',
237
- '@paretools/search',
238
- '@upstash/context7-mcp',
239
- 'exa-mcp-server',
240
- 'grep-mcp',
241
- 'btca',
242
- 'opencode-model-selector',
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' },
243
271
  ];
244
272
 
245
- output.checks.dependencies.items = deps.map(d => checkNpmPackage(d));
246
- output.checks.dependencies.total = deps.length;
247
- output.checks.dependencies.installed = output.checks.dependencies.items.filter(d => d.installed).length;
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;
248
276
 
249
277
  // Check CLI tools
250
- const cliTools = [
251
- { name: 'dora', command: '@butttons/dora', description: 'SCIP-based code navigation' },
252
- { name: 'auto-cr', command: 'auto-cr-cmd', description: 'SWC-based automated code review' },
253
- { name: 'veil', command: '@ushiradineth/veil', description: 'Code discovery and retrieval' },
254
- { name: 'scip-typescript', command: '@sourcegraph/scip-typescript', description: 'TypeScript SCIP indexer' },
255
- { name: 'btca', command: 'btca', description: 'BTC/A agent for blockchain tasks' },
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' },
256
284
  ];
257
285
 
258
- output.checks.cliTools.items = cliTools.map(t => checkCliTool(t.name, t.command, t.description));
259
- output.checks.cliTools.total = cliTools.length;
286
+ output.checks.cliTools.items = cliToolsList.map(t => checkCliTool(t.name, t.command, t.desc));
287
+ output.checks.cliTools.total = cliToolsList.length;
260
288
  output.checks.cliTools.available = output.checks.cliTools.items.filter(t => t.installed).length;
261
289
 
262
- // Check native binaries
263
- output.checks.nativeBinaries = checkAstGrepNative();
264
-
265
- // Check config
266
- output.checks.config = checkConfig();
267
-
268
290
  // Generate action items
269
- const missingDeps = output.checks.dependencies.items.filter(d => !d.installed);
270
291
  const missingTools = output.checks.cliTools.items.filter(t => !t.installed);
292
+ const missingAgent = output.checks.agentTools.items.filter(t => !t.installed);
271
293
 
272
294
  if (missingTools.length > 0) {
273
295
  output.actionItems.push({
274
296
  priority: 'high',
275
- action: `Install ${missingTools.length} CLI tool(s)`,
297
+ action: `Install CLI tools`,
276
298
  command: missingTools.map(t => `npx -y ${t.command}`).join(' && '),
277
- reason: 'CLI tools provide code navigation, review, and analysis features',
299
+ reason: 'CLI tools enhance code navigation and review',
278
300
  });
279
301
  }
280
302
 
281
- if (missingDeps.length > 0) {
282
- const important = missingDeps.filter(d =>
283
- ['@ast-grep/napi', '@notprolands/ast-grep-mcp', '@paretools/search'].includes(d.name)
284
- );
285
-
286
- if (important.length > 0) {
287
- output.actionItems.push({
288
- priority: 'medium',
289
- action: `Install ${important.length} important package(s)`,
290
- command: important.map(d => `npm install ${d.name}`).join(' && '),
291
- reason: 'These packages enable core functionality',
292
- });
293
- }
294
- }
295
-
296
- if (!output.checks.config.exists) {
303
+ if (missingAgent.length > 0) {
297
304
  output.actionItems.push({
298
- priority: 'low',
299
- action: 'Create config file',
300
- command: `mkdir -p ~/.config/opencode && cat > ~/.config/opencode/agent_hive.json << 'EOF'\n{\n "snip": { "enabled": true },\n "vectorMemory": { "enabled": true }\n}\nEOF`,
301
- reason: 'Enable optimizations for better performance',
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',
302
309
  });
303
310
  }
304
311
 
305
- // Generate install commands
306
- if (missingDeps.length > 0) {
307
- output.installCommands.deps = `npm install ${missingDeps.map(d => d.name).join(' ')}`;
312
+ // Generate quick install
313
+ const allCommands: string[] = [];
314
+ for (const tool of missingTools) {
315
+ allCommands.push(`npx -y ${tool.command}`);
308
316
  }
309
-
310
- if (missingTools.length > 0) {
311
- 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}`);
312
319
  }
320
+ output.quickInstall = allCommands.join(' && ');
313
321
 
314
322
  // Determine status
315
- if (output.actionItems.some(a => a.priority === 'critical')) {
323
+ if (missingTools.length >= 3) {
316
324
  output.status = 'action-required';
317
- } else if (output.actionItems.some(a => a.priority === 'high' || a.priority === 'medium')) {
325
+ } else if (missingTools.length > 0 || missingAgent.length > 0) {
318
326
  output.status = 'needs-setup';
319
327
  }
320
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
+
321
345
  return output;
322
346
  }
323
347
 
@@ -326,109 +350,93 @@ function runDoctor(): DoctorOutput {
326
350
  // ============================================================================
327
351
 
328
352
  function printDoctor(output: DoctorOutput) {
329
- console.log('\n' + colors.blue('╔═══════════════════════════════════════════════════════════╗'));
330
- console.log(colors.blue('║') + ' 🐝 Hive Doctor v' + output.version + ' - System Check' + ' '.repeat(14) + colors.blue('║'));
331
- console.log(colors.blue('╚═══════════════════════════════════════════════════════════╝'));
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('╚═══════════════════════════════════════════════════════════╝'));
332
356
 
333
- // Summary
334
- console.log('\n' + colors.gray('─'.repeat(55)));
357
+ console.log('\n' + c.gray('─'.repeat(55)));
335
358
  console.log(` OS: ${output.summary.os}`);
336
359
  console.log(` Node: ${output.summary.nodeVersion}`);
337
- console.log(` Package Manager: ${output.summary.packageManager}`);
338
- console.log(colors.gray('─'.repeat(55)));
360
+ console.log(` PM: ${output.summary.packageManager}`);
361
+ console.log(c.gray('─'.repeat(55)));
339
362
 
340
363
  // Status
341
- const statusColor = output.status === 'ready' ? colors.green :
342
- output.status === 'needs-setup' ? colors.yellow : colors.red;
364
+ const statusColor = output.status === 'ready' ? c.green :
365
+ output.status === 'needs-setup' ? c.yellow : c.red;
343
366
  const statusText = output.status === 'ready' ? '✅ READY' :
344
367
  output.status === 'needs-setup' ? '⚠️ NEEDS SETUP' : '❌ ACTION REQUIRED';
345
368
 
346
369
  console.log('\n Status: ' + statusColor(statusText));
347
370
 
348
- // Dependencies
349
- console.log('\n📦 Dependencies (' + output.checks.dependencies.installed + '/' + output.checks.dependencies.total + ')');
350
- for (const dep of output.checks.dependencies.items) {
351
- const icon = dep.installed ? colors.green('✅') : colors.yellow('○');
352
- const version = dep.version ? colors.gray(`v${dep.version}`) : colors.red('not installed');
353
- console.log(` ${icon} ${dep.name} ${version}`);
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}`);
354
377
  }
355
378
 
356
- // CLI Tools
379
+ // CLI tools
357
380
  console.log('\n🔧 CLI Tools (' + output.checks.cliTools.available + '/' + output.checks.cliTools.total + ')');
358
381
  for (const tool of output.checks.cliTools.items) {
359
- const icon = tool.installed ? colors.green('✅') : colors.yellow('○');
360
- const version = tool.version ? colors.gray(`(${tool.version})`) : colors.red('not available');
382
+ const icon = tool.installed ? c.green('✅') : c.yellow('○');
383
+ const version = tool.version ? c.gray(`(${tool.version})`) : c.red('not available');
361
384
  console.log(` ${icon} ${tool.name} - ${tool.description} ${version}`);
362
385
  }
363
386
 
364
- // Native binaries
365
- console.log('\n Native Binaries');
366
- if (output.checks.nativeBinaries.status === 'native') {
367
- console.log(' ' + colors.green('✅ Native mode (fastest)'));
368
- } else {
369
- console.log(' ' + colors.yellow('○ CLI mode (falls back via npx)'));
370
- if (output.checks.nativeBinaries.reason) {
371
- console.log(' ' + colors.gray(output.checks.nativeBinaries.reason));
372
- }
373
- }
387
+ // Note about MCPs
388
+ console.log('\n📦 MCPs: ' + c.gray('Auto-installed with plugin'));
374
389
 
375
- // Config
376
- console.log('\n⚙️ Config');
377
- if (output.checks.config.exists) {
378
- console.log(' ' + colors.green(' Config file found'));
379
- if (output.checks.config.optimizations.length > 0) {
380
- console.log(' ' + colors.gray('Optimizations: ' + output.checks.config.optimizations.join(', ')));
381
- }
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)'));
382
396
  } else {
383
- console.log(' ' + colors.yellow('○ No config file (optional)'));
397
+ console.log(' ' + c.yellow('○ Not set (needed for @ast-grep/napi)'));
398
+ console.log(' ' + c.gray(' Run with --fix to auto-configure'));
384
399
  }
385
400
 
386
401
  // Action items
387
402
  if (output.actionItems.length > 0) {
388
- console.log('\n' + colors.gray('─'.repeat(55)));
389
- console.log('📋 Action Items\n');
403
+ console.log('\n' + c.gray('─'.repeat(55)));
404
+ console.log('\n📋 Action Items\n');
390
405
 
391
406
  for (const item of output.actionItems) {
392
- const priorityColor = item.priority === 'critical' ? colors.red :
393
- item.priority === 'high' ? colors.yellow :
394
- item.priority === 'medium' ? colors.blue : colors.gray;
407
+ const priorityColor = item.priority === 'high' ? c.red :
408
+ item.priority === 'medium' ? c.yellow : c.gray;
395
409
 
396
410
  console.log(` [${priorityColor(item.priority.toUpperCase())}] ${item.action}`);
397
- console.log(` ${colors.gray(item.reason)}`);
411
+ console.log(` ${c.gray(item.reason)}`);
398
412
  if (item.command) {
399
- console.log(` ${colors.green(item.command)}`);
413
+ console.log(` ${c.green(item.command)}`);
400
414
  }
401
415
  console.log();
402
416
  }
403
417
  }
404
418
 
405
419
  // Quick install
406
- if (output.installCommands.deps || output.installCommands.cliTools) {
407
- console.log(colors.gray('─'.repeat(55)));
420
+ if (output.quickInstall) {
421
+ console.log(c.gray('─'.repeat(55)));
408
422
  console.log('\n🚀 Quick Install\n');
409
-
410
- if (output.installCommands.deps) {
411
- console.log(' ' + colors.cyan('Dependencies:'));
412
- console.log(' ' + colors.green(output.installCommands.deps));
413
- }
414
-
415
- if (output.installCommands.cliTools) {
416
- console.log('\n ' + colors.cyan('CLI Tools:'));
417
- console.log(' ' + colors.green(output.installCommands.cliTools));
418
- }
423
+ console.log(' ' + c.green(output.quickInstall));
419
424
  }
420
425
 
421
- console.log('\n' + colors.blue('═'.repeat(55)));
422
- console.log(colors.gray(' Run with: bunx @hung319/opencode-hive doctor'));
423
- console.log(colors.blue('═'.repeat(55)) + '\n');
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');
424
430
  }
425
431
 
426
432
  // ============================================================================
427
433
  // Main
428
434
  // ============================================================================
429
435
 
430
- const output = runDoctor();
436
+ const args = process.argv.slice(2);
437
+ const autoFix = args.includes('--fix') || args.includes('-f');
438
+
439
+ const output = runDoctor(autoFix);
431
440
  printDoctor(output);
432
441
 
433
- // Exit with appropriate code
434
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 checkConfig() {
17850
- const checks3 = [];
17851
- const configPaths = [
17852
- path6.join(process.env.HOME || "", ".config/opencode/agent_hive.json"),
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
- let config2 = null;
17856
- for (const configPath of configPaths) {
17857
- if (fs5.existsSync(configPath)) {
17858
- try {
17859
- const content = fs5.readFileSync(configPath, "utf-8");
17860
- config2 = JSON.parse(content.replace(/\\/g, ""));
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
- const snipEnabled = config2?.snip?.enabled === true;
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 with actionable fixes.
17864
+ description: `Hive Doctor - System health check for Hive plugin.
17909
17865
 
17910
- **Checks performed:**
17911
- 1. Dependencies - MCP packages, agent tools, blockchain, etc.
17912
- 2. CLI Tools - dora, auto-cr, scip-typescript, veil, btca, etc.
17913
- 3. Config - optimizations and MCPs enabled
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
- **Output includes:**
17916
- - Status summary (healthy/warning/action-required)
17917
- - Missing items with install commands
17918
- - Action items prioritized by impact
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 before installing: \`bunx @hung319/opencode-hive doctor\``,
17876
+ **Tip:** Run standalone for auto-fix: \`bunx @hung319/opencode-hive doctor --fix\``,
17922
17877
  args: {},
17923
17878
  async execute() {
17924
- const dependencyChecks = await Promise.all([
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
- const cliToolChecks = [
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 automated code review"),
17937
- checkCliTool("scip-typescript", "@sourcegraph/scip-typescript", "TypeScript SCIP indexer"),
17938
- checkCliTool("veil", "@ushiradineth/veil", "Code discovery and retrieval"),
17939
- checkCliTool("btca", "btca", "BTC/A agent for blockchain tasks")
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
- const configChecks = checkConfig();
17942
- const missingDeps = dependencyChecks.filter((d) => !d.installed);
17943
- const missingTools = cliToolChecks.filter((t) => !t.installed);
17944
- const disabledConfigs = configChecks.filter((c) => !c.enabled);
17945
- let status = "healthy";
17946
- if (missingTools.length >= 2 || missingDeps.length >= 3) {
17947
- status = "action-required";
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: `Install ${tool3.name}`,
17956
- command: `npx -y ${tool3.command}`,
17957
- reason: `${tool3.description}`
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 (!dependencyChecks.find((d) => d.package === "btca")?.installed) {
17961
- actionItems.push({
17917
+ if (missingAgent.length > 0) {
17918
+ result.actionItems.push({
17962
17919
  priority: "medium",
17963
- action: "Install btca for blockchain tasks",
17964
- command: `npm install btca`,
17965
- reason: "BTC/A agent for blockchain analysis and development"
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
- for (const config2 of disabledConfigs) {
17969
- actionItems.push({
17925
+ if (result.cxxflagsStatus === "not-set") {
17926
+ result.actionItems.push({
17970
17927
  priority: "low",
17971
- action: config2.recommendation,
17972
- reason: `Enable ${config2.name} for better performance/features`
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 quickInstall = {
17976
- deps: missingDeps.map((d) => d.package),
17977
- cliTools: missingTools.map((t) => t.command)
17978
- };
17979
- const summary = {
17980
- dependencies: missingDeps.length === 0 ? "✅ All dependencies installed" : `⚠️ ${missingDeps.length} missing: ${missingDeps.map((d) => d.name).join(", ")}`,
17981
- cliTools: missingTools.length === 0 ? "✅ All CLI tools available" : `⚠️ ${missingTools.length} missing: ${missingTools.map((t) => t.name).join(", ")}`,
17982
- config: disabledConfigs.length === 0 ? "✅ All optimizations enabled" : `\uD83D\uDCA1 ${disabledConfigs.length} disabled: ${disabledConfigs.map((c) => c.name).join(", ")}`
17983
- };
17984
- const result = {
17985
- status,
17986
- summary,
17987
- details: {
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 without details.
17950
+ description: `Quick health status - shows summary only.
18008
17951
 
18009
17952
  **Returns:**
18010
- - healthy: All dependencies and CLI tools available
18011
- - warning: Some items missing (not blocking)
18012
- - action-required: Multiple items missing (fix recommended)`,
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 ? "healthy" : missing >= 2 ? "action-required" : "warning",
17965
+ status: missing === 0 ? "ready" : missing >= 2 ? "action-required" : "needs-setup",
18024
17966
  missingCount: missing,
18025
- runFullCheck: "Run hive_doctor for detailed analysis and install commands"
17967
+ autoFix: "Run standalone: bunx @hung319/opencode-hive doctor --fix"
18026
17968
  }, null, 2);
18027
17969
  }
18028
17970
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hung319/opencode-hive",
3
- "version": "1.6.2",
3
+ "version": "1.6.4",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for Agent Hive - from vibe coding to hive coding",
6
6
  "license": "MIT WITH Commons-Clause",