opencoding-agent 1.0.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/LICENSE +21 -0
- package/README.md +42 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/src/agents/build.d.ts +2 -0
- package/dist/src/agents/build.js +9 -0
- package/dist/src/agents/index.d.ts +1 -0
- package/dist/src/agents/index.js +24 -0
- package/dist/src/agents/plan.d.ts +2 -0
- package/dist/src/agents/plan.js +12 -0
- package/dist/src/config.d.ts +8 -0
- package/dist/src/config.js +1 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.js +20 -0
- package/dist/src/tools/catalog.d.ts +33 -0
- package/dist/src/tools/catalog.js +113 -0
- package/package.json +36 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 j5hjun
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# opencoding-agent
|
|
2
|
+
|
|
3
|
+
opencoding-agent is an OpenCode plugin that provides specialized agents and a subagent management system.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Custom Agents**: Replaces default agents with specialized `plan` and `build` modes.
|
|
8
|
+
- **Subagent Catalog**: Browse and install subagents from the [awesome-opencode-subagents](https://github.com/j5hjun/awesome-opencode-subagents) repository.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
Add this plugin to your `opencode.json`:
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"plugin": [
|
|
17
|
+
"opencoding-agent"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
OpenCode automatically installs plugin dependencies at runtime.
|
|
23
|
+
|
|
24
|
+
## Tools
|
|
25
|
+
|
|
26
|
+
- `/subagent-catalog:list`: List available subagent categories.
|
|
27
|
+
- `/subagent-catalog:search <query>`: Search for specific subagents by name or description.
|
|
28
|
+
- `/subagent-catalog:fetch <name> [scope]`: Download and install a subagent (scope: `global` or `local`).
|
|
29
|
+
|
|
30
|
+
## Development
|
|
31
|
+
|
|
32
|
+
To install dependencies:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
bun install
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
To build:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
bun run build
|
|
42
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./src/index";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./src/index";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const injectAgents: (config: any) => Promise<void>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { planAgent } from "./plan";
|
|
2
|
+
import { buildAgent } from "./build";
|
|
3
|
+
export const injectAgents = async (config) => {
|
|
4
|
+
const planPrompt = await Bun.file(`${import.meta.dir}/../prompts/plan.txt`).text();
|
|
5
|
+
const buildPrompt = await Bun.file(`${import.meta.dir}/../prompts/build.txt`).text();
|
|
6
|
+
config.agent = {
|
|
7
|
+
...config.agent,
|
|
8
|
+
// Disable default agents
|
|
9
|
+
"build": { disable: true },
|
|
10
|
+
"plan": { disable: true },
|
|
11
|
+
// Inject our opencoding- prefixed agents
|
|
12
|
+
"opencoding-plan": {
|
|
13
|
+
...planAgent,
|
|
14
|
+
disable: false,
|
|
15
|
+
prompt: planPrompt
|
|
16
|
+
},
|
|
17
|
+
"opencoding-build": {
|
|
18
|
+
...buildAgent,
|
|
19
|
+
disable: false,
|
|
20
|
+
prompt: buildPrompt
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
config.default_agent = "opencoding-plan";
|
|
24
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const PLUGIN_NAME = "opencoding-agent";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { injectAgents } from "./agents";
|
|
2
|
+
import { catalogTools } from "./tools/catalog";
|
|
3
|
+
/**
|
|
4
|
+
* opencoding-agent Plugin
|
|
5
|
+
*
|
|
6
|
+
* Replaces default OpenCode agents with core-identical 'plan' and 'build' modes.
|
|
7
|
+
*/
|
|
8
|
+
const OpencodingAgentPlugin = async (ctx) => {
|
|
9
|
+
return {
|
|
10
|
+
// Config hook: Injected once during initialization
|
|
11
|
+
config: async (config) => {
|
|
12
|
+
await injectAgents(config);
|
|
13
|
+
},
|
|
14
|
+
// Register custom tools
|
|
15
|
+
tool: {
|
|
16
|
+
...catalogTools
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
export default OpencodingAgentPlugin;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const catalogTools: {
|
|
3
|
+
"subagent-catalog:list": {
|
|
4
|
+
description: string;
|
|
5
|
+
args: {};
|
|
6
|
+
execute(args: Record<string, never>, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
7
|
+
};
|
|
8
|
+
"subagent-catalog:search": {
|
|
9
|
+
description: string;
|
|
10
|
+
args: {
|
|
11
|
+
query: z.ZodString;
|
|
12
|
+
category: z.ZodOptional<z.ZodString>;
|
|
13
|
+
};
|
|
14
|
+
execute(args: {
|
|
15
|
+
query: string;
|
|
16
|
+
category?: string | undefined;
|
|
17
|
+
}, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
18
|
+
};
|
|
19
|
+
"subagent-catalog:fetch": {
|
|
20
|
+
description: string;
|
|
21
|
+
args: {
|
|
22
|
+
name: z.ZodString;
|
|
23
|
+
scope: z.ZodDefault<z.ZodEnum<{
|
|
24
|
+
global: "global";
|
|
25
|
+
local: "local";
|
|
26
|
+
}>>;
|
|
27
|
+
};
|
|
28
|
+
execute(args: {
|
|
29
|
+
name: string;
|
|
30
|
+
scope: "global" | "local";
|
|
31
|
+
}, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { tool } from "@opencode-ai/plugin";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import * as os from "os";
|
|
5
|
+
const REPO_URL = "https://raw.githubusercontent.com/j5hjun/awesome-opencode-subagents/main";
|
|
6
|
+
export const catalogTools = {
|
|
7
|
+
"subagent-catalog:list": tool({
|
|
8
|
+
description: "List all available subagent categories and the number of agents in each.",
|
|
9
|
+
args: {},
|
|
10
|
+
execute: async () => {
|
|
11
|
+
try {
|
|
12
|
+
const url = `${REPO_URL}/catalog.json?t=${Date.now()}`;
|
|
13
|
+
console.log(`Fetching catalog from: ${url}`);
|
|
14
|
+
const response = await fetch(url);
|
|
15
|
+
if (!response.ok) {
|
|
16
|
+
const errorMsg = `Fetch failed for ${url}: ${response.status} ${response.statusText}`;
|
|
17
|
+
console.error(errorMsg);
|
|
18
|
+
return errorMsg;
|
|
19
|
+
}
|
|
20
|
+
const catalog = await response.json();
|
|
21
|
+
const categories = catalog.reduce((acc, item) => {
|
|
22
|
+
acc[item.category] = (acc[item.category] || 0) + 1;
|
|
23
|
+
return acc;
|
|
24
|
+
}, {});
|
|
25
|
+
let output = "Available Subagent Categories:\n\n";
|
|
26
|
+
for (const [name, count] of Object.entries(categories)) {
|
|
27
|
+
output += `- ${name}: ${count} agents\n`;
|
|
28
|
+
}
|
|
29
|
+
output += "\nUse subagent-catalog:search to find specific agents.";
|
|
30
|
+
return output;
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
return `Error fetching catalog: ${error.message}`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}),
|
|
37
|
+
"subagent-catalog:search": tool({
|
|
38
|
+
description: "Search for subagents by name, description, or category.",
|
|
39
|
+
args: {
|
|
40
|
+
query: z.string().describe("Search term"),
|
|
41
|
+
category: z.string().optional().describe("Filter by category")
|
|
42
|
+
},
|
|
43
|
+
execute: async ({ query, category }) => {
|
|
44
|
+
try {
|
|
45
|
+
const url = `${REPO_URL}/catalog.json?t=${Date.now()}`;
|
|
46
|
+
const response = await fetch(url);
|
|
47
|
+
if (!response.ok)
|
|
48
|
+
return `Fetch failed for ${url}: ${response.status} ${response.statusText}`;
|
|
49
|
+
const catalog = await response.json();
|
|
50
|
+
const results = catalog.filter(item => {
|
|
51
|
+
const matchesQuery = item.name.toLowerCase().includes(query.toLowerCase()) ||
|
|
52
|
+
item.description.toLowerCase().includes(query.toLowerCase());
|
|
53
|
+
const matchesCategory = !category || item.category.toLowerCase() === category.toLowerCase();
|
|
54
|
+
return matchesQuery && matchesCategory;
|
|
55
|
+
});
|
|
56
|
+
if (results.length === 0)
|
|
57
|
+
return "No agents found matching your search.";
|
|
58
|
+
let output = `Search Results for "${query}":\n\n`;
|
|
59
|
+
for (const item of results) {
|
|
60
|
+
output += `### ${item.name}\n`;
|
|
61
|
+
output += `**Category**: ${item.category}\n`;
|
|
62
|
+
output += `**Description**: ${item.description}\n\n`;
|
|
63
|
+
}
|
|
64
|
+
output += "Use subagent-catalog:fetch to install an agent.";
|
|
65
|
+
return output;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
return `Error searching catalog: ${error.message}`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}),
|
|
72
|
+
"subagent-catalog:fetch": tool({
|
|
73
|
+
description: "Download and install a subagent by name. You can choose to install it globally or locally.",
|
|
74
|
+
args: {
|
|
75
|
+
name: z.string().describe("Name of the agent to fetch"),
|
|
76
|
+
scope: z.enum(["global", "local"]).default("global").describe("Installation scope (global: all projects, local: current project only)")
|
|
77
|
+
},
|
|
78
|
+
execute: async ({ name, scope }, { directory }) => {
|
|
79
|
+
try {
|
|
80
|
+
const catalogUrl = `${REPO_URL}/catalog.json?t=${Date.now()}`;
|
|
81
|
+
const catalogResponse = await fetch(catalogUrl);
|
|
82
|
+
if (!catalogResponse.ok)
|
|
83
|
+
return `Fetch failed for ${catalogUrl}: ${catalogResponse.status} ${catalogResponse.statusText}`;
|
|
84
|
+
const catalog = await catalogResponse.json();
|
|
85
|
+
const agent = catalog.find(item => item.name.toLowerCase() === name.toLowerCase());
|
|
86
|
+
if (!agent)
|
|
87
|
+
return `Agent "${name}" not found in the catalog.`;
|
|
88
|
+
const agentUrl = `${REPO_URL}/${agent.path}?t=${Date.now()}`;
|
|
89
|
+
const agentResponse = await fetch(agentUrl);
|
|
90
|
+
if (!agentResponse.ok)
|
|
91
|
+
return `Fetch failed for ${agentUrl}: ${agentResponse.status} ${agentResponse.statusText}`;
|
|
92
|
+
const content = await agentResponse.text();
|
|
93
|
+
let targetDir;
|
|
94
|
+
if (scope === "global") {
|
|
95
|
+
targetDir = path.join(os.homedir(), ".config", "opencode", "agents");
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
targetDir = path.join(directory, ".opencode", "agents");
|
|
99
|
+
}
|
|
100
|
+
const fileName = `${agent.name}.md`;
|
|
101
|
+
const filePath = path.join(targetDir, fileName);
|
|
102
|
+
// Ensure directory exists - Bun.write will create the file, but we might need to create the directory
|
|
103
|
+
const fs = await import("fs/promises");
|
|
104
|
+
await fs.mkdir(targetDir, { recursive: true });
|
|
105
|
+
await Bun.write(filePath, content);
|
|
106
|
+
return `✓ Successfully installed **${agent.name}** to ${scope} path: \`${filePath}\`\n\nYou can now use this agent by saying: "Use the ${agent.name} to [task]"`;
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
return `Error fetching agent: ${error.message}`;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "opencoding-agent",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "OpenCode specialized agents and subagent catalog manager",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md",
|
|
11
|
+
"LICENSE"
|
|
12
|
+
],
|
|
13
|
+
"keywords": [
|
|
14
|
+
"opencode",
|
|
15
|
+
"opencode-plugin",
|
|
16
|
+
"plugin"
|
|
17
|
+
],
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"@opencode-ai/plugin": "^1.0.0"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@opencode-ai/plugin": "^1.0.0",
|
|
24
|
+
"@types/bun": "^1.2.0",
|
|
25
|
+
"@types/node": "^22.0.0",
|
|
26
|
+
"typescript": "^5.7.0"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"clean": "rm -rf dist",
|
|
30
|
+
"build": "npm run clean && tsc",
|
|
31
|
+
"prepublishOnly": "npm run build"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
}
|
|
36
|
+
}
|