@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.
Files changed (4) hide show
  1. package/README.md +72 -39
  2. package/bin/doctor.ts +193 -190
  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
  // ============================================================================
@@ -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
- function checkAstGrepNative(): { status: 'native' | 'cli-mode'; reason?: string } {
160
- // Check if @ast-grep/napi package exists with native binaries
161
- const napiDirs = [
162
- path.join(process.cwd(), 'node_modules/@ast-grep/napi'),
163
- 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'),
164
167
  ];
165
168
 
166
- for (const napiDir of napiDirs) {
167
- if (!fs.existsSync(napiDir)) continue;
168
-
169
- const binaryPaths = [
170
- path.join(napiDir, 'index.node'),
171
- path.join(napiDir, 'build/Release/ast_grep.node'),
172
- path.join(napiDir, 'dist/index.node'),
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 hasBinary = binaryPaths.some(p => fs.existsSync(p));
199
+ const content = fs.readFileSync(bashrc, 'utf-8');
176
200
 
177
- if (hasBinary) {
178
- return { status: 'native' };
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
- function checkConfig(): { exists: boolean; path?: string; optimizations: string[] } {
189
- const configPaths = [
190
- path.join(process.env.HOME || '', '.config/opencode/agent_hive.json'),
191
- path.join(process.env.HOME || '', '.config/opencode/agent_hive.jsonc'),
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 configPath of configPaths) {
195
- if (fs.existsSync(configPath)) {
196
- try {
197
- const content = fs.readFileSync(configPath, 'utf-8');
198
- const config = JSON.parse(content.replace(/\\/g, ''));
199
- const optimizations: string[] = [];
200
-
201
- if (config.snip?.enabled) optimizations.push('snip');
202
- if (config.vectorMemory?.enabled) optimizations.push('vectorMemory');
203
- if (config.agentBooster?.enabled !== false) optimizations.push('agentBooster');
204
- if (config.sandbox?.mode !== 'none') optimizations.push('sandbox');
205
-
206
- return { exists: true, path: configPath, optimizations };
207
- } 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`));
208
235
  }
209
236
  }
210
237
 
211
- return { exists: false, optimizations: [] };
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.5.8',
248
+ version: '1.6.4',
222
249
  summary: getSystemInfo(),
223
250
  checks: {
224
- dependencies: { total: 0, installed: 0, items: [] },
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
- installCommands: { deps: '', cliTools: '' },
255
+ quickInstall: '',
256
+ cxxflagsStatus: checkCxxFlags(),
231
257
  };
232
258
 
233
- // Check dependencies
234
- const deps = [
235
- '@ast-grep/napi',
236
- '@sparkleideas/agent-booster',
237
- '@sparkleideas/memory',
238
- '@paretools/search',
239
- '@upstash/context7-mcp',
240
- 'exa-mcp-server',
241
- 'grep-mcp',
242
- 'btca',
243
- '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' },
244
271
  ];
245
272
 
246
- output.checks.dependencies.items = deps.map(d => checkNpmPackage(d));
247
- output.checks.dependencies.total = deps.length;
248
- 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;
249
276
 
250
277
  // Check CLI tools
251
- const cliTools = [
252
- { name: 'dora', command: '@butttons/dora', description: 'SCIP-based code navigation' },
253
- { name: 'auto-cr', command: 'auto-cr-cmd', description: 'SWC-based automated code review' },
254
- { name: 'veil', command: '@ushiradineth/veil', description: 'Code discovery and retrieval' },
255
- { name: 'scip-typescript', command: '@sourcegraph/scip-typescript', description: 'TypeScript SCIP indexer' },
256
- { 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' },
257
284
  ];
258
285
 
259
- output.checks.cliTools.items = cliTools.map(t => checkCliTool(t.name, t.command, t.description));
260
- 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;
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 ${missingTools.length} CLI tool(s)`,
297
+ action: `Install CLI tools`,
277
298
  command: missingTools.map(t => `npx -y ${t.command}`).join(' && '),
278
- reason: 'CLI tools provide code navigation, review, and analysis features',
299
+ reason: 'CLI tools enhance code navigation and review',
279
300
  });
280
301
  }
281
302
 
282
- if (missingDeps.length > 0) {
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: 'low',
300
- action: 'Create config file',
301
- command: `mkdir -p ~/.config/opencode && cat > ~/.config/opencode/agent_hive.json << 'EOF'\n{\n "snip": { "enabled": true },\n "vectorMemory": { "enabled": true }\n}\nEOF`,
302
- 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',
303
309
  });
304
310
  }
305
311
 
306
- // Generate install commands
307
- if (missingDeps.length > 0) {
308
- 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}`);
309
316
  }
310
-
311
- if (missingTools.length > 0) {
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 (output.actionItems.some(a => a.priority === 'critical')) {
323
+ if (missingTools.length >= 3) {
317
324
  output.status = 'action-required';
318
- } else if (output.actionItems.some(a => a.priority === 'high' || a.priority === 'medium')) {
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' + colors.blue('╔═══════════════════════════════════════════════════════════╗'));
331
- console.log(colors.blue('║') + ' 🐝 Hive Doctor v' + output.version + ' - System Check' + ' '.repeat(14) + colors.blue('║'));
332
- 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('╚═══════════════════════════════════════════════════════════╝'));
333
356
 
334
- // Summary
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(` Package Manager: ${output.summary.packageManager}`);
339
- console.log(colors.gray('─'.repeat(55)));
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' ? colors.green :
343
- 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;
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
- // Dependencies
350
- console.log('\n📦 Dependencies (' + output.checks.dependencies.installed + '/' + output.checks.dependencies.total + ')');
351
- for (const dep of output.checks.dependencies.items) {
352
- const icon = dep.installed ? colors.green('✅') : colors.yellow('○');
353
- const version = dep.version ? colors.gray(`v${dep.version}`) : colors.red('not installed');
354
- 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}`);
355
377
  }
356
378
 
357
- // CLI Tools
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 ? colors.green('✅') : colors.yellow('○');
361
- 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');
362
384
  console.log(` ${icon} ${tool.name} - ${tool.description} ${version}`);
363
385
  }
364
386
 
365
- // Native binaries
366
- console.log('\n Native Binaries');
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
- // Config
377
- console.log('\n⚙️ Config');
378
- if (output.checks.config.exists) {
379
- console.log(' ' + colors.green(' Config file found'));
380
- if (output.checks.config.optimizations.length > 0) {
381
- console.log(' ' + colors.gray('Optimizations: ' + output.checks.config.optimizations.join(', ')));
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(' ' + 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'));
385
399
  }
386
400
 
387
401
  // Action items
388
402
  if (output.actionItems.length > 0) {
389
- console.log('\n' + colors.gray('─'.repeat(55)));
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 === 'critical' ? colors.red :
394
- item.priority === 'high' ? colors.yellow :
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(` ${colors.gray(item.reason)}`);
411
+ console.log(` ${c.gray(item.reason)}`);
399
412
  if (item.command) {
400
- console.log(` ${colors.green(item.command)}`);
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.installCommands.deps || output.installCommands.cliTools) {
408
- console.log(colors.gray('─'.repeat(55)));
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' + colors.blue('═'.repeat(55)));
427
- console.log(colors.gray(' Run with: bunx @hung319/opencode-hive doctor'));
428
- 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');
429
430
  }
430
431
 
431
432
  // ============================================================================
432
433
  // Main
433
434
  // ============================================================================
434
435
 
435
- 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);
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 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.3",
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",