Drush DTK - the "Drush Token Killer" - provides token-saving output defaults for common Drush commands. Inspired by RTK (the "Rust Token Killer"), it shrinks the output of frequently-run, read-only Drush commands so that AI agents (and humans) spend far fewer tokens reading them.
Opt-in compression. Enabling the module changes nothing for humans at a terminal - you (or your agent) switch it on per command, per session, or permanently. See "Enabling compression" below.
It works with lightweight Drush hooks that, when you have not asked for specific output yourself, select a compact set of fields and force CSV to drop the wide ASCII table chrome. No commands are added for everyday use - the module only alters the output of existing core and contrib Drush commands.
How it works
Each supported command has an INITIALIZE hook that, when compression is enabled, sets sensible defaults (--fields and/or --format=csv) before the command runs. config:status also has an ALTER_RESULT hook that rewrites its verbose state strings to short tokens. The original commands and their behaviour are otherwise untouched.
Enabling compression
Three opt-in surfaces, highest precedence first:
--ai-compressflag - one command, e.g.drush pml --ai-compressDTK_COMPRESS=1environment variable - one session; recommended for agents, since they invoke Drush through wrappers where injecting flags is awkward- Config -
drush config:set dtk.settings compress 1for always-on
DTK_COMPRESS=0 (also false, no, off) explicitly disables compression, overriding the config. --no-ai-compress on any command beats everything and restores native output. There is deliberately no TTY or "am I an agent?" detection - output only changes when something asked for it.
Agent hooks
One command wires DTK_COMPRESS=1 into an agent's project-level config:
|
Compressed commands
Defaults applied when compression is enabled:
| Command | Default applied | Savings |
|---|---|---|
pm:list (pml) |
--status=<wbr>enabled|<wbr>disabled → --fields=<wbr>name; otherwise --fields=<wbr>name,<wbr>status; CSV |
up to 90% |
core:requirements (rq) |
--severity=1 (warnings + errors only), --fields=<wbr>title,<wbr>severity, CSV |
up to 97% |
config:status (cst) |
CSV + state tokens (see below) | up to 45% |
watchdog:show (ws) |
--fields=<wbr>type,<wbr>severity,<wbr>message, CSV |
up to 50% |
role:list (rls) |
--fields=<wbr>rid,<wbr>label, CSV (native default is YAML) |
up to 50% |
queue:list |
CSV | small |
migrate:status (ms) |
CSV | varies |
migrate:messages (mmsg) |
--fields=<wbr>level,<wbr>source_ids,<wbr>message, CSV |
up to 40% |
field:info (fi) |
CSV | varies |
field:base-info (fbi) |
--fields=<wbr>field_name,<wbr>field_type,<wbr>required,<wbr>cardinality, CSV |
up to 70% |
field:types |
--fields=<wbr>id,<wbr>label (native YAML kept — result can't render as CSV) |
up to 80% |
field:formatters |
--fields=<wbr>id,<wbr>label,<wbr>field_types (native YAML kept — result can't render as CSV) |
up to 70% |
field:widgets |
--fields=<wbr>id,<wbr>label,<wbr>field_types (native YAML kept — result can't render as CSV) |
up to 70% |
updatedb:status (updbst) |
--fields=<wbr>module,<wbr>update_id,<wbr>description, CSV |
up to 50% |
user:information (uinf) |
--fields=<wbr>uid,<wbr>name,<wbr>mail,<wbr>user_status, CSV |
up to 60% |
deploy:hook-status |
CSV | small |
Contrib module compressed commands
Compressed only when the owning module is installed; with it absent the hook never fires. The Devel rows also require Drush 13.7+ (see Requirements).
| Command | Module | Default applied | Savings |
|---|---|---|---|
devel:services (dcs) |
Devel | CSV (single id column) | ~67% |
devel:token (token) |
Devel | --fields=group,token, CSV |
~85% |
search-api:list (sapi-l) |
Search API | --fields=id,serverName,status, CSV |
Varies |
search-api:status (sapi-s) |
Search API | --fields=id,complete,indexed,total, CSV |
Varies |
search-api:server-list (sapi-sl) |
Search API | --fields=id,status, CSV |
Varies |
search-api:search (sapi-search) |
Search API | CSV | Small |
views:bulk-operations:list (vbo-list) |
Views Bulk Operations | --fields=id,entity_type_id, CSV |
Small |
config:status state tokens
The verbose state strings are collapsed to single tokens:
The --state filter still works with the original strings (e.g. drush config:status --state='Only in DB'), because the tokenisation runs after the command has already filtered.
Opting out
Even when compression is enabled, add --no-ai-compress to any command to get its native, uncompressed output:
drush pml --no-ai-compressCompression is also skipped automatically whenever you choose your own output, i.e. you pass --field or --fields (and, for format, any --format other than the command's native default).
Limitations
- Pre-bootstrap commands cannot be compressed. Commands that run before Drupal's modules load - notably
core:statusandcache:rebuild(cr) - never receive this module's hooks.core:status --no-ai-compresseven reports "option does not exist". This is inherent to module-provided Drush hooks. config:import/config:exportpreviews are not reformatted. Those commands print their change preview as a hardcoded Symfony Console table straight to the terminal, mid-command, before the confirmation prompt - there is no formatter hook to retarget it. To preview pending config changes as CSV, useconfig:statusinstead (itsonly_sync/only_db/differenttokens are the same information framed as create / delete / update).
Requirements
- Drupal ^11
- Drush 13+
Installation
|
Contributing
The Drush Token Killer module's issue queue is intended for reporting bugs, submitting feature requests, and planning.
Additionally, you can join the #ai-contrib or #ai-learners channels on Drupal Slack.
Project information
- Project categories: Artificial Intelligence (AI)
- Ecosystem: AI (Artificial Intelligence)
21 sites report using this module
- Created by marcus_johansson on , updated
Stable releases for this project are covered by the security advisory policy.
Look for the shield icon below.

