beast-agent 2.14.0 → 2.16.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.
Files changed (41) hide show
  1. package/package.json +1 -1
  2. package/src/agent/engine.js +499 -154
  3. package/src/agent/financetools.js +307 -0
  4. package/src/agent/opencode/agents.js +161 -0
  5. package/src/agent/opencode/askperm.js +135 -0
  6. package/src/agent/opencode/index.js +51 -0
  7. package/src/agent/opencode/permission.js +108 -0
  8. package/src/agent/opencode/prompts/anthropic.txt +105 -0
  9. package/src/agent/opencode/prompts/beast.txt +147 -0
  10. package/src/agent/opencode/prompts/build-switch.txt +5 -0
  11. package/src/agent/opencode/prompts/codex.txt +79 -0
  12. package/src/agent/opencode/prompts/default.txt +95 -0
  13. package/src/agent/opencode/prompts/edit.txt +10 -0
  14. package/src/agent/opencode/prompts/explore.txt +18 -0
  15. package/src/agent/opencode/prompts/gemini.txt +155 -0
  16. package/src/agent/opencode/prompts/glob.txt +6 -0
  17. package/src/agent/opencode/prompts/gpt.txt +107 -0
  18. package/src/agent/opencode/prompts/grep.txt +8 -0
  19. package/src/agent/opencode/prompts/kimi.txt +95 -0
  20. package/src/agent/opencode/prompts/max-steps.txt +16 -0
  21. package/src/agent/opencode/prompts/meta.txt +65 -0
  22. package/src/agent/opencode/prompts/plan.txt +26 -0
  23. package/src/agent/opencode/prompts/read.txt +14 -0
  24. package/src/agent/opencode/prompts/skill.txt +5 -0
  25. package/src/agent/opencode/prompts/task.txt +19 -0
  26. package/src/agent/opencode/prompts/todowrite.txt +44 -0
  27. package/src/agent/opencode/prompts/trinity.txt +97 -0
  28. package/src/agent/opencode/prompts/webfetch.txt +13 -0
  29. package/src/agent/opencode/prompts/websearch.txt +14 -0
  30. package/src/agent/opencode/prompts/write.txt +8 -0
  31. package/src/agent/opencode/systemprompt.js +157 -0
  32. package/src/agent/opencode/toolmap.js +316 -0
  33. package/src/agent/scripts/mt5_bridge.py +381 -0
  34. package/src/agent/tools.js +10 -3
  35. package/src/main.js +503 -69
  36. package/src/mt5bridge.js +215 -0
  37. package/src/preload.js +13 -3
  38. package/src/renderer/index.html +67 -0
  39. package/src/renderer/renderer.js +552 -53
  40. package/src/renderer/style.css +328 -1
  41. package/src/agent/android.js +0 -265
