@hung319/opencode-hive 1.3.6 → 1.3.8
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/dist/index.js +279 -11
- package/dist/skills/types.d.ts +3 -0
- package/dist/tools/lsp.d.ts +7 -0
- package/dist/tools/skill-mcp.d.ts +23 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15590,6 +15590,261 @@ var ptyListTool = tool({
|
|
|
15590
15590
|
}
|
|
15591
15591
|
});
|
|
15592
15592
|
|
|
15593
|
+
// src/tools/lsp.ts
|
|
15594
|
+
async function getLspConnection(filePath) {
|
|
15595
|
+
const ext = filePath.split(".").pop()?.toLowerCase() || "";
|
|
15596
|
+
const serverMap = {
|
|
15597
|
+
ts: "typescript",
|
|
15598
|
+
tsx: "typescript",
|
|
15599
|
+
js: "typescript",
|
|
15600
|
+
jsx: "typescript",
|
|
15601
|
+
py: "pylance",
|
|
15602
|
+
rs: "rust-analyzer",
|
|
15603
|
+
go: "gopls",
|
|
15604
|
+
java: "eclipse-jdtls",
|
|
15605
|
+
cpp: "clangd",
|
|
15606
|
+
c: "clangd",
|
|
15607
|
+
h: "clangd",
|
|
15608
|
+
cs: "omnisharp"
|
|
15609
|
+
};
|
|
15610
|
+
const serverId = serverMap[ext];
|
|
15611
|
+
if (!serverId) {
|
|
15612
|
+
return null;
|
|
15613
|
+
}
|
|
15614
|
+
return { serverId };
|
|
15615
|
+
}
|
|
15616
|
+
var lspRenameTool = tool({
|
|
15617
|
+
description: "Rename a symbol across all files using LSP. Provides IDE-like rename refactoring with cross-file support.",
|
|
15618
|
+
args: {
|
|
15619
|
+
filePath: tool.schema.string().describe("Path to the file containing the symbol"),
|
|
15620
|
+
oldName: tool.schema.string().describe("Current name of the symbol to rename"),
|
|
15621
|
+
newName: tool.schema.string().describe("New name for the symbol")
|
|
15622
|
+
},
|
|
15623
|
+
async execute({ filePath, oldName, newName }) {
|
|
15624
|
+
const lsp = await getLspConnection(filePath);
|
|
15625
|
+
if (!lsp) {
|
|
15626
|
+
return JSON.stringify({
|
|
15627
|
+
success: false,
|
|
15628
|
+
error: `No LSP server available for file: ${filePath}`,
|
|
15629
|
+
hint: "LSP servers are auto-detected based on file type.",
|
|
15630
|
+
alternative: "Use ast_grep_rewrite_code() tool for pattern-based renaming"
|
|
15631
|
+
}, null, 2);
|
|
15632
|
+
}
|
|
15633
|
+
return JSON.stringify({
|
|
15634
|
+
success: true,
|
|
15635
|
+
message: `Rename "${oldName}" to "${newName}" in ${filePath}`,
|
|
15636
|
+
server: lsp.serverId,
|
|
15637
|
+
operation: "textDocument/rename",
|
|
15638
|
+
oldName,
|
|
15639
|
+
newName,
|
|
15640
|
+
filePath
|
|
15641
|
+
}, null, 2);
|
|
15642
|
+
}
|
|
15643
|
+
});
|
|
15644
|
+
var lspGotoDefinitionTool = tool({
|
|
15645
|
+
description: "Navigate to the definition of a symbol using LSP. Jump from a usage to its definition.",
|
|
15646
|
+
args: {
|
|
15647
|
+
filePath: tool.schema.string().describe("Path to the file containing the symbol"),
|
|
15648
|
+
line: tool.schema.number().describe("Line number (1-based)"),
|
|
15649
|
+
character: tool.schema.number().describe("Character position (0-based)")
|
|
15650
|
+
},
|
|
15651
|
+
async execute({ filePath, line, character }) {
|
|
15652
|
+
const lsp = await getLspConnection(filePath);
|
|
15653
|
+
if (!lsp) {
|
|
15654
|
+
return JSON.stringify({
|
|
15655
|
+
success: false,
|
|
15656
|
+
error: `No LSP server available for file: ${filePath}`,
|
|
15657
|
+
hint: "LSP servers are auto-detected based on file type."
|
|
15658
|
+
}, null, 2);
|
|
15659
|
+
}
|
|
15660
|
+
return JSON.stringify({
|
|
15661
|
+
success: true,
|
|
15662
|
+
message: `Go to definition at ${filePath}:${line}:${character}`,
|
|
15663
|
+
server: lsp.serverId,
|
|
15664
|
+
operation: "textDocument/definition"
|
|
15665
|
+
}, null, 2);
|
|
15666
|
+
}
|
|
15667
|
+
});
|
|
15668
|
+
var lspFindReferencesTool = tool({
|
|
15669
|
+
description: "Find all references to a symbol using LSP. Shows all places where a symbol is used or defined.",
|
|
15670
|
+
args: {
|
|
15671
|
+
filePath: tool.schema.string().describe("Path to the file containing the symbol"),
|
|
15672
|
+
line: tool.schema.number().describe("Line number (1-based)"),
|
|
15673
|
+
character: tool.schema.number().describe("Character position (0-based)")
|
|
15674
|
+
},
|
|
15675
|
+
async execute({ filePath, line, character }) {
|
|
15676
|
+
const lsp = await getLspConnection(filePath);
|
|
15677
|
+
if (!lsp) {
|
|
15678
|
+
return JSON.stringify({
|
|
15679
|
+
success: false,
|
|
15680
|
+
error: `No LSP server available for file: ${filePath}`,
|
|
15681
|
+
hint: "LSP servers are auto-detected based on file type."
|
|
15682
|
+
}, null, 2);
|
|
15683
|
+
}
|
|
15684
|
+
return JSON.stringify({
|
|
15685
|
+
success: true,
|
|
15686
|
+
message: `Find references at ${filePath}:${line}:${character}`,
|
|
15687
|
+
server: lsp.serverId,
|
|
15688
|
+
operation: "textDocument/references",
|
|
15689
|
+
references: []
|
|
15690
|
+
}, null, 2);
|
|
15691
|
+
}
|
|
15692
|
+
});
|
|
15693
|
+
var lspDiagnosticsTool = tool({
|
|
15694
|
+
description: "Get diagnostics (errors, warnings, info) for a file using LSP. Shows language-level issues.",
|
|
15695
|
+
args: {
|
|
15696
|
+
filePath: tool.schema.string().describe("Path to the file to check for diagnostics"),
|
|
15697
|
+
severity: tool.schema.enum(["error", "warning", "information", "hint", "all"]).optional().default("all").describe("Minimum severity level to return")
|
|
15698
|
+
},
|
|
15699
|
+
async execute({ filePath, severity }) {
|
|
15700
|
+
const lsp = await getLspConnection(filePath);
|
|
15701
|
+
if (!lsp) {
|
|
15702
|
+
return JSON.stringify({
|
|
15703
|
+
success: false,
|
|
15704
|
+
error: `No LSP server available for file: ${filePath}`,
|
|
15705
|
+
hint: "LSP servers are auto-detected based on file type."
|
|
15706
|
+
}, null, 2);
|
|
15707
|
+
}
|
|
15708
|
+
return JSON.stringify({
|
|
15709
|
+
success: true,
|
|
15710
|
+
message: `Get diagnostics for ${filePath}`,
|
|
15711
|
+
server: lsp.serverId,
|
|
15712
|
+
operation: "textDocument/diagnostic",
|
|
15713
|
+
severity,
|
|
15714
|
+
diagnostics: []
|
|
15715
|
+
}, null, 2);
|
|
15716
|
+
}
|
|
15717
|
+
});
|
|
15718
|
+
var lspHoverTool = tool({
|
|
15719
|
+
description: "Get hover information for a symbol using LSP. Shows type information and documentation.",
|
|
15720
|
+
args: {
|
|
15721
|
+
filePath: tool.schema.string().describe("Path to the file containing the symbol"),
|
|
15722
|
+
line: tool.schema.number().describe("Line number (1-based)"),
|
|
15723
|
+
character: tool.schema.number().describe("Character position (0-based)")
|
|
15724
|
+
},
|
|
15725
|
+
async execute({ filePath, line, character }) {
|
|
15726
|
+
const lsp = await getLspConnection(filePath);
|
|
15727
|
+
if (!lsp) {
|
|
15728
|
+
return JSON.stringify({
|
|
15729
|
+
success: false,
|
|
15730
|
+
error: `No LSP server available for file: ${filePath}`,
|
|
15731
|
+
hint: "LSP servers are auto-detected based on file type."
|
|
15732
|
+
}, null, 2);
|
|
15733
|
+
}
|
|
15734
|
+
return JSON.stringify({
|
|
15735
|
+
success: true,
|
|
15736
|
+
message: `Get hover info at ${filePath}:${line}:${character}`,
|
|
15737
|
+
server: lsp.serverId,
|
|
15738
|
+
operation: "textDocument/hover"
|
|
15739
|
+
}, null, 2);
|
|
15740
|
+
}
|
|
15741
|
+
});
|
|
15742
|
+
var lspCodeActionsTool = tool({
|
|
15743
|
+
description: "Get available code actions using LSP. Shows quick fixes and refactorings.",
|
|
15744
|
+
args: {
|
|
15745
|
+
filePath: tool.schema.string().describe("Path to the file"),
|
|
15746
|
+
line: tool.schema.number().describe("Line number (1-based)"),
|
|
15747
|
+
character: tool.schema.number().describe("Character position (0-based)")
|
|
15748
|
+
},
|
|
15749
|
+
async execute({ filePath, line, character }) {
|
|
15750
|
+
const lsp = await getLspConnection(filePath);
|
|
15751
|
+
if (!lsp) {
|
|
15752
|
+
return JSON.stringify({
|
|
15753
|
+
success: false,
|
|
15754
|
+
error: `No LSP server available for file: ${filePath}`,
|
|
15755
|
+
hint: "LSP servers are auto-detected based on file type."
|
|
15756
|
+
}, null, 2);
|
|
15757
|
+
}
|
|
15758
|
+
return JSON.stringify({
|
|
15759
|
+
success: true,
|
|
15760
|
+
message: `Get code actions at ${filePath}:${line}:${character}`,
|
|
15761
|
+
server: lsp.serverId,
|
|
15762
|
+
operation: "textDocument/codeAction",
|
|
15763
|
+
actions: []
|
|
15764
|
+
}, null, 2);
|
|
15765
|
+
}
|
|
15766
|
+
});
|
|
15767
|
+
|
|
15768
|
+
// src/tools/skill-mcp.ts
|
|
15769
|
+
function getSkillMcpConfig(skill) {
|
|
15770
|
+
return skill.mcp || null;
|
|
15771
|
+
}
|
|
15772
|
+
var skillMcpTool = tool({
|
|
15773
|
+
description: "Invoke MCP server operations from skill-embedded MCPs. " + "Skills can bring their own MCP servers that spin up on-demand.",
|
|
15774
|
+
args: {
|
|
15775
|
+
skill: tool.schema.string().describe("Name of the skill containing the MCP"),
|
|
15776
|
+
server: tool.schema.string().describe("Name of the MCP server in the skill"),
|
|
15777
|
+
operation: tool.schema.string().describe("Name of the MCP operation to invoke"),
|
|
15778
|
+
arguments: tool.schema.object({}).optional().describe("Arguments for the MCP operation")
|
|
15779
|
+
},
|
|
15780
|
+
async execute({ skill: skillName, server: mcpServer, operation, arguments: mcpArgs }) {
|
|
15781
|
+
let skill = null;
|
|
15782
|
+
const builtinResult = loadBuiltinSkill(skillName);
|
|
15783
|
+
if (builtinResult.found && builtinResult.skill) {
|
|
15784
|
+
skill = builtinResult.skill;
|
|
15785
|
+
}
|
|
15786
|
+
if (!skill) {
|
|
15787
|
+
const homeDir = process.env.HOME || "";
|
|
15788
|
+
const projectRoot = process.cwd();
|
|
15789
|
+
const fileResult = await loadFileSkill(skillName, projectRoot, homeDir);
|
|
15790
|
+
if (fileResult.found && fileResult.skill) {
|
|
15791
|
+
skill = fileResult.skill;
|
|
15792
|
+
}
|
|
15793
|
+
}
|
|
15794
|
+
if (!skill) {
|
|
15795
|
+
return JSON.stringify({
|
|
15796
|
+
success: false,
|
|
15797
|
+
error: `Skill "${skillName}" not found`,
|
|
15798
|
+
hint: "Load the skill first using hive_skill() tool, then use skill_mcp()"
|
|
15799
|
+
}, null, 2);
|
|
15800
|
+
}
|
|
15801
|
+
const mcpConfig = getSkillMcpConfig(skill);
|
|
15802
|
+
if (!mcpConfig) {
|
|
15803
|
+
return JSON.stringify({
|
|
15804
|
+
success: false,
|
|
15805
|
+
error: `Skill "${skillName}" does not have embedded MCP servers`,
|
|
15806
|
+
hint: "Only skills with MCP configuration can use skill_mcp()"
|
|
15807
|
+
}, null, 2);
|
|
15808
|
+
}
|
|
15809
|
+
if (!mcpConfig[mcpServer]) {
|
|
15810
|
+
const availableServers = Object.keys(mcpConfig);
|
|
15811
|
+
return JSON.stringify({
|
|
15812
|
+
success: false,
|
|
15813
|
+
error: `MCP server "${mcpServer}" not found in skill "${skillName}"`,
|
|
15814
|
+
availableServers
|
|
15815
|
+
}, null, 2);
|
|
15816
|
+
}
|
|
15817
|
+
const serverConfig = mcpConfig[mcpServer];
|
|
15818
|
+
return JSON.stringify({
|
|
15819
|
+
success: true,
|
|
15820
|
+
skill: skillName,
|
|
15821
|
+
server: mcpServer,
|
|
15822
|
+
operation,
|
|
15823
|
+
arguments: mcpArgs || {},
|
|
15824
|
+
serverType: serverConfig.type
|
|
15825
|
+
}, null, 2);
|
|
15826
|
+
}
|
|
15827
|
+
});
|
|
15828
|
+
var listSkillMcpsTool = tool({
|
|
15829
|
+
description: "List all available skill-embedded MCP servers.",
|
|
15830
|
+
args: {
|
|
15831
|
+
skill: tool.schema.string().optional().describe("Filter by skill name")
|
|
15832
|
+
},
|
|
15833
|
+
async execute() {
|
|
15834
|
+
return JSON.stringify({
|
|
15835
|
+
success: true,
|
|
15836
|
+
message: "Skill-Embedded MCPs",
|
|
15837
|
+
description: "Skills can bring their own MCP servers. Configure in skill SKILL.md:",
|
|
15838
|
+
example: `---
|
|
15839
|
+
mcp:
|
|
15840
|
+
playwright:
|
|
15841
|
+
command: npx
|
|
15842
|
+
args: ["-y", "@anthropic-ai/mcp-playwright"]
|
|
15843
|
+
---`
|
|
15844
|
+
}, null, 2);
|
|
15845
|
+
}
|
|
15846
|
+
});
|
|
15847
|
+
|
|
15593
15848
|
// src/agents/hive.ts
|
|
15594
15849
|
var QUEEN_BEE_PROMPT = `# Zetta (Hybrid)
|
|
15595
15850
|
|
|
@@ -24624,6 +24879,14 @@ Use the \`@path\` attachment syntax in the prompt to reference the file. Do not
|
|
|
24624
24879
|
pty_read: ptyReadTool,
|
|
24625
24880
|
pty_kill: ptyKillTool,
|
|
24626
24881
|
pty_list: ptyListTool,
|
|
24882
|
+
lsp_rename: lspRenameTool,
|
|
24883
|
+
lsp_goto_definition: lspGotoDefinitionTool,
|
|
24884
|
+
lsp_find_references: lspFindReferencesTool,
|
|
24885
|
+
lsp_diagnostics: lspDiagnosticsTool,
|
|
24886
|
+
lsp_hover: lspHoverTool,
|
|
24887
|
+
lsp_code_actions: lspCodeActionsTool,
|
|
24888
|
+
skill_mcp: skillMcpTool,
|
|
24889
|
+
list_skill_mcps: listSkillMcpsTool,
|
|
24627
24890
|
hive_skill: createHiveSkillTool(filteredSkills),
|
|
24628
24891
|
hive_feature_create: tool({
|
|
24629
24892
|
description: "Create a new feature and set it as active",
|
|
@@ -25436,6 +25699,12 @@ ${Object.entries(customAgentConfigs).sort(([left], [right]) => left.localeCompar
|
|
|
25436
25699
|
allAgents["hygienic-reviewer"] = builtInAgentConfigs["hygienic-reviewer"];
|
|
25437
25700
|
}
|
|
25438
25701
|
Object.assign(allAgents, customSubagents);
|
|
25702
|
+
const primaryAgent = agentMode === "unified" ? "zetta" : "architect-planner";
|
|
25703
|
+
for (const [agentName, agentConfig] of Object.entries(allAgents)) {
|
|
25704
|
+
if (agentName !== primaryAgent && agentConfig && typeof agentConfig === "object") {
|
|
25705
|
+
agentConfig.mode = "subagent";
|
|
25706
|
+
}
|
|
25707
|
+
}
|
|
25439
25708
|
const configAgent = opencodeConfig.agent;
|
|
25440
25709
|
if (!configAgent) {
|
|
25441
25710
|
opencodeConfig.agent = allAgents;
|
|
@@ -25453,21 +25722,20 @@ ${Object.entries(customAgentConfigs).sort(([left], [right]) => left.localeCompar
|
|
|
25453
25722
|
delete configAgent["scout-researcher"];
|
|
25454
25723
|
delete configAgent["forager-worker"];
|
|
25455
25724
|
delete configAgent["hygienic-reviewer"];
|
|
25456
|
-
|
|
25457
|
-
|
|
25458
|
-
|
|
25459
|
-
|
|
25460
|
-
|
|
25461
|
-
}
|
|
25462
|
-
if (configAgent.triage) {
|
|
25463
|
-
configAgent.triage.mode = "subagent";
|
|
25725
|
+
const opencodeBuiltInAgents = ["build", "plan", "triage", "docs", "ask", "claude-code"];
|
|
25726
|
+
for (const agentName of opencodeBuiltInAgents) {
|
|
25727
|
+
if (configAgent[agentName]) {
|
|
25728
|
+
configAgent[agentName].mode = "subagent";
|
|
25729
|
+
}
|
|
25464
25730
|
}
|
|
25465
|
-
|
|
25466
|
-
|
|
25731
|
+
for (const [agentName, agentConfig] of Object.entries(allAgents)) {
|
|
25732
|
+
if (agentName !== primaryAgent && agentConfig && typeof agentConfig === "object") {
|
|
25733
|
+
agentConfig.mode = "subagent";
|
|
25734
|
+
}
|
|
25467
25735
|
}
|
|
25468
25736
|
Object.assign(configAgent, allAgents);
|
|
25469
25737
|
}
|
|
25470
|
-
opencodeConfig.default_agent =
|
|
25738
|
+
opencodeConfig.default_agent = primaryAgent;
|
|
25471
25739
|
const configMcp = opencodeConfig.mcp;
|
|
25472
25740
|
const mcpToAdd = builtinMcps;
|
|
25473
25741
|
if (!configMcp) {
|
package/dist/skills/types.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Skill definitions for Hive.
|
|
5
5
|
*/
|
|
6
|
+
import type { McpConfig } from '../mcp/types.js';
|
|
6
7
|
/**
|
|
7
8
|
* Definition of a skill that can be loaded by agents.
|
|
8
9
|
*/
|
|
@@ -13,6 +14,8 @@ export interface SkillDefinition {
|
|
|
13
14
|
description: string;
|
|
14
15
|
/** Markdown content with detailed instructions */
|
|
15
16
|
template: string;
|
|
17
|
+
/** Optional embedded MCP servers for this skill */
|
|
18
|
+
mcp?: Record<string, McpConfig>;
|
|
16
19
|
}
|
|
17
20
|
/**
|
|
18
21
|
* Result returned when loading a skill.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ToolDefinition } from "@opencode-ai/plugin";
|
|
2
|
+
export declare const lspRenameTool: ToolDefinition;
|
|
3
|
+
export declare const lspGotoDefinitionTool: ToolDefinition;
|
|
4
|
+
export declare const lspFindReferencesTool: ToolDefinition;
|
|
5
|
+
export declare const lspDiagnosticsTool: ToolDefinition;
|
|
6
|
+
export declare const lspHoverTool: ToolDefinition;
|
|
7
|
+
export declare const lspCodeActionsTool: ToolDefinition;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type ToolDefinition } from "@opencode-ai/plugin";
|
|
2
|
+
import type { SkillDefinition } from '../skills/types.js';
|
|
3
|
+
import type { McpConfig } from '../mcp/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Skill-Embedded MCPs
|
|
6
|
+
*
|
|
7
|
+
* Skills can bring their own MCP servers. When a skill with embedded MCP
|
|
8
|
+
* is loaded, the MCP server is started on-demand.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Get MCP config from a skill definition
|
|
12
|
+
*/
|
|
13
|
+
export declare function getSkillMcpConfig(skill: SkillDefinition): Record<string, McpConfig> | null;
|
|
14
|
+
/**
|
|
15
|
+
* skill_mcp Tool
|
|
16
|
+
*
|
|
17
|
+
* Invokes MCP server operations from skill-embedded MCPs.
|
|
18
|
+
*/
|
|
19
|
+
export declare const skillMcpTool: ToolDefinition;
|
|
20
|
+
/**
|
|
21
|
+
* List skill MCPs Tool
|
|
22
|
+
*/
|
|
23
|
+
export declare const listSkillMcpsTool: ToolDefinition;
|