Gå til hovedinnhold

Work in a .klz workspace

A .klz is a single-file, serverless carrier — the portable equivalent of a .kapi project's working state. It is a parcel, not the place you normally work: the day-to-day working model is the ambient .kapi project. This recipe is the serverless convenience where there is no project — you open a .klz into a working cache, run tools against it, and pack it back. The bindings are the same ones any flow uses (AD-026):

StepBindingVerb
ingest sourcesfile → storekapi extract <sources> -o work.klz
transform (open → work, in place)store → storekapi <tool> work.klz · kapi run <flow> -i work.klz
emit finished filesstore → filekapi merge work.klz -o <dir>
eject — write the shareable .klzstore → .klzkapi pack work.klz · transform --pack
inspect — dirty?kapi info work.klz

The "in place" transform is the shadow cache (keyed by the .klz path) making open → work → pack cheap; conceptually you are still opening a parcel into a working copy, not editing inside the file.

kapi extract src/*.json -o work.klz --target-lang fr,qps # ingest
kapi ai-translate work.klz --target-lang fr # transform in place
kapi pseudo-translate work.klz --target-lang qps # …accumulates
kapi merge work.klz -o l10n/ # emit → l10n/<lang>/<name>

No project, no server — one portable file you can hand to another machine and pick up where it was left.

Try it

Walk the lifecycle as narrated commands, running live in your browser (WebAssembly) — extract → pseudo-translate → info → pack → merge:

Loading the walkthrough…

Inspect it

The lab below is the same workflow, interactive — pick a sample (including binary Word/Excel documents) and step through it, watching the workspace's recipe, per-locale overlays, and dirty → clean state update after each step.

Loading the interactive .klz workspace lab…

Extract — ingest sources

extract pulls the source documents into the workspace and records a small recipe so config travels with the file:

kapi extract src/**/*.json -o work.klz \
--target-lang fr,qps \
--out 'l10n/{lang}/{name}.{ext}'

The recipe holds the target locales and the output layout, so later steps need no flags. (extract also still emits bilingual XLIFF/PO for a .kapi project — the .klz form is the ad-hoc, no-project path.)

By default the .klz carries each source's identity + round-trip skeleton (enough to merge), not the raw bytes — so it stays small and doesn't duplicate git-tracked source. Add --with-source to embed the raw originals too, for a fully self-contained archive you can re-extract from offline.

Transform — run tools in place

Running a tool or flow on a .klz transforms the workspace: it appends the work (per-block overlays). It does not write output documents — that is merge's job. Transforms are repeatable and composable, and locales accumulate:

kapi ai-translate work.klz --target-lang fr
kapi pseudo-translate work.klz --target-lang qps
kapi run ai-translate-qa -i work.klz --target-lang fr

Re-running a transform reuses the work already done instead of recomputing it, so the expensive steps (AI, MT) don't run twice. Each document's work stays isolated.

The cache and the bundle

Transforms run against a fast, persistent working cache (under your cache dir, keyed to the .klz) — they do not rewrite the .klz on every command. The .klz is the stable, shareable bundle; the cache is your working clone. The .klz changes only when you explicitly eject:

kapi info work.klz # documents, locales, and whether the cache is dirty
kapi pack work.klz # eject the cache → work.klz (for sharing)

info reports dirty when the cache has work not yet packed. Add --pack to a transform to eject immediately:

kapi ai-translate work.klz --target-lang fr --pack # transform AND eject

Receive a packed .klz on another machine and the first command rebuilds the cache from the file automatically — nothing to set up.

Merge — emit the finished files

merge writes the localized documents, one per source × target locale. With no -o it uses the recipe's layout; otherwise -o <dir> (one file per source, under <lang>/ when there are several locales) or an -o template:

kapi merge work.klz # → recipe's layout
kapi merge work.klz -o l10n/ # → l10n/<lang>/<name>
kapi merge work.klz -o '{dir}/{name}.{lang}.{ext}'

Merge replays the stored translations onto the source and writes — it never re-runs a tool or calls a provider.

Why these verbs

extract / merge are kapi's existing localization round-trip: pull translatable content out, put the finished content back. A .klz is just another working form of that round-trip — alongside bilingual XLIFF/PO — except the translation happens in the workspace with kapi's tools rather than in an external editor. Progress is derived from the content itself (the overlays present), never a separate status file, so resuming is correct, idempotent, and crash-safe by construction.

Compare: a .kapi project

The same engine powers a .kapi project — the multi-file, team/server form. A project keeps its config in a committed .kapi recipe (declared content, flows, target languages) and its working state in a .kapi/ directory (the persistent cache, TM, and termbase). Run a declared flow against it below — and contrast it with the single-file .klz workspace above: same content, same output, different packaging.

Loading the interactive .kapi project lab…
.kapi project.klz workspace
shaperecipe file + .kapi/ state dirsingle portable file
configcommitted recipe (content, flows, locales)recipe carried in the file
best forteams, servers, version controlad-hoc, single-file hand-off
statepersistent project cacheshadow cache, ejected on pack

See also