# Developing How to add a command to luish-extra, step by step. The reference for the conventions (what each module holds, the quirks of Rhai met so far, how caching and releases work) is [`CLAUDE.md`](https://github.com/luispedro/luish-extra/blob/main/CLAUDE.md). This page is the path through it. ## Setting up You need: - luish 0.7 or later, in `PATH` or given as `LUISH`; - a checkout of [luish](https://github.com/luispedro/luish) next to this one (`../luish`), for std's plugins, whose completion engine the plugins use (`STD_PLUGINS`, by default `../luish/luish-std-plugins`); - Python 3.11 or later, for the scripts; - [pixi](https://pixi.sh/), for the scripts that run a tool: `pixi exec` runs it in a temporary environment, with Bioconda and conda-forge, so nothing is installed. Then run the tests: ```sh tests/run.sh # every case tests/run.sh bio_align gui_media # some cases, by name without .sh ``` ## How a plugin is laid out Each completion plugin (`completion/bio`, `completion/science`, ...) has: - `plugin.toml`, which says which luish it needs (`luish-version = "0.7"`) and what it depends on (`std.completion`, and `extra-lib`, the helpers that the plugins share); - `extension.rhai`, which registers a completer for each command. Its `module_of` map gives the module of each command. A module is imported only on the first Tab for one of its commands, so a shell start costs nothing per module; - modules of specs, one per family of tools (`align.rhai`, `blast.rhai`, ...), each with `fn spec(cmd)`; - `kinds.rhai`, with `fn kind(name, cur, words)`: what an argument or the value of an option completes to (FASTA files, the reference names of a BAM, the rules of a Snakefile). A spec is a map (`opts`, `values`, `args`, `commands`, `subs`, ...) that std's completion engine completes from. luish documents its fields and the format of the option tables in [Reusing std's completion engine](https://luish-shell.xyz/extensions.html#reusing-std-s-completion-engine). `completion/system/tools.rhai` is a short example of a module. `media` (ffmpeg) and `hpc` (Slurm) have a completer of their own rather than specs, and so do a few commands elsewhere (`nextflow`, `mpv`, `code`, `xdotool`, `git-annex`). Start from a spec unless the line itself decides what an option means. ## Adding a tool The [commit that added pyrodigal](https://github.com/luispedro/luish-extra/commit/af48d70) is a complete example. It touched the generator, the generated module, `extension.rhai`, a test, `completion-todo.md`, the README, the ChangeLog and `CLAUDE.md`. ### 1. Check that it is on the list, and how it should be completed [](completion.md) is the list of commands to complete, and `completion-todo.md` has a box for each. A command goes on the list in `docs/completion.md` first. Completion is by command name, not by package name: `STAR`, not `star`; `featureCounts`, not `subread`. Install the package, or look at its recipe, to see which executables it brings. Before writing a spec, check whether one is needed: - std's `completion` plugin may already complete the command (`fd`, `rg`, `uv`, `docker`, ...). Then it isn't repeated here. - A Python program built with Click completes itself. `scripts/clickcheck.sh PACKAGE PROG [WORD]...` checks that it answers std's Click bridge and times it. A program that answers in under a second is one name in a list of `extension.rhai`; a slower one is left to the user (`complete-click PROG`). Read the output: not every program with `click` among its dependencies is a Click program. - A Go program built with Cobra completes itself too: `PROG __complete ''` answers with its subcommands. It is registered with std's Cobra bridge, also in `extension.rhai`. ### 2. Choose the module A tool goes in the module of its family (`reads.rhai` for read QC and trimming, `profile.rhai` for taxonomic profilers, ...). `CLAUDE.md` says what each module holds. A new module needs `fn own(name)` and `fn spec(cmd)`, as the others have, and an entry in `module_of`. Some modules are **generated**: `CLAUDE.md` lists them. In one of those, the spec is added to the generator (`scripts/gen/mk_MODULE.py`), which is then rerun. An edit to the `.rhai` itself would be undone by the next run. ### 3. Write the spec from the tool's own help Option tables are written from the real `--help` of a pinned version, never from memory or from the manual of another version: ```sh pixi exec -c conda-forge -c bioconda -s pyrodigal=3.7.1 -- pyrodigal --help