Understanding the CLI layers
Most users run kapi up and stop: it catches the whole project up to its
ship gates, and the porcelain verbs around it (status, check, apply,
translate) cover the daily work. Underneath them are the layers those verbs
are made of, which you can run one piece at a time.
At the bottom is a registry
of tools: translate, recycle, qa, term-check, redact, and the rest (list
them with kapi tools list; the tool reference documents each). A
flow composes tools into a named pipeline. The porcelain verbs are
workflows over those two layers: kapi translate wraps recycle → translate →
checks, and kapi up loops a flow until the project's gates are met.
Each layer composes the one below: a flow is an ordered list of tools; kapi up is a flow in a loop with coverage, checks, and gates around it.
exec: one tool, one pass
kapi exec <tool> executes a single registry tool on the files you name: one
tool, one pass, no guardrails around it. These are the same tools a flow runs:
exec translate is a bare AI translate with no content-memory pass before it and no checks
after it; exec term-check runs just the terminology check; exec recycle
runs just the content-memory leverage. Discover a tool's options with
kapi tools schema <name>.
kapi exec translate app.json --target-lang fr # bare translate, no memory, no checks
kapi exec term-check locales/en.json --target locales/fr.json --target-lang fr
kapi exec recycle app.json --target-lang fr # content-memory leverage only
A check that compares a block's source with its translation reads both. A
file that holds both, such as XLIFF, needs nothing more. When the translation
is a file of its own, name the source file and pass the translation with
--target. The run reads the two files as one set of blocks, prints its
findings, and writes no file:
$ kapi exec qa docs/contacts.md --target docs/nb/contacts.md --target-lang nb
outcome rule location message
REPORTS qa.doubled-word docs/contacts.md:contacts/p#2 Target contains doubled word: "på"
0 failing, 1 reported · score 99/100
Run on docs/contacts.md alone, qa finds no nb translation to compare
with. kapi reports that the check did not run, names --target, and exits with
code 4, as kapi check does when it checks no content. qa writes a file only
where -o or --output-dir names one.
review pairs a translation file the same way. It asks a provider to review
each block's translation, prints what the provider found, and changes neither
file:
$ kapi exec review docs/contacts.md --target docs/nb/contacts.md --target-lang nb --provider demo
demo mode: illustrative output from a built-in stub rather than a real language model.
outcome rule location message
REPORTS review.review docs/contacts.md:contacts/p ⟦demo⟧ illustrative stub response (no real language model)
REPORTS review.review docs/contacts.md:h ⟦demo⟧ illustrative stub response (no real language model)
0 failing, 2 reported · score 98/100
The demo provider answers each block in prose, so each block carries one
finding that holds the answer. A provider that answers with the review's
findings reports one row per finding, and counts a critical or major one as
failing. When it runs without --target on a file that holds no nb translation,
review reports that it did not run and exits with code 4, as qa does.
Reach for exec when you want exactly one tool's behavior: isolating a step
while debugging a flow, or a one-off check on a file. See the
exec reference.
In a project that declares a redaction policy,
exec puts redact before a tool that calls a model and unredact after it.
Each file is redacted under the policy that covers it: its collection's or
content item's redaction:, else defaults.redaction.
The model reads placeholders in every block, in each translation beside it,
and in everything the tool sends with them: term rules, the voice profile,
the content memory's previous version and the instruction. The output carries
the original values. A policy that detects entities
stops the run; run the tool in a flow with entity-extract ahead of redact
instead.
run: compose tools into a flow
kapi run <flow> runs a named flow (an ordered
composition of tools) for one pass. Built-in flows cover the common
compositions (translate, translate-qa, secure-translate; kapi flows
lists what your build ships), and a project recipe defines its own under
flows:.
kapi run translate-qa -i app.xliff --target-lang fr # translate, then LLM-judged review
kapi run secure-translate -i notes.md --target-lang de # redact → translate → unredact
kapi run pseudo -p kapi.yaml # a project-defined flow
A flow the recipe defines runs over the project's files, so given a .kpz package it stops: kapi exec <tool> work.kpz runs one tool on the package, and kapi merge work.kpz brings it into the project first.
A flow is also what kapi up loops: defaults.flow names the project's
default, and without one up runs the built-in default: content-memory reuse
(recycle) followed by AI translate. run executes the composition once and stops;
it re-derives no coverage and consults no gates. See the
run reference.
extract / merge: the translator hand-off
Not every pass is a tool run. When a person does the translation, kapi extract emits one bilingual file per source → target pair (XLIFF 2.x or PO
for a third-party CAT tool, a lossless .kpz for a recipient working in kapi),
pre-filled from the project's content memory. kapi merge applies the returned
file back onto the project, restoring the original formats through the skeleton
captured at extract time and absorbing the corrections into memory.
kapi extract --target-lang fr # → out/<name>.en-to-fr.xliff, memory pre-filled
kapi merge -i out/app.en-to-fr.xliff
Extract and merge sit at the same layer as run: they move work through an
external pass instead of a tool pass, and the result lands in the same project
state the porcelain re-derives. The workflow (carriers, memory provenance,
vendor rounds) is covered in Hand off to translators;
the flags are in the extract and
merge references.
What kapi up adds
Seen from this layer, kapi up is run the default flow, in a loop, with the
project machinery around it. Each pass:
- re-derives coverage from the working tree (re-extracting when source files changed),
- runs the flow for the locales still short of their gate: the same
composition
runwould execute once, - runs the bound checks over what was produced, so a locale with a failing finding does not clear its gate,
- evaluates the gates and either loops, stops when the project is up to date, or holds back for review what needs a person.
run and exec skip the coverage derivation, the checks and the gates. The full
model is the kapi loop.
When to reach for each
| You want | Reach for |
|---|---|
| The daily catch-up: everything toward the gates | kapi up |
| One guardrailed translation pass over named files | kapi translate |
| A specific composition, one pass, no gate loop | kapi run <flow> |
| Exactly one tool's behavior, nothing around it | kapi exec <tool> |
| A person translates: hand the work out and take it back | kapi extract / kapi merge |
See also
- The kapi loop: the model behind
up,status, and the gates. - Flows: how a flow is authored and executed.
- Hand off to translators: the bilingual interchange workflow.
exec,run,extract,merge: command reference.