Skip to content

Latest commit

 

History

History
486 lines (354 loc) · 11.9 KB

File metadata and controls

486 lines (354 loc) · 11.9 KB

CopyTree CLI Reference

Basic Usage

copytree [path] [options]

Arguments:

  • path - Directory path or GitHub URL to copy (defaults to current directory)

Command Options

Profile Options

--profile=<name>, -p <name>

Use a specific profile for file selection. If omitted, CopyTree uses the default profile.

Examples:

copytree --profile mycustom
copytree -p mycustom

Note: The default profile is automatically used when no profile is specified. Create custom profiles in ~/.copytree/profiles/ or .copytree/ for project-specific needs.

Filter Options

--filter=<pattern>, -f <pattern>

Include files matching glob patterns. Can be used multiple times.

copytree --filter "*.js" --filter "*.ts"
copytree -f "src/**/*.php" -f "tests/**/*.php"

--modified, -m

Only include files modified since the last Git commit.

copytree --modified
copytree -m

--changed=<ref>, -c <ref>

Include files changed since a specific Git reference (commit, branch, or tag).

copytree --changed HEAD~5
copytree -c main
copytree --changed v1.0.0

--exclude=<pattern>, -x <pattern>

Exclude files matching glob patterns. Can be used multiple times.

copytree --exclude "**/*.test.js" --exclude "fixtures/**"

Scope Options

--scope <path...>

Copy only these paths. Literal paths, not globs — a directory named src/[draft] is just a path, and there is nothing to escape.

Ignore rules still resolve from the project root: the root .gitignore, the root .copytreeignore, and every nested ignore file between the root and the selection all apply. A scoped run selects exactly the files a filtered full run would. Output paths stay relative to the project root, so @-references handed to an agent still resolve.

Traversal starts at the selection rather than the root, so the cost scales with what you asked for instead of with the size of the repository.

# One folder, repository rules
copytree --scope src/panels/file-browser

# Several entries, files as well as directories
copytree --scope src/panels package.json

# Compose with a filter: TypeScript files under src
copytree --scope src --filter "**/*.ts"

--scope-include-ignored

Let --scope entries override the ignore rules that would otherwise exclude them. Off by default, so a scoped run keeps the "same set as a full run" guarantee. Use it for the deliberate gesture: you navigated into a gitignored folder and want it anyway.

copytree --scope build/generated --scope-include-ignored

--scope-include-config-excluded

Let --scope entries override the config exclusions blocking them (node_modules, and anything in copytree.globalExcludedDirectories / globalExcludedFiles).

Separate from --scope-include-ignored because the two answer different questions: one is "yes, I know it's gitignored", the other is "yes, I really do mean node_modules". A path excluded by both layers needs both flags, which scoping into node_modules normally does, since most repositories also gitignore it.

.git is excluded by a layer neither flag lifts.

copytree --scope node_modules/some-package --scope-include-ignored --scope-include-config-excluded

Output Options

--output[=<file>], -o [<file>]

Save output to a file.

copytree --output output.xml
copytree -o output.xml

--display, -i

Print the output to the terminal instead of writing a file reference.

copytree --display
copytree -i

--stream, -S

Stream output without buffering (useful for piping).

copytree --stream | less
copytree -S > project.xml

See --clipboard under Content Options for copying the output text itself. The default is a file reference: CopyTree writes the output to a temp file and puts that path on the clipboard.

Format Options

--format=<type>

Output format: xml, markdown|md, json, ndjson, sarif, or tree.

Default: xml

copytree --format json
copytree --format ndjson
copytree --format sarif
copytree --format tree
copytree --format xml  # default
copytree --format markdown

Display Control Options

--head=<number>, -l <number>

Limit to first N files processed.

copytree --head 50
copytree -l 100

--char-limit=<number>, -C <number>

Character budget across all file content.

Truncation happens at a line boundary and is marked inline (… [truncated 4,213 of 9,001 lines]), so an agent cannot conclude the file simply ends there. When a single line is longer than the remaining budget — a minified bundle, say — the cut is mid-line and labelled as such rather than dropping the file. Chunks never end on an unpaired UTF-16 surrogate.

copytree --char-limit 100000
copytree -C 50000

Budget Options

Budgets are applied after sorting, so which files survive follows --sort. Truncation is always reported, never silent: a silently truncated context is worse than an error, because the agent answers confidently from a partial repository.

--size-gate=<size> / --no-size-gate

Hard per-file size gate, applied from stat() before anything is opened. Default: 256KB.

This is not the same as maxFileSize (a 10MB memory-safety ceiling) or --char-limit (which truncates after reading). No single 256KB+ file belongs in an agent's context window, and the gate exists whether or not truncation is enabled.

Only --always and .copytreeinclude lift the gate, and the override is reported.

copytree --size-gate 64KB
copytree --no-size-gate            # include large files
copytree --size-gate 64KB --always "docs/spec.md"

--max-total-size=<size>

Total size budget across all selected files.

copytree --max-total-size 5MB

--max-files=<number>

Maximum number of files to include.

