oh-my-opencode 2.13.2 → 2.14.0
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/README.ja.md +1 -0
- package/README.md +6 -3
- package/README.zh-cn.md +1 -0
- package/dist/cli/index.js +9 -3
- package/dist/config/schema.d.ts +12 -1
- package/dist/features/background-agent/concurrency.d.ts +10 -0
- package/dist/features/background-agent/concurrency.test.d.ts +1 -0
- package/dist/features/background-agent/index.d.ts +1 -0
- package/dist/features/background-agent/manager.d.ts +3 -1
- package/dist/features/background-agent/types.d.ts +1 -0
- package/dist/hooks/auto-slash-command/executor.d.ts +5 -1
- package/dist/hooks/auto-slash-command/index.d.ts +5 -1
- package/dist/hooks/keyword-detector/index.test.d.ts +1 -0
- package/dist/index.js +234 -86
- package/dist/mcp/types.d.ts +1 -0
- package/dist/mcp/websearch.d.ts +5 -0
- package/dist/tools/slashcommand/types.d.ts +2 -1
- package/package.json +1 -1
- package/README.ko.md +0 -1040
package/dist/index.js
CHANGED
|
@@ -8374,7 +8374,7 @@ var require_cross_spawn = __commonJS((exports, module) => {
|
|
|
8374
8374
|
var cp = __require("child_process");
|
|
8375
8375
|
var parse7 = require_parse2();
|
|
8376
8376
|
var enoent = require_enoent();
|
|
8377
|
-
function
|
|
8377
|
+
function spawn13(command, args, options) {
|
|
8378
8378
|
const parsed = parse7(command, args, options);
|
|
8379
8379
|
const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
|
|
8380
8380
|
enoent.hookChildProcess(spawned, parsed);
|
|
@@ -8386,8 +8386,8 @@ var require_cross_spawn = __commonJS((exports, module) => {
|
|
|
8386
8386
|
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
8387
8387
|
return result;
|
|
8388
8388
|
}
|
|
8389
|
-
module.exports =
|
|
8390
|
-
module.exports.spawn =
|
|
8389
|
+
module.exports = spawn13;
|
|
8390
|
+
module.exports.spawn = spawn13;
|
|
8391
8391
|
module.exports.sync = spawnSync2;
|
|
8392
8392
|
module.exports._parse = parse7;
|
|
8393
8393
|
module.exports._enoent = enoent;
|
|
@@ -8889,6 +8889,7 @@ ${CONTEXT_REMINDER}
|
|
|
8889
8889
|
}
|
|
8890
8890
|
// src/hooks/session-notification.ts
|
|
8891
8891
|
import { platform } from "os";
|
|
8892
|
+
import { spawn as spawn2 } from "child_process";
|
|
8892
8893
|
|
|
8893
8894
|
// src/hooks/session-notification-utils.ts
|
|
8894
8895
|
var {spawn } = globalThis.Bun;
|
|
@@ -9013,6 +9014,16 @@ function startBackgroundCheck(platform) {
|
|
|
9013
9014
|
}
|
|
9014
9015
|
|
|
9015
9016
|
// src/hooks/session-notification.ts
|
|
9017
|
+
function execCommand(command, args) {
|
|
9018
|
+
return new Promise((resolve) => {
|
|
9019
|
+
const proc = spawn2(command, args, {
|
|
9020
|
+
stdio: "ignore",
|
|
9021
|
+
detached: false
|
|
9022
|
+
});
|
|
9023
|
+
proc.on("close", () => resolve());
|
|
9024
|
+
proc.on("error", () => resolve());
|
|
9025
|
+
});
|
|
9026
|
+
}
|
|
9016
9027
|
function detectPlatform() {
|
|
9017
9028
|
const p = platform();
|
|
9018
9029
|
if (p === "darwin" || p === "linux" || p === "win32")
|
|
@@ -9039,14 +9050,15 @@ async function sendNotification(ctx, p, title, message) {
|
|
|
9039
9050
|
return;
|
|
9040
9051
|
const esTitle = title.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
|
|
9041
9052
|
const esMessage = message.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
|
|
9042
|
-
|
|
9053
|
+
const script = `display notification "${esMessage}" with title "${esTitle}"`;
|
|
9054
|
+
await execCommand(osascriptPath2, ["-e", script]).catch(() => {});
|
|
9043
9055
|
break;
|
|
9044
9056
|
}
|
|
9045
9057
|
case "linux": {
|
|
9046
9058
|
const notifySendPath2 = await getNotifySendPath();
|
|
9047
9059
|
if (!notifySendPath2)
|
|
9048
9060
|
return;
|
|
9049
|
-
await
|
|
9061
|
+
await execCommand(notifySendPath2, [title, message]).catch(() => {});
|
|
9050
9062
|
break;
|
|
9051
9063
|
}
|
|
9052
9064
|
case "win32": {
|
|
@@ -9067,7 +9079,7 @@ $Toast = [Windows.UI.Notifications.ToastNotification]::new($SerializedXml)
|
|
|
9067
9079
|
$Notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier('OpenCode')
|
|
9068
9080
|
$Notifier.Show($Toast)
|
|
9069
9081
|
`.trim().replace(/\n/g, "; ");
|
|
9070
|
-
await
|
|
9082
|
+
await execCommand(powershellPath2, ["-Command", toastScript]).catch(() => {});
|
|
9071
9083
|
break;
|
|
9072
9084
|
}
|
|
9073
9085
|
}
|
|
@@ -9078,17 +9090,17 @@ async function playSound(ctx, p, soundPath) {
|
|
|
9078
9090
|
const afplayPath2 = await getAfplayPath();
|
|
9079
9091
|
if (!afplayPath2)
|
|
9080
9092
|
return;
|
|
9081
|
-
|
|
9093
|
+
execCommand(afplayPath2, [soundPath]).catch(() => {});
|
|
9082
9094
|
break;
|
|
9083
9095
|
}
|
|
9084
9096
|
case "linux": {
|
|
9085
9097
|
const paplayPath2 = await getPaplayPath();
|
|
9086
9098
|
if (paplayPath2) {
|
|
9087
|
-
|
|
9099
|
+
execCommand(paplayPath2, [soundPath]).catch(() => {});
|
|
9088
9100
|
} else {
|
|
9089
9101
|
const aplayPath2 = await getAplayPath();
|
|
9090
9102
|
if (aplayPath2) {
|
|
9091
|
-
|
|
9103
|
+
execCommand(aplayPath2, [soundPath]).catch(() => {});
|
|
9092
9104
|
}
|
|
9093
9105
|
}
|
|
9094
9106
|
break;
|
|
@@ -9097,7 +9109,8 @@ async function playSound(ctx, p, soundPath) {
|
|
|
9097
9109
|
const powershellPath2 = await getPowershellPath();
|
|
9098
9110
|
if (!powershellPath2)
|
|
9099
9111
|
return;
|
|
9100
|
-
|
|
9112
|
+
const soundScript = `(New-Object Media.SoundPlayer '${soundPath.replace(/'/g, "''")}').PlaySync()`;
|
|
9113
|
+
execCommand(powershellPath2, ["-Command", soundScript]).catch(() => {});
|
|
9101
9114
|
break;
|
|
9102
9115
|
}
|
|
9103
9116
|
}
|
|
@@ -9805,7 +9818,7 @@ function createSessionRecoveryHook(ctx, options) {
|
|
|
9805
9818
|
};
|
|
9806
9819
|
}
|
|
9807
9820
|
// src/hooks/comment-checker/cli.ts
|
|
9808
|
-
var {spawn:
|
|
9821
|
+
var {spawn: spawn4 } = globalThis.Bun;
|
|
9809
9822
|
import { createRequire as createRequire2 } from "module";
|
|
9810
9823
|
import { dirname, join as join9 } from "path";
|
|
9811
9824
|
import { existsSync as existsSync5 } from "fs";
|
|
@@ -9813,7 +9826,7 @@ import * as fs2 from "fs";
|
|
|
9813
9826
|
import { tmpdir as tmpdir3 } from "os";
|
|
9814
9827
|
|
|
9815
9828
|
// src/hooks/comment-checker/downloader.ts
|
|
9816
|
-
var {spawn:
|
|
9829
|
+
var {spawn: spawn3 } = globalThis.Bun;
|
|
9817
9830
|
import { existsSync as existsSync4, mkdirSync as mkdirSync3, chmodSync, unlinkSync as unlinkSync2, appendFileSync as appendFileSync2 } from "fs";
|
|
9818
9831
|
import { join as join8 } from "path";
|
|
9819
9832
|
import { homedir as homedir2, tmpdir as tmpdir2 } from "os";
|
|
@@ -9863,7 +9876,7 @@ function getPackageVersion() {
|
|
|
9863
9876
|
}
|
|
9864
9877
|
async function extractTarGz(archivePath, destDir) {
|
|
9865
9878
|
debugLog("Extracting tar.gz:", archivePath, "to", destDir);
|
|
9866
|
-
const proc =
|
|
9879
|
+
const proc = spawn3(["tar", "-xzf", archivePath, "-C", destDir], {
|
|
9867
9880
|
stdout: "pipe",
|
|
9868
9881
|
stderr: "pipe"
|
|
9869
9882
|
});
|
|
@@ -9875,10 +9888,10 @@ async function extractTarGz(archivePath, destDir) {
|
|
|
9875
9888
|
}
|
|
9876
9889
|
async function extractZip(archivePath, destDir) {
|
|
9877
9890
|
debugLog("Extracting zip:", archivePath, "to", destDir);
|
|
9878
|
-
const proc = process.platform === "win32" ?
|
|
9891
|
+
const proc = process.platform === "win32" ? spawn3(["powershell", "-command", `Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force`], {
|
|
9879
9892
|
stdout: "pipe",
|
|
9880
9893
|
stderr: "pipe"
|
|
9881
|
-
}) :
|
|
9894
|
+
}) : spawn3(["unzip", "-o", archivePath, "-d", destDir], {
|
|
9882
9895
|
stdout: "pipe",
|
|
9883
9896
|
stderr: "pipe"
|
|
9884
9897
|
});
|
|
@@ -10045,7 +10058,7 @@ async function runCommentChecker(input, cliPath, customPrompt) {
|
|
|
10045
10058
|
if (customPrompt) {
|
|
10046
10059
|
args.push("--prompt", customPrompt);
|
|
10047
10060
|
}
|
|
10048
|
-
const proc =
|
|
10061
|
+
const proc = spawn4(args, {
|
|
10049
10062
|
stdin: "pipe",
|
|
10050
10063
|
stdout: "pipe",
|
|
10051
10064
|
stderr: "pipe"
|
|
@@ -15235,40 +15248,52 @@ function parseFrontmatter(content) {
|
|
|
15235
15248
|
}
|
|
15236
15249
|
}
|
|
15237
15250
|
// src/shared/command-executor.ts
|
|
15238
|
-
import { spawn as
|
|
15251
|
+
import { spawn as spawn5 } from "child_process";
|
|
15239
15252
|
import { exec } from "child_process";
|
|
15240
15253
|
import { promisify } from "util";
|
|
15241
15254
|
import { existsSync as existsSync17 } from "fs";
|
|
15242
15255
|
import { homedir as homedir3 } from "os";
|
|
15243
15256
|
var DEFAULT_ZSH_PATHS = ["/bin/zsh", "/usr/bin/zsh", "/usr/local/bin/zsh"];
|
|
15257
|
+
var DEFAULT_BASH_PATHS = ["/bin/bash", "/usr/bin/bash", "/usr/local/bin/bash"];
|
|
15244
15258
|
function getHomeDir() {
|
|
15245
15259
|
return process.env.HOME || process.env.USERPROFILE || homedir3();
|
|
15246
15260
|
}
|
|
15247
|
-
function
|
|
15248
|
-
if (
|
|
15249
|
-
return
|
|
15261
|
+
function findShellPath(defaultPaths, customPath) {
|
|
15262
|
+
if (customPath && existsSync17(customPath)) {
|
|
15263
|
+
return customPath;
|
|
15250
15264
|
}
|
|
15251
|
-
for (const path3 of
|
|
15265
|
+
for (const path3 of defaultPaths) {
|
|
15252
15266
|
if (existsSync17(path3)) {
|
|
15253
15267
|
return path3;
|
|
15254
15268
|
}
|
|
15255
15269
|
}
|
|
15256
15270
|
return null;
|
|
15257
15271
|
}
|
|
15272
|
+
function findZshPath(customZshPath) {
|
|
15273
|
+
return findShellPath(DEFAULT_ZSH_PATHS, customZshPath);
|
|
15274
|
+
}
|
|
15275
|
+
function findBashPath() {
|
|
15276
|
+
return findShellPath(DEFAULT_BASH_PATHS);
|
|
15277
|
+
}
|
|
15258
15278
|
var execAsync = promisify(exec);
|
|
15259
15279
|
async function executeHookCommand(command, stdin, cwd, options) {
|
|
15260
15280
|
const home = getHomeDir();
|
|
15261
15281
|
let expandedCommand = command.replace(/^~(?=\/|$)/g, home).replace(/\s~(?=\/)/g, ` ${home}`).replace(/\$CLAUDE_PROJECT_DIR/g, cwd).replace(/\$\{CLAUDE_PROJECT_DIR\}/g, cwd);
|
|
15262
15282
|
let finalCommand = expandedCommand;
|
|
15263
15283
|
if (options?.forceZsh) {
|
|
15264
|
-
const zshPath = options.zshPath
|
|
15284
|
+
const zshPath = findZshPath(options.zshPath);
|
|
15285
|
+
const escapedCommand = expandedCommand.replace(/'/g, "'\\''");
|
|
15265
15286
|
if (zshPath) {
|
|
15266
|
-
const escapedCommand = expandedCommand.replace(/'/g, "'\\''");
|
|
15267
15287
|
finalCommand = `${zshPath} -lc '${escapedCommand}'`;
|
|
15288
|
+
} else {
|
|
15289
|
+
const bashPath = findBashPath();
|
|
15290
|
+
if (bashPath) {
|
|
15291
|
+
finalCommand = `${bashPath} -lc '${escapedCommand}'`;
|
|
15292
|
+
}
|
|
15268
15293
|
}
|
|
15269
15294
|
}
|
|
15270
15295
|
return new Promise((resolve3) => {
|
|
15271
|
-
const proc =
|
|
15296
|
+
const proc = spawn5(finalCommand, {
|
|
15272
15297
|
cwd,
|
|
15273
15298
|
shell: true,
|
|
15274
15299
|
env: { ...process.env, HOME: home, CLAUDE_PROJECT_DIR: cwd }
|
|
@@ -17767,10 +17792,22 @@ function createKeywordDetectorHook(ctx) {
|
|
|
17767
17792
|
return {
|
|
17768
17793
|
"chat.message": async (input, output) => {
|
|
17769
17794
|
const promptText = extractPromptText2(output.parts);
|
|
17770
|
-
|
|
17795
|
+
let detectedKeywords = detectKeywordsWithType(removeCodeBlocks2(promptText), input.agent);
|
|
17771
17796
|
if (detectedKeywords.length === 0) {
|
|
17772
17797
|
return;
|
|
17773
17798
|
}
|
|
17799
|
+
const mainSessionID2 = getMainSessionID();
|
|
17800
|
+
const isNonMainSession = mainSessionID2 && input.sessionID !== mainSessionID2;
|
|
17801
|
+
if (isNonMainSession) {
|
|
17802
|
+
detectedKeywords = detectedKeywords.filter((k) => k.type === "ultrawork");
|
|
17803
|
+
if (detectedKeywords.length === 0) {
|
|
17804
|
+
log(`[keyword-detector] Skipping non-ultrawork keywords in non-main session`, {
|
|
17805
|
+
sessionID: input.sessionID,
|
|
17806
|
+
mainSessionID: mainSessionID2
|
|
17807
|
+
});
|
|
17808
|
+
return;
|
|
17809
|
+
}
|
|
17810
|
+
}
|
|
17774
17811
|
const hasUltrawork = detectedKeywords.some((k) => k.type === "ultrawork");
|
|
17775
17812
|
if (hasUltrawork) {
|
|
17776
17813
|
log(`[keyword-detector] Ultrawork mode activated`, { sessionID: input.sessionID });
|
|
@@ -20641,10 +20678,11 @@ function skillToCommandInfo(skill) {
|
|
|
20641
20678
|
subtask: skill.definition.subtask
|
|
20642
20679
|
},
|
|
20643
20680
|
content: skill.definition.template,
|
|
20644
|
-
scope: "skill"
|
|
20681
|
+
scope: "skill",
|
|
20682
|
+
lazyContentLoader: skill.lazyContent
|
|
20645
20683
|
};
|
|
20646
20684
|
}
|
|
20647
|
-
async function discoverAllCommands() {
|
|
20685
|
+
async function discoverAllCommands(options) {
|
|
20648
20686
|
const userCommandsDir = join43(getClaudeConfigDir(), "commands");
|
|
20649
20687
|
const projectCommandsDir = join43(process.cwd(), ".claude", "commands");
|
|
20650
20688
|
const opencodeGlobalDir = join43(homedir13(), ".config", "opencode", "command");
|
|
@@ -20653,7 +20691,7 @@ async function discoverAllCommands() {
|
|
|
20653
20691
|
const opencodeGlobalCommands = discoverCommandsFromDir(opencodeGlobalDir, "opencode");
|
|
20654
20692
|
const projectCommands = discoverCommandsFromDir(projectCommandsDir, "project");
|
|
20655
20693
|
const opencodeProjectCommands = discoverCommandsFromDir(opencodeProjectDir, "opencode-project");
|
|
20656
|
-
const skills = await discoverAllSkills();
|
|
20694
|
+
const skills = options?.skills ?? await discoverAllSkills();
|
|
20657
20695
|
const skillCommands = skills.map(skillToCommandInfo);
|
|
20658
20696
|
return [
|
|
20659
20697
|
...opencodeProjectCommands,
|
|
@@ -20663,8 +20701,8 @@ async function discoverAllCommands() {
|
|
|
20663
20701
|
...skillCommands
|
|
20664
20702
|
];
|
|
20665
20703
|
}
|
|
20666
|
-
async function findCommand2(commandName) {
|
|
20667
|
-
const allCommands = await discoverAllCommands();
|
|
20704
|
+
async function findCommand2(commandName, options) {
|
|
20705
|
+
const allCommands = await discoverAllCommands(options);
|
|
20668
20706
|
return allCommands.find((cmd) => cmd.name.toLowerCase() === commandName.toLowerCase()) ?? null;
|
|
20669
20707
|
}
|
|
20670
20708
|
async function formatCommandTemplate(cmd, args) {
|
|
@@ -20693,8 +20731,12 @@ async function formatCommandTemplate(cmd, args) {
|
|
|
20693
20731
|
`);
|
|
20694
20732
|
sections.push(`## Command Instructions
|
|
20695
20733
|
`);
|
|
20734
|
+
let content = cmd.content || "";
|
|
20735
|
+
if (!content && cmd.lazyContentLoader) {
|
|
20736
|
+
content = await cmd.lazyContentLoader.load();
|
|
20737
|
+
}
|
|
20696
20738
|
const commandDir = cmd.path ? dirname8(cmd.path) : process.cwd();
|
|
20697
|
-
const withFileRefs = await resolveFileReferencesInText(
|
|
20739
|
+
const withFileRefs = await resolveFileReferencesInText(content, commandDir);
|
|
20698
20740
|
const resolvedContent = await resolveCommandsInText(withFileRefs);
|
|
20699
20741
|
sections.push(resolvedContent.trim());
|
|
20700
20742
|
if (args) {
|
|
@@ -20709,8 +20751,8 @@ async function formatCommandTemplate(cmd, args) {
|
|
|
20709
20751
|
return sections.join(`
|
|
20710
20752
|
`);
|
|
20711
20753
|
}
|
|
20712
|
-
async function executeSlashCommand(parsed) {
|
|
20713
|
-
const command = await findCommand2(parsed.command);
|
|
20754
|
+
async function executeSlashCommand(parsed, options) {
|
|
20755
|
+
const command = await findCommand2(parsed.command, options);
|
|
20714
20756
|
if (!command) {
|
|
20715
20757
|
return {
|
|
20716
20758
|
success: false,
|
|
@@ -20733,7 +20775,10 @@ async function executeSlashCommand(parsed) {
|
|
|
20733
20775
|
|
|
20734
20776
|
// src/hooks/auto-slash-command/index.ts
|
|
20735
20777
|
var sessionProcessedCommands = new Set;
|
|
20736
|
-
function createAutoSlashCommandHook() {
|
|
20778
|
+
function createAutoSlashCommandHook(options) {
|
|
20779
|
+
const executorOptions = {
|
|
20780
|
+
skills: options?.skills
|
|
20781
|
+
};
|
|
20737
20782
|
return {
|
|
20738
20783
|
"chat.message": async (input, output) => {
|
|
20739
20784
|
const promptText = extractPromptText3(output.parts);
|
|
@@ -20753,7 +20798,7 @@ function createAutoSlashCommandHook() {
|
|
|
20753
20798
|
sessionID: input.sessionID,
|
|
20754
20799
|
args: parsed.args
|
|
20755
20800
|
});
|
|
20756
|
-
const result = await executeSlashCommand(parsed);
|
|
20801
|
+
const result = await executeSlashCommand(parsed, executorOptions);
|
|
20757
20802
|
const idx = output.parts.findIndex((p) => p.type === "text" && p.text);
|
|
20758
20803
|
if (idx < 0) {
|
|
20759
20804
|
return;
|
|
@@ -22789,7 +22834,7 @@ async function createGoogleAntigravityAuthPlugin({
|
|
|
22789
22834
|
// src/features/builtin-skills/skills.ts
|
|
22790
22835
|
var playwrightSkill = {
|
|
22791
22836
|
name: "playwright",
|
|
22792
|
-
description: "Browser automation
|
|
22837
|
+
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.",
|
|
22793
22838
|
template: `# Playwright Browser Automation
|
|
22794
22839
|
|
|
22795
22840
|
This skill provides browser automation capabilities via the Playwright MCP server.`,
|
|
@@ -23535,7 +23580,7 @@ function getAllServers() {
|
|
|
23535
23580
|
return result;
|
|
23536
23581
|
}
|
|
23537
23582
|
// src/tools/lsp/client.ts
|
|
23538
|
-
var {spawn:
|
|
23583
|
+
var {spawn: spawn6 } = globalThis.Bun;
|
|
23539
23584
|
import { readFileSync as readFileSync26 } from "fs";
|
|
23540
23585
|
import { extname, resolve as resolve6 } from "path";
|
|
23541
23586
|
class LSPServerManager {
|
|
@@ -23702,7 +23747,7 @@ class LSPClient {
|
|
|
23702
23747
|
this.server = server;
|
|
23703
23748
|
}
|
|
23704
23749
|
async start() {
|
|
23705
|
-
this.proc =
|
|
23750
|
+
this.proc = spawn6(this.server.command, {
|
|
23706
23751
|
stdin: "pipe",
|
|
23707
23752
|
stdout: "pipe",
|
|
23708
23753
|
stderr: "pipe",
|
|
@@ -37058,7 +37103,7 @@ import { dirname as dirname9, join as join47 } from "path";
|
|
|
37058
37103
|
import { existsSync as existsSync40, statSync as statSync4 } from "fs";
|
|
37059
37104
|
|
|
37060
37105
|
// src/tools/ast-grep/downloader.ts
|
|
37061
|
-
var {spawn:
|
|
37106
|
+
var {spawn: spawn7 } = globalThis.Bun;
|
|
37062
37107
|
import { existsSync as existsSync39, mkdirSync as mkdirSync11, chmodSync as chmodSync2, unlinkSync as unlinkSync10 } from "fs";
|
|
37063
37108
|
import { join as join46 } from "path";
|
|
37064
37109
|
import { homedir as homedir15 } from "os";
|
|
@@ -37101,11 +37146,11 @@ function getCachedBinaryPath2() {
|
|
|
37101
37146
|
return existsSync39(binaryPath) ? binaryPath : null;
|
|
37102
37147
|
}
|
|
37103
37148
|
async function extractZip2(archivePath, destDir) {
|
|
37104
|
-
const proc = process.platform === "win32" ?
|
|
37149
|
+
const proc = process.platform === "win32" ? spawn7([
|
|
37105
37150
|
"powershell",
|
|
37106
37151
|
"-command",
|
|
37107
37152
|
`Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force`
|
|
37108
|
-
], { stdout: "pipe", stderr: "pipe" }) :
|
|
37153
|
+
], { stdout: "pipe", stderr: "pipe" }) : spawn7(["unzip", "-o", archivePath, "-d", destDir], { stdout: "pipe", stderr: "pipe" });
|
|
37109
37154
|
const exitCode = await proc.exited;
|
|
37110
37155
|
if (exitCode !== 0) {
|
|
37111
37156
|
const stderr = await new Response(proc.stderr).text();
|
|
@@ -37273,7 +37318,7 @@ var DEFAULT_MAX_OUTPUT_BYTES = 1 * 1024 * 1024;
|
|
|
37273
37318
|
var DEFAULT_MAX_MATCHES = 500;
|
|
37274
37319
|
|
|
37275
37320
|
// src/tools/ast-grep/cli.ts
|
|
37276
|
-
var {spawn:
|
|
37321
|
+
var {spawn: spawn8 } = globalThis.Bun;
|
|
37277
37322
|
import { existsSync as existsSync41 } from "fs";
|
|
37278
37323
|
var resolvedCliPath3 = null;
|
|
37279
37324
|
var initPromise2 = null;
|
|
@@ -37327,7 +37372,7 @@ async function runSg(options) {
|
|
|
37327
37372
|
}
|
|
37328
37373
|
}
|
|
37329
37374
|
const timeout = DEFAULT_TIMEOUT_MS;
|
|
37330
|
-
const proc =
|
|
37375
|
+
const proc = spawn8([cliPath, ...args], {
|
|
37331
37376
|
stdout: "pipe",
|
|
37332
37377
|
stderr: "pipe"
|
|
37333
37378
|
});
|
|
@@ -37581,7 +37626,7 @@ var ast_grep_replace = tool({
|
|
|
37581
37626
|
}
|
|
37582
37627
|
});
|
|
37583
37628
|
// src/tools/grep/cli.ts
|
|
37584
|
-
var {spawn:
|
|
37629
|
+
var {spawn: spawn10 } = globalThis.Bun;
|
|
37585
37630
|
|
|
37586
37631
|
// src/tools/grep/constants.ts
|
|
37587
37632
|
import { existsSync as existsSync43 } from "fs";
|
|
@@ -37591,7 +37636,7 @@ import { spawnSync } from "child_process";
|
|
|
37591
37636
|
// src/tools/grep/downloader.ts
|
|
37592
37637
|
import { existsSync as existsSync42, mkdirSync as mkdirSync12, chmodSync as chmodSync3, unlinkSync as unlinkSync11, readdirSync as readdirSync12 } from "fs";
|
|
37593
37638
|
import { join as join48 } from "path";
|
|
37594
|
-
var {spawn:
|
|
37639
|
+
var {spawn: spawn9 } = globalThis.Bun;
|
|
37595
37640
|
function findFileRecursive(dir, filename) {
|
|
37596
37641
|
try {
|
|
37597
37642
|
const entries = readdirSync12(dir, { withFileTypes: true, recursive: true });
|
|
@@ -37640,7 +37685,7 @@ async function extractTarGz2(archivePath, destDir) {
|
|
|
37640
37685
|
} else if (platformKey.endsWith("-linux")) {
|
|
37641
37686
|
args.push("--wildcards", "*/rg");
|
|
37642
37687
|
}
|
|
37643
|
-
const proc =
|
|
37688
|
+
const proc = spawn9(args, {
|
|
37644
37689
|
cwd: destDir,
|
|
37645
37690
|
stdout: "pipe",
|
|
37646
37691
|
stderr: "pipe"
|
|
@@ -37652,7 +37697,7 @@ async function extractTarGz2(archivePath, destDir) {
|
|
|
37652
37697
|
}
|
|
37653
37698
|
}
|
|
37654
37699
|
async function extractZipWindows(archivePath, destDir) {
|
|
37655
|
-
const proc =
|
|
37700
|
+
const proc = spawn9(["powershell", "-Command", `Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force`], { stdout: "pipe", stderr: "pipe" });
|
|
37656
37701
|
const exitCode = await proc.exited;
|
|
37657
37702
|
if (exitCode !== 0) {
|
|
37658
37703
|
throw new Error("Failed to extract zip with PowerShell");
|
|
@@ -37667,7 +37712,7 @@ async function extractZipWindows(archivePath, destDir) {
|
|
|
37667
37712
|
}
|
|
37668
37713
|
}
|
|
37669
37714
|
async function extractZipUnix(archivePath, destDir) {
|
|
37670
|
-
const proc =
|
|
37715
|
+
const proc = spawn9(["unzip", "-o", archivePath, "-d", destDir], {
|
|
37671
37716
|
stdout: "pipe",
|
|
37672
37717
|
stderr: "pipe"
|
|
37673
37718
|
});
|
|
@@ -37924,7 +37969,7 @@ async function runRg(options) {
|
|
|
37924
37969
|
}
|
|
37925
37970
|
const paths = options.paths?.length ? options.paths : ["."];
|
|
37926
37971
|
args.push(...paths);
|
|
37927
|
-
const proc =
|
|
37972
|
+
const proc = spawn10([cli.path, ...args], {
|
|
37928
37973
|
stdout: "pipe",
|
|
37929
37974
|
stderr: "pipe"
|
|
37930
37975
|
});
|
|
@@ -38026,7 +38071,7 @@ var grep = tool({
|
|
|
38026
38071
|
});
|
|
38027
38072
|
|
|
38028
38073
|
// src/tools/glob/cli.ts
|
|
38029
|
-
var {spawn:
|
|
38074
|
+
var {spawn: spawn11 } = globalThis.Bun;
|
|
38030
38075
|
|
|
38031
38076
|
// src/tools/glob/constants.ts
|
|
38032
38077
|
var DEFAULT_TIMEOUT_MS3 = 60000;
|
|
@@ -38108,7 +38153,7 @@ async function runRgFiles(options, resolvedCli) {
|
|
|
38108
38153
|
cwd = paths[0] || ".";
|
|
38109
38154
|
command = [cli.path, ...args];
|
|
38110
38155
|
}
|
|
38111
|
-
const proc =
|
|
38156
|
+
const proc = spawn11(command, {
|
|
38112
38157
|
stdout: "pipe",
|
|
38113
38158
|
stderr: "pipe",
|
|
38114
38159
|
cwd
|
|
@@ -38277,7 +38322,8 @@ function skillToCommandInfo2(skill) {
|
|
|
38277
38322
|
subtask: skill.definition.subtask
|
|
38278
38323
|
},
|
|
38279
38324
|
content: skill.definition.template,
|
|
38280
|
-
scope: skill.scope
|
|
38325
|
+
scope: skill.scope,
|
|
38326
|
+
lazyContentLoader: skill.lazyContent
|
|
38281
38327
|
};
|
|
38282
38328
|
}
|
|
38283
38329
|
async function formatLoadedCommand(cmd) {
|
|
@@ -38310,8 +38356,12 @@ async function formatLoadedCommand(cmd) {
|
|
|
38310
38356
|
`);
|
|
38311
38357
|
sections.push(`## Command Instructions
|
|
38312
38358
|
`);
|
|
38359
|
+
let content = cmd.content || "";
|
|
38360
|
+
if (!content && cmd.lazyContentLoader) {
|
|
38361
|
+
content = await cmd.lazyContentLoader.load();
|
|
38362
|
+
}
|
|
38313
38363
|
const commandDir = cmd.path ? dirname11(cmd.path) : process.cwd();
|
|
38314
|
-
const withFileRefs = await resolveFileReferencesInText(
|
|
38364
|
+
const withFileRefs = await resolveFileReferencesInText(content, commandDir);
|
|
38315
38365
|
const resolvedContent = await resolveCommandsInText(withFileRefs);
|
|
38316
38366
|
sections.push(resolvedContent.trim());
|
|
38317
38367
|
return sections.join(`
|
|
@@ -38992,14 +39042,14 @@ For: server processes, long-running tasks, background jobs, interactive CLI tool
|
|
|
38992
39042
|
Blocked (use bash instead): capture-pane, save-buffer, show-buffer, pipe-pane.`;
|
|
38993
39043
|
|
|
38994
39044
|
// src/tools/interactive-bash/utils.ts
|
|
38995
|
-
var {spawn:
|
|
39045
|
+
var {spawn: spawn12 } = globalThis.Bun;
|
|
38996
39046
|
var tmuxPath = null;
|
|
38997
39047
|
var initPromise3 = null;
|
|
38998
39048
|
async function findTmuxPath() {
|
|
38999
39049
|
const isWindows2 = process.platform === "win32";
|
|
39000
39050
|
const cmd = isWindows2 ? "where" : "which";
|
|
39001
39051
|
try {
|
|
39002
|
-
const proc =
|
|
39052
|
+
const proc = spawn12([cmd, "tmux"], {
|
|
39003
39053
|
stdout: "pipe",
|
|
39004
39054
|
stderr: "pipe"
|
|
39005
39055
|
});
|
|
@@ -39013,7 +39063,7 @@ async function findTmuxPath() {
|
|
|
39013
39063
|
if (!path7) {
|
|
39014
39064
|
return null;
|
|
39015
39065
|
}
|
|
39016
|
-
const verifyProc =
|
|
39066
|
+
const verifyProc = spawn12([path7, "-V"], {
|
|
39017
39067
|
stdout: "pipe",
|
|
39018
39068
|
stderr: "pipe"
|
|
39019
39069
|
});
|
|
@@ -40056,6 +40106,67 @@ var builtinTools = {
|
|
|
40056
40106
|
// src/features/background-agent/manager.ts
|
|
40057
40107
|
import { existsSync as existsSync47, readdirSync as readdirSync16 } from "fs";
|
|
40058
40108
|
import { join as join54 } from "path";
|
|
40109
|
+
|
|
40110
|
+
// src/features/background-agent/concurrency.ts
|
|
40111
|
+
class ConcurrencyManager {
|
|
40112
|
+
config;
|
|
40113
|
+
counts = new Map;
|
|
40114
|
+
queues = new Map;
|
|
40115
|
+
constructor(config3) {
|
|
40116
|
+
this.config = config3;
|
|
40117
|
+
}
|
|
40118
|
+
getConcurrencyLimit(model) {
|
|
40119
|
+
const modelLimit = this.config?.modelConcurrency?.[model];
|
|
40120
|
+
if (modelLimit !== undefined) {
|
|
40121
|
+
return modelLimit === 0 ? Infinity : modelLimit;
|
|
40122
|
+
}
|
|
40123
|
+
const provider = model.split("/")[0];
|
|
40124
|
+
const providerLimit = this.config?.providerConcurrency?.[provider];
|
|
40125
|
+
if (providerLimit !== undefined) {
|
|
40126
|
+
return providerLimit === 0 ? Infinity : providerLimit;
|
|
40127
|
+
}
|
|
40128
|
+
const defaultLimit = this.config?.defaultConcurrency;
|
|
40129
|
+
if (defaultLimit !== undefined) {
|
|
40130
|
+
return defaultLimit === 0 ? Infinity : defaultLimit;
|
|
40131
|
+
}
|
|
40132
|
+
return 5;
|
|
40133
|
+
}
|
|
40134
|
+
async acquire(model) {
|
|
40135
|
+
const limit = this.getConcurrencyLimit(model);
|
|
40136
|
+
if (limit === Infinity) {
|
|
40137
|
+
return;
|
|
40138
|
+
}
|
|
40139
|
+
const current = this.counts.get(model) ?? 0;
|
|
40140
|
+
if (current < limit) {
|
|
40141
|
+
this.counts.set(model, current + 1);
|
|
40142
|
+
return;
|
|
40143
|
+
}
|
|
40144
|
+
return new Promise((resolve8) => {
|
|
40145
|
+
const queue = this.queues.get(model) ?? [];
|
|
40146
|
+
queue.push(resolve8);
|
|
40147
|
+
this.queues.set(model, queue);
|
|
40148
|
+
});
|
|
40149
|
+
}
|
|
40150
|
+
release(model) {
|
|
40151
|
+
const limit = this.getConcurrencyLimit(model);
|
|
40152
|
+
if (limit === Infinity) {
|
|
40153
|
+
return;
|
|
40154
|
+
}
|
|
40155
|
+
const queue = this.queues.get(model);
|
|
40156
|
+
if (queue && queue.length > 0) {
|
|
40157
|
+
const next = queue.shift();
|
|
40158
|
+
this.counts.set(model, this.counts.get(model) ?? 0);
|
|
40159
|
+
next();
|
|
40160
|
+
} else {
|
|
40161
|
+
const current = this.counts.get(model) ?? 0;
|
|
40162
|
+
if (current > 0) {
|
|
40163
|
+
this.counts.set(model, current - 1);
|
|
40164
|
+
}
|
|
40165
|
+
}
|
|
40166
|
+
}
|
|
40167
|
+
}
|
|
40168
|
+
|
|
40169
|
+
// src/features/background-agent/manager.ts
|
|
40059
40170
|
var TASK_TTL_MS = 30 * 60 * 1000;
|
|
40060
40171
|
function getMessageDir11(sessionID) {
|
|
40061
40172
|
if (!existsSync47(MESSAGE_STORAGE))
|
|
@@ -40077,23 +40188,31 @@ class BackgroundManager {
|
|
|
40077
40188
|
client;
|
|
40078
40189
|
directory;
|
|
40079
40190
|
pollingInterval;
|
|
40080
|
-
|
|
40191
|
+
concurrencyManager;
|
|
40192
|
+
constructor(ctx, config3) {
|
|
40081
40193
|
this.tasks = new Map;
|
|
40082
40194
|
this.notifications = new Map;
|
|
40083
40195
|
this.client = ctx.client;
|
|
40084
40196
|
this.directory = ctx.directory;
|
|
40197
|
+
this.concurrencyManager = new ConcurrencyManager(config3);
|
|
40085
40198
|
}
|
|
40086
40199
|
async launch(input) {
|
|
40087
40200
|
if (!input.agent || input.agent.trim() === "") {
|
|
40088
40201
|
throw new Error("Agent parameter is required");
|
|
40089
40202
|
}
|
|
40203
|
+
const model = input.agent;
|
|
40204
|
+
await this.concurrencyManager.acquire(model);
|
|
40090
40205
|
const createResult = await this.client.session.create({
|
|
40091
40206
|
body: {
|
|
40092
40207
|
parentID: input.parentSessionID,
|
|
40093
40208
|
title: `Background: ${input.description}`
|
|
40094
40209
|
}
|
|
40210
|
+
}).catch((error45) => {
|
|
40211
|
+
this.concurrencyManager.release(model);
|
|
40212
|
+
throw error45;
|
|
40095
40213
|
});
|
|
40096
40214
|
if (createResult.error) {
|
|
40215
|
+
this.concurrencyManager.release(model);
|
|
40097
40216
|
throw new Error(`Failed to create background session: ${createResult.error}`);
|
|
40098
40217
|
}
|
|
40099
40218
|
const sessionID = createResult.data.id;
|
|
@@ -40112,7 +40231,8 @@ class BackgroundManager {
|
|
|
40112
40231
|
toolCalls: 0,
|
|
40113
40232
|
lastUpdate: new Date
|
|
40114
40233
|
},
|
|
40115
|
-
parentModel: input.parentModel
|
|
40234
|
+
parentModel: input.parentModel,
|
|
40235
|
+
model
|
|
40116
40236
|
};
|
|
40117
40237
|
this.tasks.set(task.id, task);
|
|
40118
40238
|
this.startPolling();
|
|
@@ -40140,6 +40260,9 @@ class BackgroundManager {
|
|
|
40140
40260
|
existingTask.error = errorMessage;
|
|
40141
40261
|
}
|
|
40142
40262
|
existingTask.completedAt = new Date;
|
|
40263
|
+
if (existingTask.model) {
|
|
40264
|
+
this.concurrencyManager.release(existingTask.model);
|
|
40265
|
+
}
|
|
40143
40266
|
this.markForNotification(existingTask);
|
|
40144
40267
|
this.notifyParentSession(existingTask);
|
|
40145
40268
|
}
|
|
@@ -40246,6 +40369,9 @@ class BackgroundManager {
|
|
|
40246
40369
|
task.completedAt = new Date;
|
|
40247
40370
|
task.error = "Session deleted";
|
|
40248
40371
|
}
|
|
40372
|
+
if (task.model) {
|
|
40373
|
+
this.concurrencyManager.release(task.model);
|
|
40374
|
+
}
|
|
40249
40375
|
this.tasks.delete(task.id);
|
|
40250
40376
|
this.clearNotificationsForTask(task.id);
|
|
40251
40377
|
subagentSessions.delete(sessionID);
|
|
@@ -40309,6 +40435,9 @@ class BackgroundManager {
|
|
|
40309
40435
|
log("[background-agent] Sending notification to parent session:", { parentSessionID: task.parentSessionID });
|
|
40310
40436
|
const taskId = task.id;
|
|
40311
40437
|
setTimeout(async () => {
|
|
40438
|
+
if (task.model) {
|
|
40439
|
+
this.concurrencyManager.release(task.model);
|
|
40440
|
+
}
|
|
40312
40441
|
try {
|
|
40313
40442
|
const messageDir = getMessageDir11(task.parentSessionID);
|
|
40314
40443
|
const prevMessage = messageDir ? findNearestMessageWithFields(messageDir) : null;
|
|
@@ -40361,6 +40490,9 @@ class BackgroundManager {
|
|
|
40361
40490
|
task.status = "error";
|
|
40362
40491
|
task.error = "Task timed out after 30 minutes";
|
|
40363
40492
|
task.completedAt = new Date;
|
|
40493
|
+
if (task.model) {
|
|
40494
|
+
this.concurrencyManager.release(task.model);
|
|
40495
|
+
}
|
|
40364
40496
|
this.clearNotificationsForTask(taskId);
|
|
40365
40497
|
this.tasks.delete(taskId);
|
|
40366
40498
|
subagentSessions.delete(task.sessionID);
|
|
@@ -43231,7 +43363,7 @@ import * as fs11 from "fs";
|
|
|
43231
43363
|
import * as path7 from "path";
|
|
43232
43364
|
|
|
43233
43365
|
// src/mcp/types.ts
|
|
43234
|
-
var McpNameSchema = exports_external.enum(["context7", "grep_app"]);
|
|
43366
|
+
var McpNameSchema = exports_external.enum(["websearch", "context7", "grep_app"]);
|
|
43235
43367
|
var AnyMcpNameSchema = exports_external.string().min(1);
|
|
43236
43368
|
|
|
43237
43369
|
// src/config/schema.ts
|
|
@@ -43428,6 +43560,11 @@ var RalphLoopConfigSchema = exports_external.object({
|
|
|
43428
43560
|
default_max_iterations: exports_external.number().min(1).max(1000).default(100),
|
|
43429
43561
|
state_dir: exports_external.string().optional()
|
|
43430
43562
|
});
|
|
43563
|
+
var BackgroundTaskConfigSchema = exports_external.object({
|
|
43564
|
+
defaultConcurrency: exports_external.number().min(1).optional(),
|
|
43565
|
+
providerConcurrency: exports_external.record(exports_external.string(), exports_external.number().min(1)).optional(),
|
|
43566
|
+
modelConcurrency: exports_external.record(exports_external.string(), exports_external.number().min(1)).optional()
|
|
43567
|
+
});
|
|
43431
43568
|
var OhMyOpenCodeConfigSchema = exports_external.object({
|
|
43432
43569
|
$schema: exports_external.string().optional(),
|
|
43433
43570
|
disabled_mcps: exports_external.array(AnyMcpNameSchema).optional(),
|
|
@@ -43443,7 +43580,8 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
|
|
|
43443
43580
|
experimental: ExperimentalConfigSchema.optional(),
|
|
43444
43581
|
auto_update: exports_external.boolean().optional(),
|
|
43445
43582
|
skills: SkillsConfigSchema.optional(),
|
|
43446
|
-
ralph_loop: RalphLoopConfigSchema.optional()
|
|
43583
|
+
ralph_loop: RalphLoopConfigSchema.optional(),
|
|
43584
|
+
background_task: BackgroundTaskConfigSchema.optional()
|
|
43447
43585
|
});
|
|
43448
43586
|
// src/plugin-config.ts
|
|
43449
43587
|
function loadConfigFromPath2(configPath, ctx) {
|
|
@@ -44356,8 +44494,7 @@ function createOracleAgent(model = DEFAULT_MODEL2) {
|
|
|
44356
44494
|
const restrictions = createAgentToolRestrictions([
|
|
44357
44495
|
"write",
|
|
44358
44496
|
"edit",
|
|
44359
|
-
"task"
|
|
44360
|
-
"background_task"
|
|
44497
|
+
"task"
|
|
44361
44498
|
]);
|
|
44362
44499
|
const base = {
|
|
44363
44500
|
description: "Expert technical advisor with deep reasoning for architecture decisions, code analysis, and engineering guidance.",
|
|
@@ -44375,7 +44512,7 @@ function createOracleAgent(model = DEFAULT_MODEL2) {
|
|
|
44375
44512
|
var oracleAgent = createOracleAgent();
|
|
44376
44513
|
|
|
44377
44514
|
// src/agents/librarian.ts
|
|
44378
|
-
var DEFAULT_MODEL3 = "
|
|
44515
|
+
var DEFAULT_MODEL3 = "opencode/glm-4.7-free";
|
|
44379
44516
|
var LIBRARIAN_PROMPT_METADATA = {
|
|
44380
44517
|
category: "exploration",
|
|
44381
44518
|
cost: "CHEAP",
|
|
@@ -44395,8 +44532,7 @@ var LIBRARIAN_PROMPT_METADATA = {
|
|
|
44395
44532
|
function createLibrarianAgent(model = DEFAULT_MODEL3) {
|
|
44396
44533
|
const restrictions = createAgentToolRestrictions([
|
|
44397
44534
|
"write",
|
|
44398
|
-
"edit"
|
|
44399
|
-
"background_task"
|
|
44535
|
+
"edit"
|
|
44400
44536
|
]);
|
|
44401
44537
|
return {
|
|
44402
44538
|
description: "Specialized codebase understanding agent for multi-repository analysis, searching remote codebases, retrieving official documentation, and finding implementation examples using GitHub CLI, Context7, and Web Search. MUST BE USED when users ask to look up code in remote repositories, explain library internals, or find usage examples in open source.",
|
|
@@ -44408,7 +44544,7 @@ function createLibrarianAgent(model = DEFAULT_MODEL3) {
|
|
|
44408
44544
|
|
|
44409
44545
|
You are **THE LIBRARIAN**, a specialized open-source codebase understanding agent.
|
|
44410
44546
|
|
|
44411
|
-
Your job: Answer questions about open-source libraries
|
|
44547
|
+
Your job: Answer questions about open-source libraries. Provide **EVIDENCE** with **GitHub permalinks** when the question requires verification, implementation details, or current/version-specific information. For well-known APIs and stable concepts, answer directly from knowledge.
|
|
44412
44548
|
|
|
44413
44549
|
## CRITICAL: DATE AWARENESS
|
|
44414
44550
|
|
|
@@ -44420,9 +44556,13 @@ Your job: Answer questions about open-source libraries by finding **EVIDENCE** w
|
|
|
44420
44556
|
|
|
44421
44557
|
---
|
|
44422
44558
|
|
|
44423
|
-
## PHASE 0:
|
|
44559
|
+
## PHASE 0: ASSESS BEFORE SEARCHING
|
|
44424
44560
|
|
|
44425
|
-
|
|
44561
|
+
**First**: Can you answer confidently from training knowledge? If yes, answer directly.
|
|
44562
|
+
|
|
44563
|
+
**Search when**: version-specific info, implementation internals, recent changes, unfamiliar libraries, user explicitly requests source/examples.
|
|
44564
|
+
|
|
44565
|
+
**If search needed**, classify into:
|
|
44426
44566
|
|
|
44427
44567
|
| Type | Trigger Examples | Tools |
|
|
44428
44568
|
|------|------------------|-------|
|
|
@@ -44438,7 +44578,7 @@ Classify EVERY request into one of these categories before taking action:
|
|
|
44438
44578
|
### TYPE A: CONCEPTUAL QUESTION
|
|
44439
44579
|
**Trigger**: "How do I...", "What is...", "Best practice for...", rough/general questions
|
|
44440
44580
|
|
|
44441
|
-
**
|
|
44581
|
+
**If searching**, use tools as needed:
|
|
44442
44582
|
\`\`\`
|
|
44443
44583
|
Tool 1: context7_resolve-library-id("library-name")
|
|
44444
44584
|
\u2192 then context7_get-library-docs(id, topic: "specific-topic")
|
|
@@ -44470,7 +44610,7 @@ Step 4: Construct permalink
|
|
|
44470
44610
|
https://github.com/owner/repo/blob/<sha>/path/to/file#L10-L20
|
|
44471
44611
|
\`\`\`
|
|
44472
44612
|
|
|
44473
|
-
**
|
|
44613
|
+
**For faster results, parallelize**:
|
|
44474
44614
|
\`\`\`
|
|
44475
44615
|
Tool 1: gh repo clone owner/repo \${TMPDIR:-/tmp}/repo -- --depth 1
|
|
44476
44616
|
Tool 2: grep_app_searchGitHub(query: "function_name", repo: "owner/repo")
|
|
@@ -44483,7 +44623,7 @@ Tool 4: context7_get-library-docs(id, topic: "relevant-api")
|
|
|
44483
44623
|
### TYPE C: CONTEXT & HISTORY
|
|
44484
44624
|
**Trigger**: "Why was this changed?", "What's the history?", "Related issues/PRs?"
|
|
44485
44625
|
|
|
44486
|
-
**
|
|
44626
|
+
**Tools to use**:
|
|
44487
44627
|
\`\`\`
|
|
44488
44628
|
Tool 1: gh search issues "keyword" --repo owner/repo --state all --limit 10
|
|
44489
44629
|
Tool 2: gh search prs "keyword" --repo owner/repo --state merged --limit 10
|
|
@@ -44505,7 +44645,7 @@ gh api repos/owner/repo/pulls/<number>/files
|
|
|
44505
44645
|
### TYPE D: COMPREHENSIVE RESEARCH
|
|
44506
44646
|
**Trigger**: Complex questions, ambiguous requests, "deep dive into..."
|
|
44507
44647
|
|
|
44508
|
-
**
|
|
44648
|
+
**Use multiple tools as needed**:
|
|
44509
44649
|
\`\`\`
|
|
44510
44650
|
// Documentation
|
|
44511
44651
|
Tool 1: context7_resolve-library-id \u2192 context7_get-library-docs
|
|
@@ -44591,14 +44731,16 @@ Use OS-appropriate temp directory:
|
|
|
44591
44731
|
|
|
44592
44732
|
---
|
|
44593
44733
|
|
|
44594
|
-
## PARALLEL EXECUTION
|
|
44734
|
+
## PARALLEL EXECUTION GUIDANCE
|
|
44595
44735
|
|
|
44596
|
-
|
|
44597
|
-
|
|
44598
|
-
|
|
|
44599
|
-
|
|
44600
|
-
| TYPE
|
|
44601
|
-
| TYPE
|
|
44736
|
+
When searching is needed, scale effort to question complexity:
|
|
44737
|
+
|
|
44738
|
+
| Request Type | Suggested Calls |
|
|
44739
|
+
|--------------|----------------|
|
|
44740
|
+
| TYPE A (Conceptual) | 1-2 |
|
|
44741
|
+
| TYPE B (Implementation) | 2-3 |
|
|
44742
|
+
| TYPE C (Context) | 2-3 |
|
|
44743
|
+
| TYPE D (Comprehensive) | 3-5 |
|
|
44602
44744
|
|
|
44603
44745
|
**Always vary queries** when using grep_app:
|
|
44604
44746
|
\`\`\`
|
|
@@ -44663,8 +44805,7 @@ var EXPLORE_PROMPT_METADATA = {
|
|
|
44663
44805
|
function createExploreAgent(model = DEFAULT_MODEL4) {
|
|
44664
44806
|
const restrictions = createAgentToolRestrictions([
|
|
44665
44807
|
"write",
|
|
44666
|
-
"edit"
|
|
44667
|
-
"background_task"
|
|
44808
|
+
"edit"
|
|
44668
44809
|
]);
|
|
44669
44810
|
return {
|
|
44670
44811
|
description: 'Contextual grep for codebases. Answers "Where is X?", "Which file has Y?", "Find the code that does Z". Fire multiple in parallel for broad searches. Specify thoroughness: "quick" for basic, "medium" for moderate, "very thorough" for comprehensive analysis.',
|
|
@@ -44772,7 +44913,7 @@ var FRONTEND_PROMPT_METADATA = {
|
|
|
44772
44913
|
]
|
|
44773
44914
|
};
|
|
44774
44915
|
function createFrontendUiUxEngineerAgent(model = DEFAULT_MODEL5) {
|
|
44775
|
-
const restrictions = createAgentToolRestrictions([
|
|
44916
|
+
const restrictions = createAgentToolRestrictions([]);
|
|
44776
44917
|
return {
|
|
44777
44918
|
description: "A designer-turned-developer who crafts stunning UI/UX even without design mockups. Code may be a bit messy, but the visual output is always fire.",
|
|
44778
44919
|
mode: "subagent",
|
|
@@ -44866,7 +45007,7 @@ var DOCUMENT_WRITER_PROMPT_METADATA = {
|
|
|
44866
45007
|
]
|
|
44867
45008
|
};
|
|
44868
45009
|
function createDocumentWriterAgent(model = DEFAULT_MODEL6) {
|
|
44869
|
-
const restrictions = createAgentToolRestrictions([
|
|
45010
|
+
const restrictions = createAgentToolRestrictions([]);
|
|
44870
45011
|
return {
|
|
44871
45012
|
description: "A technical writer who crafts clear, comprehensive documentation. Specializes in README files, API docs, architecture docs, and user guides. MUST BE USED when executing documentation tasks from ai-todo list plans.",
|
|
44872
45013
|
mode: "subagent",
|
|
@@ -45082,8 +45223,7 @@ function createMultimodalLookerAgent(model = DEFAULT_MODEL7) {
|
|
|
45082
45223
|
const restrictions = createAgentToolRestrictions([
|
|
45083
45224
|
"write",
|
|
45084
45225
|
"edit",
|
|
45085
|
-
"bash"
|
|
45086
|
-
"background_task"
|
|
45226
|
+
"bash"
|
|
45087
45227
|
]);
|
|
45088
45228
|
return {
|
|
45089
45229
|
description: "Analyze media files (PDFs, images, diagrams) that require interpretation beyond raw text. Extracts specific information or summaries from documents, describes visual content. Use when you need analyzed/extracted data rather than literal file contents.",
|
|
@@ -46782,6 +46922,13 @@ async function loadAllPluginComponents(options) {
|
|
|
46782
46922
|
errors: errors3
|
|
46783
46923
|
};
|
|
46784
46924
|
}
|
|
46925
|
+
// src/mcp/websearch.ts
|
|
46926
|
+
var websearch = {
|
|
46927
|
+
type: "remote",
|
|
46928
|
+
url: "https://mcp.exa.ai/mcp?tools=web_search_exa",
|
|
46929
|
+
enabled: true
|
|
46930
|
+
};
|
|
46931
|
+
|
|
46785
46932
|
// src/mcp/context7.ts
|
|
46786
46933
|
var context7 = {
|
|
46787
46934
|
type: "remote",
|
|
@@ -46798,6 +46945,7 @@ var grep_app = {
|
|
|
46798
46945
|
|
|
46799
46946
|
// src/mcp/index.ts
|
|
46800
46947
|
var allBuiltinMcps = {
|
|
46948
|
+
websearch,
|
|
46801
46949
|
context7,
|
|
46802
46950
|
grep_app
|
|
46803
46951
|
};
|
|
@@ -47121,7 +47269,6 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
47121
47269
|
config: pluginConfig.ralph_loop,
|
|
47122
47270
|
checkSessionExists: async (sessionId) => sessionExists(sessionId)
|
|
47123
47271
|
}) : null;
|
|
47124
|
-
const autoSlashCommand = isHookEnabled("auto-slash-command") ? createAutoSlashCommandHook() : null;
|
|
47125
47272
|
const editErrorRecovery = isHookEnabled("edit-error-recovery") ? createEditErrorRecoveryHook(ctx) : null;
|
|
47126
47273
|
const backgroundManager = new BackgroundManager(ctx);
|
|
47127
47274
|
const todoContinuationEnforcer = isHookEnabled("todo-continuation-enforcer") ? createTodoContinuationEnforcer(ctx, { backgroundManager }) : null;
|
|
@@ -47171,6 +47318,7 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
47171
47318
|
commands: commands2,
|
|
47172
47319
|
skills: mergedSkills
|
|
47173
47320
|
});
|
|
47321
|
+
const autoSlashCommand = isHookEnabled("auto-slash-command") ? createAutoSlashCommandHook({ skills: mergedSkills }) : null;
|
|
47174
47322
|
const googleAuthHooks = pluginConfig.google_auth !== false ? await createGoogleAntigravityAuthPlugin(ctx) : null;
|
|
47175
47323
|
const configHandler = createConfigHandler({
|
|
47176
47324
|
ctx,
|