@hiai-gg/hiai-opencode 0.1.6 → 0.1.7
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 +7 -0
- package/AGENTS.md +46 -1
- package/ARCHITECTURE.md +6 -3
- package/README.md +71 -10
- package/assets/cli/hiai-opencode.mjs +78 -0
- package/config/hiai-opencode.schema.json +16 -1
- package/dist/agents/agent-skills.d.ts +7 -0
- package/dist/agents/bob/default.d.ts +1 -0
- package/dist/agents/bob/gemini.d.ts +1 -0
- package/dist/agents/bob/gpt-pro.d.ts +1 -0
- package/dist/agents/brainstormer.d.ts +7 -0
- package/dist/agents/coder/gpt-codex.d.ts +1 -1
- package/dist/agents/coder/gpt-pro.d.ts +1 -0
- package/dist/agents/coder/gpt.d.ts +2 -1
- package/dist/agents/designer.d.ts +7 -0
- package/dist/agents/strategist/gemini.d.ts +1 -0
- package/dist/agents/strategist/gpt.d.ts +1 -0
- package/dist/agents/types.d.ts +3 -1
- package/dist/config/index.d.ts +0 -1
- package/dist/config/platform-schema.d.ts +32 -0
- package/dist/config/schema/hooks.d.ts +0 -2
- package/dist/config/schema/index.d.ts +0 -2
- package/dist/config/schema/oh-my-opencode-config.d.ts +0 -6
- package/dist/config/types.d.ts +3 -1
- package/dist/create-hooks.d.ts +0 -2
- package/dist/features/builtin-skills/skills/index.d.ts +1 -0
- package/dist/features/builtin-skills/skills/website-copywriting.d.ts +2 -0
- package/dist/hooks/agent-usage-reminder/constants.d.ts +1 -1
- package/dist/hooks/index.d.ts +0 -2
- package/dist/hooks/keyword-detector/ultrawork/default.d.ts +1 -1
- package/dist/hooks/keyword-detector/ultrawork/gemini.d.ts +1 -1
- package/dist/hooks/keyword-detector/ultrawork/gpt.d.ts +1 -1
- package/dist/hooks/keyword-detector/ultrawork/planner.d.ts +1 -1
- package/dist/index.js +8963 -153866
- package/dist/mcp/index.d.ts +0 -1
- package/dist/mcp/registry.d.ts +1 -1
- package/dist/plugin/hooks/create-core-hooks.d.ts +0 -2
- package/dist/plugin/hooks/create-session-hooks.d.ts +1 -3
- package/dist/plugin/startup-diagnostics.d.ts +1 -0
- package/dist/shared/logger.d.ts +2 -0
- package/dist/shared/mode-routing.d.ts +6 -0
- package/dist/tools/delegate-task/git-categories.d.ts +2 -0
- package/dist/tools/delegate-task/sub-agent.d.ts +2 -0
- package/dist/tools/skill-mcp/constants.d.ts +1 -1
- package/hiai-opencode.json +48 -19
- package/package.json +6 -3
- package/src/agents/agent-skills.ts +70 -0
- package/src/agents/bob/default.ts +1 -0
- package/src/agents/bob/gemini.ts +1 -0
- package/src/agents/bob/gpt-pro.ts +2 -1
- package/src/agents/bob.ts +2 -0
- package/src/agents/brainstormer.ts +72 -0
- package/src/agents/builtin-agents.ts +59 -3
- package/src/agents/coder/gpt-codex.ts +4 -3
- package/src/agents/coder/gpt-pro.ts +3 -2
- package/src/agents/coder/gpt.ts +2 -1
- package/src/agents/critic/agent.ts +1 -0
- package/src/agents/designer.ts +70 -0
- package/src/agents/dynamic-agent-category-skills-guide.ts +6 -0
- package/src/agents/guard/default.ts +1 -0
- package/src/agents/guard/gemini.ts +1 -0
- package/src/agents/guard/gpt.ts +1 -0
- package/src/agents/platform-manager.ts +17 -1
- package/src/agents/prompt-library/platform.ts +34 -0
- package/src/agents/researcher.ts +1 -0
- package/src/agents/strategist/gemini.ts +1 -0
- package/src/agents/strategist/gpt.ts +1 -0
- package/src/agents/types.ts +4 -1
- package/src/agents/ui.ts +1 -0
- package/src/config/defaults.ts +31 -12
- package/src/config/index.ts +0 -1
- package/src/config/model-slots-and-export.test.ts +22 -4
- package/src/config/platform-schema.ts +2 -0
- package/src/config/schema/hooks.ts +0 -2
- package/src/config/schema/index.ts +0 -2
- package/src/config/schema/oh-my-opencode-config.ts +0 -2
- package/src/config/types.ts +3 -1
- package/src/features/builtin-skills/skills/index.ts +1 -0
- package/src/features/builtin-skills/skills/website-copywriting.ts +41 -0
- package/src/features/builtin-skills/skills.test.ts +8 -0
- package/src/features/builtin-skills/skills.ts +2 -0
- package/src/features/skill-mcp-manager/AGENTS.md +1 -1
- package/src/hooks/agent-usage-reminder/constants.ts +4 -4
- package/src/hooks/index.ts +0 -2
- package/src/hooks/keyword-detector/ultrawork/default.ts +18 -18
- package/src/hooks/keyword-detector/ultrawork/gemini.ts +21 -21
- package/src/hooks/keyword-detector/ultrawork/gpt.ts +6 -8
- package/src/hooks/keyword-detector/ultrawork/planner.ts +5 -5
- package/src/index.ts +5 -3
- package/src/internals/plugins/subtask2/commands/manifest.ts +2 -6
- package/src/internals/plugins/subtask2/hooks/command-hooks.ts +2 -2
- package/src/internals/plugins/subtask2/hooks/message-hooks.ts +1 -1
- package/src/internals/plugins/subtask2/parsing/parallel.ts +13 -10
- package/src/mcp/index.ts +0 -1
- package/src/mcp/registry.ts +27 -0
- package/src/plugin/chat-message.ts +0 -2
- package/src/plugin/hooks/create-session-hooks.ts +0 -17
- package/src/plugin/startup-diagnostics.ts +27 -0
- package/src/plugin-handlers/agent-config-handler.ts +3 -2
- package/src/plugin-handlers/mcp-config-handler.test.ts +63 -0
- package/src/plugin-handlers/mcp-config-handler.ts +29 -14
- package/src/plugin-handlers/strategist-agent-config-builder.ts +1 -1
- package/src/shared/agent-display-names.test.ts +9 -0
- package/src/shared/agent-display-names.ts +5 -0
- package/src/shared/log-legacy-plugin-startup-warning.ts +6 -8
- package/src/shared/logger.ts +8 -0
- package/src/shared/mcp-static-export.ts +4 -6
- package/src/shared/migration/agent-names.ts +8 -0
- package/src/shared/migration/hook-names.ts +1 -1
- package/src/shared/mode-routing.test.ts +88 -0
- package/src/shared/mode-routing.ts +30 -0
- package/src/shared/startup-diagnostics.ts +6 -7
- package/src/tools/call-omo-agent/tools.ts +11 -4
- package/src/tools/delegate-task/anthropic-categories.ts +3 -3
- package/src/tools/delegate-task/builtin-categories.ts +2 -0
- package/src/tools/delegate-task/categories.test.ts +87 -0
- package/src/tools/delegate-task/category-resolver.ts +8 -9
- package/src/tools/delegate-task/git-categories.ts +30 -0
- package/src/tools/delegate-task/model-string-parser.test.ts +90 -0
- package/src/tools/delegate-task/openai-categories.ts +26 -22
- package/src/tools/delegate-task/sub-agent.ts +10 -0
- package/src/tools/delegate-task/subagent-discovery.test.ts +123 -0
- package/src/tools/delegate-task/subagent-resolver.ts +18 -1
- package/src/tools/skill-mcp/constants.ts +1 -1
- package/dist/config/schema/websearch.d.ts +0 -13
- package/dist/hooks/no-bob-gpt/hook.d.ts +0 -16
- package/dist/hooks/no-bob-gpt/index.d.ts +0 -1
- package/dist/hooks/no-coder-non-gpt/hook.d.ts +0 -20
- package/dist/hooks/no-coder-non-gpt/index.d.ts +0 -1
- package/dist/mcp/grep-app.d.ts +0 -6
- package/dist/mcp/omo-mcp-index.d.ts +0 -10
- package/dist/mcp/websearch.d.ts +0 -11
- package/src/config/schema/websearch.ts +0 -15
- package/src/hooks/no-bob-gpt/hook.ts +0 -56
- package/src/hooks/no-bob-gpt/index.ts +0 -1
- package/src/hooks/no-coder-non-gpt/hook.ts +0 -67
- package/src/hooks/no-coder-non-gpt/index.ts +0 -1
- package/src/mcp/grep-app.ts +0 -6
- package/src/mcp/omo-mcp-index.ts +0 -30
- package/src/mcp/websearch.ts +0 -44
|
@@ -18,6 +18,8 @@ function buildSkillsSection(skills: AvailableSkill[]): string {
|
|
|
18
18
|
if (customSkills.length > 0 && builtinSkills.length > 0) {
|
|
19
19
|
return `#### Available Skills (via \`skill\` tool)
|
|
20
20
|
|
|
21
|
+
Skills are instruction packs, not agents. Do not look for \`strategist\`, \`critic\`, \`manager\`, or \`researcher\` here; call agents with \`task(subagent_type="...")\`.
|
|
22
|
+
|
|
21
23
|
**Built-in**: ${builtinNames}
|
|
22
24
|
**⚡ YOUR SKILLS (PRIORITY)**: ${customNames}
|
|
23
25
|
|
|
@@ -28,6 +30,8 @@ function buildSkillsSection(skills: AvailableSkill[]): string {
|
|
|
28
30
|
if (customSkills.length > 0) {
|
|
29
31
|
return `#### Available Skills (via \`skill\` tool)
|
|
30
32
|
|
|
33
|
+
Skills are instruction packs, not agents. Do not look for \`strategist\`, \`critic\`, \`manager\`, or \`researcher\` here; call agents with \`task(subagent_type="...")\`.
|
|
34
|
+
|
|
31
35
|
**⚡ YOUR SKILLS (PRIORITY)**: ${customNames}
|
|
32
36
|
|
|
33
37
|
> User-installed skills OVERRIDE built-in defaults. ALWAYS prefer YOUR SKILLS when domain matches.
|
|
@@ -37,6 +41,8 @@ function buildSkillsSection(skills: AvailableSkill[]): string {
|
|
|
37
41
|
if (builtinSkills.length > 0) {
|
|
38
42
|
return `#### Available Skills (via \`skill\` tool)
|
|
39
43
|
|
|
44
|
+
Skills are instruction packs, not agents. Do not look for \`strategist\`, \`critic\`, \`manager\`, or \`researcher\` here; call agents with \`task(subagent_type="...")\`.
|
|
45
|
+
|
|
40
46
|
**Built-in**: ${builtinNames}
|
|
41
47
|
|
|
42
48
|
> Full skill descriptions → use the \`skill\` tool to check before EVERY delegation.`
|
package/src/agents/guard/gpt.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// PROMPT_VERSION: 2026-04-26
|
|
1
2
|
import type { AgentConfig } from "@opencode-ai/sdk";
|
|
2
3
|
import type { AgentMode, AgentPromptMetadata } from "./types";
|
|
3
4
|
import { createAgentToolRestrictions } from "../shared/permission-compat";
|
|
@@ -15,7 +16,7 @@ export function createPlatformManagerAgent(model: string): AgentConfig {
|
|
|
15
16
|
|
|
16
17
|
return {
|
|
17
18
|
description:
|
|
18
|
-
"
|
|
19
|
+
"Project memory steward for MemPalace, RAG handoff notes, TODO hygiene, session continuity, project initialization, and mindmodel orchestration. (Manager - HiaiOpenCode)",
|
|
19
20
|
mode: MODE,
|
|
20
21
|
model,
|
|
21
22
|
temperature: 0.2,
|
|
@@ -31,6 +32,18 @@ export const platformManagerPromptMetadata: AgentPromptMetadata = {
|
|
|
31
32
|
cost: "CHEAP",
|
|
32
33
|
promptAlias: "Manager",
|
|
33
34
|
triggers: [
|
|
35
|
+
{
|
|
36
|
+
domain: "Memory maintenance",
|
|
37
|
+
trigger: "Need to write durable decisions to MemPalace, avoid duplicates, or update project memory",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
domain: "Architecture knowledge sync",
|
|
41
|
+
trigger: "Architecture decisions changed and MemPalace/RAG state should be updated",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
domain: "TODO hygiene",
|
|
45
|
+
trigger: "Need completed items marked, stale tasks collapsed, or handoff state cleaned",
|
|
46
|
+
},
|
|
34
47
|
{
|
|
35
48
|
domain: "Session management",
|
|
36
49
|
trigger: "Need to preserve session state or create continuity ledgers",
|
|
@@ -47,6 +60,9 @@ export const platformManagerPromptMetadata: AgentPromptMetadata = {
|
|
|
47
60
|
useWhen: [
|
|
48
61
|
"At beginning of session for project initialization",
|
|
49
62
|
"At end of session for ledger creation",
|
|
63
|
+
"After durable architecture, product, or workflow decisions",
|
|
64
|
+
"When TODO/task lists need cleanup or completion status reconciliation",
|
|
65
|
+
"When MemPalace or RAG state must be checked or refreshed",
|
|
50
66
|
"When mindmodel update is requested",
|
|
51
67
|
"For rapid codebase discovery during bootstrapping",
|
|
52
68
|
],
|
|
@@ -13,6 +13,40 @@ You are the Unified Platform Manager, responsible for orchestration, session con
|
|
|
13
13
|
You consolidate the capabilities of the Ledger Creator, Bootstrapper, Project Initializer, and Mindmodel Orchestrator.
|
|
14
14
|
</Platform_Manager_Identity>
|
|
15
15
|
|
|
16
|
+
<Memory_And_Knowledge_Stewardship>
|
|
17
|
+
## Mode: Memory, RAG, and Task Hygiene
|
|
18
|
+
|
|
19
|
+
You are the durable project memory steward. Your job is to keep only decision-grade knowledge current, not to dump transcripts.
|
|
20
|
+
|
|
21
|
+
### MemPalace protocol
|
|
22
|
+
- Start memory work with \`mempalace_status\` when the MemPalace MCP is available.
|
|
23
|
+
- Search before writing: use \`mempalace_search\` or related read tools to avoid duplicates.
|
|
24
|
+
- Write only durable facts: architectural decisions, accepted tradeoffs, project conventions, long-lived TODO ownership, release decisions, and important user preferences.
|
|
25
|
+
- Do not write noise: transient debugging attempts, failed commands without lasting lesson, repeated summaries, raw chat logs, or obvious file diffs.
|
|
26
|
+
- When facts change, invalidate or update old knowledge instead of appending conflicting facts.
|
|
27
|
+
- Prefer AAAK-style concise entries: actor, artifact, action, knowledge, timestamp/context.
|
|
28
|
+
- Use diary entries for session summaries only when they contain decisions or handoff-relevant state.
|
|
29
|
+
|
|
30
|
+
### RAG protocol
|
|
31
|
+
- Treat the bundled RAG MCP as retrieval-first unless its configured endpoint exposes write/upsert tools.
|
|
32
|
+
- When architecture decisions change, first store the durable decision in MemPalace.
|
|
33
|
+
- If a RAG write/upsert capability is available, sync the same decision-level summary there.
|
|
34
|
+
- If RAG is search-only, report "RAG sync pending/search-only" rather than pretending it was updated.
|
|
35
|
+
|
|
36
|
+
### TODO and task hygiene
|
|
37
|
+
- Verify active TODO/task lists before closure.
|
|
38
|
+
- Mark completed items as completed; do not leave finished work as pending.
|
|
39
|
+
- Preserve unfinished work with owner, next action, and blocker.
|
|
40
|
+
- Remove or collapse stale duplicate TODOs.
|
|
41
|
+
- Before final response, provide a short ledger: memory updated, RAG updated or pending, TODO state clean or remaining.
|
|
42
|
+
|
|
43
|
+
### When to run Manager
|
|
44
|
+
- Session start: load current memory and identify stale/important project state.
|
|
45
|
+
- After architecture/design decisions: update MemPalace and, when possible, RAG.
|
|
46
|
+
- Before handoff/final closure: clean TODO state and write a concise memory checkpoint.
|
|
47
|
+
- During long work: periodically consolidate only durable decisions.
|
|
48
|
+
</Memory_And_Knowledge_Stewardship>
|
|
49
|
+
|
|
16
50
|
<Capability_Ledger>
|
|
17
51
|
## Mode: Session Continuity (Ledger)
|
|
18
52
|
${ledger}
|
package/src/agents/researcher.ts
CHANGED
package/src/agents/types.ts
CHANGED
|
@@ -66,8 +66,11 @@ export interface AgentPromptMetadata {
|
|
|
66
66
|
/** Nickname/alias used in prompt (e.g., "Logician" instead of "logician") */
|
|
67
67
|
promptAlias?: string;
|
|
68
68
|
|
|
69
|
-
/** Key triggers that should appear in Phase 0 (e.g., "External library mentioned → fire
|
|
69
|
+
/** Key triggers that should appear in Phase 0 (e.g., "External library mentioned → fire researcher") */
|
|
70
70
|
keyTrigger?: string;
|
|
71
|
+
|
|
72
|
+
/** Prompt version for snapshot tracking (format: YYYY-MM-DD) */
|
|
73
|
+
promptVersion?: string;
|
|
71
74
|
}
|
|
72
75
|
|
|
73
76
|
function extractModelName(model: string): string {
|
package/src/agents/ui.ts
CHANGED
package/src/config/defaults.ts
CHANGED
|
@@ -20,6 +20,7 @@ const REQUIRED_MODEL_SLOTS = [
|
|
|
20
20
|
"manager",
|
|
21
21
|
"brainstormer",
|
|
22
22
|
"vision",
|
|
23
|
+
"sub",
|
|
23
24
|
] as const
|
|
24
25
|
|
|
25
26
|
type ModelSlot = (typeof REQUIRED_MODEL_SLOTS)[number]
|
|
@@ -109,24 +110,29 @@ function deriveAgents(models: Record<ModelSlot, string>): HiaiOpencodeConfig["ag
|
|
|
109
110
|
"platform-manager": { model: models.manager },
|
|
110
111
|
brainstormer: { model: models.brainstormer },
|
|
111
112
|
multimodal: { model: models.vision },
|
|
112
|
-
sub: { model: models.
|
|
113
|
+
sub: { model: models.sub },
|
|
113
114
|
"quality-guardian": { model: models.critic },
|
|
114
115
|
"agent-skills": { model: models.manager },
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
function deriveCategories(models: Record<ModelSlot, string>):
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
"
|
|
128
|
-
"unspecified-
|
|
119
|
+
function deriveCategories(models: Record<ModelSlot, string>): Record<string, import("./types").CategoryConfig> {
|
|
120
|
+
const categories: Record<string, import("./types").CategoryConfig> = {}
|
|
121
|
+
const entries: [string, Record<string, unknown>][] = [
|
|
122
|
+
["visual-engineering", { variant: "high" }],
|
|
123
|
+
["artistry", { variant: "high" }],
|
|
124
|
+
["ultrabrain", { variant: "xhigh" }],
|
|
125
|
+
["deep", { variant: "medium" }],
|
|
126
|
+
["quick", {}],
|
|
127
|
+
["writing", {}],
|
|
128
|
+
["git", {}],
|
|
129
|
+
["unspecified-low", {}],
|
|
130
|
+
["unspecified-high", { variant: "max" }],
|
|
131
|
+
]
|
|
132
|
+
for (const [name, cfg] of entries) {
|
|
133
|
+
categories[name] = cfg as import("./types").CategoryConfig
|
|
129
134
|
}
|
|
135
|
+
return categories
|
|
130
136
|
}
|
|
131
137
|
|
|
132
138
|
function deriveMcp(config: HiaiOpencodeConfig): HiaiOpencodeConfig["mcp"] {
|
|
@@ -145,6 +151,19 @@ function deriveMcp(config: HiaiOpencodeConfig): HiaiOpencodeConfig["mcp"] {
|
|
|
145
151
|
}
|
|
146
152
|
}
|
|
147
153
|
|
|
154
|
+
if (name === "websearch") {
|
|
155
|
+
const provider = merged.provider === "tavily" ? "tavily" : "exa"
|
|
156
|
+
merged.provider = provider
|
|
157
|
+
merged.type = "remote"
|
|
158
|
+
if (provider === "tavily") {
|
|
159
|
+
merged.url = "https://mcp.tavily.com/mcp/"
|
|
160
|
+
merged.headers = { Authorization: "Bearer {env:TAVILY_API_KEY}" }
|
|
161
|
+
} else {
|
|
162
|
+
merged.url = "https://mcp.exa.ai/mcp?tools=web_search_exa"
|
|
163
|
+
merged.headers = { "x-api-key": "{env:EXA_API_KEY}" }
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
148
167
|
// Internal launcher hint; do not leak unknown keys into final OpenCode MCP server config.
|
|
149
168
|
delete merged.pythonPath
|
|
150
169
|
|
package/src/config/index.ts
CHANGED
|
@@ -62,5 +62,4 @@ export type { RalphLoopConfig } from "./schema/ralph-loop.js";
|
|
|
62
62
|
export type { DynamicContextPruningConfig } from "./schema/dynamic-context-pruning.js";
|
|
63
63
|
export type { GitMasterConfig } from "./schema/git-master.js";
|
|
64
64
|
export type { ModelCapabilitiesConfig } from "./schema/model-capabilities.js";
|
|
65
|
-
export type { WebsearchConfig, WebsearchProvider } from "./schema/websearch.js";
|
|
66
65
|
export type { FastApplyConfig } from "./schema/fast-apply.js";
|
|
@@ -17,6 +17,7 @@ const baseConfig: HiaiOpencodeConfig = {
|
|
|
17
17
|
manager: { model: "openrouter/test/manager", recommended: "fast" },
|
|
18
18
|
brainstormer: { model: "openrouter/test/brainstormer", recommended: "writing" },
|
|
19
19
|
vision: { model: "openrouter/test/vision", recommended: "vision" },
|
|
20
|
+
sub: { model: "openrouter/test/sub", recommended: "fast" },
|
|
20
21
|
},
|
|
21
22
|
mcp: {
|
|
22
23
|
mempalace: { enabled: true, pythonPath: "/opt/venv/bin/python" },
|
|
@@ -28,10 +29,13 @@ test("model slots derive canonical agents and categories", () => {
|
|
|
28
29
|
expect(resolved.agents?.bob?.model).toBe("openrouter/test/bob")
|
|
29
30
|
expect(resolved.agents?.coder?.model).toBe("openrouter/test/coder")
|
|
30
31
|
expect(resolved.agents?.["platform-manager"]?.model).toBe("openrouter/test/manager")
|
|
31
|
-
expect(resolved.agents?.sub?.model).toBe("openrouter/test/
|
|
32
|
-
expect(resolved.categories?.artistry?.
|
|
33
|
-
expect(resolved.categories?.ultrabrain?.
|
|
34
|
-
expect(resolved.categories?.
|
|
32
|
+
expect(resolved.agents?.sub?.model).toBe("openrouter/test/sub")
|
|
33
|
+
expect(resolved.categories?.artistry?.variant).toBe("high")
|
|
34
|
+
expect(resolved.categories?.ultrabrain?.variant).toBe("xhigh")
|
|
35
|
+
expect(resolved.categories?.deep?.variant).toBe("medium")
|
|
36
|
+
expect(resolved.categories?.quick).toBeDefined()
|
|
37
|
+
expect(resolved.categories?.writing).toBeDefined()
|
|
38
|
+
expect(resolved.categories?.git).toBeDefined()
|
|
35
39
|
})
|
|
36
40
|
|
|
37
41
|
test("compact MCP mempalace pythonPath is materialized into environment", () => {
|
|
@@ -47,6 +51,20 @@ test("static MCP export includes marker metadata and servers", () => {
|
|
|
47
51
|
expect(exported._meta?.version).toBe(1)
|
|
48
52
|
expect(exported.mcpServers.playwright).toBeDefined()
|
|
49
53
|
expect(exported.mcpServers.mempalace).toBeDefined()
|
|
54
|
+
expect(exported.mcpServers.websearch).toBeDefined()
|
|
55
|
+
expect(exported.mcpServers.grep_app).toBeDefined()
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
test("websearch MCP provider is selected from the MCP switchboard", () => {
|
|
59
|
+
const resolved = applyModelSlots({
|
|
60
|
+
...baseConfig,
|
|
61
|
+
mcp: {
|
|
62
|
+
websearch: { enabled: true, provider: "tavily" },
|
|
63
|
+
},
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
expect(resolved.mcp?.websearch?.url).toBe("https://mcp.tavily.com/mcp/")
|
|
67
|
+
expect(resolved.mcp?.websearch?.headers?.Authorization).toBe("Bearer {env:TAVILY_API_KEY}")
|
|
50
68
|
})
|
|
51
69
|
|
|
52
70
|
test("integration primer does not request model provider API keys", () => {
|
|
@@ -37,6 +37,7 @@ export const ModelSlotsConfigSchema = z.object({
|
|
|
37
37
|
manager: ModelSlotConfigSchema.optional(),
|
|
38
38
|
brainstormer: ModelSlotConfigSchema.optional(),
|
|
39
39
|
vision: ModelSlotConfigSchema.optional(),
|
|
40
|
+
sub: ModelSlotConfigSchema.optional(),
|
|
40
41
|
});
|
|
41
42
|
|
|
42
43
|
export const FallbackEntrySchema = z.object({
|
|
@@ -71,6 +72,7 @@ export const CategoryConfigSchema = z.object({
|
|
|
71
72
|
export const McpServerConfigSchema = z.object({
|
|
72
73
|
enabled: z.boolean().default(true),
|
|
73
74
|
type: z.enum(["remote", "local"]).optional(),
|
|
75
|
+
provider: z.enum(["exa", "tavily"]).optional(),
|
|
74
76
|
url: z.string().optional(),
|
|
75
77
|
headers: z.record(z.string(), z.string()).optional(),
|
|
76
78
|
command: z.array(z.string()).optional(),
|
|
@@ -50,5 +50,3 @@ export { StartWorkConfigSchema } from "./start-work"
|
|
|
50
50
|
export type { StartWorkConfig } from "./start-work"
|
|
51
51
|
export { TmuxConfigSchema, TmuxLayoutSchema, TmuxIsolationSchema } from "./tmux"
|
|
52
52
|
export type { TmuxConfig, TmuxLayout, TmuxIsolation } from "./tmux"
|
|
53
|
-
export { WebsearchConfigSchema } from "./websearch"
|
|
54
|
-
export type { WebsearchConfig, WebsearchProvider } from "./websearch"
|
|
@@ -23,7 +23,6 @@ import { BobAgentConfigSchema } from "./bob-agent"
|
|
|
23
23
|
import { TmuxConfigSchema } from "./tmux"
|
|
24
24
|
import { StartWorkConfigSchema } from "./start-work"
|
|
25
25
|
import { FastApplyConfigSchema } from "./fast-apply"
|
|
26
|
-
import { WebsearchConfigSchema } from "./websearch"
|
|
27
26
|
|
|
28
27
|
const AuthConfigSchema = z.object({
|
|
29
28
|
stitch: z.string().optional(),
|
|
@@ -78,7 +77,6 @@ export const HiaiOpenCodeConfigSchema = z.object({
|
|
|
78
77
|
git_env_prefix: "GIT_MASTER=1",
|
|
79
78
|
}),
|
|
80
79
|
browser_automation_engine: BrowserAutomationConfigSchema.optional(),
|
|
81
|
-
websearch: WebsearchConfigSchema.optional(),
|
|
82
80
|
tmux: TmuxConfigSchema.optional(),
|
|
83
81
|
"bob": BobConfigSchema.optional(),
|
|
84
82
|
start_work: StartWorkConfigSchema.optional(),
|
package/src/config/types.ts
CHANGED
|
@@ -34,6 +34,7 @@ export interface ModelSlotsConfig {
|
|
|
34
34
|
manager?: ModelSlotConfig;
|
|
35
35
|
brainstormer?: ModelSlotConfig;
|
|
36
36
|
vision?: ModelSlotConfig;
|
|
37
|
+
sub?: ModelSlotConfig;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
// Canonical 12-agent model exposed by schema/default config.
|
|
@@ -136,7 +137,7 @@ export interface HeuristicModelFamilyDefinition {
|
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
export interface CategoryConfig {
|
|
139
|
-
model
|
|
140
|
+
model?: string;
|
|
140
141
|
variant?: string;
|
|
141
142
|
description?: string;
|
|
142
143
|
fallbackChain?: FallbackEntry[];
|
|
@@ -145,6 +146,7 @@ export interface CategoryConfig {
|
|
|
145
146
|
export interface McpServerConfig {
|
|
146
147
|
enabled: boolean;
|
|
147
148
|
type?: "remote" | "local";
|
|
149
|
+
provider?: "exa" | "tavily";
|
|
148
150
|
url?: string;
|
|
149
151
|
headers?: Record<string, string>;
|
|
150
152
|
command?: string[];
|
|
@@ -6,3 +6,4 @@ export { devBrowserSkill } from "./dev-browser"
|
|
|
6
6
|
export { reviewWorkSkill } from "./review-work"
|
|
7
7
|
export { aiSlopRemoverSkill } from "./ai-slop-remover"
|
|
8
8
|
export { hiaiOpencodeSetupSkill } from "./hiai-opencode-setup"
|
|
9
|
+
export { websiteCopywritingSkill } from "./website-copywriting"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { BuiltinSkill } from "../types"
|
|
2
|
+
|
|
3
|
+
export const websiteCopywritingSkill: BuiltinSkill = {
|
|
4
|
+
name: "website-copywriting",
|
|
5
|
+
description:
|
|
6
|
+
"Writes sharp website/product copy: landing pages, hero sections, CTAs, feature blocks, positioning, naming, and tone of voice.",
|
|
7
|
+
template: `# Website Copywriting
|
|
8
|
+
|
|
9
|
+
Use this skill for public-facing product and website text.
|
|
10
|
+
|
|
11
|
+
## Inputs To Clarify
|
|
12
|
+
|
|
13
|
+
- Audience: who reads this and what do they already know?
|
|
14
|
+
- Goal: sign up, book demo, understand feature, trust product, recover from error, continue onboarding.
|
|
15
|
+
- Tone: precise, playful, premium, technical, calm, bold, founder-led, enterprise, developer-first.
|
|
16
|
+
- Proof: real features, constraints, metrics, customer pain, differentiators. Do not invent proof.
|
|
17
|
+
|
|
18
|
+
## Output Shape
|
|
19
|
+
|
|
20
|
+
Prefer copy that can be pasted into UI:
|
|
21
|
+
|
|
22
|
+
- Hero: headline, subheadline, primary CTA, secondary CTA.
|
|
23
|
+
- Feature block: title, one-sentence value, 2-4 proof bullets.
|
|
24
|
+
- Section copy: heading, short intro, card titles, card bodies.
|
|
25
|
+
- Microcopy: button labels, empty states, errors, onboarding hints.
|
|
26
|
+
- Alternatives: 3-5 variants when tone or positioning is undecided.
|
|
27
|
+
|
|
28
|
+
## Writing Rules
|
|
29
|
+
|
|
30
|
+
- Specific beats clever. Concrete verbs beat vague hype.
|
|
31
|
+
- Avoid generic AI language: seamless, unlock, supercharge, leverage, robust, cutting-edge, revolutionize, next-generation.
|
|
32
|
+
- Keep claims tied to actual capabilities.
|
|
33
|
+
- Use short lines for UI. Long paragraphs are usually wrong for websites.
|
|
34
|
+
- Preserve product vocabulary from the codebase/docs when available.
|
|
35
|
+
- If visual direction matters, pair with \`frontend-ui-ux\` or delegate visual work to Designer.
|
|
36
|
+
|
|
37
|
+
## Delegation Hint
|
|
38
|
+
|
|
39
|
+
Use \`task(subagent_type="brainstormer", load_skills=["website-copywriting"], ...)\` for copy-only work.
|
|
40
|
+
Use \`category="writing"\` when a category is required. Writer/copywriter aliases map to Brainstormer.`,
|
|
41
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { expect, test } from "bun:test"
|
|
2
|
+
|
|
3
|
+
import { createBuiltinSkills } from "./skills"
|
|
4
|
+
|
|
5
|
+
test("website-copywriting is available as a builtin skill", () => {
|
|
6
|
+
const skills = createBuiltinSkills()
|
|
7
|
+
expect(skills.some((skill) => skill.name === "website-copywriting")).toBe(true)
|
|
8
|
+
})
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
reviewWorkSkill,
|
|
12
12
|
aiSlopRemoverSkill,
|
|
13
13
|
hiaiOpencodeSetupSkill,
|
|
14
|
+
websiteCopywritingSkill,
|
|
14
15
|
} from "./skills/index"
|
|
15
16
|
|
|
16
17
|
export interface CreateBuiltinSkillsOptions {
|
|
@@ -38,6 +39,7 @@ export function createBuiltinSkills(options: CreateBuiltinSkillsOptions = {}): B
|
|
|
38
39
|
devBrowserSkill,
|
|
39
40
|
reviewWorkSkill,
|
|
40
41
|
aiSlopRemoverSkill,
|
|
42
|
+
websiteCopywritingSkill,
|
|
41
43
|
]
|
|
42
44
|
|
|
43
45
|
if (!disabledSkills) {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
| Tier | Manager | Scope |
|
|
12
12
|
|------|---------|-------|
|
|
13
|
-
| 1.
|
|
13
|
+
| 1. Platform defaults | `HIAI_MCP_REGISTRY` (src/mcp/registry.ts) | Global MCP defaults materialized from hiai-opencode.json |
|
|
14
14
|
| 2. Claude Code | `claude-code-mcp-loader` (src/features/) | From `.mcp.json` |
|
|
15
15
|
| 3. **Skill-embedded** | **`SkillMcpManager` (this module)** | **Per-session, from SKILL.md YAML** |
|
|
16
16
|
|
|
@@ -30,13 +30,13 @@ export const REMINDER_MESSAGE = `
|
|
|
30
30
|
|
|
31
31
|
You called a search/fetch tool directly without leveraging specialized agents.
|
|
32
32
|
|
|
33
|
-
RECOMMENDED: Use task with
|
|
33
|
+
RECOMMENDED: Use task with researcher agents for better results:
|
|
34
34
|
|
|
35
35
|
\`\`\`
|
|
36
36
|
// Parallel exploration - fire multiple agents simultaneously
|
|
37
|
-
task(subagent_type="
|
|
38
|
-
task(subagent_type="
|
|
39
|
-
task(subagent_type="
|
|
37
|
+
task(subagent_type="researcher", load_skills=[], prompt="Find all files matching pattern X")
|
|
38
|
+
task(subagent_type="researcher", load_skills=[], prompt="Search for implementation of Y")
|
|
39
|
+
task(subagent_type="researcher", load_skills=[], prompt="Lookup documentation for Z")
|
|
40
40
|
|
|
41
41
|
// Then continue your work while they run in background
|
|
42
42
|
// System will notify you when each completes
|
package/src/hooks/index.ts
CHANGED
|
@@ -28,8 +28,6 @@ export { createThinkingBlockValidatorHook } from "./thinking-block-validator";
|
|
|
28
28
|
export { createToolPairValidatorHook } from "./tool-pair-validator";
|
|
29
29
|
export { createCategorySkillReminderHook } from "./category-skill-reminder";
|
|
30
30
|
export { createRalphLoopHook, type RalphLoopHook } from "./ralph-loop";
|
|
31
|
-
export { createNoBobGptHook } from "./no-bob-gpt";
|
|
32
|
-
export { createNoCoderNonGptHook } from "./no-coder-non-gpt";
|
|
33
31
|
export { createAutoSlashCommandHook } from "./auto-slash-command";
|
|
34
32
|
export { createEditErrorRecoveryHook } from "./edit-error-recovery";
|
|
35
33
|
|
|
@@ -95,50 +95,50 @@ TELL THE USER WHAT AGENTS YOU WILL LEVERAGE NOW TO SATISFY USER'S REQUEST.
|
|
|
95
95
|
|
|
96
96
|
## MANDATORY: PLAN AGENT INVOCATION (NON-NEGOTIABLE)
|
|
97
97
|
|
|
98
|
-
**YOU MUST ALWAYS INVOKE THE
|
|
98
|
+
**YOU MUST ALWAYS INVOKE THE STRATEGIST AGENT FOR ANY NON-TRIVIAL TASK.**
|
|
99
99
|
|
|
100
100
|
| Condition | Action |
|
|
101
101
|
|-----------|--------|
|
|
102
|
-
| Task has 2+ steps | MUST call
|
|
103
|
-
| Task scope unclear | MUST call
|
|
104
|
-
| Implementation required | MUST call
|
|
105
|
-
| Architecture decision needed | MUST call
|
|
102
|
+
| Task has 2+ steps | MUST call strategist agent |
|
|
103
|
+
| Task scope unclear | MUST call strategist agent |
|
|
104
|
+
| Implementation required | MUST call strategist agent |
|
|
105
|
+
| Architecture decision needed | MUST call strategist agent |
|
|
106
106
|
|
|
107
107
|
\`\`\`
|
|
108
|
-
task(subagent_type="
|
|
108
|
+
task(subagent_type="strategist", load_skills=[], run_in_background=false, prompt="<gathered context + user request>")
|
|
109
109
|
\`\`\`
|
|
110
110
|
|
|
111
|
-
**WHY
|
|
112
|
-
-
|
|
113
|
-
-
|
|
114
|
-
-
|
|
111
|
+
**WHY STRATEGIST AGENT IS MANDATORY:**
|
|
112
|
+
- Strategist analyzes dependencies and parallel execution opportunities
|
|
113
|
+
- Strategist outputs a **parallel task graph** with waves and dependencies
|
|
114
|
+
- Strategist provides structured TODO list with category + skills per task
|
|
115
115
|
- YOU are an orchestrator, NOT an implementer
|
|
116
116
|
|
|
117
|
-
### SESSION CONTINUITY WITH
|
|
117
|
+
### SESSION CONTINUITY WITH STRATEGIST AGENT (CRITICAL)
|
|
118
118
|
|
|
119
|
-
**
|
|
119
|
+
**Strategist agent returns a session_id. USE IT for follow-up interactions.**
|
|
120
120
|
|
|
121
121
|
| Scenario | Action |
|
|
122
122
|
|----------|--------|
|
|
123
|
-
|
|
|
123
|
+
| Strategist asks clarifying questions | \`task(session_id="{returned_session_id}", load_skills=[], run_in_background=false, prompt="<your answer>")\` |
|
|
124
124
|
| Need to refine the plan | \`task(session_id="{returned_session_id}", load_skills=[], run_in_background=false, prompt="Please adjust: <feedback>")\` |
|
|
125
|
-
|
|
|
125
|
+
| Strategist needs more detail | \`task(session_id="{returned_session_id}", load_skills=[], run_in_background=false, prompt="Add more detail to Task N")\` |
|
|
126
126
|
|
|
127
127
|
**WHY SESSION_ID IS CRITICAL:**
|
|
128
|
-
-
|
|
128
|
+
- Strategist retains FULL conversation context
|
|
129
129
|
- No repeated exploration or context gathering
|
|
130
130
|
- Saves 70%+ tokens on follow-ups
|
|
131
131
|
- Maintains interview continuity until plan is finalized
|
|
132
132
|
|
|
133
133
|
\`\`\`
|
|
134
134
|
// WRONG: Starting fresh loses all context
|
|
135
|
-
task(subagent_type="
|
|
135
|
+
task(subagent_type="strategist", load_skills=[], run_in_background=false, prompt="Here's more info...")
|
|
136
136
|
|
|
137
137
|
// CORRECT: Resume preserves everything
|
|
138
138
|
task(session_id="ses_abc123", load_skills=[], run_in_background=false, prompt="Here's my answer to your question: ...")
|
|
139
139
|
\`\`\`
|
|
140
140
|
|
|
141
|
-
**FAILURE TO CALL
|
|
141
|
+
**FAILURE TO CALL STRATEGIST AGENT = INCOMPLETE WORK.**
|
|
142
142
|
|
|
143
143
|
---
|
|
144
144
|
|
|
@@ -150,7 +150,7 @@ task(session_id="ses_abc123", load_skills=[], run_in_background=false, prompt="H
|
|
|
150
150
|
|-----------|--------|-----|
|
|
151
151
|
| Codebase exploration | task(subagent_type="researcher", load_skills=[], run_in_background=true) | Parallel, context-efficient |
|
|
152
152
|
| Documentation lookup | task(subagent_type="researcher", load_skills=[], run_in_background=true) | Specialized knowledge |
|
|
153
|
-
| Planning | task(subagent_type="
|
|
153
|
+
| Planning | task(subagent_type="strategist", load_skills=[], run_in_background=false) | Parallel task graph + structured TODO list |
|
|
154
154
|
| Hard problem (conventional) | task(subagent_type="strategist", load_skills=[], run_in_background=false) | Architecture, planning, complex logic |
|
|
155
155
|
| Hard problem (review/debugging) | task(subagent_type="critic", load_skills=[], run_in_background=false) | Verification, debugging, high-risk review |
|
|
156
156
|
| Hard problem (non-conventional) | task(category="artistry", load_skills=[...], run_in_background=true) | Different approach needed |
|