@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
package/dist/index.js
CHANGED
|
@@ -146,9 +146,9 @@ var init_agent_names = __esm(() => {
|
|
|
146
146
|
subagent: "coder",
|
|
147
147
|
sub: "coder",
|
|
148
148
|
designer: "designer",
|
|
149
|
-
ui: "
|
|
150
|
-
vision: "
|
|
151
|
-
multimodal: "
|
|
149
|
+
ui: "multimodal",
|
|
150
|
+
vision: "multimodal",
|
|
151
|
+
multimodal: "multimodal"
|
|
152
152
|
};
|
|
153
153
|
BUILTIN_AGENT_NAMES = new Set([
|
|
154
154
|
"bob",
|
|
@@ -157,7 +157,7 @@ var init_agent_names = __esm(() => {
|
|
|
157
157
|
"critic",
|
|
158
158
|
"designer",
|
|
159
159
|
"researcher",
|
|
160
|
-
"
|
|
160
|
+
"multimodal",
|
|
161
161
|
"platform-manager",
|
|
162
162
|
"guard"
|
|
163
163
|
]);
|
|
@@ -20778,8 +20778,8 @@ var require_resolve = __commonJS((exports) => {
|
|
|
20778
20778
|
}
|
|
20779
20779
|
return count;
|
|
20780
20780
|
}
|
|
20781
|
-
function getFullPath(resolver, id = "",
|
|
20782
|
-
if (
|
|
20781
|
+
function getFullPath(resolver, id = "", normalize4) {
|
|
20782
|
+
if (normalize4 !== false)
|
|
20783
20783
|
id = normalizeId(id);
|
|
20784
20784
|
const p = resolver.parse(id);
|
|
20785
20785
|
return _getFullPath(resolver, p);
|
|
@@ -22066,7 +22066,7 @@ var require_schemes = __commonJS((exports, module) => {
|
|
|
22066
22066
|
var require_fast_uri = __commonJS((exports, module) => {
|
|
22067
22067
|
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizeComponentEncoding, isIPv4, nonSimpleDomain } = require_utils2();
|
|
22068
22068
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
22069
|
-
function
|
|
22069
|
+
function normalize4(uri, options) {
|
|
22070
22070
|
if (typeof uri === "string") {
|
|
22071
22071
|
uri = serialize(parse11(uri, options), options);
|
|
22072
22072
|
} else if (typeof uri === "object") {
|
|
@@ -22301,7 +22301,7 @@ var require_fast_uri = __commonJS((exports, module) => {
|
|
|
22301
22301
|
}
|
|
22302
22302
|
var fastUri = {
|
|
22303
22303
|
SCHEMES,
|
|
22304
|
-
normalize:
|
|
22304
|
+
normalize: normalize4,
|
|
22305
22305
|
resolve: resolve22,
|
|
22306
22306
|
resolveComponent,
|
|
22307
22307
|
equal,
|
|
@@ -33808,8 +33808,8 @@ class EventEmitter {
|
|
|
33808
33808
|
// node_modules/bun-pty/src/terminal.ts
|
|
33809
33809
|
import { dlopen, FFIType, ptr } from "bun:ffi";
|
|
33810
33810
|
import { Buffer as Buffer2 } from "buffer";
|
|
33811
|
-
import { join as
|
|
33812
|
-
import { existsSync as
|
|
33811
|
+
import { join as join104, dirname as dirname31, basename as basename16 } from "path";
|
|
33812
|
+
import { existsSync as existsSync91 } from "fs";
|
|
33813
33813
|
function shQuote(s) {
|
|
33814
33814
|
if (s.length === 0)
|
|
33815
33815
|
return "''";
|
|
@@ -33817,7 +33817,7 @@ function shQuote(s) {
|
|
|
33817
33817
|
}
|
|
33818
33818
|
function resolveLibPath() {
|
|
33819
33819
|
const env = process.env.BUN_PTY_LIB;
|
|
33820
|
-
if (env &&
|
|
33820
|
+
if (env && existsSync91(env))
|
|
33821
33821
|
return env;
|
|
33822
33822
|
try {
|
|
33823
33823
|
const embeddedPath = __require(`../rust-pty/target/release/${process.platform === "win32" ? "rust_pty.dll" : process.platform === "darwin" ? process.arch === "arm64" ? "librust_pty_arm64.dylib" : "librust_pty.dylib" : process.arch === "arm64" ? "librust_pty_arm64.so" : "librust_pty.so"}`);
|
|
@@ -33828,22 +33828,22 @@ function resolveLibPath() {
|
|
|
33828
33828
|
const arch = process.arch;
|
|
33829
33829
|
const filenames = platform2 === "darwin" ? arch === "arm64" ? ["librust_pty_arm64.dylib", "librust_pty.dylib"] : ["librust_pty.dylib"] : platform2 === "win32" ? ["rust_pty.dll"] : arch === "arm64" ? ["librust_pty_arm64.so", "librust_pty.so"] : ["librust_pty.so"];
|
|
33830
33830
|
const base = Bun.fileURLToPath(import.meta.url);
|
|
33831
|
-
const fileDir =
|
|
33831
|
+
const fileDir = dirname31(base);
|
|
33832
33832
|
const dirName = basename16(fileDir);
|
|
33833
|
-
const here = dirName === "src" || dirName === "dist" ?
|
|
33833
|
+
const here = dirName === "src" || dirName === "dist" ? dirname31(fileDir) : fileDir;
|
|
33834
33834
|
const basePaths = [
|
|
33835
|
-
|
|
33836
|
-
|
|
33837
|
-
|
|
33835
|
+
join104(here, "rust-pty", "target", "release"),
|
|
33836
|
+
join104(here, "..", "bun-pty", "rust-pty", "target", "release"),
|
|
33837
|
+
join104(process.cwd(), "node_modules", "bun-pty", "rust-pty", "target", "release")
|
|
33838
33838
|
];
|
|
33839
33839
|
const fallbackPaths = [];
|
|
33840
33840
|
for (const basePath of basePaths) {
|
|
33841
33841
|
for (const filename of filenames) {
|
|
33842
|
-
fallbackPaths.push(
|
|
33842
|
+
fallbackPaths.push(join104(basePath, filename));
|
|
33843
33843
|
}
|
|
33844
33844
|
}
|
|
33845
33845
|
for (const path10 of fallbackPaths) {
|
|
33846
|
-
if (
|
|
33846
|
+
if (existsSync91(path10))
|
|
33847
33847
|
return path10;
|
|
33848
33848
|
}
|
|
33849
33849
|
throw new Error(`librust_pty shared library not found.
|
|
@@ -35060,8 +35060,8 @@ var init_plugin = __esm(() => {
|
|
|
35060
35060
|
});
|
|
35061
35061
|
|
|
35062
35062
|
// src/index.ts
|
|
35063
|
-
import { existsSync as
|
|
35064
|
-
import { join as
|
|
35063
|
+
import { existsSync as existsSync92 } from "fs";
|
|
35064
|
+
import { join as join105 } from "path";
|
|
35065
35065
|
|
|
35066
35066
|
// src/hooks/todo-continuation-enforcer/index.ts
|
|
35067
35067
|
init_logger();
|
|
@@ -110591,6 +110591,11 @@ async function loadGlobalAgentsSkills() {
|
|
|
110591
110591
|
const skills = await loadSkillsFromDir({ skillsDir: agentsGlobalDir, scope: "user" });
|
|
110592
110592
|
return skillsToCommandDefinitionRecord(skills);
|
|
110593
110593
|
}
|
|
110594
|
+
async function loadManagedPluginSkills() {
|
|
110595
|
+
const skillsDir = join60(getOpenCodeConfigDir({ binary: "opencode" }), ".hiai", "skills", "plugin");
|
|
110596
|
+
const skills = await loadSkillsFromDir({ skillsDir, scope: "builtin" });
|
|
110597
|
+
return skillsToCommandDefinitionRecord(skills);
|
|
110598
|
+
}
|
|
110594
110599
|
async function discoverAllSkills(directory) {
|
|
110595
110600
|
const [opencodeProjectSkills, opencodeGlobalSkills, projectSkills, userSkills, agentsProjectSkills, agentsGlobalSkills] = await Promise.all([
|
|
110596
110601
|
discoverOpencodeProjectSkills(directory),
|
|
@@ -110661,6 +110666,10 @@ async function discoverGlobalAgentsSkills() {
|
|
|
110661
110666
|
const agentsGlobalDir = join60(getAgentsConfigDir(), "skills");
|
|
110662
110667
|
return loadSkillsFromDir({ skillsDir: agentsGlobalDir, scope: "user" });
|
|
110663
110668
|
}
|
|
110669
|
+
async function discoverManagedPluginSkills() {
|
|
110670
|
+
const skillsDir = join60(getOpenCodeConfigDir({ binary: "opencode" }), ".hiai", "skills", "plugin");
|
|
110671
|
+
return loadSkillsFromDir({ skillsDir, scope: "builtin" });
|
|
110672
|
+
}
|
|
110664
110673
|
// src/features/opencode-skill-loader/merger/builtin-skill-converter.ts
|
|
110665
110674
|
function builtinToLoadedSkill(builtin) {
|
|
110666
110675
|
const definition = {
|
|
@@ -110893,11 +110902,33 @@ var playwrightSkill = {
|
|
|
110893
110902
|
description: "MUST USE for any browser-related tasks. Browser automation via Playwright MCP - verification, browsing, information gathering, web scraping, testing, screenshots, and all browser interactions.",
|
|
110894
110903
|
template: `# Playwright Browser Automation
|
|
110895
110904
|
|
|
110896
|
-
This skill provides browser automation capabilities via the Playwright MCP server
|
|
110905
|
+
This skill provides browser automation capabilities via the Playwright MCP server.
|
|
110906
|
+
|
|
110907
|
+
## Required workflow
|
|
110908
|
+
|
|
110909
|
+
1. Load this skill before calling \`skill_mcp\`.
|
|
110910
|
+
2. Use \`skill_mcp\` with \`mcp_name="playwright"\` for browser navigation, interaction, screenshots, and visual verification.
|
|
110911
|
+
3. If the host says \`MCP server "playwright" not found\`, do not conclude that Playwright is impossible. First report that the skill was not loaded or the Playwright MCP server was not registered in this session.
|
|
110912
|
+
4. If Chromium starts but fails with missing Linux libraries such as \`libnspr4\`, \`libnss3\`, \`libatk-bridge\`, \`libgtk-3\`, or similar, distinguish browser OS dependencies from MCP availability.
|
|
110913
|
+
|
|
110914
|
+
## Linux dependency fallback
|
|
110915
|
+
|
|
110916
|
+
Playwright has two dependency layers:
|
|
110917
|
+
|
|
110918
|
+
- Browser binary: installable without sudo with \`npx playwright install chromium\` or by setting \`HIAI_PLAYWRIGHT_INSTALL_BROWSERS=1\` before OpenCode starts.
|
|
110919
|
+
- System libraries: on minimal Linux images these usually require admin rights via \`sudo npx playwright install-deps chromium\` or OS package manager equivalents.
|
|
110920
|
+
|
|
110921
|
+
If sudo is unavailable, try these alternatives before falling back to curl-only checks:
|
|
110922
|
+
|
|
110923
|
+
- Use an already installed Chrome/Chromium/Edge by adding Playwright MCP args in \`hiai-opencode.json\`, for example \`--browser chrome\` or \`--browser msedge\`.
|
|
110924
|
+
- Use a remote/browser service or CDP-backed browser when available.
|
|
110925
|
+
- Switch the browser automation provider to \`agent-browser\` or \`playwright-cli\` if the workspace has those tools installed.
|
|
110926
|
+
|
|
110927
|
+
Only use \`curl\` as a final degraded check. Clearly say that HTTP checks do not replace interactive browser verification.`,
|
|
110897
110928
|
mcpConfig: {
|
|
110898
110929
|
playwright: {
|
|
110899
110930
|
command: "npx",
|
|
110900
|
-
args: ["@playwright/mcp@latest"]
|
|
110931
|
+
args: ["-y", "@playwright/mcp@latest"]
|
|
110901
110932
|
}
|
|
110902
110933
|
}
|
|
110903
110934
|
};
|
|
@@ -113926,6 +113957,8 @@ var AgentOverridesSchema = exports_external.object({
|
|
|
113926
113957
|
general: AgentOverrideConfigSchema.optional(),
|
|
113927
113958
|
zoe: AgentOverrideConfigSchema.optional(),
|
|
113928
113959
|
"pre-plan": AgentOverrideConfigSchema.optional(),
|
|
113960
|
+
manager: AgentOverrideConfigSchema.optional(),
|
|
113961
|
+
vision: AgentOverrideConfigSchema.optional(),
|
|
113929
113962
|
logician: AgentOverrideConfigSchema.optional(),
|
|
113930
113963
|
librarian: AgentOverrideConfigSchema.optional(),
|
|
113931
113964
|
explore: AgentOverrideConfigSchema.optional(),
|
|
@@ -114022,7 +114055,8 @@ var BuiltinCommandNameSchema = exports_external.enum([
|
|
|
114022
114055
|
"refactor",
|
|
114023
114056
|
"start-work",
|
|
114024
114057
|
"stop-continuation",
|
|
114025
|
-
"remove-ai-slops"
|
|
114058
|
+
"remove-ai-slops",
|
|
114059
|
+
"mcp-status"
|
|
114026
114060
|
]);
|
|
114027
114061
|
// src/config/schema/comment-checker.ts
|
|
114028
114062
|
var CommentCheckerConfigSchema = exports_external.object({
|
|
@@ -114077,8 +114111,8 @@ var ExperimentalConfigSchema = exports_external.object({
|
|
|
114077
114111
|
// src/config/schema/fast-apply.ts
|
|
114078
114112
|
var FastApplyConfigSchema = exports_external.object({
|
|
114079
114113
|
enabled: exports_external.boolean().optional().default(false),
|
|
114080
|
-
ollama_url: exports_external.string().optional().default("
|
|
114081
|
-
model: exports_external.string().optional().default("
|
|
114114
|
+
ollama_url: exports_external.string().optional().default(""),
|
|
114115
|
+
model: exports_external.string().optional().default(""),
|
|
114082
114116
|
timeout: exports_external.number().int().positive().optional().default(30000)
|
|
114083
114117
|
});
|
|
114084
114118
|
// src/config/schema/git-env-prefix.ts
|
|
@@ -114171,7 +114205,17 @@ var NotificationConfigSchema = exports_external.object({
|
|
|
114171
114205
|
force_enable: exports_external.boolean().optional()
|
|
114172
114206
|
});
|
|
114173
114207
|
// src/mcp/types.ts
|
|
114174
|
-
var McpNameSchema = exports_external.enum([
|
|
114208
|
+
var McpNameSchema = exports_external.enum([
|
|
114209
|
+
"playwright",
|
|
114210
|
+
"stitch",
|
|
114211
|
+
"sequential-thinking",
|
|
114212
|
+
"firecrawl",
|
|
114213
|
+
"rag",
|
|
114214
|
+
"context7",
|
|
114215
|
+
"mempalace",
|
|
114216
|
+
"websearch",
|
|
114217
|
+
"grep_app"
|
|
114218
|
+
]);
|
|
114175
114219
|
var AnyMcpNameSchema = exports_external.string().min(1);
|
|
114176
114220
|
|
|
114177
114221
|
// src/config/schema/ralph-loop.ts
|
|
@@ -114225,6 +114269,17 @@ var SkillsConfigSchema = exports_external.union([
|
|
|
114225
114269
|
}).catchall(SkillEntrySchema)
|
|
114226
114270
|
]);
|
|
114227
114271
|
|
|
114272
|
+
// src/config/schema/skill-discovery.ts
|
|
114273
|
+
var SkillDiscoveryConfigSchema = exports_external.object({
|
|
114274
|
+
config_sources: exports_external.boolean().default(true),
|
|
114275
|
+
project_opencode: exports_external.boolean().default(true),
|
|
114276
|
+
global_opencode: exports_external.boolean().default(false),
|
|
114277
|
+
project_claude: exports_external.boolean().default(false),
|
|
114278
|
+
global_claude: exports_external.boolean().default(false),
|
|
114279
|
+
project_agents: exports_external.boolean().default(false),
|
|
114280
|
+
global_agents: exports_external.boolean().default(false)
|
|
114281
|
+
});
|
|
114282
|
+
|
|
114228
114283
|
// src/config/schema/bob.ts
|
|
114229
114284
|
var BobTasksConfigSchema = exports_external.object({
|
|
114230
114285
|
storage_path: exports_external.string().optional(),
|
|
@@ -114283,7 +114338,8 @@ var AuthConfigSchema = exports_external.object({
|
|
|
114283
114338
|
openai: exports_external.string().optional(),
|
|
114284
114339
|
openrouter: exports_external.string().optional(),
|
|
114285
114340
|
stitch: exports_external.string().optional(),
|
|
114286
|
-
firecrawl: exports_external.string().optional()
|
|
114341
|
+
firecrawl: exports_external.string().optional(),
|
|
114342
|
+
context7: exports_external.string().optional()
|
|
114287
114343
|
}).optional();
|
|
114288
114344
|
var HiaiOpenCodeConfigSchema = exports_external.object({
|
|
114289
114345
|
$schema: exports_external.string().optional(),
|
|
@@ -114307,6 +114363,7 @@ var HiaiOpenCodeConfigSchema = exports_external.object({
|
|
|
114307
114363
|
experimental: ExperimentalConfigSchema.optional(),
|
|
114308
114364
|
auto_update: exports_external.boolean().optional(),
|
|
114309
114365
|
skills: SkillsConfigSchema.optional(),
|
|
114366
|
+
skill_discovery: SkillDiscoveryConfigSchema.optional(),
|
|
114310
114367
|
ralph_loop: RalphLoopConfigSchema.optional(),
|
|
114311
114368
|
runtime_fallback: exports_external.union([exports_external.boolean(), RuntimeFallbackConfigSchema]).optional(),
|
|
114312
114369
|
background_task: BackgroundTaskConfigSchema.optional(),
|
|
@@ -115994,6 +116051,44 @@ If any issues are found during critical review:
|
|
|
115994
116051
|
- ALWAYS preserve test coverage
|
|
115995
116052
|
- If uncertain about a change, err on the side of keeping the original code`;
|
|
115996
116053
|
|
|
116054
|
+
// src/features/builtin-commands/templates/mcp-status.ts
|
|
116055
|
+
var MCP_STATUS_TEMPLATE = `# MCP Status Command
|
|
116056
|
+
|
|
116057
|
+
## Purpose
|
|
116058
|
+
|
|
116059
|
+
Use /mcp-status to show the effective hiai-opencode MCP setup without relying on OpenCode's mcp list output.
|
|
116060
|
+
|
|
116061
|
+
## Execute
|
|
116062
|
+
|
|
116063
|
+
Run:
|
|
116064
|
+
|
|
116065
|
+
\`\`\`bash
|
|
116066
|
+
hiai-opencode mcp-status
|
|
116067
|
+
\`\`\`
|
|
116068
|
+
|
|
116069
|
+
If the binary is not on PATH, try the package-local fallback:
|
|
116070
|
+
|
|
116071
|
+
\`\`\`bash
|
|
116072
|
+
node ./node_modules/@hiai-gg/hiai-opencode/assets/cli/hiai-opencode.mjs mcp-status
|
|
116073
|
+
\`\`\`
|
|
116074
|
+
|
|
116075
|
+
## Report
|
|
116076
|
+
|
|
116077
|
+
Summarize the output in a compact status table:
|
|
116078
|
+
|
|
116079
|
+
- MCP server name
|
|
116080
|
+
- status: ok, warning, error, disabled
|
|
116081
|
+
- cause or next action
|
|
116082
|
+
|
|
116083
|
+
Rules:
|
|
116084
|
+
|
|
116085
|
+
- Do not print API key values.
|
|
116086
|
+
- If a key is missing, name the env var only.
|
|
116087
|
+
- If a runtime is missing, give the exact install hint from the command output or the shortest safe next command.
|
|
116088
|
+
- Do not edit config unless the user explicitly asks.
|
|
116089
|
+
- Do not run package installs unless the user explicitly asks.
|
|
116090
|
+
`;
|
|
116091
|
+
|
|
115997
116092
|
// src/features/builtin-commands/commands.ts
|
|
115998
116093
|
function resolveStartWorkAgent(options) {
|
|
115999
116094
|
if (options?.useRegisteredAgents) {
|
|
@@ -116097,6 +116192,12 @@ Timestamp: $TIMESTAMP
|
|
|
116097
116192
|
$ARGUMENTS
|
|
116098
116193
|
</user-request>`,
|
|
116099
116194
|
argumentHint: "[goal]"
|
|
116195
|
+
},
|
|
116196
|
+
"mcp-status": {
|
|
116197
|
+
description: "(builtin) Show hiai-opencode MCP server status, missing keys, and local runtime availability",
|
|
116198
|
+
template: `<command-instruction>
|
|
116199
|
+
${MCP_STATUS_TEMPLATE}
|
|
116200
|
+
</command-instruction>`
|
|
116100
116201
|
}
|
|
116101
116202
|
};
|
|
116102
116203
|
}
|
|
@@ -120433,7 +120534,7 @@ import * as fs12 from "fs";
|
|
|
120433
120534
|
import * as path6 from "path";
|
|
120434
120535
|
|
|
120435
120536
|
// src/config/loader.ts
|
|
120436
|
-
import { existsSync as
|
|
120537
|
+
import { existsSync as existsSync57, readFileSync as readFileSync43 } from "fs";
|
|
120437
120538
|
import { join as join66 } from "path";
|
|
120438
120539
|
|
|
120439
120540
|
// src/config/platform-schema.ts
|
|
@@ -120471,6 +120572,7 @@ var McpServerConfigSchema = exports_external.object({
|
|
|
120471
120572
|
enabled: exports_external.boolean().default(true),
|
|
120472
120573
|
type: exports_external.enum(["remote", "local"]).optional(),
|
|
120473
120574
|
url: exports_external.string().optional(),
|
|
120575
|
+
headers: exports_external.record(exports_external.string(), exports_external.string()).optional(),
|
|
120474
120576
|
command: exports_external.array(exports_external.string()).optional(),
|
|
120475
120577
|
timeout: exports_external.number().optional(),
|
|
120476
120578
|
environment: exports_external.record(exports_external.string(), exports_external.string()).optional()
|
|
@@ -120488,6 +120590,15 @@ var SkillsConfigSchema2 = exports_external.object({
|
|
|
120488
120590
|
enabled: exports_external.boolean().optional(),
|
|
120489
120591
|
disabled: exports_external.array(exports_external.string()).optional()
|
|
120490
120592
|
});
|
|
120593
|
+
var SkillDiscoveryConfigSchema2 = exports_external.object({
|
|
120594
|
+
config_sources: exports_external.boolean().optional(),
|
|
120595
|
+
project_opencode: exports_external.boolean().optional(),
|
|
120596
|
+
global_opencode: exports_external.boolean().optional(),
|
|
120597
|
+
project_claude: exports_external.boolean().optional(),
|
|
120598
|
+
global_claude: exports_external.boolean().optional(),
|
|
120599
|
+
project_agents: exports_external.boolean().optional(),
|
|
120600
|
+
global_agents: exports_external.boolean().optional()
|
|
120601
|
+
});
|
|
120491
120602
|
var PermissionsConfigSchema = exports_external.object({
|
|
120492
120603
|
read: exports_external.record(exports_external.string(), exports_external.string()).optional(),
|
|
120493
120604
|
edit: exports_external.record(exports_external.string(), exports_external.string()).optional(),
|
|
@@ -120519,8 +120630,8 @@ var AuthKeysSchema = exports_external.object({
|
|
|
120519
120630
|
});
|
|
120520
120631
|
var OllamaConfigSchema = exports_external.object({
|
|
120521
120632
|
enabled: exports_external.boolean().default(false),
|
|
120522
|
-
model: exports_external.string().default("
|
|
120523
|
-
baseUrl: exports_external.string().default("
|
|
120633
|
+
model: exports_external.string().default(""),
|
|
120634
|
+
baseUrl: exports_external.string().default(""),
|
|
120524
120635
|
purpose: exports_external.enum(["verification", "helper", "fallback"]).default("helper")
|
|
120525
120636
|
});
|
|
120526
120637
|
var ModelFamilySchema = exports_external.object({
|
|
@@ -120549,6 +120660,8 @@ var AgentsConfigSchema = exports_external.object({
|
|
|
120549
120660
|
zoe: AgentConfigSchema.optional(),
|
|
120550
120661
|
build: AgentConfigSchema.optional(),
|
|
120551
120662
|
"pre-plan": AgentConfigSchema.optional(),
|
|
120663
|
+
manager: AgentConfigSchema.optional(),
|
|
120664
|
+
vision: AgentConfigSchema.optional(),
|
|
120552
120665
|
logician: AgentConfigSchema.optional(),
|
|
120553
120666
|
librarian: AgentConfigSchema.optional(),
|
|
120554
120667
|
explore: AgentConfigSchema.optional(),
|
|
@@ -120578,6 +120691,8 @@ var AgentRequirementsConfigSchema = exports_external.object({
|
|
|
120578
120691
|
zoe: ModelRequirementSchema.optional(),
|
|
120579
120692
|
build: ModelRequirementSchema.optional(),
|
|
120580
120693
|
"pre-plan": ModelRequirementSchema.optional(),
|
|
120694
|
+
manager: ModelRequirementSchema.optional(),
|
|
120695
|
+
vision: ModelRequirementSchema.optional(),
|
|
120581
120696
|
logician: ModelRequirementSchema.optional(),
|
|
120582
120697
|
librarian: ModelRequirementSchema.optional(),
|
|
120583
120698
|
explore: ModelRequirementSchema.optional(),
|
|
@@ -120600,158 +120715,54 @@ var HiaiOpencodeConfigSchema = exports_external.object({
|
|
|
120600
120715
|
lsp: exports_external.record(exports_external.string(), LspServerConfigSchema).optional(),
|
|
120601
120716
|
subtask2: Subtask2ConfigSchema.optional(),
|
|
120602
120717
|
skills: SkillsConfigSchema2.optional(),
|
|
120718
|
+
skill_discovery: SkillDiscoveryConfigSchema2.optional(),
|
|
120603
120719
|
permissions: PermissionsConfigSchema.optional(),
|
|
120604
120720
|
auth: AuthKeysSchema.optional(),
|
|
120605
120721
|
ollama: OllamaConfigSchema.optional()
|
|
120606
120722
|
});
|
|
120607
120723
|
|
|
120608
120724
|
// src/config/defaults.ts
|
|
120609
|
-
import {
|
|
120610
|
-
|
|
120611
|
-
|
|
120612
|
-
|
|
120613
|
-
|
|
120614
|
-
|
|
120615
|
-
|
|
120616
|
-
|
|
120617
|
-
|
|
120618
|
-
|
|
120619
|
-
|
|
120620
|
-
|
|
120621
|
-
|
|
120622
|
-
|
|
120623
|
-
|
|
120624
|
-
// src/config/defaults.ts
|
|
120625
|
-
function resolveAssetScript(...segments) {
|
|
120626
|
-
return join65(import.meta.dirname, "..", "assets", ...segments);
|
|
120627
|
-
}
|
|
120628
|
-
function createNpmPackageCommand(pkg, ...args) {
|
|
120629
|
-
return ["node", resolveAssetScript("runtime", "npm-package-runner.mjs"), pkg, ...args];
|
|
120630
|
-
}
|
|
120631
|
-
function createUpstreamNpxCommand(pkg, ...args) {
|
|
120632
|
-
if (process.platform === "win32") {
|
|
120633
|
-
return ["cmd", "/c", "npx", "-y", pkg, ...args];
|
|
120634
|
-
}
|
|
120635
|
-
return ["npx", "-y", pkg, ...args];
|
|
120636
|
-
}
|
|
120637
|
-
var defaultConfig = {
|
|
120638
|
-
agents: {
|
|
120639
|
-
bob: { model: MODEL_PRESETS.high },
|
|
120640
|
-
guard: { model: MODEL_PRESETS.ultrahigh },
|
|
120641
|
-
strategist: { model: MODEL_PRESETS.strategist },
|
|
120642
|
-
critic: { model: MODEL_PRESETS.critic },
|
|
120643
|
-
coder: { model: MODEL_PRESETS.mid },
|
|
120644
|
-
designer: {
|
|
120645
|
-
model: "openrouter/google/gemini-3.1-pro",
|
|
120646
|
-
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)"
|
|
120647
|
-
},
|
|
120648
|
-
sub: { model: MODEL_PRESETS.fast },
|
|
120649
|
-
researcher: { model: MODEL_PRESETS.fast },
|
|
120650
|
-
multimodal: { model: MODEL_PRESETS.vision },
|
|
120651
|
-
"quality-guardian": { model: MODEL_PRESETS.mid },
|
|
120652
|
-
"platform-manager": { model: MODEL_PRESETS.fast },
|
|
120653
|
-
brainstormer: { model: MODEL_PRESETS.fast },
|
|
120654
|
-
"agent-skills": { model: MODEL_PRESETS.fast }
|
|
120655
|
-
},
|
|
120656
|
-
agentRequirements: {},
|
|
120657
|
-
categories: {
|
|
120658
|
-
"visual-engineering": { model: MODEL_PRESETS.vision, variant: "high" },
|
|
120659
|
-
artistry: { model: MODEL_PRESETS.vision, variant: "high" },
|
|
120660
|
-
ultrabrain: { model: MODEL_PRESETS.ultrahigh, variant: "xhigh" },
|
|
120661
|
-
deep: { model: MODEL_PRESETS.reasoning, variant: "medium" },
|
|
120662
|
-
quick: { model: MODEL_PRESETS.fast },
|
|
120663
|
-
writing: { model: MODEL_PRESETS.writing },
|
|
120664
|
-
git: { model: MODEL_PRESETS.fast },
|
|
120665
|
-
"unspecified-low": { model: MODEL_PRESETS.mid },
|
|
120666
|
-
"unspecified-high": { model: MODEL_PRESETS.high, variant: "max" }
|
|
120667
|
-
},
|
|
120668
|
-
categoryRequirements: {},
|
|
120669
|
-
mcp: {
|
|
120670
|
-
playwright: {
|
|
120671
|
-
enabled: true,
|
|
120672
|
-
command: createNpmPackageCommand("@playwright/mcp@latest"),
|
|
120673
|
-
timeout: 600000
|
|
120674
|
-
},
|
|
120675
|
-
stitch: {
|
|
120676
|
-
enabled: true,
|
|
120677
|
-
type: "remote",
|
|
120678
|
-
url: "https://stitch.googleapis.com/mcp",
|
|
120679
|
-
headers: { "X-Goog-Api-Key": "{env:STITCH_AI_API_KEY}" },
|
|
120680
|
-
timeout: 600000
|
|
120681
|
-
},
|
|
120682
|
-
"sequential-thinking": {
|
|
120683
|
-
enabled: true,
|
|
120684
|
-
command: createUpstreamNpxCommand("@modelcontextprotocol/server-sequential-thinking"),
|
|
120685
|
-
timeout: 600000
|
|
120686
|
-
},
|
|
120687
|
-
firecrawl: {
|
|
120688
|
-
enabled: true,
|
|
120689
|
-
command: createUpstreamNpxCommand("firecrawl-mcp"),
|
|
120690
|
-
timeout: 600000,
|
|
120691
|
-
environment: { FIRECRAWL_API_KEY: "{env:FIRECRAWL_API_KEY}" }
|
|
120692
|
-
},
|
|
120693
|
-
rag: {
|
|
120694
|
-
enabled: true,
|
|
120695
|
-
type: "remote",
|
|
120696
|
-
url: "http://localhost:9002",
|
|
120697
|
-
timeout: 600000
|
|
120698
|
-
},
|
|
120699
|
-
context7: {
|
|
120700
|
-
enabled: true,
|
|
120701
|
-
type: "remote",
|
|
120702
|
-
url: "https://mcp.context7.com/mcp",
|
|
120703
|
-
headers: { "X-API-KEY": "{env:CONTEXT7_API_KEY}" },
|
|
120704
|
-
timeout: 600000
|
|
120705
|
-
},
|
|
120706
|
-
mempalace: {
|
|
120707
|
-
enabled: true,
|
|
120708
|
-
command: ["node", resolveAssetScript("mcp", "mempalace.mjs"), "--palace", "./.opencode/palace"],
|
|
120709
|
-
timeout: 600000
|
|
120710
|
-
}
|
|
120711
|
-
},
|
|
120712
|
-
lsp: {
|
|
120713
|
-
typescript: {
|
|
120714
|
-
command: ["typescript-language-server", "--stdio"],
|
|
120715
|
-
extensions: [".ts", ".tsx", ".mts", ".cts"]
|
|
120716
|
-
},
|
|
120717
|
-
svelte: {
|
|
120718
|
-
command: ["svelteserver", "--stdio"],
|
|
120719
|
-
extensions: [".svelte"]
|
|
120720
|
-
},
|
|
120721
|
-
eslint: {
|
|
120722
|
-
command: createNpmPackageCommand("eslint-lsp", "--stdio"),
|
|
120723
|
-
extensions: [".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs", ".svelte"]
|
|
120724
|
-
},
|
|
120725
|
-
bash: {
|
|
120726
|
-
command: createNpmPackageCommand("bash-language-server", "start"),
|
|
120727
|
-
extensions: [".sh", ".bash"]
|
|
120728
|
-
},
|
|
120729
|
-
pyright: {
|
|
120730
|
-
command: ["pyright-langserver", "--stdio"],
|
|
120731
|
-
extensions: [".py"]
|
|
120725
|
+
import { existsSync as existsSync56, readFileSync as readFileSync42 } from "fs";
|
|
120726
|
+
import { dirname as dirname18, join as join65, normalize as normalize2 } from "path";
|
|
120727
|
+
function findPluginRoot() {
|
|
120728
|
+
const candidates = [
|
|
120729
|
+
join65(import.meta.dirname, "..", ".."),
|
|
120730
|
+
join65(import.meta.dirname, ".."),
|
|
120731
|
+
join65(import.meta.dirname, "..", ".."),
|
|
120732
|
+
dirname18(process.argv[1] ?? ""),
|
|
120733
|
+
process.cwd()
|
|
120734
|
+
];
|
|
120735
|
+
for (const candidate of candidates) {
|
|
120736
|
+
const root = normalize2(candidate);
|
|
120737
|
+
if (existsSync56(join65(root, "hiai-opencode.json"))) {
|
|
120738
|
+
return root;
|
|
120732
120739
|
}
|
|
120733
|
-
},
|
|
120734
|
-
subtask2: {
|
|
120735
|
-
replace_generic: true,
|
|
120736
|
-
generic_return: null
|
|
120737
|
-
},
|
|
120738
|
-
skills: {
|
|
120739
|
-
enabled: true,
|
|
120740
|
-
disabled: []
|
|
120741
|
-
},
|
|
120742
|
-
permissions: {
|
|
120743
|
-
read: { "*": "allow", "*.env": "deny", "*.env.*": "deny", "*.env.example": "allow" },
|
|
120744
|
-
edit: { "*": "allow" },
|
|
120745
|
-
bash: { "*": "allow" },
|
|
120746
|
-
deny_paths: ["**/backup/**", "**/secrets.*", "**/.env", "**/.env.*"]
|
|
120747
|
-
},
|
|
120748
|
-
ollama: {
|
|
120749
|
-
enabled: false,
|
|
120750
|
-
model: "{env:OLLAMA_MODEL:-qwen3.5:4b}",
|
|
120751
|
-
baseUrl: "http://localhost:11434",
|
|
120752
|
-
purpose: "helper"
|
|
120753
120740
|
}
|
|
120754
|
-
|
|
120741
|
+
throw new Error("[hiai-opencode] Cannot find bundled hiai-opencode.json. The package is incomplete.");
|
|
120742
|
+
}
|
|
120743
|
+
function expandPluginRootPlaceholders(value, pluginRoot) {
|
|
120744
|
+
if (typeof value === "string") {
|
|
120745
|
+
return value.replaceAll("{pluginRoot}", pluginRoot);
|
|
120746
|
+
}
|
|
120747
|
+
if (Array.isArray(value)) {
|
|
120748
|
+
return value.map((item) => expandPluginRootPlaceholders(item, pluginRoot));
|
|
120749
|
+
}
|
|
120750
|
+
if (value && typeof value === "object") {
|
|
120751
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [
|
|
120752
|
+
key,
|
|
120753
|
+
expandPluginRootPlaceholders(entry, pluginRoot)
|
|
120754
|
+
]));
|
|
120755
|
+
}
|
|
120756
|
+
return value;
|
|
120757
|
+
}
|
|
120758
|
+
function loadBundledDefaultConfig() {
|
|
120759
|
+
const pluginRoot = findPluginRoot();
|
|
120760
|
+
const configPath = join65(pluginRoot, "hiai-opencode.json");
|
|
120761
|
+
const raw = readFileSync42(configPath, "utf-8");
|
|
120762
|
+
const parsed = JSON.parse(raw);
|
|
120763
|
+
return expandPluginRootPlaceholders(parsed, pluginRoot);
|
|
120764
|
+
}
|
|
120765
|
+
var defaultConfig = loadBundledDefaultConfig();
|
|
120755
120766
|
|
|
120756
120767
|
// src/config/types.ts
|
|
120757
120768
|
var LEGACY_AGENT_ALIAS_TO_CANONICAL2 = {
|
|
@@ -120759,6 +120770,8 @@ var LEGACY_AGENT_ALIAS_TO_CANONICAL2 = {
|
|
|
120759
120770
|
zoe: "bob",
|
|
120760
120771
|
build: "bob",
|
|
120761
120772
|
"pre-plan": "strategist",
|
|
120773
|
+
manager: "platform-manager",
|
|
120774
|
+
vision: "multimodal",
|
|
120762
120775
|
logician: "strategist",
|
|
120763
120776
|
librarian: "researcher",
|
|
120764
120777
|
explore: "researcher",
|
|
@@ -120797,7 +120810,7 @@ function findConfigFile(searchDirs) {
|
|
|
120797
120810
|
for (const dir of searchDirs) {
|
|
120798
120811
|
for (const filename of CONFIG_FILENAMES) {
|
|
120799
120812
|
const candidate = join66(dir, filename);
|
|
120800
|
-
if (
|
|
120813
|
+
if (existsSync57(candidate))
|
|
120801
120814
|
return candidate;
|
|
120802
120815
|
}
|
|
120803
120816
|
}
|
|
@@ -120875,7 +120888,7 @@ function loadConfig(projectDir) {
|
|
|
120875
120888
|
const configPath = findConfigFile(searchDirs);
|
|
120876
120889
|
if (!configPath)
|
|
120877
120890
|
return BASE_CONFIG;
|
|
120878
|
-
const raw =
|
|
120891
|
+
const raw = readFileSync43(configPath, "utf-8");
|
|
120879
120892
|
const parsed = parse2(raw);
|
|
120880
120893
|
const normalizedParsed = normalizeCompactLspConfig(parsed);
|
|
120881
120894
|
const validated = HiaiOpencodeConfigSchema.parse(normalizedParsed);
|
|
@@ -120883,15 +120896,18 @@ function loadConfig(projectDir) {
|
|
|
120883
120896
|
return deepMerge2(BASE_CONFIG, normalized);
|
|
120884
120897
|
}
|
|
120885
120898
|
function resolveEnvVars(value) {
|
|
120886
|
-
return value.replace(/\{env:([^}]+)\}/g, (_,
|
|
120899
|
+
return value.replace(/\{env:([^}]+)\}/g, (_, expression) => {
|
|
120900
|
+
const [key, fallback] = String(expression).split(":-", 2);
|
|
120901
|
+
return process.env[key] || fallback || "";
|
|
120902
|
+
});
|
|
120887
120903
|
}
|
|
120888
120904
|
// src/shared/migrate-legacy-config-file.ts
|
|
120889
120905
|
init_logger();
|
|
120890
120906
|
init_plugin_identity();
|
|
120891
|
-
import { existsSync as
|
|
120892
|
-
import { join as join67, dirname as
|
|
120907
|
+
import { existsSync as existsSync58, readFileSync as readFileSync44, renameSync as renameSync3, rmSync as rmSync2 } from "fs";
|
|
120908
|
+
import { join as join67, dirname as dirname19, basename as basename9 } from "path";
|
|
120893
120909
|
function buildCanonicalPath(legacyPath) {
|
|
120894
|
-
const dir =
|
|
120910
|
+
const dir = dirname19(legacyPath);
|
|
120895
120911
|
const ext = basename9(legacyPath).includes(".jsonc") ? ".jsonc" : ".json";
|
|
120896
120912
|
return join67(dir, `${CONFIG_BASENAME}${ext}`);
|
|
120897
120913
|
}
|
|
@@ -120925,15 +120941,15 @@ function archiveLegacyConfigFile(legacyPath) {
|
|
|
120925
120941
|
}
|
|
120926
120942
|
}
|
|
120927
120943
|
function migrateLegacyConfigFile(legacyPath) {
|
|
120928
|
-
if (!
|
|
120944
|
+
if (!existsSync58(legacyPath))
|
|
120929
120945
|
return false;
|
|
120930
120946
|
if (!basename9(legacyPath).startsWith(LEGACY_CONFIG_BASENAME))
|
|
120931
120947
|
return false;
|
|
120932
120948
|
const canonicalPath = buildCanonicalPath(legacyPath);
|
|
120933
|
-
if (
|
|
120949
|
+
if (existsSync58(canonicalPath))
|
|
120934
120950
|
return false;
|
|
120935
120951
|
try {
|
|
120936
|
-
const content =
|
|
120952
|
+
const content = readFileSync44(legacyPath, "utf-8");
|
|
120937
120953
|
writeFileAtomically(canonicalPath, content);
|
|
120938
120954
|
const archivedLegacyConfig = archiveLegacyConfigFile(legacyPath);
|
|
120939
120955
|
log("[migrateLegacyConfigFile] Migrated legacy config to canonical path", {
|
|
@@ -122453,11 +122469,11 @@ function createRuntimeFallbackHook(ctx, options) {
|
|
|
122453
122469
|
};
|
|
122454
122470
|
}
|
|
122455
122471
|
// src/hooks/write-existing-file-guard/hook.ts
|
|
122456
|
-
import { existsSync as
|
|
122457
|
-
import { basename as basename11, dirname as
|
|
122472
|
+
import { existsSync as existsSync61, realpathSync as realpathSync6 } from "fs";
|
|
122473
|
+
import { basename as basename11, dirname as dirname21, isAbsolute as isAbsolute11, join as join69, normalize as normalize3, relative as relative8, resolve as resolve14 } from "path";
|
|
122458
122474
|
|
|
122459
122475
|
// src/hooks/write-existing-file-guard/tool-execute-before-handler.ts
|
|
122460
|
-
import { existsSync as
|
|
122476
|
+
import { existsSync as existsSync60 } from "fs";
|
|
122461
122477
|
|
|
122462
122478
|
// src/hooks/write-existing-file-guard/session-read-permissions.ts
|
|
122463
122479
|
function touchSession(sessionLastAccess, sessionID) {
|
|
@@ -122545,7 +122561,7 @@ async function handleWriteExistingFileGuardToolExecuteBefore(params) {
|
|
|
122545
122561
|
return;
|
|
122546
122562
|
}
|
|
122547
122563
|
if (toolName === "read") {
|
|
122548
|
-
if (!
|
|
122564
|
+
if (!existsSync60(resolvedPath) || !input.sessionID) {
|
|
122549
122565
|
return;
|
|
122550
122566
|
}
|
|
122551
122567
|
registerReadPermission({
|
|
@@ -122561,7 +122577,7 @@ async function handleWriteExistingFileGuardToolExecuteBefore(params) {
|
|
|
122561
122577
|
if (argsRecord && "overwrite" in argsRecord) {
|
|
122562
122578
|
delete argsRecord.overwrite;
|
|
122563
122579
|
}
|
|
122564
|
-
if (!
|
|
122580
|
+
if (!existsSync60(resolvedPath)) {
|
|
122565
122581
|
return;
|
|
122566
122582
|
}
|
|
122567
122583
|
const isBobPath2 = canonicalPath.includes("/.bob/");
|
|
@@ -122612,7 +122628,7 @@ function getPathFromArgs(args) {
|
|
|
122612
122628
|
return args?.filePath ?? args?.path ?? args?.file_path;
|
|
122613
122629
|
}
|
|
122614
122630
|
function resolveInputPath(ctx, inputPath) {
|
|
122615
|
-
return
|
|
122631
|
+
return normalize3(isAbsolute11(inputPath) ? inputPath : resolve14(ctx.directory, inputPath));
|
|
122616
122632
|
}
|
|
122617
122633
|
function isPathInsideDirectory(pathToCheck, directory) {
|
|
122618
122634
|
const relativePath = relative8(directory, pathToCheck);
|
|
@@ -122620,18 +122636,18 @@ function isPathInsideDirectory(pathToCheck, directory) {
|
|
|
122620
122636
|
}
|
|
122621
122637
|
function toCanonicalPath2(absolutePath) {
|
|
122622
122638
|
let canonicalPath = absolutePath;
|
|
122623
|
-
if (
|
|
122639
|
+
if (existsSync61(absolutePath)) {
|
|
122624
122640
|
try {
|
|
122625
122641
|
canonicalPath = realpathSync6.native(absolutePath);
|
|
122626
122642
|
} catch {
|
|
122627
122643
|
canonicalPath = absolutePath;
|
|
122628
122644
|
}
|
|
122629
122645
|
} else {
|
|
122630
|
-
const absoluteDir =
|
|
122631
|
-
const resolvedDir =
|
|
122646
|
+
const absoluteDir = dirname21(absolutePath);
|
|
122647
|
+
const resolvedDir = existsSync61(absoluteDir) ? realpathSync6.native(absoluteDir) : absoluteDir;
|
|
122632
122648
|
canonicalPath = join69(resolvedDir, basename11(absolutePath));
|
|
122633
122649
|
}
|
|
122634
|
-
return
|
|
122650
|
+
return normalize3(canonicalPath);
|
|
122635
122651
|
}
|
|
122636
122652
|
function isOverwriteEnabled(value) {
|
|
122637
122653
|
if (value === true) {
|
|
@@ -123905,23 +123921,23 @@ init_logger();
|
|
|
123905
123921
|
init_plugin_identity();
|
|
123906
123922
|
|
|
123907
123923
|
// src/hooks/legacy-plugin-toast/auto-migrate.ts
|
|
123908
|
-
import { existsSync as
|
|
123924
|
+
import { existsSync as existsSync62, readFileSync as readFileSync46 } from "fs";
|
|
123909
123925
|
import { join as join70 } from "path";
|
|
123910
123926
|
init_plugin_identity();
|
|
123911
123927
|
function detectOpenCodeConfigPath(overrideConfigDir) {
|
|
123912
123928
|
if (overrideConfigDir) {
|
|
123913
123929
|
const jsoncPath = join70(overrideConfigDir, "opencode.jsonc");
|
|
123914
123930
|
const jsonPath = join70(overrideConfigDir, "opencode.json");
|
|
123915
|
-
if (
|
|
123931
|
+
if (existsSync62(jsoncPath))
|
|
123916
123932
|
return jsoncPath;
|
|
123917
|
-
if (
|
|
123933
|
+
if (existsSync62(jsonPath))
|
|
123918
123934
|
return jsonPath;
|
|
123919
123935
|
return null;
|
|
123920
123936
|
}
|
|
123921
123937
|
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
123922
|
-
if (
|
|
123938
|
+
if (existsSync62(paths.configJsonc))
|
|
123923
123939
|
return paths.configJsonc;
|
|
123924
|
-
if (
|
|
123940
|
+
if (existsSync62(paths.configJson))
|
|
123925
123941
|
return paths.configJson;
|
|
123926
123942
|
return null;
|
|
123927
123943
|
}
|
|
@@ -123930,7 +123946,7 @@ function autoMigrateLegacyPluginEntry(overrideConfigDir) {
|
|
|
123930
123946
|
if (!configPath)
|
|
123931
123947
|
return { migrated: false, from: null, to: null, configPath: null };
|
|
123932
123948
|
try {
|
|
123933
|
-
const content =
|
|
123949
|
+
const content = readFileSync46(configPath, "utf-8");
|
|
123934
123950
|
const parseResult = parseJsoncSafe(content);
|
|
123935
123951
|
if (!parseResult.data?.plugin)
|
|
123936
123952
|
return { migrated: false, from: null, to: null, configPath };
|
|
@@ -124048,7 +124064,7 @@ async function queryOllama(args) {
|
|
|
124048
124064
|
}
|
|
124049
124065
|
|
|
124050
124066
|
// src/hooks/fast-apply/tool-execute-before-handler.ts
|
|
124051
|
-
import { existsSync as
|
|
124067
|
+
import { existsSync as existsSync63, readFileSync as readFileSync47 } from "fs";
|
|
124052
124068
|
async function handleFastApplyToolExecuteBefore(args) {
|
|
124053
124069
|
const { input, output, config: config2 } = args;
|
|
124054
124070
|
const normalizedTool = input.tool.toLowerCase();
|
|
@@ -124067,7 +124083,7 @@ async function handleFastApplyToolExecuteBefore(args) {
|
|
|
124067
124083
|
});
|
|
124068
124084
|
return;
|
|
124069
124085
|
}
|
|
124070
|
-
if (!
|
|
124086
|
+
if (!existsSync63(filePath)) {
|
|
124071
124087
|
log("[fast-apply] Skipping: file does not exist (new file)", {
|
|
124072
124088
|
sessionID: input.sessionID,
|
|
124073
124089
|
callID: input.callID,
|
|
@@ -124077,7 +124093,7 @@ async function handleFastApplyToolExecuteBefore(args) {
|
|
|
124077
124093
|
}
|
|
124078
124094
|
let originalContent;
|
|
124079
124095
|
try {
|
|
124080
|
-
originalContent =
|
|
124096
|
+
originalContent = readFileSync47(filePath, "utf-8");
|
|
124081
124097
|
} catch (err) {
|
|
124082
124098
|
log("[fast-apply] Failed to read file, falling back to default", {
|
|
124083
124099
|
sessionID: input.sessionID,
|
|
@@ -124456,13 +124472,13 @@ var DEFAULT_MAX_SYMBOLS = 200;
|
|
|
124456
124472
|
var DEFAULT_MAX_DIAGNOSTICS = 200;
|
|
124457
124473
|
var DEFAULT_MAX_DIRECTORY_FILES = 50;
|
|
124458
124474
|
// src/tools/lsp/server-config-loader.ts
|
|
124459
|
-
import { existsSync as
|
|
124475
|
+
import { existsSync as existsSync64, readFileSync as readFileSync48 } from "fs";
|
|
124460
124476
|
import { join as join71 } from "path";
|
|
124461
124477
|
function loadJsonFile(path7) {
|
|
124462
|
-
if (!
|
|
124478
|
+
if (!existsSync64(path7))
|
|
124463
124479
|
return null;
|
|
124464
124480
|
try {
|
|
124465
|
-
return parseJsonc(
|
|
124481
|
+
return parseJsonc(readFileSync48(path7, "utf-8"));
|
|
124466
124482
|
} catch {
|
|
124467
124483
|
return null;
|
|
124468
124484
|
}
|
|
@@ -124542,7 +124558,7 @@ function getMergedServers() {
|
|
|
124542
124558
|
}
|
|
124543
124559
|
|
|
124544
124560
|
// src/tools/lsp/server-installation.ts
|
|
124545
|
-
import { existsSync as
|
|
124561
|
+
import { existsSync as existsSync65 } from "fs";
|
|
124546
124562
|
import { delimiter, join as join73 } from "path";
|
|
124547
124563
|
|
|
124548
124564
|
// src/tools/lsp/server-path-bases.ts
|
|
@@ -124565,7 +124581,7 @@ function isServerInstalled(command) {
|
|
|
124565
124581
|
return false;
|
|
124566
124582
|
const cmd = command[0];
|
|
124567
124583
|
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
124568
|
-
if (
|
|
124584
|
+
if (existsSync65(cmd))
|
|
124569
124585
|
return true;
|
|
124570
124586
|
}
|
|
124571
124587
|
const isWindows2 = process.platform === "win32";
|
|
@@ -124586,14 +124602,14 @@ function isServerInstalled(command) {
|
|
|
124586
124602
|
const paths = pathEnv.split(delimiter);
|
|
124587
124603
|
for (const p of paths) {
|
|
124588
124604
|
for (const suffix of exts) {
|
|
124589
|
-
if (
|
|
124605
|
+
if (existsSync65(join73(p, cmd + suffix))) {
|
|
124590
124606
|
return true;
|
|
124591
124607
|
}
|
|
124592
124608
|
}
|
|
124593
124609
|
}
|
|
124594
124610
|
for (const base of getLspServerAdditionalPathBases(process.cwd())) {
|
|
124595
124611
|
for (const suffix of exts) {
|
|
124596
|
-
if (
|
|
124612
|
+
if (existsSync65(join73(base, cmd + suffix))) {
|
|
124597
124613
|
return true;
|
|
124598
124614
|
}
|
|
124599
124615
|
}
|
|
@@ -124651,13 +124667,13 @@ function getLanguageId(ext) {
|
|
|
124651
124667
|
init_logger();
|
|
124652
124668
|
var {spawn: bunSpawn2 } = globalThis.Bun;
|
|
124653
124669
|
import { spawn as nodeSpawn2 } from "child_process";
|
|
124654
|
-
import { existsSync as
|
|
124670
|
+
import { existsSync as existsSync66, statSync as statSync7 } from "fs";
|
|
124655
124671
|
function shouldUseNodeSpawn() {
|
|
124656
124672
|
return process.platform === "win32";
|
|
124657
124673
|
}
|
|
124658
124674
|
function validateCwd(cwd) {
|
|
124659
124675
|
try {
|
|
124660
|
-
if (!
|
|
124676
|
+
if (!existsSync66(cwd)) {
|
|
124661
124677
|
return { valid: false, error: `Working directory does not exist: ${cwd}` };
|
|
124662
124678
|
}
|
|
124663
124679
|
const stats = statSync7(cwd);
|
|
@@ -124789,7 +124805,7 @@ function spawnProcess(command, options) {
|
|
|
124789
124805
|
return proc;
|
|
124790
124806
|
}
|
|
124791
124807
|
// src/tools/lsp/lsp-client.ts
|
|
124792
|
-
import { readFileSync as
|
|
124808
|
+
import { readFileSync as readFileSync49 } from "fs";
|
|
124793
124809
|
import { extname as extname4, resolve as resolve15 } from "path";
|
|
124794
124810
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
124795
124811
|
|
|
@@ -125061,7 +125077,7 @@ class LSPClient extends LSPClientConnection {
|
|
|
125061
125077
|
async openFile(filePath) {
|
|
125062
125078
|
const absPath = resolve15(filePath);
|
|
125063
125079
|
const uri = pathToFileURL2(absPath).href;
|
|
125064
|
-
const text =
|
|
125080
|
+
const text = readFileSync49(absPath, "utf-8");
|
|
125065
125081
|
if (!this.openedFiles.has(absPath)) {
|
|
125066
125082
|
const ext = extname4(absPath);
|
|
125067
125083
|
const languageId = getLanguageId(ext);
|
|
@@ -125419,10 +125435,10 @@ var lspManager = LSPServerManager.getInstance();
|
|
|
125419
125435
|
// src/tools/lsp/lsp-client-wrapper.ts
|
|
125420
125436
|
import { extname as extname5, resolve as resolve16 } from "path";
|
|
125421
125437
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
125422
|
-
import { existsSync as
|
|
125438
|
+
import { existsSync as existsSync67, statSync as statSync8 } from "fs";
|
|
125423
125439
|
init_plugin_identity();
|
|
125424
125440
|
function isDirectoryPath(filePath) {
|
|
125425
|
-
if (!
|
|
125441
|
+
if (!existsSync67(filePath)) {
|
|
125426
125442
|
return false;
|
|
125427
125443
|
}
|
|
125428
125444
|
return statSync8(filePath).isDirectory();
|
|
@@ -125432,14 +125448,14 @@ function uriToPath(uri) {
|
|
|
125432
125448
|
}
|
|
125433
125449
|
function findWorkspaceRoot(filePath) {
|
|
125434
125450
|
let dir = resolve16(filePath);
|
|
125435
|
-
if (!
|
|
125451
|
+
if (!existsSync67(dir) || !isDirectoryPath(dir)) {
|
|
125436
125452
|
dir = __require("path").dirname(dir);
|
|
125437
125453
|
}
|
|
125438
125454
|
const markers = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
125439
125455
|
let prevDir = "";
|
|
125440
125456
|
while (dir !== prevDir) {
|
|
125441
125457
|
for (const marker of markers) {
|
|
125442
|
-
if (
|
|
125458
|
+
if (existsSync67(__require("path").join(dir, marker))) {
|
|
125443
125459
|
return dir;
|
|
125444
125460
|
}
|
|
125445
125461
|
}
|
|
@@ -125614,10 +125630,10 @@ function formatApplyResult(result) {
|
|
|
125614
125630
|
`);
|
|
125615
125631
|
}
|
|
125616
125632
|
// src/tools/lsp/workspace-edit.ts
|
|
125617
|
-
import { readFileSync as
|
|
125633
|
+
import { readFileSync as readFileSync50, writeFileSync as writeFileSync17 } from "fs";
|
|
125618
125634
|
function applyTextEditsToFile(filePath, edits) {
|
|
125619
125635
|
try {
|
|
125620
|
-
let content =
|
|
125636
|
+
let content = readFileSync50(filePath, "utf-8");
|
|
125621
125637
|
const lines = content.split(`
|
|
125622
125638
|
`);
|
|
125623
125639
|
const sortedEdits = [...edits].sort((a, b) => {
|
|
@@ -125683,7 +125699,7 @@ function applyWorkspaceEdit(edit) {
|
|
|
125683
125699
|
try {
|
|
125684
125700
|
const oldPath = uriToPath(change.oldUri);
|
|
125685
125701
|
const newPath = uriToPath(change.newUri);
|
|
125686
|
-
const content =
|
|
125702
|
+
const content = readFileSync50(oldPath, "utf-8");
|
|
125687
125703
|
writeFileSync17(newPath, content, "utf-8");
|
|
125688
125704
|
__require("fs").unlinkSync(oldPath);
|
|
125689
125705
|
result.filesModified.push(newPath);
|
|
@@ -125849,7 +125865,7 @@ init_tool();
|
|
|
125849
125865
|
import { resolve as resolve18 } from "path";
|
|
125850
125866
|
|
|
125851
125867
|
// src/tools/lsp/directory-diagnostics.ts
|
|
125852
|
-
import { existsSync as
|
|
125868
|
+
import { existsSync as existsSync68, lstatSync as lstatSync2, readdirSync as readdirSync19 } from "fs";
|
|
125853
125869
|
import { extname as extname6, join as join74, resolve as resolve17 } from "path";
|
|
125854
125870
|
var SKIP_DIRECTORIES = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
|
|
125855
125871
|
function collectFilesWithExtension(dir, extension, maxFiles) {
|
|
@@ -125895,7 +125911,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
125895
125911
|
throw new Error(`Extension must start with a dot (e.g., ".ts", not "${extension}"). ` + `Use ".${extension}" instead.`);
|
|
125896
125912
|
}
|
|
125897
125913
|
const absDir = resolve17(directory);
|
|
125898
|
-
if (!
|
|
125914
|
+
if (!existsSync68(absDir)) {
|
|
125899
125915
|
throw new Error(`Directory does not exist: ${absDir}`);
|
|
125900
125916
|
}
|
|
125901
125917
|
const serverResult = findServerForExtension(extension);
|
|
@@ -126156,11 +126172,11 @@ var DEFAULT_MAX_MATCHES = 500;
|
|
|
126156
126172
|
|
|
126157
126173
|
// src/tools/ast-grep/sg-cli-path.ts
|
|
126158
126174
|
import { createRequire as createRequire4 } from "module";
|
|
126159
|
-
import { dirname as
|
|
126160
|
-
import { existsSync as
|
|
126175
|
+
import { dirname as dirname22, join as join77 } from "path";
|
|
126176
|
+
import { existsSync as existsSync70, statSync as statSync9 } from "fs";
|
|
126161
126177
|
|
|
126162
126178
|
// src/tools/ast-grep/downloader.ts
|
|
126163
|
-
import { existsSync as
|
|
126179
|
+
import { existsSync as existsSync69 } from "fs";
|
|
126164
126180
|
import { join as join76 } from "path";
|
|
126165
126181
|
import { homedir as homedir14 } from "os";
|
|
126166
126182
|
import { createRequire as createRequire3 } from "module";
|
|
@@ -126212,7 +126228,7 @@ async function downloadAstGrep(version3 = DEFAULT_VERSION) {
|
|
|
126212
126228
|
const cacheDir = getCacheDir3();
|
|
126213
126229
|
const binaryName = getBinaryName3();
|
|
126214
126230
|
const binaryPath = join76(cacheDir, binaryName);
|
|
126215
|
-
if (
|
|
126231
|
+
if (existsSync69(binaryPath)) {
|
|
126216
126232
|
return binaryPath;
|
|
126217
126233
|
}
|
|
126218
126234
|
const { arch, os: os4 } = platformInfo;
|
|
@@ -126273,9 +126289,9 @@ function findSgCliPathSync() {
|
|
|
126273
126289
|
try {
|
|
126274
126290
|
const require2 = createRequire4(import.meta.url);
|
|
126275
126291
|
const cliPackageJsonPath = require2.resolve("@ast-grep/cli/package.json");
|
|
126276
|
-
const cliDirectory =
|
|
126292
|
+
const cliDirectory = dirname22(cliPackageJsonPath);
|
|
126277
126293
|
const sgPath = join77(cliDirectory, binaryName);
|
|
126278
|
-
if (
|
|
126294
|
+
if (existsSync70(sgPath) && isValidBinary(sgPath)) {
|
|
126279
126295
|
return sgPath;
|
|
126280
126296
|
}
|
|
126281
126297
|
} catch {}
|
|
@@ -126284,10 +126300,10 @@ function findSgCliPathSync() {
|
|
|
126284
126300
|
try {
|
|
126285
126301
|
const require2 = createRequire4(import.meta.url);
|
|
126286
126302
|
const packageJsonPath = require2.resolve(`${platformPackage}/package.json`);
|
|
126287
|
-
const packageDirectory =
|
|
126303
|
+
const packageDirectory = dirname22(packageJsonPath);
|
|
126288
126304
|
const astGrepBinaryName = process.platform === "win32" ? "ast-grep.exe" : "ast-grep";
|
|
126289
126305
|
const binaryPath = join77(packageDirectory, astGrepBinaryName);
|
|
126290
|
-
if (
|
|
126306
|
+
if (existsSync70(binaryPath) && isValidBinary(binaryPath)) {
|
|
126291
126307
|
return binaryPath;
|
|
126292
126308
|
}
|
|
126293
126309
|
} catch {}
|
|
@@ -126295,7 +126311,7 @@ function findSgCliPathSync() {
|
|
|
126295
126311
|
if (process.platform === "darwin") {
|
|
126296
126312
|
const homebrewPaths = ["/opt/homebrew/bin/sg", "/usr/local/bin/sg"];
|
|
126297
126313
|
for (const path7 of homebrewPaths) {
|
|
126298
|
-
if (
|
|
126314
|
+
if (existsSync70(path7) && isValidBinary(path7)) {
|
|
126299
126315
|
return path7;
|
|
126300
126316
|
}
|
|
126301
126317
|
}
|
|
@@ -126319,14 +126335,14 @@ function setSgCliPath(path7) {
|
|
|
126319
126335
|
}
|
|
126320
126336
|
// src/tools/ast-grep/cli.ts
|
|
126321
126337
|
var {spawn: spawn17 } = globalThis.Bun;
|
|
126322
|
-
import { existsSync as
|
|
126338
|
+
import { existsSync as existsSync72 } from "fs";
|
|
126323
126339
|
|
|
126324
126340
|
// src/tools/ast-grep/cli-binary-path-resolution.ts
|
|
126325
|
-
import { existsSync as
|
|
126341
|
+
import { existsSync as existsSync71 } from "fs";
|
|
126326
126342
|
var resolvedCliPath3 = null;
|
|
126327
126343
|
var initPromise3 = null;
|
|
126328
126344
|
async function getAstGrepPath() {
|
|
126329
|
-
if (resolvedCliPath3 !== null &&
|
|
126345
|
+
if (resolvedCliPath3 !== null && existsSync71(resolvedCliPath3)) {
|
|
126330
126346
|
return resolvedCliPath3;
|
|
126331
126347
|
}
|
|
126332
126348
|
if (initPromise3) {
|
|
@@ -126334,7 +126350,7 @@ async function getAstGrepPath() {
|
|
|
126334
126350
|
}
|
|
126335
126351
|
initPromise3 = (async () => {
|
|
126336
126352
|
const syncPath = findSgCliPathSync();
|
|
126337
|
-
if (syncPath &&
|
|
126353
|
+
if (syncPath && existsSync71(syncPath)) {
|
|
126338
126354
|
resolvedCliPath3 = syncPath;
|
|
126339
126355
|
setSgCliPath(syncPath);
|
|
126340
126356
|
return syncPath;
|
|
@@ -126433,7 +126449,7 @@ async function runSg(options) {
|
|
|
126433
126449
|
const paths = options.paths && options.paths.length > 0 ? options.paths : ["."];
|
|
126434
126450
|
args.push(...paths);
|
|
126435
126451
|
let cliPath = getSgCliPath();
|
|
126436
|
-
if (!cliPath || !
|
|
126452
|
+
if (!cliPath || !existsSync72(cliPath)) {
|
|
126437
126453
|
const downloadedPath = await getAstGrepPath();
|
|
126438
126454
|
if (downloadedPath) {
|
|
126439
126455
|
cliPath = downloadedPath;
|
|
@@ -126688,12 +126704,12 @@ import { resolve as resolve19 } from "path";
|
|
|
126688
126704
|
var {spawn: spawn18 } = globalThis.Bun;
|
|
126689
126705
|
|
|
126690
126706
|
// src/tools/grep/constants.ts
|
|
126691
|
-
import { existsSync as
|
|
126692
|
-
import { join as join79, dirname as
|
|
126707
|
+
import { existsSync as existsSync74 } from "fs";
|
|
126708
|
+
import { join as join79, dirname as dirname23 } from "path";
|
|
126693
126709
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
126694
126710
|
|
|
126695
126711
|
// src/tools/grep/downloader.ts
|
|
126696
|
-
import { existsSync as
|
|
126712
|
+
import { existsSync as existsSync73, readdirSync as readdirSync21 } from "fs";
|
|
126697
126713
|
import { join as join78 } from "path";
|
|
126698
126714
|
init_plugin_identity();
|
|
126699
126715
|
function findFileRecursive(dir, filename) {
|
|
@@ -126758,7 +126774,7 @@ async function downloadAndInstallRipgrep() {
|
|
|
126758
126774
|
}
|
|
126759
126775
|
const installDir = getInstallDir();
|
|
126760
126776
|
const rgPath = getRgPath();
|
|
126761
|
-
if (
|
|
126777
|
+
if (existsSync73(rgPath)) {
|
|
126762
126778
|
return rgPath;
|
|
126763
126779
|
}
|
|
126764
126780
|
ensureCacheDir(installDir);
|
|
@@ -126773,7 +126789,7 @@ async function downloadAndInstallRipgrep() {
|
|
|
126773
126789
|
await extractZip2(archivePath, installDir);
|
|
126774
126790
|
}
|
|
126775
126791
|
ensureExecutable(rgPath);
|
|
126776
|
-
if (!
|
|
126792
|
+
if (!existsSync73(rgPath)) {
|
|
126777
126793
|
throw new Error("ripgrep binary not found after extraction");
|
|
126778
126794
|
}
|
|
126779
126795
|
return rgPath;
|
|
@@ -126785,7 +126801,7 @@ async function downloadAndInstallRipgrep() {
|
|
|
126785
126801
|
}
|
|
126786
126802
|
function getInstalledRipgrepPath() {
|
|
126787
126803
|
const rgPath = getRgPath();
|
|
126788
|
-
return
|
|
126804
|
+
return existsSync73(rgPath) ? rgPath : null;
|
|
126789
126805
|
}
|
|
126790
126806
|
|
|
126791
126807
|
// src/tools/grep/constants.ts
|
|
@@ -126807,7 +126823,7 @@ function findExecutable(name) {
|
|
|
126807
126823
|
}
|
|
126808
126824
|
function getOpenCodeBundledRg() {
|
|
126809
126825
|
const execPath = process.execPath;
|
|
126810
|
-
const execDir =
|
|
126826
|
+
const execDir = dirname23(execPath);
|
|
126811
126827
|
const isWindows2 = process.platform === "win32";
|
|
126812
126828
|
const rgName = isWindows2 ? "rg.exe" : "rg";
|
|
126813
126829
|
const candidates = [
|
|
@@ -126818,7 +126834,7 @@ function getOpenCodeBundledRg() {
|
|
|
126818
126834
|
join79(execDir, "..", "libexec", rgName)
|
|
126819
126835
|
];
|
|
126820
126836
|
for (const candidate of candidates) {
|
|
126821
|
-
if (
|
|
126837
|
+
if (existsSync74(candidate)) {
|
|
126822
126838
|
return candidate;
|
|
126823
126839
|
}
|
|
126824
126840
|
}
|
|
@@ -127470,10 +127486,10 @@ Use this when a task matches an available skill's or command's description.
|
|
|
127470
127486
|
`;
|
|
127471
127487
|
// src/tools/skill/tools.ts
|
|
127472
127488
|
init_dist();
|
|
127473
|
-
import { dirname as
|
|
127489
|
+
import { dirname as dirname25 } from "path";
|
|
127474
127490
|
|
|
127475
127491
|
// src/tools/slashcommand/command-output-formatter.ts
|
|
127476
|
-
import { dirname as
|
|
127492
|
+
import { dirname as dirname24 } from "path";
|
|
127477
127493
|
async function formatLoadedCommand(command, userMessage) {
|
|
127478
127494
|
const sections = [];
|
|
127479
127495
|
sections.push(`# /${command.name} Command
|
|
@@ -127512,7 +127528,7 @@ async function formatLoadedCommand(command, userMessage) {
|
|
|
127512
127528
|
if (!content && command.lazyContentLoader) {
|
|
127513
127529
|
content = await command.lazyContentLoader.load();
|
|
127514
127530
|
}
|
|
127515
|
-
const commandDir = command.path ?
|
|
127531
|
+
const commandDir = command.path ? dirname24(command.path) : process.cwd();
|
|
127516
127532
|
const withFileReferences = await resolveFileReferencesInText(content, commandDir);
|
|
127517
127533
|
const resolvedContent = await resolveCommandsInText(withFileReferences);
|
|
127518
127534
|
let finalContent = resolvedContent.trim();
|
|
@@ -127902,7 +127918,7 @@ function createSkillTool(options = {}) {
|
|
|
127902
127918
|
if (matchedSkill.name === "git-master") {
|
|
127903
127919
|
body = injectGitMasterConfig(body, options.gitMasterConfig);
|
|
127904
127920
|
}
|
|
127905
|
-
const dir = matchedSkill.path ?
|
|
127921
|
+
const dir = matchedSkill.path ? dirname25(matchedSkill.path) : matchedSkill.resolvedPath || process.cwd();
|
|
127906
127922
|
const output = [
|
|
127907
127923
|
`## Skill: ${matchedSkill.name}`,
|
|
127908
127924
|
"",
|
|
@@ -128020,11 +128036,11 @@ Has Todos: Yes (12 items, 8 completed)
|
|
|
128020
128036
|
Has Transcript: Yes (234 entries)`;
|
|
128021
128037
|
|
|
128022
128038
|
// src/tools/session-manager/file-storage.ts
|
|
128023
|
-
import { existsSync as
|
|
128039
|
+
import { existsSync as existsSync75 } from "fs";
|
|
128024
128040
|
import { readdir, readFile } from "fs/promises";
|
|
128025
128041
|
import { join as join81 } from "path";
|
|
128026
128042
|
async function getFileMainSessions(directory) {
|
|
128027
|
-
if (!
|
|
128043
|
+
if (!existsSync75(SESSION_STORAGE))
|
|
128028
128044
|
return [];
|
|
128029
128045
|
const sessions = [];
|
|
128030
128046
|
try {
|
|
@@ -128056,7 +128072,7 @@ async function getFileMainSessions(directory) {
|
|
|
128056
128072
|
return sessions.sort((a, b) => b.time.updated - a.time.updated);
|
|
128057
128073
|
}
|
|
128058
128074
|
async function getFileAllSessions() {
|
|
128059
|
-
if (!
|
|
128075
|
+
if (!existsSync75(MESSAGE_STORAGE))
|
|
128060
128076
|
return [];
|
|
128061
128077
|
const sessions = [];
|
|
128062
128078
|
async function scanDirectory(dir) {
|
|
@@ -128085,7 +128101,7 @@ async function fileSessionExists(sessionID) {
|
|
|
128085
128101
|
}
|
|
128086
128102
|
async function getFileSessionMessages(sessionID) {
|
|
128087
128103
|
const messageDir = getMessageDir(sessionID);
|
|
128088
|
-
if (!messageDir || !
|
|
128104
|
+
if (!messageDir || !existsSync75(messageDir))
|
|
128089
128105
|
return [];
|
|
128090
128106
|
const messages = [];
|
|
128091
128107
|
try {
|
|
@@ -128121,7 +128137,7 @@ async function getFileSessionMessages(sessionID) {
|
|
|
128121
128137
|
}
|
|
128122
128138
|
async function readParts2(messageID) {
|
|
128123
128139
|
const partDir = join81(PART_STORAGE, messageID);
|
|
128124
|
-
if (!
|
|
128140
|
+
if (!existsSync75(partDir))
|
|
128125
128141
|
return [];
|
|
128126
128142
|
const parts = [];
|
|
128127
128143
|
try {
|
|
@@ -128142,7 +128158,7 @@ async function readParts2(messageID) {
|
|
|
128142
128158
|
return parts.sort((a, b) => a.id.localeCompare(b.id));
|
|
128143
128159
|
}
|
|
128144
128160
|
async function getFileSessionTodos(sessionID) {
|
|
128145
|
-
if (!
|
|
128161
|
+
if (!existsSync75(TODO_DIR2))
|
|
128146
128162
|
return [];
|
|
128147
128163
|
try {
|
|
128148
128164
|
const allFiles = await readdir(TODO_DIR2);
|
|
@@ -128169,10 +128185,10 @@ async function getFileSessionTodos(sessionID) {
|
|
|
128169
128185
|
return [];
|
|
128170
128186
|
}
|
|
128171
128187
|
async function getFileSessionTranscript(sessionID) {
|
|
128172
|
-
if (!
|
|
128188
|
+
if (!existsSync75(TRANSCRIPT_DIR2))
|
|
128173
128189
|
return 0;
|
|
128174
128190
|
const transcriptFile = join81(TRANSCRIPT_DIR2, `${sessionID}.jsonl`);
|
|
128175
|
-
if (!
|
|
128191
|
+
if (!existsSync75(transcriptFile))
|
|
128176
128192
|
return 0;
|
|
128177
128193
|
try {
|
|
128178
128194
|
const content = await readFile(transcriptFile, "utf-8");
|
|
@@ -130552,9 +130568,9 @@ async function resolveMultimodalLookerAgentMetadata(ctx) {
|
|
|
130552
130568
|
|
|
130553
130569
|
// src/tools/look-at/image-converter.ts
|
|
130554
130570
|
import * as childProcess from "child_process";
|
|
130555
|
-
import { existsSync as
|
|
130571
|
+
import { existsSync as existsSync76, mkdtempSync, readFileSync as readFileSync51, rmSync as rmSync3, unlinkSync as unlinkSync10, writeFileSync as writeFileSync18 } from "fs";
|
|
130556
130572
|
import { tmpdir as tmpdir7 } from "os";
|
|
130557
|
-
import { dirname as
|
|
130573
|
+
import { dirname as dirname26, join as join82 } from "path";
|
|
130558
130574
|
var SUPPORTED_FORMATS = new Set([
|
|
130559
130575
|
"image/jpeg",
|
|
130560
130576
|
"image/png",
|
|
@@ -130592,7 +130608,7 @@ function needsConversion(mimeType) {
|
|
|
130592
130608
|
return mimeType.startsWith("image/");
|
|
130593
130609
|
}
|
|
130594
130610
|
function convertImageToJpeg(inputPath, mimeType) {
|
|
130595
|
-
if (!
|
|
130611
|
+
if (!existsSync76(inputPath)) {
|
|
130596
130612
|
throw new Error(`File not found: ${inputPath}`);
|
|
130597
130613
|
}
|
|
130598
130614
|
const tempDir = mkdtempSync(join82(tmpdir7(), "opencode-img-"));
|
|
@@ -130606,7 +130622,7 @@ function convertImageToJpeg(inputPath, mimeType) {
|
|
|
130606
130622
|
encoding: "utf-8",
|
|
130607
130623
|
timeout: CONVERSION_TIMEOUT_MS
|
|
130608
130624
|
});
|
|
130609
|
-
if (
|
|
130625
|
+
if (existsSync76(outputPath)) {
|
|
130610
130626
|
log(`[image-converter] Converted using sips: ${outputPath}`);
|
|
130611
130627
|
return outputPath;
|
|
130612
130628
|
}
|
|
@@ -130621,7 +130637,7 @@ function convertImageToJpeg(inputPath, mimeType) {
|
|
|
130621
130637
|
encoding: "utf-8",
|
|
130622
130638
|
timeout: CONVERSION_TIMEOUT_MS
|
|
130623
130639
|
});
|
|
130624
|
-
if (
|
|
130640
|
+
if (existsSync76(outputPath)) {
|
|
130625
130641
|
log(`[image-converter] Converted using ImageMagick: ${outputPath}`);
|
|
130626
130642
|
return outputPath;
|
|
130627
130643
|
}
|
|
@@ -130634,7 +130650,7 @@ function convertImageToJpeg(inputPath, mimeType) {
|
|
|
130634
130650
|
` + ` RHEL/CentOS: sudo yum install ImageMagick`);
|
|
130635
130651
|
} catch (error92) {
|
|
130636
130652
|
try {
|
|
130637
|
-
if (
|
|
130653
|
+
if (existsSync76(outputPath)) {
|
|
130638
130654
|
unlinkSync10(outputPath);
|
|
130639
130655
|
}
|
|
130640
130656
|
} catch {}
|
|
@@ -130647,12 +130663,12 @@ function convertImageToJpeg(inputPath, mimeType) {
|
|
|
130647
130663
|
}
|
|
130648
130664
|
function cleanupConvertedImage(filePath) {
|
|
130649
130665
|
try {
|
|
130650
|
-
const tempDirectory =
|
|
130651
|
-
if (
|
|
130666
|
+
const tempDirectory = dirname26(filePath);
|
|
130667
|
+
if (existsSync76(filePath)) {
|
|
130652
130668
|
unlinkSync10(filePath);
|
|
130653
130669
|
log(`[image-converter] Cleaned up temporary file: ${filePath}`);
|
|
130654
130670
|
}
|
|
130655
|
-
if (
|
|
130671
|
+
if (existsSync76(tempDirectory)) {
|
|
130656
130672
|
rmSync3(tempDirectory, { recursive: true, force: true });
|
|
130657
130673
|
log(`[image-converter] Cleaned up temporary directory: ${tempDirectory}`);
|
|
130658
130674
|
}
|
|
@@ -130672,14 +130688,14 @@ function convertBase64ImageToJpeg(base64Data, mimeType) {
|
|
|
130672
130688
|
log(`[image-converter] Converting Base64 ${mimeType} to JPEG`);
|
|
130673
130689
|
const outputPath = convertImageToJpeg(inputPath, mimeType);
|
|
130674
130690
|
tempFiles.push(outputPath);
|
|
130675
|
-
const convertedBuffer =
|
|
130691
|
+
const convertedBuffer = readFileSync51(outputPath);
|
|
130676
130692
|
const convertedBase64 = convertedBuffer.toString("base64");
|
|
130677
130693
|
log(`[image-converter] Base64 conversion successful`);
|
|
130678
130694
|
return { base64: convertedBase64, tempFiles };
|
|
130679
130695
|
} catch (error92) {
|
|
130680
130696
|
tempFiles.forEach((file3) => {
|
|
130681
130697
|
try {
|
|
130682
|
-
if (
|
|
130698
|
+
if (existsSync76(file3))
|
|
130683
130699
|
unlinkSync10(file3);
|
|
130684
130700
|
} catch {}
|
|
130685
130701
|
});
|
|
@@ -132860,22 +132876,22 @@ function applyFallbackEntrySettings(input) {
|
|
|
132860
132876
|
// src/tools/delegate-task/subagent-discovery.ts
|
|
132861
132877
|
init_agent_display_names();
|
|
132862
132878
|
// src/features/claude-code-agent-loader/loader.ts
|
|
132863
|
-
import { existsSync as
|
|
132879
|
+
import { existsSync as existsSync79, readdirSync as readdirSync22 } from "fs";
|
|
132864
132880
|
import { join as join83 } from "path";
|
|
132865
132881
|
|
|
132866
132882
|
// src/features/claude-code-agent-loader/agent-definitions-loader.ts
|
|
132867
|
-
import { existsSync as
|
|
132883
|
+
import { existsSync as existsSync78, readFileSync as readFileSync53 } from "fs";
|
|
132868
132884
|
import { basename as basename13, extname as extname8 } from "path";
|
|
132869
132885
|
init_logger();
|
|
132870
132886
|
|
|
132871
132887
|
// src/features/claude-code-agent-loader/json-agent-loader.ts
|
|
132872
|
-
import { existsSync as
|
|
132888
|
+
import { existsSync as existsSync77, readFileSync as readFileSync52 } from "fs";
|
|
132873
132889
|
function parseJsonAgentFile(filePath, scope) {
|
|
132874
132890
|
try {
|
|
132875
|
-
if (!
|
|
132891
|
+
if (!existsSync77(filePath)) {
|
|
132876
132892
|
return null;
|
|
132877
132893
|
}
|
|
132878
|
-
const content =
|
|
132894
|
+
const content = readFileSync52(filePath, "utf-8");
|
|
132879
132895
|
const { data } = parseJsoncSafe(content);
|
|
132880
132896
|
if (!data) {
|
|
132881
132897
|
return null;
|
|
@@ -132911,10 +132927,10 @@ function parseJsonAgentFile(filePath, scope) {
|
|
|
132911
132927
|
// src/features/claude-code-agent-loader/agent-definitions-loader.ts
|
|
132912
132928
|
function parseMarkdownAgentFile(filePath, scope) {
|
|
132913
132929
|
try {
|
|
132914
|
-
if (!
|
|
132930
|
+
if (!existsSync78(filePath)) {
|
|
132915
132931
|
return null;
|
|
132916
132932
|
}
|
|
132917
|
-
const content =
|
|
132933
|
+
const content = readFileSync53(filePath, "utf-8");
|
|
132918
132934
|
const { data, body } = parseFrontmatter(content);
|
|
132919
132935
|
const fileName = basename13(filePath);
|
|
132920
132936
|
const agentName = fileName.replace(/\.md$/i, "");
|
|
@@ -132946,7 +132962,7 @@ function parseMarkdownAgentFile(filePath, scope) {
|
|
|
132946
132962
|
function loadAgentDefinitions(paths, scope) {
|
|
132947
132963
|
const result = Object.create(null);
|
|
132948
132964
|
for (const filePath of paths) {
|
|
132949
|
-
if (!
|
|
132965
|
+
if (!existsSync78(filePath)) {
|
|
132950
132966
|
log(`[agent-definitions-loader] File not found, skipping: ${filePath}`);
|
|
132951
132967
|
continue;
|
|
132952
132968
|
}
|
|
@@ -132971,7 +132987,7 @@ function loadAgentDefinitions(paths, scope) {
|
|
|
132971
132987
|
|
|
132972
132988
|
// src/features/claude-code-agent-loader/loader.ts
|
|
132973
132989
|
function loadAgentsFromDir(agentsDir, scope) {
|
|
132974
|
-
if (!
|
|
132990
|
+
if (!existsSync79(agentsDir)) {
|
|
132975
132991
|
return [];
|
|
132976
132992
|
}
|
|
132977
132993
|
const entries = readdirSync22(agentsDir, { withFileTypes: true });
|
|
@@ -133613,8 +133629,8 @@ var TaskDeleteInputSchema = exports_external.object({
|
|
|
133613
133629
|
});
|
|
133614
133630
|
|
|
133615
133631
|
// src/features/claude-tasks/storage.ts
|
|
133616
|
-
import { join as join85, dirname as
|
|
133617
|
-
import { existsSync as
|
|
133632
|
+
import { join as join85, dirname as dirname28, basename as basename14, isAbsolute as isAbsolute12 } from "path";
|
|
133633
|
+
import { existsSync as existsSync81, mkdirSync as mkdirSync16, readFileSync as readFileSync55, writeFileSync as writeFileSync19, renameSync as renameSync4, unlinkSync as unlinkSync11, readdirSync as readdirSync23 } from "fs";
|
|
133618
133634
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
133619
133635
|
function getTaskDir(config4 = {}) {
|
|
133620
133636
|
const tasksConfig = config4.bob?.tasks;
|
|
@@ -133642,16 +133658,16 @@ function resolveTaskListId(config4 = {}) {
|
|
|
133642
133658
|
return sanitizePathSegment(basename14(process.cwd()));
|
|
133643
133659
|
}
|
|
133644
133660
|
function ensureDir(dirPath) {
|
|
133645
|
-
if (!
|
|
133661
|
+
if (!existsSync81(dirPath)) {
|
|
133646
133662
|
mkdirSync16(dirPath, { recursive: true });
|
|
133647
133663
|
}
|
|
133648
133664
|
}
|
|
133649
133665
|
function readJsonSafe(filePath, schema2) {
|
|
133650
133666
|
try {
|
|
133651
|
-
if (!
|
|
133667
|
+
if (!existsSync81(filePath)) {
|
|
133652
133668
|
return null;
|
|
133653
133669
|
}
|
|
133654
|
-
const content =
|
|
133670
|
+
const content = readFileSync55(filePath, "utf-8");
|
|
133655
133671
|
const parsed = JSON.parse(content);
|
|
133656
133672
|
const result = schema2.safeParse(parsed);
|
|
133657
133673
|
if (!result.success) {
|
|
@@ -133663,7 +133679,7 @@ function readJsonSafe(filePath, schema2) {
|
|
|
133663
133679
|
}
|
|
133664
133680
|
}
|
|
133665
133681
|
function writeJsonAtomic(filePath, data) {
|
|
133666
|
-
const dir =
|
|
133682
|
+
const dir = dirname28(filePath);
|
|
133667
133683
|
ensureDir(dir);
|
|
133668
133684
|
const tempPath = `${filePath}.tmp.${Date.now()}`;
|
|
133669
133685
|
try {
|
|
@@ -133671,7 +133687,7 @@ function writeJsonAtomic(filePath, data) {
|
|
|
133671
133687
|
renameSync4(tempPath, filePath);
|
|
133672
133688
|
} catch (error92) {
|
|
133673
133689
|
try {
|
|
133674
|
-
if (
|
|
133690
|
+
if (existsSync81(tempPath)) {
|
|
133675
133691
|
unlinkSync11(tempPath);
|
|
133676
133692
|
}
|
|
133677
133693
|
} catch {}
|
|
@@ -133693,7 +133709,7 @@ function acquireLock(dirPath) {
|
|
|
133693
133709
|
};
|
|
133694
133710
|
const isStale = () => {
|
|
133695
133711
|
try {
|
|
133696
|
-
const lockContent =
|
|
133712
|
+
const lockContent = readFileSync55(lockPath, "utf-8");
|
|
133697
133713
|
const lockData = JSON.parse(lockContent);
|
|
133698
133714
|
const lockAge = Date.now() - lockData.timestamp;
|
|
133699
133715
|
return lockAge > STALE_LOCK_THRESHOLD_MS;
|
|
@@ -133731,9 +133747,9 @@ function acquireLock(dirPath) {
|
|
|
133731
133747
|
acquired: true,
|
|
133732
133748
|
release: () => {
|
|
133733
133749
|
try {
|
|
133734
|
-
if (!
|
|
133750
|
+
if (!existsSync81(lockPath))
|
|
133735
133751
|
return;
|
|
133736
|
-
const lockContent =
|
|
133752
|
+
const lockContent = readFileSync55(lockPath, "utf-8");
|
|
133737
133753
|
const lockData = JSON.parse(lockContent);
|
|
133738
133754
|
if (lockData.id !== lockId)
|
|
133739
133755
|
return;
|
|
@@ -133959,7 +133975,7 @@ Returns null if the task does not exist or the file is invalid.`,
|
|
|
133959
133975
|
// src/tools/task/task-list.ts
|
|
133960
133976
|
init_tool();
|
|
133961
133977
|
import { join as join88 } from "path";
|
|
133962
|
-
import { existsSync as
|
|
133978
|
+
import { existsSync as existsSync82, readdirSync as readdirSync24 } from "fs";
|
|
133963
133979
|
function createTaskList(config4) {
|
|
133964
133980
|
return tool({
|
|
133965
133981
|
description: `List all active tasks with summary information.
|
|
@@ -133970,7 +133986,7 @@ Returns summary format: id, subject, status, owner, blockedBy (not full descript
|
|
|
133970
133986
|
args: {},
|
|
133971
133987
|
execute: async () => {
|
|
133972
133988
|
const taskDir = getTaskDir(config4);
|
|
133973
|
-
if (!
|
|
133989
|
+
if (!existsSync82(taskDir)) {
|
|
133974
133990
|
return JSON.stringify({ tasks: [] });
|
|
133975
133991
|
}
|
|
133976
133992
|
const files = readdirSync24(taskDir).filter((f) => f.endsWith(".json") && f.startsWith("T-")).map((f) => f.replace(".json", ""));
|
|
@@ -136273,7 +136289,7 @@ function createToolGuardHooks(args) {
|
|
|
136273
136289
|
const readImageResizer = isHookEnabled("read-image-resizer") ? safeHook("read-image-resizer", () => createReadImageResizerHook(ctx)) : null;
|
|
136274
136290
|
const todoDescriptionOverride = isHookEnabled("todo-description-override") ? safeHook("todo-description-override", () => createTodoDescriptionOverrideHook()) : null;
|
|
136275
136291
|
const webfetchRedirectGuard = isHookEnabled("webfetch-redirect-guard") ? safeHook("webfetch-redirect-guard", () => createWebFetchRedirectGuardHook(ctx)) : null;
|
|
136276
|
-
const fastApply = isHookEnabled("fast-apply") ? safeHook("fast-apply", () => createFastApplyHook(pluginConfig.fast_apply ?? { enabled: false, ollama_url: "
|
|
136292
|
+
const fastApply = isHookEnabled("fast-apply") ? safeHook("fast-apply", () => createFastApplyHook(pluginConfig.fast_apply ?? { enabled: false, ollama_url: "", model: "", timeout: 30000 })) : null;
|
|
136277
136293
|
return {
|
|
136278
136294
|
commentChecker,
|
|
136279
136295
|
toolOutputTruncator,
|
|
@@ -137186,7 +137202,7 @@ function unregisterManagerForCleanup(manager) {
|
|
|
137186
137202
|
}
|
|
137187
137203
|
|
|
137188
137204
|
// src/features/background-agent/compaction-aware-message-resolver.ts
|
|
137189
|
-
import { readdirSync as readdirSync25, readFileSync as
|
|
137205
|
+
import { readdirSync as readdirSync25, readFileSync as readFileSync56 } from "fs";
|
|
137190
137206
|
import { join as join91 } from "path";
|
|
137191
137207
|
function hasFullAgentAndModel(message) {
|
|
137192
137208
|
return !!message.agent && !isCompactionAgent(message.agent) && !!message.model?.providerID && !!message.model?.modelID;
|
|
@@ -137266,7 +137282,7 @@ function findNearestMessageExcludingCompaction(messageDir, sessionID) {
|
|
|
137266
137282
|
const messages = [];
|
|
137267
137283
|
for (const file3 of files) {
|
|
137268
137284
|
try {
|
|
137269
|
-
const content =
|
|
137285
|
+
const content = readFileSync56(join91(messageDir, file3), "utf-8");
|
|
137270
137286
|
const parsed = JSON.parse(content);
|
|
137271
137287
|
if (hasCompactionPartInStorage(parsed.id) || isCompactionAgent(parsed.agent)) {
|
|
137272
137288
|
continue;
|
|
@@ -139363,8 +139379,8 @@ ${originalText}`;
|
|
|
139363
139379
|
}
|
|
139364
139380
|
}
|
|
139365
139381
|
// src/features/mcp-oauth/storage.ts
|
|
139366
|
-
import { chmodSync as chmodSync2, existsSync as
|
|
139367
|
-
import { dirname as
|
|
139382
|
+
import { chmodSync as chmodSync2, existsSync as existsSync83, mkdirSync as mkdirSync17, readFileSync as readFileSync57, renameSync as renameSync5, unlinkSync as unlinkSync12, writeFileSync as writeFileSync20 } from "fs";
|
|
139383
|
+
import { dirname as dirname29, join as join93 } from "path";
|
|
139368
139384
|
var STORAGE_FILE_NAME = "mcp-oauth.json";
|
|
139369
139385
|
function getMcpOauthStoragePath() {
|
|
139370
139386
|
return join93(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
|
|
@@ -139404,11 +139420,11 @@ function buildKey(serverHost, resource) {
|
|
|
139404
139420
|
}
|
|
139405
139421
|
function readStore() {
|
|
139406
139422
|
const filePath = getMcpOauthStoragePath();
|
|
139407
|
-
if (!
|
|
139423
|
+
if (!existsSync83(filePath)) {
|
|
139408
139424
|
return null;
|
|
139409
139425
|
}
|
|
139410
139426
|
try {
|
|
139411
|
-
const content =
|
|
139427
|
+
const content = readFileSync57(filePath, "utf-8");
|
|
139412
139428
|
return JSON.parse(content);
|
|
139413
139429
|
} catch {
|
|
139414
139430
|
return null;
|
|
@@ -139417,8 +139433,8 @@ function readStore() {
|
|
|
139417
139433
|
function writeStore(store2) {
|
|
139418
139434
|
const filePath = getMcpOauthStoragePath();
|
|
139419
139435
|
try {
|
|
139420
|
-
const dir =
|
|
139421
|
-
if (!
|
|
139436
|
+
const dir = dirname29(filePath);
|
|
139437
|
+
if (!existsSync83(dir)) {
|
|
139422
139438
|
mkdirSync17(dir, { recursive: true });
|
|
139423
139439
|
}
|
|
139424
139440
|
const tempPath = `${filePath}.tmp.${Date.now()}`;
|
|
@@ -146065,7 +146081,7 @@ class TmuxSessionManager {
|
|
|
146065
146081
|
var SESSION_TIMEOUT_MS3 = 10 * 60 * 1000;
|
|
146066
146082
|
var MIN_STABILITY_TIME_MS4 = 10 * 1000;
|
|
146067
146083
|
// src/features/claude-code-mcp-loader/loader.ts
|
|
146068
|
-
import { existsSync as
|
|
146084
|
+
import { existsSync as existsSync84, readFileSync as readFileSync58 } from "fs";
|
|
146069
146085
|
import { join as join94 } from "path";
|
|
146070
146086
|
import { homedir as homedir15 } from "os";
|
|
146071
146087
|
init_logger();
|
|
@@ -146088,7 +146104,7 @@ function getMcpConfigPaths() {
|
|
|
146088
146104
|
});
|
|
146089
146105
|
}
|
|
146090
146106
|
async function loadMcpConfigFile(filePath) {
|
|
146091
|
-
if (!
|
|
146107
|
+
if (!existsSync84(filePath)) {
|
|
146092
146108
|
return null;
|
|
146093
146109
|
}
|
|
146094
146110
|
try {
|
|
@@ -146104,10 +146120,10 @@ function getSystemMcpServerNames() {
|
|
|
146104
146120
|
const paths = getMcpConfigPaths();
|
|
146105
146121
|
const cwd = process.cwd();
|
|
146106
146122
|
for (const { path: path9 } of paths) {
|
|
146107
|
-
if (!
|
|
146123
|
+
if (!existsSync84(path9))
|
|
146108
146124
|
continue;
|
|
146109
146125
|
try {
|
|
146110
|
-
const content =
|
|
146126
|
+
const content = readFileSync58(path9, "utf-8");
|
|
146111
146127
|
const config4 = JSON.parse(content);
|
|
146112
146128
|
if (!config4?.mcpServers)
|
|
146113
146129
|
continue;
|
|
@@ -150452,7 +150468,7 @@ var researcherPromptMetadata = {
|
|
|
150452
150468
|
};
|
|
150453
150469
|
|
|
150454
150470
|
// src/agents/builtin-agents/resolve-file-uri.ts
|
|
150455
|
-
import { existsSync as
|
|
150471
|
+
import { existsSync as existsSync85, readFileSync as readFileSync59 } from "fs";
|
|
150456
150472
|
import { homedir as homedir16 } from "os";
|
|
150457
150473
|
import { isAbsolute as isAbsolute13, resolve as resolve22 } from "path";
|
|
150458
150474
|
init_logger();
|
|
@@ -150477,11 +150493,11 @@ function resolvePromptAppend(promptAppend, configDir) {
|
|
|
150477
150493
|
});
|
|
150478
150494
|
return `[WARNING: Path rejected: ${promptAppend}]`;
|
|
150479
150495
|
}
|
|
150480
|
-
if (!
|
|
150496
|
+
if (!existsSync85(filePath)) {
|
|
150481
150497
|
return `[WARNING: Could not resolve file URI: ${promptAppend}]`;
|
|
150482
150498
|
}
|
|
150483
150499
|
try {
|
|
150484
|
-
return
|
|
150500
|
+
return readFileSync59(filePath, "utf8");
|
|
150485
150501
|
} catch {
|
|
150486
150502
|
return `[WARNING: Could not read file: ${promptAppend}]`;
|
|
150487
150503
|
}
|
|
@@ -154115,6 +154131,28 @@ async function buildStrategistAgentConfig(params) {
|
|
|
154115
154131
|
return merged;
|
|
154116
154132
|
}
|
|
154117
154133
|
|
|
154134
|
+
// src/plugin/skill-discovery-config.ts
|
|
154135
|
+
var DEFAULT_SKILL_DISCOVERY = {
|
|
154136
|
+
config_sources: true,
|
|
154137
|
+
project_opencode: true,
|
|
154138
|
+
global_opencode: false,
|
|
154139
|
+
project_claude: false,
|
|
154140
|
+
global_claude: false,
|
|
154141
|
+
project_agents: false,
|
|
154142
|
+
global_agents: false
|
|
154143
|
+
};
|
|
154144
|
+
function resolveSkillDiscoveryConfig(pluginConfig) {
|
|
154145
|
+
const resolved = {
|
|
154146
|
+
...DEFAULT_SKILL_DISCOVERY,
|
|
154147
|
+
...pluginConfig.skill_discovery ?? {}
|
|
154148
|
+
};
|
|
154149
|
+
if (pluginConfig.claude_code?.skills === false) {
|
|
154150
|
+
resolved.project_claude = false;
|
|
154151
|
+
resolved.global_claude = false;
|
|
154152
|
+
}
|
|
154153
|
+
return resolved;
|
|
154154
|
+
}
|
|
154155
|
+
|
|
154118
154156
|
// src/plugin-handlers/agent-config-handler.ts
|
|
154119
154157
|
var CANONICAL_VISIBLE_AGENT_NAMES = [
|
|
154120
154158
|
"Bob",
|
|
@@ -154177,8 +154215,9 @@ async function applyAgentConfig(params) {
|
|
|
154177
154215
|
const migratedDisabledAgents = (params.pluginConfig.disabled_agents ?? []).map((agent) => {
|
|
154178
154216
|
return AGENT_NAME_MAP[agent.toLowerCase()] ?? AGENT_NAME_MAP[agent] ?? agent;
|
|
154179
154217
|
});
|
|
154180
|
-
const
|
|
154218
|
+
const discovery2 = resolveSkillDiscoveryConfig(params.pluginConfig);
|
|
154181
154219
|
const [
|
|
154220
|
+
discoveredManagedPluginSkills,
|
|
154182
154221
|
discoveredConfigSourceSkills,
|
|
154183
154222
|
discoveredUserSkills,
|
|
154184
154223
|
discoveredProjectSkills,
|
|
@@ -154187,18 +154226,20 @@ async function applyAgentConfig(params) {
|
|
|
154187
154226
|
discoveredOpencodeProjectSkills,
|
|
154188
154227
|
discoveredGlobalAgentsSkills
|
|
154189
154228
|
] = await Promise.all([
|
|
154190
|
-
|
|
154229
|
+
discoverManagedPluginSkills(),
|
|
154230
|
+
discovery2.config_sources ? discoverConfigSourceSkills({
|
|
154191
154231
|
config: params.pluginConfig.skills,
|
|
154192
154232
|
configDir: params.ctx.directory
|
|
154193
|
-
}),
|
|
154194
|
-
|
|
154195
|
-
|
|
154196
|
-
|
|
154197
|
-
discoverOpencodeGlobalSkills(),
|
|
154198
|
-
discoverOpencodeProjectSkills(params.ctx.directory),
|
|
154199
|
-
|
|
154233
|
+
}) : Promise.resolve([]),
|
|
154234
|
+
discovery2.global_claude ? discoverUserClaudeSkills() : Promise.resolve([]),
|
|
154235
|
+
discovery2.project_claude ? discoverProjectClaudeSkills(params.ctx.directory) : Promise.resolve([]),
|
|
154236
|
+
discovery2.project_agents ? discoverProjectAgentsSkills(params.ctx.directory) : Promise.resolve([]),
|
|
154237
|
+
discovery2.global_opencode ? discoverOpencodeGlobalSkills() : Promise.resolve([]),
|
|
154238
|
+
discovery2.project_opencode ? discoverOpencodeProjectSkills(params.ctx.directory) : Promise.resolve([]),
|
|
154239
|
+
discovery2.global_agents ? discoverGlobalAgentsSkills() : Promise.resolve([])
|
|
154200
154240
|
]);
|
|
154201
154241
|
const allDiscoveredSkills = [
|
|
154242
|
+
...discoveredManagedPluginSkills,
|
|
154202
154243
|
...discoveredConfigSourceSkills,
|
|
154203
154244
|
...discoveredOpencodeProjectSkills,
|
|
154204
154245
|
...discoveredProjectSkills,
|
|
@@ -154531,9 +154572,9 @@ async function applyCommandConfig(params) {
|
|
|
154531
154572
|
});
|
|
154532
154573
|
const systemCommands = params.config.command ?? {};
|
|
154533
154574
|
const includeClaudeCommands = params.pluginConfig.claude_code?.commands ?? true;
|
|
154534
|
-
const
|
|
154575
|
+
const discovery2 = resolveSkillDiscoveryConfig(params.pluginConfig);
|
|
154535
154576
|
const externalSkillPlugin = detectExternalSkillPlugin(params.ctx.directory);
|
|
154536
|
-
if (
|
|
154577
|
+
if ((discovery2.project_claude || discovery2.global_claude || discovery2.global_opencode) && externalSkillPlugin.detected) {
|
|
154537
154578
|
log(getSkillPluginConflictWarning(externalSkillPlugin.pluginName));
|
|
154538
154579
|
}
|
|
154539
154580
|
const [
|
|
@@ -154542,6 +154583,7 @@ async function applyCommandConfig(params) {
|
|
|
154542
154583
|
projectCommands,
|
|
154543
154584
|
opencodeGlobalCommands,
|
|
154544
154585
|
opencodeProjectCommands,
|
|
154586
|
+
managedPluginSkills,
|
|
154545
154587
|
userSkills,
|
|
154546
154588
|
globalAgentsSkills,
|
|
154547
154589
|
projectSkills,
|
|
@@ -154549,23 +154591,25 @@ async function applyCommandConfig(params) {
|
|
|
154549
154591
|
opencodeGlobalSkills,
|
|
154550
154592
|
opencodeProjectSkills
|
|
154551
154593
|
] = await Promise.all([
|
|
154552
|
-
discoverConfigSourceSkills({
|
|
154594
|
+
discovery2.config_sources ? discoverConfigSourceSkills({
|
|
154553
154595
|
config: params.pluginConfig.skills,
|
|
154554
154596
|
configDir: params.ctx.directory
|
|
154555
|
-
}),
|
|
154597
|
+
}) : Promise.resolve([]),
|
|
154556
154598
|
includeClaudeCommands ? loadUserCommands() : Promise.resolve({}),
|
|
154557
154599
|
includeClaudeCommands ? loadProjectCommands(params.ctx.directory) : Promise.resolve({}),
|
|
154558
154600
|
loadOpencodeGlobalCommands(),
|
|
154559
154601
|
loadOpencodeProjectCommands(params.ctx.directory),
|
|
154560
|
-
|
|
154561
|
-
|
|
154562
|
-
|
|
154563
|
-
|
|
154564
|
-
|
|
154565
|
-
|
|
154602
|
+
loadManagedPluginSkills(),
|
|
154603
|
+
discovery2.global_claude ? loadUserSkills() : Promise.resolve({}),
|
|
154604
|
+
discovery2.global_agents ? loadGlobalAgentsSkills() : Promise.resolve({}),
|
|
154605
|
+
discovery2.project_claude ? loadProjectSkills(params.ctx.directory) : Promise.resolve({}),
|
|
154606
|
+
discovery2.project_agents ? loadProjectAgentsSkills(params.ctx.directory) : Promise.resolve({}),
|
|
154607
|
+
discovery2.global_opencode ? loadOpencodeGlobalSkills() : Promise.resolve({}),
|
|
154608
|
+
discovery2.project_opencode ? loadOpencodeProjectSkills(params.ctx.directory) : Promise.resolve({})
|
|
154566
154609
|
]);
|
|
154567
154610
|
params.config.command = {
|
|
154568
154611
|
...builtinCommands,
|
|
154612
|
+
...managedPluginSkills,
|
|
154569
154613
|
...skillsToCommandDefinitionRecord(configSourceSkills),
|
|
154570
154614
|
...userCommands,
|
|
154571
154615
|
...userSkills,
|
|
@@ -154593,7 +154637,7 @@ function remapCommandAgentFields(commands2) {
|
|
|
154593
154637
|
|
|
154594
154638
|
// src/plugin-handlers/mcp-config-handler.ts
|
|
154595
154639
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
154596
|
-
import { existsSync as
|
|
154640
|
+
import { existsSync as existsSync86 } from "fs";
|
|
154597
154641
|
|
|
154598
154642
|
// src/mcp/websearch.ts
|
|
154599
154643
|
init_logger();
|
|
@@ -154625,15 +154669,6 @@ function createWebsearchConfig(config4) {
|
|
|
154625
154669
|
}
|
|
154626
154670
|
var websearch = createWebsearchConfig();
|
|
154627
154671
|
|
|
154628
|
-
// src/mcp/context7.ts
|
|
154629
|
-
var context7 = {
|
|
154630
|
-
type: "remote",
|
|
154631
|
-
url: "https://mcp.context7.com/mcp",
|
|
154632
|
-
enabled: true,
|
|
154633
|
-
headers: process.env.CONTEXT7_API_KEY ? { Authorization: `Bearer ${process.env.CONTEXT7_API_KEY}` } : undefined,
|
|
154634
|
-
oauth: false
|
|
154635
|
-
};
|
|
154636
|
-
|
|
154637
154672
|
// src/mcp/grep-app.ts
|
|
154638
154673
|
var grep_app = {
|
|
154639
154674
|
type: "remote",
|
|
@@ -154651,19 +154686,11 @@ function createBuiltinMcps(disabledMcps = [], config4) {
|
|
|
154651
154686
|
mcps.websearch = websearchConfig;
|
|
154652
154687
|
}
|
|
154653
154688
|
}
|
|
154654
|
-
if (!disabledMcps.includes("context7")) {
|
|
154655
|
-
mcps.context7 = context7;
|
|
154656
|
-
}
|
|
154657
154689
|
if (!disabledMcps.includes("grep_app")) {
|
|
154658
154690
|
mcps.grep_app = grep_app;
|
|
154659
154691
|
}
|
|
154660
154692
|
return mcps;
|
|
154661
154693
|
}
|
|
154662
|
-
// src/mcp/index.ts
|
|
154663
|
-
import { join as join96 } from "path";
|
|
154664
|
-
var __dirname = "C:\\hiai\\hiai-opencode-public\\src\\mcp";
|
|
154665
|
-
var ASSETS_DIR = join96(import.meta.dirname || __dirname, "..", "assets", "mcp");
|
|
154666
|
-
|
|
154667
154694
|
// src/shared/runtime-plugin-config.ts
|
|
154668
154695
|
function mergeRecords(base, override) {
|
|
154669
154696
|
if (!base && !override)
|
|
@@ -154763,7 +154790,7 @@ function hasUsableLocalMcpRuntime(name, entry) {
|
|
|
154763
154790
|
return false;
|
|
154764
154791
|
}
|
|
154765
154792
|
if (binary2 === "node" && typeof args[0] === "string" && args[0].endsWith(".mjs")) {
|
|
154766
|
-
if (!
|
|
154793
|
+
if (!existsSync86(args[0])) {
|
|
154767
154794
|
return false;
|
|
154768
154795
|
}
|
|
154769
154796
|
const probe2 = spawnSync5(binary2, ["--version"], {
|
|
@@ -155237,19 +155264,30 @@ async function createSkillContext(args) {
|
|
|
155237
155264
|
}
|
|
155238
155265
|
return true;
|
|
155239
155266
|
});
|
|
155240
|
-
const
|
|
155241
|
-
const [
|
|
155242
|
-
|
|
155267
|
+
const discovery2 = resolveSkillDiscoveryConfig(pluginConfig);
|
|
155268
|
+
const [
|
|
155269
|
+
managedPluginSkills,
|
|
155270
|
+
configSourceSkills,
|
|
155271
|
+
userSkills,
|
|
155272
|
+
globalSkills,
|
|
155273
|
+
projectSkills,
|
|
155274
|
+
opencodeProjectSkills,
|
|
155275
|
+
agentsProjectSkills,
|
|
155276
|
+
agentsGlobalSkills
|
|
155277
|
+
] = await Promise.all([
|
|
155278
|
+
discoverManagedPluginSkills(),
|
|
155279
|
+
discovery2.config_sources ? discoverConfigSourceSkills({
|
|
155243
155280
|
config: pluginConfig.skills,
|
|
155244
155281
|
configDir: directory
|
|
155245
|
-
}),
|
|
155246
|
-
|
|
155247
|
-
discoverOpencodeGlobalSkills(),
|
|
155248
|
-
|
|
155249
|
-
discoverOpencodeProjectSkills(directory),
|
|
155250
|
-
discoverProjectAgentsSkills(directory),
|
|
155251
|
-
discoverGlobalAgentsSkills()
|
|
155282
|
+
}) : Promise.resolve([]),
|
|
155283
|
+
discovery2.global_claude ? discoverUserClaudeSkills() : Promise.resolve([]),
|
|
155284
|
+
discovery2.global_opencode ? discoverOpencodeGlobalSkills() : Promise.resolve([]),
|
|
155285
|
+
discovery2.project_claude ? discoverProjectClaudeSkills(directory) : Promise.resolve([]),
|
|
155286
|
+
discovery2.project_opencode ? discoverOpencodeProjectSkills(directory) : Promise.resolve([]),
|
|
155287
|
+
discovery2.project_agents ? discoverProjectAgentsSkills(directory) : Promise.resolve([]),
|
|
155288
|
+
discovery2.global_agents ? discoverGlobalAgentsSkills() : Promise.resolve([])
|
|
155252
155289
|
]);
|
|
155290
|
+
const filteredManagedPluginSkills = filterProviderGatedSkills(managedPluginSkills, browserProvider);
|
|
155253
155291
|
const filteredConfigSourceSkills = filterProviderGatedSkills(configSourceSkills, browserProvider);
|
|
155254
155292
|
const filteredUserSkills = filterProviderGatedSkills(userSkills, browserProvider);
|
|
155255
155293
|
const filteredGlobalSkills = filterProviderGatedSkills(globalSkills, browserProvider);
|
|
@@ -155257,7 +155295,7 @@ async function createSkillContext(args) {
|
|
|
155257
155295
|
const filteredOpencodeProjectSkills = filterProviderGatedSkills(opencodeProjectSkills, browserProvider);
|
|
155258
155296
|
const filteredAgentsProjectSkills = filterProviderGatedSkills(agentsProjectSkills, browserProvider);
|
|
155259
155297
|
const filteredAgentsGlobalSkills = filterProviderGatedSkills(agentsGlobalSkills, browserProvider);
|
|
155260
|
-
const mergedSkills = mergeSkills(builtinSkills, pluginConfig.skills, filteredConfigSourceSkills, [...filteredUserSkills, ...filteredAgentsGlobalSkills], filteredGlobalSkills, [...filteredProjectSkills, ...filteredAgentsProjectSkills], filteredOpencodeProjectSkills, { configDir: directory });
|
|
155298
|
+
const mergedSkills = mergeSkills(builtinSkills, pluginConfig.skills, [...filteredManagedPluginSkills, ...filteredConfigSourceSkills], [...filteredUserSkills, ...filteredAgentsGlobalSkills], filteredGlobalSkills, [...filteredProjectSkills, ...filteredAgentsProjectSkills], filteredOpencodeProjectSkills, { configDir: directory });
|
|
155261
155299
|
const availableSkills = mergedSkills.map((skill2) => ({
|
|
155262
155300
|
name: skill2.name,
|
|
155263
155301
|
description: skill2.definition.description ?? "",
|
|
@@ -155747,10 +155785,10 @@ init_agent_display_names();
|
|
|
155747
155785
|
|
|
155748
155786
|
// src/plugin/ultrawork-db-model-override.ts
|
|
155749
155787
|
import { Database } from "bun:sqlite";
|
|
155750
|
-
import { join as
|
|
155751
|
-
import { existsSync as
|
|
155788
|
+
import { join as join96 } from "path";
|
|
155789
|
+
import { existsSync as existsSync87 } from "fs";
|
|
155752
155790
|
function getDbPath() {
|
|
155753
|
-
return
|
|
155791
|
+
return join96(getDataDir(), "opencode", "opencode.db");
|
|
155754
155792
|
}
|
|
155755
155793
|
var MAX_MICROTASK_RETRIES = 10;
|
|
155756
155794
|
function tryUpdateMessageModel(db, messageId, targetModel, variant) {
|
|
@@ -155827,7 +155865,7 @@ function retryViaMicrotask(db, messageId, targetModel, variant, attempt) {
|
|
|
155827
155865
|
function scheduleDeferredModelOverride(messageId, targetModel, variant) {
|
|
155828
155866
|
queueMicrotask(() => {
|
|
155829
155867
|
const dbPath = getDbPath();
|
|
155830
|
-
if (!
|
|
155868
|
+
if (!existsSync87(dbPath)) {
|
|
155831
155869
|
log("[ultrawork-db-override] DB not found, skipping deferred override");
|
|
155832
155870
|
return;
|
|
155833
155871
|
}
|
|
@@ -157169,6 +157207,163 @@ function createFirstMessageVariantGate() {
|
|
|
157169
157207
|
// src/index.ts
|
|
157170
157208
|
init_plugin_identity();
|
|
157171
157209
|
|
|
157210
|
+
// src/shared/startup-diagnostics.ts
|
|
157211
|
+
import { existsSync as existsSync88, readFileSync as readFileSync60 } from "fs";
|
|
157212
|
+
import { join as join98 } from "path";
|
|
157213
|
+
|
|
157214
|
+
// src/mcp/registry.ts
|
|
157215
|
+
import { join as join97 } from "path";
|
|
157216
|
+
function resolveAssetScript(...segments) {
|
|
157217
|
+
return join97(import.meta.dirname, "..", "assets", ...segments);
|
|
157218
|
+
}
|
|
157219
|
+
function createNpmPackageCommand(pkg, ...args) {
|
|
157220
|
+
return ["node", resolveAssetScript("runtime", "npm-package-runner.mjs"), pkg, ...args];
|
|
157221
|
+
}
|
|
157222
|
+
var HIAI_MCP_REGISTRY = {
|
|
157223
|
+
playwright: {
|
|
157224
|
+
name: "playwright",
|
|
157225
|
+
enabledByDefault: true,
|
|
157226
|
+
install: "npm",
|
|
157227
|
+
optionalEnv: ["HIAI_PLAYWRIGHT_INSTALL_BROWSERS"],
|
|
157228
|
+
config: {
|
|
157229
|
+
enabled: true,
|
|
157230
|
+
command: ["node", resolveAssetScript("mcp", "playwright.mjs")],
|
|
157231
|
+
timeout: 600000
|
|
157232
|
+
}
|
|
157233
|
+
},
|
|
157234
|
+
stitch: {
|
|
157235
|
+
name: "stitch",
|
|
157236
|
+
enabledByDefault: true,
|
|
157237
|
+
install: "remote",
|
|
157238
|
+
requiredEnv: ["STITCH_AI_API_KEY"],
|
|
157239
|
+
config: {
|
|
157240
|
+
enabled: true,
|
|
157241
|
+
type: "remote",
|
|
157242
|
+
url: "https://stitch.googleapis.com/mcp",
|
|
157243
|
+
headers: { "X-Goog-Api-Key": "{env:STITCH_AI_API_KEY}" },
|
|
157244
|
+
timeout: 600000
|
|
157245
|
+
}
|
|
157246
|
+
},
|
|
157247
|
+
"sequential-thinking": {
|
|
157248
|
+
name: "sequential-thinking",
|
|
157249
|
+
enabledByDefault: true,
|
|
157250
|
+
install: "npm",
|
|
157251
|
+
config: {
|
|
157252
|
+
enabled: true,
|
|
157253
|
+
command: createNpmPackageCommand("@modelcontextprotocol/server-sequential-thinking"),
|
|
157254
|
+
timeout: 600000
|
|
157255
|
+
}
|
|
157256
|
+
},
|
|
157257
|
+
firecrawl: {
|
|
157258
|
+
name: "firecrawl",
|
|
157259
|
+
enabledByDefault: true,
|
|
157260
|
+
install: "npm",
|
|
157261
|
+
requiredEnv: ["FIRECRAWL_API_KEY"],
|
|
157262
|
+
config: {
|
|
157263
|
+
enabled: true,
|
|
157264
|
+
command: createNpmPackageCommand("firecrawl-mcp"),
|
|
157265
|
+
timeout: 600000,
|
|
157266
|
+
environment: { FIRECRAWL_API_KEY: "{env:FIRECRAWL_API_KEY}" }
|
|
157267
|
+
}
|
|
157268
|
+
},
|
|
157269
|
+
rag: {
|
|
157270
|
+
name: "rag",
|
|
157271
|
+
enabledByDefault: true,
|
|
157272
|
+
install: "user-service",
|
|
157273
|
+
optionalEnv: ["OPENCODE_RAG_URL"],
|
|
157274
|
+
config: {
|
|
157275
|
+
enabled: true,
|
|
157276
|
+
type: "local",
|
|
157277
|
+
command: ["node", resolveAssetScript("mcp", "rag.mjs")],
|
|
157278
|
+
environment: {
|
|
157279
|
+
OPENCODE_RAG_URL: "{env:OPENCODE_RAG_URL:-http://localhost:9002/tools/search}"
|
|
157280
|
+
},
|
|
157281
|
+
timeout: 600000
|
|
157282
|
+
}
|
|
157283
|
+
},
|
|
157284
|
+
context7: {
|
|
157285
|
+
name: "context7",
|
|
157286
|
+
enabledByDefault: true,
|
|
157287
|
+
install: "remote",
|
|
157288
|
+
optionalEnv: ["CONTEXT7_API_KEY"],
|
|
157289
|
+
config: {
|
|
157290
|
+
enabled: true,
|
|
157291
|
+
type: "remote",
|
|
157292
|
+
url: "https://mcp.context7.com/mcp",
|
|
157293
|
+
headers: { "X-API-KEY": "{env:CONTEXT7_API_KEY}" },
|
|
157294
|
+
timeout: 600000
|
|
157295
|
+
}
|
|
157296
|
+
},
|
|
157297
|
+
mempalace: {
|
|
157298
|
+
name: "mempalace",
|
|
157299
|
+
enabledByDefault: true,
|
|
157300
|
+
install: "python",
|
|
157301
|
+
optionalEnv: ["MEMPALACE_PYTHON", "MEMPALACE_PALACE_PATH", "HIAI_MCP_AUTO_INSTALL"],
|
|
157302
|
+
config: {
|
|
157303
|
+
enabled: true,
|
|
157304
|
+
type: "local",
|
|
157305
|
+
command: ["node", resolveAssetScript("mcp", "mempalace.mjs"), "--palace", "./.opencode/palace"],
|
|
157306
|
+
timeout: 600000
|
|
157307
|
+
}
|
|
157308
|
+
}
|
|
157309
|
+
};
|
|
157310
|
+
|
|
157311
|
+
// src/shared/startup-diagnostics.ts
|
|
157312
|
+
init_plugin_identity();
|
|
157313
|
+
function readPlugins(configPath) {
|
|
157314
|
+
if (!existsSync88(configPath))
|
|
157315
|
+
return [];
|
|
157316
|
+
try {
|
|
157317
|
+
const content = readFileSync60(configPath, "utf-8");
|
|
157318
|
+
const parsed = parseJsoncSafe(content);
|
|
157319
|
+
return (parsed.data?.plugin ?? []).map((entry) => typeof entry === "string" ? entry : Array.isArray(entry) ? entry[0] : "").filter((entry) => typeof entry === "string" && entry.trim().length > 0);
|
|
157320
|
+
} catch {
|
|
157321
|
+
return [];
|
|
157322
|
+
}
|
|
157323
|
+
}
|
|
157324
|
+
function warnIfListPluginEntry(directory) {
|
|
157325
|
+
const globalPaths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
157326
|
+
const candidates = [
|
|
157327
|
+
join98(directory, ".opencode", "opencode.json"),
|
|
157328
|
+
join98(directory, ".opencode", "opencode.jsonc"),
|
|
157329
|
+
globalPaths.configJson,
|
|
157330
|
+
globalPaths.configJsonc
|
|
157331
|
+
];
|
|
157332
|
+
for (const configPath of candidates) {
|
|
157333
|
+
const plugins = readPlugins(configPath);
|
|
157334
|
+
if (!plugins.includes("list"))
|
|
157335
|
+
continue;
|
|
157336
|
+
console.warn(`[hiai-opencode] WARNING: ${configPath} contains plugin: ["list"].`);
|
|
157337
|
+
console.warn("[hiai-opencode] This can prevent hiai-opencode MCP servers from loading from that config scope.");
|
|
157338
|
+
console.warn(`[hiai-opencode] Update it to: plugin: ["${PLUGIN_NAME}"]`);
|
|
157339
|
+
}
|
|
157340
|
+
}
|
|
157341
|
+
function hasConfigAuthFallback(pluginConfig, envName) {
|
|
157342
|
+
if (envName === "FIRECRAWL_API_KEY")
|
|
157343
|
+
return !!pluginConfig.auth?.firecrawl?.trim();
|
|
157344
|
+
if (envName === "STITCH_AI_API_KEY")
|
|
157345
|
+
return !!pluginConfig.auth?.stitch?.trim();
|
|
157346
|
+
if (envName === "CONTEXT7_API_KEY")
|
|
157347
|
+
return !!pluginConfig.auth?.context7?.trim();
|
|
157348
|
+
return false;
|
|
157349
|
+
}
|
|
157350
|
+
function warnMissingRequiredMcpEnv(args) {
|
|
157351
|
+
const disabled = new Set(args.pluginConfig.disabled_mcps ?? []);
|
|
157352
|
+
const mcpConfig = args.platformConfig.mcp ?? {};
|
|
157353
|
+
for (const [name, entry] of Object.entries(HIAI_MCP_REGISTRY)) {
|
|
157354
|
+
if (disabled.has(name))
|
|
157355
|
+
continue;
|
|
157356
|
+
if (mcpConfig[name]?.enabled === false)
|
|
157357
|
+
continue;
|
|
157358
|
+
if (!entry.requiredEnv || entry.requiredEnv.length === 0)
|
|
157359
|
+
continue;
|
|
157360
|
+
const missing = entry.requiredEnv.filter((envName) => !process.env[envName]?.trim() && !hasConfigAuthFallback(args.pluginConfig, envName));
|
|
157361
|
+
if (missing.length === 0)
|
|
157362
|
+
continue;
|
|
157363
|
+
console.warn(`[hiai-opencode] MCP "${name}" is enabled but missing required env: ${missing.join(", ")}.` + " The plugin will continue to load; set the key or disable this MCP in hiai-opencode.json.");
|
|
157364
|
+
}
|
|
157365
|
+
}
|
|
157366
|
+
|
|
157172
157367
|
// src/internals/plugins/subtask2/core/state.ts
|
|
157173
157368
|
var configs = {};
|
|
157174
157369
|
var pluginConfig = { replace_generic: true };
|
|
@@ -157484,7 +157679,7 @@ function resolveResultReferences(text, sessionID) {
|
|
|
157484
157679
|
|
|
157485
157680
|
// src/internals/plugins/subtask2/utils/config.ts
|
|
157486
157681
|
import { mkdirSync as mkdirSync18 } from "fs";
|
|
157487
|
-
import { dirname as
|
|
157682
|
+
import { dirname as dirname30, join as join99 } from "path";
|
|
157488
157683
|
|
|
157489
157684
|
// src/internals/plugins/subtask2/utils/prompts.ts
|
|
157490
157685
|
var DEFAULT_RETURN_PROMPT = "Review, challenge and verify the task tool output above against the codebase. Then validate or revise it, before continuing with the next logical step.";
|
|
@@ -157550,15 +157745,15 @@ async function getAutoWorkflowPrompt() {
|
|
|
157550
157745
|
var AUTO_WORKFLOW_PROMPT = AUTO_WORKFLOW_PROMPT_TEMPLATE.replace(README_PLACEHOLDER, "[Use getAutoWorkflowPrompt() to get full documentation]");
|
|
157551
157746
|
|
|
157552
157747
|
// src/internals/plugins/subtask2/utils/config.ts
|
|
157553
|
-
var CONFIG_PATH =
|
|
157748
|
+
var CONFIG_PATH = join99(getOpenCodeConfigDir({ binary: "opencode" }), "subtask2.jsonc");
|
|
157554
157749
|
var cachedReadmeContent = null;
|
|
157555
157750
|
async function loadReadmeContent() {
|
|
157556
157751
|
if (cachedReadmeContent !== null) {
|
|
157557
157752
|
return cachedReadmeContent;
|
|
157558
157753
|
}
|
|
157559
157754
|
try {
|
|
157560
|
-
const pluginRoot =
|
|
157561
|
-
const readmePath =
|
|
157755
|
+
const pluginRoot = join99(dirname30(import.meta.path), "..", "..");
|
|
157756
|
+
const readmePath = join99(pluginRoot, "README.md");
|
|
157562
157757
|
const file3 = Bun.file(readmePath);
|
|
157563
157758
|
if (await file3.exists()) {
|
|
157564
157759
|
cachedReadmeContent = await file3.text();
|
|
@@ -157593,7 +157788,7 @@ async function loadConfig2() {
|
|
|
157593
157788
|
}
|
|
157594
157789
|
}
|
|
157595
157790
|
} catch {}
|
|
157596
|
-
mkdirSync18(
|
|
157791
|
+
mkdirSync18(dirname30(CONFIG_PATH), { recursive: true });
|
|
157597
157792
|
await Bun.write(CONFIG_PATH, `{
|
|
157598
157793
|
// Replace OpenCode's generic "Summarize..." prompt when no return is specified
|
|
157599
157794
|
"replace_generic": true,
|
|
@@ -157665,7 +157860,7 @@ function clearLog() {
|
|
|
157665
157860
|
}
|
|
157666
157861
|
|
|
157667
157862
|
// src/internals/plugins/subtask2/commands/manifest.ts
|
|
157668
|
-
import { join as
|
|
157863
|
+
import { join as join101 } from "path";
|
|
157669
157864
|
|
|
157670
157865
|
// src/internals/plugins/subtask2/parsing/frontmatter.ts
|
|
157671
157866
|
var import_yaml = __toESM(require_dist2(), 1);
|
|
@@ -157921,8 +158116,8 @@ function parseAutoWorkflowOutput(text) {
|
|
|
157921
158116
|
async function buildManifest() {
|
|
157922
158117
|
const manifest = {};
|
|
157923
158118
|
const dirs = [
|
|
157924
|
-
|
|
157925
|
-
|
|
158119
|
+
join101(getOpenCodeConfigDir({ binary: "opencode" }), "command"),
|
|
158120
|
+
join101(Bun.env.PWD ?? ".", ".opencode", "command")
|
|
157926
158121
|
];
|
|
157927
158122
|
for (const dir of dirs) {
|
|
157928
158123
|
try {
|
|
@@ -158085,11 +158280,11 @@ async function resolveTurnReferences(text, sessionID) {
|
|
|
158085
158280
|
}
|
|
158086
158281
|
|
|
158087
158282
|
// src/internals/plugins/subtask2/commands/loader.ts
|
|
158088
|
-
import { join as
|
|
158283
|
+
import { join as join102 } from "path";
|
|
158089
158284
|
async function loadCommandFile(name) {
|
|
158090
158285
|
const dirs = [
|
|
158091
|
-
|
|
158092
|
-
|
|
158286
|
+
join102(getOpenCodeConfigDir({ binary: "opencode" }), "command"),
|
|
158287
|
+
join102(Bun.env.PWD ?? ".", ".opencode", "command")
|
|
158093
158288
|
];
|
|
158094
158289
|
for (const dir of dirs) {
|
|
158095
158290
|
const directPath = `${dir}/${name}.md`;
|
|
@@ -159369,14 +159564,14 @@ init_websearch_cited();
|
|
|
159369
159564
|
// src/features/builtin-skills/materialize.ts
|
|
159370
159565
|
import {
|
|
159371
159566
|
cpSync,
|
|
159372
|
-
existsSync as
|
|
159567
|
+
existsSync as existsSync90,
|
|
159373
159568
|
mkdirSync as mkdirSync20,
|
|
159374
159569
|
readdirSync as readdirSync26,
|
|
159375
|
-
readFileSync as
|
|
159570
|
+
readFileSync as readFileSync61,
|
|
159376
159571
|
rmSync as rmSync4,
|
|
159377
159572
|
writeFileSync as writeFileSync22
|
|
159378
159573
|
} from "fs";
|
|
159379
|
-
import { join as
|
|
159574
|
+
import { join as join103 } from "path";
|
|
159380
159575
|
var GENERATED_MARKER = "<!-- Generated by hiai-opencode builtin skill materializer. -->";
|
|
159381
159576
|
var MANAGED_SKILL_METADATA = ".hiai-skill.json";
|
|
159382
159577
|
var LEGACY_MANAGED_DIR_MARKER = ".hiai-plugin-skill";
|
|
@@ -159403,10 +159598,10 @@ function buildSkillFrontmatter(skill2) {
|
|
|
159403
159598
|
`);
|
|
159404
159599
|
}
|
|
159405
159600
|
function shouldWriteSkillFile(skillFilePath) {
|
|
159406
|
-
if (!
|
|
159601
|
+
if (!existsSync90(skillFilePath))
|
|
159407
159602
|
return true;
|
|
159408
159603
|
try {
|
|
159409
|
-
const existing =
|
|
159604
|
+
const existing = readFileSync61(skillFilePath, "utf-8");
|
|
159410
159605
|
return existing.includes(GENERATED_MARKER);
|
|
159411
159606
|
} catch {
|
|
159412
159607
|
return false;
|
|
@@ -159414,10 +159609,10 @@ function shouldWriteSkillFile(skillFilePath) {
|
|
|
159414
159609
|
}
|
|
159415
159610
|
function getSkillLayout() {
|
|
159416
159611
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
159417
|
-
const assembledSkillsDir =
|
|
159418
|
-
const sourceRootDir =
|
|
159419
|
-
const builtinSourceDir =
|
|
159420
|
-
const pluginSourceDir =
|
|
159612
|
+
const assembledSkillsDir = join103(configDir, "skills");
|
|
159613
|
+
const sourceRootDir = join103(configDir, ".hiai", "skills");
|
|
159614
|
+
const builtinSourceDir = join103(sourceRootDir, "builtin");
|
|
159615
|
+
const pluginSourceDir = join103(sourceRootDir, "plugin");
|
|
159421
159616
|
mkdirSync20(assembledSkillsDir, { recursive: true });
|
|
159422
159617
|
mkdirSync20(builtinSourceDir, { recursive: true });
|
|
159423
159618
|
mkdirSync20(pluginSourceDir, { recursive: true });
|
|
@@ -159430,31 +159625,31 @@ function getSkillLayout() {
|
|
|
159430
159625
|
};
|
|
159431
159626
|
}
|
|
159432
159627
|
function writeManagedSkillMetadata(targetDir, metadata) {
|
|
159433
|
-
writeFileSync22(
|
|
159628
|
+
writeFileSync22(join103(targetDir, MANAGED_SKILL_METADATA), `${JSON.stringify(metadata, null, 2)}
|
|
159434
159629
|
`, "utf-8");
|
|
159435
159630
|
}
|
|
159436
159631
|
function readManagedSkillMetadata(targetDir) {
|
|
159437
|
-
const metadataPath =
|
|
159438
|
-
if (!
|
|
159632
|
+
const metadataPath = join103(targetDir, MANAGED_SKILL_METADATA);
|
|
159633
|
+
if (!existsSync90(metadataPath)) {
|
|
159439
159634
|
return null;
|
|
159440
159635
|
}
|
|
159441
159636
|
try {
|
|
159442
|
-
return JSON.parse(
|
|
159637
|
+
return JSON.parse(readFileSync61(metadataPath, "utf-8"));
|
|
159443
159638
|
} catch {
|
|
159444
159639
|
return null;
|
|
159445
159640
|
}
|
|
159446
159641
|
}
|
|
159447
159642
|
function isLegacyManagedSkillDir(targetDir, origin) {
|
|
159448
|
-
if (origin === "plugin" &&
|
|
159643
|
+
if (origin === "plugin" && existsSync90(join103(targetDir, LEGACY_MANAGED_DIR_MARKER))) {
|
|
159449
159644
|
return true;
|
|
159450
159645
|
}
|
|
159451
159646
|
if (origin === "builtin") {
|
|
159452
|
-
const skillFilePath =
|
|
159453
|
-
if (!
|
|
159647
|
+
const skillFilePath = join103(targetDir, "SKILL.md");
|
|
159648
|
+
if (!existsSync90(skillFilePath)) {
|
|
159454
159649
|
return false;
|
|
159455
159650
|
}
|
|
159456
159651
|
try {
|
|
159457
|
-
return
|
|
159652
|
+
return readFileSync61(skillFilePath, "utf-8").includes(GENERATED_MARKER);
|
|
159458
159653
|
} catch {
|
|
159459
159654
|
return false;
|
|
159460
159655
|
}
|
|
@@ -159462,7 +159657,7 @@ function isLegacyManagedSkillDir(targetDir, origin) {
|
|
|
159462
159657
|
return false;
|
|
159463
159658
|
}
|
|
159464
159659
|
function shouldSyncManagedSkillDir(targetDir, origin) {
|
|
159465
|
-
if (!
|
|
159660
|
+
if (!existsSync90(targetDir))
|
|
159466
159661
|
return true;
|
|
159467
159662
|
const metadata = readManagedSkillMetadata(targetDir);
|
|
159468
159663
|
if (metadata?.generatedBy === "hiai-opencode" && metadata.origin === origin) {
|
|
@@ -159478,7 +159673,7 @@ function shouldCleanupManagedSkillDir(targetDir, origin) {
|
|
|
159478
159673
|
return isLegacyManagedSkillDir(targetDir, origin);
|
|
159479
159674
|
}
|
|
159480
159675
|
function cleanupRemovedManagedSkillDirs(rootDir, origin, expectedSkillNames) {
|
|
159481
|
-
if (!
|
|
159676
|
+
if (!existsSync90(rootDir)) {
|
|
159482
159677
|
return;
|
|
159483
159678
|
}
|
|
159484
159679
|
for (const entry of readdirSync26(rootDir, { withFileTypes: true })) {
|
|
@@ -159486,15 +159681,15 @@ function cleanupRemovedManagedSkillDirs(rootDir, origin, expectedSkillNames) {
|
|
|
159486
159681
|
continue;
|
|
159487
159682
|
if (expectedSkillNames.has(entry.name))
|
|
159488
159683
|
continue;
|
|
159489
|
-
const targetDir =
|
|
159684
|
+
const targetDir = join103(rootDir, entry.name);
|
|
159490
159685
|
if (shouldCleanupManagedSkillDir(targetDir, origin)) {
|
|
159491
159686
|
rmSync4(targetDir, { recursive: true, force: true });
|
|
159492
159687
|
}
|
|
159493
159688
|
}
|
|
159494
159689
|
}
|
|
159495
159690
|
function writeSkillRegistry(configDir, entries) {
|
|
159496
|
-
const registryDir =
|
|
159497
|
-
const assembledSkillsDir =
|
|
159691
|
+
const registryDir = join103(configDir, ".hiai");
|
|
159692
|
+
const assembledSkillsDir = join103(configDir, "skills");
|
|
159498
159693
|
mkdirSync20(registryDir, { recursive: true });
|
|
159499
159694
|
mkdirSync20(assembledSkillsDir, { recursive: true });
|
|
159500
159695
|
const sortedEntries = [...entries].sort((left, right) => left.name.localeCompare(right.name));
|
|
@@ -159508,12 +159703,12 @@ function writeSkillRegistry(configDir, entries) {
|
|
|
159508
159703
|
},
|
|
159509
159704
|
layout: {
|
|
159510
159705
|
assembledSkillsDir,
|
|
159511
|
-
builtinSourceDir:
|
|
159512
|
-
pluginSourceDir:
|
|
159706
|
+
builtinSourceDir: join103(registryDir, "skills", "builtin"),
|
|
159707
|
+
pluginSourceDir: join103(registryDir, "skills", "plugin")
|
|
159513
159708
|
},
|
|
159514
159709
|
entries: sortedEntries
|
|
159515
159710
|
};
|
|
159516
|
-
writeFileSync22(
|
|
159711
|
+
writeFileSync22(join103(registryDir, "skill-registry.json"), `${JSON.stringify(payload, null, 2)}
|
|
159517
159712
|
`, "utf-8");
|
|
159518
159713
|
const readme = [
|
|
159519
159714
|
"# Hiai Skill Layout",
|
|
@@ -159528,16 +159723,16 @@ function writeSkillRegistry(configDir, entries) {
|
|
|
159528
159723
|
""
|
|
159529
159724
|
].join(`
|
|
159530
159725
|
`);
|
|
159531
|
-
writeFileSync22(
|
|
159726
|
+
writeFileSync22(join103(assembledSkillsDir, "README.md"), readme, "utf-8");
|
|
159532
159727
|
}
|
|
159533
159728
|
function materializeBuiltinSkills(skills) {
|
|
159534
159729
|
const { assembledSkillsDir, builtinSourceDir } = getSkillLayout();
|
|
159535
159730
|
const expectedSkillNames = new Set(skills.map((skill2) => skill2.name));
|
|
159536
159731
|
for (const skill2 of skills) {
|
|
159537
|
-
const sourceSkillDir =
|
|
159538
|
-
const sourceSkillFilePath =
|
|
159539
|
-
const assembledSkillDir =
|
|
159540
|
-
const assembledSkillFilePath =
|
|
159732
|
+
const sourceSkillDir = join103(builtinSourceDir, skill2.name);
|
|
159733
|
+
const sourceSkillFilePath = join103(sourceSkillDir, "SKILL.md");
|
|
159734
|
+
const assembledSkillDir = join103(assembledSkillsDir, skill2.name);
|
|
159735
|
+
const assembledSkillFilePath = join103(assembledSkillDir, "SKILL.md");
|
|
159541
159736
|
const content = buildSkillFrontmatter(skill2);
|
|
159542
159737
|
mkdirSync20(sourceSkillDir, { recursive: true });
|
|
159543
159738
|
mkdirSync20(assembledSkillDir, { recursive: true });
|
|
@@ -159565,8 +159760,8 @@ function materializeBuiltinSkills(skills) {
|
|
|
159565
159760
|
cleanupRemovedManagedSkillDirs(assembledSkillsDir, "builtin", expectedSkillNames);
|
|
159566
159761
|
}
|
|
159567
159762
|
function materializePluginSkillDirectories(pluginRootDir) {
|
|
159568
|
-
const sourceSkillsDir =
|
|
159569
|
-
if (!
|
|
159763
|
+
const sourceSkillsDir = join103(pluginRootDir, "skills");
|
|
159764
|
+
if (!existsSync90(sourceSkillsDir)) {
|
|
159570
159765
|
return;
|
|
159571
159766
|
}
|
|
159572
159767
|
const { assembledSkillsDir, pluginSourceDir, configDir } = getSkillLayout();
|
|
@@ -159578,9 +159773,9 @@ function materializePluginSkillDirectories(pluginRootDir) {
|
|
|
159578
159773
|
if (entry.name === "tmp")
|
|
159579
159774
|
continue;
|
|
159580
159775
|
expectedSkillNames.add(entry.name);
|
|
159581
|
-
const sourceDir =
|
|
159582
|
-
const mirroredSourceDir =
|
|
159583
|
-
const assembledDir =
|
|
159776
|
+
const sourceDir = join103(sourceSkillsDir, entry.name);
|
|
159777
|
+
const mirroredSourceDir = join103(pluginSourceDir, entry.name);
|
|
159778
|
+
const assembledDir = join103(assembledSkillsDir, entry.name);
|
|
159584
159779
|
if (!shouldSyncManagedSkillDir(mirroredSourceDir, "plugin") || !shouldSyncManagedSkillDir(assembledDir, "plugin")) {
|
|
159585
159780
|
continue;
|
|
159586
159781
|
}
|
|
@@ -159614,7 +159809,7 @@ function materializePluginSkillDirectories(pluginRootDir) {
|
|
|
159614
159809
|
for (const builtinEntry of readdirSync26(assembledSkillsDir, { withFileTypes: true })) {
|
|
159615
159810
|
if (!builtinEntry.isDirectory())
|
|
159616
159811
|
continue;
|
|
159617
|
-
const assembledDir =
|
|
159812
|
+
const assembledDir = join103(assembledSkillsDir, builtinEntry.name);
|
|
159618
159813
|
const metadata = readManagedSkillMetadata(assembledDir);
|
|
159619
159814
|
if (metadata?.generatedBy !== "hiai-opencode" || metadata.origin !== "builtin") {
|
|
159620
159815
|
continue;
|
|
@@ -159637,10 +159832,11 @@ function configureBundledBunPtyLibrary() {
|
|
|
159637
159832
|
}
|
|
159638
159833
|
const libraryName = process.platform === "win32" ? "rust_pty.dll" : process.platform === "darwin" ? process.arch === "arm64" ? "librust_pty_arm64.dylib" : "librust_pty.dylib" : process.arch === "arm64" ? "librust_pty_arm64.so" : "librust_pty.so";
|
|
159639
159834
|
const candidates = [
|
|
159640
|
-
|
|
159641
|
-
|
|
159835
|
+
join105(import.meta.dirname, "..", "node_modules", "bun-pty", "rust-pty", "target", "release", libraryName),
|
|
159836
|
+
join105(import.meta.dirname, "..", "..", "bun-pty", "rust-pty", "target", "release", libraryName),
|
|
159837
|
+
join105(import.meta.dirname, "..", "..", "..", "bun-pty", "rust-pty", "target", "release", libraryName)
|
|
159642
159838
|
];
|
|
159643
|
-
const resolved = candidates.find((candidate) =>
|
|
159839
|
+
const resolved = candidates.find((candidate) => existsSync92(candidate));
|
|
159644
159840
|
if (resolved) {
|
|
159645
159841
|
process.env.BUN_PTY_LIB = resolved;
|
|
159646
159842
|
}
|
|
@@ -159649,6 +159845,7 @@ var HiaiOpenCodePlugin = async (ctx) => {
|
|
|
159649
159845
|
log("[HiaiOpenCodePlugin] ENTRY - plugin loading", {
|
|
159650
159846
|
directory: ctx.directory
|
|
159651
159847
|
});
|
|
159848
|
+
warnIfListPluginEntry(ctx.directory);
|
|
159652
159849
|
const skillPluginCheck = detectExternalSkillPlugin(ctx.directory);
|
|
159653
159850
|
if (skillPluginCheck.detected && skillPluginCheck.pluginName) {
|
|
159654
159851
|
console.warn(getSkillPluginConflictWarning(skillPluginCheck.pluginName));
|
|
@@ -159657,11 +159854,15 @@ var HiaiOpenCodePlugin = async (ctx) => {
|
|
|
159657
159854
|
await activePluginDispose?.();
|
|
159658
159855
|
const internalConfig = loadConfig(ctx.directory);
|
|
159659
159856
|
const pluginConfig2 = hydratePluginConfigWithPlatformDefaults(loadPluginConfig(ctx.directory, ctx), internalConfig);
|
|
159857
|
+
warnMissingRequiredMcpEnv({
|
|
159858
|
+
pluginConfig: pluginConfig2,
|
|
159859
|
+
platformConfig: internalConfig
|
|
159860
|
+
});
|
|
159660
159861
|
materializeBuiltinSkills(createBuiltinSkills({
|
|
159661
159862
|
browserProvider: pluginConfig2.browser_automation_engine?.provider ?? "playwright",
|
|
159662
159863
|
disabledSkills: new Set(pluginConfig2.disabled_skills ?? [])
|
|
159663
159864
|
}));
|
|
159664
|
-
materializePluginSkillDirectories(
|
|
159865
|
+
materializePluginSkillDirectories(join105(import.meta.dirname, ".."));
|
|
159665
159866
|
const { initializeModelRequirements: initializeModelRequirements2 } = await Promise.resolve().then(() => (init_model_requirements(), exports_model_requirements));
|
|
159666
159867
|
initializeModelRequirements2(internalConfig);
|
|
159667
159868
|
const { initializeModelHeuristics: initializeModelHeuristics2 } = await Promise.resolve().then(() => (init_model_capability_heuristics(), exports_model_capability_heuristics));
|
|
@@ -159761,30 +159962,25 @@ var HiaiOpenCodePlugin = async (ctx) => {
|
|
|
159761
159962
|
auth: {
|
|
159762
159963
|
provider: "hiai-opencode",
|
|
159763
159964
|
methods: [
|
|
159764
|
-
{ type: "api", label: "Google API key" }
|
|
159765
|
-
{ type: "api", label: "OpenAI API key" },
|
|
159766
|
-
{ type: "api", label: "OpenRouter API key" }
|
|
159965
|
+
{ type: "api", label: "Google Search API key" }
|
|
159767
159966
|
],
|
|
159768
159967
|
loader: async (getAuth) => {
|
|
159769
159968
|
const authData = await getAuth();
|
|
159770
159969
|
const { registerGetAuth: registerGetAuth2, GOOGLE_PROVIDER_ID: GOOGLE_PROVIDER_ID2, OPENAI_PROVIDER_ID: OPENAI_PROVIDER_ID2, OPENROUTER_PROVIDER_ID: OPENROUTER_PROVIDER_ID2 } = await Promise.resolve().then(() => (init_websearch_cited(), exports_websearch_cited));
|
|
159771
|
-
const
|
|
159772
|
-
const fromAuth = authData[label];
|
|
159773
|
-
if (fromAuth)
|
|
159774
|
-
return fromAuth;
|
|
159970
|
+
const getConfiguredKey = (configKey) => {
|
|
159775
159971
|
if (configKey)
|
|
159776
159972
|
return resolveEnvVars(configKey);
|
|
159777
159973
|
return;
|
|
159778
159974
|
};
|
|
159779
|
-
const googleKey =
|
|
159780
|
-
const openaiKey =
|
|
159781
|
-
const openRouterKey =
|
|
159975
|
+
const googleKey = authData["Google Search API key"] || getConfiguredKey(internalConfig.auth?.googleSearch);
|
|
159976
|
+
const openaiKey = getConfiguredKey(internalConfig.auth?.openai);
|
|
159977
|
+
const openRouterKey = getConfiguredKey(internalConfig.auth?.openrouter);
|
|
159782
159978
|
if (googleKey)
|
|
159783
|
-
registerGetAuth2(GOOGLE_PROVIDER_ID2, () => Promise.resolve(googleKey));
|
|
159979
|
+
registerGetAuth2(GOOGLE_PROVIDER_ID2, () => Promise.resolve({ type: "api", key: googleKey }));
|
|
159784
159980
|
if (openaiKey)
|
|
159785
|
-
registerGetAuth2(OPENAI_PROVIDER_ID2, () => Promise.resolve(openaiKey));
|
|
159981
|
+
registerGetAuth2(OPENAI_PROVIDER_ID2, () => Promise.resolve({ type: "api", key: openaiKey }));
|
|
159786
159982
|
if (openRouterKey)
|
|
159787
|
-
registerGetAuth2(OPENROUTER_PROVIDER_ID2, () => Promise.resolve(openRouterKey));
|
|
159983
|
+
registerGetAuth2(OPENROUTER_PROVIDER_ID2, () => Promise.resolve({ type: "api", key: openRouterKey }));
|
|
159788
159984
|
return {};
|
|
159789
159985
|
}
|
|
159790
159986
|
},
|