@hiai-gg/hiai-opencode 0.1.5 → 0.1.6
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 +14 -8
- package/AGENTS.md +14 -5
- package/LICENSE.md +0 -1
- package/README.md +42 -23
- package/assets/cli/hiai-opencode.mjs +590 -7
- package/assets/mcp/mempalace.mjs +159 -25
- package/config/hiai-opencode.schema.json +13 -2
- package/dist/agents/dynamic-agent-core-sections.d.ts +4 -1
- package/dist/agents/dynamic-agent-prompt-builder.d.ts +1 -1
- package/dist/config/platform-schema.d.ts +2 -6
- package/dist/config/schema/commands.d.ts +1 -0
- package/dist/config/schema/oh-my-opencode-config.d.ts +1 -3
- package/dist/config/types.d.ts +1 -3
- package/dist/features/builtin-commands/templates/doctor.d.ts +1 -0
- package/dist/features/builtin-commands/types.d.ts +1 -1
- package/dist/features/builtin-skills/skills/hiai-opencode-setup.d.ts +2 -0
- package/dist/features/builtin-skills/skills/index.d.ts +1 -0
- package/dist/index.js +348 -1424
- package/dist/shared/mcp-static-export.d.ts +22 -0
- package/dist/tools/ast-grep/constants.d.ts +1 -1
- package/dist/tools/ast-grep/environment-check.d.ts +1 -5
- package/dist/tools/ast-grep/language-support.d.ts +0 -1
- package/dist/tools/ast-grep/types.d.ts +1 -2
- package/hiai-opencode.json +4 -2
- package/package.json +6 -4
- package/src/agents/bob/default.ts +6 -1
- package/src/agents/bob/gpt-pro.ts +1 -0
- package/src/agents/bob.ts +1 -0
- package/src/agents/coder/gpt-codex.ts +1 -0
- package/src/agents/coder/gpt-pro.ts +1 -0
- package/src/agents/coder/gpt.ts +1 -0
- package/src/agents/dynamic-agent-core-sections.ts +36 -0
- package/src/agents/dynamic-agent-prompt-builder.ts +1 -0
- package/src/config/defaults.ts +14 -1
- package/src/config/model-slots-and-export.test.ts +55 -0
- package/src/config/platform-schema.ts +1 -3
- package/src/config/schema/commands.ts +1 -0
- package/src/config/schema/oh-my-opencode-config.ts +0 -3
- package/src/config/types.ts +1 -3
- package/src/features/builtin-commands/commands.ts +7 -0
- package/src/features/builtin-commands/templates/doctor.ts +43 -0
- package/src/features/builtin-commands/types.ts +1 -1
- package/src/features/builtin-skills/skills/hiai-opencode-setup.ts +69 -0
- package/src/features/builtin-skills/skills/index.ts +1 -0
- package/src/features/builtin-skills/skills.ts +10 -1
- package/src/index.ts +3 -75
- package/src/shared/mcp-static-export.ts +121 -0
- package/src/tools/ast-grep/constants.ts +1 -1
- package/src/tools/ast-grep/environment-check.ts +2 -32
- package/src/tools/ast-grep/language-support.ts +0 -3
- package/src/tools/ast-grep/types.ts +1 -2
- package/src/tools/skill-mcp/tools.test.ts +44 -0
- package/dist/ast-grep-napi.win32-x64-msvc-67c0y8nc.node +0 -0
- package/dist/config/loader.test.d.ts +0 -1
- package/dist/config/models.d.ts +0 -13
- package/dist/internals/plugins/websearch-cited/google.d.ts +0 -38
- package/dist/internals/plugins/websearch-cited/index.d.ts +0 -17
- package/dist/internals/plugins/websearch-cited/openai.d.ts +0 -9
- package/dist/internals/plugins/websearch-cited/openrouter.d.ts +0 -2
- package/dist/internals/plugins/websearch-cited/types.d.ts +0 -5
- package/src/internals/plugins/websearch-cited/LICENSE +0 -214
- package/src/internals/plugins/websearch-cited/codex_prompt.txt +0 -79
- package/src/internals/plugins/websearch-cited/google.ts +0 -749
- package/src/internals/plugins/websearch-cited/index.ts +0 -306
- package/src/internals/plugins/websearch-cited/openai.ts +0 -407
- package/src/internals/plugins/websearch-cited/openrouter.ts +0 -190
- package/src/internals/plugins/websearch-cited/types.ts +0 -7
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { HiaiOpencodeConfig } from "../config/types";
|
|
2
|
+
type StaticMcpServer = {
|
|
3
|
+
type?: "http" | "stdio";
|
|
4
|
+
url?: string;
|
|
5
|
+
command?: string;
|
|
6
|
+
args?: string[];
|
|
7
|
+
env?: Record<string, string>;
|
|
8
|
+
headers?: Record<string, string>;
|
|
9
|
+
};
|
|
10
|
+
export declare const MCP_EXPORT_MARKER = "hiai-opencode";
|
|
11
|
+
type StaticMcpJsonPayload = {
|
|
12
|
+
mcpServers: Record<string, StaticMcpServer>;
|
|
13
|
+
_meta?: {
|
|
14
|
+
generatedBy: typeof MCP_EXPORT_MARKER;
|
|
15
|
+
version: 1;
|
|
16
|
+
generatedAt: string;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
export declare function buildStaticMcpJson(config: HiaiOpencodeConfig): StaticMcpJsonPayload;
|
|
20
|
+
export declare function isManagedStaticMcpFile(path: string): boolean;
|
|
21
|
+
export declare function autoExportStaticMcpJson(directory: string, config: HiaiOpencodeConfig): void;
|
|
22
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type { EnvironmentCheckResult } from "./environment-check";
|
|
2
2
|
export { checkEnvironment, formatEnvironmentCheck } from "./environment-check";
|
|
3
|
-
export { CLI_LANGUAGES,
|
|
3
|
+
export { CLI_LANGUAGES, LANG_EXTENSIONS } from "./language-support";
|
|
4
4
|
export { DEFAULT_TIMEOUT_MS, DEFAULT_MAX_OUTPUT_BYTES, DEFAULT_MAX_MATCHES } from "./language-support";
|
|
5
5
|
export { findSgCliPathSync, getSgCliPath, setSgCliPath } from "./sg-cli-path";
|
|
@@ -4,13 +4,9 @@ export interface EnvironmentCheckResult {
|
|
|
4
4
|
path: string;
|
|
5
5
|
error?: string;
|
|
6
6
|
};
|
|
7
|
-
napi: {
|
|
8
|
-
available: boolean;
|
|
9
|
-
error?: string;
|
|
10
|
-
};
|
|
11
7
|
}
|
|
12
8
|
/**
|
|
13
|
-
* Check if ast-grep CLI
|
|
9
|
+
* Check if ast-grep CLI is available.
|
|
14
10
|
* Call this at startup to provide early feedback about missing dependencies.
|
|
15
11
|
*/
|
|
16
12
|
export declare function checkEnvironment(): EnvironmentCheckResult;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export declare const CLI_LANGUAGES: readonly ["bash", "c", "cpp", "csharp", "css", "elixir", "go", "haskell", "html", "java", "javascript", "json", "kotlin", "lua", "nix", "php", "python", "ruby", "rust", "scala", "solidity", "swift", "typescript", "tsx", "yaml"];
|
|
2
|
-
export declare const NAPI_LANGUAGES: readonly ["html", "javascript", "tsx", "css", "typescript"];
|
|
3
2
|
export declare const DEFAULT_TIMEOUT_MS = 300000;
|
|
4
3
|
export declare const DEFAULT_MAX_OUTPUT_BYTES: number;
|
|
5
4
|
export declare const DEFAULT_MAX_MATCHES = 500;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type { CLI_LANGUAGES
|
|
1
|
+
import type { CLI_LANGUAGES } from "./constants";
|
|
2
2
|
export type CliLanguage = (typeof CLI_LANGUAGES)[number];
|
|
3
|
-
export type NapiLanguage = (typeof NAPI_LANGUAGES)[number];
|
|
4
3
|
export interface Position {
|
|
5
4
|
line: number;
|
|
6
5
|
column: number;
|
package/hiai-opencode.json
CHANGED
|
@@ -44,7 +44,6 @@
|
|
|
44
44
|
}
|
|
45
45
|
},
|
|
46
46
|
"auth": {
|
|
47
|
-
"googleSearch": "{env:GOOGLE_SEARCH_API_KEY}",
|
|
48
47
|
"stitch": "{env:STITCH_AI_API_KEY}",
|
|
49
48
|
"firecrawl": "{env:FIRECRAWL_API_KEY}",
|
|
50
49
|
"context7": "{env:CONTEXT7_API_KEY}"
|
|
@@ -55,7 +54,10 @@
|
|
|
55
54
|
"sequential-thinking": { "enabled": true },
|
|
56
55
|
"firecrawl": { "enabled": true },
|
|
57
56
|
"rag": { "enabled": true },
|
|
58
|
-
"mempalace": {
|
|
57
|
+
"mempalace": {
|
|
58
|
+
"enabled": true,
|
|
59
|
+
"pythonPath": "{env:MEMPALACE_PYTHON:-./.venv/bin/python}"
|
|
60
|
+
},
|
|
59
61
|
"context7": { "enabled": true }
|
|
60
62
|
},
|
|
61
63
|
"lsp": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hiai-gg/hiai-opencode",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
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",
|
|
@@ -50,19 +50,21 @@
|
|
|
50
50
|
"access": "public"
|
|
51
51
|
},
|
|
52
52
|
"scripts": {
|
|
53
|
-
"
|
|
53
|
+
"clean:dist": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
54
|
+
"build": "bun run clean:dist && bun build src/index.ts --outdir dist --target bun --format esm && tsc --emitDeclarationOnly",
|
|
54
55
|
"build:bundle": "bun build src/index.ts --outdir dist --target bun --format esm",
|
|
55
56
|
"build:types": "tsc --emitDeclarationOnly",
|
|
56
57
|
"typecheck": "tsc --noEmit",
|
|
58
|
+
"test": "bun test",
|
|
59
|
+
"pack:check": "npm pack --dry-run",
|
|
57
60
|
"prepare": "bun run build",
|
|
58
|
-
"prepublishOnly": "bun run build"
|
|
61
|
+
"prepublishOnly": "bun run typecheck && bun run test && bun run build && bun run pack:check"
|
|
59
62
|
},
|
|
60
63
|
"dependencies": {
|
|
61
64
|
"bun-pty": "^0.4.8",
|
|
62
65
|
"@opencode-ai/plugin": "^1.4.0",
|
|
63
66
|
"@opencode-ai/sdk": "^1.4.0",
|
|
64
67
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
65
|
-
"@ast-grep/napi": "^0.37.0",
|
|
66
68
|
"zod": "^4.3.0",
|
|
67
69
|
"jsonc-parser": "^3.3.1",
|
|
68
70
|
"js-yaml": "^4.1.0",
|
|
@@ -36,7 +36,12 @@ export function buildDefaultBobPrompt(
|
|
|
36
36
|
useTaskSystem = false,
|
|
37
37
|
): string {
|
|
38
38
|
const keyTriggers = buildKeyTriggersSection(availableAgents, availableSkills)
|
|
39
|
-
const toolSelection = buildToolSelectionTable(
|
|
39
|
+
const toolSelection = buildToolSelectionTable(
|
|
40
|
+
availableAgents,
|
|
41
|
+
availableTools,
|
|
42
|
+
availableSkills,
|
|
43
|
+
{ includeIntegrationPrimer: true },
|
|
44
|
+
)
|
|
40
45
|
const researcherSection = buildResearcherSection(availableAgents)
|
|
41
46
|
const categorySkillsGuide = buildCategorySkillsDelegationGuide(availableCategories, availableSkills)
|
|
42
47
|
const delegationTable = buildDelegationTable(availableAgents)
|
|
@@ -88,6 +88,7 @@ export function buildGptProBobPrompt(
|
|
|
88
88
|
availableAgents,
|
|
89
89
|
availableTools,
|
|
90
90
|
availableSkills,
|
|
91
|
+
{ includeIntegrationPrimer: true },
|
|
91
92
|
);
|
|
92
93
|
const researcherSection = buildResearcherSection(availableAgents);
|
|
93
94
|
const categorySkillsGuide = buildCategorySkillsDelegationGuide(
|
package/src/agents/bob.ts
CHANGED
|
@@ -54,6 +54,7 @@ function buildDynamicBobPrompt(
|
|
|
54
54
|
availableAgents,
|
|
55
55
|
availableTools,
|
|
56
56
|
availableSkills,
|
|
57
|
+
{ includeIntegrationPrimer: true },
|
|
57
58
|
);
|
|
58
59
|
const researcherSection = buildResearcherSection(availableAgents);
|
|
59
60
|
const categorySkillsGuide = buildCategorySkillsDelegationGuide(
|
|
@@ -56,6 +56,7 @@ export function buildCoderPrompt(
|
|
|
56
56
|
availableAgents,
|
|
57
57
|
availableTools,
|
|
58
58
|
availableSkills,
|
|
59
|
+
{ includeIntegrationPrimer: true },
|
|
59
60
|
);
|
|
60
61
|
const researcherSection = buildResearcherSection(availableAgents);
|
|
61
62
|
const categorySkillsGuide = buildCategorySkillsDelegationGuide(
|
|
@@ -51,6 +51,7 @@ export function buildCoderPrompt(
|
|
|
51
51
|
availableAgents,
|
|
52
52
|
availableTools,
|
|
53
53
|
availableSkills,
|
|
54
|
+
{ includeIntegrationPrimer: true },
|
|
54
55
|
);
|
|
55
56
|
const researcherSection = buildResearcherSection(availableAgents);
|
|
56
57
|
const categorySkillsGuide = buildCategorySkillsDelegationGuide(
|
package/src/agents/coder/gpt.ts
CHANGED
|
@@ -32,6 +32,7 @@ export function buildCoderPrompt(
|
|
|
32
32
|
availableAgents,
|
|
33
33
|
availableTools,
|
|
34
34
|
availableSkills,
|
|
35
|
+
{ includeIntegrationPrimer: true },
|
|
35
36
|
);
|
|
36
37
|
const researcherSection = buildResearcherSection(availableAgents);
|
|
37
38
|
const categorySkillsGuide = buildCategorySkillsDelegationGuide(
|
|
@@ -45,6 +45,7 @@ export function buildToolSelectionTable(
|
|
|
45
45
|
agents: AvailableAgent[],
|
|
46
46
|
tools: AvailableTool[] = [],
|
|
47
47
|
_skills: AvailableSkill[] = [],
|
|
48
|
+
options: { includeIntegrationPrimer?: boolean } = {},
|
|
48
49
|
): string {
|
|
49
50
|
const rows: string[] = ["### Tool & Agent Selection:", ""]
|
|
50
51
|
|
|
@@ -72,10 +73,45 @@ export function buildToolSelectionTable(
|
|
|
72
73
|
rows.push(
|
|
73
74
|
"**Default flow**: researcher (background) + tools → strategist (if required) → critic (high-risk gate)",
|
|
74
75
|
)
|
|
76
|
+
if (options.includeIntegrationPrimer) {
|
|
77
|
+
rows.push("")
|
|
78
|
+
rows.push(buildHiaiIntegrationPrimerSection())
|
|
79
|
+
}
|
|
75
80
|
|
|
76
81
|
return rows.join("\n")
|
|
77
82
|
}
|
|
78
83
|
|
|
84
|
+
export function buildHiaiIntegrationPrimerSection(): string {
|
|
85
|
+
return `<hiai-opencode-integration-primer>
|
|
86
|
+
## hiai-opencode Architecture And Integration Rules
|
|
87
|
+
|
|
88
|
+
This workspace may use hiai-opencode, an OpenCode plugin that wires agents, skills, MCP launchers, LSP, diagnostics, and compatibility helpers around external upstream tools.
|
|
89
|
+
|
|
90
|
+
Core rules:
|
|
91
|
+
- OpenCode plugins are not MCP servers. Keep \`@hiai-gg/hiai-opencode\` and optional \`@tarquinen/opencode-dcp\` in the OpenCode plugin list; never add MCP packages such as \`firecrawl-mcp\`, \`@playwright/mcp\`, or \`@modelcontextprotocol/server-sequential-thinking\` to the plugin list.
|
|
92
|
+
- User-facing config lives in \`hiai-opencode.json\` or \`.opencode/hiai-opencode.json\`: 10 model slots, MCP enable flags, LSP enable flags, service auth placeholders, and skill discovery switches.
|
|
93
|
+
- Model provider credentials are configured through OpenCode Connect. Do not ask for \`OPENROUTER_API_KEY\`, \`OPENAI_API_KEY\`, or \`ANTHROPIC_API_KEY\` for normal model usage.
|
|
94
|
+
- Service keys are separate: \`FIRECRAWL_API_KEY\`, \`STITCH_AI_API_KEY\`, \`CONTEXT7_API_KEY\`, and \`OPENCODE_RAG_URL\` when those services are enabled.
|
|
95
|
+
|
|
96
|
+
MCP usage:
|
|
97
|
+
- Run \`hiai-opencode doctor\` or \`hiai-opencode mcp-status\` for effective runtime MCP status.
|
|
98
|
+
- \`opencode mcp list\` often reads only static \`.mcp.json\`; plugin runtime MCP may work even when that list is empty.
|
|
99
|
+
- The plugin auto-exports \`.mcp.json\` when missing. Run \`hiai-opencode export-mcp .mcp.json\` to refresh static visibility.
|
|
100
|
+
- \`skill_mcp\` can call skill-embedded MCP and enabled hiai-opencode MCP. If an MCP is "not found", check whether the skill was loaded, whether \`hiai-opencode.json\` enables it, and whether static export is needed.
|
|
101
|
+
|
|
102
|
+
Memory and retrieval:
|
|
103
|
+
- MemPalace MCP is external. If enabled, use \`mempalace_status\` first, search before answering about remembered people/projects/past decisions, and write diary entries when appropriate. Never invent memories.
|
|
104
|
+
- RAG MCP is external/local. Use it for project knowledge search when \`OPENCODE_RAG_URL\` is configured or the default \`http://localhost:9002/tools/search\` is reachable.
|
|
105
|
+
- Sequential Thinking MCP is for complex planning/revision/branching, not for trivial edits.
|
|
106
|
+
- Firecrawl/Stitch/Context7 are external web/docs/research services; missing service keys should be reported by env var name only.
|
|
107
|
+
|
|
108
|
+
Installation/debugging:
|
|
109
|
+
- Use \`/doctor\` or \`hiai-opencode doctor\` before changing config.
|
|
110
|
+
- Prefer user-level or project-local installs. Do not use sudo/admin rights unless explicitly requested.
|
|
111
|
+
- If DCP is requested, install it separately with \`opencode plugin @tarquinen/opencode-dcp@latest --global\`.
|
|
112
|
+
</hiai-opencode-integration-primer>`
|
|
113
|
+
}
|
|
114
|
+
|
|
79
115
|
export function buildResearcherSection(agents: AvailableAgent[]): string {
|
|
80
116
|
const researcherAgent = agents.find((agent) => agent.name === "researcher")
|
|
81
117
|
if (!researcherAgent) {
|
package/src/config/defaults.ts
CHANGED
|
@@ -135,7 +135,20 @@ function deriveMcp(config: HiaiOpencodeConfig): HiaiOpencodeConfig["mcp"] {
|
|
|
135
135
|
return Object.fromEntries(
|
|
136
136
|
Object.entries(defaults).map(([name, entry]) => {
|
|
137
137
|
const override = userMcp[name] ?? {}
|
|
138
|
-
|
|
138
|
+
const merged = { ...entry, ...override }
|
|
139
|
+
|
|
140
|
+
if (name === "mempalace" && typeof merged.pythonPath === "string" && merged.pythonPath.trim()) {
|
|
141
|
+
merged.environment = {
|
|
142
|
+
...(entry.environment ?? {}),
|
|
143
|
+
...(merged.environment ?? {}),
|
|
144
|
+
MEMPALACE_PYTHON: merged.pythonPath.trim(),
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Internal launcher hint; do not leak unknown keys into final OpenCode MCP server config.
|
|
149
|
+
delete merged.pythonPath
|
|
150
|
+
|
|
151
|
+
return [name, merged]
|
|
139
152
|
}),
|
|
140
153
|
)
|
|
141
154
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { expect, test } from "bun:test"
|
|
2
|
+
|
|
3
|
+
import { applyModelSlots } from "./defaults"
|
|
4
|
+
import type { HiaiOpencodeConfig } from "./types"
|
|
5
|
+
import { buildStaticMcpJson, MCP_EXPORT_MARKER } from "../shared/mcp-static-export"
|
|
6
|
+
import { buildHiaiIntegrationPrimerSection } from "../agents/dynamic-agent-core-sections"
|
|
7
|
+
|
|
8
|
+
const baseConfig: HiaiOpencodeConfig = {
|
|
9
|
+
models: {
|
|
10
|
+
bob: { model: "openrouter/test/bob", recommended: "xhigh" },
|
|
11
|
+
coder: { model: "openrouter/test/coder", recommended: "high" },
|
|
12
|
+
strategist: { model: "openrouter/test/strategist", recommended: "high" },
|
|
13
|
+
guard: { model: "openrouter/test/guard", recommended: "middle" },
|
|
14
|
+
critic: { model: "openrouter/test/critic", recommended: "high" },
|
|
15
|
+
designer: { model: "openrouter/test/designer", recommended: "design" },
|
|
16
|
+
researcher: { model: "openrouter/test/researcher", recommended: "fast" },
|
|
17
|
+
manager: { model: "openrouter/test/manager", recommended: "fast" },
|
|
18
|
+
brainstormer: { model: "openrouter/test/brainstormer", recommended: "writing" },
|
|
19
|
+
vision: { model: "openrouter/test/vision", recommended: "vision" },
|
|
20
|
+
},
|
|
21
|
+
mcp: {
|
|
22
|
+
mempalace: { enabled: true, pythonPath: "/opt/venv/bin/python" },
|
|
23
|
+
},
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
test("model slots derive canonical agents and categories", () => {
|
|
27
|
+
const resolved = applyModelSlots(baseConfig)
|
|
28
|
+
expect(resolved.agents?.bob?.model).toBe("openrouter/test/bob")
|
|
29
|
+
expect(resolved.agents?.coder?.model).toBe("openrouter/test/coder")
|
|
30
|
+
expect(resolved.agents?.["platform-manager"]?.model).toBe("openrouter/test/manager")
|
|
31
|
+
expect(resolved.agents?.sub?.model).toBe("openrouter/test/coder")
|
|
32
|
+
expect(resolved.categories?.artistry?.model).toBe("openrouter/test/designer")
|
|
33
|
+
expect(resolved.categories?.ultrabrain?.model).toBe("openrouter/test/strategist")
|
|
34
|
+
expect(resolved.categories?.writing?.model).toBe("openrouter/test/brainstormer")
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
test("compact MCP mempalace pythonPath is materialized into environment", () => {
|
|
38
|
+
const resolved = applyModelSlots(baseConfig)
|
|
39
|
+
expect(resolved.mcp?.mempalace?.environment?.MEMPALACE_PYTHON).toBe("/opt/venv/bin/python")
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
test("static MCP export includes marker metadata and servers", () => {
|
|
43
|
+
const resolved = applyModelSlots(baseConfig)
|
|
44
|
+
const exported = buildStaticMcpJson(resolved)
|
|
45
|
+
|
|
46
|
+
expect(exported._meta?.generatedBy).toBe(MCP_EXPORT_MARKER)
|
|
47
|
+
expect(exported._meta?.version).toBe(1)
|
|
48
|
+
expect(exported.mcpServers.playwright).toBeDefined()
|
|
49
|
+
expect(exported.mcpServers.mempalace).toBeDefined()
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
test("integration primer does not request model provider API keys", () => {
|
|
53
|
+
const primer = buildHiaiIntegrationPrimerSection()
|
|
54
|
+
expect(primer).toContain("Do not ask for `OPENROUTER_API_KEY`, `OPENAI_API_KEY`, or `ANTHROPIC_API_KEY`")
|
|
55
|
+
})
|
|
@@ -76,6 +76,7 @@ export const McpServerConfigSchema = z.object({
|
|
|
76
76
|
command: z.array(z.string()).optional(),
|
|
77
77
|
timeout: z.number().optional(),
|
|
78
78
|
environment: z.record(z.string(), z.string()).optional(),
|
|
79
|
+
pythonPath: z.string().optional(),
|
|
79
80
|
});
|
|
80
81
|
|
|
81
82
|
export const LspServerConfigSchema = z.object({
|
|
@@ -129,9 +130,6 @@ export const PermissionsConfigSchema = z.object({
|
|
|
129
130
|
});
|
|
130
131
|
|
|
131
132
|
export const AuthKeysSchema = z.object({
|
|
132
|
-
googleSearch: z.string().optional(),
|
|
133
|
-
openai: z.string().optional(),
|
|
134
|
-
openrouter: z.string().optional(),
|
|
135
133
|
stitch: z.string().optional(),
|
|
136
134
|
firecrawl: z.string().optional(),
|
|
137
135
|
context7: z.string().optional(),
|
|
@@ -26,9 +26,6 @@ import { FastApplyConfigSchema } from "./fast-apply"
|
|
|
26
26
|
import { WebsearchConfigSchema } from "./websearch"
|
|
27
27
|
|
|
28
28
|
const AuthConfigSchema = z.object({
|
|
29
|
-
googleSearch: z.string().optional(),
|
|
30
|
-
openai: z.string().optional(),
|
|
31
|
-
openrouter: z.string().optional(),
|
|
32
29
|
stitch: z.string().optional(),
|
|
33
30
|
firecrawl: z.string().optional(),
|
|
34
31
|
context7: z.string().optional(),
|
package/src/config/types.ts
CHANGED
|
@@ -150,6 +150,7 @@ export interface McpServerConfig {
|
|
|
150
150
|
command?: string[];
|
|
151
151
|
timeout?: number;
|
|
152
152
|
environment?: Record<string, string>;
|
|
153
|
+
pythonPath?: string;
|
|
153
154
|
}
|
|
154
155
|
|
|
155
156
|
export interface LspServerConfig {
|
|
@@ -187,9 +188,6 @@ export interface PermissionsConfig {
|
|
|
187
188
|
}
|
|
188
189
|
|
|
189
190
|
export interface AuthKeys {
|
|
190
|
-
googleSearch?: string;
|
|
191
|
-
openai?: string;
|
|
192
|
-
openrouter?: string;
|
|
193
191
|
stitch?: string;
|
|
194
192
|
firecrawl?: string;
|
|
195
193
|
context7?: string;
|
|
@@ -9,6 +9,7 @@ import { START_WORK_TEMPLATE } from "./templates/start-work"
|
|
|
9
9
|
import { HANDOFF_TEMPLATE } from "./templates/handoff"
|
|
10
10
|
import { REMOVE_AI_SLOPS_TEMPLATE } from "./templates/remove-ai-slops"
|
|
11
11
|
import { MCP_STATUS_TEMPLATE } from "./templates/mcp-status"
|
|
12
|
+
import { DOCTOR_TEMPLATE } from "./templates/doctor"
|
|
12
13
|
|
|
13
14
|
interface LoadBuiltinCommandsOptions {
|
|
14
15
|
useRegisteredAgents?: boolean
|
|
@@ -126,6 +127,12 @@ $ARGUMENTS
|
|
|
126
127
|
description: "(builtin) Show hiai-opencode MCP server status, missing keys, and local runtime availability",
|
|
127
128
|
template: `<command-instruction>
|
|
128
129
|
${MCP_STATUS_TEMPLATE}
|
|
130
|
+
</command-instruction>`,
|
|
131
|
+
},
|
|
132
|
+
doctor: {
|
|
133
|
+
description: "(builtin) Run hiai-opencode install/runtime diagnostics and explain setup issues",
|
|
134
|
+
template: `<command-instruction>
|
|
135
|
+
${DOCTOR_TEMPLATE}
|
|
129
136
|
</command-instruction>`,
|
|
130
137
|
},
|
|
131
138
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export const DOCTOR_TEMPLATE = `# Hiai OpenCode Doctor Command
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Use /doctor to run the hiai-opencode install/runtime diagnostic and report actionable setup issues.
|
|
6
|
+
|
|
7
|
+
## Execute
|
|
8
|
+
|
|
9
|
+
Run:
|
|
10
|
+
|
|
11
|
+
\`\`\`bash
|
|
12
|
+
hiai-opencode doctor
|
|
13
|
+
\`\`\`
|
|
14
|
+
|
|
15
|
+
If the binary is not on PATH, try the package-local fallback:
|
|
16
|
+
|
|
17
|
+
\`\`\`bash
|
|
18
|
+
node ./node_modules/@hiai-gg/hiai-opencode/assets/cli/hiai-opencode.mjs doctor
|
|
19
|
+
\`\`\`
|
|
20
|
+
|
|
21
|
+
## Report
|
|
22
|
+
|
|
23
|
+
Summarize:
|
|
24
|
+
|
|
25
|
+
- config path
|
|
26
|
+
- enabled and disabled MCP servers
|
|
27
|
+
- missing env vars by name only
|
|
28
|
+
- static \`.mcp.json\` freshness and whether it is managed by hiai-opencode
|
|
29
|
+
- OpenCode Connect visibility for configured model providers
|
|
30
|
+
- OpenCode plugin registration sanity (including \`plugin: ["list"]\` misconfiguration warning)
|
|
31
|
+
- skill materialization status from skill registry
|
|
32
|
+
- agent count and naming summary
|
|
33
|
+
- LSP runtime availability
|
|
34
|
+
- MemPalace python source and selected interpreter (env/config/auto)
|
|
35
|
+
- MCP tool probes (real connect + tools/list) for stdio and basic endpoint probes for remote MCP
|
|
36
|
+
|
|
37
|
+
Rules:
|
|
38
|
+
|
|
39
|
+
- Do not print API key values.
|
|
40
|
+
- Do not ask for model provider env vars such as OPENROUTER_API_KEY or OPENAI_API_KEY; normal model auth belongs to OpenCode Connect.
|
|
41
|
+
- If \`opencode mcp list\` is empty but doctor/mcp-status sees servers, explain the runtime-vs-static config distinction and run \`hiai-opencode export-mcp .mcp.json\` if the user wants static visibility.
|
|
42
|
+
- Do not run package installs unless the user explicitly asks.
|
|
43
|
+
`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CommandDefinition } from "../claude-code-command-loader"
|
|
2
2
|
|
|
3
|
-
export type BuiltinCommandName = "init-deep" | "ralph-loop" | "cancel-ralph" | "ulw-loop" | "refactor" | "start-work" | "stop-continuation" | "handoff" | "remove-ai-slops" | "mcp-status"
|
|
3
|
+
export type BuiltinCommandName = "init-deep" | "ralph-loop" | "cancel-ralph" | "ulw-loop" | "refactor" | "start-work" | "stop-continuation" | "handoff" | "remove-ai-slops" | "mcp-status" | "doctor"
|
|
4
4
|
|
|
5
5
|
export interface BuiltinCommandConfig {
|
|
6
6
|
disabled_commands?: BuiltinCommandName[]
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { BuiltinSkill } from "../types"
|
|
2
|
+
|
|
3
|
+
export const hiaiOpencodeSetupSkill: BuiltinSkill = {
|
|
4
|
+
name: "hiai-opencode-setup",
|
|
5
|
+
description:
|
|
6
|
+
"Use when install/setup/onboarding or MCP debug mentions: install, setup, bootstrap, doctor, mcp-status, MCP not found, mcp list empty, MemPalace, RAG, firecrawl, stitch, sequential-thinking, playwright, DCP, agents, skills, or LSP.",
|
|
7
|
+
template: `# hiai-opencode Setup And Runtime Operations
|
|
8
|
+
|
|
9
|
+
Use this skill for hiai-opencode installation, diagnostics, and integration repair.
|
|
10
|
+
|
|
11
|
+
## Architecture
|
|
12
|
+
|
|
13
|
+
- hiai-opencode is an OpenCode plugin, not a standalone app.
|
|
14
|
+
- MCP servers are external upstream tools launched by hiai-opencode wiring.
|
|
15
|
+
- The user-facing config is \`hiai-opencode.json\` or \`.opencode/hiai-opencode.json\`.
|
|
16
|
+
- Model provider credentials belong to OpenCode Connect. Do not ask for \`OPENROUTER_API_KEY\`, \`OPENAI_API_KEY\`, or \`ANTHROPIC_API_KEY\` for normal model usage.
|
|
17
|
+
- Service credentials are separate: \`FIRECRAWL_API_KEY\`, \`STITCH_AI_API_KEY\`, \`CONTEXT7_API_KEY\`.
|
|
18
|
+
|
|
19
|
+
## First Diagnostic Commands
|
|
20
|
+
|
|
21
|
+
\`\`\`bash
|
|
22
|
+
hiai-opencode doctor
|
|
23
|
+
hiai-opencode mcp-status
|
|
24
|
+
opencode debug config
|
|
25
|
+
\`\`\`
|
|
26
|
+
|
|
27
|
+
If \`opencode mcp list\` is empty but doctor/mcp-status sees servers, explain that OpenCode's list may read only static \`.mcp.json\`. Refresh static visibility:
|
|
28
|
+
|
|
29
|
+
\`\`\`bash
|
|
30
|
+
hiai-opencode export-mcp .mcp.json
|
|
31
|
+
opencode mcp list --print-logs --log-level INFO
|
|
32
|
+
\`\`\`
|
|
33
|
+
|
|
34
|
+
## Plugin vs MCP
|
|
35
|
+
|
|
36
|
+
Install OpenCode plugins with:
|
|
37
|
+
|
|
38
|
+
\`\`\`bash
|
|
39
|
+
opencode plugin @hiai-gg/hiai-opencode@latest --global
|
|
40
|
+
opencode plugin @tarquinen/opencode-dcp@latest --global
|
|
41
|
+
\`\`\`
|
|
42
|
+
|
|
43
|
+
Do not add MCP packages to the OpenCode plugin array. MCP packages are launched through \`hiai-opencode.json\` and helper scripts.
|
|
44
|
+
|
|
45
|
+
## MCP Runtime Notes
|
|
46
|
+
|
|
47
|
+
- \`playwright\`: node/npx; browser binaries may need \`HIAI_PLAYWRIGHT_INSTALL_BROWSERS=1\`; Linux system deps may require admin rights.
|
|
48
|
+
- \`sequential-thinking\`: node/npx; use for complex planning, revision, and branching.
|
|
49
|
+
- \`firecrawl\`: requires \`FIRECRAWL_API_KEY\`.
|
|
50
|
+
- \`mempalace\`: prefers \`uv\`; otherwise Python 3.9+ with \`mempalace\`. Use \`mempalace_status\` first, search before answering memory questions, and never invent memories.
|
|
51
|
+
- \`rag\`: requires \`OPENCODE_RAG_URL\` or a reachable default \`http://localhost:9002/tools/search\`.
|
|
52
|
+
- \`stitch\`: requires \`STITCH_AI_API_KEY\`.
|
|
53
|
+
- \`context7\`: remote docs/search; key optional but recommended for limits.
|
|
54
|
+
|
|
55
|
+
## Calling MCP
|
|
56
|
+
|
|
57
|
+
- Use native MCP tools if OpenCode exposes them.
|
|
58
|
+
- Use \`skill_mcp\` for skill-embedded MCP or enabled hiai-opencode MCP.
|
|
59
|
+
- If \`skill_mcp\` says a server is not found, check whether the skill is loaded, whether the MCP is enabled in \`hiai-opencode.json\`, and whether \`.mcp.json\` needs export.
|
|
60
|
+
|
|
61
|
+
## Safety Rules
|
|
62
|
+
|
|
63
|
+
- Report missing keys by env var name only. Never print key values.
|
|
64
|
+
- Prefer project-local or user-level installs. Do not use sudo/admin rights unless the user explicitly asks.
|
|
65
|
+
- Do not edit unrelated OpenCode/Claude/Agents global skill folders unless the user opts in.
|
|
66
|
+
- Keep DCP separate: it is an optional OpenCode plugin, not part of the hiai-opencode package.
|
|
67
|
+
`,
|
|
68
|
+
allowedTools: ["Bash(*)", "Read(*)", "Edit(*)", "Glob(*)", "Grep(*)", "skill_mcp(*)"],
|
|
69
|
+
}
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
devBrowserSkill,
|
|
11
11
|
reviewWorkSkill,
|
|
12
12
|
aiSlopRemoverSkill,
|
|
13
|
+
hiaiOpencodeSetupSkill,
|
|
13
14
|
} from "./skills/index"
|
|
14
15
|
|
|
15
16
|
export interface CreateBuiltinSkillsOptions {
|
|
@@ -29,7 +30,15 @@ export function createBuiltinSkills(options: CreateBuiltinSkillsOptions = {}): B
|
|
|
29
30
|
browserSkill = playwrightSkill
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
const skills = [
|
|
33
|
+
const skills = [
|
|
34
|
+
browserSkill,
|
|
35
|
+
hiaiOpencodeSetupSkill,
|
|
36
|
+
frontendUiUxSkill,
|
|
37
|
+
gitMasterSkill,
|
|
38
|
+
devBrowserSkill,
|
|
39
|
+
reviewWorkSkill,
|
|
40
|
+
aiSlopRemoverSkill,
|
|
41
|
+
]
|
|
33
42
|
|
|
34
43
|
if (!disabledSkills) {
|
|
35
44
|
return skills
|