This repository ships a native zsh completion for Dokku and includes a local Docker-backed Dokku harness for developing it against live core and plugin commands.
Keep user-facing installation, verification, and troubleshooting information
in README.md. Keep contributor and agent workflow in this file.
| Path | Purpose |
|---|---|
completions/_dokku |
Shipped native zsh completion (#compdef dokku) |
zsh-dokku.plugin.zsh |
Adds completions/ to fpath |
generate-completion-prompt.md |
Detailed implementation and acceptance brief |
tests/completion_test.zsh |
Hermetic, read-only live, and dynamic tests |
Justfile |
Harness lifecycle and test recipes |
bin/dokku |
Local docker exec wrapper |
compose.yml |
Local Dokku service |
dokku-plugins.txt |
Plugins installed in the local harness |
tmp/ |
Gitignored harness runtime state |
Read generate-completion-prompt.md before substantial completion work. In
particular:
- Keep the shipped completion pure zsh. Do not use
bashcompinitor wrap a bash completion. - Discover goals from live
dokku --quiet help --all. - Dokku goals are flat colon-shaped tokens such as
apps:create, not space-separated subcommands. - Use
compaddfor colon-shaped goals;_describetreats colons as description separators. - Never hard-code app names, networks, service instances, domains, config keys, or another server resource inventory.
- Follow each live goal signature exactly. For example,
apps:listaccepts flags but no app positional, whileapps:destroyaccepts an app. - Once a goal is recognized, handled terminal/no-match states must not fall through to filenames or top-level goal completion.
- Only use safe, non-interactive lookup commands during completion.
- Preserve connection-isolated caches and validate cached candidates when loading them.
- Keep
zsh-dokku.plugin.zshlimited to loadingcompletions/throughfpath; registration belongs to the#compdef dokkucompletion file.
Do not embed the local harness's example, example-db, example-redis, or
host domain values in completions/_dokku.
Requirements:
- mise
- Docker or OrbStack
Bootstrap a fresh harness with the example app, Redis service, and Postgres service:
just bootstrap_local_dokkuThe canonical local context is:
| Variable | Default |
|---|---|
DOKKU_CONTAINER |
dokku-completion-harness |
DOKKU_DATA_ROOT |
<repo>/tmp/dokku-data |
DOKKU_HOST |
dokku-completion-harness.orb.local |
DOKKU_PORT |
22 |
When the project environment is not already activated, use:
mise exec -- dokku --quiet help --all
mise exec -- dokku plugin:list
mise exec -- dokku apps:listmise puts bin/dokku ahead of a system Dokku client. Confirm command
resolution before trusting output:
mise exec -- which dokkuThe expected path is this repository's bin/dokku.
Run the Docker-free suite after every completion change:
just testIt covers zsh parsing, compinit registration, goal and argument parsing,
flags and enums, contextual dispatch, no-match ownership, unconfigured-client
rejection, stale-cache fallback, connection isolation, and atomic refresh.
With the harness running, execute the read-only live suite:
just test_integrationIt first runs just test, then compares completion candidates with live apps,
Postgres and Redis services, networks, config keys, domains, flags, and enum
values.
Run the dynamic inventory test when changing resource caching or discovery:
just test_integration_dynamicThis runs both lower suites, creates one uniquely named temporary app, verifies that completion discovers it, removes it, and verifies that it disappears. An exit trap attempts to remove the temporary app if the test is interrupted.
Additional harness recipes:
| Recipe | Purpose |
|---|---|
just setup |
Write .env and stage the plugin list |
just up |
Pull/start Dokku and wait for health |
just bootstrap_local_dokku |
Reset and create the example resources |
just smoke |
Confirm core, Postgres, and Redis help goals |
just down |
Stop the harness while preserving state |
just clean |
Stop the harness and wipe runtime state |
- Read
generate-completion-prompt.md. - Start or verify the harness.
- Inspect the actual goal signature and safe query output before changing a parser.
- Update
completions/_dokku. - Add a hermetic regression assertion to
tests/completion_test.zsh. - Run
just test. - Run
just test_integrationfor live behavior. - Use
just test_integration_dynamiconly when mutable inventory behavior is relevant.
Keep temporary test resources uniquely named and clean them with an exit trap. Do not reset or wipe the harness merely to run completion tests.