@hiai-gg/hiai-opencode 0.1.3 → 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 +14 -18
- package/AGENTS.md +75 -23
- package/ARCHITECTURE.md +11 -14
- package/LICENSE.md +1 -0
- package/README.md +177 -94
- package/assets/cli/hiai-opencode.mjs +276 -0
- package/assets/mcp/playwright.mjs +7 -0
- package/config/hiai-opencode.schema.json +113 -1
- package/dist/config/defaults.d.ts +0 -3
- package/dist/config/index.d.ts +0 -1
- package/dist/config/platform-schema.d.ts +70 -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 +692 -541
- package/dist/plugin/skill-discovery-config.d.ts +4 -0
- package/dist/shared/startup-diagnostics.d.ts +6 -0
- package/hiai-opencode.json +191 -35
- package/package.json +4 -1
- package/src/agents/AGENTS.md +3 -4
- package/src/config/defaults.ts +60 -81
- package/src/config/index.ts +0 -1
- package/src/config/platform-schema.ts +17 -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 +14 -13
- 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
|
|
@@ -114235,6 +114269,17 @@ var SkillsConfigSchema = exports_external.union([
|
|
|
114235
114269
|
}).catchall(SkillEntrySchema)
|
|
114236
114270
|
]);
|
|
114237
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
|
+
|
|
114238
114283
|
// src/config/schema/bob.ts
|
|
114239
114284
|
var BobTasksConfigSchema = exports_external.object({
|
|
114240
114285
|
storage_path: exports_external.string().optional(),
|
|
@@ -114293,7 +114338,8 @@ var AuthConfigSchema = exports_external.object({
|
|
|
114293
114338
|
openai: exports_external.string().optional(),
|
|
114294
114339
|
openrouter: exports_external.string().optional(),
|
|
114295
114340
|
stitch: exports_external.string().optional(),
|
|
114296
|
-
firecrawl: exports_external.string().optional()
|
|
114341
|
+
firecrawl: exports_external.string().optional(),
|
|
114342
|
+
context7: exports_external.string().optional()
|
|
114297
114343
|
}).optional();
|
|
114298
114344
|
var HiaiOpenCodeConfigSchema = exports_external.object({
|
|
114299
114345
|
$schema: exports_external.string().optional(),
|
|
@@ -114317,6 +114363,7 @@ var HiaiOpenCodeConfigSchema = exports_external.object({
|
|
|
114317
114363
|
experimental: ExperimentalConfigSchema.optional(),
|
|
114318
114364
|
auto_update: exports_external.boolean().optional(),
|
|
114319
114365
|
skills: SkillsConfigSchema.optional(),
|
|
114366
|
+
skill_discovery: SkillDiscoveryConfigSchema.optional(),
|
|
114320
114367
|
ralph_loop: RalphLoopConfigSchema.optional(),
|
|
114321
114368
|
runtime_fallback: exports_external.union([exports_external.boolean(), RuntimeFallbackConfigSchema]).optional(),
|
|
114322
114369
|
background_task: BackgroundTaskConfigSchema.optional(),
|
|
@@ -116004,6 +116051,44 @@ If any issues are found during critical review:
|
|
|
116004
116051
|
- ALWAYS preserve test coverage
|
|
116005
116052
|
- If uncertain about a change, err on the side of keeping the original code`;
|
|
116006
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
|
+
|
|
116007
116092
|
// src/features/builtin-commands/commands.ts
|
|
116008
116093
|
function resolveStartWorkAgent(options) {
|
|
116009
116094
|
if (options?.useRegisteredAgents) {
|
|
@@ -116107,6 +116192,12 @@ Timestamp: $TIMESTAMP
|
|
|
116107
116192
|
$ARGUMENTS
|
|
116108
116193
|
</user-request>`,
|
|
116109
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>`
|
|
116110
116201
|
}
|
|
116111
116202
|
};
|
|
116112
116203
|
}
|
|
@@ -120443,8 +120534,8 @@ import * as fs12 from "fs";
|
|
|
120443
120534
|
import * as path6 from "path";
|
|
120444
120535
|
|
|
120445
120536
|
// src/config/loader.ts
|
|
120446
|
-
import { existsSync as
|
|
120447
|
-
import { join as
|
|
120537
|
+
import { existsSync as existsSync57, readFileSync as readFileSync43 } from "fs";
|
|
120538
|
+
import { join as join66 } from "path";
|
|
120448
120539
|
|
|
120449
120540
|
// src/config/platform-schema.ts
|
|
120450
120541
|
var AgentConfigSchema = exports_external.object({
|
|
@@ -120499,6 +120590,15 @@ var SkillsConfigSchema2 = exports_external.object({
|
|
|
120499
120590
|
enabled: exports_external.boolean().optional(),
|
|
120500
120591
|
disabled: exports_external.array(exports_external.string()).optional()
|
|
120501
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
|
+
});
|
|
120502
120602
|
var PermissionsConfigSchema = exports_external.object({
|
|
120503
120603
|
read: exports_external.record(exports_external.string(), exports_external.string()).optional(),
|
|
120504
120604
|
edit: exports_external.record(exports_external.string(), exports_external.string()).optional(),
|
|
@@ -120530,8 +120630,8 @@ var AuthKeysSchema = exports_external.object({
|
|
|
120530
120630
|
});
|
|
120531
120631
|
var OllamaConfigSchema = exports_external.object({
|
|
120532
120632
|
enabled: exports_external.boolean().default(false),
|
|
120533
|
-
model: exports_external.string().default("
|
|
120534
|
-
baseUrl: exports_external.string().default("
|
|
120633
|
+
model: exports_external.string().default(""),
|
|
120634
|
+
baseUrl: exports_external.string().default(""),
|
|
120535
120635
|
purpose: exports_external.enum(["verification", "helper", "fallback"]).default("helper")
|
|
120536
120636
|
});
|
|
120537
120637
|
var ModelFamilySchema = exports_external.object({
|
|
@@ -120560,6 +120660,8 @@ var AgentsConfigSchema = exports_external.object({
|
|
|
120560
120660
|
zoe: AgentConfigSchema.optional(),
|
|
120561
120661
|
build: AgentConfigSchema.optional(),
|
|
120562
120662
|
"pre-plan": AgentConfigSchema.optional(),
|
|
120663
|
+
manager: AgentConfigSchema.optional(),
|
|
120664
|
+
vision: AgentConfigSchema.optional(),
|
|
120563
120665
|
logician: AgentConfigSchema.optional(),
|
|
120564
120666
|
librarian: AgentConfigSchema.optional(),
|
|
120565
120667
|
explore: AgentConfigSchema.optional(),
|
|
@@ -120589,6 +120691,8 @@ var AgentRequirementsConfigSchema = exports_external.object({
|
|
|
120589
120691
|
zoe: ModelRequirementSchema.optional(),
|
|
120590
120692
|
build: ModelRequirementSchema.optional(),
|
|
120591
120693
|
"pre-plan": ModelRequirementSchema.optional(),
|
|
120694
|
+
manager: ModelRequirementSchema.optional(),
|
|
120695
|
+
vision: ModelRequirementSchema.optional(),
|
|
120592
120696
|
logician: ModelRequirementSchema.optional(),
|
|
120593
120697
|
librarian: ModelRequirementSchema.optional(),
|
|
120594
120698
|
explore: ModelRequirementSchema.optional(),
|
|
@@ -120611,205 +120715,54 @@ var HiaiOpencodeConfigSchema = exports_external.object({
|
|
|
120611
120715
|
lsp: exports_external.record(exports_external.string(), LspServerConfigSchema).optional(),
|
|
120612
120716
|
subtask2: Subtask2ConfigSchema.optional(),
|
|
120613
120717
|
skills: SkillsConfigSchema2.optional(),
|
|
120718
|
+
skill_discovery: SkillDiscoveryConfigSchema2.optional(),
|
|
120614
120719
|
permissions: PermissionsConfigSchema.optional(),
|
|
120615
120720
|
auth: AuthKeysSchema.optional(),
|
|
120616
120721
|
ollama: OllamaConfigSchema.optional()
|
|
120617
120722
|
});
|
|
120618
120723
|
|
|
120619
|
-
// src/config/
|
|
120620
|
-
|
|
120621
|
-
|
|
120622
|
-
|
|
120623
|
-
|
|
120624
|
-
|
|
120625
|
-
|
|
120626
|
-
|
|
120627
|
-
|
|
120628
|
-
|
|
120629
|
-
|
|
120630
|
-
|
|
120631
|
-
|
|
120632
|
-
|
|
120633
|
-
|
|
120634
|
-
function resolveAssetScript(...segments) {
|
|
120635
|
-
return join65(import.meta.dirname, "..", "assets", ...segments);
|
|
120636
|
-
}
|
|
120637
|
-
function createNpmPackageCommand(pkg, ...args) {
|
|
120638
|
-
return ["node", resolveAssetScript("runtime", "npm-package-runner.mjs"), pkg, ...args];
|
|
120639
|
-
}
|
|
120640
|
-
var HIAI_MCP_REGISTRY = {
|
|
120641
|
-
playwright: {
|
|
120642
|
-
name: "playwright",
|
|
120643
|
-
enabledByDefault: true,
|
|
120644
|
-
install: "npm",
|
|
120645
|
-
optionalEnv: ["HIAI_PLAYWRIGHT_INSTALL_BROWSERS"],
|
|
120646
|
-
config: {
|
|
120647
|
-
enabled: true,
|
|
120648
|
-
command: ["node", resolveAssetScript("mcp", "playwright.mjs")],
|
|
120649
|
-
timeout: 600000
|
|
120650
|
-
}
|
|
120651
|
-
},
|
|
120652
|
-
stitch: {
|
|
120653
|
-
name: "stitch",
|
|
120654
|
-
enabledByDefault: true,
|
|
120655
|
-
install: "remote",
|
|
120656
|
-
requiredEnv: ["STITCH_AI_API_KEY"],
|
|
120657
|
-
config: {
|
|
120658
|
-
enabled: true,
|
|
120659
|
-
type: "remote",
|
|
120660
|
-
url: "https://stitch.googleapis.com/mcp",
|
|
120661
|
-
headers: { "X-Goog-Api-Key": "{env:STITCH_AI_API_KEY}" },
|
|
120662
|
-
timeout: 600000
|
|
120663
|
-
}
|
|
120664
|
-
},
|
|
120665
|
-
"sequential-thinking": {
|
|
120666
|
-
name: "sequential-thinking",
|
|
120667
|
-
enabledByDefault: true,
|
|
120668
|
-
install: "npm",
|
|
120669
|
-
config: {
|
|
120670
|
-
enabled: true,
|
|
120671
|
-
command: createNpmPackageCommand("@modelcontextprotocol/server-sequential-thinking"),
|
|
120672
|
-
timeout: 600000
|
|
120673
|
-
}
|
|
120674
|
-
},
|
|
120675
|
-
firecrawl: {
|
|
120676
|
-
name: "firecrawl",
|
|
120677
|
-
enabledByDefault: true,
|
|
120678
|
-
install: "npm",
|
|
120679
|
-
requiredEnv: ["FIRECRAWL_API_KEY"],
|
|
120680
|
-
config: {
|
|
120681
|
-
enabled: true,
|
|
120682
|
-
command: createNpmPackageCommand("firecrawl-mcp"),
|
|
120683
|
-
timeout: 600000,
|
|
120684
|
-
environment: { FIRECRAWL_API_KEY: "{env:FIRECRAWL_API_KEY}" }
|
|
120685
|
-
}
|
|
120686
|
-
},
|
|
120687
|
-
rag: {
|
|
120688
|
-
name: "rag",
|
|
120689
|
-
enabledByDefault: true,
|
|
120690
|
-
install: "user-service",
|
|
120691
|
-
optionalEnv: ["OPENCODE_RAG_URL"],
|
|
120692
|
-
config: {
|
|
120693
|
-
enabled: true,
|
|
120694
|
-
type: "local",
|
|
120695
|
-
command: ["node", resolveAssetScript("mcp", "rag.mjs")],
|
|
120696
|
-
environment: {
|
|
120697
|
-
OPENCODE_RAG_URL: "{env:OPENCODE_RAG_URL:-http://localhost:9002/tools/search}"
|
|
120698
|
-
},
|
|
120699
|
-
timeout: 600000
|
|
120700
|
-
}
|
|
120701
|
-
},
|
|
120702
|
-
context7: {
|
|
120703
|
-
name: "context7",
|
|
120704
|
-
enabledByDefault: true,
|
|
120705
|
-
install: "remote",
|
|
120706
|
-
optionalEnv: ["CONTEXT7_API_KEY"],
|
|
120707
|
-
config: {
|
|
120708
|
-
enabled: true,
|
|
120709
|
-
type: "remote",
|
|
120710
|
-
url: "https://mcp.context7.com/mcp",
|
|
120711
|
-
headers: { "X-API-KEY": "{env:CONTEXT7_API_KEY}" },
|
|
120712
|
-
timeout: 600000
|
|
120713
|
-
}
|
|
120714
|
-
},
|
|
120715
|
-
mempalace: {
|
|
120716
|
-
name: "mempalace",
|
|
120717
|
-
enabledByDefault: true,
|
|
120718
|
-
install: "python",
|
|
120719
|
-
optionalEnv: ["MEMPALACE_PYTHON", "MEMPALACE_PALACE_PATH", "HIAI_MCP_AUTO_INSTALL"],
|
|
120720
|
-
config: {
|
|
120721
|
-
enabled: true,
|
|
120722
|
-
type: "local",
|
|
120723
|
-
command: ["node", resolveAssetScript("mcp", "mempalace.mjs"), "--palace", "./.opencode/palace"],
|
|
120724
|
-
timeout: 600000
|
|
120724
|
+
// src/config/defaults.ts
|
|
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;
|
|
120725
120739
|
}
|
|
120726
120740
|
}
|
|
120727
|
-
|
|
120728
|
-
function createDefaultMcpConfig() {
|
|
120729
|
-
return Object.fromEntries(Object.entries(HIAI_MCP_REGISTRY).map(([name, entry]) => [
|
|
120730
|
-
name,
|
|
120731
|
-
{ ...entry.config, enabled: entry.enabledByDefault }
|
|
120732
|
-
]));
|
|
120741
|
+
throw new Error("[hiai-opencode] Cannot find bundled hiai-opencode.json. The package is incomplete.");
|
|
120733
120742
|
}
|
|
120734
|
-
|
|
120735
|
-
|
|
120736
|
-
|
|
120737
|
-
var defaultConfig = {
|
|
120738
|
-
agents: {
|
|
120739
|
-
bob: { model: MODEL_PRESETS.high },
|
|
120740
|
-
guard: { model: MODEL_PRESETS.ultrahigh },
|
|
120741
|
-
strategist: { model: MODEL_PRESETS.strategist },
|
|
120742
|
-
critic: { model: MODEL_PRESETS.critic },
|
|
120743
|
-
coder: { model: MODEL_PRESETS.mid },
|
|
120744
|
-
designer: {
|
|
120745
|
-
model: "openrouter/google/gemini-3.1-pro",
|
|
120746
|
-
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)"
|
|
120747
|
-
},
|
|
120748
|
-
sub: { model: MODEL_PRESETS.fast },
|
|
120749
|
-
researcher: { model: MODEL_PRESETS.fast },
|
|
120750
|
-
multimodal: { model: MODEL_PRESETS.vision },
|
|
120751
|
-
"quality-guardian": { model: MODEL_PRESETS.mid },
|
|
120752
|
-
"platform-manager": { model: MODEL_PRESETS.fast },
|
|
120753
|
-
brainstormer: { model: MODEL_PRESETS.fast },
|
|
120754
|
-
"agent-skills": { model: MODEL_PRESETS.fast }
|
|
120755
|
-
},
|
|
120756
|
-
agentRequirements: {},
|
|
120757
|
-
categories: {
|
|
120758
|
-
"visual-engineering": { model: MODEL_PRESETS.vision, variant: "high" },
|
|
120759
|
-
artistry: { model: MODEL_PRESETS.vision, variant: "high" },
|
|
120760
|
-
ultrabrain: { model: MODEL_PRESETS.ultrahigh, variant: "xhigh" },
|
|
120761
|
-
deep: { model: MODEL_PRESETS.reasoning, variant: "medium" },
|
|
120762
|
-
quick: { model: MODEL_PRESETS.fast },
|
|
120763
|
-
writing: { model: MODEL_PRESETS.writing },
|
|
120764
|
-
git: { model: MODEL_PRESETS.fast },
|
|
120765
|
-
"unspecified-low": { model: MODEL_PRESETS.mid },
|
|
120766
|
-
"unspecified-high": { model: MODEL_PRESETS.high, variant: "max" }
|
|
120767
|
-
},
|
|
120768
|
-
categoryRequirements: {},
|
|
120769
|
-
mcp: createDefaultMcpConfig(),
|
|
120770
|
-
lsp: {
|
|
120771
|
-
typescript: {
|
|
120772
|
-
command: ["typescript-language-server", "--stdio"],
|
|
120773
|
-
extensions: [".ts", ".tsx", ".mts", ".cts"]
|
|
120774
|
-
},
|
|
120775
|
-
svelte: {
|
|
120776
|
-
command: ["svelteserver", "--stdio"],
|
|
120777
|
-
extensions: [".svelte"]
|
|
120778
|
-
},
|
|
120779
|
-
eslint: {
|
|
120780
|
-
command: ["node", join66(import.meta.dirname, "..", "assets", "runtime", "npm-package-runner.mjs"), "eslint-lsp", "--stdio"],
|
|
120781
|
-
extensions: [".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs", ".svelte"]
|
|
120782
|
-
},
|
|
120783
|
-
bash: {
|
|
120784
|
-
command: ["node", join66(import.meta.dirname, "..", "assets", "runtime", "npm-package-runner.mjs"), "bash-language-server", "start"],
|
|
120785
|
-
extensions: [".sh", ".bash"]
|
|
120786
|
-
},
|
|
120787
|
-
pyright: {
|
|
120788
|
-
command: ["pyright-langserver", "--stdio"],
|
|
120789
|
-
extensions: [".py"]
|
|
120790
|
-
}
|
|
120791
|
-
},
|
|
120792
|
-
subtask2: {
|
|
120793
|
-
replace_generic: true,
|
|
120794
|
-
generic_return: null
|
|
120795
|
-
},
|
|
120796
|
-
skills: {
|
|
120797
|
-
enabled: true,
|
|
120798
|
-
disabled: []
|
|
120799
|
-
},
|
|
120800
|
-
permissions: {
|
|
120801
|
-
read: { "*": "allow", "*.env": "deny", "*.env.*": "deny", "*.env.example": "allow" },
|
|
120802
|
-
edit: { "*": "allow" },
|
|
120803
|
-
bash: { "*": "allow" },
|
|
120804
|
-
deny_paths: ["**/backup/**", "**/secrets.*", "**/.env", "**/.env.*"]
|
|
120805
|
-
},
|
|
120806
|
-
ollama: {
|
|
120807
|
-
enabled: false,
|
|
120808
|
-
model: "{env:OLLAMA_MODEL:-qwen3.5:4b}",
|
|
120809
|
-
baseUrl: "http://localhost:11434",
|
|
120810
|
-
purpose: "helper"
|
|
120743
|
+
function expandPluginRootPlaceholders(value, pluginRoot) {
|
|
120744
|
+
if (typeof value === "string") {
|
|
120745
|
+
return value.replaceAll("{pluginRoot}", pluginRoot);
|
|
120811
120746
|
}
|
|
120812
|
-
|
|
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();
|
|
120813
120766
|
|
|
120814
120767
|
// src/config/types.ts
|
|
120815
120768
|
var LEGACY_AGENT_ALIAS_TO_CANONICAL2 = {
|
|
@@ -120817,6 +120770,8 @@ var LEGACY_AGENT_ALIAS_TO_CANONICAL2 = {
|
|
|
120817
120770
|
zoe: "bob",
|
|
120818
120771
|
build: "bob",
|
|
120819
120772
|
"pre-plan": "strategist",
|
|
120773
|
+
manager: "platform-manager",
|
|
120774
|
+
vision: "multimodal",
|
|
120820
120775
|
logician: "strategist",
|
|
120821
120776
|
librarian: "researcher",
|
|
120822
120777
|
explore: "researcher",
|
|
@@ -120854,8 +120809,8 @@ function deepMerge2(base, override) {
|
|
|
120854
120809
|
function findConfigFile(searchDirs) {
|
|
120855
120810
|
for (const dir of searchDirs) {
|
|
120856
120811
|
for (const filename of CONFIG_FILENAMES) {
|
|
120857
|
-
const candidate =
|
|
120858
|
-
if (
|
|
120812
|
+
const candidate = join66(dir, filename);
|
|
120813
|
+
if (existsSync57(candidate))
|
|
120859
120814
|
return candidate;
|
|
120860
120815
|
}
|
|
120861
120816
|
}
|
|
@@ -120927,13 +120882,13 @@ function normalizeCompactLspConfig(rawConfig) {
|
|
|
120927
120882
|
function loadConfig(projectDir) {
|
|
120928
120883
|
const searchDirs = [
|
|
120929
120884
|
projectDir,
|
|
120930
|
-
|
|
120931
|
-
|
|
120885
|
+
join66(projectDir, ".opencode"),
|
|
120886
|
+
join66(process.env.HOME || "", ".config", "opencode")
|
|
120932
120887
|
];
|
|
120933
120888
|
const configPath = findConfigFile(searchDirs);
|
|
120934
120889
|
if (!configPath)
|
|
120935
120890
|
return BASE_CONFIG;
|
|
120936
|
-
const raw =
|
|
120891
|
+
const raw = readFileSync43(configPath, "utf-8");
|
|
120937
120892
|
const parsed = parse2(raw);
|
|
120938
120893
|
const normalizedParsed = normalizeCompactLspConfig(parsed);
|
|
120939
120894
|
const validated = HiaiOpencodeConfigSchema.parse(normalizedParsed);
|
|
@@ -120949,12 +120904,12 @@ function resolveEnvVars(value) {
|
|
|
120949
120904
|
// src/shared/migrate-legacy-config-file.ts
|
|
120950
120905
|
init_logger();
|
|
120951
120906
|
init_plugin_identity();
|
|
120952
|
-
import { existsSync as
|
|
120953
|
-
import { join 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";
|
|
120954
120909
|
function buildCanonicalPath(legacyPath) {
|
|
120955
|
-
const dir =
|
|
120910
|
+
const dir = dirname19(legacyPath);
|
|
120956
120911
|
const ext = basename9(legacyPath).includes(".jsonc") ? ".jsonc" : ".json";
|
|
120957
|
-
return
|
|
120912
|
+
return join67(dir, `${CONFIG_BASENAME}${ext}`);
|
|
120958
120913
|
}
|
|
120959
120914
|
function archiveLegacyConfigFile(legacyPath) {
|
|
120960
120915
|
const backupPath = `${legacyPath}.bak`;
|
|
@@ -120986,15 +120941,15 @@ function archiveLegacyConfigFile(legacyPath) {
|
|
|
120986
120941
|
}
|
|
120987
120942
|
}
|
|
120988
120943
|
function migrateLegacyConfigFile(legacyPath) {
|
|
120989
|
-
if (!
|
|
120944
|
+
if (!existsSync58(legacyPath))
|
|
120990
120945
|
return false;
|
|
120991
120946
|
if (!basename9(legacyPath).startsWith(LEGACY_CONFIG_BASENAME))
|
|
120992
120947
|
return false;
|
|
120993
120948
|
const canonicalPath = buildCanonicalPath(legacyPath);
|
|
120994
|
-
if (
|
|
120949
|
+
if (existsSync58(canonicalPath))
|
|
120995
120950
|
return false;
|
|
120996
120951
|
try {
|
|
120997
|
-
const content =
|
|
120952
|
+
const content = readFileSync44(legacyPath, "utf-8");
|
|
120998
120953
|
writeFileAtomically(canonicalPath, content);
|
|
120999
120954
|
const archivedLegacyConfig = archiveLegacyConfigFile(legacyPath);
|
|
121000
120955
|
log("[migrateLegacyConfigFile] Migrated legacy config to canonical path", {
|
|
@@ -122514,11 +122469,11 @@ function createRuntimeFallbackHook(ctx, options) {
|
|
|
122514
122469
|
};
|
|
122515
122470
|
}
|
|
122516
122471
|
// src/hooks/write-existing-file-guard/hook.ts
|
|
122517
|
-
import { existsSync as
|
|
122518
|
-
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";
|
|
122519
122474
|
|
|
122520
122475
|
// src/hooks/write-existing-file-guard/tool-execute-before-handler.ts
|
|
122521
|
-
import { existsSync as
|
|
122476
|
+
import { existsSync as existsSync60 } from "fs";
|
|
122522
122477
|
|
|
122523
122478
|
// src/hooks/write-existing-file-guard/session-read-permissions.ts
|
|
122524
122479
|
function touchSession(sessionLastAccess, sessionID) {
|
|
@@ -122606,7 +122561,7 @@ async function handleWriteExistingFileGuardToolExecuteBefore(params) {
|
|
|
122606
122561
|
return;
|
|
122607
122562
|
}
|
|
122608
122563
|
if (toolName === "read") {
|
|
122609
|
-
if (!
|
|
122564
|
+
if (!existsSync60(resolvedPath) || !input.sessionID) {
|
|
122610
122565
|
return;
|
|
122611
122566
|
}
|
|
122612
122567
|
registerReadPermission({
|
|
@@ -122622,7 +122577,7 @@ async function handleWriteExistingFileGuardToolExecuteBefore(params) {
|
|
|
122622
122577
|
if (argsRecord && "overwrite" in argsRecord) {
|
|
122623
122578
|
delete argsRecord.overwrite;
|
|
122624
122579
|
}
|
|
122625
|
-
if (!
|
|
122580
|
+
if (!existsSync60(resolvedPath)) {
|
|
122626
122581
|
return;
|
|
122627
122582
|
}
|
|
122628
122583
|
const isBobPath2 = canonicalPath.includes("/.bob/");
|
|
@@ -122673,7 +122628,7 @@ function getPathFromArgs(args) {
|
|
|
122673
122628
|
return args?.filePath ?? args?.path ?? args?.file_path;
|
|
122674
122629
|
}
|
|
122675
122630
|
function resolveInputPath(ctx, inputPath) {
|
|
122676
|
-
return
|
|
122631
|
+
return normalize3(isAbsolute11(inputPath) ? inputPath : resolve14(ctx.directory, inputPath));
|
|
122677
122632
|
}
|
|
122678
122633
|
function isPathInsideDirectory(pathToCheck, directory) {
|
|
122679
122634
|
const relativePath = relative8(directory, pathToCheck);
|
|
@@ -122681,18 +122636,18 @@ function isPathInsideDirectory(pathToCheck, directory) {
|
|
|
122681
122636
|
}
|
|
122682
122637
|
function toCanonicalPath2(absolutePath) {
|
|
122683
122638
|
let canonicalPath = absolutePath;
|
|
122684
|
-
if (
|
|
122639
|
+
if (existsSync61(absolutePath)) {
|
|
122685
122640
|
try {
|
|
122686
122641
|
canonicalPath = realpathSync6.native(absolutePath);
|
|
122687
122642
|
} catch {
|
|
122688
122643
|
canonicalPath = absolutePath;
|
|
122689
122644
|
}
|
|
122690
122645
|
} else {
|
|
122691
|
-
const absoluteDir =
|
|
122692
|
-
const resolvedDir =
|
|
122693
|
-
canonicalPath =
|
|
122646
|
+
const absoluteDir = dirname21(absolutePath);
|
|
122647
|
+
const resolvedDir = existsSync61(absoluteDir) ? realpathSync6.native(absoluteDir) : absoluteDir;
|
|
122648
|
+
canonicalPath = join69(resolvedDir, basename11(absolutePath));
|
|
122694
122649
|
}
|
|
122695
|
-
return
|
|
122650
|
+
return normalize3(canonicalPath);
|
|
122696
122651
|
}
|
|
122697
122652
|
function isOverwriteEnabled(value) {
|
|
122698
122653
|
if (value === true) {
|
|
@@ -123966,23 +123921,23 @@ init_logger();
|
|
|
123966
123921
|
init_plugin_identity();
|
|
123967
123922
|
|
|
123968
123923
|
// src/hooks/legacy-plugin-toast/auto-migrate.ts
|
|
123969
|
-
import { existsSync as
|
|
123970
|
-
import { join as
|
|
123924
|
+
import { existsSync as existsSync62, readFileSync as readFileSync46 } from "fs";
|
|
123925
|
+
import { join as join70 } from "path";
|
|
123971
123926
|
init_plugin_identity();
|
|
123972
123927
|
function detectOpenCodeConfigPath(overrideConfigDir) {
|
|
123973
123928
|
if (overrideConfigDir) {
|
|
123974
|
-
const jsoncPath =
|
|
123975
|
-
const jsonPath =
|
|
123976
|
-
if (
|
|
123929
|
+
const jsoncPath = join70(overrideConfigDir, "opencode.jsonc");
|
|
123930
|
+
const jsonPath = join70(overrideConfigDir, "opencode.json");
|
|
123931
|
+
if (existsSync62(jsoncPath))
|
|
123977
123932
|
return jsoncPath;
|
|
123978
|
-
if (
|
|
123933
|
+
if (existsSync62(jsonPath))
|
|
123979
123934
|
return jsonPath;
|
|
123980
123935
|
return null;
|
|
123981
123936
|
}
|
|
123982
123937
|
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
123983
|
-
if (
|
|
123938
|
+
if (existsSync62(paths.configJsonc))
|
|
123984
123939
|
return paths.configJsonc;
|
|
123985
|
-
if (
|
|
123940
|
+
if (existsSync62(paths.configJson))
|
|
123986
123941
|
return paths.configJson;
|
|
123987
123942
|
return null;
|
|
123988
123943
|
}
|
|
@@ -123991,7 +123946,7 @@ function autoMigrateLegacyPluginEntry(overrideConfigDir) {
|
|
|
123991
123946
|
if (!configPath)
|
|
123992
123947
|
return { migrated: false, from: null, to: null, configPath: null };
|
|
123993
123948
|
try {
|
|
123994
|
-
const content =
|
|
123949
|
+
const content = readFileSync46(configPath, "utf-8");
|
|
123995
123950
|
const parseResult = parseJsoncSafe(content);
|
|
123996
123951
|
if (!parseResult.data?.plugin)
|
|
123997
123952
|
return { migrated: false, from: null, to: null, configPath };
|
|
@@ -124109,7 +124064,7 @@ async function queryOllama(args) {
|
|
|
124109
124064
|
}
|
|
124110
124065
|
|
|
124111
124066
|
// src/hooks/fast-apply/tool-execute-before-handler.ts
|
|
124112
|
-
import { existsSync as
|
|
124067
|
+
import { existsSync as existsSync63, readFileSync as readFileSync47 } from "fs";
|
|
124113
124068
|
async function handleFastApplyToolExecuteBefore(args) {
|
|
124114
124069
|
const { input, output, config: config2 } = args;
|
|
124115
124070
|
const normalizedTool = input.tool.toLowerCase();
|
|
@@ -124128,7 +124083,7 @@ async function handleFastApplyToolExecuteBefore(args) {
|
|
|
124128
124083
|
});
|
|
124129
124084
|
return;
|
|
124130
124085
|
}
|
|
124131
|
-
if (!
|
|
124086
|
+
if (!existsSync63(filePath)) {
|
|
124132
124087
|
log("[fast-apply] Skipping: file does not exist (new file)", {
|
|
124133
124088
|
sessionID: input.sessionID,
|
|
124134
124089
|
callID: input.callID,
|
|
@@ -124138,7 +124093,7 @@ async function handleFastApplyToolExecuteBefore(args) {
|
|
|
124138
124093
|
}
|
|
124139
124094
|
let originalContent;
|
|
124140
124095
|
try {
|
|
124141
|
-
originalContent =
|
|
124096
|
+
originalContent = readFileSync47(filePath, "utf-8");
|
|
124142
124097
|
} catch (err) {
|
|
124143
124098
|
log("[fast-apply] Failed to read file, falling back to default", {
|
|
124144
124099
|
sessionID: input.sessionID,
|
|
@@ -124517,13 +124472,13 @@ var DEFAULT_MAX_SYMBOLS = 200;
|
|
|
124517
124472
|
var DEFAULT_MAX_DIAGNOSTICS = 200;
|
|
124518
124473
|
var DEFAULT_MAX_DIRECTORY_FILES = 50;
|
|
124519
124474
|
// src/tools/lsp/server-config-loader.ts
|
|
124520
|
-
import { existsSync as
|
|
124521
|
-
import { join as
|
|
124475
|
+
import { existsSync as existsSync64, readFileSync as readFileSync48 } from "fs";
|
|
124476
|
+
import { join as join71 } from "path";
|
|
124522
124477
|
function loadJsonFile(path7) {
|
|
124523
|
-
if (!
|
|
124478
|
+
if (!existsSync64(path7))
|
|
124524
124479
|
return null;
|
|
124525
124480
|
try {
|
|
124526
|
-
return parseJsonc(
|
|
124481
|
+
return parseJsonc(readFileSync48(path7, "utf-8"));
|
|
124527
124482
|
} catch {
|
|
124528
124483
|
return null;
|
|
124529
124484
|
}
|
|
@@ -124532,9 +124487,9 @@ function getConfigPaths2() {
|
|
|
124532
124487
|
const cwd = process.cwd();
|
|
124533
124488
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
124534
124489
|
return {
|
|
124535
|
-
project: detectPluginConfigFile(
|
|
124490
|
+
project: detectPluginConfigFile(join71(cwd, ".opencode")).path,
|
|
124536
124491
|
user: detectPluginConfigFile(configDir).path,
|
|
124537
|
-
opencode: detectConfigFile(
|
|
124492
|
+
opencode: detectConfigFile(join71(configDir, "opencode")).path
|
|
124538
124493
|
};
|
|
124539
124494
|
}
|
|
124540
124495
|
function loadAllConfigs() {
|
|
@@ -124603,20 +124558,20 @@ function getMergedServers() {
|
|
|
124603
124558
|
}
|
|
124604
124559
|
|
|
124605
124560
|
// src/tools/lsp/server-installation.ts
|
|
124606
|
-
import { existsSync as
|
|
124607
|
-
import { delimiter, join as
|
|
124561
|
+
import { existsSync as existsSync65 } from "fs";
|
|
124562
|
+
import { delimiter, join as join73 } from "path";
|
|
124608
124563
|
|
|
124609
124564
|
// src/tools/lsp/server-path-bases.ts
|
|
124610
|
-
import { join as
|
|
124565
|
+
import { join as join72 } from "path";
|
|
124611
124566
|
function getLspServerAdditionalPathBases(workingDirectory) {
|
|
124612
124567
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
124613
|
-
const dataDir =
|
|
124568
|
+
const dataDir = join72(getDataDir(), "opencode");
|
|
124614
124569
|
return [
|
|
124615
|
-
|
|
124616
|
-
|
|
124617
|
-
|
|
124618
|
-
|
|
124619
|
-
|
|
124570
|
+
join72(workingDirectory, "node_modules", ".bin"),
|
|
124571
|
+
join72(configDir, "bin"),
|
|
124572
|
+
join72(configDir, "node_modules", ".bin"),
|
|
124573
|
+
join72(dataDir, "bin"),
|
|
124574
|
+
join72(dataDir, "bin", "node_modules", ".bin")
|
|
124620
124575
|
];
|
|
124621
124576
|
}
|
|
124622
124577
|
|
|
@@ -124626,7 +124581,7 @@ function isServerInstalled(command) {
|
|
|
124626
124581
|
return false;
|
|
124627
124582
|
const cmd = command[0];
|
|
124628
124583
|
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
124629
|
-
if (
|
|
124584
|
+
if (existsSync65(cmd))
|
|
124630
124585
|
return true;
|
|
124631
124586
|
}
|
|
124632
124587
|
const isWindows2 = process.platform === "win32";
|
|
@@ -124647,14 +124602,14 @@ function isServerInstalled(command) {
|
|
|
124647
124602
|
const paths = pathEnv.split(delimiter);
|
|
124648
124603
|
for (const p of paths) {
|
|
124649
124604
|
for (const suffix of exts) {
|
|
124650
|
-
if (
|
|
124605
|
+
if (existsSync65(join73(p, cmd + suffix))) {
|
|
124651
124606
|
return true;
|
|
124652
124607
|
}
|
|
124653
124608
|
}
|
|
124654
124609
|
}
|
|
124655
124610
|
for (const base of getLspServerAdditionalPathBases(process.cwd())) {
|
|
124656
124611
|
for (const suffix of exts) {
|
|
124657
|
-
if (
|
|
124612
|
+
if (existsSync65(join73(base, cmd + suffix))) {
|
|
124658
124613
|
return true;
|
|
124659
124614
|
}
|
|
124660
124615
|
}
|
|
@@ -124712,13 +124667,13 @@ function getLanguageId(ext) {
|
|
|
124712
124667
|
init_logger();
|
|
124713
124668
|
var {spawn: bunSpawn2 } = globalThis.Bun;
|
|
124714
124669
|
import { spawn as nodeSpawn2 } from "child_process";
|
|
124715
|
-
import { existsSync as
|
|
124670
|
+
import { existsSync as existsSync66, statSync as statSync7 } from "fs";
|
|
124716
124671
|
function shouldUseNodeSpawn() {
|
|
124717
124672
|
return process.platform === "win32";
|
|
124718
124673
|
}
|
|
124719
124674
|
function validateCwd(cwd) {
|
|
124720
124675
|
try {
|
|
124721
|
-
if (!
|
|
124676
|
+
if (!existsSync66(cwd)) {
|
|
124722
124677
|
return { valid: false, error: `Working directory does not exist: ${cwd}` };
|
|
124723
124678
|
}
|
|
124724
124679
|
const stats = statSync7(cwd);
|
|
@@ -124850,7 +124805,7 @@ function spawnProcess(command, options) {
|
|
|
124850
124805
|
return proc;
|
|
124851
124806
|
}
|
|
124852
124807
|
// src/tools/lsp/lsp-client.ts
|
|
124853
|
-
import { readFileSync as
|
|
124808
|
+
import { readFileSync as readFileSync49 } from "fs";
|
|
124854
124809
|
import { extname as extname4, resolve as resolve15 } from "path";
|
|
124855
124810
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
124856
124811
|
|
|
@@ -125122,7 +125077,7 @@ class LSPClient extends LSPClientConnection {
|
|
|
125122
125077
|
async openFile(filePath) {
|
|
125123
125078
|
const absPath = resolve15(filePath);
|
|
125124
125079
|
const uri = pathToFileURL2(absPath).href;
|
|
125125
|
-
const text =
|
|
125080
|
+
const text = readFileSync49(absPath, "utf-8");
|
|
125126
125081
|
if (!this.openedFiles.has(absPath)) {
|
|
125127
125082
|
const ext = extname4(absPath);
|
|
125128
125083
|
const languageId = getLanguageId(ext);
|
|
@@ -125480,10 +125435,10 @@ var lspManager = LSPServerManager.getInstance();
|
|
|
125480
125435
|
// src/tools/lsp/lsp-client-wrapper.ts
|
|
125481
125436
|
import { extname as extname5, resolve as resolve16 } from "path";
|
|
125482
125437
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
125483
|
-
import { existsSync as
|
|
125438
|
+
import { existsSync as existsSync67, statSync as statSync8 } from "fs";
|
|
125484
125439
|
init_plugin_identity();
|
|
125485
125440
|
function isDirectoryPath(filePath) {
|
|
125486
|
-
if (!
|
|
125441
|
+
if (!existsSync67(filePath)) {
|
|
125487
125442
|
return false;
|
|
125488
125443
|
}
|
|
125489
125444
|
return statSync8(filePath).isDirectory();
|
|
@@ -125493,14 +125448,14 @@ function uriToPath(uri) {
|
|
|
125493
125448
|
}
|
|
125494
125449
|
function findWorkspaceRoot(filePath) {
|
|
125495
125450
|
let dir = resolve16(filePath);
|
|
125496
|
-
if (!
|
|
125451
|
+
if (!existsSync67(dir) || !isDirectoryPath(dir)) {
|
|
125497
125452
|
dir = __require("path").dirname(dir);
|
|
125498
125453
|
}
|
|
125499
125454
|
const markers = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
125500
125455
|
let prevDir = "";
|
|
125501
125456
|
while (dir !== prevDir) {
|
|
125502
125457
|
for (const marker of markers) {
|
|
125503
|
-
if (
|
|
125458
|
+
if (existsSync67(__require("path").join(dir, marker))) {
|
|
125504
125459
|
return dir;
|
|
125505
125460
|
}
|
|
125506
125461
|
}
|
|
@@ -125675,10 +125630,10 @@ function formatApplyResult(result) {
|
|
|
125675
125630
|
`);
|
|
125676
125631
|
}
|
|
125677
125632
|
// src/tools/lsp/workspace-edit.ts
|
|
125678
|
-
import { readFileSync as
|
|
125633
|
+
import { readFileSync as readFileSync50, writeFileSync as writeFileSync17 } from "fs";
|
|
125679
125634
|
function applyTextEditsToFile(filePath, edits) {
|
|
125680
125635
|
try {
|
|
125681
|
-
let content =
|
|
125636
|
+
let content = readFileSync50(filePath, "utf-8");
|
|
125682
125637
|
const lines = content.split(`
|
|
125683
125638
|
`);
|
|
125684
125639
|
const sortedEdits = [...edits].sort((a, b) => {
|
|
@@ -125744,7 +125699,7 @@ function applyWorkspaceEdit(edit) {
|
|
|
125744
125699
|
try {
|
|
125745
125700
|
const oldPath = uriToPath(change.oldUri);
|
|
125746
125701
|
const newPath = uriToPath(change.newUri);
|
|
125747
|
-
const content =
|
|
125702
|
+
const content = readFileSync50(oldPath, "utf-8");
|
|
125748
125703
|
writeFileSync17(newPath, content, "utf-8");
|
|
125749
125704
|
__require("fs").unlinkSync(oldPath);
|
|
125750
125705
|
result.filesModified.push(newPath);
|
|
@@ -125910,8 +125865,8 @@ init_tool();
|
|
|
125910
125865
|
import { resolve as resolve18 } from "path";
|
|
125911
125866
|
|
|
125912
125867
|
// src/tools/lsp/directory-diagnostics.ts
|
|
125913
|
-
import { existsSync as
|
|
125914
|
-
import { extname as extname6, join as
|
|
125868
|
+
import { existsSync as existsSync68, lstatSync as lstatSync2, readdirSync as readdirSync19 } from "fs";
|
|
125869
|
+
import { extname as extname6, join as join74, resolve as resolve17 } from "path";
|
|
125915
125870
|
var SKIP_DIRECTORIES = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
|
|
125916
125871
|
function collectFilesWithExtension(dir, extension, maxFiles) {
|
|
125917
125872
|
const files = [];
|
|
@@ -125927,7 +125882,7 @@ function collectFilesWithExtension(dir, extension, maxFiles) {
|
|
|
125927
125882
|
for (const entry of entries) {
|
|
125928
125883
|
if (files.length >= maxFiles)
|
|
125929
125884
|
return;
|
|
125930
|
-
const fullPath =
|
|
125885
|
+
const fullPath = join74(currentDir, entry);
|
|
125931
125886
|
let stat;
|
|
125932
125887
|
try {
|
|
125933
125888
|
stat = lstatSync2(fullPath);
|
|
@@ -125956,7 +125911,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
125956
125911
|
throw new Error(`Extension must start with a dot (e.g., ".ts", not "${extension}"). ` + `Use ".${extension}" instead.`);
|
|
125957
125912
|
}
|
|
125958
125913
|
const absDir = resolve17(directory);
|
|
125959
|
-
if (!
|
|
125914
|
+
if (!existsSync68(absDir)) {
|
|
125960
125915
|
throw new Error(`Directory does not exist: ${absDir}`);
|
|
125961
125916
|
}
|
|
125962
125917
|
const serverResult = findServerForExtension(extension);
|
|
@@ -126030,7 +125985,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
|
|
|
126030
125985
|
|
|
126031
125986
|
// src/tools/lsp/infer-extension.ts
|
|
126032
125987
|
import { readdirSync as readdirSync20, lstatSync as lstatSync3 } from "fs";
|
|
126033
|
-
import { extname as extname7, join as
|
|
125988
|
+
import { extname as extname7, join as join75 } from "path";
|
|
126034
125989
|
var SKIP_DIRECTORIES2 = new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
|
|
126035
125990
|
var MAX_SCAN_ENTRIES = 500;
|
|
126036
125991
|
function inferExtensionFromDirectory(directory) {
|
|
@@ -126048,7 +126003,7 @@ function inferExtensionFromDirectory(directory) {
|
|
|
126048
126003
|
for (const entry of entries) {
|
|
126049
126004
|
if (scanned >= MAX_SCAN_ENTRIES)
|
|
126050
126005
|
return;
|
|
126051
|
-
const fullPath =
|
|
126006
|
+
const fullPath = join75(dir, entry);
|
|
126052
126007
|
let stat;
|
|
126053
126008
|
try {
|
|
126054
126009
|
stat = lstatSync3(fullPath);
|
|
@@ -126217,12 +126172,12 @@ var DEFAULT_MAX_MATCHES = 500;
|
|
|
126217
126172
|
|
|
126218
126173
|
// src/tools/ast-grep/sg-cli-path.ts
|
|
126219
126174
|
import { createRequire as createRequire4 } from "module";
|
|
126220
|
-
import { dirname as
|
|
126221
|
-
import { existsSync as
|
|
126175
|
+
import { dirname as dirname22, join as join77 } from "path";
|
|
126176
|
+
import { existsSync as existsSync70, statSync as statSync9 } from "fs";
|
|
126222
126177
|
|
|
126223
126178
|
// src/tools/ast-grep/downloader.ts
|
|
126224
|
-
import { existsSync as
|
|
126225
|
-
import { join as
|
|
126179
|
+
import { existsSync as existsSync69 } from "fs";
|
|
126180
|
+
import { join as join76 } from "path";
|
|
126226
126181
|
import { homedir as homedir14 } from "os";
|
|
126227
126182
|
import { createRequire as createRequire3 } from "module";
|
|
126228
126183
|
init_logger();
|
|
@@ -126250,12 +126205,12 @@ var PLATFORM_MAP2 = {
|
|
|
126250
126205
|
function getCacheDir3() {
|
|
126251
126206
|
if (process.platform === "win32") {
|
|
126252
126207
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
126253
|
-
const base2 = localAppData ||
|
|
126254
|
-
return
|
|
126208
|
+
const base2 = localAppData || join76(homedir14(), "AppData", "Local");
|
|
126209
|
+
return join76(base2, CACHE_DIR_NAME, "bin");
|
|
126255
126210
|
}
|
|
126256
126211
|
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
126257
|
-
const base = xdgCache ||
|
|
126258
|
-
return
|
|
126212
|
+
const base = xdgCache || join76(homedir14(), ".cache");
|
|
126213
|
+
return join76(base, CACHE_DIR_NAME, "bin");
|
|
126259
126214
|
}
|
|
126260
126215
|
function getBinaryName3() {
|
|
126261
126216
|
return process.platform === "win32" ? "sg.exe" : "sg";
|
|
@@ -126272,8 +126227,8 @@ async function downloadAstGrep(version3 = DEFAULT_VERSION) {
|
|
|
126272
126227
|
}
|
|
126273
126228
|
const cacheDir = getCacheDir3();
|
|
126274
126229
|
const binaryName = getBinaryName3();
|
|
126275
|
-
const binaryPath =
|
|
126276
|
-
if (
|
|
126230
|
+
const binaryPath = join76(cacheDir, binaryName);
|
|
126231
|
+
if (existsSync69(binaryPath)) {
|
|
126277
126232
|
return binaryPath;
|
|
126278
126233
|
}
|
|
126279
126234
|
const { arch, os: os4 } = platformInfo;
|
|
@@ -126281,7 +126236,7 @@ async function downloadAstGrep(version3 = DEFAULT_VERSION) {
|
|
|
126281
126236
|
const downloadUrl = `https://github.com/${REPO2}/releases/download/${version3}/${assetName}`;
|
|
126282
126237
|
log(`[${PUBLISHED_PACKAGE_NAME}] Downloading ast-grep binary...`);
|
|
126283
126238
|
try {
|
|
126284
|
-
const archivePath =
|
|
126239
|
+
const archivePath = join76(cacheDir, assetName);
|
|
126285
126240
|
ensureCacheDir(cacheDir);
|
|
126286
126241
|
await downloadArchive(downloadUrl, archivePath);
|
|
126287
126242
|
await extractZipArchive(archivePath, cacheDir);
|
|
@@ -126334,9 +126289,9 @@ function findSgCliPathSync() {
|
|
|
126334
126289
|
try {
|
|
126335
126290
|
const require2 = createRequire4(import.meta.url);
|
|
126336
126291
|
const cliPackageJsonPath = require2.resolve("@ast-grep/cli/package.json");
|
|
126337
|
-
const cliDirectory =
|
|
126338
|
-
const sgPath =
|
|
126339
|
-
if (
|
|
126292
|
+
const cliDirectory = dirname22(cliPackageJsonPath);
|
|
126293
|
+
const sgPath = join77(cliDirectory, binaryName);
|
|
126294
|
+
if (existsSync70(sgPath) && isValidBinary(sgPath)) {
|
|
126340
126295
|
return sgPath;
|
|
126341
126296
|
}
|
|
126342
126297
|
} catch {}
|
|
@@ -126345,10 +126300,10 @@ function findSgCliPathSync() {
|
|
|
126345
126300
|
try {
|
|
126346
126301
|
const require2 = createRequire4(import.meta.url);
|
|
126347
126302
|
const packageJsonPath = require2.resolve(`${platformPackage}/package.json`);
|
|
126348
|
-
const packageDirectory =
|
|
126303
|
+
const packageDirectory = dirname22(packageJsonPath);
|
|
126349
126304
|
const astGrepBinaryName = process.platform === "win32" ? "ast-grep.exe" : "ast-grep";
|
|
126350
|
-
const binaryPath =
|
|
126351
|
-
if (
|
|
126305
|
+
const binaryPath = join77(packageDirectory, astGrepBinaryName);
|
|
126306
|
+
if (existsSync70(binaryPath) && isValidBinary(binaryPath)) {
|
|
126352
126307
|
return binaryPath;
|
|
126353
126308
|
}
|
|
126354
126309
|
} catch {}
|
|
@@ -126356,7 +126311,7 @@ function findSgCliPathSync() {
|
|
|
126356
126311
|
if (process.platform === "darwin") {
|
|
126357
126312
|
const homebrewPaths = ["/opt/homebrew/bin/sg", "/usr/local/bin/sg"];
|
|
126358
126313
|
for (const path7 of homebrewPaths) {
|
|
126359
|
-
if (
|
|
126314
|
+
if (existsSync70(path7) && isValidBinary(path7)) {
|
|
126360
126315
|
return path7;
|
|
126361
126316
|
}
|
|
126362
126317
|
}
|
|
@@ -126380,14 +126335,14 @@ function setSgCliPath(path7) {
|
|
|
126380
126335
|
}
|
|
126381
126336
|
// src/tools/ast-grep/cli.ts
|
|
126382
126337
|
var {spawn: spawn17 } = globalThis.Bun;
|
|
126383
|
-
import { existsSync as
|
|
126338
|
+
import { existsSync as existsSync72 } from "fs";
|
|
126384
126339
|
|
|
126385
126340
|
// src/tools/ast-grep/cli-binary-path-resolution.ts
|
|
126386
|
-
import { existsSync as
|
|
126341
|
+
import { existsSync as existsSync71 } from "fs";
|
|
126387
126342
|
var resolvedCliPath3 = null;
|
|
126388
126343
|
var initPromise3 = null;
|
|
126389
126344
|
async function getAstGrepPath() {
|
|
126390
|
-
if (resolvedCliPath3 !== null &&
|
|
126345
|
+
if (resolvedCliPath3 !== null && existsSync71(resolvedCliPath3)) {
|
|
126391
126346
|
return resolvedCliPath3;
|
|
126392
126347
|
}
|
|
126393
126348
|
if (initPromise3) {
|
|
@@ -126395,7 +126350,7 @@ async function getAstGrepPath() {
|
|
|
126395
126350
|
}
|
|
126396
126351
|
initPromise3 = (async () => {
|
|
126397
126352
|
const syncPath = findSgCliPathSync();
|
|
126398
|
-
if (syncPath &&
|
|
126353
|
+
if (syncPath && existsSync71(syncPath)) {
|
|
126399
126354
|
resolvedCliPath3 = syncPath;
|
|
126400
126355
|
setSgCliPath(syncPath);
|
|
126401
126356
|
return syncPath;
|
|
@@ -126494,7 +126449,7 @@ async function runSg(options) {
|
|
|
126494
126449
|
const paths = options.paths && options.paths.length > 0 ? options.paths : ["."];
|
|
126495
126450
|
args.push(...paths);
|
|
126496
126451
|
let cliPath = getSgCliPath();
|
|
126497
|
-
if (!cliPath || !
|
|
126452
|
+
if (!cliPath || !existsSync72(cliPath)) {
|
|
126498
126453
|
const downloadedPath = await getAstGrepPath();
|
|
126499
126454
|
if (downloadedPath) {
|
|
126500
126455
|
cliPath = downloadedPath;
|
|
@@ -126749,20 +126704,20 @@ import { resolve as resolve19 } from "path";
|
|
|
126749
126704
|
var {spawn: spawn18 } = globalThis.Bun;
|
|
126750
126705
|
|
|
126751
126706
|
// src/tools/grep/constants.ts
|
|
126752
|
-
import { existsSync as
|
|
126753
|
-
import { join as
|
|
126707
|
+
import { existsSync as existsSync74 } from "fs";
|
|
126708
|
+
import { join as join79, dirname as dirname23 } from "path";
|
|
126754
126709
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
126755
126710
|
|
|
126756
126711
|
// src/tools/grep/downloader.ts
|
|
126757
|
-
import { existsSync as
|
|
126758
|
-
import { join as
|
|
126712
|
+
import { existsSync as existsSync73, readdirSync as readdirSync21 } from "fs";
|
|
126713
|
+
import { join as join78 } from "path";
|
|
126759
126714
|
init_plugin_identity();
|
|
126760
126715
|
function findFileRecursive(dir, filename) {
|
|
126761
126716
|
try {
|
|
126762
126717
|
const entries = readdirSync21(dir, { withFileTypes: true, recursive: true });
|
|
126763
126718
|
for (const entry of entries) {
|
|
126764
126719
|
if (entry.isFile() && entry.name === filename) {
|
|
126765
|
-
return
|
|
126720
|
+
return join78(entry.parentPath ?? dir, entry.name);
|
|
126766
126721
|
}
|
|
126767
126722
|
}
|
|
126768
126723
|
} catch {
|
|
@@ -126783,11 +126738,11 @@ function getPlatformKey() {
|
|
|
126783
126738
|
}
|
|
126784
126739
|
function getInstallDir() {
|
|
126785
126740
|
const homeDir = process.env.HOME || process.env.USERPROFILE || ".";
|
|
126786
|
-
return
|
|
126741
|
+
return join78(homeDir, ".cache", CACHE_DIR_NAME, "bin");
|
|
126787
126742
|
}
|
|
126788
126743
|
function getRgPath() {
|
|
126789
126744
|
const isWindows2 = process.platform === "win32";
|
|
126790
|
-
return
|
|
126745
|
+
return join78(getInstallDir(), isWindows2 ? "rg.exe" : "rg");
|
|
126791
126746
|
}
|
|
126792
126747
|
async function extractTarGz2(archivePath, destDir) {
|
|
126793
126748
|
const platformKey = getPlatformKey();
|
|
@@ -126804,7 +126759,7 @@ async function extractZip2(archivePath, destDir) {
|
|
|
126804
126759
|
const binaryName = process.platform === "win32" ? "rg.exe" : "rg";
|
|
126805
126760
|
const foundPath = findFileRecursive(destDir, binaryName);
|
|
126806
126761
|
if (foundPath) {
|
|
126807
|
-
const destPath =
|
|
126762
|
+
const destPath = join78(destDir, binaryName);
|
|
126808
126763
|
if (foundPath !== destPath) {
|
|
126809
126764
|
const { renameSync: renameSync4 } = await import("fs");
|
|
126810
126765
|
renameSync4(foundPath, destPath);
|
|
@@ -126819,13 +126774,13 @@ async function downloadAndInstallRipgrep() {
|
|
|
126819
126774
|
}
|
|
126820
126775
|
const installDir = getInstallDir();
|
|
126821
126776
|
const rgPath = getRgPath();
|
|
126822
|
-
if (
|
|
126777
|
+
if (existsSync73(rgPath)) {
|
|
126823
126778
|
return rgPath;
|
|
126824
126779
|
}
|
|
126825
126780
|
ensureCacheDir(installDir);
|
|
126826
126781
|
const filename = `ripgrep-${RG_VERSION}-${config4.platform}.${config4.extension}`;
|
|
126827
126782
|
const url3 = `https://github.com/BurntSushi/ripgrep/releases/download/${RG_VERSION}/${filename}`;
|
|
126828
|
-
const archivePath =
|
|
126783
|
+
const archivePath = join78(installDir, filename);
|
|
126829
126784
|
try {
|
|
126830
126785
|
await downloadArchive(url3, archivePath);
|
|
126831
126786
|
if (config4.extension === "tar.gz") {
|
|
@@ -126834,7 +126789,7 @@ async function downloadAndInstallRipgrep() {
|
|
|
126834
126789
|
await extractZip2(archivePath, installDir);
|
|
126835
126790
|
}
|
|
126836
126791
|
ensureExecutable(rgPath);
|
|
126837
|
-
if (!
|
|
126792
|
+
if (!existsSync73(rgPath)) {
|
|
126838
126793
|
throw new Error("ripgrep binary not found after extraction");
|
|
126839
126794
|
}
|
|
126840
126795
|
return rgPath;
|
|
@@ -126846,7 +126801,7 @@ async function downloadAndInstallRipgrep() {
|
|
|
126846
126801
|
}
|
|
126847
126802
|
function getInstalledRipgrepPath() {
|
|
126848
126803
|
const rgPath = getRgPath();
|
|
126849
|
-
return
|
|
126804
|
+
return existsSync73(rgPath) ? rgPath : null;
|
|
126850
126805
|
}
|
|
126851
126806
|
|
|
126852
126807
|
// src/tools/grep/constants.ts
|
|
@@ -126868,18 +126823,18 @@ function findExecutable(name) {
|
|
|
126868
126823
|
}
|
|
126869
126824
|
function getOpenCodeBundledRg() {
|
|
126870
126825
|
const execPath = process.execPath;
|
|
126871
|
-
const execDir =
|
|
126826
|
+
const execDir = dirname23(execPath);
|
|
126872
126827
|
const isWindows2 = process.platform === "win32";
|
|
126873
126828
|
const rgName = isWindows2 ? "rg.exe" : "rg";
|
|
126874
126829
|
const candidates = [
|
|
126875
|
-
|
|
126876
|
-
|
|
126877
|
-
|
|
126878
|
-
|
|
126879
|
-
|
|
126830
|
+
join79(getDataDir(), "opencode", "bin", rgName),
|
|
126831
|
+
join79(execDir, rgName),
|
|
126832
|
+
join79(execDir, "bin", rgName),
|
|
126833
|
+
join79(execDir, "..", "bin", rgName),
|
|
126834
|
+
join79(execDir, "..", "libexec", rgName)
|
|
126880
126835
|
];
|
|
126881
126836
|
for (const candidate of candidates) {
|
|
126882
|
-
if (
|
|
126837
|
+
if (existsSync74(candidate)) {
|
|
126883
126838
|
return candidate;
|
|
126884
126839
|
}
|
|
126885
126840
|
}
|
|
@@ -127531,10 +127486,10 @@ Use this when a task matches an available skill's or command's description.
|
|
|
127531
127486
|
`;
|
|
127532
127487
|
// src/tools/skill/tools.ts
|
|
127533
127488
|
init_dist();
|
|
127534
|
-
import { dirname as
|
|
127489
|
+
import { dirname as dirname25 } from "path";
|
|
127535
127490
|
|
|
127536
127491
|
// src/tools/slashcommand/command-output-formatter.ts
|
|
127537
|
-
import { dirname as
|
|
127492
|
+
import { dirname as dirname24 } from "path";
|
|
127538
127493
|
async function formatLoadedCommand(command, userMessage) {
|
|
127539
127494
|
const sections = [];
|
|
127540
127495
|
sections.push(`# /${command.name} Command
|
|
@@ -127573,7 +127528,7 @@ async function formatLoadedCommand(command, userMessage) {
|
|
|
127573
127528
|
if (!content && command.lazyContentLoader) {
|
|
127574
127529
|
content = await command.lazyContentLoader.load();
|
|
127575
127530
|
}
|
|
127576
|
-
const commandDir = command.path ?
|
|
127531
|
+
const commandDir = command.path ? dirname24(command.path) : process.cwd();
|
|
127577
127532
|
const withFileReferences = await resolveFileReferencesInText(content, commandDir);
|
|
127578
127533
|
const resolvedContent = await resolveCommandsInText(withFileReferences);
|
|
127579
127534
|
let finalContent = resolvedContent.trim();
|
|
@@ -127963,7 +127918,7 @@ function createSkillTool(options = {}) {
|
|
|
127963
127918
|
if (matchedSkill.name === "git-master") {
|
|
127964
127919
|
body = injectGitMasterConfig(body, options.gitMasterConfig);
|
|
127965
127920
|
}
|
|
127966
|
-
const dir = matchedSkill.path ?
|
|
127921
|
+
const dir = matchedSkill.path ? dirname25(matchedSkill.path) : matchedSkill.resolvedPath || process.cwd();
|
|
127967
127922
|
const output = [
|
|
127968
127923
|
`## Skill: ${matchedSkill.name}`,
|
|
127969
127924
|
"",
|
|
@@ -128006,9 +127961,9 @@ var skill = createSkillTool();
|
|
|
128006
127961
|
init_tool();
|
|
128007
127962
|
|
|
128008
127963
|
// src/tools/session-manager/constants.ts
|
|
128009
|
-
import { join as
|
|
128010
|
-
var TODO_DIR2 =
|
|
128011
|
-
var TRANSCRIPT_DIR2 =
|
|
127964
|
+
import { join as join80 } from "path";
|
|
127965
|
+
var TODO_DIR2 = join80(getClaudeConfigDir(), "todos");
|
|
127966
|
+
var TRANSCRIPT_DIR2 = join80(getClaudeConfigDir(), "transcripts");
|
|
128012
127967
|
var SESSION_LIST_DESCRIPTION = `List all OpenCode sessions with optional filtering.
|
|
128013
127968
|
|
|
128014
127969
|
Returns a list of available session IDs with metadata including message count, date range, and agents used.
|
|
@@ -128081,11 +128036,11 @@ Has Todos: Yes (12 items, 8 completed)
|
|
|
128081
128036
|
Has Transcript: Yes (234 entries)`;
|
|
128082
128037
|
|
|
128083
128038
|
// src/tools/session-manager/file-storage.ts
|
|
128084
|
-
import { existsSync as
|
|
128039
|
+
import { existsSync as existsSync75 } from "fs";
|
|
128085
128040
|
import { readdir, readFile } from "fs/promises";
|
|
128086
|
-
import { join as
|
|
128041
|
+
import { join as join81 } from "path";
|
|
128087
128042
|
async function getFileMainSessions(directory) {
|
|
128088
|
-
if (!
|
|
128043
|
+
if (!existsSync75(SESSION_STORAGE))
|
|
128089
128044
|
return [];
|
|
128090
128045
|
const sessions = [];
|
|
128091
128046
|
try {
|
|
@@ -128093,13 +128048,13 @@ async function getFileMainSessions(directory) {
|
|
|
128093
128048
|
for (const projectDir of projectDirs) {
|
|
128094
128049
|
if (!projectDir.isDirectory())
|
|
128095
128050
|
continue;
|
|
128096
|
-
const projectPath =
|
|
128051
|
+
const projectPath = join81(SESSION_STORAGE, projectDir.name);
|
|
128097
128052
|
const sessionFiles = await readdir(projectPath);
|
|
128098
128053
|
for (const file3 of sessionFiles) {
|
|
128099
128054
|
if (!file3.endsWith(".json"))
|
|
128100
128055
|
continue;
|
|
128101
128056
|
try {
|
|
128102
|
-
const content = await readFile(
|
|
128057
|
+
const content = await readFile(join81(projectPath, file3), "utf-8");
|
|
128103
128058
|
const meta3 = JSON.parse(content);
|
|
128104
128059
|
if (meta3.parentID)
|
|
128105
128060
|
continue;
|
|
@@ -128117,7 +128072,7 @@ async function getFileMainSessions(directory) {
|
|
|
128117
128072
|
return sessions.sort((a, b) => b.time.updated - a.time.updated);
|
|
128118
128073
|
}
|
|
128119
128074
|
async function getFileAllSessions() {
|
|
128120
|
-
if (!
|
|
128075
|
+
if (!existsSync75(MESSAGE_STORAGE))
|
|
128121
128076
|
return [];
|
|
128122
128077
|
const sessions = [];
|
|
128123
128078
|
async function scanDirectory(dir) {
|
|
@@ -128126,7 +128081,7 @@ async function getFileAllSessions() {
|
|
|
128126
128081
|
for (const entry of entries) {
|
|
128127
128082
|
if (!entry.isDirectory())
|
|
128128
128083
|
continue;
|
|
128129
|
-
const sessionPath =
|
|
128084
|
+
const sessionPath = join81(dir, entry.name);
|
|
128130
128085
|
const files = await readdir(sessionPath);
|
|
128131
128086
|
if (files.some((file3) => file3.endsWith(".json"))) {
|
|
128132
128087
|
sessions.push(entry.name);
|
|
@@ -128146,7 +128101,7 @@ async function fileSessionExists(sessionID) {
|
|
|
128146
128101
|
}
|
|
128147
128102
|
async function getFileSessionMessages(sessionID) {
|
|
128148
128103
|
const messageDir = getMessageDir(sessionID);
|
|
128149
|
-
if (!messageDir || !
|
|
128104
|
+
if (!messageDir || !existsSync75(messageDir))
|
|
128150
128105
|
return [];
|
|
128151
128106
|
const messages = [];
|
|
128152
128107
|
try {
|
|
@@ -128155,7 +128110,7 @@ async function getFileSessionMessages(sessionID) {
|
|
|
128155
128110
|
if (!file3.endsWith(".json"))
|
|
128156
128111
|
continue;
|
|
128157
128112
|
try {
|
|
128158
|
-
const content = await readFile(
|
|
128113
|
+
const content = await readFile(join81(messageDir, file3), "utf-8");
|
|
128159
128114
|
const meta3 = JSON.parse(content);
|
|
128160
128115
|
const parts = await readParts2(meta3.id);
|
|
128161
128116
|
messages.push({
|
|
@@ -128181,8 +128136,8 @@ async function getFileSessionMessages(sessionID) {
|
|
|
128181
128136
|
});
|
|
128182
128137
|
}
|
|
128183
128138
|
async function readParts2(messageID) {
|
|
128184
|
-
const partDir =
|
|
128185
|
-
if (!
|
|
128139
|
+
const partDir = join81(PART_STORAGE, messageID);
|
|
128140
|
+
if (!existsSync75(partDir))
|
|
128186
128141
|
return [];
|
|
128187
128142
|
const parts = [];
|
|
128188
128143
|
try {
|
|
@@ -128191,7 +128146,7 @@ async function readParts2(messageID) {
|
|
|
128191
128146
|
if (!file3.endsWith(".json"))
|
|
128192
128147
|
continue;
|
|
128193
128148
|
try {
|
|
128194
|
-
const content = await readFile(
|
|
128149
|
+
const content = await readFile(join81(partDir, file3), "utf-8");
|
|
128195
128150
|
parts.push(JSON.parse(content));
|
|
128196
128151
|
} catch {
|
|
128197
128152
|
continue;
|
|
@@ -128203,14 +128158,14 @@ async function readParts2(messageID) {
|
|
|
128203
128158
|
return parts.sort((a, b) => a.id.localeCompare(b.id));
|
|
128204
128159
|
}
|
|
128205
128160
|
async function getFileSessionTodos(sessionID) {
|
|
128206
|
-
if (!
|
|
128161
|
+
if (!existsSync75(TODO_DIR2))
|
|
128207
128162
|
return [];
|
|
128208
128163
|
try {
|
|
128209
128164
|
const allFiles = await readdir(TODO_DIR2);
|
|
128210
128165
|
const todoFiles = allFiles.filter((file3) => file3 === `${sessionID}.json`);
|
|
128211
128166
|
for (const file3 of todoFiles) {
|
|
128212
128167
|
try {
|
|
128213
|
-
const content = await readFile(
|
|
128168
|
+
const content = await readFile(join81(TODO_DIR2, file3), "utf-8");
|
|
128214
128169
|
const data = JSON.parse(content);
|
|
128215
128170
|
if (!Array.isArray(data))
|
|
128216
128171
|
continue;
|
|
@@ -128230,10 +128185,10 @@ async function getFileSessionTodos(sessionID) {
|
|
|
128230
128185
|
return [];
|
|
128231
128186
|
}
|
|
128232
128187
|
async function getFileSessionTranscript(sessionID) {
|
|
128233
|
-
if (!
|
|
128188
|
+
if (!existsSync75(TRANSCRIPT_DIR2))
|
|
128234
128189
|
return 0;
|
|
128235
|
-
const transcriptFile =
|
|
128236
|
-
if (!
|
|
128190
|
+
const transcriptFile = join81(TRANSCRIPT_DIR2, `${sessionID}.jsonl`);
|
|
128191
|
+
if (!existsSync75(transcriptFile))
|
|
128237
128192
|
return 0;
|
|
128238
128193
|
try {
|
|
128239
128194
|
const content = await readFile(transcriptFile, "utf-8");
|
|
@@ -130613,9 +130568,9 @@ async function resolveMultimodalLookerAgentMetadata(ctx) {
|
|
|
130613
130568
|
|
|
130614
130569
|
// src/tools/look-at/image-converter.ts
|
|
130615
130570
|
import * as childProcess from "child_process";
|
|
130616
|
-
import { existsSync as
|
|
130571
|
+
import { existsSync as existsSync76, mkdtempSync, readFileSync as readFileSync51, rmSync as rmSync3, unlinkSync as unlinkSync10, writeFileSync as writeFileSync18 } from "fs";
|
|
130617
130572
|
import { tmpdir as tmpdir7 } from "os";
|
|
130618
|
-
import { dirname as
|
|
130573
|
+
import { dirname as dirname26, join as join82 } from "path";
|
|
130619
130574
|
var SUPPORTED_FORMATS = new Set([
|
|
130620
130575
|
"image/jpeg",
|
|
130621
130576
|
"image/png",
|
|
@@ -130653,11 +130608,11 @@ function needsConversion(mimeType) {
|
|
|
130653
130608
|
return mimeType.startsWith("image/");
|
|
130654
130609
|
}
|
|
130655
130610
|
function convertImageToJpeg(inputPath, mimeType) {
|
|
130656
|
-
if (!
|
|
130611
|
+
if (!existsSync76(inputPath)) {
|
|
130657
130612
|
throw new Error(`File not found: ${inputPath}`);
|
|
130658
130613
|
}
|
|
130659
|
-
const tempDir = mkdtempSync(
|
|
130660
|
-
const outputPath =
|
|
130614
|
+
const tempDir = mkdtempSync(join82(tmpdir7(), "opencode-img-"));
|
|
130615
|
+
const outputPath = join82(tempDir, "converted.jpg");
|
|
130661
130616
|
log(`[image-converter] Converting ${mimeType} to JPEG: ${inputPath}`);
|
|
130662
130617
|
try {
|
|
130663
130618
|
if (process.platform === "darwin") {
|
|
@@ -130667,7 +130622,7 @@ function convertImageToJpeg(inputPath, mimeType) {
|
|
|
130667
130622
|
encoding: "utf-8",
|
|
130668
130623
|
timeout: CONVERSION_TIMEOUT_MS
|
|
130669
130624
|
});
|
|
130670
|
-
if (
|
|
130625
|
+
if (existsSync76(outputPath)) {
|
|
130671
130626
|
log(`[image-converter] Converted using sips: ${outputPath}`);
|
|
130672
130627
|
return outputPath;
|
|
130673
130628
|
}
|
|
@@ -130682,7 +130637,7 @@ function convertImageToJpeg(inputPath, mimeType) {
|
|
|
130682
130637
|
encoding: "utf-8",
|
|
130683
130638
|
timeout: CONVERSION_TIMEOUT_MS
|
|
130684
130639
|
});
|
|
130685
|
-
if (
|
|
130640
|
+
if (existsSync76(outputPath)) {
|
|
130686
130641
|
log(`[image-converter] Converted using ImageMagick: ${outputPath}`);
|
|
130687
130642
|
return outputPath;
|
|
130688
130643
|
}
|
|
@@ -130695,7 +130650,7 @@ function convertImageToJpeg(inputPath, mimeType) {
|
|
|
130695
130650
|
` + ` RHEL/CentOS: sudo yum install ImageMagick`);
|
|
130696
130651
|
} catch (error92) {
|
|
130697
130652
|
try {
|
|
130698
|
-
if (
|
|
130653
|
+
if (existsSync76(outputPath)) {
|
|
130699
130654
|
unlinkSync10(outputPath);
|
|
130700
130655
|
}
|
|
130701
130656
|
} catch {}
|
|
@@ -130708,12 +130663,12 @@ function convertImageToJpeg(inputPath, mimeType) {
|
|
|
130708
130663
|
}
|
|
130709
130664
|
function cleanupConvertedImage(filePath) {
|
|
130710
130665
|
try {
|
|
130711
|
-
const tempDirectory =
|
|
130712
|
-
if (
|
|
130666
|
+
const tempDirectory = dirname26(filePath);
|
|
130667
|
+
if (existsSync76(filePath)) {
|
|
130713
130668
|
unlinkSync10(filePath);
|
|
130714
130669
|
log(`[image-converter] Cleaned up temporary file: ${filePath}`);
|
|
130715
130670
|
}
|
|
130716
|
-
if (
|
|
130671
|
+
if (existsSync76(tempDirectory)) {
|
|
130717
130672
|
rmSync3(tempDirectory, { recursive: true, force: true });
|
|
130718
130673
|
log(`[image-converter] Cleaned up temporary directory: ${tempDirectory}`);
|
|
130719
130674
|
}
|
|
@@ -130722,9 +130677,9 @@ function cleanupConvertedImage(filePath) {
|
|
|
130722
130677
|
}
|
|
130723
130678
|
}
|
|
130724
130679
|
function convertBase64ImageToJpeg(base64Data, mimeType) {
|
|
130725
|
-
const tempDir = mkdtempSync(
|
|
130680
|
+
const tempDir = mkdtempSync(join82(tmpdir7(), "opencode-b64-"));
|
|
130726
130681
|
const inputExt = mimeType.split("/")[1] || "bin";
|
|
130727
|
-
const inputPath =
|
|
130682
|
+
const inputPath = join82(tempDir, `input.${inputExt}`);
|
|
130728
130683
|
const tempFiles = [inputPath];
|
|
130729
130684
|
try {
|
|
130730
130685
|
const cleanBase64 = base64Data.replace(/^data:[^;]+;base64,/, "");
|
|
@@ -130733,14 +130688,14 @@ function convertBase64ImageToJpeg(base64Data, mimeType) {
|
|
|
130733
130688
|
log(`[image-converter] Converting Base64 ${mimeType} to JPEG`);
|
|
130734
130689
|
const outputPath = convertImageToJpeg(inputPath, mimeType);
|
|
130735
130690
|
tempFiles.push(outputPath);
|
|
130736
|
-
const convertedBuffer =
|
|
130691
|
+
const convertedBuffer = readFileSync51(outputPath);
|
|
130737
130692
|
const convertedBase64 = convertedBuffer.toString("base64");
|
|
130738
130693
|
log(`[image-converter] Base64 conversion successful`);
|
|
130739
130694
|
return { base64: convertedBase64, tempFiles };
|
|
130740
130695
|
} catch (error92) {
|
|
130741
130696
|
tempFiles.forEach((file3) => {
|
|
130742
130697
|
try {
|
|
130743
|
-
if (
|
|
130698
|
+
if (existsSync76(file3))
|
|
130744
130699
|
unlinkSync10(file3);
|
|
130745
130700
|
} catch {}
|
|
130746
130701
|
});
|
|
@@ -132921,22 +132876,22 @@ function applyFallbackEntrySettings(input) {
|
|
|
132921
132876
|
// src/tools/delegate-task/subagent-discovery.ts
|
|
132922
132877
|
init_agent_display_names();
|
|
132923
132878
|
// src/features/claude-code-agent-loader/loader.ts
|
|
132924
|
-
import { existsSync as
|
|
132925
|
-
import { join as
|
|
132879
|
+
import { existsSync as existsSync79, readdirSync as readdirSync22 } from "fs";
|
|
132880
|
+
import { join as join83 } from "path";
|
|
132926
132881
|
|
|
132927
132882
|
// src/features/claude-code-agent-loader/agent-definitions-loader.ts
|
|
132928
|
-
import { existsSync as
|
|
132883
|
+
import { existsSync as existsSync78, readFileSync as readFileSync53 } from "fs";
|
|
132929
132884
|
import { basename as basename13, extname as extname8 } from "path";
|
|
132930
132885
|
init_logger();
|
|
132931
132886
|
|
|
132932
132887
|
// src/features/claude-code-agent-loader/json-agent-loader.ts
|
|
132933
|
-
import { existsSync as
|
|
132888
|
+
import { existsSync as existsSync77, readFileSync as readFileSync52 } from "fs";
|
|
132934
132889
|
function parseJsonAgentFile(filePath, scope) {
|
|
132935
132890
|
try {
|
|
132936
|
-
if (!
|
|
132891
|
+
if (!existsSync77(filePath)) {
|
|
132937
132892
|
return null;
|
|
132938
132893
|
}
|
|
132939
|
-
const content =
|
|
132894
|
+
const content = readFileSync52(filePath, "utf-8");
|
|
132940
132895
|
const { data } = parseJsoncSafe(content);
|
|
132941
132896
|
if (!data) {
|
|
132942
132897
|
return null;
|
|
@@ -132972,10 +132927,10 @@ function parseJsonAgentFile(filePath, scope) {
|
|
|
132972
132927
|
// src/features/claude-code-agent-loader/agent-definitions-loader.ts
|
|
132973
132928
|
function parseMarkdownAgentFile(filePath, scope) {
|
|
132974
132929
|
try {
|
|
132975
|
-
if (!
|
|
132930
|
+
if (!existsSync78(filePath)) {
|
|
132976
132931
|
return null;
|
|
132977
132932
|
}
|
|
132978
|
-
const content =
|
|
132933
|
+
const content = readFileSync53(filePath, "utf-8");
|
|
132979
132934
|
const { data, body } = parseFrontmatter(content);
|
|
132980
132935
|
const fileName = basename13(filePath);
|
|
132981
132936
|
const agentName = fileName.replace(/\.md$/i, "");
|
|
@@ -133007,7 +132962,7 @@ function parseMarkdownAgentFile(filePath, scope) {
|
|
|
133007
132962
|
function loadAgentDefinitions(paths, scope) {
|
|
133008
132963
|
const result = Object.create(null);
|
|
133009
132964
|
for (const filePath of paths) {
|
|
133010
|
-
if (!
|
|
132965
|
+
if (!existsSync78(filePath)) {
|
|
133011
132966
|
log(`[agent-definitions-loader] File not found, skipping: ${filePath}`);
|
|
133012
132967
|
continue;
|
|
133013
132968
|
}
|
|
@@ -133032,7 +132987,7 @@ function loadAgentDefinitions(paths, scope) {
|
|
|
133032
132987
|
|
|
133033
132988
|
// src/features/claude-code-agent-loader/loader.ts
|
|
133034
132989
|
function loadAgentsFromDir(agentsDir, scope) {
|
|
133035
|
-
if (!
|
|
132990
|
+
if (!existsSync79(agentsDir)) {
|
|
133036
132991
|
return [];
|
|
133037
132992
|
}
|
|
133038
132993
|
const entries = readdirSync22(agentsDir, { withFileTypes: true });
|
|
@@ -133040,7 +132995,7 @@ function loadAgentsFromDir(agentsDir, scope) {
|
|
|
133040
132995
|
for (const entry of entries) {
|
|
133041
132996
|
if (!isMarkdownFile(entry))
|
|
133042
132997
|
continue;
|
|
133043
|
-
const agentPath =
|
|
132998
|
+
const agentPath = join83(agentsDir, entry.name);
|
|
133044
132999
|
const agent = parseMarkdownAgentFile(agentPath, scope);
|
|
133045
133000
|
if (agent) {
|
|
133046
133001
|
agents.push(agent);
|
|
@@ -133049,7 +133004,7 @@ function loadAgentsFromDir(agentsDir, scope) {
|
|
|
133049
133004
|
return agents;
|
|
133050
133005
|
}
|
|
133051
133006
|
function loadUserAgents() {
|
|
133052
|
-
const userAgentsDir =
|
|
133007
|
+
const userAgentsDir = join83(getClaudeConfigDir(), "agents");
|
|
133053
133008
|
const agents = loadAgentsFromDir(userAgentsDir, "user");
|
|
133054
133009
|
const result = Object.create(null);
|
|
133055
133010
|
for (const agent of agents) {
|
|
@@ -133058,7 +133013,7 @@ function loadUserAgents() {
|
|
|
133058
133013
|
return result;
|
|
133059
133014
|
}
|
|
133060
133015
|
function loadProjectAgents(directory) {
|
|
133061
|
-
const projectAgentsDir =
|
|
133016
|
+
const projectAgentsDir = join83(directory ?? process.cwd(), ".claude", "agents");
|
|
133062
133017
|
const agents = loadAgentsFromDir(projectAgentsDir, "project");
|
|
133063
133018
|
const result = Object.create(null);
|
|
133064
133019
|
for (const agent of agents) {
|
|
@@ -133068,7 +133023,7 @@ function loadProjectAgents(directory) {
|
|
|
133068
133023
|
}
|
|
133069
133024
|
function loadOpencodeGlobalAgents() {
|
|
133070
133025
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
133071
|
-
const opencodeAgentsDir =
|
|
133026
|
+
const opencodeAgentsDir = join83(configDir, "agents");
|
|
133072
133027
|
const agents = loadAgentsFromDir(opencodeAgentsDir, "opencode");
|
|
133073
133028
|
const result = Object.create(null);
|
|
133074
133029
|
for (const agent of agents) {
|
|
@@ -133077,7 +133032,7 @@ function loadOpencodeGlobalAgents() {
|
|
|
133077
133032
|
return result;
|
|
133078
133033
|
}
|
|
133079
133034
|
function loadOpencodeProjectAgents(directory) {
|
|
133080
|
-
const opencodeProjectDir =
|
|
133035
|
+
const opencodeProjectDir = join83(directory ?? process.cwd(), ".opencode", "agents");
|
|
133081
133036
|
const agents = loadAgentsFromDir(opencodeProjectDir, "opencode-project");
|
|
133082
133037
|
const result = Object.create(null);
|
|
133083
133038
|
for (const agent of agents) {
|
|
@@ -133620,7 +133575,7 @@ function createDelegateTask(options) {
|
|
|
133620
133575
|
init_constants();
|
|
133621
133576
|
// src/tools/task/task-create.ts
|
|
133622
133577
|
init_tool();
|
|
133623
|
-
import { join as
|
|
133578
|
+
import { join as join86 } from "path";
|
|
133624
133579
|
|
|
133625
133580
|
// src/tools/task/types.ts
|
|
133626
133581
|
var TaskStatusSchema = exports_external.enum(["pending", "in_progress", "completed", "deleted"]);
|
|
@@ -133674,18 +133629,18 @@ var TaskDeleteInputSchema = exports_external.object({
|
|
|
133674
133629
|
});
|
|
133675
133630
|
|
|
133676
133631
|
// src/features/claude-tasks/storage.ts
|
|
133677
|
-
import { join as
|
|
133678
|
-
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";
|
|
133679
133634
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
133680
133635
|
function getTaskDir(config4 = {}) {
|
|
133681
133636
|
const tasksConfig = config4.bob?.tasks;
|
|
133682
133637
|
const storagePath = tasksConfig?.storage_path;
|
|
133683
133638
|
if (storagePath) {
|
|
133684
|
-
return isAbsolute12(storagePath) ? storagePath :
|
|
133639
|
+
return isAbsolute12(storagePath) ? storagePath : join85(process.cwd(), storagePath);
|
|
133685
133640
|
}
|
|
133686
133641
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
133687
133642
|
const listId = resolveTaskListId(config4);
|
|
133688
|
-
return
|
|
133643
|
+
return join85(configDir, "tasks", listId);
|
|
133689
133644
|
}
|
|
133690
133645
|
function sanitizePathSegment(value) {
|
|
133691
133646
|
return value.replace(/[^a-zA-Z0-9_-]/g, "-") || "default";
|
|
@@ -133703,16 +133658,16 @@ function resolveTaskListId(config4 = {}) {
|
|
|
133703
133658
|
return sanitizePathSegment(basename14(process.cwd()));
|
|
133704
133659
|
}
|
|
133705
133660
|
function ensureDir(dirPath) {
|
|
133706
|
-
if (!
|
|
133661
|
+
if (!existsSync81(dirPath)) {
|
|
133707
133662
|
mkdirSync16(dirPath, { recursive: true });
|
|
133708
133663
|
}
|
|
133709
133664
|
}
|
|
133710
133665
|
function readJsonSafe(filePath, schema2) {
|
|
133711
133666
|
try {
|
|
133712
|
-
if (!
|
|
133667
|
+
if (!existsSync81(filePath)) {
|
|
133713
133668
|
return null;
|
|
133714
133669
|
}
|
|
133715
|
-
const content =
|
|
133670
|
+
const content = readFileSync55(filePath, "utf-8");
|
|
133716
133671
|
const parsed = JSON.parse(content);
|
|
133717
133672
|
const result = schema2.safeParse(parsed);
|
|
133718
133673
|
if (!result.success) {
|
|
@@ -133724,7 +133679,7 @@ function readJsonSafe(filePath, schema2) {
|
|
|
133724
133679
|
}
|
|
133725
133680
|
}
|
|
133726
133681
|
function writeJsonAtomic(filePath, data) {
|
|
133727
|
-
const dir =
|
|
133682
|
+
const dir = dirname28(filePath);
|
|
133728
133683
|
ensureDir(dir);
|
|
133729
133684
|
const tempPath = `${filePath}.tmp.${Date.now()}`;
|
|
133730
133685
|
try {
|
|
@@ -133732,7 +133687,7 @@ function writeJsonAtomic(filePath, data) {
|
|
|
133732
133687
|
renameSync4(tempPath, filePath);
|
|
133733
133688
|
} catch (error92) {
|
|
133734
133689
|
try {
|
|
133735
|
-
if (
|
|
133690
|
+
if (existsSync81(tempPath)) {
|
|
133736
133691
|
unlinkSync11(tempPath);
|
|
133737
133692
|
}
|
|
133738
133693
|
} catch {}
|
|
@@ -133744,7 +133699,7 @@ function generateTaskId() {
|
|
|
133744
133699
|
return `T-${randomUUID2()}`;
|
|
133745
133700
|
}
|
|
133746
133701
|
function acquireLock(dirPath) {
|
|
133747
|
-
const lockPath =
|
|
133702
|
+
const lockPath = join85(dirPath, ".lock");
|
|
133748
133703
|
const lockId = randomUUID2();
|
|
133749
133704
|
const createLock = (timestamp2) => {
|
|
133750
133705
|
writeFileSync19(lockPath, JSON.stringify({ id: lockId, timestamp: timestamp2 }), {
|
|
@@ -133754,7 +133709,7 @@ function acquireLock(dirPath) {
|
|
|
133754
133709
|
};
|
|
133755
133710
|
const isStale = () => {
|
|
133756
133711
|
try {
|
|
133757
|
-
const lockContent =
|
|
133712
|
+
const lockContent = readFileSync55(lockPath, "utf-8");
|
|
133758
133713
|
const lockData = JSON.parse(lockContent);
|
|
133759
133714
|
const lockAge = Date.now() - lockData.timestamp;
|
|
133760
133715
|
return lockAge > STALE_LOCK_THRESHOLD_MS;
|
|
@@ -133792,9 +133747,9 @@ function acquireLock(dirPath) {
|
|
|
133792
133747
|
acquired: true,
|
|
133793
133748
|
release: () => {
|
|
133794
133749
|
try {
|
|
133795
|
-
if (!
|
|
133750
|
+
if (!existsSync81(lockPath))
|
|
133796
133751
|
return;
|
|
133797
|
-
const lockContent =
|
|
133752
|
+
const lockContent = readFileSync55(lockPath, "utf-8");
|
|
133798
133753
|
const lockData = JSON.parse(lockContent);
|
|
133799
133754
|
if (lockData.id !== lockId)
|
|
133800
133755
|
return;
|
|
@@ -133957,7 +133912,7 @@ async function handleCreate(args, config4, ctx, context) {
|
|
|
133957
133912
|
threadID: context.sessionID
|
|
133958
133913
|
};
|
|
133959
133914
|
const validatedTask = TaskObjectSchema.parse(task);
|
|
133960
|
-
writeJsonAtomic(
|
|
133915
|
+
writeJsonAtomic(join86(taskDir, `${taskId}.json`), validatedTask);
|
|
133961
133916
|
await syncTaskTodoUpdate(ctx, validatedTask, context.sessionID);
|
|
133962
133917
|
return JSON.stringify({
|
|
133963
133918
|
task: {
|
|
@@ -133980,7 +133935,7 @@ async function handleCreate(args, config4, ctx, context) {
|
|
|
133980
133935
|
}
|
|
133981
133936
|
// src/tools/task/task-get.ts
|
|
133982
133937
|
init_tool();
|
|
133983
|
-
import { join as
|
|
133938
|
+
import { join as join87 } from "path";
|
|
133984
133939
|
var TASK_ID_PATTERN = /^T-[A-Za-z0-9-]+$/;
|
|
133985
133940
|
function parseTaskId(id) {
|
|
133986
133941
|
if (!TASK_ID_PATTERN.test(id))
|
|
@@ -134005,7 +133960,7 @@ Returns null if the task does not exist or the file is invalid.`,
|
|
|
134005
133960
|
return JSON.stringify({ error: "invalid_task_id" });
|
|
134006
133961
|
}
|
|
134007
133962
|
const taskDir = getTaskDir(config4);
|
|
134008
|
-
const taskPath =
|
|
133963
|
+
const taskPath = join87(taskDir, `${taskId}.json`);
|
|
134009
133964
|
const task = readJsonSafe(taskPath, TaskObjectSchema);
|
|
134010
133965
|
return JSON.stringify({ task: task ?? null });
|
|
134011
133966
|
} catch (error92) {
|
|
@@ -134019,8 +133974,8 @@ Returns null if the task does not exist or the file is invalid.`,
|
|
|
134019
133974
|
}
|
|
134020
133975
|
// src/tools/task/task-list.ts
|
|
134021
133976
|
init_tool();
|
|
134022
|
-
import { join as
|
|
134023
|
-
import { existsSync as
|
|
133977
|
+
import { join as join88 } from "path";
|
|
133978
|
+
import { existsSync as existsSync82, readdirSync as readdirSync24 } from "fs";
|
|
134024
133979
|
function createTaskList(config4) {
|
|
134025
133980
|
return tool({
|
|
134026
133981
|
description: `List all active tasks with summary information.
|
|
@@ -134031,7 +133986,7 @@ Returns summary format: id, subject, status, owner, blockedBy (not full descript
|
|
|
134031
133986
|
args: {},
|
|
134032
133987
|
execute: async () => {
|
|
134033
133988
|
const taskDir = getTaskDir(config4);
|
|
134034
|
-
if (!
|
|
133989
|
+
if (!existsSync82(taskDir)) {
|
|
134035
133990
|
return JSON.stringify({ tasks: [] });
|
|
134036
133991
|
}
|
|
134037
133992
|
const files = readdirSync24(taskDir).filter((f) => f.endsWith(".json") && f.startsWith("T-")).map((f) => f.replace(".json", ""));
|
|
@@ -134040,7 +133995,7 @@ Returns summary format: id, subject, status, owner, blockedBy (not full descript
|
|
|
134040
133995
|
}
|
|
134041
133996
|
const allTasks = [];
|
|
134042
133997
|
for (const fileId of files) {
|
|
134043
|
-
const task = readJsonSafe(
|
|
133998
|
+
const task = readJsonSafe(join88(taskDir, `${fileId}.json`), TaskObjectSchema);
|
|
134044
133999
|
if (task) {
|
|
134045
134000
|
allTasks.push(task);
|
|
134046
134001
|
}
|
|
@@ -134069,7 +134024,7 @@ Returns summary format: id, subject, status, owner, blockedBy (not full descript
|
|
|
134069
134024
|
}
|
|
134070
134025
|
// src/tools/task/task-update.ts
|
|
134071
134026
|
init_tool();
|
|
134072
|
-
import { join as
|
|
134027
|
+
import { join as join89 } from "path";
|
|
134073
134028
|
var TASK_ID_PATTERN2 = /^T-[A-Za-z0-9-]+$/;
|
|
134074
134029
|
function parseTaskId2(id) {
|
|
134075
134030
|
if (!TASK_ID_PATTERN2.test(id))
|
|
@@ -134117,7 +134072,7 @@ async function handleUpdate(args, config4, ctx, context) {
|
|
|
134117
134072
|
return JSON.stringify({ error: "task_lock_unavailable" });
|
|
134118
134073
|
}
|
|
134119
134074
|
try {
|
|
134120
|
-
const taskPath =
|
|
134075
|
+
const taskPath = join89(taskDir, `${taskId}.json`);
|
|
134121
134076
|
const task = readJsonSafe(taskPath, TaskObjectSchema);
|
|
134122
134077
|
if (!task) {
|
|
134123
134078
|
return JSON.stringify({ error: "task_not_found" });
|
|
@@ -134987,7 +134942,7 @@ Diff.prototype = {
|
|
|
134987
134942
|
tokenize: function tokenize(value) {
|
|
134988
134943
|
return Array.from(value);
|
|
134989
134944
|
},
|
|
134990
|
-
join: function
|
|
134945
|
+
join: function join90(chars) {
|
|
134991
134946
|
return chars.join("");
|
|
134992
134947
|
},
|
|
134993
134948
|
postProcess: function postProcess(changeObjects) {
|
|
@@ -136334,7 +136289,7 @@ function createToolGuardHooks(args) {
|
|
|
136334
136289
|
const readImageResizer = isHookEnabled("read-image-resizer") ? safeHook("read-image-resizer", () => createReadImageResizerHook(ctx)) : null;
|
|
136335
136290
|
const todoDescriptionOverride = isHookEnabled("todo-description-override") ? safeHook("todo-description-override", () => createTodoDescriptionOverrideHook()) : null;
|
|
136336
136291
|
const webfetchRedirectGuard = isHookEnabled("webfetch-redirect-guard") ? safeHook("webfetch-redirect-guard", () => createWebFetchRedirectGuardHook(ctx)) : null;
|
|
136337
|
-
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;
|
|
136338
136293
|
return {
|
|
136339
136294
|
commentChecker,
|
|
136340
136295
|
toolOutputTruncator,
|
|
@@ -137247,8 +137202,8 @@ function unregisterManagerForCleanup(manager) {
|
|
|
137247
137202
|
}
|
|
137248
137203
|
|
|
137249
137204
|
// src/features/background-agent/compaction-aware-message-resolver.ts
|
|
137250
|
-
import { readdirSync as readdirSync25, readFileSync as
|
|
137251
|
-
import { join as
|
|
137205
|
+
import { readdirSync as readdirSync25, readFileSync as readFileSync56 } from "fs";
|
|
137206
|
+
import { join as join91 } from "path";
|
|
137252
137207
|
function hasFullAgentAndModel(message) {
|
|
137253
137208
|
return !!message.agent && !isCompactionAgent(message.agent) && !!message.model?.providerID && !!message.model?.modelID;
|
|
137254
137209
|
}
|
|
@@ -137327,7 +137282,7 @@ function findNearestMessageExcludingCompaction(messageDir, sessionID) {
|
|
|
137327
137282
|
const messages = [];
|
|
137328
137283
|
for (const file3 of files) {
|
|
137329
137284
|
try {
|
|
137330
|
-
const content =
|
|
137285
|
+
const content = readFileSync56(join91(messageDir, file3), "utf-8");
|
|
137331
137286
|
const parsed = JSON.parse(content);
|
|
137332
137287
|
if (hasCompactionPartInStorage(parsed.id) || isCompactionAgent(parsed.agent)) {
|
|
137333
137288
|
continue;
|
|
@@ -137417,7 +137372,7 @@ function handleSessionIdleBackgroundEvent(args) {
|
|
|
137417
137372
|
}
|
|
137418
137373
|
|
|
137419
137374
|
// src/features/background-agent/manager.ts
|
|
137420
|
-
import { join as
|
|
137375
|
+
import { join as join92 } from "path";
|
|
137421
137376
|
|
|
137422
137377
|
// src/features/background-agent/task-poller.ts
|
|
137423
137378
|
init_plugin_identity();
|
|
@@ -139093,7 +139048,7 @@ ${originalText}`;
|
|
|
139093
139048
|
parentSessionID: task.parentSessionID
|
|
139094
139049
|
});
|
|
139095
139050
|
}
|
|
139096
|
-
const messageDir =
|
|
139051
|
+
const messageDir = join92(MESSAGE_STORAGE, task.parentSessionID);
|
|
139097
139052
|
const currentMessage = messageDir ? findNearestMessageExcludingCompaction(messageDir, task.parentSessionID) : null;
|
|
139098
139053
|
agent = currentMessage?.agent ?? task.parentAgent;
|
|
139099
139054
|
model = currentMessage?.model?.providerID && currentMessage?.model?.modelID ? { providerID: currentMessage.model.providerID, modelID: currentMessage.model.modelID } : undefined;
|
|
@@ -139424,11 +139379,11 @@ ${originalText}`;
|
|
|
139424
139379
|
}
|
|
139425
139380
|
}
|
|
139426
139381
|
// src/features/mcp-oauth/storage.ts
|
|
139427
|
-
import { chmodSync as chmodSync2, existsSync as
|
|
139428
|
-
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";
|
|
139429
139384
|
var STORAGE_FILE_NAME = "mcp-oauth.json";
|
|
139430
139385
|
function getMcpOauthStoragePath() {
|
|
139431
|
-
return
|
|
139386
|
+
return join93(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
|
|
139432
139387
|
}
|
|
139433
139388
|
function normalizeHost(serverHost) {
|
|
139434
139389
|
let host = serverHost.trim();
|
|
@@ -139465,11 +139420,11 @@ function buildKey(serverHost, resource) {
|
|
|
139465
139420
|
}
|
|
139466
139421
|
function readStore() {
|
|
139467
139422
|
const filePath = getMcpOauthStoragePath();
|
|
139468
|
-
if (!
|
|
139423
|
+
if (!existsSync83(filePath)) {
|
|
139469
139424
|
return null;
|
|
139470
139425
|
}
|
|
139471
139426
|
try {
|
|
139472
|
-
const content =
|
|
139427
|
+
const content = readFileSync57(filePath, "utf-8");
|
|
139473
139428
|
return JSON.parse(content);
|
|
139474
139429
|
} catch {
|
|
139475
139430
|
return null;
|
|
@@ -139478,8 +139433,8 @@ function readStore() {
|
|
|
139478
139433
|
function writeStore(store2) {
|
|
139479
139434
|
const filePath = getMcpOauthStoragePath();
|
|
139480
139435
|
try {
|
|
139481
|
-
const dir =
|
|
139482
|
-
if (!
|
|
139436
|
+
const dir = dirname29(filePath);
|
|
139437
|
+
if (!existsSync83(dir)) {
|
|
139483
139438
|
mkdirSync17(dir, { recursive: true });
|
|
139484
139439
|
}
|
|
139485
139440
|
const tempPath = `${filePath}.tmp.${Date.now()}`;
|
|
@@ -146126,8 +146081,8 @@ class TmuxSessionManager {
|
|
|
146126
146081
|
var SESSION_TIMEOUT_MS3 = 10 * 60 * 1000;
|
|
146127
146082
|
var MIN_STABILITY_TIME_MS4 = 10 * 1000;
|
|
146128
146083
|
// src/features/claude-code-mcp-loader/loader.ts
|
|
146129
|
-
import { existsSync as
|
|
146130
|
-
import { join as
|
|
146084
|
+
import { existsSync as existsSync84, readFileSync as readFileSync58 } from "fs";
|
|
146085
|
+
import { join as join94 } from "path";
|
|
146131
146086
|
import { homedir as homedir15 } from "os";
|
|
146132
146087
|
init_logger();
|
|
146133
146088
|
function getMcpConfigPaths() {
|
|
@@ -146135,10 +146090,10 @@ function getMcpConfigPaths() {
|
|
|
146135
146090
|
const cwd = process.cwd();
|
|
146136
146091
|
const explicitClaudeConfigDir = process.env.CLAUDE_CONFIG_DIR?.trim() || process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
146137
146092
|
const candidates = [
|
|
146138
|
-
...explicitClaudeConfigDir ? [] : [{ path:
|
|
146139
|
-
{ path:
|
|
146140
|
-
{ path:
|
|
146141
|
-
{ path:
|
|
146093
|
+
...explicitClaudeConfigDir ? [] : [{ path: join94(homedir15(), ".claude.json"), scope: "user" }],
|
|
146094
|
+
{ path: join94(claudeConfigDir, ".mcp.json"), scope: "user" },
|
|
146095
|
+
{ path: join94(cwd, ".mcp.json"), scope: "project" },
|
|
146096
|
+
{ path: join94(cwd, ".claude", ".mcp.json"), scope: "local" }
|
|
146142
146097
|
];
|
|
146143
146098
|
const seen = new Set;
|
|
146144
146099
|
return candidates.filter(({ path: path9 }) => {
|
|
@@ -146149,7 +146104,7 @@ function getMcpConfigPaths() {
|
|
|
146149
146104
|
});
|
|
146150
146105
|
}
|
|
146151
146106
|
async function loadMcpConfigFile(filePath) {
|
|
146152
|
-
if (!
|
|
146107
|
+
if (!existsSync84(filePath)) {
|
|
146153
146108
|
return null;
|
|
146154
146109
|
}
|
|
146155
146110
|
try {
|
|
@@ -146165,10 +146120,10 @@ function getSystemMcpServerNames() {
|
|
|
146165
146120
|
const paths = getMcpConfigPaths();
|
|
146166
146121
|
const cwd = process.cwd();
|
|
146167
146122
|
for (const { path: path9 } of paths) {
|
|
146168
|
-
if (!
|
|
146123
|
+
if (!existsSync84(path9))
|
|
146169
146124
|
continue;
|
|
146170
146125
|
try {
|
|
146171
|
-
const content =
|
|
146126
|
+
const content = readFileSync58(path9, "utf-8");
|
|
146172
146127
|
const config4 = JSON.parse(content);
|
|
146173
146128
|
if (!config4?.mcpServers)
|
|
146174
146129
|
continue;
|
|
@@ -150513,7 +150468,7 @@ var researcherPromptMetadata = {
|
|
|
150513
150468
|
};
|
|
150514
150469
|
|
|
150515
150470
|
// src/agents/builtin-agents/resolve-file-uri.ts
|
|
150516
|
-
import { existsSync as
|
|
150471
|
+
import { existsSync as existsSync85, readFileSync as readFileSync59 } from "fs";
|
|
150517
150472
|
import { homedir as homedir16 } from "os";
|
|
150518
150473
|
import { isAbsolute as isAbsolute13, resolve as resolve22 } from "path";
|
|
150519
150474
|
init_logger();
|
|
@@ -150538,11 +150493,11 @@ function resolvePromptAppend(promptAppend, configDir) {
|
|
|
150538
150493
|
});
|
|
150539
150494
|
return `[WARNING: Path rejected: ${promptAppend}]`;
|
|
150540
150495
|
}
|
|
150541
|
-
if (!
|
|
150496
|
+
if (!existsSync85(filePath)) {
|
|
150542
150497
|
return `[WARNING: Could not resolve file URI: ${promptAppend}]`;
|
|
150543
150498
|
}
|
|
150544
150499
|
try {
|
|
150545
|
-
return
|
|
150500
|
+
return readFileSync59(filePath, "utf8");
|
|
150546
150501
|
} catch {
|
|
150547
150502
|
return `[WARNING: Could not read file: ${promptAppend}]`;
|
|
150548
150503
|
}
|
|
@@ -154176,6 +154131,28 @@ async function buildStrategistAgentConfig(params) {
|
|
|
154176
154131
|
return merged;
|
|
154177
154132
|
}
|
|
154178
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
|
+
|
|
154179
154156
|
// src/plugin-handlers/agent-config-handler.ts
|
|
154180
154157
|
var CANONICAL_VISIBLE_AGENT_NAMES = [
|
|
154181
154158
|
"Bob",
|
|
@@ -154238,8 +154215,9 @@ async function applyAgentConfig(params) {
|
|
|
154238
154215
|
const migratedDisabledAgents = (params.pluginConfig.disabled_agents ?? []).map((agent) => {
|
|
154239
154216
|
return AGENT_NAME_MAP[agent.toLowerCase()] ?? AGENT_NAME_MAP[agent] ?? agent;
|
|
154240
154217
|
});
|
|
154241
|
-
const
|
|
154218
|
+
const discovery2 = resolveSkillDiscoveryConfig(params.pluginConfig);
|
|
154242
154219
|
const [
|
|
154220
|
+
discoveredManagedPluginSkills,
|
|
154243
154221
|
discoveredConfigSourceSkills,
|
|
154244
154222
|
discoveredUserSkills,
|
|
154245
154223
|
discoveredProjectSkills,
|
|
@@ -154248,18 +154226,20 @@ async function applyAgentConfig(params) {
|
|
|
154248
154226
|
discoveredOpencodeProjectSkills,
|
|
154249
154227
|
discoveredGlobalAgentsSkills
|
|
154250
154228
|
] = await Promise.all([
|
|
154251
|
-
|
|
154229
|
+
discoverManagedPluginSkills(),
|
|
154230
|
+
discovery2.config_sources ? discoverConfigSourceSkills({
|
|
154252
154231
|
config: params.pluginConfig.skills,
|
|
154253
154232
|
configDir: params.ctx.directory
|
|
154254
|
-
}),
|
|
154255
|
-
|
|
154256
|
-
|
|
154257
|
-
|
|
154258
|
-
discoverOpencodeGlobalSkills(),
|
|
154259
|
-
discoverOpencodeProjectSkills(params.ctx.directory),
|
|
154260
|
-
|
|
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([])
|
|
154261
154240
|
]);
|
|
154262
154241
|
const allDiscoveredSkills = [
|
|
154242
|
+
...discoveredManagedPluginSkills,
|
|
154263
154243
|
...discoveredConfigSourceSkills,
|
|
154264
154244
|
...discoveredOpencodeProjectSkills,
|
|
154265
154245
|
...discoveredProjectSkills,
|
|
@@ -154468,7 +154448,7 @@ async function applyAgentConfig(params) {
|
|
|
154468
154448
|
init_agent_display_names();
|
|
154469
154449
|
// src/features/claude-code-command-loader/loader.ts
|
|
154470
154450
|
import { promises as fs14 } from "fs";
|
|
154471
|
-
import { join as
|
|
154451
|
+
import { join as join95, basename as basename15 } from "path";
|
|
154472
154452
|
init_logger();
|
|
154473
154453
|
async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix = "") {
|
|
154474
154454
|
try {
|
|
@@ -154499,7 +154479,7 @@ async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix
|
|
|
154499
154479
|
if (entry.isDirectory()) {
|
|
154500
154480
|
if (entry.name.startsWith("."))
|
|
154501
154481
|
continue;
|
|
154502
|
-
const subDirPath =
|
|
154482
|
+
const subDirPath = join95(commandsDir, entry.name);
|
|
154503
154483
|
const subPrefix = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
154504
154484
|
const subCommands = await loadCommandsFromDir(subDirPath, scope, visited, subPrefix);
|
|
154505
154485
|
commands2.push(...subCommands);
|
|
@@ -154507,7 +154487,7 @@ async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix
|
|
|
154507
154487
|
}
|
|
154508
154488
|
if (!isMarkdownFile(entry))
|
|
154509
154489
|
continue;
|
|
154510
|
-
const commandPath =
|
|
154490
|
+
const commandPath = join95(commandsDir, entry.name);
|
|
154511
154491
|
const baseCommandName = basename15(entry.name, ".md");
|
|
154512
154492
|
const commandName = prefix ? `${prefix}/${baseCommandName}` : baseCommandName;
|
|
154513
154493
|
try {
|
|
@@ -154566,12 +154546,12 @@ function commandsToRecord(commands2) {
|
|
|
154566
154546
|
return result;
|
|
154567
154547
|
}
|
|
154568
154548
|
async function loadUserCommands() {
|
|
154569
|
-
const userCommandsDir =
|
|
154549
|
+
const userCommandsDir = join95(getClaudeConfigDir(), "commands");
|
|
154570
154550
|
const commands2 = await loadCommandsFromDir(userCommandsDir, "user");
|
|
154571
154551
|
return commandsToRecord(commands2);
|
|
154572
154552
|
}
|
|
154573
154553
|
async function loadProjectCommands(directory) {
|
|
154574
|
-
const projectCommandsDir =
|
|
154554
|
+
const projectCommandsDir = join95(directory ?? process.cwd(), ".claude", "commands");
|
|
154575
154555
|
const commands2 = await loadCommandsFromDir(projectCommandsDir, "project");
|
|
154576
154556
|
return commandsToRecord(commands2);
|
|
154577
154557
|
}
|
|
@@ -154592,9 +154572,9 @@ async function applyCommandConfig(params) {
|
|
|
154592
154572
|
});
|
|
154593
154573
|
const systemCommands = params.config.command ?? {};
|
|
154594
154574
|
const includeClaudeCommands = params.pluginConfig.claude_code?.commands ?? true;
|
|
154595
|
-
const
|
|
154575
|
+
const discovery2 = resolveSkillDiscoveryConfig(params.pluginConfig);
|
|
154596
154576
|
const externalSkillPlugin = detectExternalSkillPlugin(params.ctx.directory);
|
|
154597
|
-
if (
|
|
154577
|
+
if ((discovery2.project_claude || discovery2.global_claude || discovery2.global_opencode) && externalSkillPlugin.detected) {
|
|
154598
154578
|
log(getSkillPluginConflictWarning(externalSkillPlugin.pluginName));
|
|
154599
154579
|
}
|
|
154600
154580
|
const [
|
|
@@ -154603,6 +154583,7 @@ async function applyCommandConfig(params) {
|
|
|
154603
154583
|
projectCommands,
|
|
154604
154584
|
opencodeGlobalCommands,
|
|
154605
154585
|
opencodeProjectCommands,
|
|
154586
|
+
managedPluginSkills,
|
|
154606
154587
|
userSkills,
|
|
154607
154588
|
globalAgentsSkills,
|
|
154608
154589
|
projectSkills,
|
|
@@ -154610,23 +154591,25 @@ async function applyCommandConfig(params) {
|
|
|
154610
154591
|
opencodeGlobalSkills,
|
|
154611
154592
|
opencodeProjectSkills
|
|
154612
154593
|
] = await Promise.all([
|
|
154613
|
-
discoverConfigSourceSkills({
|
|
154594
|
+
discovery2.config_sources ? discoverConfigSourceSkills({
|
|
154614
154595
|
config: params.pluginConfig.skills,
|
|
154615
154596
|
configDir: params.ctx.directory
|
|
154616
|
-
}),
|
|
154597
|
+
}) : Promise.resolve([]),
|
|
154617
154598
|
includeClaudeCommands ? loadUserCommands() : Promise.resolve({}),
|
|
154618
154599
|
includeClaudeCommands ? loadProjectCommands(params.ctx.directory) : Promise.resolve({}),
|
|
154619
154600
|
loadOpencodeGlobalCommands(),
|
|
154620
154601
|
loadOpencodeProjectCommands(params.ctx.directory),
|
|
154621
|
-
|
|
154622
|
-
|
|
154623
|
-
|
|
154624
|
-
|
|
154625
|
-
|
|
154626
|
-
|
|
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({})
|
|
154627
154609
|
]);
|
|
154628
154610
|
params.config.command = {
|
|
154629
154611
|
...builtinCommands,
|
|
154612
|
+
...managedPluginSkills,
|
|
154630
154613
|
...skillsToCommandDefinitionRecord(configSourceSkills),
|
|
154631
154614
|
...userCommands,
|
|
154632
154615
|
...userSkills,
|
|
@@ -154654,7 +154637,7 @@ function remapCommandAgentFields(commands2) {
|
|
|
154654
154637
|
|
|
154655
154638
|
// src/plugin-handlers/mcp-config-handler.ts
|
|
154656
154639
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
154657
|
-
import { existsSync as
|
|
154640
|
+
import { existsSync as existsSync86 } from "fs";
|
|
154658
154641
|
|
|
154659
154642
|
// src/mcp/websearch.ts
|
|
154660
154643
|
init_logger();
|
|
@@ -154807,7 +154790,7 @@ function hasUsableLocalMcpRuntime(name, entry) {
|
|
|
154807
154790
|
return false;
|
|
154808
154791
|
}
|
|
154809
154792
|
if (binary2 === "node" && typeof args[0] === "string" && args[0].endsWith(".mjs")) {
|
|
154810
|
-
if (!
|
|
154793
|
+
if (!existsSync86(args[0])) {
|
|
154811
154794
|
return false;
|
|
154812
154795
|
}
|
|
154813
154796
|
const probe2 = spawnSync5(binary2, ["--version"], {
|
|
@@ -155281,19 +155264,30 @@ async function createSkillContext(args) {
|
|
|
155281
155264
|
}
|
|
155282
155265
|
return true;
|
|
155283
155266
|
});
|
|
155284
|
-
const
|
|
155285
|
-
const [
|
|
155286
|
-
|
|
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({
|
|
155287
155280
|
config: pluginConfig.skills,
|
|
155288
155281
|
configDir: directory
|
|
155289
|
-
}),
|
|
155290
|
-
|
|
155291
|
-
discoverOpencodeGlobalSkills(),
|
|
155292
|
-
|
|
155293
|
-
discoverOpencodeProjectSkills(directory),
|
|
155294
|
-
discoverProjectAgentsSkills(directory),
|
|
155295
|
-
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([])
|
|
155296
155289
|
]);
|
|
155290
|
+
const filteredManagedPluginSkills = filterProviderGatedSkills(managedPluginSkills, browserProvider);
|
|
155297
155291
|
const filteredConfigSourceSkills = filterProviderGatedSkills(configSourceSkills, browserProvider);
|
|
155298
155292
|
const filteredUserSkills = filterProviderGatedSkills(userSkills, browserProvider);
|
|
155299
155293
|
const filteredGlobalSkills = filterProviderGatedSkills(globalSkills, browserProvider);
|
|
@@ -155301,7 +155295,7 @@ async function createSkillContext(args) {
|
|
|
155301
155295
|
const filteredOpencodeProjectSkills = filterProviderGatedSkills(opencodeProjectSkills, browserProvider);
|
|
155302
155296
|
const filteredAgentsProjectSkills = filterProviderGatedSkills(agentsProjectSkills, browserProvider);
|
|
155303
155297
|
const filteredAgentsGlobalSkills = filterProviderGatedSkills(agentsGlobalSkills, browserProvider);
|
|
155304
|
-
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 });
|
|
155305
155299
|
const availableSkills = mergedSkills.map((skill2) => ({
|
|
155306
155300
|
name: skill2.name,
|
|
155307
155301
|
description: skill2.definition.description ?? "",
|
|
@@ -155791,10 +155785,10 @@ init_agent_display_names();
|
|
|
155791
155785
|
|
|
155792
155786
|
// src/plugin/ultrawork-db-model-override.ts
|
|
155793
155787
|
import { Database } from "bun:sqlite";
|
|
155794
|
-
import { join as
|
|
155795
|
-
import { existsSync as
|
|
155788
|
+
import { join as join96 } from "path";
|
|
155789
|
+
import { existsSync as existsSync87 } from "fs";
|
|
155796
155790
|
function getDbPath() {
|
|
155797
|
-
return
|
|
155791
|
+
return join96(getDataDir(), "opencode", "opencode.db");
|
|
155798
155792
|
}
|
|
155799
155793
|
var MAX_MICROTASK_RETRIES = 10;
|
|
155800
155794
|
function tryUpdateMessageModel(db, messageId, targetModel, variant) {
|
|
@@ -155871,7 +155865,7 @@ function retryViaMicrotask(db, messageId, targetModel, variant, attempt) {
|
|
|
155871
155865
|
function scheduleDeferredModelOverride(messageId, targetModel, variant) {
|
|
155872
155866
|
queueMicrotask(() => {
|
|
155873
155867
|
const dbPath = getDbPath();
|
|
155874
|
-
if (!
|
|
155868
|
+
if (!existsSync87(dbPath)) {
|
|
155875
155869
|
log("[ultrawork-db-override] DB not found, skipping deferred override");
|
|
155876
155870
|
return;
|
|
155877
155871
|
}
|
|
@@ -157213,6 +157207,163 @@ function createFirstMessageVariantGate() {
|
|
|
157213
157207
|
// src/index.ts
|
|
157214
157208
|
init_plugin_identity();
|
|
157215
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
|
+
|
|
157216
157367
|
// src/internals/plugins/subtask2/core/state.ts
|
|
157217
157368
|
var configs = {};
|
|
157218
157369
|
var pluginConfig = { replace_generic: true };
|
|
@@ -157528,7 +157679,7 @@ function resolveResultReferences(text, sessionID) {
|
|
|
157528
157679
|
|
|
157529
157680
|
// src/internals/plugins/subtask2/utils/config.ts
|
|
157530
157681
|
import { mkdirSync as mkdirSync18 } from "fs";
|
|
157531
|
-
import { dirname as
|
|
157682
|
+
import { dirname as dirname30, join as join99 } from "path";
|
|
157532
157683
|
|
|
157533
157684
|
// src/internals/plugins/subtask2/utils/prompts.ts
|
|
157534
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.";
|
|
@@ -157594,15 +157745,15 @@ async function getAutoWorkflowPrompt() {
|
|
|
157594
157745
|
var AUTO_WORKFLOW_PROMPT = AUTO_WORKFLOW_PROMPT_TEMPLATE.replace(README_PLACEHOLDER, "[Use getAutoWorkflowPrompt() to get full documentation]");
|
|
157595
157746
|
|
|
157596
157747
|
// src/internals/plugins/subtask2/utils/config.ts
|
|
157597
|
-
var CONFIG_PATH =
|
|
157748
|
+
var CONFIG_PATH = join99(getOpenCodeConfigDir({ binary: "opencode" }), "subtask2.jsonc");
|
|
157598
157749
|
var cachedReadmeContent = null;
|
|
157599
157750
|
async function loadReadmeContent() {
|
|
157600
157751
|
if (cachedReadmeContent !== null) {
|
|
157601
157752
|
return cachedReadmeContent;
|
|
157602
157753
|
}
|
|
157603
157754
|
try {
|
|
157604
|
-
const pluginRoot =
|
|
157605
|
-
const readmePath =
|
|
157755
|
+
const pluginRoot = join99(dirname30(import.meta.path), "..", "..");
|
|
157756
|
+
const readmePath = join99(pluginRoot, "README.md");
|
|
157606
157757
|
const file3 = Bun.file(readmePath);
|
|
157607
157758
|
if (await file3.exists()) {
|
|
157608
157759
|
cachedReadmeContent = await file3.text();
|
|
@@ -157637,7 +157788,7 @@ async function loadConfig2() {
|
|
|
157637
157788
|
}
|
|
157638
157789
|
}
|
|
157639
157790
|
} catch {}
|
|
157640
|
-
mkdirSync18(
|
|
157791
|
+
mkdirSync18(dirname30(CONFIG_PATH), { recursive: true });
|
|
157641
157792
|
await Bun.write(CONFIG_PATH, `{
|
|
157642
157793
|
// Replace OpenCode's generic "Summarize..." prompt when no return is specified
|
|
157643
157794
|
"replace_generic": true,
|
|
@@ -157709,7 +157860,7 @@ function clearLog() {
|
|
|
157709
157860
|
}
|
|
157710
157861
|
|
|
157711
157862
|
// src/internals/plugins/subtask2/commands/manifest.ts
|
|
157712
|
-
import { join as
|
|
157863
|
+
import { join as join101 } from "path";
|
|
157713
157864
|
|
|
157714
157865
|
// src/internals/plugins/subtask2/parsing/frontmatter.ts
|
|
157715
157866
|
var import_yaml = __toESM(require_dist2(), 1);
|
|
@@ -157965,8 +158116,8 @@ function parseAutoWorkflowOutput(text) {
|
|
|
157965
158116
|
async function buildManifest() {
|
|
157966
158117
|
const manifest = {};
|
|
157967
158118
|
const dirs = [
|
|
157968
|
-
|
|
157969
|
-
|
|
158119
|
+
join101(getOpenCodeConfigDir({ binary: "opencode" }), "command"),
|
|
158120
|
+
join101(Bun.env.PWD ?? ".", ".opencode", "command")
|
|
157970
158121
|
];
|
|
157971
158122
|
for (const dir of dirs) {
|
|
157972
158123
|
try {
|
|
@@ -158129,11 +158280,11 @@ async function resolveTurnReferences(text, sessionID) {
|
|
|
158129
158280
|
}
|
|
158130
158281
|
|
|
158131
158282
|
// src/internals/plugins/subtask2/commands/loader.ts
|
|
158132
|
-
import { join as
|
|
158283
|
+
import { join as join102 } from "path";
|
|
158133
158284
|
async function loadCommandFile(name) {
|
|
158134
158285
|
const dirs = [
|
|
158135
|
-
|
|
158136
|
-
|
|
158286
|
+
join102(getOpenCodeConfigDir({ binary: "opencode" }), "command"),
|
|
158287
|
+
join102(Bun.env.PWD ?? ".", ".opencode", "command")
|
|
158137
158288
|
];
|
|
158138
158289
|
for (const dir of dirs) {
|
|
158139
158290
|
const directPath = `${dir}/${name}.md`;
|
|
@@ -159413,14 +159564,14 @@ init_websearch_cited();
|
|
|
159413
159564
|
// src/features/builtin-skills/materialize.ts
|
|
159414
159565
|
import {
|
|
159415
159566
|
cpSync,
|
|
159416
|
-
existsSync as
|
|
159567
|
+
existsSync as existsSync90,
|
|
159417
159568
|
mkdirSync as mkdirSync20,
|
|
159418
159569
|
readdirSync as readdirSync26,
|
|
159419
|
-
readFileSync as
|
|
159570
|
+
readFileSync as readFileSync61,
|
|
159420
159571
|
rmSync as rmSync4,
|
|
159421
159572
|
writeFileSync as writeFileSync22
|
|
159422
159573
|
} from "fs";
|
|
159423
|
-
import { join as
|
|
159574
|
+
import { join as join103 } from "path";
|
|
159424
159575
|
var GENERATED_MARKER = "<!-- Generated by hiai-opencode builtin skill materializer. -->";
|
|
159425
159576
|
var MANAGED_SKILL_METADATA = ".hiai-skill.json";
|
|
159426
159577
|
var LEGACY_MANAGED_DIR_MARKER = ".hiai-plugin-skill";
|
|
@@ -159447,10 +159598,10 @@ function buildSkillFrontmatter(skill2) {
|
|
|
159447
159598
|
`);
|
|
159448
159599
|
}
|
|
159449
159600
|
function shouldWriteSkillFile(skillFilePath) {
|
|
159450
|
-
if (!
|
|
159601
|
+
if (!existsSync90(skillFilePath))
|
|
159451
159602
|
return true;
|
|
159452
159603
|
try {
|
|
159453
|
-
const existing =
|
|
159604
|
+
const existing = readFileSync61(skillFilePath, "utf-8");
|
|
159454
159605
|
return existing.includes(GENERATED_MARKER);
|
|
159455
159606
|
} catch {
|
|
159456
159607
|
return false;
|
|
@@ -159458,10 +159609,10 @@ function shouldWriteSkillFile(skillFilePath) {
|
|
|
159458
159609
|
}
|
|
159459
159610
|
function getSkillLayout() {
|
|
159460
159611
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
159461
|
-
const assembledSkillsDir =
|
|
159462
|
-
const sourceRootDir =
|
|
159463
|
-
const builtinSourceDir =
|
|
159464
|
-
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");
|
|
159465
159616
|
mkdirSync20(assembledSkillsDir, { recursive: true });
|
|
159466
159617
|
mkdirSync20(builtinSourceDir, { recursive: true });
|
|
159467
159618
|
mkdirSync20(pluginSourceDir, { recursive: true });
|
|
@@ -159474,31 +159625,31 @@ function getSkillLayout() {
|
|
|
159474
159625
|
};
|
|
159475
159626
|
}
|
|
159476
159627
|
function writeManagedSkillMetadata(targetDir, metadata) {
|
|
159477
|
-
writeFileSync22(
|
|
159628
|
+
writeFileSync22(join103(targetDir, MANAGED_SKILL_METADATA), `${JSON.stringify(metadata, null, 2)}
|
|
159478
159629
|
`, "utf-8");
|
|
159479
159630
|
}
|
|
159480
159631
|
function readManagedSkillMetadata(targetDir) {
|
|
159481
|
-
const metadataPath =
|
|
159482
|
-
if (!
|
|
159632
|
+
const metadataPath = join103(targetDir, MANAGED_SKILL_METADATA);
|
|
159633
|
+
if (!existsSync90(metadataPath)) {
|
|
159483
159634
|
return null;
|
|
159484
159635
|
}
|
|
159485
159636
|
try {
|
|
159486
|
-
return JSON.parse(
|
|
159637
|
+
return JSON.parse(readFileSync61(metadataPath, "utf-8"));
|
|
159487
159638
|
} catch {
|
|
159488
159639
|
return null;
|
|
159489
159640
|
}
|
|
159490
159641
|
}
|
|
159491
159642
|
function isLegacyManagedSkillDir(targetDir, origin) {
|
|
159492
|
-
if (origin === "plugin" &&
|
|
159643
|
+
if (origin === "plugin" && existsSync90(join103(targetDir, LEGACY_MANAGED_DIR_MARKER))) {
|
|
159493
159644
|
return true;
|
|
159494
159645
|
}
|
|
159495
159646
|
if (origin === "builtin") {
|
|
159496
|
-
const skillFilePath =
|
|
159497
|
-
if (!
|
|
159647
|
+
const skillFilePath = join103(targetDir, "SKILL.md");
|
|
159648
|
+
if (!existsSync90(skillFilePath)) {
|
|
159498
159649
|
return false;
|
|
159499
159650
|
}
|
|
159500
159651
|
try {
|
|
159501
|
-
return
|
|
159652
|
+
return readFileSync61(skillFilePath, "utf-8").includes(GENERATED_MARKER);
|
|
159502
159653
|
} catch {
|
|
159503
159654
|
return false;
|
|
159504
159655
|
}
|
|
@@ -159506,7 +159657,7 @@ function isLegacyManagedSkillDir(targetDir, origin) {
|
|
|
159506
159657
|
return false;
|
|
159507
159658
|
}
|
|
159508
159659
|
function shouldSyncManagedSkillDir(targetDir, origin) {
|
|
159509
|
-
if (!
|
|
159660
|
+
if (!existsSync90(targetDir))
|
|
159510
159661
|
return true;
|
|
159511
159662
|
const metadata = readManagedSkillMetadata(targetDir);
|
|
159512
159663
|
if (metadata?.generatedBy === "hiai-opencode" && metadata.origin === origin) {
|
|
@@ -159522,7 +159673,7 @@ function shouldCleanupManagedSkillDir(targetDir, origin) {
|
|
|
159522
159673
|
return isLegacyManagedSkillDir(targetDir, origin);
|
|
159523
159674
|
}
|
|
159524
159675
|
function cleanupRemovedManagedSkillDirs(rootDir, origin, expectedSkillNames) {
|
|
159525
|
-
if (!
|
|
159676
|
+
if (!existsSync90(rootDir)) {
|
|
159526
159677
|
return;
|
|
159527
159678
|
}
|
|
159528
159679
|
for (const entry of readdirSync26(rootDir, { withFileTypes: true })) {
|
|
@@ -159530,15 +159681,15 @@ function cleanupRemovedManagedSkillDirs(rootDir, origin, expectedSkillNames) {
|
|
|
159530
159681
|
continue;
|
|
159531
159682
|
if (expectedSkillNames.has(entry.name))
|
|
159532
159683
|
continue;
|
|
159533
|
-
const targetDir =
|
|
159684
|
+
const targetDir = join103(rootDir, entry.name);
|
|
159534
159685
|
if (shouldCleanupManagedSkillDir(targetDir, origin)) {
|
|
159535
159686
|
rmSync4(targetDir, { recursive: true, force: true });
|
|
159536
159687
|
}
|
|
159537
159688
|
}
|
|
159538
159689
|
}
|
|
159539
159690
|
function writeSkillRegistry(configDir, entries) {
|
|
159540
|
-
const registryDir =
|
|
159541
|
-
const assembledSkillsDir =
|
|
159691
|
+
const registryDir = join103(configDir, ".hiai");
|
|
159692
|
+
const assembledSkillsDir = join103(configDir, "skills");
|
|
159542
159693
|
mkdirSync20(registryDir, { recursive: true });
|
|
159543
159694
|
mkdirSync20(assembledSkillsDir, { recursive: true });
|
|
159544
159695
|
const sortedEntries = [...entries].sort((left, right) => left.name.localeCompare(right.name));
|
|
@@ -159552,12 +159703,12 @@ function writeSkillRegistry(configDir, entries) {
|
|
|
159552
159703
|
},
|
|
159553
159704
|
layout: {
|
|
159554
159705
|
assembledSkillsDir,
|
|
159555
|
-
builtinSourceDir:
|
|
159556
|
-
pluginSourceDir:
|
|
159706
|
+
builtinSourceDir: join103(registryDir, "skills", "builtin"),
|
|
159707
|
+
pluginSourceDir: join103(registryDir, "skills", "plugin")
|
|
159557
159708
|
},
|
|
159558
159709
|
entries: sortedEntries
|
|
159559
159710
|
};
|
|
159560
|
-
writeFileSync22(
|
|
159711
|
+
writeFileSync22(join103(registryDir, "skill-registry.json"), `${JSON.stringify(payload, null, 2)}
|
|
159561
159712
|
`, "utf-8");
|
|
159562
159713
|
const readme = [
|
|
159563
159714
|
"# Hiai Skill Layout",
|
|
@@ -159572,16 +159723,16 @@ function writeSkillRegistry(configDir, entries) {
|
|
|
159572
159723
|
""
|
|
159573
159724
|
].join(`
|
|
159574
159725
|
`);
|
|
159575
|
-
writeFileSync22(
|
|
159726
|
+
writeFileSync22(join103(assembledSkillsDir, "README.md"), readme, "utf-8");
|
|
159576
159727
|
}
|
|
159577
159728
|
function materializeBuiltinSkills(skills) {
|
|
159578
159729
|
const { assembledSkillsDir, builtinSourceDir } = getSkillLayout();
|
|
159579
159730
|
const expectedSkillNames = new Set(skills.map((skill2) => skill2.name));
|
|
159580
159731
|
for (const skill2 of skills) {
|
|
159581
|
-
const sourceSkillDir =
|
|
159582
|
-
const sourceSkillFilePath =
|
|
159583
|
-
const assembledSkillDir =
|
|
159584
|
-
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");
|
|
159585
159736
|
const content = buildSkillFrontmatter(skill2);
|
|
159586
159737
|
mkdirSync20(sourceSkillDir, { recursive: true });
|
|
159587
159738
|
mkdirSync20(assembledSkillDir, { recursive: true });
|
|
@@ -159609,8 +159760,8 @@ function materializeBuiltinSkills(skills) {
|
|
|
159609
159760
|
cleanupRemovedManagedSkillDirs(assembledSkillsDir, "builtin", expectedSkillNames);
|
|
159610
159761
|
}
|
|
159611
159762
|
function materializePluginSkillDirectories(pluginRootDir) {
|
|
159612
|
-
const sourceSkillsDir =
|
|
159613
|
-
if (!
|
|
159763
|
+
const sourceSkillsDir = join103(pluginRootDir, "skills");
|
|
159764
|
+
if (!existsSync90(sourceSkillsDir)) {
|
|
159614
159765
|
return;
|
|
159615
159766
|
}
|
|
159616
159767
|
const { assembledSkillsDir, pluginSourceDir, configDir } = getSkillLayout();
|
|
@@ -159622,9 +159773,9 @@ function materializePluginSkillDirectories(pluginRootDir) {
|
|
|
159622
159773
|
if (entry.name === "tmp")
|
|
159623
159774
|
continue;
|
|
159624
159775
|
expectedSkillNames.add(entry.name);
|
|
159625
|
-
const sourceDir =
|
|
159626
|
-
const mirroredSourceDir =
|
|
159627
|
-
const assembledDir =
|
|
159776
|
+
const sourceDir = join103(sourceSkillsDir, entry.name);
|
|
159777
|
+
const mirroredSourceDir = join103(pluginSourceDir, entry.name);
|
|
159778
|
+
const assembledDir = join103(assembledSkillsDir, entry.name);
|
|
159628
159779
|
if (!shouldSyncManagedSkillDir(mirroredSourceDir, "plugin") || !shouldSyncManagedSkillDir(assembledDir, "plugin")) {
|
|
159629
159780
|
continue;
|
|
159630
159781
|
}
|
|
@@ -159658,7 +159809,7 @@ function materializePluginSkillDirectories(pluginRootDir) {
|
|
|
159658
159809
|
for (const builtinEntry of readdirSync26(assembledSkillsDir, { withFileTypes: true })) {
|
|
159659
159810
|
if (!builtinEntry.isDirectory())
|
|
159660
159811
|
continue;
|
|
159661
|
-
const assembledDir =
|
|
159812
|
+
const assembledDir = join103(assembledSkillsDir, builtinEntry.name);
|
|
159662
159813
|
const metadata = readManagedSkillMetadata(assembledDir);
|
|
159663
159814
|
if (metadata?.generatedBy !== "hiai-opencode" || metadata.origin !== "builtin") {
|
|
159664
159815
|
continue;
|
|
@@ -159681,11 +159832,11 @@ function configureBundledBunPtyLibrary() {
|
|
|
159681
159832
|
}
|
|
159682
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";
|
|
159683
159834
|
const candidates = [
|
|
159684
|
-
|
|
159685
|
-
|
|
159686
|
-
|
|
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)
|
|
159687
159838
|
];
|
|
159688
|
-
const resolved = candidates.find((candidate) =>
|
|
159839
|
+
const resolved = candidates.find((candidate) => existsSync92(candidate));
|
|
159689
159840
|
if (resolved) {
|
|
159690
159841
|
process.env.BUN_PTY_LIB = resolved;
|
|
159691
159842
|
}
|
|
@@ -159694,6 +159845,7 @@ var HiaiOpenCodePlugin = async (ctx) => {
|
|
|
159694
159845
|
log("[HiaiOpenCodePlugin] ENTRY - plugin loading", {
|
|
159695
159846
|
directory: ctx.directory
|
|
159696
159847
|
});
|
|
159848
|
+
warnIfListPluginEntry(ctx.directory);
|
|
159697
159849
|
const skillPluginCheck = detectExternalSkillPlugin(ctx.directory);
|
|
159698
159850
|
if (skillPluginCheck.detected && skillPluginCheck.pluginName) {
|
|
159699
159851
|
console.warn(getSkillPluginConflictWarning(skillPluginCheck.pluginName));
|
|
@@ -159702,11 +159854,15 @@ var HiaiOpenCodePlugin = async (ctx) => {
|
|
|
159702
159854
|
await activePluginDispose?.();
|
|
159703
159855
|
const internalConfig = loadConfig(ctx.directory);
|
|
159704
159856
|
const pluginConfig2 = hydratePluginConfigWithPlatformDefaults(loadPluginConfig(ctx.directory, ctx), internalConfig);
|
|
159857
|
+
warnMissingRequiredMcpEnv({
|
|
159858
|
+
pluginConfig: pluginConfig2,
|
|
159859
|
+
platformConfig: internalConfig
|
|
159860
|
+
});
|
|
159705
159861
|
materializeBuiltinSkills(createBuiltinSkills({
|
|
159706
159862
|
browserProvider: pluginConfig2.browser_automation_engine?.provider ?? "playwright",
|
|
159707
159863
|
disabledSkills: new Set(pluginConfig2.disabled_skills ?? [])
|
|
159708
159864
|
}));
|
|
159709
|
-
materializePluginSkillDirectories(
|
|
159865
|
+
materializePluginSkillDirectories(join105(import.meta.dirname, ".."));
|
|
159710
159866
|
const { initializeModelRequirements: initializeModelRequirements2 } = await Promise.resolve().then(() => (init_model_requirements(), exports_model_requirements));
|
|
159711
159867
|
initializeModelRequirements2(internalConfig);
|
|
159712
159868
|
const { initializeModelHeuristics: initializeModelHeuristics2 } = await Promise.resolve().then(() => (init_model_capability_heuristics(), exports_model_capability_heuristics));
|
|
@@ -159806,30 +159962,25 @@ var HiaiOpenCodePlugin = async (ctx) => {
|
|
|
159806
159962
|
auth: {
|
|
159807
159963
|
provider: "hiai-opencode",
|
|
159808
159964
|
methods: [
|
|
159809
|
-
{ type: "api", label: "Google API key" }
|
|
159810
|
-
{ type: "api", label: "OpenAI API key" },
|
|
159811
|
-
{ type: "api", label: "OpenRouter API key" }
|
|
159965
|
+
{ type: "api", label: "Google Search API key" }
|
|
159812
159966
|
],
|
|
159813
159967
|
loader: async (getAuth) => {
|
|
159814
159968
|
const authData = await getAuth();
|
|
159815
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));
|
|
159816
|
-
const
|
|
159817
|
-
const fromAuth = authData[label];
|
|
159818
|
-
if (fromAuth)
|
|
159819
|
-
return fromAuth;
|
|
159970
|
+
const getConfiguredKey = (configKey) => {
|
|
159820
159971
|
if (configKey)
|
|
159821
159972
|
return resolveEnvVars(configKey);
|
|
159822
159973
|
return;
|
|
159823
159974
|
};
|
|
159824
|
-
const googleKey =
|
|
159825
|
-
const openaiKey =
|
|
159826
|
-
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);
|
|
159827
159978
|
if (googleKey)
|
|
159828
|
-
registerGetAuth2(GOOGLE_PROVIDER_ID2, () => Promise.resolve(googleKey));
|
|
159979
|
+
registerGetAuth2(GOOGLE_PROVIDER_ID2, () => Promise.resolve({ type: "api", key: googleKey }));
|
|
159829
159980
|
if (openaiKey)
|
|
159830
|
-
registerGetAuth2(OPENAI_PROVIDER_ID2, () => Promise.resolve(openaiKey));
|
|
159981
|
+
registerGetAuth2(OPENAI_PROVIDER_ID2, () => Promise.resolve({ type: "api", key: openaiKey }));
|
|
159831
159982
|
if (openRouterKey)
|
|
159832
|
-
registerGetAuth2(OPENROUTER_PROVIDER_ID2, () => Promise.resolve(openRouterKey));
|
|
159983
|
+
registerGetAuth2(OPENROUTER_PROVIDER_ID2, () => Promise.resolve({ type: "api", key: openRouterKey }));
|
|
159833
159984
|
return {};
|
|
159834
159985
|
}
|
|
159835
159986
|
},
|