[PERF] Write tool has high per-call latency for bulk file copying — need built-in copy/move
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When a plugin command needs to copy multiple files verbatim (no model-generated modifications), using the Write tool for each file is extremely slow. Each Write call requires the model to stream the entire file content as a tool parameter, adding significant latency per file. For 11 files, this caused an ~8 minute stall (visible as a long "Musing" phase) where the model was sequentially generating Write tool calls.
Switching to Bash cp commands reduced this to under 1 second.
Why We're Copying Files in the First Place
Plugin subagents cannot read files from the plugin cache directory (~/.claude/plugins/cache/). They are sandboxed to the project working directory. This means any plugin that needs subagents to access bundled templates, methodology files, or other plugin assets must first stage those files into the project directory where subagents can reach them.
This is compounded by #9354 — ${CLAUDE_PLUGIN_ROOT} is resolved in command markdown text but is not set as an actual shell environment variable, so subagents can't even construct paths to the plugin cache.
The result is that plugins with subagent pipelines (like audit tools that fan out work to parallel agents) must copy N files from the plugin cache to the project directory on every invocation. With Read+Write as the only non-Bash option, this staging phase dominates startup time.
The Gap
There is no built-in tool for copying or moving files. The Write tool is the only non-Bash option, but it is designed for model-generated content and has overhead that makes it unsuitable for verbatim file copies:
- The model must output the full file content as a tool parameter (token generation latency)
- The diff UI renders for each file (rendering overhead)
- Calls are sequential — the model generates one Write at a time
Suggested Solutions
Any of these would help:
- Built-in Copy/Move tool — takes source and destination paths, no content streaming needed
- Batch Write support — accept multiple file writes in a single tool call
- Grant subagents read access to the plugin cache — this would eliminate the need to copy files entirely (see #9354)
- Documentation guidance — explicitly recommend Bash
cpover Read+Write for verbatim file copying in plugin development docs
Workaround
Use Bash cp commands instead of Read+Write. This works but requires the Bash tool to be in the command's allowed-tools list.
Environment
- macOS
- Claude Code latest
- Observed in a plugin command that stages 11 template files from the plugin cache to a project directory
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