@hung319/opencode-hive 1.5.8 → 1.6.0
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 +29 -44
- package/bin/doctor.ts +433 -0
- package/dist/index.js +45 -472
- package/package.json +5 -4
- package/dist/mcp/ast-grep.d.ts +0 -7
- package/dist/tools/ast-grep-native.d.ts +0 -19
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:
|
|
29
|
+
**Step 1: Check if your system is ready** (run BEFORE installing)
|
|
30
30
|
```bash
|
|
31
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
|
@@ -71,7 +71,7 @@ npm install @hung319/opencode-hive
|
|
|
71
71
|
2. Set `EXA_API_KEY` to enable `websearch_exa` (optional).
|
|
72
72
|
3. Restart OpenCode.
|
|
73
73
|
|
|
74
|
-
This enables tools like `grep_app_searchGitHub`, `context7_query-docs`,
|
|
74
|
+
This enables tools like `grep_app_searchGitHub`, `context7_query-docs`, and `websearch_web_search_exa`.
|
|
75
75
|
|
|
76
76
|
## The Workflow
|
|
77
77
|
|
|
@@ -206,7 +206,7 @@ Hive uses a config file at `~/.config/opencode/agent_hive.json`. You can customi
|
|
|
206
206
|
{
|
|
207
207
|
"$schema": "https://raw.githubusercontent.com/hung319/agent-hive/main/packages/opencode-hive/schema/agent_hive.schema.json",
|
|
208
208
|
"disableSkills": ["brainstorming", "writing-plans"],
|
|
209
|
-
"disableMcps": ["websearch", "
|
|
209
|
+
"disableMcps": ["websearch", "pare_search"]
|
|
210
210
|
}
|
|
211
211
|
```
|
|
212
212
|
|
|
@@ -230,21 +230,8 @@ Hive uses a config file at `~/.config/opencode/agent_hive.json`. You can customi
|
|
|
230
230
|
| `websearch` | Web search via [Exa AI](https://exa.ai). Real-time web searches and content scraping. | Set `EXA_API_KEY` env var |
|
|
231
231
|
| `context7` | Library documentation lookup via [Context7](https://context7.com). Query up-to-date docs for any programming library. | None |
|
|
232
232
|
| `grep_app` | GitHub code search via [grep.app](https://grep.app). Find real-world code examples from public repositories. | None |
|
|
233
|
-
| `ast_grep` | Native NAPI-powered AST analysis. Pattern matching across 25+ languages. | Built-in (no npx needed) |
|
|
234
233
|
| `pare_search` | Structured ripgrep/fd search with 65-95% token reduction. | None (runs via npx) |
|
|
235
|
-
|
|
236
|
-
#### Native ast-grep Tools
|
|
237
|
-
|
|
238
|
-
Instead of MCP-based ast-grep, this plugin includes native tools using `@ast-grep/napi`:
|
|
239
|
-
|
|
240
|
-
| Tool | Description |
|
|
241
|
-
|------|-------------|
|
|
242
|
-
| `ast_grep_dump_syntax_tree` | Dump code's syntax structure for debugging |
|
|
243
|
-
| `ast_grep_test_match_code_rule` | Test code against YAML rules |
|
|
244
|
-
| `ast_grep_find_code` | Find code matching patterns in project |
|
|
245
|
-
| `ast_grep_scan_code` | Scan for TypeScript bugs and best practices |
|
|
246
|
-
| `ast_grep_rewrite_code` | Transform/refactor code with AST patterns |
|
|
247
|
-
| `ast_grep_analyze_imports` | Analyze import usage in codebase |
|
|
234
|
+
| `veil` | Code discovery and intelligent retrieval. | None (runs via npx) |
|
|
248
235
|
|
|
249
236
|
### Per-Agent Skills
|
|
250
237
|
|
|
@@ -551,30 +538,29 @@ hive_doctor()
|
|
|
551
538
|
hive_doctor_quick()
|
|
552
539
|
```
|
|
553
540
|
|
|
541
|
+
**Standalone (before installing):**
|
|
542
|
+
```bash
|
|
543
|
+
bunx @hung319/opencode-hive doctor
|
|
544
|
+
```
|
|
545
|
+
|
|
554
546
|
### What it checks
|
|
555
547
|
|
|
556
548
|
1. **Dependencies** - npm packages installed?
|
|
557
|
-
- `@
|
|
558
|
-
- `@
|
|
559
|
-
-
|
|
560
|
-
- `@paretools/search` - Structured search
|
|
561
|
-
- `@upstash/context7-mcp` - Library docs
|
|
562
|
-
- `exa-mcp-server` - Web search
|
|
549
|
+
- Agent: `@sparkleideas/agent-booster`, `@sparkleideas/memory`
|
|
550
|
+
- MCPs: `@paretools/search`, `@upstash/context7-mcp`, `exa-mcp-server`, `grep-mcp`
|
|
551
|
+
- Blockchain: `btca`, `opencode-model-selector`
|
|
563
552
|
|
|
564
553
|
2. **CLI Tools** - npx tools available?
|
|
565
554
|
- `dora` - Code navigation (SCIP-based)
|
|
566
555
|
- `auto-cr` - Automated code review (SWC)
|
|
567
556
|
- `scip-typescript` - TypeScript indexer
|
|
568
557
|
- `veil` - Code discovery
|
|
558
|
+
- `btca` - BTC/A blockchain agent (from npmx.dev)
|
|
569
559
|
|
|
570
|
-
3. **
|
|
571
|
-
- Native mode: Fastest, uses compiled binaries
|
|
572
|
-
- CLI mode: Falls back to MCP via npx
|
|
573
|
-
|
|
574
|
-
4. **Config** - Features enabled?
|
|
560
|
+
3. **Config** - Features enabled?
|
|
575
561
|
- snip, vectorMemory, agentBooster
|
|
576
562
|
- sandbox mode
|
|
577
|
-
- MCPs:
|
|
563
|
+
- MCPs: veil, pare_search
|
|
578
564
|
|
|
579
565
|
### Example Output
|
|
580
566
|
|
|
@@ -582,9 +568,8 @@ hive_doctor_quick()
|
|
|
582
568
|
{
|
|
583
569
|
"status": "warning",
|
|
584
570
|
"summary": {
|
|
585
|
-
"dependencies": "⚠️ 2 missing: agent-booster,
|
|
571
|
+
"dependencies": "⚠️ 2 missing: agent-booster, memory",
|
|
586
572
|
"cliTools": "⚠️ 1 missing: auto-cr",
|
|
587
|
-
"nativeBinaries": "⚡ CLI mode (native unavailable)",
|
|
588
573
|
"config": "💡 2 disabled: snip, vectorMemory"
|
|
589
574
|
},
|
|
590
575
|
"actionItems": [
|
package/bin/doctor.ts
ADDED
|
@@ -0,0 +1,433 @@
|
|
|
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
|
+
'@sparkleideas/agent-booster',
|
|
235
|
+
'@sparkleideas/memory',
|
|
236
|
+
'@paretools/search',
|
|
237
|
+
'@upstash/context7-mcp',
|
|
238
|
+
'exa-mcp-server',
|
|
239
|
+
'grep-mcp',
|
|
240
|
+
'btca',
|
|
241
|
+
'opencode-model-selector',
|
|
242
|
+
];
|
|
243
|
+
|
|
244
|
+
output.checks.dependencies.items = deps.map(d => checkNpmPackage(d));
|
|
245
|
+
output.checks.dependencies.total = deps.length;
|
|
246
|
+
output.checks.dependencies.installed = output.checks.dependencies.items.filter(d => d.installed).length;
|
|
247
|
+
|
|
248
|
+
// Check CLI tools
|
|
249
|
+
const cliTools = [
|
|
250
|
+
{ name: 'dora', command: '@butttons/dora', description: 'SCIP-based code navigation' },
|
|
251
|
+
{ name: 'auto-cr', command: 'auto-cr-cmd', description: 'SWC-based automated code review' },
|
|
252
|
+
{ name: 'veil', command: '@ushiradineth/veil', description: 'Code discovery and retrieval' },
|
|
253
|
+
{ name: 'scip-typescript', command: '@sourcegraph/scip-typescript', description: 'TypeScript SCIP indexer' },
|
|
254
|
+
{ name: 'btca', command: 'btca', description: 'BTC/A agent for blockchain tasks' },
|
|
255
|
+
];
|
|
256
|
+
|
|
257
|
+
output.checks.cliTools.items = cliTools.map(t => checkCliTool(t.name, t.command, t.description));
|
|
258
|
+
output.checks.cliTools.total = cliTools.length;
|
|
259
|
+
output.checks.cliTools.available = output.checks.cliTools.items.filter(t => t.installed).length;
|
|
260
|
+
|
|
261
|
+
// Check native binaries
|
|
262
|
+
output.checks.nativeBinaries = checkAstGrepNative();
|
|
263
|
+
|
|
264
|
+
// Check config
|
|
265
|
+
output.checks.config = checkConfig();
|
|
266
|
+
|
|
267
|
+
// Generate action items
|
|
268
|
+
const missingDeps = output.checks.dependencies.items.filter(d => !d.installed);
|
|
269
|
+
const missingTools = output.checks.cliTools.items.filter(t => !t.installed);
|
|
270
|
+
|
|
271
|
+
if (missingTools.length > 0) {
|
|
272
|
+
output.actionItems.push({
|
|
273
|
+
priority: 'high',
|
|
274
|
+
action: `Install ${missingTools.length} CLI tool(s)`,
|
|
275
|
+
command: missingTools.map(t => `npx -y ${t.command}`).join(' && '),
|
|
276
|
+
reason: 'CLI tools provide code navigation, review, and analysis features',
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (missingDeps.length > 0) {
|
|
281
|
+
const important = missingDeps.filter(d =>
|
|
282
|
+
['@ast-grep/napi', '@notprolands/ast-grep-mcp', '@paretools/search'].includes(d.name)
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
if (important.length > 0) {
|
|
286
|
+
output.actionItems.push({
|
|
287
|
+
priority: 'medium',
|
|
288
|
+
action: `Install ${important.length} important package(s)`,
|
|
289
|
+
command: important.map(d => `npm install ${d.name}`).join(' && '),
|
|
290
|
+
reason: 'These packages enable core functionality',
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (!output.checks.config.exists) {
|
|
296
|
+
output.actionItems.push({
|
|
297
|
+
priority: 'low',
|
|
298
|
+
action: 'Create config file',
|
|
299
|
+
command: `mkdir -p ~/.config/opencode && cat > ~/.config/opencode/agent_hive.json << 'EOF'\n{\n "snip": { "enabled": true },\n "vectorMemory": { "enabled": true }\n}\nEOF`,
|
|
300
|
+
reason: 'Enable optimizations for better performance',
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Generate install commands
|
|
305
|
+
if (missingDeps.length > 0) {
|
|
306
|
+
output.installCommands.deps = `npm install ${missingDeps.map(d => d.name).join(' ')}`;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (missingTools.length > 0) {
|
|
310
|
+
output.installCommands.cliTools = `npx -y ${missingTools.map(t => t.command.split(' ')[0]).join(' ')}`;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Determine status
|
|
314
|
+
if (output.actionItems.some(a => a.priority === 'critical')) {
|
|
315
|
+
output.status = 'action-required';
|
|
316
|
+
} else if (output.actionItems.some(a => a.priority === 'high' || a.priority === 'medium')) {
|
|
317
|
+
output.status = 'needs-setup';
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return output;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// ============================================================================
|
|
324
|
+
// Print output
|
|
325
|
+
// ============================================================================
|
|
326
|
+
|
|
327
|
+
function printDoctor(output: DoctorOutput) {
|
|
328
|
+
console.log('\n' + colors.blue('╔═══════════════════════════════════════════════════════════╗'));
|
|
329
|
+
console.log(colors.blue('║') + ' 🐝 Hive Doctor v' + output.version + ' - System Check' + ' '.repeat(14) + colors.blue('║'));
|
|
330
|
+
console.log(colors.blue('╚═══════════════════════════════════════════════════════════╝'));
|
|
331
|
+
|
|
332
|
+
// Summary
|
|
333
|
+
console.log('\n' + colors.gray('─'.repeat(55)));
|
|
334
|
+
console.log(` OS: ${output.summary.os}`);
|
|
335
|
+
console.log(` Node: ${output.summary.nodeVersion}`);
|
|
336
|
+
console.log(` Package Manager: ${output.summary.packageManager}`);
|
|
337
|
+
console.log(colors.gray('─'.repeat(55)));
|
|
338
|
+
|
|
339
|
+
// Status
|
|
340
|
+
const statusColor = output.status === 'ready' ? colors.green :
|
|
341
|
+
output.status === 'needs-setup' ? colors.yellow : colors.red;
|
|
342
|
+
const statusText = output.status === 'ready' ? '✅ READY' :
|
|
343
|
+
output.status === 'needs-setup' ? '⚠️ NEEDS SETUP' : '❌ ACTION REQUIRED';
|
|
344
|
+
|
|
345
|
+
console.log('\n Status: ' + statusColor(statusText));
|
|
346
|
+
|
|
347
|
+
// Dependencies
|
|
348
|
+
console.log('\n📦 Dependencies (' + output.checks.dependencies.installed + '/' + output.checks.dependencies.total + ')');
|
|
349
|
+
for (const dep of output.checks.dependencies.items) {
|
|
350
|
+
const icon = dep.installed ? colors.green('✅') : colors.yellow('○');
|
|
351
|
+
const version = dep.version ? colors.gray(`v${dep.version}`) : colors.red('not installed');
|
|
352
|
+
console.log(` ${icon} ${dep.name} ${version}`);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// CLI Tools
|
|
356
|
+
console.log('\n🔧 CLI Tools (' + output.checks.cliTools.available + '/' + output.checks.cliTools.total + ')');
|
|
357
|
+
for (const tool of output.checks.cliTools.items) {
|
|
358
|
+
const icon = tool.installed ? colors.green('✅') : colors.yellow('○');
|
|
359
|
+
const version = tool.version ? colors.gray(`(${tool.version})`) : colors.red('not available');
|
|
360
|
+
console.log(` ${icon} ${tool.name} - ${tool.description} ${version}`);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Native binaries
|
|
364
|
+
console.log('\n⚡ Native Binaries');
|
|
365
|
+
if (output.checks.nativeBinaries.status === 'native') {
|
|
366
|
+
console.log(' ' + colors.green('✅ Native mode (fastest)'));
|
|
367
|
+
} else {
|
|
368
|
+
console.log(' ' + colors.yellow('○ CLI mode (falls back via npx)'));
|
|
369
|
+
if (output.checks.nativeBinaries.reason) {
|
|
370
|
+
console.log(' ' + colors.gray(output.checks.nativeBinaries.reason));
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Config
|
|
375
|
+
console.log('\n⚙️ Config');
|
|
376
|
+
if (output.checks.config.exists) {
|
|
377
|
+
console.log(' ' + colors.green('✅ Config file found'));
|
|
378
|
+
if (output.checks.config.optimizations.length > 0) {
|
|
379
|
+
console.log(' ' + colors.gray('Optimizations: ' + output.checks.config.optimizations.join(', ')));
|
|
380
|
+
}
|
|
381
|
+
} else {
|
|
382
|
+
console.log(' ' + colors.yellow('○ No config file (optional)'));
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Action items
|
|
386
|
+
if (output.actionItems.length > 0) {
|
|
387
|
+
console.log('\n' + colors.gray('─'.repeat(55)));
|
|
388
|
+
console.log('📋 Action Items\n');
|
|
389
|
+
|
|
390
|
+
for (const item of output.actionItems) {
|
|
391
|
+
const priorityColor = item.priority === 'critical' ? colors.red :
|
|
392
|
+
item.priority === 'high' ? colors.yellow :
|
|
393
|
+
item.priority === 'medium' ? colors.blue : colors.gray;
|
|
394
|
+
|
|
395
|
+
console.log(` [${priorityColor(item.priority.toUpperCase())}] ${item.action}`);
|
|
396
|
+
console.log(` ${colors.gray(item.reason)}`);
|
|
397
|
+
if (item.command) {
|
|
398
|
+
console.log(` ${colors.green(item.command)}`);
|
|
399
|
+
}
|
|
400
|
+
console.log();
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Quick install
|
|
405
|
+
if (output.installCommands.deps || output.installCommands.cliTools) {
|
|
406
|
+
console.log(colors.gray('─'.repeat(55)));
|
|
407
|
+
console.log('\n🚀 Quick Install\n');
|
|
408
|
+
|
|
409
|
+
if (output.installCommands.deps) {
|
|
410
|
+
console.log(' ' + colors.cyan('Dependencies:'));
|
|
411
|
+
console.log(' ' + colors.green(output.installCommands.deps));
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
if (output.installCommands.cliTools) {
|
|
415
|
+
console.log('\n ' + colors.cyan('CLI Tools:'));
|
|
416
|
+
console.log(' ' + colors.green(output.installCommands.cliTools));
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
console.log('\n' + colors.blue('═'.repeat(55)));
|
|
421
|
+
console.log(colors.gray(' Run with: bunx @hung319/opencode-hive doctor'));
|
|
422
|
+
console.log(colors.blue('═'.repeat(55)) + '\n');
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// ============================================================================
|
|
426
|
+
// Main
|
|
427
|
+
// ============================================================================
|
|
428
|
+
|
|
429
|
+
const output = runDoctor();
|
|
430
|
+
printDoctor(output);
|
|
431
|
+
|
|
432
|
+
// Exit with appropriate code
|
|
433
|
+
process.exit(output.status === 'ready' ? 0 : 1);
|
package/dist/index.js
CHANGED
|
@@ -17812,8 +17812,7 @@ async function checkPackage(packageName) {
|
|
|
17812
17812
|
const result = {
|
|
17813
17813
|
name: packageName,
|
|
17814
17814
|
package: packageName,
|
|
17815
|
-
installed: false
|
|
17816
|
-
optional: true
|
|
17815
|
+
installed: false
|
|
17817
17816
|
};
|
|
17818
17817
|
try {
|
|
17819
17818
|
const packageJsonPath = __require.resolve(`${packageName}/package.json`, {
|
|
@@ -17847,34 +17846,6 @@ function checkCliTool(name, command, description) {
|
|
|
17847
17846
|
}
|
|
17848
17847
|
return result;
|
|
17849
17848
|
}
|
|
17850
|
-
function checkAstGrepNative() {
|
|
17851
|
-
const result = {
|
|
17852
|
-
available: false,
|
|
17853
|
-
reason: ""
|
|
17854
|
-
};
|
|
17855
|
-
try {
|
|
17856
|
-
const napiPath = __require.resolve("@ast-grep/napi");
|
|
17857
|
-
const napiDir = path6.dirname(napiPath);
|
|
17858
|
-
const binaryPaths = [
|
|
17859
|
-
path6.join(napiDir, "index.node"),
|
|
17860
|
-
path6.join(napiDir, "build", "Release", "ast_grep.node"),
|
|
17861
|
-
path6.join(napiDir, "dist", "index.node")
|
|
17862
|
-
];
|
|
17863
|
-
const binaryExists = binaryPaths.some((p) => fs5.existsSync(p));
|
|
17864
|
-
if (binaryExists) {
|
|
17865
|
-
result.available = true;
|
|
17866
|
-
try {
|
|
17867
|
-
const pkg = JSON.parse(fs5.readFileSync(path6.join(napiDir, "package.json"), "utf-8"));
|
|
17868
|
-
result.version = pkg.version;
|
|
17869
|
-
} catch {}
|
|
17870
|
-
} else {
|
|
17871
|
-
result.reason = "Native binaries not compiled (tree-sitter failed to build)";
|
|
17872
|
-
}
|
|
17873
|
-
} catch (error45) {
|
|
17874
|
-
result.reason = "@ast-grep/napi not installed";
|
|
17875
|
-
}
|
|
17876
|
-
return result;
|
|
17877
|
-
}
|
|
17878
17849
|
function checkConfig() {
|
|
17879
17850
|
const checks3 = [];
|
|
17880
17851
|
const configPaths = [
|
|
@@ -17921,11 +17892,6 @@ function checkConfig() {
|
|
|
17921
17892
|
recommendation: sandboxEnabled ? `Sandbox enabled (${sandboxMode} mode)` : 'Enable sandbox: Add { "sandbox": { "mode": "docker" } } to config for isolated testing'
|
|
17922
17893
|
});
|
|
17923
17894
|
const disabledMcps = config2?.disableMcps || [];
|
|
17924
|
-
checks3.push({
|
|
17925
|
-
name: "ast_grep MCP",
|
|
17926
|
-
enabled: !disabledMcps.includes("ast_grep"),
|
|
17927
|
-
recommendation: !disabledMcps.includes("ast_grep") ? "ast_grep MCP enabled" : 'Enable ast_grep: Remove "ast_grep" from disableMcps array'
|
|
17928
|
-
});
|
|
17929
17895
|
checks3.push({
|
|
17930
17896
|
name: "veil MCP",
|
|
17931
17897
|
enabled: !disabledMcps.includes("veil"),
|
|
@@ -17942,36 +17908,36 @@ var hiveDoctorTool = tool({
|
|
|
17942
17908
|
description: `Hive Doctor - System health check with actionable fixes.
|
|
17943
17909
|
|
|
17944
17910
|
**Checks performed:**
|
|
17945
|
-
1. Dependencies -
|
|
17946
|
-
2. CLI Tools - dora, auto-cr, scip-typescript, veil
|
|
17947
|
-
3.
|
|
17948
|
-
4. Config - optimizations and MCPs enabled
|
|
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
|
|
17949
17914
|
|
|
17950
17915
|
**Output includes:**
|
|
17951
17916
|
- Status summary (healthy/warning/action-required)
|
|
17952
17917
|
- Missing items with install commands
|
|
17953
17918
|
- Action items prioritized by impact
|
|
17954
|
-
- Quick install commands for all missing items
|
|
17919
|
+
- Quick install commands for all missing items
|
|
17920
|
+
|
|
17921
|
+
**Tip:** Run standalone before installing: \`bunx @hung319/opencode-hive doctor\``,
|
|
17955
17922
|
args: {},
|
|
17956
17923
|
async execute() {
|
|
17957
17924
|
const dependencyChecks = await Promise.all([
|
|
17958
|
-
checkPackage("@ast-grep/napi"),
|
|
17959
17925
|
checkPackage("@sparkleideas/agent-booster"),
|
|
17960
17926
|
checkPackage("@sparkleideas/memory"),
|
|
17961
17927
|
checkPackage("@paretools/search"),
|
|
17962
17928
|
checkPackage("@upstash/context7-mcp"),
|
|
17963
17929
|
checkPackage("exa-mcp-server"),
|
|
17964
17930
|
checkPackage("grep-mcp"),
|
|
17965
|
-
checkPackage("
|
|
17931
|
+
checkPackage("btca"),
|
|
17932
|
+
checkPackage("opencode-model-selector")
|
|
17966
17933
|
]);
|
|
17967
17934
|
const cliToolChecks = [
|
|
17968
17935
|
checkCliTool("dora", "@butttons/dora", "SCIP-based code navigation"),
|
|
17969
17936
|
checkCliTool("auto-cr", "auto-cr-cmd", "SWC-based automated code review"),
|
|
17970
17937
|
checkCliTool("scip-typescript", "@sourcegraph/scip-typescript", "TypeScript SCIP indexer"),
|
|
17971
|
-
checkCliTool("veil", "@ushiradineth/veil", "Code discovery and retrieval")
|
|
17938
|
+
checkCliTool("veil", "@ushiradineth/veil", "Code discovery and retrieval"),
|
|
17939
|
+
checkCliTool("btca", "btca", "BTC/A agent for blockchain tasks")
|
|
17972
17940
|
];
|
|
17973
|
-
const nativeCheck = checkAstGrepNative();
|
|
17974
|
-
const nativeStatus = nativeCheck.available ? "native" : "cli-mode";
|
|
17975
17941
|
const configChecks = checkConfig();
|
|
17976
17942
|
const missingDeps = dependencyChecks.filter((d) => !d.installed);
|
|
17977
17943
|
const missingTools = cliToolChecks.filter((t) => !t.installed);
|
|
@@ -17988,15 +17954,15 @@ var hiveDoctorTool = tool({
|
|
|
17988
17954
|
priority: "high",
|
|
17989
17955
|
action: `Install ${tool3.name}`,
|
|
17990
17956
|
command: `npx -y ${tool3.command}`,
|
|
17991
|
-
reason: `${tool3.description}
|
|
17957
|
+
reason: `${tool3.description}`
|
|
17992
17958
|
});
|
|
17993
17959
|
}
|
|
17994
|
-
if (!dependencyChecks.find((d) => d.package === "
|
|
17960
|
+
if (!dependencyChecks.find((d) => d.package === "btca")?.installed) {
|
|
17995
17961
|
actionItems.push({
|
|
17996
17962
|
priority: "medium",
|
|
17997
|
-
action: "Install
|
|
17998
|
-
command: `npm install
|
|
17999
|
-
reason: "
|
|
17963
|
+
action: "Install btca for blockchain tasks",
|
|
17964
|
+
command: `npm install btca`,
|
|
17965
|
+
reason: "BTC/A agent for blockchain analysis and development"
|
|
18000
17966
|
});
|
|
18001
17967
|
}
|
|
18002
17968
|
for (const config2 of disabledConfigs) {
|
|
@@ -18013,7 +17979,6 @@ var hiveDoctorTool = tool({
|
|
|
18013
17979
|
const summary = {
|
|
18014
17980
|
dependencies: missingDeps.length === 0 ? "✅ All dependencies installed" : `⚠️ ${missingDeps.length} missing: ${missingDeps.map((d) => d.name).join(", ")}`,
|
|
18015
17981
|
cliTools: missingTools.length === 0 ? "✅ All CLI tools available" : `⚠️ ${missingTools.length} missing: ${missingTools.map((t) => t.name).join(", ")}`,
|
|
18016
|
-
nativeBinaries: nativeCheck.available ? `✅ Native mode (v${nativeCheck.version || "?"})` : `⚡ CLI mode (${nativeCheck.reason || "native unavailable"})`,
|
|
18017
17982
|
config: disabledConfigs.length === 0 ? "✅ All optimizations enabled" : `\uD83D\uDCA1 ${disabledConfigs.length} disabled: ${disabledConfigs.map((c) => c.name).join(", ")}`
|
|
18018
17983
|
};
|
|
18019
17984
|
const result = {
|
|
@@ -18030,14 +17995,6 @@ var hiveDoctorTool = tool({
|
|
|
18030
17995
|
available: cliToolChecks.filter((t) => t.installed).length,
|
|
18031
17996
|
missing: missingTools
|
|
18032
17997
|
},
|
|
18033
|
-
nativeBinaries: {
|
|
18034
|
-
status: nativeStatus,
|
|
18035
|
-
reason: nativeCheck.reason,
|
|
18036
|
-
astGrep: {
|
|
18037
|
-
available: nativeCheck.available,
|
|
18038
|
-
version: nativeCheck.version
|
|
18039
|
-
}
|
|
18040
|
-
},
|
|
18041
17998
|
config: configChecks
|
|
18042
17999
|
},
|
|
18043
18000
|
actionItems,
|
|
@@ -18056,8 +18013,8 @@ var hiveDoctorQuickTool = tool({
|
|
|
18056
18013
|
args: {},
|
|
18057
18014
|
async execute() {
|
|
18058
18015
|
const checks3 = await Promise.all([
|
|
18059
|
-
checkPackage("@ast-grep/napi"),
|
|
18060
18016
|
checkPackage("@sparkleideas/agent-booster"),
|
|
18017
|
+
checkPackage("btca"),
|
|
18061
18018
|
checkCliTool("dora", "@butttons/dora", ""),
|
|
18062
18019
|
checkCliTool("auto-cr", "auto-cr-cmd", "")
|
|
18063
18020
|
]);
|
|
@@ -18556,377 +18513,6 @@ var autoCrRulesTool = tool({
|
|
|
18556
18513
|
}
|
|
18557
18514
|
});
|
|
18558
18515
|
|
|
18559
|
-
// src/tools/ast-grep-native.ts
|
|
18560
|
-
import * as fs7 from "fs";
|
|
18561
|
-
import { spawn as spawn2 } from "child_process";
|
|
18562
|
-
var astGrepModule = null;
|
|
18563
|
-
var astGrepInitPromise = null;
|
|
18564
|
-
var nativeChecked = false;
|
|
18565
|
-
var nativeAvailable = false;
|
|
18566
|
-
function checkNativeBinariesExist() {
|
|
18567
|
-
try {
|
|
18568
|
-
const napiPath = __require.resolve("@ast-grep/napi");
|
|
18569
|
-
if (!napiPath)
|
|
18570
|
-
return false;
|
|
18571
|
-
const napiDir = __require("path").dirname(napiPath);
|
|
18572
|
-
const bindingsDir = __require("path").join(napiDir, "build", "Release");
|
|
18573
|
-
if (fs7.existsSync(bindingsDir)) {
|
|
18574
|
-
const files = fs7.readdirSync(bindingsDir);
|
|
18575
|
-
return files.some((f) => f.endsWith(".node"));
|
|
18576
|
-
}
|
|
18577
|
-
const possiblePaths = [
|
|
18578
|
-
__require("path").join(napiDir, "index.node"),
|
|
18579
|
-
__require("path").join(napiDir, "dist", "index.node")
|
|
18580
|
-
];
|
|
18581
|
-
return possiblePaths.some((p) => fs7.existsSync(p));
|
|
18582
|
-
} catch {
|
|
18583
|
-
return false;
|
|
18584
|
-
}
|
|
18585
|
-
}
|
|
18586
|
-
async function initAstGrep() {
|
|
18587
|
-
if (nativeChecked) {
|
|
18588
|
-
return;
|
|
18589
|
-
}
|
|
18590
|
-
nativeAvailable = checkNativeBinariesExist();
|
|
18591
|
-
if (!nativeAvailable) {
|
|
18592
|
-
console.log("[ast-grep] Native binaries not found, using CLI mode");
|
|
18593
|
-
nativeChecked = true;
|
|
18594
|
-
return;
|
|
18595
|
-
}
|
|
18596
|
-
if (astGrepInitPromise !== null) {
|
|
18597
|
-
await astGrepInitPromise;
|
|
18598
|
-
return;
|
|
18599
|
-
}
|
|
18600
|
-
astGrepInitPromise = (async () => {
|
|
18601
|
-
try {
|
|
18602
|
-
astGrepModule = await import("@ast-grep/napi");
|
|
18603
|
-
console.log("[ast-grep] Native NAPI initialized successfully");
|
|
18604
|
-
nativeAvailable = true;
|
|
18605
|
-
} catch (error45) {
|
|
18606
|
-
console.warn("[ast-grep] Failed to load @ast-grep/napi, falling back to CLI:", error45 instanceof Error ? error45.message : error45);
|
|
18607
|
-
astGrepModule = null;
|
|
18608
|
-
nativeAvailable = false;
|
|
18609
|
-
} finally {
|
|
18610
|
-
nativeChecked = true;
|
|
18611
|
-
}
|
|
18612
|
-
})();
|
|
18613
|
-
await astGrepInitPromise;
|
|
18614
|
-
}
|
|
18615
|
-
async function getAstGrepStatus() {
|
|
18616
|
-
await initAstGrep();
|
|
18617
|
-
if (nativeAvailable && astGrepModule) {
|
|
18618
|
-
try {
|
|
18619
|
-
const pkg = await import("@ast-grep/napi/package.json", { assert: { type: "json" } });
|
|
18620
|
-
return {
|
|
18621
|
-
available: true,
|
|
18622
|
-
mode: "native",
|
|
18623
|
-
version: pkg.default.version || "unknown"
|
|
18624
|
-
};
|
|
18625
|
-
} catch {
|
|
18626
|
-
return { available: true, mode: "native", version: "unknown" };
|
|
18627
|
-
}
|
|
18628
|
-
}
|
|
18629
|
-
const cliAvailable = await checkCliAvailable();
|
|
18630
|
-
return {
|
|
18631
|
-
available: cliAvailable,
|
|
18632
|
-
mode: cliAvailable ? "cli" : "unavailable"
|
|
18633
|
-
};
|
|
18634
|
-
}
|
|
18635
|
-
async function checkCliAvailable() {
|
|
18636
|
-
return new Promise((resolve) => {
|
|
18637
|
-
const proc = spawn2("npx", ["-y", "@notprolands/ast-grep-mcp", "--help"], {
|
|
18638
|
-
timeout: 3000,
|
|
18639
|
-
shell: true
|
|
18640
|
-
});
|
|
18641
|
-
proc.on("close", (code) => {
|
|
18642
|
-
resolve(code === 0);
|
|
18643
|
-
});
|
|
18644
|
-
proc.on("error", () => {
|
|
18645
|
-
resolve(false);
|
|
18646
|
-
});
|
|
18647
|
-
setTimeout(() => {
|
|
18648
|
-
try {
|
|
18649
|
-
proc.kill();
|
|
18650
|
-
} catch {}
|
|
18651
|
-
resolve(false);
|
|
18652
|
-
}, 3000);
|
|
18653
|
-
});
|
|
18654
|
-
}
|
|
18655
|
-
var astGrepDumpSyntaxTreeTool = tool({
|
|
18656
|
-
description: `Dump code's syntax structure or dump a query's pattern structure.
|
|
18657
|
-
|
|
18658
|
-
This is useful to discover correct syntax kind and syntax tree structure. Call it when debugging a rule.
|
|
18659
|
-
|
|
18660
|
-
**Parameters:**
|
|
18661
|
-
- code: The code you need
|
|
18662
|
-
- language: Programming language (typescript, javascript, python, rust, go, java, etc.)
|
|
18663
|
-
- format: Output format - 'cst' (concrete syntax tree) or 'pattern' (to inspect rule patterns)
|
|
18664
|
-
|
|
18665
|
-
**Use when:**
|
|
18666
|
-
- Debugging AST patterns
|
|
18667
|
-
- Finding correct syntax kind names
|
|
18668
|
-
- Understanding code structure`,
|
|
18669
|
-
args: {
|
|
18670
|
-
code: tool.schema.string().describe("The code to analyze"),
|
|
18671
|
-
language: tool.schema.string().describe("Programming language (typescript, javascript, python, rust, go, java, etc.)"),
|
|
18672
|
-
format: tool.schema.enum(["cst", "pattern"]).default("cst").describe("Output format")
|
|
18673
|
-
},
|
|
18674
|
-
async execute({ code, language, format }) {
|
|
18675
|
-
await initAstGrep();
|
|
18676
|
-
if (nativeAvailable && astGrepModule) {
|
|
18677
|
-
try {
|
|
18678
|
-
return executeNativeDump(code, language, format, astGrepModule);
|
|
18679
|
-
} catch (error45) {
|
|
18680
|
-
console.warn("[ast-grep] Native failed, trying CLI:", error45 instanceof Error ? error45.message : error45);
|
|
18681
|
-
}
|
|
18682
|
-
}
|
|
18683
|
-
return JSON.stringify({
|
|
18684
|
-
success: true,
|
|
18685
|
-
mode: "cli",
|
|
18686
|
-
message: "CLI mode - limited functionality. Install @ast-grep/napi for full native support.",
|
|
18687
|
-
suggestion: "Run: npm install @ast-grep/napi",
|
|
18688
|
-
format,
|
|
18689
|
-
language,
|
|
18690
|
-
example: {
|
|
18691
|
-
cst: "Use ast_grep MCP tool via ast_grep_search for pattern matching"
|
|
18692
|
-
}
|
|
18693
|
-
}, null, 2);
|
|
18694
|
-
}
|
|
18695
|
-
});
|
|
18696
|
-
function executeNativeDump(code, language, format, mod) {
|
|
18697
|
-
const langMap = {
|
|
18698
|
-
typescript: "TypeScript",
|
|
18699
|
-
javascript: "JavaScript",
|
|
18700
|
-
tsx: "Tsx",
|
|
18701
|
-
jsx: "Jsx",
|
|
18702
|
-
python: "Python",
|
|
18703
|
-
rust: "Rust",
|
|
18704
|
-
go: "Go",
|
|
18705
|
-
java: "Java"
|
|
18706
|
-
};
|
|
18707
|
-
const lang = langMap[language.toLowerCase()] || language;
|
|
18708
|
-
const Lang = mod.Lang;
|
|
18709
|
-
if (!Lang || !Lang[lang]) {
|
|
18710
|
-
return JSON.stringify({
|
|
18711
|
-
success: false,
|
|
18712
|
-
error: `Unsupported language: ${language}`,
|
|
18713
|
-
availableLanguages: Object.keys(langMap)
|
|
18714
|
-
}, null, 2);
|
|
18715
|
-
}
|
|
18716
|
-
if (format === "pattern") {
|
|
18717
|
-
return JSON.stringify({
|
|
18718
|
-
success: true,
|
|
18719
|
-
format: "pattern",
|
|
18720
|
-
language,
|
|
18721
|
-
example: {
|
|
18722
|
-
match: "AwaitExpression",
|
|
18723
|
-
kind: "Use kind to match AST node types",
|
|
18724
|
-
pattern: "Use pattern for code templates"
|
|
18725
|
-
}
|
|
18726
|
-
}, null, 2);
|
|
18727
|
-
}
|
|
18728
|
-
const parse5 = mod.parse;
|
|
18729
|
-
const ast = parse5(Lang[lang], code);
|
|
18730
|
-
const root = ast.root();
|
|
18731
|
-
const dump = (node) => {
|
|
18732
|
-
if (!node)
|
|
18733
|
-
return null;
|
|
18734
|
-
return {
|
|
18735
|
-
kind: node.kind(),
|
|
18736
|
-
text: node.text(),
|
|
18737
|
-
children: node.children().map((child) => dump(child))
|
|
18738
|
-
};
|
|
18739
|
-
};
|
|
18740
|
-
return JSON.stringify({
|
|
18741
|
-
success: true,
|
|
18742
|
-
format: "cst",
|
|
18743
|
-
mode: "native",
|
|
18744
|
-
language,
|
|
18745
|
-
tree: dump(root)
|
|
18746
|
-
}, null, 2);
|
|
18747
|
-
}
|
|
18748
|
-
var astGrepTestMatchCodeRuleTool = tool({
|
|
18749
|
-
description: `Test a code against an ast-grep YAML rule.
|
|
18750
|
-
|
|
18751
|
-
This is useful to test a rule before using it in a project.
|
|
18752
|
-
|
|
18753
|
-
**Parameters:**
|
|
18754
|
-
- code: The code to test against the rule
|
|
18755
|
-
- yaml: The ast-grep YAML rule to test`,
|
|
18756
|
-
args: {
|
|
18757
|
-
code: tool.schema.string().describe("The code to test against the rule"),
|
|
18758
|
-
yaml: tool.schema.string().describe("The ast-grep YAML rule to search")
|
|
18759
|
-
},
|
|
18760
|
-
async execute({ code, yaml }) {
|
|
18761
|
-
await initAstGrep();
|
|
18762
|
-
if (nativeAvailable && astGrepModule) {
|
|
18763
|
-
try {
|
|
18764
|
-
const parse5 = astGrepModule.parse;
|
|
18765
|
-
const Lang = astGrepModule.Lang;
|
|
18766
|
-
parse5(Lang.TypeScript, code);
|
|
18767
|
-
return JSON.stringify({
|
|
18768
|
-
success: true,
|
|
18769
|
-
mode: "native",
|
|
18770
|
-
matched: false,
|
|
18771
|
-
note: "YAML rule testing works best with ast_grep MCP tool"
|
|
18772
|
-
}, null, 2);
|
|
18773
|
-
} catch (error45) {}
|
|
18774
|
-
}
|
|
18775
|
-
return JSON.stringify({
|
|
18776
|
-
success: true,
|
|
18777
|
-
mode: "cli",
|
|
18778
|
-
note: "Use ast_grep MCP tool (ast_grep_search) for YAML rule testing"
|
|
18779
|
-
}, null, 2);
|
|
18780
|
-
}
|
|
18781
|
-
});
|
|
18782
|
-
var astGrepFindCodeTool = tool({
|
|
18783
|
-
description: `Find code in a project folder that matches the given ast-grep pattern.
|
|
18784
|
-
|
|
18785
|
-
**Parameters:**
|
|
18786
|
-
- project_folder: The absolute path to the project folder
|
|
18787
|
-
- pattern: The ast-grep pattern to search for
|
|
18788
|
-
- language: Optional - programming language filter`,
|
|
18789
|
-
args: {
|
|
18790
|
-
project_folder: tool.schema.string().describe("The absolute path to the project folder"),
|
|
18791
|
-
pattern: tool.schema.string().describe("The ast-grep pattern to search for"),
|
|
18792
|
-
language: tool.schema.string().optional().describe("Programming language filter")
|
|
18793
|
-
},
|
|
18794
|
-
async execute({ project_folder, pattern, language }) {
|
|
18795
|
-
await initAstGrep();
|
|
18796
|
-
if (!fs7.existsSync(project_folder)) {
|
|
18797
|
-
return JSON.stringify({
|
|
18798
|
-
success: false,
|
|
18799
|
-
error: `Path not found: ${project_folder}`
|
|
18800
|
-
}, null, 2);
|
|
18801
|
-
}
|
|
18802
|
-
if (nativeAvailable && astGrepModule) {
|
|
18803
|
-
try {
|
|
18804
|
-
return executeNativeFind(project_folder, pattern, language, astGrepModule);
|
|
18805
|
-
} catch (error45) {
|
|
18806
|
-
console.warn("[ast-grep] Native find failed:", error45 instanceof Error ? error45.message : error45);
|
|
18807
|
-
}
|
|
18808
|
-
}
|
|
18809
|
-
const lang = language || "typescript";
|
|
18810
|
-
return JSON.stringify({
|
|
18811
|
-
success: true,
|
|
18812
|
-
mode: "cli",
|
|
18813
|
-
message: "CLI mode active - for best results, use ast_grep MCP tool",
|
|
18814
|
-
suggestion: "Use ast_grep MCP with ast_grep_search for pattern matching",
|
|
18815
|
-
parameters: {
|
|
18816
|
-
projectFolder: project_folder,
|
|
18817
|
-
pattern,
|
|
18818
|
-
language: lang
|
|
18819
|
-
}
|
|
18820
|
-
}, null, 2);
|
|
18821
|
-
}
|
|
18822
|
-
});
|
|
18823
|
-
function executeNativeFind(project_folder, pattern, language, mod) {
|
|
18824
|
-
const langMap = {
|
|
18825
|
-
typescript: "TypeScript",
|
|
18826
|
-
javascript: "JavaScript",
|
|
18827
|
-
tsx: "Tsx",
|
|
18828
|
-
jsx: "Jsx",
|
|
18829
|
-
python: "Python",
|
|
18830
|
-
rust: "Rust",
|
|
18831
|
-
go: "Go",
|
|
18832
|
-
java: "Java"
|
|
18833
|
-
};
|
|
18834
|
-
const lang = language ? langMap[language.toLowerCase()] || language : "TypeScript";
|
|
18835
|
-
const Lang = mod.Lang;
|
|
18836
|
-
if (!Lang[lang]) {
|
|
18837
|
-
return JSON.stringify({
|
|
18838
|
-
success: false,
|
|
18839
|
-
error: `Unsupported language: ${language}`
|
|
18840
|
-
}, null, 2);
|
|
18841
|
-
}
|
|
18842
|
-
const findInFiles = mod.findInFiles;
|
|
18843
|
-
const results = [];
|
|
18844
|
-
return JSON.stringify({
|
|
18845
|
-
success: true,
|
|
18846
|
-
mode: "native",
|
|
18847
|
-
count: results.length,
|
|
18848
|
-
message: "Native find - see ast_grep MCP for full pattern matching"
|
|
18849
|
-
}, null, 2);
|
|
18850
|
-
}
|
|
18851
|
-
var astGrepScanCodeTool = tool({
|
|
18852
|
-
description: `Analyze TypeScript/JS code for common bugs, performance issues and best practices.
|
|
18853
|
-
|
|
18854
|
-
**Parameters:**
|
|
18855
|
-
- project_folder: Optional - path to scan (defaults to current directory)`,
|
|
18856
|
-
args: {
|
|
18857
|
-
project_folder: tool.schema.string().optional().describe("Path to scan")
|
|
18858
|
-
},
|
|
18859
|
-
async execute({ project_folder }) {
|
|
18860
|
-
await initAstGrep();
|
|
18861
|
-
const scanPath = project_folder || process.cwd();
|
|
18862
|
-
if (!fs7.existsSync(scanPath)) {
|
|
18863
|
-
return JSON.stringify({
|
|
18864
|
-
success: false,
|
|
18865
|
-
error: `Path not found: ${scanPath}`
|
|
18866
|
-
}, null, 2);
|
|
18867
|
-
}
|
|
18868
|
-
const status = await getAstGrepStatus();
|
|
18869
|
-
return JSON.stringify({
|
|
18870
|
-
success: true,
|
|
18871
|
-
scanned: scanPath,
|
|
18872
|
-
mode: status.mode,
|
|
18873
|
-
message: status.mode === "native" ? "Scan complete - no issues found" : "CLI mode - for full scan, install @ast-grep/napi or use ast_grep MCP"
|
|
18874
|
-
}, null, 2);
|
|
18875
|
-
}
|
|
18876
|
-
});
|
|
18877
|
-
var astGrepRewriteCodeTool = tool({
|
|
18878
|
-
description: `Transform and refactor code using AST-based find-and-replace patterns.
|
|
18879
|
-
|
|
18880
|
-
**Parameters:**
|
|
18881
|
-
- project_folder: Path to the project folder
|
|
18882
|
-
- pattern: AST pattern to find
|
|
18883
|
-
- replacement: Replacement pattern
|
|
18884
|
-
- language: Programming language`,
|
|
18885
|
-
args: {
|
|
18886
|
-
project_folder: tool.schema.string().describe("Path to the project folder"),
|
|
18887
|
-
pattern: tool.schema.string().describe("AST pattern to find"),
|
|
18888
|
-
replacement: tool.schema.string().describe("Replacement pattern"),
|
|
18889
|
-
language: tool.schema.string().optional().default("TypeScript").describe("Programming language")
|
|
18890
|
-
},
|
|
18891
|
-
async execute({ project_folder, pattern, replacement, language }) {
|
|
18892
|
-
await initAstGrep();
|
|
18893
|
-
return JSON.stringify({
|
|
18894
|
-
success: true,
|
|
18895
|
-
message: "Full rewrite requires @ast-grep/cli with config file",
|
|
18896
|
-
suggestion: "Use ast_grep MCP tool for search, then hive_code_edit for replacements",
|
|
18897
|
-
parameters: { project_folder, pattern, replacement, language }
|
|
18898
|
-
}, null, 2);
|
|
18899
|
-
}
|
|
18900
|
-
});
|
|
18901
|
-
var astGrepAnalyzeImportsTool = tool({
|
|
18902
|
-
description: `Analyze import statements and dependencies in your codebase.
|
|
18903
|
-
|
|
18904
|
-
**Parameters:**
|
|
18905
|
-
- mode: "usage" or "discovery"
|
|
18906
|
-
- path: Directory or file to analyze`,
|
|
18907
|
-
args: {
|
|
18908
|
-
mode: tool.schema.enum(["usage", "discovery"]).default("usage").describe("Analysis mode"),
|
|
18909
|
-
path: tool.schema.string().optional().describe("Directory or file to analyze")
|
|
18910
|
-
},
|
|
18911
|
-
async execute({ mode, path: path7 }) {
|
|
18912
|
-
await initAstGrep();
|
|
18913
|
-
const analyzePath = path7 || process.cwd();
|
|
18914
|
-
if (!fs7.existsSync(analyzePath)) {
|
|
18915
|
-
return JSON.stringify({
|
|
18916
|
-
success: false,
|
|
18917
|
-
error: `Path not found: ${analyzePath}`
|
|
18918
|
-
}, null, 2);
|
|
18919
|
-
}
|
|
18920
|
-
const status = await getAstGrepStatus();
|
|
18921
|
-
return JSON.stringify({
|
|
18922
|
-
success: true,
|
|
18923
|
-
mode: status.mode,
|
|
18924
|
-
path: analyzePath,
|
|
18925
|
-
message: status.mode === "native" ? "Import analysis complete" : "CLI mode - for full analysis, use ast_grep MCP or install @ast-grep/napi"
|
|
18926
|
-
}, null, 2);
|
|
18927
|
-
}
|
|
18928
|
-
});
|
|
18929
|
-
|
|
18930
18516
|
// src/agents/hive.ts
|
|
18931
18517
|
var QUEEN_BEE_PROMPT = `# Zetta (Hybrid)
|
|
18932
18518
|
|
|
@@ -20266,20 +19852,13 @@ var veilMcp = {
|
|
|
20266
19852
|
command: ["npx", "-y", "@ushiradineth/veil@latest", "mcp", "server"]
|
|
20267
19853
|
};
|
|
20268
19854
|
|
|
20269
|
-
// src/mcp/ast-grep.ts
|
|
20270
|
-
var astGrepMcp = {
|
|
20271
|
-
type: "local",
|
|
20272
|
-
command: ["npx", "-y", "@notprolands/ast-grep-mcp"]
|
|
20273
|
-
};
|
|
20274
|
-
|
|
20275
19855
|
// src/mcp/index.ts
|
|
20276
19856
|
var allBuiltinMcps = {
|
|
20277
19857
|
websearch: websearchMcp,
|
|
20278
19858
|
context7: context7Mcp,
|
|
20279
19859
|
grep_app: grepAppMcp,
|
|
20280
19860
|
pare_search: pareSearchMcp,
|
|
20281
|
-
veil: veilMcp
|
|
20282
|
-
ast_grep: astGrepMcp
|
|
19861
|
+
veil: veilMcp
|
|
20283
19862
|
};
|
|
20284
19863
|
var createBuiltinMcps = (disabledMcps = []) => {
|
|
20285
19864
|
const disabled = new Set(disabledMcps);
|
|
@@ -20291,7 +19870,7 @@ import { createRequire as createRequire2 } from "node:module";
|
|
|
20291
19870
|
import * as path7 from "path";
|
|
20292
19871
|
import * as os3 from "os";
|
|
20293
19872
|
import * as path22 from "path";
|
|
20294
|
-
import * as
|
|
19873
|
+
import * as fs7 from "fs";
|
|
20295
19874
|
import * as path32 from "path";
|
|
20296
19875
|
import * as fs22 from "fs";
|
|
20297
19876
|
import * as fs32 from "fs";
|
|
@@ -20300,10 +19879,10 @@ import * as fs52 from "fs";
|
|
|
20300
19879
|
import * as fs72 from "fs/promises";
|
|
20301
19880
|
import * as path42 from "path";
|
|
20302
19881
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
20303
|
-
import { spawn as
|
|
19882
|
+
import { spawn as spawn2 } from "child_process";
|
|
20304
19883
|
import { normalize } from "node:path";
|
|
20305
19884
|
import { EventEmitter } from "node:events";
|
|
20306
|
-
import * as
|
|
19885
|
+
import * as fs8 from "fs";
|
|
20307
19886
|
import * as path52 from "path";
|
|
20308
19887
|
import * as fs10 from "fs";
|
|
20309
19888
|
import * as path72 from "path";
|
|
@@ -21237,22 +20816,22 @@ function getSubtaskReportPath(projectRoot, featureName, taskFolder, subtaskFolde
|
|
|
21237
20816
|
return path22.join(getSubtaskPath(projectRoot, featureName, taskFolder, subtaskFolder), REPORT_FILE);
|
|
21238
20817
|
}
|
|
21239
20818
|
function ensureDir(dirPath) {
|
|
21240
|
-
if (!
|
|
21241
|
-
|
|
20819
|
+
if (!fs7.existsSync(dirPath)) {
|
|
20820
|
+
fs7.mkdirSync(dirPath, { recursive: true });
|
|
21242
20821
|
}
|
|
21243
20822
|
}
|
|
21244
20823
|
function fileExists(filePath) {
|
|
21245
|
-
return
|
|
20824
|
+
return fs7.existsSync(filePath);
|
|
21246
20825
|
}
|
|
21247
20826
|
function readJson(filePath) {
|
|
21248
|
-
if (!
|
|
20827
|
+
if (!fs7.existsSync(filePath))
|
|
21249
20828
|
return null;
|
|
21250
|
-
const content =
|
|
20829
|
+
const content = fs7.readFileSync(filePath, "utf-8");
|
|
21251
20830
|
return JSON.parse(content);
|
|
21252
20831
|
}
|
|
21253
20832
|
function writeJson(filePath, data) {
|
|
21254
20833
|
ensureDir(path22.dirname(filePath));
|
|
21255
|
-
|
|
20834
|
+
fs7.writeFileSync(filePath, JSON.stringify(data, null, 2));
|
|
21256
20835
|
}
|
|
21257
20836
|
var DEFAULT_LOCK_OPTIONS = {
|
|
21258
20837
|
timeout: 5000,
|
|
@@ -21264,7 +20843,7 @@ function getLockPath(filePath) {
|
|
|
21264
20843
|
}
|
|
21265
20844
|
function isLockStale(lockPath, staleTTL) {
|
|
21266
20845
|
try {
|
|
21267
|
-
const stat2 =
|
|
20846
|
+
const stat2 = fs7.statSync(lockPath);
|
|
21268
20847
|
const age = Date.now() - stat2.mtimeMs;
|
|
21269
20848
|
return age > staleTTL;
|
|
21270
20849
|
} catch {
|
|
@@ -21284,12 +20863,12 @@ function acquireLockSync(filePath, options = {}) {
|
|
|
21284
20863
|
ensureDir(lockDir);
|
|
21285
20864
|
while (true) {
|
|
21286
20865
|
try {
|
|
21287
|
-
const fd =
|
|
21288
|
-
|
|
21289
|
-
|
|
20866
|
+
const fd = fs7.openSync(lockPath, fs7.constants.O_CREAT | fs7.constants.O_EXCL | fs7.constants.O_WRONLY);
|
|
20867
|
+
fs7.writeSync(fd, lockContent);
|
|
20868
|
+
fs7.closeSync(fd);
|
|
21290
20869
|
return () => {
|
|
21291
20870
|
try {
|
|
21292
|
-
|
|
20871
|
+
fs7.unlinkSync(lockPath);
|
|
21293
20872
|
} catch {}
|
|
21294
20873
|
};
|
|
21295
20874
|
} catch (err) {
|
|
@@ -21299,7 +20878,7 @@ function acquireLockSync(filePath, options = {}) {
|
|
|
21299
20878
|
} else if (error45.code === "EEXIST") {
|
|
21300
20879
|
if (isLockStale(lockPath, opts.staleLockTTL)) {
|
|
21301
20880
|
try {
|
|
21302
|
-
|
|
20881
|
+
fs7.unlinkSync(lockPath);
|
|
21303
20882
|
continue;
|
|
21304
20883
|
} catch {}
|
|
21305
20884
|
}
|
|
@@ -21318,11 +20897,11 @@ function writeAtomic(filePath, content) {
|
|
|
21318
20897
|
ensureDir(path22.dirname(filePath));
|
|
21319
20898
|
const tempPath = `${filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
21320
20899
|
try {
|
|
21321
|
-
|
|
21322
|
-
|
|
20900
|
+
fs7.writeFileSync(tempPath, content);
|
|
20901
|
+
fs7.renameSync(tempPath, filePath);
|
|
21323
20902
|
} catch (error45) {
|
|
21324
20903
|
try {
|
|
21325
|
-
|
|
20904
|
+
fs7.unlinkSync(tempPath);
|
|
21326
20905
|
} catch {}
|
|
21327
20906
|
throw error45;
|
|
21328
20907
|
}
|
|
@@ -21357,13 +20936,13 @@ function patchJsonLockedSync(filePath, patch, options = {}) {
|
|
|
21357
20936
|
}
|
|
21358
20937
|
}
|
|
21359
20938
|
function readText(filePath) {
|
|
21360
|
-
if (!
|
|
20939
|
+
if (!fs7.existsSync(filePath))
|
|
21361
20940
|
return null;
|
|
21362
|
-
return
|
|
20941
|
+
return fs7.readFileSync(filePath, "utf-8");
|
|
21363
20942
|
}
|
|
21364
20943
|
function writeText(filePath, content) {
|
|
21365
20944
|
ensureDir(path22.dirname(filePath));
|
|
21366
|
-
|
|
20945
|
+
fs7.writeFileSync(filePath, content);
|
|
21367
20946
|
}
|
|
21368
20947
|
function detectContext(cwd) {
|
|
21369
20948
|
const result = {
|
|
@@ -23454,7 +23033,7 @@ var init_git_executor_chain = __esm2({
|
|
|
23454
23033
|
rejection = reason || rejection;
|
|
23455
23034
|
}
|
|
23456
23035
|
});
|
|
23457
|
-
const spawned =
|
|
23036
|
+
const spawned = spawn2(command, args2, spawnOptions);
|
|
23458
23037
|
spawned.stdout.on("data", onDataReceived(stdOut, "stdOut", logger, outputLogger.step("stdOut")));
|
|
23459
23038
|
spawned.stderr.on("data", onDataReceived(stdErr, "stdErr", logger, outputLogger.step("stdErr")));
|
|
23460
23039
|
spawned.on("error", onErrorReceived(stdErr, logger));
|
|
@@ -26648,10 +26227,10 @@ class ContextService {
|
|
|
26648
26227
|
const contextPath = getContextPath(this.projectRoot, featureName);
|
|
26649
26228
|
if (!fileExists(contextPath))
|
|
26650
26229
|
return [];
|
|
26651
|
-
const files =
|
|
26230
|
+
const files = fs8.readdirSync(contextPath, { withFileTypes: true }).filter((f) => f.isFile() && f.name.endsWith(".md")).map((f) => f.name);
|
|
26652
26231
|
return files.map((name) => {
|
|
26653
26232
|
const filePath = path52.join(contextPath, name);
|
|
26654
|
-
const stat2 =
|
|
26233
|
+
const stat2 = fs8.statSync(filePath);
|
|
26655
26234
|
const content = readText(filePath) || "";
|
|
26656
26235
|
return {
|
|
26657
26236
|
name: name.replace(/\.md$/, ""),
|
|
@@ -26664,7 +26243,7 @@ class ContextService {
|
|
|
26664
26243
|
const contextPath = getContextPath(this.projectRoot, featureName);
|
|
26665
26244
|
const filePath = path52.join(contextPath, this.normalizeFileName(fileName));
|
|
26666
26245
|
if (fileExists(filePath)) {
|
|
26667
|
-
|
|
26246
|
+
fs8.unlinkSync(filePath);
|
|
26668
26247
|
return true;
|
|
26669
26248
|
}
|
|
26670
26249
|
return false;
|
|
@@ -26695,8 +26274,8 @@ ${f.content}`);
|
|
|
26695
26274
|
const archiveName = `${timestamp}_${ctx.name}.md`;
|
|
26696
26275
|
const src = path52.join(contextPath, `${ctx.name}.md`);
|
|
26697
26276
|
const dest = path52.join(archiveDir, archiveName);
|
|
26698
|
-
|
|
26699
|
-
|
|
26277
|
+
fs8.copyFileSync(src, dest);
|
|
26278
|
+
fs8.unlinkSync(src);
|
|
26700
26279
|
archived.push(ctx.name);
|
|
26701
26280
|
}
|
|
26702
26281
|
return { archived, archivePath: archiveDir };
|
|
@@ -28558,12 +28137,6 @@ ${snapshot}
|
|
|
28558
28137
|
auto_cr_scan: autoCrScanTool,
|
|
28559
28138
|
auto_cr_diff: autoCrDiffTool,
|
|
28560
28139
|
auto_cr_rules: autoCrRulesTool,
|
|
28561
|
-
ast_grep_dump_syntax_tree: astGrepDumpSyntaxTreeTool,
|
|
28562
|
-
ast_grep_test_match_code_rule: astGrepTestMatchCodeRuleTool,
|
|
28563
|
-
ast_grep_find_code: astGrepFindCodeTool,
|
|
28564
|
-
ast_grep_scan_code: astGrepScanCodeTool,
|
|
28565
|
-
ast_grep_rewrite_code: astGrepRewriteCodeTool,
|
|
28566
|
-
ast_grep_analyze_imports: astGrepAnalyzeImportsTool,
|
|
28567
28140
|
hive_skill: createHiveSkillTool(filteredSkills),
|
|
28568
28141
|
hive_feature_create: tool({
|
|
28569
28142
|
description: "Create a new feature and set it as active",
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hung319/opencode-hive",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
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",
|
|
@@ -28,7 +31,7 @@
|
|
|
28
31
|
"scripts": {
|
|
29
32
|
"clean": "rm -rf dist",
|
|
30
33
|
"generate-skills": "bun run scripts/generate-skills.ts",
|
|
31
|
-
"build": "npm run clean && npm run generate-skills && bun build src/index.ts --outdir dist --target node --format esm --packages=bundle
|
|
34
|
+
"build": "npm run clean && npm run generate-skills && bun build src/index.ts --outdir dist --target node --format esm --packages=bundle && tsc --emitDeclarationOnly",
|
|
32
35
|
"dev": "opencode plugin dev",
|
|
33
36
|
"test": "bun test"
|
|
34
37
|
},
|
|
@@ -36,12 +39,10 @@
|
|
|
36
39
|
"@opencode-ai/plugin": ">=0.13.7"
|
|
37
40
|
},
|
|
38
41
|
"dependencies": {
|
|
39
|
-
"@ast-grep/napi": "^0.41.1",
|
|
40
42
|
"simple-git": "^3.27.0"
|
|
41
43
|
},
|
|
42
44
|
"optionalDependencies": {
|
|
43
45
|
"grep-mcp": "^1.1.0",
|
|
44
|
-
"@notprolands/ast-grep-mcp": "^1.1.1",
|
|
45
46
|
"@upstash/context7-mcp": "^2.1.0",
|
|
46
47
|
"exa-mcp-server": "^3.1.5",
|
|
47
48
|
"@sparkleideas/agent-booster": "^0.2.3",
|
package/dist/mcp/ast-grep.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { type ToolDefinition } from "@opencode-ai/plugin";
|
|
2
|
-
/**
|
|
3
|
-
* Check if native ast-grep is available
|
|
4
|
-
*/
|
|
5
|
-
export declare function isAstGrepAvailable(): Promise<boolean>;
|
|
6
|
-
/**
|
|
7
|
-
* Get ast-grep status
|
|
8
|
-
*/
|
|
9
|
-
export declare function getAstGrepStatus(): Promise<{
|
|
10
|
-
available: boolean;
|
|
11
|
-
mode: 'native' | 'cli' | 'unavailable';
|
|
12
|
-
version?: string;
|
|
13
|
-
}>;
|
|
14
|
-
export declare const astGrepDumpSyntaxTreeTool: ToolDefinition;
|
|
15
|
-
export declare const astGrepTestMatchCodeRuleTool: ToolDefinition;
|
|
16
|
-
export declare const astGrepFindCodeTool: ToolDefinition;
|
|
17
|
-
export declare const astGrepScanCodeTool: ToolDefinition;
|
|
18
|
-
export declare const astGrepRewriteCodeTool: ToolDefinition;
|
|
19
|
-
export declare const astGrepAnalyzeImportsTool: ToolDefinition;
|