tunacode-cli 0.0.55__py3-none-any.whl → 0.0.78.6__py3-none-any.whl
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.
Potentially problematic release.
This version of tunacode-cli might be problematic. Click here for more details.
- tunacode/cli/commands/__init__.py +2 -2
- tunacode/cli/commands/implementations/__init__.py +2 -3
- tunacode/cli/commands/implementations/command_reload.py +48 -0
- tunacode/cli/commands/implementations/debug.py +2 -2
- tunacode/cli/commands/implementations/development.py +10 -8
- tunacode/cli/commands/implementations/model.py +357 -29
- tunacode/cli/commands/implementations/quickstart.py +43 -0
- tunacode/cli/commands/implementations/system.py +96 -3
- tunacode/cli/commands/implementations/template.py +0 -2
- tunacode/cli/commands/registry.py +139 -5
- tunacode/cli/commands/slash/__init__.py +32 -0
- tunacode/cli/commands/slash/command.py +157 -0
- tunacode/cli/commands/slash/loader.py +135 -0
- tunacode/cli/commands/slash/processor.py +294 -0
- tunacode/cli/commands/slash/types.py +93 -0
- tunacode/cli/commands/slash/validator.py +400 -0
- tunacode/cli/main.py +23 -2
- tunacode/cli/repl.py +217 -190
- tunacode/cli/repl_components/command_parser.py +38 -4
- tunacode/cli/repl_components/error_recovery.py +85 -4
- tunacode/cli/repl_components/output_display.py +12 -1
- tunacode/cli/repl_components/tool_executor.py +1 -1
- tunacode/configuration/defaults.py +12 -3
- tunacode/configuration/key_descriptions.py +284 -0
- tunacode/configuration/settings.py +0 -1
- tunacode/constants.py +12 -40
- tunacode/core/agents/__init__.py +43 -2
- tunacode/core/agents/agent_components/__init__.py +7 -0
- tunacode/core/agents/agent_components/agent_config.py +249 -55
- tunacode/core/agents/agent_components/agent_helpers.py +43 -13
- tunacode/core/agents/agent_components/node_processor.py +179 -139
- tunacode/core/agents/agent_components/response_state.py +123 -6
- tunacode/core/agents/agent_components/state_transition.py +116 -0
- tunacode/core/agents/agent_components/streaming.py +296 -0
- tunacode/core/agents/agent_components/task_completion.py +19 -6
- tunacode/core/agents/agent_components/tool_buffer.py +21 -1
- tunacode/core/agents/agent_components/tool_executor.py +10 -0
- tunacode/core/agents/main.py +522 -370
- tunacode/core/agents/main_legact.py +538 -0
- tunacode/core/agents/prompts.py +66 -0
- tunacode/core/agents/utils.py +29 -121
- tunacode/core/code_index.py +83 -29
- tunacode/core/setup/__init__.py +0 -2
- tunacode/core/setup/config_setup.py +110 -20
- tunacode/core/setup/config_wizard.py +230 -0
- tunacode/core/setup/coordinator.py +14 -5
- tunacode/core/state.py +16 -20
- tunacode/core/token_usage/usage_tracker.py +5 -3
- tunacode/core/tool_authorization.py +352 -0
- tunacode/core/tool_handler.py +67 -40
- tunacode/exceptions.py +119 -5
- tunacode/prompts/system.xml +751 -0
- tunacode/services/mcp.py +125 -7
- tunacode/setup.py +5 -25
- tunacode/tools/base.py +163 -0
- tunacode/tools/bash.py +110 -1
- tunacode/tools/glob.py +332 -34
- tunacode/tools/grep.py +179 -82
- tunacode/tools/grep_components/result_formatter.py +98 -4
- tunacode/tools/list_dir.py +132 -2
- tunacode/tools/prompts/bash_prompt.xml +72 -0
- tunacode/tools/prompts/glob_prompt.xml +45 -0
- tunacode/tools/prompts/grep_prompt.xml +98 -0
- tunacode/tools/prompts/list_dir_prompt.xml +31 -0
- tunacode/tools/prompts/react_prompt.xml +23 -0
- tunacode/tools/prompts/read_file_prompt.xml +54 -0
- tunacode/tools/prompts/run_command_prompt.xml +64 -0
- tunacode/tools/prompts/update_file_prompt.xml +53 -0
- tunacode/tools/prompts/write_file_prompt.xml +37 -0
- tunacode/tools/react.py +153 -0
- tunacode/tools/read_file.py +91 -0
- tunacode/tools/run_command.py +114 -0
- tunacode/tools/schema_assembler.py +167 -0
- tunacode/tools/update_file.py +94 -0
- tunacode/tools/write_file.py +86 -0
- tunacode/tools/xml_helper.py +83 -0
- tunacode/tutorial/__init__.py +9 -0
- tunacode/tutorial/content.py +98 -0
- tunacode/tutorial/manager.py +182 -0
- tunacode/tutorial/steps.py +124 -0
- tunacode/types.py +20 -27
- tunacode/ui/completers.py +434 -50
- tunacode/ui/config_dashboard.py +585 -0
- tunacode/ui/console.py +63 -11
- tunacode/ui/input.py +20 -3
- tunacode/ui/keybindings.py +7 -4
- tunacode/ui/model_selector.py +395 -0
- tunacode/ui/output.py +40 -19
- tunacode/ui/panels.py +212 -43
- tunacode/ui/path_heuristics.py +91 -0
- tunacode/ui/prompt_manager.py +5 -1
- tunacode/ui/tool_ui.py +33 -10
- tunacode/utils/api_key_validation.py +93 -0
- tunacode/utils/config_comparator.py +340 -0
- tunacode/utils/json_utils.py +206 -0
- tunacode/utils/message_utils.py +14 -4
- tunacode/utils/models_registry.py +593 -0
- tunacode/utils/ripgrep.py +332 -9
- tunacode/utils/text_utils.py +18 -1
- tunacode/utils/user_configuration.py +45 -0
- tunacode_cli-0.0.78.6.dist-info/METADATA +260 -0
- tunacode_cli-0.0.78.6.dist-info/RECORD +158 -0
- {tunacode_cli-0.0.55.dist-info → tunacode_cli-0.0.78.6.dist-info}/WHEEL +1 -2
- tunacode/cli/commands/implementations/todo.py +0 -217
- tunacode/context.py +0 -71
- tunacode/core/setup/git_safety_setup.py +0 -182
- tunacode/prompts/system.md +0 -731
- tunacode/tools/read_file_async_poc.py +0 -196
- tunacode/tools/todo.py +0 -349
- tunacode_cli-0.0.55.dist-info/METADATA +0 -322
- tunacode_cli-0.0.55.dist-info/RECORD +0 -126
- tunacode_cli-0.0.55.dist-info/top_level.txt +0 -1
- {tunacode_cli-0.0.55.dist-info → tunacode_cli-0.0.78.6.dist-info}/entry_points.txt +0 -0
- {tunacode_cli-0.0.55.dist-info → tunacode_cli-0.0.78.6.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<tool_prompt>
|
|
3
|
+
<description>
|
|
4
|
+
Executes a given bash command in a persistent shell session with optional timeout, ensuring proper handling and security measures.
|
|
5
|
+
|
|
6
|
+
Before executing the command, please follow these steps:
|
|
7
|
+
|
|
8
|
+
1. Directory Verification:
|
|
9
|
+
- If the command will create new directories or files, first use the LS tool to verify the parent directory exists and is the correct location
|
|
10
|
+
- For example, before running "mkdir foo/bar", first use LS to check that "foo" exists and is the intended parent directory
|
|
11
|
+
|
|
12
|
+
2. Command Execution:
|
|
13
|
+
- Always quote file paths that contain spaces with double quotes (e.g., cd "path with spaces/file.txt")
|
|
14
|
+
- Examples of proper quoting:
|
|
15
|
+
- cd "/Users/name/My Documents" (correct)
|
|
16
|
+
- cd /Users/name/My Documents (incorrect - will fail)
|
|
17
|
+
- python "/path/with spaces/script.py" (correct)
|
|
18
|
+
- python /path/with spaces/script.py (incorrect - will fail)
|
|
19
|
+
- After ensuring proper quoting, execute the command.
|
|
20
|
+
- Capture the output of the command.
|
|
21
|
+
|
|
22
|
+
Usage notes:
|
|
23
|
+
- The command argument is required.
|
|
24
|
+
- You can specify an optional timeout in milliseconds (up to 600000ms / 10 minutes). If not specified, commands will timeout after 120000ms (2 minutes).
|
|
25
|
+
- It is very helpful if you write a clear, concise description of what this command does in 5-10 words.
|
|
26
|
+
- If the output exceeds 30000 characters, output will be truncated before being returned to you.
|
|
27
|
+
- You can use the `run_in_background` parameter to run the command in the background, which allows you to continue working while the command runs. You can monitor the output using the Bash tool as it becomes available. Never use `run_in_background` to run 'sleep' as it will return immediately. You do not need to use '&' at the end of the command when using this parameter.
|
|
28
|
+
- VERY IMPORTANT: You MUST avoid using search commands like `find` and `grep`. Instead use Grep, Glob, or Task to search. You MUST avoid read tools like `cat`, `head`, `tail`, and `ls`, and use Read and LS to read files.
|
|
29
|
+
- If you _still_ need to run `grep`, STOP. ALWAYS USE ripgrep at `rg` first, which all Claude Code users have pre-installed.
|
|
30
|
+
- When issuing multiple commands, use the ';' or '&&' operator to separate them. DO NOT use newlines (newlines are ok in quoted strings).
|
|
31
|
+
- Try to maintain your current working directory throughout the session by using absolute paths and avoiding usage of `cd`. You may use `cd` if the User explicitly requests it.
|
|
32
|
+
</description>
|
|
33
|
+
|
|
34
|
+
<parameters>
|
|
35
|
+
<parameter name="command" required="true">
|
|
36
|
+
<description>The command to execute</description>
|
|
37
|
+
<type>string</type>
|
|
38
|
+
</parameter>
|
|
39
|
+
|
|
40
|
+
<parameter name="description" required="false">
|
|
41
|
+
<description>Clear, concise description of what this command does in 5-10 words</description>
|
|
42
|
+
<type>string</type>
|
|
43
|
+
</parameter>
|
|
44
|
+
|
|
45
|
+
<parameter name="timeout" required="false">
|
|
46
|
+
<description>Optional timeout in milliseconds (max 600000)</description>
|
|
47
|
+
<type>number</type>
|
|
48
|
+
</parameter>
|
|
49
|
+
|
|
50
|
+
<parameter name="run_in_background" required="false">
|
|
51
|
+
<description>Set to true to run this command in the background. Use BashOutput to read the output later.</description>
|
|
52
|
+
<type>boolean</type>
|
|
53
|
+
</parameter>
|
|
54
|
+
</parameters>
|
|
55
|
+
|
|
56
|
+
<examples>
|
|
57
|
+
<example>
|
|
58
|
+
<title>List files in current directory</title>
|
|
59
|
+
<command>{"command": "ls", "description": "Lists files in current directory"}</command>
|
|
60
|
+
</example>
|
|
61
|
+
|
|
62
|
+
<example>
|
|
63
|
+
<title>Run tests with timeout</title>
|
|
64
|
+
<command>{"command": "npm test", "description": "Run npm test suite", "timeout": 60000}</command>
|
|
65
|
+
</example>
|
|
66
|
+
|
|
67
|
+
<example>
|
|
68
|
+
<title>Background server startup</title>
|
|
69
|
+
<command>{"command": "npm start", "description": "Start development server", "run_in_background": true}</command>
|
|
70
|
+
</example>
|
|
71
|
+
</examples>
|
|
72
|
+
</tool_prompt>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<tool_prompt>
|
|
3
|
+
<description>
|
|
4
|
+
- Fast file pattern matching tool that works with any codebase size
|
|
5
|
+
- Supports glob patterns like "**/*.js" or "src/**/*.ts"
|
|
6
|
+
- Returns matching file paths sorted by modification time
|
|
7
|
+
- Use this tool when you need to find files by name patterns
|
|
8
|
+
- When you are doing an open ended search that may require multiple rounds of globbing and grepping, use the Agent tool instead
|
|
9
|
+
- You have the capability to call multiple tools in a single response. When you need multiple glob patterns, list each call up front so the read-only scheduler can execute them together as one batch.
|
|
10
|
+
</description>
|
|
11
|
+
|
|
12
|
+
<parameters>
|
|
13
|
+
<parameter name="pattern" required="true">
|
|
14
|
+
<description>The glob pattern to match files against</description>
|
|
15
|
+
<type>string</type>
|
|
16
|
+
</parameter>
|
|
17
|
+
|
|
18
|
+
<parameter name="path" required="false">
|
|
19
|
+
<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.</description>
|
|
20
|
+
<type>string</type>
|
|
21
|
+
</parameter>
|
|
22
|
+
</parameters>
|
|
23
|
+
|
|
24
|
+
<examples>
|
|
25
|
+
<example>
|
|
26
|
+
<title>Find all JavaScript files</title>
|
|
27
|
+
<command>{"pattern": "**/*.js"}</command>
|
|
28
|
+
</example>
|
|
29
|
+
|
|
30
|
+
<example>
|
|
31
|
+
<title>Find TypeScript files in src directory</title>
|
|
32
|
+
<command>{"pattern": "src/**/*.ts"}</command>
|
|
33
|
+
</example>
|
|
34
|
+
|
|
35
|
+
<example>
|
|
36
|
+
<title>Find test files</title>
|
|
37
|
+
<command>{"pattern": "**/*test*.py"}</command>
|
|
38
|
+
</example>
|
|
39
|
+
|
|
40
|
+
<example>
|
|
41
|
+
<title>Find config files</title>
|
|
42
|
+
<command>{"pattern": "**/*.{json,yaml,yml,toml}"}</command>
|
|
43
|
+
</example>
|
|
44
|
+
</examples>
|
|
45
|
+
</tool_prompt>
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<tool_prompt>
|
|
3
|
+
<description>
|
|
4
|
+
A powerful search tool built on ripgrep
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
- ALWAYS use Grep for search tasks. NEVER invoke `grep` or `rg` as a Bash command. The Grep tool has been optimized for correct permissions and access.
|
|
8
|
+
- Supports full regex syntax (e.g., "log.*Error", "function\s+\w+")
|
|
9
|
+
- Filter files with glob parameter (e.g., "*.js", "**/*.tsx") or type parameter (e.g., "js", "py", "rust")
|
|
10
|
+
- Output modes: "content" shows matching lines, "files_with_matches" shows only file paths (default), "count" shows match counts
|
|
11
|
+
- Use Task tool for open-ended searches requiring multiple rounds
|
|
12
|
+
- Pattern syntax: Uses ripgrep (not grep) - literal braces need escaping (use `interface\{\}` to find `interface{}` in Go code)
|
|
13
|
+
- Multiline matching: By default patterns match within single lines only. For cross-line patterns like `struct \{[\s\S]*?field`, use `multiline: true`
|
|
14
|
+
- When investigating several patterns or directories at once, queue every `grep` call within the same response so they form a single batched execution.
|
|
15
|
+
</description>
|
|
16
|
+
|
|
17
|
+
<parameters>
|
|
18
|
+
<parameter name="pattern" required="true">
|
|
19
|
+
<description>The regular expression pattern to search for in file contents</description>
|
|
20
|
+
<type>string</type>
|
|
21
|
+
</parameter>
|
|
22
|
+
|
|
23
|
+
<parameter name="path" required="false">
|
|
24
|
+
<description>File or directory to search in (rg PATH). Defaults to current working directory.</description>
|
|
25
|
+
<type>string</type>
|
|
26
|
+
</parameter>
|
|
27
|
+
|
|
28
|
+
<parameter name="glob" required="false">
|
|
29
|
+
<description>Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}") - maps to rg --glob</description>
|
|
30
|
+
<type>string</type>
|
|
31
|
+
</parameter>
|
|
32
|
+
|
|
33
|
+
<parameter name="type" required="false">
|
|
34
|
+
<description>File type to search (rg --type). Common types: js, py, rust, go, java, etc. More efficient than include for standard file types.</description>
|
|
35
|
+
<type>string</type>
|
|
36
|
+
</parameter>
|
|
37
|
+
|
|
38
|
+
<parameter name="output_mode" required="false">
|
|
39
|
+
<description>Output mode: "content" shows matching lines (supports -A/-B/-C context, -n line numbers, head_limit), "files_with_matches" shows file paths (supports head_limit), "count" shows match counts (supports head_limit). Defaults to "files_with_matches".</description>
|
|
40
|
+
<type>string</type>
|
|
41
|
+
<enum>content</enum>
|
|
42
|
+
<enum>files_with_matches</enum>
|
|
43
|
+
<enum>count</enum>
|
|
44
|
+
</parameter>
|
|
45
|
+
|
|
46
|
+
<parameter name="-i" required="false">
|
|
47
|
+
<description>Case insensitive search (rg -i)</description>
|
|
48
|
+
<type>boolean</type>
|
|
49
|
+
</parameter>
|
|
50
|
+
|
|
51
|
+
<parameter name="-n" required="false">
|
|
52
|
+
<description>Show line numbers in output (rg -n). Requires output_mode: "content", ignored otherwise.</description>
|
|
53
|
+
<type>boolean</type>
|
|
54
|
+
</parameter>
|
|
55
|
+
|
|
56
|
+
<parameter name="-A" required="false">
|
|
57
|
+
<description>Number of lines to show after each match (rg -A). Requires output_mode: "content", ignored otherwise.</description>
|
|
58
|
+
<type>number</type>
|
|
59
|
+
</parameter>
|
|
60
|
+
|
|
61
|
+
<parameter name="-B" required="false">
|
|
62
|
+
<description>Number of lines to show before each match (rg -B). Requires output_mode: "content", ignored otherwise.</description>
|
|
63
|
+
<type>number</type>
|
|
64
|
+
</parameter>
|
|
65
|
+
|
|
66
|
+
<parameter name="-C" required="false">
|
|
67
|
+
<description>Number of lines to show before and after each match (rg -C). Requires output_mode: "content", ignored otherwise.</description>
|
|
68
|
+
<type>number</type>
|
|
69
|
+
</parameter>
|
|
70
|
+
|
|
71
|
+
<parameter name="multiline" required="false">
|
|
72
|
+
<description>Enable multiline mode where . matches newlines and patterns can span lines (rg -U --multiline-dotall). Default: false.</description>
|
|
73
|
+
<type>boolean</type>
|
|
74
|
+
</parameter>
|
|
75
|
+
|
|
76
|
+
<parameter name="head_limit" required="false">
|
|
77
|
+
<description>Limit output to first N lines/entries, equivalent to "| head -N". Works across all output modes: content (limits output lines), files_with_matches (limits file paths), count (limits count entries). When unspecified, shows all results from ripgrep.</description>
|
|
78
|
+
<type>number</type>
|
|
79
|
+
</parameter>
|
|
80
|
+
</parameters>
|
|
81
|
+
|
|
82
|
+
<examples>
|
|
83
|
+
<example>
|
|
84
|
+
<title>Search for a pattern in all files</title>
|
|
85
|
+
<command>{"pattern": "TODO"}</command>
|
|
86
|
+
</example>
|
|
87
|
+
|
|
88
|
+
<example>
|
|
89
|
+
<title>Case-insensitive search in Python files</title>
|
|
90
|
+
<command>{"pattern": "error", "-i": true, "type": "py"}</command>
|
|
91
|
+
</example>
|
|
92
|
+
|
|
93
|
+
<example>
|
|
94
|
+
<title>Search with context lines</title>
|
|
95
|
+
<command>{"pattern": "def.*process", "output_mode": "content", "-B": 2, "-A": 2}</command>
|
|
96
|
+
</example>
|
|
97
|
+
</examples>
|
|
98
|
+
</tool_prompt>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<tool_prompt>
|
|
3
|
+
<description>
|
|
4
|
+
Lists files and directories in a given path. The path parameter must be an absolute path, not a relative path. You can optionally provide an array of glob patterns to ignore with the ignore parameter. You should generally prefer the Glob and Grep tools, if you know which directories to search. When inspecting multiple directories, enumerate every `list_dir` call you intend to run in the same response so they execute together as a parallel batch.
|
|
5
|
+
</description>
|
|
6
|
+
|
|
7
|
+
<parameters>
|
|
8
|
+
<parameter name="path" required="true">
|
|
9
|
+
<description>The absolute path to the directory to list (must be absolute, not relative)</description>
|
|
10
|
+
<type>string</type>
|
|
11
|
+
</parameter>
|
|
12
|
+
|
|
13
|
+
<parameter name="ignore" required="false">
|
|
14
|
+
<description>List of glob patterns to ignore</description>
|
|
15
|
+
<type>array</type>
|
|
16
|
+
<items>string</items>
|
|
17
|
+
</parameter>
|
|
18
|
+
</parameters>
|
|
19
|
+
|
|
20
|
+
<examples>
|
|
21
|
+
<example>
|
|
22
|
+
<title>List files in project root</title>
|
|
23
|
+
<command>{"path": "/home/user/project"}</command>
|
|
24
|
+
</example>
|
|
25
|
+
|
|
26
|
+
<example>
|
|
27
|
+
<title>List files ignoring node_modules</title>
|
|
28
|
+
<command>{"path": "/home/user/project", "ignore": ["node_modules/**", "*.pyc"]}</command>
|
|
29
|
+
</example>
|
|
30
|
+
</examples>
|
|
31
|
+
</tool_prompt>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<tool>
|
|
2
|
+
<description>
|
|
3
|
+
Record a ReAct-style think/observe timeline, retrieve it, or clear it for the current session.
|
|
4
|
+
</description>
|
|
5
|
+
<parameters>
|
|
6
|
+
<parameter name="action" required="true">
|
|
7
|
+
<type>string</type>
|
|
8
|
+
<description>One of think, observe, get, clear.</description>
|
|
9
|
+
</parameter>
|
|
10
|
+
<parameter name="thoughts" required="false">
|
|
11
|
+
<type>string</type>
|
|
12
|
+
<description>Reasoning text for think entries.</description>
|
|
13
|
+
</parameter>
|
|
14
|
+
<parameter name="next_action" required="false">
|
|
15
|
+
<type>string</type>
|
|
16
|
+
<description>Planned action to pair with think entries.</description>
|
|
17
|
+
</parameter>
|
|
18
|
+
<parameter name="result" required="false">
|
|
19
|
+
<type>string</type>
|
|
20
|
+
<description>Observation details for observe entries.</description>
|
|
21
|
+
</parameter>
|
|
22
|
+
</parameters>
|
|
23
|
+
</tool>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<tool_prompt>
|
|
3
|
+
<description>
|
|
4
|
+
Reads a file from the local filesystem. You can access any file directly by using this tool.
|
|
5
|
+
Assume this tool is able to read all files on the machine. If the User provides a path to a file assume that path is valid. It is okay to read a file that does not exist; an error will be returned.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
- The file_path parameter must be an absolute path, not a relative path
|
|
9
|
+
- By default, it reads up to 2000 lines starting from the beginning of the file
|
|
10
|
+
- You can optionally specify a line offset and limit (especially handy for long files), but it's recommended to read the whole file by not providing these parameters
|
|
11
|
+
- Any lines longer than 2000 characters will be truncated
|
|
12
|
+
- Results are returned using cat -n format, with line numbers starting at 1
|
|
13
|
+
- This tool allows Claude Code to read images (eg PNG, JPG, etc). When reading an image file the contents are presented visually as Claude Code is a multimodal LLM.
|
|
14
|
+
- This tool can read PDF files (.pdf). PDFs are processed page by page, extracting both text and visual content for analysis.
|
|
15
|
+
- This tool can read Jupyter notebooks (.ipynb files) and returns all cells with their outputs, combining code, text, and visualizations.
|
|
16
|
+
- You have the capability to call multiple tools in a single response. Enumerate every file you plan to inspect so multiple `read_file` calls can run in parallel rather than waiting for sequential turns.
|
|
17
|
+
- You will regularly be asked to read screenshots. If the user provides a path to a screenshot ALWAYS use this tool to view the file at the path. This tool will work with all temporary file paths like /var/folders/123/abc/T/TemporaryItems/NSIRD_screencaptureui_ZfB1tD/Screenshot.png
|
|
18
|
+
- If you read a file that exists but has empty contents you will receive a system reminder warning in place of file contents.
|
|
19
|
+
</description>
|
|
20
|
+
|
|
21
|
+
<parameters>
|
|
22
|
+
<parameter name="file_path" required="true">
|
|
23
|
+
<description>The absolute path to the file to read</description>
|
|
24
|
+
<type>string</type>
|
|
25
|
+
</parameter>
|
|
26
|
+
|
|
27
|
+
<parameter name="offset" required="false">
|
|
28
|
+
<description>The line number to start reading from. Only provide if the file is too large to read at once</description>
|
|
29
|
+
<type>number</type>
|
|
30
|
+
</parameter>
|
|
31
|
+
|
|
32
|
+
<parameter name="limit" required="false">
|
|
33
|
+
<description>The number of lines to read. Only provide if the file is too large to read at once.</description>
|
|
34
|
+
<type>number</type>
|
|
35
|
+
</parameter>
|
|
36
|
+
</parameters>
|
|
37
|
+
|
|
38
|
+
<examples>
|
|
39
|
+
<example>
|
|
40
|
+
<title>Read entire file</title>
|
|
41
|
+
<command>{"file_path": "/home/user/project/main.py"}</command>
|
|
42
|
+
</example>
|
|
43
|
+
|
|
44
|
+
<example>
|
|
45
|
+
<title>Read partial file with offset</title>
|
|
46
|
+
<command>{"file_path": "/home/user/large_file.log", "offset": 1000, "limit": 500}</command>
|
|
47
|
+
</example>
|
|
48
|
+
|
|
49
|
+
<example>
|
|
50
|
+
<title>Read image file</title>
|
|
51
|
+
<command>{"file_path": "/home/user/screenshot.png"}</command>
|
|
52
|
+
</example>
|
|
53
|
+
</examples>
|
|
54
|
+
</tool_prompt>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<tool_prompt>
|
|
3
|
+
<description>
|
|
4
|
+
Executes system commands with enhanced control and monitoring capabilities. This tool provides advanced features for running commands including environment variable management, working directory control, and timeout handling.
|
|
5
|
+
|
|
6
|
+
Key features:
|
|
7
|
+
- Execute any system command or script
|
|
8
|
+
- Set custom working directory
|
|
9
|
+
- Manage environment variables
|
|
10
|
+
- Configure execution timeout
|
|
11
|
+
- Control output capture
|
|
12
|
+
- Support for background execution
|
|
13
|
+
|
|
14
|
+
Security considerations:
|
|
15
|
+
- Commands are validated for potentially destructive operations
|
|
16
|
+
- Working directories are verified before execution
|
|
17
|
+
- Environment variables are sanitized
|
|
18
|
+
- Timeout limits prevent runaway processes
|
|
19
|
+
</description>
|
|
20
|
+
|
|
21
|
+
<parameters>
|
|
22
|
+
<parameter name="command" required="true">
|
|
23
|
+
<description>The command to execute</description>
|
|
24
|
+
<type>string</type>
|
|
25
|
+
</parameter>
|
|
26
|
+
|
|
27
|
+
<parameter name="cwd" required="false">
|
|
28
|
+
<description>Working directory for the command (defaults to current)</description>
|
|
29
|
+
<type>string</type>
|
|
30
|
+
</parameter>
|
|
31
|
+
|
|
32
|
+
<parameter name="env" required="false">
|
|
33
|
+
<description>Additional environment variables to set</description>
|
|
34
|
+
<type>object</type>
|
|
35
|
+
</parameter>
|
|
36
|
+
|
|
37
|
+
<parameter name="timeout" required="false">
|
|
38
|
+
<description>Command timeout in seconds (default 30, max 300)</description>
|
|
39
|
+
<type>integer</type>
|
|
40
|
+
</parameter>
|
|
41
|
+
|
|
42
|
+
<parameter name="capture_output" required="false">
|
|
43
|
+
<description>Whether to capture stdout/stderr (default true)</description>
|
|
44
|
+
<type>boolean</type>
|
|
45
|
+
</parameter>
|
|
46
|
+
</parameters>
|
|
47
|
+
|
|
48
|
+
<examples>
|
|
49
|
+
<example>
|
|
50
|
+
<title>Run command in specific directory</title>
|
|
51
|
+
<command>{"command": "npm install", "cwd": "/home/user/project"}</command>
|
|
52
|
+
</example>
|
|
53
|
+
|
|
54
|
+
<example>
|
|
55
|
+
<title>Run with environment variables</title>
|
|
56
|
+
<command>{"command": "python script.py", "env": {"PYTHONPATH": "/custom/path", "DEBUG": "true"}}</command>
|
|
57
|
+
</example>
|
|
58
|
+
|
|
59
|
+
<example>
|
|
60
|
+
<title>Run with extended timeout</title>
|
|
61
|
+
<command>{"command": "make build", "timeout": 120}</command>
|
|
62
|
+
</example>
|
|
63
|
+
</examples>
|
|
64
|
+
</tool_prompt>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<tool_prompt>
|
|
3
|
+
<description>
|
|
4
|
+
Performs exact string replacements in files.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
- You must use your `Read` tool at least once in the conversation before editing. This tool will error if you attempt an edit without reading the file.
|
|
8
|
+
- When editing text from Read tool output, ensure you preserve the exact indentation (tabs/spaces) as it appears AFTER the line number prefix. The line number prefix format is: spaces + line number + tab. Everything after that tab is the actual file content to match. Never include any part of the line number prefix in the old_string or new_string.
|
|
9
|
+
- ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.
|
|
10
|
+
- Only use emojis if the user explicitly requests it. Avoid adding emojis to files unless asked.
|
|
11
|
+
- The edit will FAIL if `old_string` is not unique in the file. Either provide a larger string with more surrounding context to make it unique or use `replace_all` to change every instance of `old_string`.
|
|
12
|
+
- Use `replace_all` for replacing and renaming strings across the file. This parameter is useful if you want to rename a variable for instance.
|
|
13
|
+
</description>
|
|
14
|
+
|
|
15
|
+
<parameters>
|
|
16
|
+
<parameter name="file_path" required="true">
|
|
17
|
+
<description>The absolute path to the file to modify</description>
|
|
18
|
+
<type>string</type>
|
|
19
|
+
</parameter>
|
|
20
|
+
|
|
21
|
+
<parameter name="old_string" required="true">
|
|
22
|
+
<description>The text to replace</description>
|
|
23
|
+
<type>string</type>
|
|
24
|
+
</parameter>
|
|
25
|
+
|
|
26
|
+
<parameter name="new_string" required="true">
|
|
27
|
+
<description>The text to replace it with (must be different from old_string)</description>
|
|
28
|
+
<type>string</type>
|
|
29
|
+
</parameter>
|
|
30
|
+
|
|
31
|
+
<parameter name="replace_all" required="false">
|
|
32
|
+
<description>Replace all occurences of old_string (default false)</description>
|
|
33
|
+
<type>boolean</type>
|
|
34
|
+
</parameter>
|
|
35
|
+
</parameters>
|
|
36
|
+
|
|
37
|
+
<examples>
|
|
38
|
+
<example>
|
|
39
|
+
<title>Update a single line</title>
|
|
40
|
+
<command>{"file_path": "/home/user/project/config.py", "old_string": "DEBUG = False", "new_string": "DEBUG = True"}</command>
|
|
41
|
+
</example>
|
|
42
|
+
|
|
43
|
+
<example>
|
|
44
|
+
<title>Rename variable throughout file</title>
|
|
45
|
+
<command>{"file_path": "/home/user/project/main.py", "old_string": "old_var", "new_string": "new_var", "replace_all": true}</command>
|
|
46
|
+
</example>
|
|
47
|
+
|
|
48
|
+
<example>
|
|
49
|
+
<title>Update function with context</title>
|
|
50
|
+
<command>{"file_path": "/home/user/project/utils.py", "old_string": "def process_data(data):\n return data", "new_string": "def process_data(data):\n # Process the data\n return data.strip()"}</command>
|
|
51
|
+
</example>
|
|
52
|
+
</examples>
|
|
53
|
+
</tool_prompt>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<tool_prompt>
|
|
3
|
+
<description>
|
|
4
|
+
Writes a file to the local filesystem.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
- This tool will overwrite the existing file if there is one at the provided path.
|
|
8
|
+
- 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.
|
|
9
|
+
- ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.
|
|
10
|
+
- NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.
|
|
11
|
+
- Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked.
|
|
12
|
+
</description>
|
|
13
|
+
|
|
14
|
+
<parameters>
|
|
15
|
+
<parameter name="file_path" required="true">
|
|
16
|
+
<description>The absolute path to the file to write (must be absolute, not relative)</description>
|
|
17
|
+
<type>string</type>
|
|
18
|
+
</parameter>
|
|
19
|
+
|
|
20
|
+
<parameter name="content" required="true">
|
|
21
|
+
<description>The content to write to the file</description>
|
|
22
|
+
<type>string</type>
|
|
23
|
+
</parameter>
|
|
24
|
+
</parameters>
|
|
25
|
+
|
|
26
|
+
<examples>
|
|
27
|
+
<example>
|
|
28
|
+
<title>Write a Python file</title>
|
|
29
|
+
<command>{"file_path": "/home/user/project/script.py", "content": "#!/usr/bin/env python3\nprint('Hello, World!')"}</command>
|
|
30
|
+
</example>
|
|
31
|
+
|
|
32
|
+
<example>
|
|
33
|
+
<title>Write configuration file</title>
|
|
34
|
+
<command>{"file_path": "/home/user/project/.env", "content": "DEBUG=true\nPORT=3000"}</command>
|
|
35
|
+
</example>
|
|
36
|
+
</examples>
|
|
37
|
+
</tool_prompt>
|
tunacode/tools/react.py
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"""Lightweight ReAct-style scratchpad tool."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any, Dict, Literal
|
|
7
|
+
|
|
8
|
+
import defusedxml.ElementTree as ET
|
|
9
|
+
from pydantic_ai.exceptions import ModelRetry
|
|
10
|
+
|
|
11
|
+
from tunacode.core.state import StateManager
|
|
12
|
+
from tunacode.types import ToolResult, UILogger
|
|
13
|
+
|
|
14
|
+
from .base import BaseTool
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# CLAUDE_ANCHOR[react-tool]: Minimal ReAct scratchpad tool surface
|
|
18
|
+
class ReactTool(BaseTool):
|
|
19
|
+
"""Minimal ReAct scratchpad for tracking think/observe steps."""
|
|
20
|
+
|
|
21
|
+
def __init__(self, state_manager: StateManager, ui_logger: UILogger | None = None):
|
|
22
|
+
super().__init__(ui_logger)
|
|
23
|
+
self.state_manager = state_manager
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def tool_name(self) -> str:
|
|
27
|
+
return "react"
|
|
28
|
+
|
|
29
|
+
async def _execute(
|
|
30
|
+
self,
|
|
31
|
+
action: Literal["think", "observe", "get", "clear"],
|
|
32
|
+
thoughts: str | None = None,
|
|
33
|
+
next_action: str | None = None,
|
|
34
|
+
result: str | None = None,
|
|
35
|
+
) -> ToolResult:
|
|
36
|
+
scratchpad = self._ensure_scratchpad()
|
|
37
|
+
|
|
38
|
+
if action == "think":
|
|
39
|
+
if not thoughts:
|
|
40
|
+
raise ModelRetry("Provide thoughts when using react think action")
|
|
41
|
+
if not next_action:
|
|
42
|
+
raise ModelRetry("Specify next_action when recording react thoughts")
|
|
43
|
+
|
|
44
|
+
entry = {
|
|
45
|
+
"type": "think",
|
|
46
|
+
"thoughts": thoughts,
|
|
47
|
+
"next_action": next_action,
|
|
48
|
+
}
|
|
49
|
+
self.state_manager.append_react_entry(entry)
|
|
50
|
+
return "Recorded think step"
|
|
51
|
+
|
|
52
|
+
if action == "observe":
|
|
53
|
+
if not result:
|
|
54
|
+
raise ModelRetry("Provide result when using react observe action")
|
|
55
|
+
|
|
56
|
+
entry = {
|
|
57
|
+
"type": "observe",
|
|
58
|
+
"result": result,
|
|
59
|
+
}
|
|
60
|
+
self.state_manager.append_react_entry(entry)
|
|
61
|
+
return "Recorded observation"
|
|
62
|
+
|
|
63
|
+
if action == "get":
|
|
64
|
+
timeline = scratchpad.get("timeline", [])
|
|
65
|
+
if not timeline:
|
|
66
|
+
return "React scratchpad is empty"
|
|
67
|
+
|
|
68
|
+
formatted = [
|
|
69
|
+
f"{index + 1}. {item['type']}: {self._format_entry(item)}"
|
|
70
|
+
for index, item in enumerate(timeline)
|
|
71
|
+
]
|
|
72
|
+
return "\n".join(formatted)
|
|
73
|
+
|
|
74
|
+
if action == "clear":
|
|
75
|
+
self.state_manager.clear_react_scratchpad()
|
|
76
|
+
return "React scratchpad cleared"
|
|
77
|
+
|
|
78
|
+
raise ModelRetry("Invalid react action. Use one of: think, observe, get, clear")
|
|
79
|
+
|
|
80
|
+
def _format_entry(self, item: Dict[str, Any]) -> str:
|
|
81
|
+
if item["type"] == "think":
|
|
82
|
+
return f"thoughts='{item['thoughts']}', next_action='{item['next_action']}'"
|
|
83
|
+
if item["type"] == "observe":
|
|
84
|
+
return f"result='{item['result']}'"
|
|
85
|
+
return str(item)
|
|
86
|
+
|
|
87
|
+
def _ensure_scratchpad(self) -> dict[str, Any]:
|
|
88
|
+
scratchpad = self.state_manager.get_react_scratchpad()
|
|
89
|
+
scratchpad.setdefault("timeline", [])
|
|
90
|
+
return scratchpad
|
|
91
|
+
|
|
92
|
+
def _get_base_prompt(self) -> str:
|
|
93
|
+
prompt_file = Path(__file__).parent / "prompts" / "react_prompt.xml"
|
|
94
|
+
if prompt_file.exists():
|
|
95
|
+
try:
|
|
96
|
+
tree = ET.parse(prompt_file)
|
|
97
|
+
root = tree.getroot()
|
|
98
|
+
description = root.find("description")
|
|
99
|
+
if description is not None and description.text:
|
|
100
|
+
return description.text.strip()
|
|
101
|
+
except Exception:
|
|
102
|
+
pass
|
|
103
|
+
return "Use this tool to record think/observe notes and manage the react scratchpad"
|
|
104
|
+
|
|
105
|
+
def _get_parameters_schema(self) -> Dict[str, Any]:
|
|
106
|
+
prompt_file = Path(__file__).parent / "prompts" / "react_prompt.xml"
|
|
107
|
+
if prompt_file.exists():
|
|
108
|
+
try:
|
|
109
|
+
tree = ET.parse(prompt_file)
|
|
110
|
+
root = tree.getroot()
|
|
111
|
+
parameters = root.find("parameters")
|
|
112
|
+
if parameters is not None:
|
|
113
|
+
schema: Dict[str, Any] = {
|
|
114
|
+
"type": "object",
|
|
115
|
+
"properties": {},
|
|
116
|
+
"required": ["action"],
|
|
117
|
+
}
|
|
118
|
+
for param in parameters.findall("parameter"):
|
|
119
|
+
name = param.get("name")
|
|
120
|
+
param_type = param.find("type")
|
|
121
|
+
description = param.find("description")
|
|
122
|
+
if name and param_type is not None:
|
|
123
|
+
schema["properties"][name] = {
|
|
124
|
+
"type": param_type.text.strip(),
|
|
125
|
+
"description": description.text.strip()
|
|
126
|
+
if description is not None and description.text
|
|
127
|
+
else "",
|
|
128
|
+
}
|
|
129
|
+
return schema
|
|
130
|
+
except Exception:
|
|
131
|
+
pass
|
|
132
|
+
return {
|
|
133
|
+
"type": "object",
|
|
134
|
+
"properties": {
|
|
135
|
+
"action": {
|
|
136
|
+
"type": "string",
|
|
137
|
+
"description": "react operation to perform",
|
|
138
|
+
},
|
|
139
|
+
"thoughts": {
|
|
140
|
+
"type": "string",
|
|
141
|
+
"description": "Thought content for think action",
|
|
142
|
+
},
|
|
143
|
+
"next_action": {
|
|
144
|
+
"type": "string",
|
|
145
|
+
"description": "Planned next action for think action",
|
|
146
|
+
},
|
|
147
|
+
"result": {
|
|
148
|
+
"type": "string",
|
|
149
|
+
"description": "Observation message for observe action",
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
"required": ["action"],
|
|
153
|
+
}
|