@hiai-gg/hiai-opencode 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +28 -21
- package/AGENTS.md +183 -28
- package/ARCHITECTURE.md +17 -20
- package/LICENSE.md +1 -0
- package/README.md +269 -66
- package/assets/cli/hiai-opencode.mjs +276 -0
- package/assets/mcp/mempalace.mjs +47 -4
- package/assets/mcp/playwright.mjs +83 -0
- package/config/hiai-opencode.schema.json +113 -1
- package/dist/config/index.d.ts +0 -1
- package/dist/config/platform-schema.d.ts +72 -0
- package/dist/config/schema/agent-overrides.d.ts +256 -0
- package/dist/config/schema/categories.d.ts +2 -2
- package/dist/config/schema/commands.d.ts +1 -0
- package/dist/config/schema/index.d.ts +2 -0
- package/dist/config/schema/oh-my-opencode-config.d.ts +267 -0
- package/dist/config/schema/skill-discovery.d.ts +11 -0
- package/dist/config/types.d.ts +12 -1
- package/dist/features/builtin-commands/templates/mcp-status.d.ts +1 -0
- package/dist/features/builtin-commands/types.d.ts +1 -1
- package/dist/features/opencode-skill-loader/loader.d.ts +2 -0
- package/dist/index.js +617 -421
- package/dist/mcp/registry.d.ts +14 -0
- package/dist/mcp/types.d.ts +6 -0
- package/dist/plugin/skill-discovery-config.d.ts +4 -0
- package/dist/shared/startup-diagnostics.d.ts +6 -0
- package/hiai-opencode.json +192 -36
- package/package.json +4 -1
- package/src/agents/AGENTS.md +3 -4
- package/src/config/defaults.ts +55 -133
- package/src/config/index.ts +0 -1
- package/src/config/loader.ts +4 -1
- package/src/config/platform-schema.ts +18 -2
- package/src/config/schema/agent-overrides.ts +2 -0
- package/src/config/schema/commands.ts +1 -0
- package/src/config/schema/fast-apply.ts +4 -4
- package/src/config/schema/index.ts +2 -0
- package/src/config/schema/oh-my-opencode-config.ts +3 -0
- package/src/config/schema/skill-discovery.ts +25 -0
- package/src/config/types.ts +16 -0
- package/src/features/builtin-commands/commands.ts +7 -0
- package/src/features/builtin-commands/templates/mcp-status.ts +36 -0
- package/src/features/builtin-commands/types.ts +1 -1
- package/src/features/builtin-skills/skills/playwright.ts +24 -2
- package/src/features/opencode-skill-loader/loader.ts +11 -0
- package/src/index.ts +15 -13
- package/src/mcp/index.ts +0 -33
- package/src/mcp/omo-mcp-index.ts +0 -5
- package/src/mcp/registry.ts +132 -0
- package/src/mcp/types.ts +11 -1
- package/src/plugin/hooks/create-tool-guard-hooks.ts +1 -1
- package/src/plugin/skill-context.ts +31 -13
- package/src/plugin/skill-discovery-config.ts +32 -0
- package/src/plugin-handlers/agent-config-handler.ts +20 -13
- package/src/plugin-handlers/command-config-handler.ts +22 -12
- package/src/shared/migration/agent-names.ts +5 -5
- package/src/shared/startup-diagnostics.ts +77 -0
- package/src/config/models.ts +0 -32
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { McpServerConfig } from "../config/types.js";
|
|
2
|
+
export type HiaiMcpName = "playwright" | "stitch" | "sequential-thinking" | "firecrawl" | "rag" | "context7" | "mempalace";
|
|
3
|
+
export type HiaiMcpInstallKind = "bundled" | "npm" | "python" | "remote" | "user-service";
|
|
4
|
+
export interface HiaiMcpRegistryEntry {
|
|
5
|
+
name: HiaiMcpName;
|
|
6
|
+
enabledByDefault: boolean;
|
|
7
|
+
install: HiaiMcpInstallKind;
|
|
8
|
+
requiredEnv?: string[];
|
|
9
|
+
optionalEnv?: string[];
|
|
10
|
+
config: McpServerConfig;
|
|
11
|
+
}
|
|
12
|
+
export declare const HIAI_MCP_REGISTRY: Record<HiaiMcpName, HiaiMcpRegistryEntry>;
|
|
13
|
+
export declare function createDefaultMcpConfig(): Record<HiaiMcpName, McpServerConfig>;
|
|
14
|
+
export declare function getKnownMcpNames(): HiaiMcpName[];
|
package/dist/mcp/types.d.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export declare const McpNameSchema: z.ZodEnum<{
|
|
3
3
|
websearch: "websearch";
|
|
4
|
+
stitch: "stitch";
|
|
5
|
+
firecrawl: "firecrawl";
|
|
6
|
+
playwright: "playwright";
|
|
7
|
+
"sequential-thinking": "sequential-thinking";
|
|
8
|
+
rag: "rag";
|
|
4
9
|
context7: "context7";
|
|
10
|
+
mempalace: "mempalace";
|
|
5
11
|
grep_app: "grep_app";
|
|
6
12
|
}>;
|
|
7
13
|
export type McpName = z.infer<typeof McpNameSchema>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { HiaiOpenCodeConfig } from "../config";
|
|
2
|
+
import type { SkillDiscoveryConfig } from "../config/schema";
|
|
3
|
+
export type ResolvedSkillDiscoveryConfig = Required<SkillDiscoveryConfig>;
|
|
4
|
+
export declare function resolveSkillDiscoveryConfig(pluginConfig: HiaiOpenCodeConfig): ResolvedSkillDiscoveryConfig;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { HiaiOpenCodeConfig, HiaiOpencodeConfig } from "../config";
|
|
2
|
+
export declare function warnIfListPluginEntry(directory: string): void;
|
|
3
|
+
export declare function warnMissingRequiredMcpEnv(args: {
|
|
4
|
+
pluginConfig: HiaiOpenCodeConfig;
|
|
5
|
+
platformConfig: HiaiOpencodeConfig;
|
|
6
|
+
}): void;
|
package/hiai-opencode.json
CHANGED
|
@@ -1,32 +1,107 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_description": "hiai-opencode
|
|
2
|
+
"_description": "Canonical hiai-opencode runtime config. Copy this file to .opencode/hiai-opencode.json and edit it there. This file is the user-facing source of truth for agent models, category models, MCP switches, LSP defaults, skill discovery, service auth placeholders, and local helper defaults. Model provider credentials are configured in OpenCode Connect; this file stores model IDs only.",
|
|
3
3
|
"$schema": "./config/hiai-opencode.schema.json",
|
|
4
4
|
"agents": {
|
|
5
|
-
"bob": {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"
|
|
14
|
-
|
|
5
|
+
"bob": {
|
|
6
|
+
"model": "openrouter/anthropic/claude-3.5-opus",
|
|
7
|
+
"description": "Primary orchestrator for end-to-end task execution, delegation, and high-level workflow control."
|
|
8
|
+
},
|
|
9
|
+
"coder": {
|
|
10
|
+
"model": "openrouter/anthropic/claude-3.5-sonnet",
|
|
11
|
+
"description": "High-depth executor for multi-file implementation, substantial refactors, and technical delivery."
|
|
12
|
+
},
|
|
13
|
+
"strategist": {
|
|
14
|
+
"model": "openrouter/z-ai/glm-5.1",
|
|
15
|
+
"description": "Planning and architecture agent for decomposition, sequencing, and decision framing before execution."
|
|
16
|
+
},
|
|
17
|
+
"guard": {
|
|
18
|
+
"model": "openrouter/openai/gpt-4o",
|
|
19
|
+
"description": "Execution supervisor that routes work, enforces discipline, and keeps delegated flows on track."
|
|
20
|
+
},
|
|
21
|
+
"critic": {
|
|
22
|
+
"model": "openrouter/qwen/qwen2.5-72b-instruct",
|
|
23
|
+
"description": "High-accuracy review gate for implementation quality, correctness, and plan validation."
|
|
24
|
+
},
|
|
25
|
+
"designer": {
|
|
26
|
+
"model": "openrouter/google/gemini-3.1-pro",
|
|
27
|
+
"description": "Creative visual problem-solver for high-touch UI, interaction, and brand-level interface direction."
|
|
28
|
+
},
|
|
29
|
+
"researcher": {
|
|
30
|
+
"model": "openrouter/google/gemini-2.0-flash",
|
|
31
|
+
"description": "Codebase exploration and external documentation research."
|
|
32
|
+
},
|
|
33
|
+
"platform-manager": {
|
|
34
|
+
"model": "openrouter/google/gemini-2.0-flash",
|
|
35
|
+
"description": "Manager. Unified platform management agent for session continuity, project initialization, and orchestration."
|
|
36
|
+
},
|
|
37
|
+
"brainstormer": {
|
|
38
|
+
"model": "openrouter/google/gemini-2.0-flash",
|
|
39
|
+
"description": "Idea exploration agent for divergent thinking, option generation, and concept shaping before execution."
|
|
40
|
+
},
|
|
41
|
+
"multimodal": {
|
|
42
|
+
"model": "openrouter/google/gemini-3.1-pro",
|
|
43
|
+
"description": "Vision. Multimodal analysis agent for images, PDFs, diagrams, and other non-text inputs."
|
|
44
|
+
},
|
|
45
|
+
"sub": {
|
|
46
|
+
"model": "openrouter/google/gemini-2.0-flash",
|
|
47
|
+
"description": "Hidden compatibility executor. Primary subtask execution is handled by Coder."
|
|
48
|
+
},
|
|
49
|
+
"quality-guardian": {
|
|
50
|
+
"model": "openrouter/anthropic/claude-3.5-sonnet",
|
|
51
|
+
"description": "Hidden compatibility review agent. Primary review work is handled by Critic."
|
|
52
|
+
},
|
|
53
|
+
"agent-skills": {
|
|
54
|
+
"model": "openrouter/google/gemini-2.0-flash",
|
|
55
|
+
"description": "Hidden system agent for skill registry, discovery, and capability orchestration."
|
|
56
|
+
}
|
|
15
57
|
},
|
|
58
|
+
"agentRequirements": {},
|
|
16
59
|
"categories": {
|
|
17
|
-
"visual-engineering": {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
60
|
+
"visual-engineering": {
|
|
61
|
+
"model": "openrouter/google/gemini-2.0-pro-exp-02-05",
|
|
62
|
+
"variant": "high",
|
|
63
|
+
"description": "Frontend and UI systems work with design-system discipline. Uses Coder deep execution contour."
|
|
64
|
+
},
|
|
65
|
+
"artistry": {
|
|
66
|
+
"model": "openrouter/google/gemini-2.0-pro-exp-02-05",
|
|
67
|
+
"variant": "high",
|
|
68
|
+
"description": "High-effort creative problem solving beyond standard patterns. Uses Coder deep execution contour."
|
|
69
|
+
},
|
|
70
|
+
"ultrabrain": {
|
|
71
|
+
"model": "openrouter/openai/gpt-4o",
|
|
72
|
+
"variant": "xhigh",
|
|
73
|
+
"description": "Hard logic and architecture tasks. Uses Coder deep execution contour."
|
|
74
|
+
},
|
|
75
|
+
"deep": {
|
|
76
|
+
"model": "openrouter/openai/o1",
|
|
77
|
+
"variant": "medium",
|
|
78
|
+
"description": "Deep autonomous implementation with full context buildup. Uses Coder deep execution contour."
|
|
79
|
+
},
|
|
80
|
+
"quick": {
|
|
81
|
+
"model": "openrouter/google/gemini-2.0-flash",
|
|
82
|
+
"description": "Fast bounded execution: single-file fixes, typos, and simple modifications. Uses Coder fast execution contour."
|
|
83
|
+
},
|
|
84
|
+
"writing": {
|
|
85
|
+
"model": "openrouter/kimi/kimi-latest",
|
|
86
|
+
"description": "Documentation and prose tasks with bounded scope. Uses Coder fast execution contour."
|
|
87
|
+
},
|
|
88
|
+
"git": {
|
|
89
|
+
"model": "openrouter/google/gemini-2.0-flash",
|
|
90
|
+
"description": "Git, commit, diff, and repository hygiene tasks."
|
|
91
|
+
},
|
|
92
|
+
"unspecified-low": {
|
|
93
|
+
"model": "openrouter/anthropic/claude-3.5-sonnet",
|
|
94
|
+
"description": "Unclassifiable moderate tasks with bounded scope. Uses Coder fast execution contour."
|
|
95
|
+
},
|
|
96
|
+
"unspecified-high": {
|
|
97
|
+
"model": "openrouter/anthropic/claude-3.5-opus",
|
|
98
|
+
"variant": "max",
|
|
99
|
+
"description": "Unclassifiable substantial tasks across modules. Uses Coder deep execution contour."
|
|
100
|
+
}
|
|
26
101
|
},
|
|
102
|
+
"categoryRequirements": {},
|
|
103
|
+
"modelFamilies": [],
|
|
27
104
|
"auth": {
|
|
28
|
-
"openrouter": "{env:OPENROUTER_API_KEY}",
|
|
29
|
-
"openai": "{env:OPENAI_API_KEY}",
|
|
30
105
|
"googleSearch": "{env:GOOGLE_SEARCH_API_KEY}",
|
|
31
106
|
"stitch": "{env:STITCH_AI_API_KEY}",
|
|
32
107
|
"firecrawl": "{env:FIRECRAWL_API_KEY}",
|
|
@@ -34,25 +109,106 @@
|
|
|
34
109
|
},
|
|
35
110
|
"ollama": {
|
|
36
111
|
"enabled": false,
|
|
37
|
-
"model": "qwen3.5:4b",
|
|
38
|
-
"baseUrl": "http://localhost:11434",
|
|
112
|
+
"model": "{env:OLLAMA_MODEL:-qwen3.5:4b}",
|
|
113
|
+
"baseUrl": "{env:OLLAMA_BASE_URL:-http://localhost:11434}",
|
|
39
114
|
"purpose": "helper"
|
|
40
115
|
},
|
|
116
|
+
"fast_apply": {
|
|
117
|
+
"enabled": false,
|
|
118
|
+
"ollama_url": "{env:OLLAMA_BASE_URL:-http://localhost:11434}",
|
|
119
|
+
"model": "{env:OLLAMA_MODEL:-qwen3.5:4b}",
|
|
120
|
+
"timeout": 30000
|
|
121
|
+
},
|
|
41
122
|
"mcp": {
|
|
42
|
-
"playwright": {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"
|
|
48
|
-
|
|
123
|
+
"playwright": {
|
|
124
|
+
"enabled": true,
|
|
125
|
+
"command": ["node", "{pluginRoot}/assets/mcp/playwright.mjs"],
|
|
126
|
+
"timeout": 600000
|
|
127
|
+
},
|
|
128
|
+
"stitch": {
|
|
129
|
+
"enabled": true,
|
|
130
|
+
"type": "remote",
|
|
131
|
+
"url": "https://stitch.googleapis.com/mcp",
|
|
132
|
+
"headers": { "X-Goog-Api-Key": "{env:STITCH_AI_API_KEY}" },
|
|
133
|
+
"timeout": 600000
|
|
134
|
+
},
|
|
135
|
+
"sequential-thinking": {
|
|
136
|
+
"enabled": true,
|
|
137
|
+
"command": ["node", "{pluginRoot}/assets/runtime/npm-package-runner.mjs", "@modelcontextprotocol/server-sequential-thinking"],
|
|
138
|
+
"timeout": 600000
|
|
139
|
+
},
|
|
140
|
+
"firecrawl": {
|
|
141
|
+
"enabled": true,
|
|
142
|
+
"command": ["node", "{pluginRoot}/assets/runtime/npm-package-runner.mjs", "firecrawl-mcp"],
|
|
143
|
+
"environment": { "FIRECRAWL_API_KEY": "{env:FIRECRAWL_API_KEY}" },
|
|
144
|
+
"timeout": 600000
|
|
145
|
+
},
|
|
146
|
+
"rag": {
|
|
147
|
+
"enabled": true,
|
|
148
|
+
"type": "local",
|
|
149
|
+
"command": ["node", "{pluginRoot}/assets/mcp/rag.mjs"],
|
|
150
|
+
"environment": {
|
|
151
|
+
"OPENCODE_RAG_URL": "{env:OPENCODE_RAG_URL:-http://localhost:9002/tools/search}"
|
|
152
|
+
},
|
|
153
|
+
"timeout": 600000
|
|
154
|
+
},
|
|
155
|
+
"mempalace": {
|
|
156
|
+
"enabled": true,
|
|
157
|
+
"type": "local",
|
|
158
|
+
"command": ["node", "{pluginRoot}/assets/mcp/mempalace.mjs", "--palace", "./.opencode/palace"],
|
|
159
|
+
"timeout": 600000
|
|
160
|
+
},
|
|
161
|
+
"context7": {
|
|
162
|
+
"enabled": true,
|
|
163
|
+
"type": "remote",
|
|
164
|
+
"url": "https://mcp.context7.com/mcp",
|
|
165
|
+
"headers": { "X-API-KEY": "{env:CONTEXT7_API_KEY}" },
|
|
166
|
+
"timeout": 600000
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
"skill_discovery": {
|
|
170
|
+
"config_sources": true,
|
|
171
|
+
"project_opencode": true,
|
|
172
|
+
"global_opencode": false,
|
|
173
|
+
"project_claude": false,
|
|
174
|
+
"global_claude": false,
|
|
175
|
+
"project_agents": false,
|
|
176
|
+
"global_agents": false
|
|
177
|
+
},
|
|
178
|
+
"skills": {
|
|
179
|
+
"enabled": true,
|
|
180
|
+
"disabled": []
|
|
49
181
|
},
|
|
50
182
|
"lsp": {
|
|
51
|
-
"typescript": {
|
|
52
|
-
|
|
53
|
-
|
|
183
|
+
"typescript": {
|
|
184
|
+
"command": ["typescript-language-server", "--stdio"],
|
|
185
|
+
"extensions": [".ts", ".tsx", ".mts", ".cts"]
|
|
186
|
+
},
|
|
187
|
+
"svelte": {
|
|
188
|
+
"command": ["svelteserver", "--stdio"],
|
|
189
|
+
"extensions": [".svelte"]
|
|
190
|
+
},
|
|
191
|
+
"eslint": {
|
|
192
|
+
"command": ["node", "{pluginRoot}/assets/runtime/npm-package-runner.mjs", "eslint-lsp", "--stdio"],
|
|
193
|
+
"extensions": [".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs", ".svelte"]
|
|
194
|
+
},
|
|
195
|
+
"bash": {
|
|
196
|
+
"command": ["node", "{pluginRoot}/assets/runtime/npm-package-runner.mjs", "bash-language-server", "start"],
|
|
197
|
+
"extensions": [".sh", ".bash"]
|
|
198
|
+
},
|
|
199
|
+
"pyright": {
|
|
200
|
+
"command": ["pyright-langserver", "--stdio"],
|
|
201
|
+
"extensions": [".py"]
|
|
202
|
+
}
|
|
54
203
|
},
|
|
55
204
|
"subtask2": {
|
|
56
|
-
"replace_generic": true
|
|
205
|
+
"replace_generic": true,
|
|
206
|
+
"generic_return": null
|
|
207
|
+
},
|
|
208
|
+
"permissions": {
|
|
209
|
+
"read": { "*": "allow", "*.env": "deny", "*.env.*": "deny", "*.env.example": "allow" },
|
|
210
|
+
"edit": { "*": "allow" },
|
|
211
|
+
"bash": { "*": "allow" },
|
|
212
|
+
"deny_paths": ["**/backup/**", "**/secrets.*", "**/.env", "**/.env.*"]
|
|
57
213
|
}
|
|
58
|
-
}
|
|
214
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hiai-gg/hiai-opencode",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Unified OpenCode plugin — canonical 12-agent model with bundled skills, MCP integrations, LSP, and permissions in one install.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"hiai-opencode": "./assets/cli/hiai-opencode.mjs"
|
|
10
|
+
},
|
|
8
11
|
"exports": {
|
|
9
12
|
".": {
|
|
10
13
|
"import": "./dist/index.js",
|
package/src/agents/AGENTS.md
CHANGED
|
@@ -56,9 +56,8 @@ These files run after the prompt library and can override what was authored. Alw
|
|
|
56
56
|
|
|
57
57
|
| What to change | Edit |
|
|
58
58
|
|---|---|
|
|
59
|
-
|
|
|
60
|
-
| Per-
|
|
61
|
-
| Per-category default model | `src/config/defaults.ts` |
|
|
59
|
+
| Per-agent default model | `hiai-opencode.json` |
|
|
60
|
+
| Per-category default model | `hiai-opencode.json` |
|
|
62
61
|
| Config schema defaults | `src/config/types.ts` |
|
|
63
62
|
|
|
64
63
|
## Prompt Measurement
|
|
@@ -72,4 +71,4 @@ Run `bun run prompts:measure` to generate snapshot files in `dist/prompt-snapsho
|
|
|
72
71
|
3. Local helper launchers: `assets/mcp/*`
|
|
73
72
|
4. NPM bootstrapper for local tools: `assets/runtime/npm-package-runner.mjs`
|
|
74
73
|
|
|
75
|
-
For more detail see `AGENTS.md` (root) and `ARCHITECTURE.md` (root).
|
|
74
|
+
For more detail see `AGENTS.md` (root) and `ARCHITECTURE.md` (root).
|
package/src/config/defaults.ts
CHANGED
|
@@ -1,146 +1,68 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Runtime defaults for hiai-opencode.
|
|
3
|
+
*
|
|
4
|
+
* Model defaults are intentionally not defined in TypeScript.
|
|
5
|
+
* The bundled hiai-opencode.json file is the single source of truth for:
|
|
6
|
+
* - agent models
|
|
7
|
+
* - category models
|
|
8
|
+
* - user-editable runtime defaults
|
|
3
9
|
*/
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
10
|
+
import { existsSync, readFileSync } from "node:fs"
|
|
11
|
+
import { dirname, join, normalize } from "node:path"
|
|
12
|
+
import type { HiaiOpencodeConfig } from "./types.js"
|
|
7
13
|
|
|
8
|
-
function
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
function findPluginRoot(): string {
|
|
15
|
+
const candidates = [
|
|
16
|
+
// Source tree: src/config/defaults.ts -> repo root
|
|
17
|
+
join(import.meta.dirname, "..", ".."),
|
|
18
|
+
// Built package: dist/index.js bundle -> package root
|
|
19
|
+
join(import.meta.dirname, ".."),
|
|
20
|
+
// Non-bundled compiled output: dist/config/defaults.js -> package root
|
|
21
|
+
join(import.meta.dirname, "..", ".."),
|
|
22
|
+
dirname(process.argv[1] ?? ""),
|
|
23
|
+
process.cwd(),
|
|
24
|
+
]
|
|
15
25
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
26
|
+
for (const candidate of candidates) {
|
|
27
|
+
const root = normalize(candidate)
|
|
28
|
+
if (existsSync(join(root, "hiai-opencode.json"))) {
|
|
29
|
+
return root
|
|
30
|
+
}
|
|
19
31
|
}
|
|
20
32
|
|
|
21
|
-
|
|
33
|
+
throw new Error(
|
|
34
|
+
"[hiai-opencode] Cannot find bundled hiai-opencode.json. The package is incomplete.",
|
|
35
|
+
)
|
|
22
36
|
}
|
|
23
37
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
strategist: { model: MODEL_PRESETS.strategist },
|
|
29
|
-
critic: { model: MODEL_PRESETS.critic },
|
|
30
|
-
coder: { model: MODEL_PRESETS.mid },
|
|
31
|
-
designer: {
|
|
32
|
-
model: "openrouter/google/gemini-3.1-pro",
|
|
33
|
-
description: "Creative visual problem-solver for high-touch UI, interaction, and brand-level interface direction. Best used when the task needs taste, composition, and design judgment rather than plain implementation. (Designer - HiaiOpenCode)",
|
|
34
|
-
},
|
|
35
|
-
sub: { model: MODEL_PRESETS.fast },
|
|
36
|
-
researcher: { model: MODEL_PRESETS.fast },
|
|
37
|
-
multimodal: { model: MODEL_PRESETS.vision },
|
|
38
|
-
"quality-guardian": { model: MODEL_PRESETS.mid },
|
|
39
|
-
"platform-manager": { model: MODEL_PRESETS.fast },
|
|
40
|
-
brainstormer: { model: MODEL_PRESETS.fast },
|
|
41
|
-
"agent-skills": { model: MODEL_PRESETS.fast },
|
|
42
|
-
},
|
|
43
|
-
agentRequirements: {},
|
|
44
|
-
categories: {
|
|
45
|
-
"visual-engineering": { model: MODEL_PRESETS.vision, variant: "high" },
|
|
46
|
-
artistry: { model: MODEL_PRESETS.vision, variant: "high" },
|
|
47
|
-
ultrabrain: { model: MODEL_PRESETS.ultrahigh, variant: "xhigh" },
|
|
48
|
-
deep: { model: MODEL_PRESETS.reasoning, variant: "medium" },
|
|
49
|
-
quick: { model: MODEL_PRESETS.fast },
|
|
50
|
-
writing: { model: MODEL_PRESETS.writing },
|
|
51
|
-
git: { model: MODEL_PRESETS.fast },
|
|
52
|
-
"unspecified-low": { model: MODEL_PRESETS.mid },
|
|
53
|
-
"unspecified-high": { model: MODEL_PRESETS.high, variant: "max" },
|
|
54
|
-
},
|
|
55
|
-
categoryRequirements: {},
|
|
38
|
+
function expandPluginRootPlaceholders(value: unknown, pluginRoot: string): unknown {
|
|
39
|
+
if (typeof value === "string") {
|
|
40
|
+
return value.replaceAll("{pluginRoot}", pluginRoot)
|
|
41
|
+
}
|
|
56
42
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
command: createNpmPackageCommand("@playwright/mcp@latest"),
|
|
61
|
-
timeout: 600000,
|
|
62
|
-
},
|
|
63
|
-
stitch: {
|
|
64
|
-
enabled: true,
|
|
65
|
-
type: "remote",
|
|
66
|
-
url: "https://stitch.googleapis.com/mcp",
|
|
67
|
-
headers: { "X-Goog-Api-Key": "{env:STITCH_AI_API_KEY}" },
|
|
68
|
-
timeout: 600000,
|
|
69
|
-
},
|
|
70
|
-
"sequential-thinking": {
|
|
71
|
-
enabled: true,
|
|
72
|
-
command: createUpstreamNpxCommand("@modelcontextprotocol/server-sequential-thinking"),
|
|
73
|
-
timeout: 600000,
|
|
74
|
-
},
|
|
75
|
-
firecrawl: {
|
|
76
|
-
enabled: true,
|
|
77
|
-
command: createUpstreamNpxCommand("firecrawl-mcp"),
|
|
78
|
-
timeout: 600000,
|
|
79
|
-
environment: { FIRECRAWL_API_KEY: "{env:FIRECRAWL_API_KEY}" },
|
|
80
|
-
},
|
|
81
|
-
rag: {
|
|
82
|
-
enabled: true,
|
|
83
|
-
type: "remote",
|
|
84
|
-
url: "http://localhost:9002",
|
|
85
|
-
timeout: 600000,
|
|
86
|
-
},
|
|
87
|
-
context7: {
|
|
88
|
-
enabled: true,
|
|
89
|
-
type: "remote",
|
|
90
|
-
url: "https://mcp.context7.com/mcp",
|
|
91
|
-
headers: { "X-API-KEY": "{env:CONTEXT7_API_KEY}" },
|
|
92
|
-
timeout: 600000,
|
|
93
|
-
},
|
|
94
|
-
mempalace: {
|
|
95
|
-
enabled: true,
|
|
96
|
-
command: ["node", resolveAssetScript("mcp", "mempalace.mjs"), "--palace", "./.opencode/palace"],
|
|
97
|
-
timeout: 600000,
|
|
98
|
-
},
|
|
99
|
-
},
|
|
43
|
+
if (Array.isArray(value)) {
|
|
44
|
+
return value.map((item) => expandPluginRootPlaceholders(item, pluginRoot))
|
|
45
|
+
}
|
|
100
46
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
extensions: [".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs", ".svelte"],
|
|
113
|
-
},
|
|
114
|
-
bash: {
|
|
115
|
-
command: createNpmPackageCommand("bash-language-server", "start"),
|
|
116
|
-
extensions: [".sh", ".bash"],
|
|
117
|
-
},
|
|
118
|
-
pyright: {
|
|
119
|
-
command: ["pyright-langserver", "--stdio"],
|
|
120
|
-
extensions: [".py"],
|
|
121
|
-
},
|
|
122
|
-
},
|
|
47
|
+
if (value && typeof value === "object") {
|
|
48
|
+
return Object.fromEntries(
|
|
49
|
+
Object.entries(value).map(([key, entry]) => [
|
|
50
|
+
key,
|
|
51
|
+
expandPluginRootPlaceholders(entry, pluginRoot),
|
|
52
|
+
]),
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return value
|
|
57
|
+
}
|
|
123
58
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
59
|
+
function loadBundledDefaultConfig(): HiaiOpencodeConfig {
|
|
60
|
+
const pluginRoot = findPluginRoot()
|
|
61
|
+
const configPath = join(pluginRoot, "hiai-opencode.json")
|
|
62
|
+
const raw = readFileSync(configPath, "utf-8")
|
|
63
|
+
const parsed = JSON.parse(raw) as HiaiOpencodeConfig
|
|
128
64
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
disabled: [],
|
|
132
|
-
},
|
|
65
|
+
return expandPluginRootPlaceholders(parsed, pluginRoot) as HiaiOpencodeConfig
|
|
66
|
+
}
|
|
133
67
|
|
|
134
|
-
|
|
135
|
-
read: { "*": "allow", "*.env": "deny", "*.env.*": "deny", "*.env.example": "allow" },
|
|
136
|
-
edit: { "*": "allow" },
|
|
137
|
-
bash: { "*": "allow" },
|
|
138
|
-
deny_paths: ["**/backup/**", "**/secrets.*", "**/.env", "**/.env.*"],
|
|
139
|
-
},
|
|
140
|
-
ollama: {
|
|
141
|
-
enabled: false,
|
|
142
|
-
model: "{env:OLLAMA_MODEL:-qwen3.5:4b}",
|
|
143
|
-
baseUrl: "http://localhost:11434",
|
|
144
|
-
purpose: "helper",
|
|
145
|
-
},
|
|
146
|
-
};
|
|
68
|
+
export const defaultConfig: HiaiOpencodeConfig = loadBundledDefaultConfig()
|
package/src/config/index.ts
CHANGED
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
export { loadConfig, resolveEnvVars, resolveMcpEnv } from "./loader.js";
|
|
12
12
|
export { HiaiOpencodeConfigSchema } from "./platform-schema.js";
|
|
13
13
|
export { defaultConfig } from "./defaults.js";
|
|
14
|
-
export { MODEL_PRESETS, MODEL_ROLE_GUIDE, PROVIDER_MODEL_RULES } from "./models.js";
|
|
15
14
|
export type {
|
|
16
15
|
HiaiOpencodeConfig,
|
|
17
16
|
AgentConfig,
|
package/src/config/loader.ts
CHANGED
|
@@ -164,7 +164,10 @@ export function loadConfig(projectDir: string): HiaiOpencodeConfig {
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
export function resolveEnvVars(value: string): string {
|
|
167
|
-
return value.replace(/\{env:([^}]+)\}/g, (_,
|
|
167
|
+
return value.replace(/\{env:([^}]+)\}/g, (_, expression) => {
|
|
168
|
+
const [key, fallback] = String(expression).split(":-", 2);
|
|
169
|
+
return process.env[key] || fallback || "";
|
|
170
|
+
});
|
|
168
171
|
}
|
|
169
172
|
|
|
170
173
|
export function resolveMcpEnv(config: HiaiOpencodeConfig): HiaiOpencodeConfig {
|
|
@@ -41,6 +41,7 @@ export const McpServerConfigSchema = z.object({
|
|
|
41
41
|
enabled: z.boolean().default(true),
|
|
42
42
|
type: z.enum(["remote", "local"]).optional(),
|
|
43
43
|
url: z.string().optional(),
|
|
44
|
+
headers: z.record(z.string(), z.string()).optional(),
|
|
44
45
|
command: z.array(z.string()).optional(),
|
|
45
46
|
timeout: z.number().optional(),
|
|
46
47
|
environment: z.record(z.string(), z.string()).optional(),
|
|
@@ -62,6 +63,16 @@ export const SkillsConfigSchema = z.object({
|
|
|
62
63
|
disabled: z.array(z.string()).optional(),
|
|
63
64
|
});
|
|
64
65
|
|
|
66
|
+
export const SkillDiscoveryConfigSchema = z.object({
|
|
67
|
+
config_sources: z.boolean().optional(),
|
|
68
|
+
project_opencode: z.boolean().optional(),
|
|
69
|
+
global_opencode: z.boolean().optional(),
|
|
70
|
+
project_claude: z.boolean().optional(),
|
|
71
|
+
global_claude: z.boolean().optional(),
|
|
72
|
+
project_agents: z.boolean().optional(),
|
|
73
|
+
global_agents: z.boolean().optional(),
|
|
74
|
+
});
|
|
75
|
+
|
|
65
76
|
export const PermissionsConfigSchema = z.object({
|
|
66
77
|
read: z.record(z.string(), z.string()).optional(),
|
|
67
78
|
edit: z.record(z.string(), z.string()).optional(),
|
|
@@ -95,8 +106,8 @@ export const AuthKeysSchema = z.object({
|
|
|
95
106
|
|
|
96
107
|
export const OllamaConfigSchema = z.object({
|
|
97
108
|
enabled: z.boolean().default(false),
|
|
98
|
-
model: z.string().default("
|
|
99
|
-
baseUrl: z.string().default("
|
|
109
|
+
model: z.string().default(""),
|
|
110
|
+
baseUrl: z.string().default(""),
|
|
100
111
|
purpose: z.enum(["verification", "helper", "fallback"]).default("helper"),
|
|
101
112
|
});
|
|
102
113
|
|
|
@@ -129,6 +140,8 @@ const AgentsConfigSchema = z.object({
|
|
|
129
140
|
zoe: AgentConfigSchema.optional(),
|
|
130
141
|
build: AgentConfigSchema.optional(),
|
|
131
142
|
"pre-plan": AgentConfigSchema.optional(),
|
|
143
|
+
manager: AgentConfigSchema.optional(),
|
|
144
|
+
vision: AgentConfigSchema.optional(),
|
|
132
145
|
logician: AgentConfigSchema.optional(),
|
|
133
146
|
librarian: AgentConfigSchema.optional(),
|
|
134
147
|
explore: AgentConfigSchema.optional(),
|
|
@@ -161,6 +174,8 @@ const AgentRequirementsConfigSchema = z.object({
|
|
|
161
174
|
zoe: ModelRequirementSchema.optional(),
|
|
162
175
|
build: ModelRequirementSchema.optional(),
|
|
163
176
|
"pre-plan": ModelRequirementSchema.optional(),
|
|
177
|
+
manager: ModelRequirementSchema.optional(),
|
|
178
|
+
vision: ModelRequirementSchema.optional(),
|
|
164
179
|
logician: ModelRequirementSchema.optional(),
|
|
165
180
|
librarian: ModelRequirementSchema.optional(),
|
|
166
181
|
explore: ModelRequirementSchema.optional(),
|
|
@@ -184,6 +199,7 @@ export const HiaiOpencodeConfigSchema = z.object({
|
|
|
184
199
|
lsp: z.record(z.string(), LspServerConfigSchema).optional(),
|
|
185
200
|
subtask2: Subtask2ConfigSchema.optional(),
|
|
186
201
|
skills: SkillsConfigSchema.optional(),
|
|
202
|
+
skill_discovery: SkillDiscoveryConfigSchema.optional(),
|
|
187
203
|
permissions: PermissionsConfigSchema.optional(),
|
|
188
204
|
auth: AuthKeysSchema.optional(),
|
|
189
205
|
ollama: OllamaConfigSchema.optional(),
|
|
@@ -79,6 +79,8 @@ export const AgentOverridesSchema = z.object({
|
|
|
79
79
|
general: AgentOverrideConfigSchema.optional(),
|
|
80
80
|
zoe: AgentOverrideConfigSchema.optional(),
|
|
81
81
|
"pre-plan": AgentOverrideConfigSchema.optional(),
|
|
82
|
+
manager: AgentOverrideConfigSchema.optional(),
|
|
83
|
+
vision: AgentOverrideConfigSchema.optional(),
|
|
82
84
|
"logician": AgentOverrideConfigSchema.optional(),
|
|
83
85
|
librarian: AgentOverrideConfigSchema.optional(),
|
|
84
86
|
explore: AgentOverrideConfigSchema.optional(),
|