@hung319/opencode-hive 1.5.8 → 1.5.9

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 CHANGED
@@ -26,26 +26,26 @@ Hive: Plan → Review → Approve → Execute → Ship
26
26
 
27
27
  ### For Humans
28
28
 
29
- **Step 1: Install the plugin**
29
+ **Step 1: Check if your system is ready** (run BEFORE installing)
30
30
  ```bash
31
- npm install @hung319/opencode-hive
31
+ # Run standalone doctor to see what's needed
32
+ bunx @hung319/opencode-hive doctor
33
+ # or
34
+ npx @hung319/opencode-hive doctor
32
35
  ```
33
36
 
34
- **Step 2: Check what's available**
35
- Open OpenCode and ask: "Run hive_doctor to check the system"
36
-
37
- **Step 3: Install extras you want**
38
- - For **code analysis**: Install `@notprolands/ast-grep-mcp`
39
- - For **fast code search**: Install `@paretools/search`
40
- - For **code navigation**: Install `@butttons/dora`
41
- - For **auto code review**: Install `auto-cr-cmd`
42
-
37
+ **Step 2: Install the plugin**
43
38
  ```bash
44
- # Install all extras at once
45
- npm install @notprolands/ast-grep-mcp @paretools/search
46
- npx -y @butttons/dora auto-cr-cmd
39
+ npm install @hung319/opencode-hive
47
40
  ```
48
41
 
42
+ **Step 3: Install extras you want**
43
+ - For **code analysis**: `npm install @notprolands/ast-grep-mcp`
44
+ - For **fast code search**: `npm install @paretools/search`
45
+ - For **code navigation**: `npx -y @butttons/dora`
46
+ - For **auto code review**: `npx -y auto-cr-cmd`
47
+ - For **blockchain tasks**: `npm install btca-ask`
48
+
49
49
  **Step 4: Optional config**
50
50
  Create `~/.config/opencode/agent_hive.json`:
51
51
  ```json
@@ -551,21 +551,25 @@ hive_doctor()
551
551
  hive_doctor_quick()
552
552
  ```
553
553
 
554
+ **Standalone (before installing):**
555
+ ```bash
556
+ bunx @hung319/opencode-hive doctor
557
+ ```
558
+
554
559
  ### What it checks
555
560
 
556
561
  1. **Dependencies** - npm packages installed?
557
- - `@ast-grep/napi` - Native AST analysis
558
- - `@sparkleideas/agent-booster` - Fast code editing
559
- - `@sparkleideas/memory` - Vector memory
560
- - `@paretools/search` - Structured search
561
- - `@upstash/context7-mcp` - Library docs
562
- - `exa-mcp-server` - Web search
562
+ - Core: `@ast-grep/napi`, `@notprolands/ast-grep-mcp`, `@paretools/search`
563
+ - Agent: `@sparkleideas/agent-booster`, `@sparkleideas/memory`
564
+ - MCPs: `@upstash/context7-mcp`, `exa-mcp-server`, `grep-mcp`
565
+ - Blockchain: `btca-ask`, `opencode-model-selector`
563
566
 
564
567
  2. **CLI Tools** - npx tools available?
565
568
  - `dora` - Code navigation (SCIP-based)
566
569
  - `auto-cr` - Automated code review (SWC)
567
570
  - `scip-typescript` - TypeScript indexer
568
571
  - `veil` - Code discovery
572
+ - `btca` - BTC/A blockchain agent
569
573
 
570
574
  3. **Native Binaries** - @ast-grep/napi tree-sitter?
571
575
  - Native mode: Fastest, uses compiled binaries