@@ -0,0 +1,97 @@
1
+ You are opencode, an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.
2
+
3
+ # Tone and style
4
+ You should be concise, direct, and to the point. When you run a non-trivial bash command, you should explain what the command does and why you are running it, to make sure the user understands what you are doing (this is especially important when you are running a command that will make changes to the user's system).
5
+ Remember that your output will be displayed on a command line interface. Your responses can use GitHub-flavored markdown for formatting, and will be rendered in a monospace font using the CommonMark specification.
6
+ Output text to communicate with the user; all text you output outside of tool use is displayed to the user. Only use tools to complete tasks. Never use tools like Bash or code comments as means to communicate with the user during the session.
7
+ If you cannot or will not help the user with something, please do not say why or what it could lead to, since this comes across as preachy and annoying. Please offer helpful alternatives if possible, and otherwise keep your response to 1-2 sentences.
8
+ Only use emojis if the user explicitly requests it. Avoid using emojis in all communication unless asked.
9
+ IMPORTANT: You should minimize output tokens as much as possible while maintaining helpfulness, quality, and accuracy. Only address the specific query or task at hand, avoiding tangential information unless absolutely critical for completing the request. If you can answer in 1-3 sentences or a short paragraph, please do.
10
+ IMPORTANT: You should NOT answer with unnecessary preamble or postamble (such as explaining your code or summarizing your action), unless the user asks you to.
11
+ IMPORTANT: Keep your responses short, since they will be displayed on a command line interface. You MUST answer concisely with fewer than 4 lines (not including tool use or code generation), unless user asks for detail. Answer the user's question directly, without elaboration, explanation, or details. One word answers are best. Avoid introductions, conclusions, and explanations. You MUST avoid text before/after your response, such as "The answer is <answer>.", "Here is the content of the file..." or "Based on the information provided, the answer is..." or "Here is what I will do next...". Here are some examples to demonstrate appropriate verbosity:
12
+ <example>
13
+ user: 2 + 2
14
+ assistant: 4
15
+ </example>
16
+
17
+ <example>
18
+ user: what is 2+2?
19
+ assistant: 4
20
+ </example>
21
+
22
+ <example>
23
+ user: is 11 a prime number?
24
+ assistant: Yes
25
+ </example>
26
+
27
+ <example>
28
+ user: what command should I run to list files in the current directory?
29
+ assistant: ls
30
+ </example>
31
+
32
+ <example>
33
+ user: what command should I run to watch files in the current directory?
34
+ assistant: [use the ls tool to list the files in the current directory, then read docs/commands in the relevant file to find out how to watch files]
35
+ npm run dev
36
+ </example>
37
+
38
+ <example>
39
+ user: How many golf balls fit inside a jetta?
40
+ assistant: 150000
41
+ </example>
42
+
43
+ <example>
44
+ user: what files are in the directory src/?
45
+ assistant: [runs ls and sees foo.c, bar.c, baz.c]
46
+ user: which file contains the implementation of foo?
47
+ assistant: src/foo.c
48
+ </example>
49
+
50
+ <example>
51
+ user: write tests for new feature
52
+ assistant: [uses grep or glob to find where similar tests are defined, then read relevant files one at a time (one tool per message, wait for each result), then edit or write to add tests]
53
+ </example>
54
+
55
+ # Proactiveness
56
+ You are allowed to be proactive, but only when the user asks you to do something. You should strive to strike a balance between:
57
+ 1. Doing the right thing when asked, including taking actions and follow-up actions
58
+ 2. Not surprising the user with actions you take without asking
59
+ For example, if the user asks you how to approach something, you should do your best to answer their question first, and not immediately jump into taking actions.
60
+ 3. Do not add additional code explanation summary unless requested by the user. After working on a file, just stop, rather than providing an explanation of what you did.
61
+
62
+ # Following conventions
63
+ When making changes to files, first understand the file's code conventions. Mimic code style, use existing libraries and utilities, and follow existing patterns.
64
+ - NEVER assume that a given library is available, even if it is well known. Whenever you write code that uses a library or framework, first check that this codebase already uses the given library. For example, you might look at neighboring files, or check the package.json (or cargo.toml, and so on depending on the language).
65
+ - When you create a new component, first look at existing components to see how they're written; then consider framework choice, naming conventions, typing, and other conventions.
66
+ - When you edit a piece of code, first look at the code's surrounding context (especially its imports) to understand the code's choice of frameworks and libraries. Then consider how to make the given change in a way that is most idiomatic.
67
+ - Always follow security best practices. Never introduce code that exposes or logs secrets and keys. Never commit secrets or keys to the repository.
68
+
69
+ # Code style
70
+ - IMPORTANT: DO NOT ADD ***ANY*** COMMENTS unless asked
71
+
72
+ # Doing tasks
73
+ The user will primarily request you perform software engineering tasks. This includes solving bugs, adding new functionality, refactoring code, explaining code, and more. For these tasks the following steps are recommended:
74
+ - Use the available search tools to understand the codebase and the user's query. Use one tool per message; after each result, decide the next step and call one tool again.
75
+ - Implement the solution using all tools available to you
76
+ - Verify the solution if possible with tests. NEVER assume specific test framework or test script. Check the README or search codebase to determine the testing approach.
77
+ - VERY IMPORTANT: When you have completed a task, you MUST run the lint and typecheck commands (e.g. npm run lint, npm run typecheck, ruff, etc.) with Bash if they were provided to you to ensure your code is correct. If you are unable to find the correct command, ask the user for the command to run and if they supply it, proactively suggest writing it to AGENTS.md so that you will know to run it next time.
78
+ NEVER commit changes unless the user explicitly asks you to. It is VERY IMPORTANT to only commit when explicitly asked, otherwise the user will feel that you are being too proactive.
79
+
80
+ - Tool results and user messages may include <system-reminder> tags. <system-reminder> tags contain useful information and reminders. They are NOT part of the user's provided input or the tool result.
81
+
82
+ # Tool usage policy
83
+ - When doing file search, prefer to use the Task tool in order to reduce context usage.
84
+ - Use exactly one tool per assistant message. After each tool call, wait for the result before continuing.
85
+ - When the user's request is vague, use the question tool to clarify before reading files or making changes.
86
+ - Avoid repeating the same tool with the same parameters once you have useful results. Use the result to take the next step (e.g. pick one match, read that file, then act); do not search again in a loop.
87
+
88
+ You MUST answer concisely with fewer than 4 lines of text (not including tool use or code generation), unless user asks for detail.
89
+
90
+ # Code References
91
+
92
+ When referencing specific functions or pieces of code include the pattern `file_path:line_number` to allow the user to easily navigate to the source code location.
93
+
94
+ <example>
95
+ user: Where are errors from the client handled?
96
+ assistant: Clients are marked as failed in the `connectToServer` function in src/services/process.ts:712.
97
+ </example>
@@ -0,0 +1,13 @@
1
+ - Fetches content from a specified URL
2
+ - Takes a URL and optional format as input
3
+ - Fetches the URL content, converts to requested format (markdown by default)
4
+ - Returns the content in the specified format
5
+ - Use this tool when you need to retrieve and analyze web content
6
+
7
+ Usage notes:
8
+ - IMPORTANT: if another tool is present that offers better web fetching capabilities, is more targeted to the task, or has fewer restrictions, prefer using that tool instead of this one.
9
+ - The URL must be a fully-formed valid URL
10
+ - HTTP URLs will be automatically upgraded to HTTPS
11
+ - Format options: "markdown" (default), "text", or "html"
12
+ - This tool is read-only and does not modify any files
13
+ - Results may be summarized if the content is very large
@@ -0,0 +1,14 @@
1
+ - Search the web using the session's web search provider - performs real-time web searches and can scrape content from specific URLs
2
+ - Provides up-to-date information for current events and recent data
3
+ - Supports configurable result counts and returns the content from the most relevant websites
4
+ - Use this tool for accessing information beyond knowledge cutoff
5
+ - Searches are performed automatically within a single API call
6
+
7
+ Usage notes:
8
+ - Supports live crawling modes when available: 'fallback' (backup if cached unavailable) or 'preferred' (prioritize live crawling)
9
+ - Search types when available: 'auto' (balanced), 'fast' (quick results), 'deep' (comprehensive search)
10
+ - Configurable context length for optimal LLM integration
11
+ - Domain filtering and advanced search options available
12
+
13
+ The current year is {{year}}. You MUST use this year when searching for recent information or current events
14
+ - Example: If the current year is 2026 and the user asks for "latest AI news", search for "AI news 2026", NOT "AI news 2025"
@@ -0,0 +1,8 @@
1
+ Writes a file to the local filesystem.
2
+
3
+ Usage:
4
+ - This tool will overwrite the existing file if there is one at the provided path.
5
+ - If this is an existing file, you MUST use the Read tool first to read the file's contents. This tool will fail if you did not read the file first.
6
+ - ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.
7
+ - NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.
8
+ - Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked.
@@ -0,0 +1,157 @@
1
+ 'use strict';
2
+
3
+ /* ---------- opencode session/system.ts + reminders.ts portu (birebir) ----------
4
+ Beast Code (bcCode) oturumlarında system prompt artık TEK elle yazılmış
5
+ metin değil, opencode birleşimidir (prompt.ts:1257-1269):
6
+
7
+ system = [ ...environment(model), → bu modül
8
+ ...instructions(AGENTS.md), → engine._projectInstructions
9
+ ...(skills kataloğu), → bu modül (skill/skill.ts fmt)
10
+ ...ajan tanımının promptu ] → agents.js (explore vb.)
11
+
12
+ Ana prompt MODEL BAZLI seçilir (system.ts:27-49): gpt-4 ailesi, o1, o3 → beast.txt,
13
+ gpt* → gpt.txt (codex* → codex.txt), gemini-* → gemini.txt, claude →
14
+ anthropic.txt, kimi → kimi.txt, muse → meta.txt, trinity → trinity.txt,
15
+ diğer → default.txt.
16
+
17
+ Reminders (reminders.ts:15-90): plan ajanındaysa son user mesajına plan.txt
18
+ synthetic part'ı; geçmişte plan koşmuşsa ve şimdi build'se build-switch.txt
19
+ eklenir. Belleği kirletmemek için payload ÖNCESİ kopya mesajlara uygulanır
20
+ (her tur taze — opencode her turda DB'den yeniden yükleyip uygular). */
21
+
22
+ const fs = require('fs');
23
+ const path = require('path');
24
+ const Permission = require('./permission');
25
+
26
+ const PROMPT_DIR = path.join(__dirname, 'prompts');
27
+ function loadPrompt(name) {
28
+ try {
29
+ let t = fs.readFileSync(path.join(PROMPT_DIR, name), 'utf8');
30
+ if (t.charCodeAt(0) === 0xfeff) t = t.slice(1); // BOM-strip
31
+ return t.replace(/\s+$/, '');
32
+ } catch {
33
+ return '';
34
+ }
35
+ }
36
+
37
+ const PROMPTS = {
38
+ beast: loadPrompt('beast.txt'),
39
+ gpt: loadPrompt('gpt.txt'),
40
+ codex: loadPrompt('codex.txt'),
41
+ anthropic: loadPrompt('anthropic.txt'),
42
+ gemini: loadPrompt('gemini.txt'),
43
+ kimi: loadPrompt('kimi.txt'),
44
+ meta: loadPrompt('meta.txt'),
45
+ trinity: loadPrompt('trinity.txt'),
46
+ default: loadPrompt('default.txt'),
47
+ plan: loadPrompt('plan.txt'),
48
+ buildSwitch: loadPrompt('build-switch.txt'),
49
+ explore: loadPrompt('explore.txt'),
50
+ };
51
+
52
+ /* opencode system.ts:27-49 — model-bazlı prompt seçimi (birebir) */
53
+ function provider(modelId) {
54
+ const id = String(modelId || '');
55
+ if (id.includes('muse')) {
56
+ const name = id.includes('muse-glimmer') ? 'Muse Glimmer' : 'Muse Spark';
57
+ return [PROMPTS.meta.replaceAll('{{MODEL_NAME}}', name)];
58
+ }
59
+ if (id.includes('gpt-4') || id.includes('o1') || id.includes('o3')) return [PROMPTS.beast];
60
+ if (id.includes('gpt')) {
61
+ if (id.includes('codex')) return [PROMPTS.codex];
62
+ return [PROMPTS.gpt];
63
+ }
64
+ if (id.includes('gemini-')) return [PROMPTS.gemini];
65
+ if (id.includes('claude')) return [PROMPTS.anthropic];
66
+ if (id.toLowerCase().includes('trinity')) return [PROMPTS.trinity];
67
+ if (id.toLowerCase().includes('kimi')) return [PROMPTS.kimi];
68
+ return [PROMPTS.default];
69
+ }
70
+
71
+ /* opencode SystemPrompt.environment — model kimliği + <env> bloğu */
72
+ function environment({ modelId, providerId, directory, worktree }) {
73
+ const isGit = (() => {
74
+ try {
75
+ return fs.existsSync(path.join(String(directory || ''), '.git')) ? 'yes' : 'no';
76
+ } catch {
77
+ return 'no';
78
+ }
79
+ })();
80
+ return [
81
+ [
82
+ `You are powered by the model named ${modelId}. The exact model ID is ${providerId}/${modelId}`,
83
+ `Here is some useful information about the environment you are running in:`,
84
+ `<env>`,
85
+ ` Working directory: ${directory}`,
86
+ ` Workspace root folder: ${worktree}`,
87
+ ` Is directory a git repo: ${isGit}`,
88
+ ` Platform: ${process.platform}`,
89
+ ` Today's date: ${new Date().toDateString()}`,
90
+ `</env>`,
91
+ ].join('\n'),
92
+ ];
93
+ }
94
+
95
+ /* opencode skill/skill.ts fmt (verbose) — skills.js scan() listesini
96
+ opencode katalog biçimine basar */
97
+ function skillsCatalog(skills) {
98
+ const described = (skills || []).filter((s) => s && s.description);
99
+ if (!described.length) return undefined;
100
+ return [
101
+ 'Skills provide specialized instructions and workflows for specific tasks.',
102
+ 'Use the skill tool to load a skill when a task matches its description.',
103
+ '<available_skills>',
104
+ ...described
105
+ .slice()
106
+ .sort((a, b) => String(a.name).localeCompare(String(b.name)))
107
+ .flatMap((s) => [
108
+ ' <skill>',
109
+ ` <name>${s.name}</name>`,
110
+ ` <description>${s.description}</description>`,
111
+ ` <location>${s.path}</location>`,
112
+ ' </skill>',
113
+ ]),
114
+ '</available_skills>',
115
+ ].join('\n');
116
+ }
117
+
118
+ /* opencode SystemPrompt.skills — ajanın skill izni yoksa katalog gösterilmez */
119
+ function skills(ruleset, scanFn) {
120
+ if (Permission.disabled(['skill'], ruleset).has('skill')) return undefined;
121
+ try {
122
+ return skillsCatalog(scanFn());
123
+ } catch {
124
+ return undefined;
125
+ }
126
+ }
127
+
128
+ /* opencode SessionReminders.apply — synthetic part yerine son user mesajının
129
+ KOPIASINA metin ekler; session.messages asla değişmez (her tur taze uygulanır).
130
+ wasPlan: bu oturumda daha önce plan ajanı koştu mu (engine takip eder). */
131
+ function applyReminders(messages, agent, wasPlan) {
132
+ const msgs = (messages || []).slice();
133
+ const lastUserIdx = msgs.findLastIndex ? msgs.findLastIndex((m) => m.role === 'user') : -1;
134
+ if (lastUserIdx < 0 || !agent) return msgs;
135
+ const adds = [];
136
+ if (agent.name === 'plan') adds.push(PROMPTS.plan);
137
+ if (wasPlan && agent.name === 'build') adds.push(PROMPTS.buildSwitch);
138
+ if (!adds.length) return msgs;
139
+ const base = msgs[lastUserIdx];
140
+ const baseText =
141
+ typeof base.content === 'string' ? base.content : '';
142
+ msgs[lastUserIdx] = {
143
+ ...base,
144
+ content: (baseText ? baseText + '\n\n' : '') + adds.join('\n\n'),
145
+ };
146
+ return msgs;
147
+ }
148
+
149
+ module.exports = {
150
+ PROMPTS,
151
+ provider,
152
+ environment,
153
+ skills,
154
+ skillsCatalog,
155
+ applyReminders,
156
+ loadPrompt,
157
+ };
@@ -0,0 +1,316 @@
1
+ 'use strict';
2
+
3
+ /* ---------- opencode tool seti → Beast araç köprüsü ----------
4
+ Beast Code (bcCode) oturumlarında model opencode'un ARAÇ DİLİYLE konuşur:
5
+ read · edit · write · bash · glob · grep · list · fetch · websearch ·
6
+ todowrite · task · skill (opencode builtin registry sırası)
7
+
8
+ Tanımlar opencode-dev'den birebir: açıklama metinleri tool/*.txt,
9
+ parametre şemaları opencode Schema.Struct karşılıkları (JSON Schema).
10
+ execMap() çağrıyı Beast'in yerleşik aracına çevirir — implementasyon
11
+ değişmez, modelin gördüğü dünya opencode olur. */
12
+
13
+ const fs = require('fs');
14
+ const path = require('path');
15
+
16
+ const PROMPT_DIR = path.join(__dirname, 'prompts');
17
+ function loadPrompt(name) {
18
+ try {
19
+ let t = fs.readFileSync(path.join(PROMPT_DIR, name), 'utf8');
20
+ if (t.charCodeAt(0) === 0xfeff) t = t.slice(1); // BOM-strip
21
+ return t.replace(/\s+$/, '') + '\n';
22
+ } catch {
23
+ return '';
24
+ }
25
+ }
26
+
27
+ /* opencode tool/shell/prompt.ts Windows (PowerShell) açıklaması — Beast
28
+ değerleriyle: varsayılan timeout 120s, 2000 satır / 50KB tavan, tam
29
+ çıktı geçici dosyaya düşer (Beast run_command zaten bu disiplinde) */
30
+ function bashDescription() {
31
+ const defaultTimeoutMs = 120000;
32
+ const maxLines = 2000;
33
+ const maxBytes = '50KB';
34
+ return `Executes a given PowerShell command in a persistent shell session.
35
+
36
+ ## Command Execution
37
+
38
+ Before executing the command, please follow these steps:
39
+ 1. If the command will create new directories or files, first use \`Test-Path -LiteralPath <parent>\` to verify the parent directory exists and is the correct location
40
+ 2. If the command will modify or delete files, first verify the paths are correct
41
+ 3. For commands expected to create new directories or files, verify the expected file/folder location is inside the working directory
42
+
43
+ After ensuring proper quoting, execute the command.
44
+ - Capture the output of the command.
45
+
46
+ ## Usage Notes
47
+
48
+ - The command argument is required.
49
+ - You can specify an optional timeout in milliseconds. If not specified, commands will time out after ${defaultTimeoutMs}ms.
50
+ - If the output exceeds ${maxLines} lines or ${maxBytes} bytes, it will be truncated and the full output will be written to a file. You can use Read with offset/limit to read specific sections or Grep to search the full content. Do NOT use \`Select-Object -First\`, \`Select-Object -Last\`, or other truncation commands to limit output; the full output will already be captured to a file for more precise searching.
51
+ - Avoid using Shell with PowerShell file/content cmdlets unless explicitly instructed or when these cmdlets are truly necessary for the task. Instead, always prefer using the dedicated tools for reading, searching, and editing files:
52
+ - Read: Reading and analyzing file contents (with line numbers)
53
+ - Edit: Making targeted changes to specific sections of files
54
+ - Write: Creating new files from scratch
55
+ - Grep: Searching file contents with regex patterns
56
+ - Glob: Finding files by patterns (e.g., "src/**/*.ts")
57
+ - When issuing multiple commands:
58
+ - If the commands are independent and can run in parallel, make multiple bash tool calls in a single message. For example, if you need to run "git status" and "git diff", send a single message with two bash tool calls in parallel.
59
+ - Use ';' only when you need to run commands sequentially but don't care if earlier commands fail
60
+ - If the commands depend on each other and must run sequentially, avoid '&&' in this shell because Windows PowerShell (5.1) does not support it. Use PowerShell conditionals such as \`cmd1; if ($?) { cmd2 }\` when later commands must depend on earlier success.
61
+ - DO NOT use newlines to separate commands (newlines are ok in quoted strings)
62
+ - The shell is PERSISTENT: working directory and environment variables are preserved between calls.
63
+ - Commands run in Windows PowerShell (5.1).`;
64
+ }
65
+
66
+ /* opencode tool şemaları — Schema.Struct karşılığı JSON Schema'lar */
67
+ const DEFS = () => [
68
+ {
69
+ name: 'bash',
70
+ description: bashDescription(),
71
+ parameters: {
72
+ type: 'object',
73
+ properties: {
74
+ command: { type: 'string', description: 'The command to execute' },
75
+ timeout: { type: 'integer', description: 'Optional timeout in milliseconds' },
76
+ },
77
+ required: ['command'],
78
+ },
79
+ },
80
+ {
81
+ name: 'read',
82
+ description: loadPrompt('read.txt'),
83
+ parameters: {
84
+ type: 'object',
85
+ properties: {
86
+ filePath: { type: 'string', description: 'The absolute path to the file or directory to read' },
87
+ offset: { type: 'integer', description: 'The line number to start reading from (1-indexed)' },
88
+ limit: { type: 'integer', description: 'The maximum number of lines to read (defaults to 2000)' },
89
+ },
90
+ required: ['filePath'],
91
+ },
92
+ },
93
+ {
94
+ name: 'edit',
95
+ description: loadPrompt('edit.txt'),
96
+ parameters: {
97
+ type: 'object',
98
+ properties: {
99
+ filePath: { type: 'string', description: 'The absolute path to the file to modify' },
100
+ oldString: { type: 'string', description: 'The text to replace' },
101
+ newString: { type: 'string', description: 'The text to replace it with (must be different from oldString)' },
102
+ replaceAll: { type: 'boolean', description: 'Replace all occurrences of oldString (default false)' },
103
+ },
104
+ required: ['filePath', 'oldString', 'newString'],
105
+ },
106
+ },
107
+ {
108
+ name: 'write',
109
+ description: loadPrompt('write.txt'),
110
+ parameters: {
111
+ type: 'object',
112
+ properties: {
113
+ filePath: { type: 'string', description: 'The absolute path to the file to write (will create the file if it does not exist, will overwrite if it does)' },
114
+ content: { type: 'string', description: 'The content to write' },
115
+ },
116
+ required: ['filePath', 'content'],
117
+ },
118
+ },
119
+ {
120
+ name: 'glob',
121
+ description: loadPrompt('glob.txt'),
122
+ parameters: {
123
+ type: 'object',
124
+ properties: {
125
+ pattern: { type: 'string', description: 'The glob pattern to match files against' },
126
+ path: { type: 'string', description: 'The directory to search in. If not specified, the current working directory will be used. IMPORTANT: Omit this field to use the default directory. DO NOT enter "undefined" or "null" - simply omit it for the default behavior. Must be a valid directory path if provided.' },
127
+ },
128
+ required: ['pattern'],
129
+ },
130
+ },
131
+ {
132
+ name: 'grep',
133
+ description: loadPrompt('grep.txt'),
134
+ parameters: {
135
+ type: 'object',
136
+ properties: {
137
+ pattern: { type: 'string', description: 'The regex pattern to search for in file contents' },
138
+ path: { type: 'string', description: 'The directory to search in. Defaults to the current working directory.' },
139
+ include: { type: 'string', description: 'File pattern to include in the search (e.g. "*.js", "*.{ts,tsx}")' },
140
+ },
141
+ required: ['pattern'],
142
+ },
143
+ },
144
+ {
145
+ name: 'list',
146
+ description: 'List files and directories in a given path. Returns entries sorted by name (directories first, then files), with type indicator and size.',
147
+ parameters: {
148
+ type: 'object',
149
+ properties: {
150
+ path: { type: 'string', description: 'The directory path to list. Defaults to the current working directory.' },
151
+ },
152
+ },
153
+ },
154
+ {
155
+ name: 'webfetch',
156
+ description: loadPrompt('webfetch.txt'),
157
+ parameters: {
158
+ type: 'object',
159
+ properties: {
160
+ url: { type: 'string', description: 'The URL to fetch' },
161
+ format: { type: 'string', enum: ['text', 'markdown', 'html'], description: 'The format to return the content in (text, markdown, or html). Defaults to markdown.' },
162
+ timeout: { type: 'integer', description: 'Optional timeout in seconds (max 120)' },
163
+ max_chars: { type: 'integer', description: 'Optional maximum characters to return' },
164
+ },
165
+ required: ['url'],
166
+ },
167
+ },
168
+ {
169
+ name: 'websearch',
170
+ description: loadPrompt('websearch.txt'),
171
+ parameters: {
172
+ type: 'object',
173
+ properties: {
174
+ query: { type: 'string', description: 'Websearch query' },
175
+ numResults: { type: 'integer', description: 'Number of search results to return (default: 8)' },
176
+ type: { type: 'string', enum: ['auto', 'fast', 'deep'], description: "Search type - 'auto': balanced search (default), 'fast': quick results, 'deep': comprehensive search" },
177
+ },
178
+ required: ['query'],
179
+ },
180
+ },
181
+ {
182
+ name: 'todowrite',
183
+ description: loadPrompt('todowrite.txt'),
184
+ parameters: {
185
+ type: 'object',
186
+ properties: {
187
+ todos: {
188
+ type: 'array',
189
+ description: 'The updated todo list',
190
+ items: {
191
+ type: 'object',
192
+ properties: {
193
+ content: { type: 'string', description: 'Brief description of the task' },
194
+ status: { type: 'string', enum: ['pending', 'in_progress', 'completed', 'cancelled'], description: 'Current status of the task' },
195
+ priority: { type: 'string', enum: ['high', 'medium', 'low'], description: 'Priority level of the task' },
196
+ },
197
+ required: ['content', 'status'],
198
+ },
199
+ },
200
+ },
201
+ required: ['todos'],
202
+ },
203
+ },
204
+ {
205
+ name: 'task',
206
+ description: loadPrompt('task.txt'),
207
+ parameters: {
208
+ type: 'object',
209
+ properties: {
210
+ description: { type: 'string', description: 'A short description of the task (max 80 chars)' },
211
+ prompt: { type: 'string', description: 'The full task description for the subagent to execute' },
212
+ subagent_type: { type: 'string', enum: ['general', 'explore'], description: 'Type of subagent to launch (options: explore, general)' },
213
+ },
214
+ required: ['description', 'prompt', 'subagent_type'],
215
+ },
216
+ },
217
+ {
218
+ name: 'skill',
219
+ description: loadPrompt('skill.txt'),
220
+ parameters: {
221
+ type: 'object',
222
+ properties: {
223
+ name: { type: 'string', description: 'The name of the skill from available_skills' },
224
+ },
225
+ required: ['name'],
226
+ },
227
+ },
228
+ {
229
+ /* Beast Sandbox'a özgü: UZUN SÜRELİ süreçleri (dev server vb.) ÇALIŞTIR
230
+ paneline devreder — tur BLOKLAMAZ. panel_run izni yalnız sandbox
231
+ ajanında allow edilir (agents.js); BC build/plan'da gizlidir. */
232
+ name: 'panel_run',
233
+ description:
234
+ 'Run a LONG-RUNNING process (dev server, background service) in the managed RUN panel instead of the blocking shell. The turn does not wait for it to finish; output streams live in the panel and can be stopped by the user. Use this instead of starting servers with bash — a blocking bash call would stall the whole job. Only ONE process runs at a time.',
235
+ parameters: {
236
+ type: 'object',
237
+ properties: {
238
+ command: { type: 'string', description: 'The command to run in the panel' },
239
+ },
240
+ required: ['command'],
241
+ },
242
+ },
243
+ ];
244
+
245
+ /* OpenAI function-call formatına çevirir (engine TOOLS formatı) */
246
+ function definitions() {
247
+ return DEFS().map((d) => ({ type: 'function', function: d }));
248
+ }
249
+
250
+ const TO_BUILTIN = {
251
+ bash: 'run_command',
252
+ read: 'read_file',
253
+ edit: 'edit_file',
254
+ write: 'write_file',
255
+ glob: 'glob',
256
+ grep: 'grep',
257
+ list: 'list_dir',
258
+ webfetch: 'webfetch',
259
+ websearch: 'web_search',
260
+ todowrite: 'todo_write',
261
+ task: 'delegate_task',
262
+ panel_run: 'panel_run',
263
+ };
264
+
265
+ /* opencode parametreleri → Beast araç parametreleri */
266
+ function execMap(name, args) {
267
+ const a = args || {};
268
+ switch (name) {
269
+ case 'read':
270
+ return { name: 'read_file', args: { path: a.filePath, offset: a.offset, limit: a.limit } };
271
+ case 'edit':
272
+ return {
273
+ name: 'edit_file',
274
+ args: { path: a.filePath, old_string: a.oldString, new_string: a.newString, replace_all: a.replaceAll === true },
275
+ };
276
+ case 'write':
277
+ return { name: 'write_file', args: { path: a.filePath, content: a.content } };
278
+ case 'bash':
279
+ return { name: 'run_command', args: { command: a.command, timeout_ms: a.timeout } };
280
+ case 'list':
281
+ return { name: 'list_dir', args: { path: a.path } };
282
+ case 'webfetch':
283
+ return { name: 'webfetch', args: { url: a.url, format: a.format, timeout: a.timeout, max_chars: a.max_chars } };
284
+ case 'websearch':
285
+ return { name: 'web_search', args: { query: a.query, max_results: a.numResults || a.max_results } };
286
+ case 'todowrite':
287
+ return { name: 'todo_write', args: { items: (a.todos || []).map(opencodeTodoToItem) } };
288
+ case 'task':
289
+ return {
290
+ name: 'delegate_task',
291
+ args: { task: a.prompt || a.description, context: a.description || '', subagent_type: a.subagent_type },
292
+ };
293
+ default:
294
+ return { name: TO_BUILTIN[name] || name, args: a };
295
+ }
296
+ }
297
+
298
+ /* opencode Todo.Info {content, status, priority} → Beast iç depo {title, status}
299
+ opencode durum makinesi: pending → in_progress → completed | cancelled
300
+ Beast iç durumu: pending | active | done */
301
+ const OC_TODO_STATUS = { pending: 'pending', in_progress: 'active', completed: 'done', cancelled: 'done' };
302
+ function opencodeTodoToItem(t) {
303
+ const it = t || {};
304
+ return {
305
+ title: String(it.content ?? '').replace(/\s+/g, ' ').trim().slice(0, 120),
306
+ status: OC_TODO_STATUS[String(it.status || 'pending')] || 'pending',
307
+ };
308
+ }
309
+
310
+ /* BC oturumunda modele sunulan opencode araç adları (permission filtresinden
311
+ önce tam set — opencode registry builtin sırası) */
312
+ function names() {
313
+ return DEFS().map((d) => d.name);
314
+ }
315
+
316
+ module.exports = { definitions, names, execMap, TO_BUILTIN, opencodeTodoToItem };