Skip to main content

Projects

There are two ways to drive Kapi, and it's the same commands either way. What changes is whether Kapi remembers anything between runs.

Ad-hoc: one-off, nothing saved​

Run a tool or flow directly on the files you name. Nothing is kept after the run.

Translate this one file to French. · Check this folder for off-brand terms.

This is the quick path for a one-time job, a script, or a CI step. In the CLI you name the files with flags; in Kapi Desktop you pick them as quick tools.

Project: a recipe plus a memory​

A project is a small kapi.yaml recipe file (which files count as content, the voice, terms and coordinates that govern them, your flows and defaults, and, if you translate, your languages) plus a store that remembers your work: translations, terminology, and where each block stands in review, ready to reuse on the next run. Kapi finds the project automatically by walking up the folder tree, the way git finds its repo.

Translate this whole repo every release, reusing everything translated last time.

Ad-hocProject
Setupnonea kapi.yaml recipe (commit it)
Memorynothing saveda store accumulates work (content memory, terms, approvals)
Finds your filesyou name themdiscovered automatically
The main verbkapi <tool> <file>kapi up, bring the project up to date
Best forone-offs, scripts, CIa repo you work on repeatedly

Set one up: your first project. In a project, kapi up runs the default flow until every gated locale is shippable or waits for review, kapi status shows standing, and kapi check --ship enforces the gates; the model behind those verbs is the kapi loop.

The mechanics: source → flow → sink​

Kapi has one set of commands, and what changes between ad-hoc and project use is the binding: where content enters (the source) and where results go (the sink), resolved when you run.

sourcebindingchanrecyclechantranslatechanqachansinkbinding
BindingAs sourceAs sink
file (default)read + parse a filewrite the file back (round-trip via skeleton)
storethe project store (blocks + overlays)commit overlays, no file
interchangeimport XLIFF / PO / a bilingual .kpzemit one for a translator
nonen/adiscard (checks/analysis only)
  • Ad-hoc = the file binding: you name -i/-o.
  • In a project, the default sink is the store (a process-only run); an explicit -o forces a file instead.

A process-only run keeps only working output: the target overlays it produced, in .kapi/work/store.db, until you merge them. A review decision is kept elsewhere: kapi apply records it in the project's context store, and a flow's sink never writes decisions. kapi can rebuild the working output from your files. The decisions are what people authored. See the project store.

--explain prints the resolved binding without running:

kapi run translate-qa -i app.json -o app.fr.json --explain
# → flow translate-qa: file(app.json) → file(app.fr.json)
kapi run translate-qa -i app.json --explain # inside a project
# → flow translate-qa: file(app.json) → store

Two project loops, both ending at merge​

1. The kapi loop (the everyday one): kapi up runs the default flow over every locale short of its gate and materializes the translated files; what a machine can't finish waits for review.

2. Interchange loop (hand bilingual files to a translator or CAT tool):

kapi extractmemory pre-fillbilingual fileXLIFF / PO / .kpztranslate elsewherekapi merge+ memory absorbtranslated files
kapi extract --target-lang fr,de # → out/*.xliff (or --format kpz)
# …translate the bilingual files…
kapi merge -i out/ # apply back onto sources, absorb into memory

See the bilingual workflow for the interchange loop in depth.

The .kpz parcel: move work without a server​

A .kpz is a portable single file that carries work between machines or people without a server. It comes in two profiles:

# Whole-project snapshot: a runnable "project in a file"
kapi pack -o snapshot.kpz # recipe + content + memory & terms
kapi unpack snapshot.kpz # rehydrate elsewhere

# Bilingual interchange: for a kapi-equipped reviewer
kapi extract --format kpz --target-lang fr
kapi merge bundle.fr.kpz

Source travels as identity + a round-trip skeleton by default; --with-source embeds the raw originals. Pause & resume a big run walks the .kpz workspace lifecycle.

What a snapshot carries​

kapi info answers this for the project you are standing in (before you pack it) and for an archive you have been handed. Both list the same parts:

PartWhat it is
recipethe project's kapi.yaml, with the venue binding, hooks and automations stripped so they travel inert
sourcessource identity + per-file round-trip skeletons (raw bytes only with --with-source)
blocksthe extracted content blocks (.kbf.json)
overlayscommitted target overlays, one per locale
memorythe authoritative content memory (.memory.json)
termsthe authoritative terms (.terms.json)
historyan advisory provenance chain (--log)

A snapshot leaves out .kapi/work/cache/ (parse cache, extractions and collections, which kapi regenerates), credentials (they live in the OS keychain) and server sync tokens. It holds only state kapi cannot recompute, with no secrets and no derived data. A part with nothing in it is absent from the archive.

kapi info # this project: what a snapshot would capture
kapi info handoff.kpz # this archive: what it holds
kapi info --output-format json # either form, machine-readable

Each part reports whether it is present and how many items it holds, measured the way pack collects it. sources counts what the extraction manifests record, not what the recipe tracks, so a project that has never been extracted reports none. A part that is absent says what would produce it.

A workspace .kpz is the ad-hoc parcel with a shadow cache. kapi info work.kpz on one reports its documents, locales and whether the cache holds work not yet packed back into the file.

pack writes exactly the parts info lists and unpack restores exactly those parts: the content memory, the terms, the blocks and overlays, the skeletons, and, with --with-source, the raw source files, which unpack writes back into the tree without overwriting anything already there. To check the round trip, compare kapi info on a project with kapi info on its snapshot. pack refuses to write an archive with no content.

Do the modes mix?​

Yes: same commands, different bindings:

You want…Use
A throwaway job on one filead-hoc (kapi <tool> or run -i -o)
A repo you work on repeatedly (accumulating memory)project (add / up / merge)
To move work between machines/people.kpz parcel (pack or extract --format kpz)

A tool run inside a project (kapi translate src/app.json) still picks up the project's defaults and content memory while working on one file. The one thing to avoid: two stateful stores over the same content, an ad-hoc .kpz workspace and a kapi project for the same files. Inside a project, an explicit -o writes a file and skips the store on purpose; --explain shows which you got.

See also​