package/bin/doctor.ts ADDED
@@ -0,0 +1,436 @@
1
+ #!/usr/bin/env bun
2
+
3
+ /**
4
+ * Hive Doctor - Standalone version
5
+ *
6
+ * Run BEFORE installing the plugin to check if your system is ready:
7
+ *
8
+ * bunx @hung319/opencode-hive doctor
9
+ * npx @hung319/opencode-hive doctor
10
+ *
11
+ * Or install and run:
12
+ *
13
+ * npm install @hung319/opencode-hive
14
+ * hive_doctor() // via OpenCode
15
+ */
16
+
17
+ import { execSync } from 'child_process';
18
+ import * as fs from 'fs';
19
+ import * as path from 'path';
20
+
21
+ // ============================================================================
22
+ // Types
23
+ // ============================================================================
24
+
25
+ interface CheckResult {
26
+ name: string;
27
+ installed: boolean;
28
+ version?: string;
29
+ reason?: string;
30
+ }
31
+
32
+ interface CliCheck {
33
+ name: string;
34
+ command: string;
35
+ installed: boolean;
36
+ version?: string;
37
+ description: string;
38
+ }
39
+
40
+ interface DoctorOutput {
41
+ status: 'ready' | 'needs-setup' | 'action-required';
42
+ version: string;
43
+ summary: {
44
+ os: string;
45
+ nodeVersion: string;
46
+ packageManager: string;
47
+ };
48
+ checks: {
49
+ dependencies: {
50
+ total: number;
51
+ installed: number;
52
+ items: CheckResult[];
53
+ };
54
+ cliTools: {
55
+ total: number;
56
+ available: number;
57
+ items: CliCheck[];
58
+ };
59
+ nativeBinaries: {
60
+ status: 'native' | 'cli-mode';
61
+ reason?: string;
62
+ };
63
+ config: {
64
+ exists: boolean;
65
+ path?: string;
66
+ optimizations: string[];
67
+ };
68
+ };
69
+ actionItems: {
70
+ priority: 'critical' | 'high' | 'medium' | 'low';
71
+ action: string;
72
+ command?: string;
73
+ reason: string;
74
+ }[];
75
+ installCommands: {
76
+ deps: string;
77
+ cliTools: string;
78
+ };
79
+ }
80
+
81
+ // ============================================================================
82
+ // Color helpers
83
+ // ============================================================================
84
+
85
+ const colors = {
86
+ green: (text: string) => `\x1b[32m${text}\x1b[0m`,
87
+ yellow: (text: string) => `\x1b[33m${text}\x1b[0m`,
88
+ red: (text: string) => `\x1b[31m${text}\x1b[0m`,
89
+ blue: (text: string) => `\x1b[34m${text}\x1b[0m`,
90
+ gray: (text: string) => `\x1b[90m${text}\x1b[0m`,
91
+ };
92
+
93
+ // ============================================================================
94
+ // Check functions
95
+ // ============================================================================
96
+
97
+ function getSystemInfo() {
98
+ return {
99
+ os: process.platform,
100
+ nodeVersion: process.version,
101
+ packageManager: exists('npm') ? 'npm' : exists('bun') ? 'bun' : 'unknown',
102
+ };
103
+ }
104
+
105
+ function exists(cmd: string): boolean {
106
+ try {
107
+ execSync(cmd, { stdio: 'ignore' });
108
+ return true;
109
+ } catch {
110
+ return false;
111
+ }
112
+ }
113
+
114
+ function checkNpmPackage(name: string): CheckResult {
115
+ const result: CheckResult = { name, installed: false };
116
+
117
+ try {
118
+ const output = execSync(`npm list ${name} --depth=0 --json 2>/dev/null`, {
119
+ encoding: 'utf-8',
120
+ timeout: 10000,
121
+ });
122
+ const json = JSON.parse(output);
123
+ if (json.dependencies && json.dependencies[name]) {
124
+ result.installed = true;
125
+ result.version = json.dependencies[name].version;
126
+ }
127
+ } catch {}
128
+
129
+ return result;
130
+ }
131
+
132
+ function checkCliTool(name: string, command: string, description: string): CliCheck {
133
+ const result: CliCheck = { name, command, installed: false, description };
134
+
135
+ // Try direct command
136
+ try {
137
+ const cmd = command.split(' ')[0];
138
+ execSync(cmd, { stdio: 'ignore', timeout: 3000 });
139
+ result.installed = true;
140
+ result.version = 'installed';
141
+ return result;
142
+ } catch {}
143
+
144
+ // Try npx
145
+ try {
146
+ execSync(`npx -y ${command.split(' ')[0]} --version`, {
147
+ stdio: 'ignore',
148
+ timeout: 10000
149
+ });
150
+ result.installed = true;
151
+ result.version = 'via npx';
152
+ return result;
153
+ } catch {}
154
+
155
+ return result;
156
+ }
157
+
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'),
163
+ ];
164
+
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
+ ];
173
+
174
+ const hasBinary = binaryPaths.some(p => fs.existsSync(p));
175
+
176
+ if (hasBinary) {
177
+ return { status: 'native' };
178
+ }
179
+ }
180
+
181
+ return {
182
+ status: 'cli-mode',
183
+ reason: 'Native binaries not found (tree-sitter compilation may have failed)'
184
+ };
185
+ }
186
+
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
+ ];
192
+
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 {}
207
+ }
208
+ }
209
+
210
+ return { exists: false, optimizations: [] };
211
+ }
212
+
213
+ // ============================================================================
214
+ // Main check
215
+ // ============================================================================
216
+
217
+ function runDoctor(): DoctorOutput {
218
+ const output: DoctorOutput = {
219
+ status: 'ready',
220
+ version: '1.5.8',
221
+ summary: getSystemInfo(),
222
+ checks: {
223
+ dependencies: { total: 0, installed: 0, items: [] },
224
+ cliTools: { total: 0, available: 0, items: [] },
225
+ nativeBinaries: { status: 'cli-mode' },
226
+ config: { exists: false, optimizations: [] },
227
+ },
228
+ actionItems: [],
229
+ installCommands: { deps: '', cliTools: '' },
230
+ };
231
+
232
+ // Check dependencies
233
+ const deps = [
234
+ '@ast-grep/napi',
235
+ '@notprolands/ast-grep-mcp',
236
+ '@sparkleideas/agent-booster',
237
+ '@sparkleideas/memory',
238
+ '@paretools/search',
239
+ '@upstash/context7-mcp',
240
+ 'exa-mcp-server',
241
+ 'grep-mcp',
242
+ 'btca-ask',
243
+ 'opencode-model-selector',
244
+ ];
245
+
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;
249
+
250
+ // 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-ask', description: 'BTC/A agent for blockchain tasks' },
257
+ { name: 'ast-grep', command: '@notprolands/ast-grep-mcp', description: 'AST-based pattern matching' },
258
+ ];
259
+
260
+ output.checks.cliTools.items = cliTools.map(t => checkCliTool(t.name, t.command, t.description));
261
+ output.checks.cliTools.total = cliTools.length;
262
+ output.checks.cliTools.available = output.checks.cliTools.items.filter(t => t.installed).length;
263
+
264
+ // Check native binaries
265
+ output.checks.nativeBinaries = checkAstGrepNative();
266
+
267
+ // Check config
268
+ output.checks.config = checkConfig();
269
+
270
+ // Generate action items
271
+ const missingDeps = output.checks.dependencies.items.filter(d => !d.installed);
272
+ const missingTools = output.checks.cliTools.items.filter(t => !t.installed);
273
+
274
+ if (missingTools.length > 0) {
275
+ output.actionItems.push({
276
+ priority: 'high',
277
+ action: `Install ${missingTools.length} CLI tool(s)`,
278
+ command: missingTools.map(t => `npx -y ${t.command}`).join(' && '),
279
+ reason: 'CLI tools provide code navigation, review, and analysis features',
280
+ });
281
+ }
282
+
283
+ if (missingDeps.length > 0) {
284
+ const important = missingDeps.filter(d =>
285
+ ['@ast-grep/napi', '@notprolands/ast-grep-mcp', '@paretools/search'].includes(d.name)
286
+ );
287
+
288
+ if (important.length > 0) {
289
+ output.actionItems.push({
290
+ priority: 'medium',
291
+ action: `Install ${important.length} important package(s)`,
292
+ command: important.map(d => `npm install ${d.name}`).join(' && '),
293
+ reason: 'These packages enable core functionality',
294
+ });
295
+ }
296
+ }
297
+
298
+ if (!output.checks.config.exists) {
299
+ output.actionItems.push({
300
+ priority: 'low',
301
+ action: 'Create config file',
302
+ command: `mkdir -p ~/.config/opencode && cat > ~/.config/opencode/agent_hive.json << 'EOF'\n{\n "snip": { "enabled": true },\n "vectorMemory": { "enabled": true }\n}\nEOF`,
303
+ reason: 'Enable optimizations for better performance',
304
+ });
305
+ }
306
+
307
+ // Generate install commands
308
+ if (missingDeps.length > 0) {
309
+ output.installCommands.deps = `npm install ${missingDeps.map(d => d.name).join(' ')}`;
310
+ }
311
+
312
+ if (missingTools.length > 0) {
313
+ output.installCommands.cliTools = `npx -y ${missingTools.map(t => t.command.split(' ')[0]).join(' ')}`;
314
+ }
315
+
316
+ // Determine status
317
+ if (output.actionItems.some(a => a.priority === 'critical')) {
318
+ output.status = 'action-required';
319
+ } else if (output.actionItems.some(a => a.priority === 'high' || a.priority === 'medium')) {
320
+ output.status = 'needs-setup';
321
+ }
322
+
323
+ return output;
324
+ }
325
+
326
+ // ============================================================================
327
+ // Print output
328
+ // ============================================================================
329
+
330
+ function printDoctor(output: DoctorOutput) {
331
+ console.log('\n' + colors.blue('╔═══════════════════════════════════════════════════════════╗'));
332
+ console.log(colors.blue('║') + ' 🐝 Hive Doctor v' + output.version + ' - System Check' + ' '.repeat(14) + colors.blue('║'));
333
+ console.log(colors.blue('╚═══════════════════════════════════════════════════════════╝'));
334
+
335
+ // Summary
336
+ console.log('\n' + colors.gray('─'.repeat(55)));
337
+ console.log(` OS: ${output.summary.os}`);
338
+ console.log(` Node: ${output.summary.nodeVersion}`);
339
+ console.log(` Package Manager: ${output.summary.packageManager}`);
340
+ console.log(colors.gray('─'.repeat(55)));
341
+
342
+ // Status
343
+ const statusColor = output.status === 'ready' ? colors.green :
344
+ output.status === 'needs-setup' ? colors.yellow : colors.red;
345
+ const statusText = output.status === 'ready' ? '✅ READY' :
346
+ output.status === 'needs-setup' ? '⚠️ NEEDS SETUP' : '❌ ACTION REQUIRED';
347
+
348
+ console.log('\n Status: ' + statusColor(statusText));
349
+
350
+ // Dependencies
351
+ console.log('\n📦 Dependencies (' + output.checks.dependencies.installed + '/' + output.checks.dependencies.total + ')');
352
+ for (const dep of output.checks.dependencies.items) {
353
+ const icon = dep.installed ? colors.green('✅') : colors.yellow('○');
354
+ const version = dep.version ? colors.gray(`v${dep.version}`) : colors.red('not installed');
355
+ console.log(` ${icon} ${dep.name} ${version}`);
356
+ }
357
+
358
+ // CLI Tools
359
+ console.log('\n🔧 CLI Tools (' + output.checks.cliTools.available + '/' + output.checks.cliTools.total + ')');
360
+ for (const tool of output.checks.cliTools.items) {
361
+ const icon = tool.installed ? colors.green('✅') : colors.yellow('○');
362
+ const version = tool.version ? colors.gray(`(${tool.version})`) : colors.red('not available');
363
+ console.log(` ${icon} ${tool.name} - ${tool.description} ${version}`);
364
+ }
365
+
366
+ // Native binaries
367
+ console.log('\n⚡ Native Binaries');
368
+ if (output.checks.nativeBinaries.status === 'native') {
369
+ console.log(' ' + colors.green('✅ Native mode (fastest)'));
370
+ } else {
371
+ console.log(' ' + colors.yellow('○ CLI mode (falls back via npx)'));
372
+ if (output.checks.nativeBinaries.reason) {
373
+ console.log(' ' + colors.gray(output.checks.nativeBinaries.reason));
374
+ }
375
+ }
376
+
377
+ // Config
378
+ console.log('\n⚙️ Config');
379
+ if (output.checks.config.exists) {
380
+ console.log(' ' + colors.green('✅ Config file found'));
381
+ if (output.checks.config.optimizations.length > 0) {
382
+ console.log(' ' + colors.gray('Optimizations: ' + output.checks.config.optimizations.join(', ')));
383
+ }
384
+ } else {
385
+ console.log(' ' + colors.yellow('○ No config file (optional)'));
386
+ }
387
+
388
+ // Action items
389
+ if (output.actionItems.length > 0) {
390
+ console.log('\n' + colors.gray('─'.repeat(55)));
391
+ console.log('📋 Action Items\n');
392
+
393
+ for (const item of output.actionItems) {
394
+ const priorityColor = item.priority === 'critical' ? colors.red :
395
+ item.priority === 'high' ? colors.yellow :
396
+ item.priority === 'medium' ? colors.blue : colors.gray;
397
+
398
+ console.log(` [${priorityColor(item.priority.toUpperCase())}] ${item.action}`);
399
+ console.log(` ${colors.gray(item.reason)}`);
400
+ if (item.command) {
401
+ console.log(` ${colors.green(item.command)}`);
402
+ }
403
+ console.log();
404
+ }
405
+ }
406
+
407
+ // Quick install
408
+ if (output.installCommands.deps || output.installCommands.cliTools) {
409
+ console.log(colors.gray('─'.repeat(55)));
410
+ console.log('\n🚀 Quick Install\n');
411
+
412
+ if (output.installCommands.deps) {
413
+ console.log(' ' + colors.cyan('Dependencies:'));
414
+ console.log(' ' + colors.green(output.installCommands.deps));
415
+ }
416
+
417
+ if (output.installCommands.cliTools) {
418
+ console.log('\n ' + colors.cyan('CLI Tools:'));
419
+ console.log(' ' + colors.green(output.installCommands.cliTools));
420
+ }
421
+ }
422
+
423
+ console.log('\n' + colors.blue('═'.repeat(55)));
424
+ console.log(colors.gray(' Run with: bunx @hung319/opencode-hive doctor'));
425
+ console.log(colors.blue('═'.repeat(55)) + '\n');
426
+ }
427
+
428
+ // ============================================================================
429
+ // Main
430
+ // ============================================================================
431
+
432
+ const output = runDoctor();
433
+ printDoctor(output);
434
+
435
+ // Exit with appropriate code
436
+ process.exit(output.status === 'ready' ? 0 : 1);
package/dist/index.js CHANGED
@@ -17942,8 +17942,8 @@ var hiveDoctorTool = tool({
17942
17942
  description: `Hive Doctor - System health check with actionable fixes.
17943
17943
 
17944
17944
  **Checks performed:**
17945
- 1. Dependencies - @ast-grep/napi, agent-booster, vector-memory, etc.
17946
- 2. CLI Tools - dora, auto-cr, scip-typescript, veil
17945
+ 1. Dependencies - All MCP packages, ast-grep, agent-booster, etc.
17946
+ 2. CLI Tools - dora, auto-cr, scip-typescript, veil, btca, etc.
17947
17947
  3. Native Binaries - tree-sitter binaries for ast-grep
17948
17948
  4. Config - optimizations and MCPs enabled
17949
17949
 
@@ -17951,24 +17951,31 @@ var hiveDoctorTool = tool({
17951
17951
  - Status summary (healthy/warning/action-required)
17952
17952
  - Missing items with install commands
17953
17953
  - Action items prioritized by impact
17954
- - Quick install commands for all missing items`,
17954
+ - Quick install commands for all missing items
17955
+
17956
+ **Tip:** Run standalone before installing: \`bunx @hung319/opencode-hive doctor\``,
17955
17957
  args: {},
17956
17958
  async execute() {
17957
17959
  const dependencyChecks = await Promise.all([
17958
17960
  checkPackage("@ast-grep/napi"),
17961
+ checkPackage("@notprolands/ast-grep-mcp"),
17962
+ checkPackage("@paretools/search"),
17959
17963
  checkPackage("@sparkleideas/agent-booster"),
17960
17964
  checkPackage("@sparkleideas/memory"),
17961
- checkPackage("@paretools/search"),
17962
17965
  checkPackage("@upstash/context7-mcp"),
17963
17966
  checkPackage("exa-mcp-server"),
17964
17967
  checkPackage("grep-mcp"),
17965
- checkPackage("@notprolands/ast-grep-mcp")
17968
+ checkPackage("btca-ask"),
17969
+ checkPackage("opencode-model-selector"),
17970
+ checkPackage("opencode-model-selector-free")
17966
17971
  ]);
17967
17972
  const cliToolChecks = [
17968
17973
  checkCliTool("dora", "@butttons/dora", "SCIP-based code navigation"),
17969
17974
  checkCliTool("auto-cr", "auto-cr-cmd", "SWC-based automated code review"),
17970
17975
  checkCliTool("scip-typescript", "@sourcegraph/scip-typescript", "TypeScript SCIP indexer"),
17971
- checkCliTool("veil", "@ushiradineth/veil", "Code discovery and retrieval")
17976
+ checkCliTool("veil", "@ushiradineth/veil", "Code discovery and retrieval"),
17977
+ checkCliTool("btca", "btca-ask", "BTC/A agent for blockchain tasks"),
17978
+ checkCliTool("ast-grep", "@notprolands/ast-grep-mcp", "AST-based pattern matching")
17972
17979
  ];
17973
17980
  const nativeCheck = checkAstGrepNative();
17974
17981
  const nativeStatus = nativeCheck.available ? "native" : "cli-mode";
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "@hung319/opencode-hive",
3
- "version": "1.5.8",
3
+ "version": "1.5.9",
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",
7
7
  "author": "hung319",
8
+ "bin": {
9
+ "hive-doctor": "./bin/doctor.ts"
10
+ },
8
11
  "repository": {
9
12
  "type": "git",
10
13
  "url": "https://github.com/hung319/agent-hive.git",