context-dropper is a CLI for iterating through a fixed list of files, tracking
position, and tagging progress.
AI coding agents struggle with large codebases in two main ways:
- Search doesn't guarantee coverage: Agents often rely on semantic or keyword search to find relevant files, and it works well in many cases. But for tasks that require iterating over every file in a set, there is no guarantee that search alone will find them all.
- Context windows are a hard constraint: Feeding an entire codebase into an LLM at once is often simply impossible. Codebases frequently exceed the model's token limit. Even when it fits, reasoning quality degrades as the context grows.
context-dropper solves this by enforcing strict, programmable processing
loops.
Instead of relying on search, a precise list of target files (a "fileset") is curated upfront - either manually or by using other tools - and the agent is instructed to process that exact list sequentially. As the agent moves from one file to the next, it can drop the previous file's tokens from memory. Each file is then evaluated in a clean context.
This approach guarantees 100% file coverage, minimizes token usage, and keeps the model's reasoning sharp.
Consider an agent tasked with exploring a large codebase to document every piece
of authentication logic it finds into a single file
(authentication-discovery.md). Without context-dropper, the agent would use
search to find files containing keywords like "auth", "login", or "session", and
might miss files that contain authentication logic but don't match those
keywords. With context-dropper, the agent instead iterates over a fixed,
curated list of files, such as all files in a subdirectory or a filtered list
from a test coverage report.
Here is how that looks in practice:
- The Fileset: A discrete list of target files is provided to the tool:
src/auth/login.tssrc/routes/api.tssrc/middleware/session.ts
- The Dropper: A "dropper" is created and attached to that fileset. The dropper acts as a stateful bookmark that tracks exactly where the agent is in the list (it can go forward or backward).
- The Loop: The AI agent is given a strict set of instructions: "Read the
current file from the dropper. If authentication logic is found, append the
findings to
authentication-discovery.md. Then mark the file as 'processed', and move the dropper to the next file until the list is exhausted."
By explicitly unloading the previous file from its context window before moving the dropper, the context size remains small. This prevents the LLM from blowing past its token limits or suffering from degraded reasoning. In theory, an unlimited number of files can be processed this way.
You can install context-dropper using one of the following methods.
Download the latest standalone executable for your operating system from the
Releases page. Ensure it
is executable and in your PATH.
chmod +x context-dropper
mv context-dropper /usr/local/bin/You can install the package globally from NPM.
Bun:
bun install -g context-dropperNPM:
npm install -g context-dropperThen run it anywhere:
context-dropper --helpTo develop, compile binaries from source, or contribute to the project, please refer to the Contributing Guide.
context-dropper [--data-dir <path>] <command>Global option:
--data-dir <path>: directory where filesets and droppers are stored.- Default:
./.context-dropperresolved from current working directory.
If run with no command, usage/help is shown. If fileset or dropper are run
without a subcommand, that group help is shown.
The CLI stores state under data-dir:
data-dir/
filesets/
<name>.txt
droppers/
<name>.json
Fileset file (filesets/<name>.txt):
- One normalized absolute file path per line.
- Import is immutable: importing the same fileset name again fails.
Dropper file (droppers/<name>.json):
{
"fileset": "my-fileset",
"pointer_position": 0,
"tags": {
"processed": ["/abs/path/a.ts", "/abs/path/b.ts"]
}
}tagsistag -> filename[].- Filename arrays are deduplicated and sorted.
Fileset/dropper names must:
- Match
^[A-Za-z0-9._-]+$ - Not be
.or.. - Not contain path separators
Import from a list file:
context-dropper fileset import --name <name> <listFilePath>listFilePathmust be plain text with one path per line.- Blank lines are ignored.
- Relative lines are resolved from the list file directory.
- Each referenced file must exist and be readable.
- Stored entries become normalized absolute paths.
List filesets:
context-dropper fileset list- Output: one fileset name per line.
Show fileset contents:
context-dropper fileset show <name>- Output: one file path per line.
Remove fileset:
context-dropper fileset remove <name>- Fails if any dropper still references it.
Create:
context-dropper dropper create --fileset <filesetName> <dropperName>Show current file contents:
context-dropper dropper show <dropperName>Move pointer forward:
context-dropper dropper next <dropperName>- Silent on success.
Move pointer backward:
context-dropper dropper previous <dropperName>- Silent on success.
Tag current item:
context-dropper dropper tag <dropperName> --tag <text> [--tag <text>]...List tags of current item:
context-dropper dropper list-tags <dropperName>- Output: one tag per line.
Remove tags from current item:
context-dropper dropper remove-tag <dropperName> --tag <text> [--tag <text>]...List dropper entries with optional filters:
context-dropper dropper list-files <dropperName> [--tag <tag>]... [--filename <absolutePath>]- Output: paths only, one per line.
- Repeated
--taguses OR semantics. --filenameis exact path match.- When both are provided: AND semantics (
filenamematch and tag OR match). - Aliases:
context-dropper dropper ls-files <dropperName>
List all droppers, optionally filtered by fileset name:
context-dropper dropper list [--fileset <filesetName>]- Output: one dropper name per line.
- When
--filesetis provided, filters for droppers referencing that fileset. - Aliases:
context-dropper dropper ls [--fileset <filesetName>]
Dump dropper materialized state:
context-dropper dropper dump <dropperName>- Output: pretty JSON.
Remove dropper:
context-dropper dropper remove <dropperName>Check completion:
context-dropper dropper is-done <dropperName>- Done condition: every file has at least one tag.
- If done: prints
trueand exits0. - If not done: exits non-zero with an error listing untagged files.
This repository also includes a dedicated, self-contained plugin for
OpenCode under opencode-plugin/.
The plugin natively binds to the context-dropper APIs and lets you iterate
through filesets autonomously inside an OpenCode chat session. See
opencode-plugin/README.md for installation and
usage instructions.
0: success1: application error2: usage/argument error3: dropper exhausted (showwith no current item, ornextat end)4: dropper at start (previousat start)
- Import a fileset:
context-dropper fileset import --name <filesetName> <listFilePath> - Create a dropper:
context-dropper dropper create --fileset <filesetName> <dropperName> - Ask the agent to perform the task (for example: review/document each file) and follow the processing loop below.
When acting as an agent over a dropper, use this exact loop:
- Run
context-dropper dropper show <dropperName>. - Perform the requested task on that file content.
- Run
context-dropper dropper tag <dropperName> --tag processed. - Run
context-dropper dropper is-done <dropperName>. - If
is-donesucceeded and printedtrue, stop. - If
is-donefailed because untagged items remain, runcontext-dropper dropper next <dropperName>and repeat from step 1.
Notes for agents:
nextandpreviousare movement only; they do not print file contents.- Use
showto read the current file. - Do not stop on
is-donenon-zero unless the message is notUntagged items remain: ....