Budgets keep the head of the sorted list and drop the tail, and --sort is ascending by default. --sort modified therefore keeps the oldest files; pair it with --sort-order desc to keep the recently-touched ones.

copytree --max-files 500 --sort modified --sort-order desc   # keep the newest 500
copytree --max-files 500 --sort size                         # keep the 500 smallest

--sort-order <asc|desc>

Sort direction (default: asc). Decides which end of the list a budget keeps.

--only-tree, -t

Show only directory structure, no file contents.

copytree --only-tree
copytree -t

Sorting & Git Status Options

--sort=<by>, -s <by>

Sort files by: path, size, modified, name, or extension.

copytree --sort modified
copytree --sort size
copytree -s name

--with-git-status

Include Git status indicators for each file.

copytree --with-git-status

--always=<patterns...>

Always include these patterns (force-include), even if excluded by profile.

copytree --always "*.config.js" --always "config.example.js"

Content Options

--with-line-numbers

Include line numbers in output.

copytree --with-line-numbers

--show-size

Show file sizes in output.

copytree --show-size

--info

Show information table with project statistics.

copytree --info

--include-binary

Include binary files in output (normally excluded).

copytree --include-binary

--dedupe

Remove duplicate files from output.

copytree --dedupe

--clipboard, -y

Copy the output text itself to the clipboard, rather than a reference to a file containing it.

The default is a file reference: CopyTree writes the output to a temp file and puts that path on the clipboard, so pasting into an agent hands over a file to read instead of a few hundred kilobytes of inline context. Use this when you want the text itself, for example to paste into a chat box directly.

copytree --clipboard
copytree -y

--as-reference, -r

No-op. Writing a file reference is the default, so this flag selects the behaviour you would get anyway. Accepted so existing scripts and habits keep working.

--no-folder-profile

Skip auto-discovery of a .copytree.yml (or .copytree.yaml / .copytree.json) profile in the project being copied. Discovery is on by default; a profile named explicitly with -p takes precedence over a discovered one.

copytree --no-folder-profile

--external=<source...>

Include external sources (GitHub URLs or local paths).

copytree --external https://github.com/user/repo

Transformation Options

Note: Transformers are configured in profiles, not via CLI flags. Built-in transformers include file-loader, binary, and streaming-file-loader.

Debug & Optimization Options

--dry-run

Plan the run without reading or formatting content.

A dry run is a strict prefix of the real run: the same file set, in the same order, under the same budgets. It reports the file count, total size, an approximate token count, and what was excluded.

copytree --dry-run
Dry run - nothing was read or written.
Base path: /repo
221 file(s), 1.42 MB, ~406k tokens
25 excluded: 19 copytreeignore, 4 gitignore, 1 configExclude, 1 sizeGate

--explain

Report which rule excluded each file, with the ignore file and line it came from. Turns "why isn't my file here?" from a bisect into a glance.

copytree --dry-run --explain
Largest exclusions:
  package-lock.json — 351.44 KB — sizeGate [sizeGate:262144]
  CHANGELOG.md — 14.78 KB — copytreeignore [CHANGELOG.md] (/repo/.copytreeignore:20)
  sub/nested.txt — 2 B — gitignore [nested.txt] (/repo/sub/.gitignore:1)

Aggregate counts are always collected and cost nothing extra. --explain adds the per-file detail.

--validate

Validate profile syntax without processing files.

copytree --validate --profile myprofile

--no-cache

Disable caching for AI operations and external sources.

copytree --no-cache

--no-validate

Disable configuration validation (for testing/debugging).

copytree --no-validate

Instructions Options

--no-instructions

Disable including instructions in output.

copytree --no-instructions

--instructions=<name>

Use custom instructions set (default: default).

copytree --instructions custom
copytree --instructions default

Exit Codes

  • 0 - Success
  • 1 - Profile validation or loading errors
  • 2 - Invalid option combination
  • 3 - File system or Git errors

Examples

Basic Usage

# Copy current directory; the clipboard gets a path to the output file
copytree

# Copy the output text itself instead
copytree --clipboard

# Copy specific directory
copytree /path/to/project

# Copy from GitHub
copytree https://github.com/facebook/react

Using Profiles

# Uses default profile automatically
copytree

# Use custom profile
copytree --profile mycustom

# Preview profile selection
copytree --profile mycustom --dry-run

Filtering Files

# Pattern matching
copytree --filter "src/**/*.js" --filter "*.json"

# Git integration
copytree --modified
copytree --changed HEAD~5

Output Options

# Save to file (Markdown by default)
copytree --output project-snapshot.md

# Save as XML
copytree --output project-snapshot.xml --format xml

# Display in console
copytree --display

# Different formats
copytree --format json
copytree --format tree

Advanced Usage

# Combine multiple options
copytree --profile myproject --modified --output snapshot.md

# Dry run with validation
copytree --dry-run --validate

# Limit output
copytree --head 50 --char-limit 100000

# Stream large projects
copytree --stream | gzip > project.md.gz

Notes

  • The --validate option cannot be combined with output options or filters
  • External sources (GitHub URLs) are cached by default in ~/.copytree/repos/
  • Use DEBUG=copytree:* environment variable for detailed debugging