Šķîþ ţö ḿàîñ çöñţéñţ

Šçŕîþţîñĝ & ĴŠÖÑ çöñţŕàçţ

ķàþî'š çöŕé ṽéŕƃš ƒöļļöŵ à đöçüḿéñţéđ, ĝöļđéñ-ţéšţéđ ḿàçĥîñé çöñţŕàçţ, šö šçŕîþţš, ÇÎ þîþéļîñéš àñđ çàļļéŕš îñ öţĥéŕ ļàñĝüàĝéš ñéṽéŕ þàŕšé þŕöšé. Ţĥé šéçţîöñš ƃéļöŵ ĝîṽé ţĥé öüţþüţ ƒļàĝš, ţĥé šţŕüçţüŕéđ ŕéšüļţš öƒ run, extract, àñđ merge, ţĥé ĴŠÖÑ éŕŕöŕ éñṽéļöþé, éẋîţ çöđéš, àñđ šţŕéàḿîñĝ þŕöĝŕéšš éṽéñţš. Àñ àþþļîçàţîöñ ţĥàţ đŕîṽéš ķàþî îñšţéàđ öƒ à þéŕšöñ àţ à ţéŕḿîñàļ üšéš öñé öƒ ţĥé çĥàññéļš îñ Đŕîṽîñĝ ķàþî ƒŕöḿ àñ àþþļîçàţîöñ; ƒöŕ ţĥé ÀÎ-àĝéñţ šüŕƒàçé, šéé ţĥé ḾÇÞ šéŕṽéŕ.

Çöḿþàţîƃîļîţý: ţĥé ĴŠÖÑ đöçüḿéñţš ƃéļöŵ àŕé à šţàƃļé çöñţŕàçţ. Ƒîéļđš ḿàý ƃé àđđéđ îñ à ŕéļéàšé; éẋîšţîñĝ ƒîéļđ ñàḿéš àñđ ţýþéš đö ñöţ çĥàñĝé. Ţĥé šĥàþéš àŕé ļöçķéđ ƃý ĝöļđéñ ţéšţš (cli/contract_golden_test.go).

Öñé éẋçéþţîöñ îš ḿàđé ƃéƒöŕé 1.3: ţĥé çöñţéñţ-ḿéḿöŕý çöüñţš îñ ţĥé kapi merge ŕéšüļţ àŕé ñàḿéđ memory_new àñđ memory_updated, àñđ ţĥé éẋàçţ-ḿàţçĥ çöüñţ îñ ţĥé kapi up --plan ŕéšüļţ îš ñàḿéđ memoryExact. Ŕéļéàšéš ƃéƒöŕé 1.3 ŵŕöţé ţĥéḿ àš tm_new, tm_updated àñđ tmExact, àñđ à šçŕîþţ ŕéàđîñĝ ţĥöšé ñàḿéš ñééđš üþđàţîñĝ.

Ĥüḿàñ-ŕéàđàƃļé ţéẋţ öüţþüţ îš ñöţ à çöñţŕàçţ. Îţ îš þŕéšéñţàţîöñ: çöļüḿñ ŵîđţĥš àđàþţ ţö ýöüŕ ţéŕḿîñàļ, ṽàļüéš àŕé ţŕüñçàţéđ ţö ƒîţ, àñđ îţ çàŕŕîéš ÀÑŠÎ šţýļîñĝ ŵĥéñ šţđöüţ îš à ŢŢÝ. Îţ îš ŕéšţýļéđ ŵĥéñéṽéŕ ţĥé ÇĻÎ'š þŕéšéñţàţîöñ îḿþŕöṽéš. Šçŕîþţš ḿüšţ üšé --json (öŕ --jq), ŵĥîçĥ îš šţàƃļé, üñšţýļéđ, àñđ ñéṽéŕ ţŕüñçàţéđ.

Öüţþüţ ƒļàĝš​

Éṽéŕý çöḿḿàñđ àççéþţš ţĥé þéŕšîšţéñţ öüţþüţ ƒļàĝš:

ƑļàĝɃƒéçţ
--jsonḾàçĥîñé-ŕéàđàƃļé ĴŠÖÑ öñ šţđöüţ
--textĤüḿàñ ţéẋţ (ţĥé đéƒàüļţ)
--output-format <json|text>Éẋþļîçîţ ƒöŕḿàţ šéļéçţîöñ
--jq <expr>Ƒîļţéŕ ĴŠÖÑ öüţþüţ ţĥŕöüĝĥ à ĵǫ éẋþŕéššîöñ (îḿþļîéš --json)
--color <auto|always|never>Çöļöŕîžé öüţþüţ. auto çöļöŕîžéš öñļý ŵĥéñ šţđöüţ îš à ţéŕḿîñàļ

Þŕéçéđéñçé: --jq > --json > --text > --output-format.

Çöļöŕ​

Çöļöŕ îš öƒƒ ŵĥéñéṽéŕ šţđöüţ îš ñöţ à ţéŕḿîñàļ, šö þîþîñĝ öŕ ŕéđîŕéçţîñĝ àļŵàýš ýîéļđš þļàîñ ţéẋţ, ŵîţĥ ñö ÀÑŠÎ šţŕîþþîñĝ ŕéǫüîŕéđ. NO_COLOR đîšàƃļéš çöļöŕ àñđ CLICOLOR_FORCE ƒöŕçéš îţ, ƃöţĥ öṽéŕŕîđđéñ ƃý àñ éẋþļîçîţ --color.

ķàþî ĥàš öñé þàļéţţé àñđ ñö ļîĝĥţ öŕ đàŕķ šéţţîñĝ. Éṽéŕý çöļöŕ îñ îţ çļéàŕš ţĥé ŴÇÀĜ çöñţŕàšţ ƃàŕ ƒöŕ ÜÎ ţéẋţ öñ àñý ţéŕḿîñàļ ƃàçķĝŕöüñđ: ŵĥîţé, ƃļàçķ, Šöļàŕîžéđ, Öñé Đàŕķ, Đŕàçüļà àļîķé.

Ţĥàţ àļšö ḿéàñš ķàþî ñéṽéŕ ǫüéŕîéš ţĥé ţéŕḿîñàļ ƒöŕ îţš ƃàçķĝŕöüñđ çöļöŕ. Ţéŕḿîñàļš àñšŵéŕ šüçĥ à ǫüéŕý öñ šţđîñ, ŵĥîçĥ ķàþî'š öŵñ çöḿḿàñđš ŕéàđ (kcat -), àñđ à ţéŕḿîñàļ ţĥàţ đöéš ñöţ àñšŵéŕ ļéàṽéš ţĥé ŕàŵ éšçàþé šéǫüéñçé îñ ţĥé öüţþüţ, çöŕŕüþţîñĝ þîþéđ öüţþüţ, ÇÎ ļöĝš, àñđ ŕéçöŕđéđ šéššîöñš.

Ŕéšüļţ đöçüḿéñţš​

Ŵîţĥ --json, ţĥé çöŕé ṽéŕƃš þŕîñţ öñé ĴŠÖÑ đöçüḿéñţ öñ šţđöüţ ŵĥéñ ţĥéý ƒîñîšĥ. Ŵîţĥöüţ îţ, ţĥéý þŕîñţ à ĥüḿàñ ŕéþöŕţ, ŵĥîçĥ îš þŕéšéñţàţîöñ àñđ çàŕŕîéš ñö çöñţŕàçţ (šéé àƃöṽé).

kapi run​

À šîñĝļé-ƒîļé ŕüñ ŕéþöŕţš ţĥé ƒļöŵ àñđ ţĥé þàţĥš îñṽöļṽéđ; à ƃàţçĥ ŕüñ ŕéþöŕţš ţĥé ƒîļé çöüñţ. Àñ îñ-þŕöĵéçţ ŕüñ ŵîţĥ ñö -o îš þŕöçéšš-öñļý (þŕöĵéçţš): îţ çöḿḿîţš ţàŕĝéţ öṽéŕļàýš ţö ţĥé þŕöĵéçţ šţöŕé îñšţéàđ öƒ ŵŕîţîñĝ à ƒîļé, àñđ ŕéþöŕţš process_only.

{
"flow_name": "pseudo-translate",
"input_path": "src/messages.json",
"output_path": "src/messages_qps.json"
}
{
"flow_name": "translate",
"input_path": "src/messages.json",
"process_only": true
}

kapi extract​

Öñé đöçüḿéñţ þéŕ ƃàţçĥ: îđéñţîţý (batch_id, manifest), ţĥé éẋţŕàçţîöñ îñþüţš (format, targets, sources), öñé éñţŕý þéŕ ţàŕĝéţ-ļöçàļé þàšš üñđéŕ pairs (ƒîļé/ƃļöçķ çöüñţš àñđ çöñţéñţ-ḿéḿöŕý ļéṽéŕàĝé), ţĥé àĝĝŕéĝàţé leverage, îñçŕéḿéñţàļ reused çöüñţ, àñđ failures ŵĥéñ šöüŕçé/ţàŕĝéţ þàîŕš ƒàîļéđ (đéţàîļš šţŕéàḿ ţö šţđéŕŕ àš ţĥéý ĥàþþéñ).

{
"batch_id": "0b6be731-3a5c-4a02-9e04-2f79e4c2d1aa",
"format": "xliff2",
"targets": ["fr", "de"],
"sources": 2,
"manifest": ".kapi/work/cache/extractions/0b6be731/manifest.yaml",
"pairs": [
{
"target_locale": "fr",
"files": 2,
"blocks": 10,
"leverage": { "exact": 4, "fuzzy": 1, "new": 5 }
}
],
"leverage": { "exact": 4, "fuzzy": 1, "new": 15 }
}

kapi merge​

Àþþļýîñĝ ŕéţüŕñéđ ƃîļîñĝüàļ ƒîļéš (merge -i) ŕéþöŕţš öñé éñţŕý þéŕ îñþüţ þļüš ţöţàļš àñđ ţĥé ŕéšöļṽéđ çöñƒļîçţ þöļîçý; à ƒàîļéđ îñþüţ çàŕŕîéš àñ error îñšţéàđ öƒ çöüñţš. Éàçĥ ƃļöçķ çöüñţš öñçé: applied (îţ ļàñđéđ, öŕ àļŕéàđý šàîđ ţĥàţ), stale (îţš šöüŕçé çĥàñĝéđ šîñçé ţĥé éẋţŕàçţîöñ, ţĥé šöüŕçé îţ çàŕŕîéš îš ñöţ îţš ƃļöçķ'š, öŕ îţš ƃļöçķ îš ĝöñé), skipped (éḿþţý, öŕ à ţŕàñšļàţîöñ ţĥé þŕöĵéçţ çĥàñĝéđ ḿéàñŵĥîļé ţĥàţ ţĥé çöñƒļîçţ þöļîçý ķéþţ), àñđ refused (ţĥé çĥàñĝé šéŕṽîçé ŕéƒüšéđ îţ, šüçĥ àš à ţàŕĝéţ ţĥàţ đŕöþš àñ îñļîñé çöđé îţš šöüŕçé þŕöţéçţš öŕ öñé ţĥàţ ƃŕéàķš à ŕüļé ĝöṽéŕñîñĝ îţ; ţĥé ƒîéļđ îš þŕéšéñţ ŵĥéñ ñöñ-žéŕö, àñđ ţĥé ŕéàšöñ ĝöéš ţö šţđéŕŕ). Àñ îñþüţ öƒ ŵĥîçĥ ñöţĥîñĝ ļàñđš ƃéçàüšé éṽéŕý ƃļöçķ ŵàš ŕéƒüšéđ ƒàîļš.

{
"files": [
{
"input": "out/app.en-to-fr.xliff",
"applied": 8,
"stale": 1,
"skipped": 0,
"memory_new": 6,
"memory_updated": 2
}
],
"applied": 8,
"stale": 1,
"skipped": 0,
"memory_new": 6,
"memory_updated": 2,
"conflict_policy": "translator-wins"
}

Ḿàţéŕîàļîžîñĝ ƒŕöḿ ţĥé þŕöĵéçţ šţöŕé (kapi merge ŵîţĥ ñö -i îñ à þŕöĵéçţ) ŵŕîţéš éàçĥ ţŕàñšļàţîöñ ƒŕöḿ ţĥé đŕàƒţš ţĥé ŵöŕķšþàçé ķééþš ƒöŕ îţ, öŕ éļšé ƒŕöḿ ţĥé ţàŕĝéţš ţĥé ƃļöçķ šţöŕé ĥöļđš, àñđ ŕéþöŕţš ţĥé çöüñţ öƒ ţŕàñšļàţîöñ ƒîļéš îţ ŵŕöţé: à ƒîļé à ķéþţ đŕàƒţ öŕ à šţöŕéđ ţàŕĝéţ çĥàñĝéđ, öŕ à đöçüḿéñţ ŵĥöšé šöüŕçé ĝàîñéđ öŕ ļöšţ à ƃļöçķ šîñçé îţ ŵàš ŵŕîţţéñ. À ţŕàñšļàţîöñ ţĥàţ àļŕéàđý šàýš ŵĥàţ ţĥé šţöŕé ĥöļđš, öñé ţĥé šţöŕé ĥöļđš ñöţĥîñĝ ƒöŕ, àñđ à šöüŕçé-öñļý çöļļéçţîöñ çöüñţ ñöñé:

{ "written": 4, "from_project_store": true }

À šţöŕéđ ţàŕĝéţ ḿàđé ƒŕöḿ à šöüŕçé ţĥé ƃļöçķ ñö ļöñĝéŕ ĥöļđš îš ñöţ ŵŕîţţéñ. stale çöüñţš ţĥöšé ƃļöçķš, àñđ îţ àþþéàŕš ŵĥéñ ţĥé çöüñţ îš àƃöṽé žéŕö:

{ "written": 4, "stale": 1, "from_project_store": true }

À šţöŕéđ ţàŕĝéţ àñ éàŕļîéŕ ķàþî ŵŕöţé ñàḿéš ñö šöüŕçé, šö îţ îš ñöţ ŵŕîţţéñ éîţĥéŕ. stale çöüñţš îţ, àñđ unstamped ñàḿéš éàçĥ ƒîļé àñđ ļöçàļé ţĥàţ ĥöļđš öñé, ŵîţĥ ţĥé ñüḿƃéŕ öƒ ƃļöçķš. À ţŕàñšļàţîñĝ þàšš đŕàƒţš ţĥöšé ƃļöçķš àĝàîñ:

{
"written": 4,
"stale": 1,
"unstamped": [{ "file": "src/en.json", "locale": "fr", "blocks": 1 }],
"from_project_store": true
}

kapi up --json çàŕŕîéš ţĥé šàḿé ļîšţ þéŕ ļöçàļé, àš unstampedDrafts ƃéšîđé staleDrafts.

Éŕŕöŕ éñṽéļöþé​

Üñđéŕ --json (öŕ --jq / --output-format=json), à ƒàîļîñĝ çöḿḿàñđ þŕîñţš à šţŕüçţüŕéđ éñṽéļöþé öñ šţđéŕŕ îñšţéàđ öƒ ţĥé þļàîñ Error: ļîñé:

{ "error": "quality gate failed", "code": "gate" }

code îš ţĥé šýḿƃöļîç ƒöŕḿ öƒ ţĥé þŕöçéšš éẋîţ çöđé (ƃéļöŵ). Éẋîţ çöđéš àŕé üñçĥàñĝéđ ƃý --json; îñ ţéẋţ ḿöđé ţĥé éŕŕöŕ îš šţîļļ ŕéþöŕţéđ àš àñ Error: <message> ļîñé.

Éẋîţ çöđéš​

ÇöđéŠýḿƃöļḾéàñîñĝ
0(ñöñé)Šüççéšš
1errorÖþéŕàţîöñàļ éŕŕöŕ
2usageÜšàĝé / îñṽöçàţîöñ éŕŕöŕ (àļšö ĝŕéþ-šţýļé "ţŕöüƃļé" ƒöŕ ţĥé ţööļƃöẋ üţîļîţîéš)
3gateÀ çĥéçķ ƒàîļéđ: àţ ļéàšţ öñé ƒîñđîñĝ ƒàîļš (kapi check, kapi check --ship, kapi voice check), đîšţîñçţ ƒŕöḿ àñ öþéŕàţîöñàļ éŕŕöŕ šö ÇÎ çàñ ţéļļ "ţĥé çöñţéñţ îšñ'ţ ĝööđ éñöüĝĥ" ƒŕöḿ "ţĥé ţööļ ƃŕöķé". kapi exec external-command, àñđ kapi up öṽéŕ à ƒļöŵ ţĥàţ ŕüñš îţ, éẋîţ 3 ţöö üñđéŕ à ŕéđàçţîöñ þöļîçý ŵĥéñ ţĥé þŕöĝŕàḿ'š öüţþüţ đŕöþš, àļţéŕš, ŕéþéàţš öŕ àđđš à ŕéđàçţîöñ þļàçéĥöļđéŕ; éàçĥ šüçĥ ƃļöçķ ķééþš îţš çöñţéñţ àñđ ţĥé ŕéþöŕţ ñàḿéš îţ üñđéŕ external-command.redaction-placeholder
4did_not_runkapi check ŕéàçĥéđ ñö ṽéŕđîçţ: îţ çĥéçķéđ ñö çöñţéñţ, öŕ öñé öƒ îţš çĥéçķš ŕéþöŕţéđ ñöţĥîñĝ öñ ţĥé ķñöŵñ-ƃàđ šàḿþļé îţ ŕüñš ƃéšîđé ţĥé çöñţéñţ. kapi exec <check> éẋîţš 4 ţöö ŵĥéñ ţĥé ţööļ çöḿþàŕéš à šöüŕçé ŵîţĥ îţš ţŕàñšļàţîöñ àñđ ñö ƃļöçķ îţ ŕéàđ ĥéļđ öñé; ţĥé ŕéþöŕţ ñàḿéš --target. Ñéṽéŕ à þàšš
130signalÎñţéŕŕüþţéđ (ŠÎĜÎÑŢ/ŠÎĜŢÉŔḾ); ñö éŕŕöŕ ļîñé îš þŕîñţéđ

Ţĥé ţööļƃöẋ üţîļîţîéš (kgrep) àđđîţîöñàļļý üšé ĝŕéþ-þàŕîţý šéḿàñţîçš: éẋîţ 1 ŵîţĥ ñö ḿéššàĝé ŵĥéñ ñöţĥîñĝ ḿàţçĥéđ.

Šţŕéàḿîñĝ þŕöĝŕéšš: --progress jsonl​

run, extract, àñđ merge àççéþţ --progress jsonl, ŵĥîçĥ šţŕéàḿš þŕöĝŕéšš éṽéñţš ţö šţđéŕŕ àš ÑĐĴŠÖÑ (öñé ĴŠÖÑ öƃĵéçţ þéŕ ļîñé) ŵĥîļé šţđöüţ šţàýš ŕéšéŕṽéđ ƒöŕ ţĥé ƒîñàļ ŕéšüļţ. Ţĥé éṽéñţš üšé ţĥé ƒļöŵ-ŕüñ éṽéñţ ṽöçàƃüļàŕý (ţĥé šàḿé šĥàþéš ţĥé Ķàþî Đéšķţöþ ŕüñ šîñķ ŕéçéîṽéš), ŵîţĥ flow ñàḿîñĝ ţĥé ṽéŕƃ öŕ ƒļöŵ:

typeḾéàñîñĝĶéý ƒîéļđš
stateŔüñ-šţàţé ţŕàñšîţîöñmessage
progressÀƃöüţ ţö þŕöçéšš öñé ƒîļé (öŕ šöüŕçé→ļöçàļé þàîŕ)file_index, file_count, file_path, locale
file_doneÖñé ƒîļé (öŕ šöüŕçé→ļöçàļé þàîŕ) çöḿþļéţéđfile_path, output_path, locale
pipeline_metricsÞéŕ-šţéþ ţĥŕöüĝĥþüţ šñàþšĥöţ (ḿüļţî-ļöçàļé þŕöĵéçţ ŕüñš)steps
completeŔüñ ƒîñîšĥéđduration_ms, files_processed, message
kapi extract -p kapi.yaml --progress jsonl 2> >(jq -c 'select(.type=="file_done")')
{"type":"progress","flow":"extract","locale":"fr","file_count":4,"file_path":"src/messages.json"}
{"type":"file_done","flow":"extract","locale":"fr","file_path":"src/messages.json","output_path":"out/src-messages.en-to-fr.xliff"}
{"type":"complete","flow":"extract","duration_ms":420,"files_processed":4}

Šţŕéàḿ îñţéĝŕîţý: à ţŕüñçàţéđ ÑĐĴŠÖÑ šţŕéàḿ îš ñéṽéŕ šîļéñţ​

Éṽéŕý ÑĐĴŠÖÑ šţŕéàḿ ķàþî ŵŕîţéš (kapi up --json, --progress jsonl) îš à çöñţŕàçţ ŵîţĥ à ḿàçĥîñé ŕéàđéŕ, šö à šţŕéàḿ ţĥàţ šţöþš éàŕļý ḿüšţ ñöţ ļööķ ļîķé öñé ţĥàţ ƒîñîšĥéđ. Ţĥé ţŵö ŵàýš à ŵŕîţé çàñ ƒàîļ àŕé ţŕéàţéđ đéŕéñţļý, ƃéçàüšé ţĥéý ḿéàñ öþþöšîţé ţĥîñĝš:

Ŵĥàţ ĥàþþéñéđķàþî'š ƃéĥàṽîöüŕ
Ýöü šţöþþéđ ŕéàđîñĝ: kapi up --json | head, à jq ƒîļţéŕ ţĥàţ éẋîţš, à ŵàţçĥîñĝ ÜÎ ţĥàţ đîšçöññéçţšŢĥé šţŕéàḿ šţöþš, ǫüîéţļý, àñđ ţĥé ŕüñ îš ñöţ ƒàîļéđ. Ƒàîļîñĝ à ŕüñ ƃéçàüšé îţš ŕéàđéŕ ŵàļķéđ àŵàý ŵöüļđ ƃé ŵöŕšé ţĥàñ ţĥé šîļéñçé. Öñ à šĥéļļ þîþé ţĥé þŕöçéšš îš ñöŕḿàļļý ţéŕḿîñàţéđ ƃý SIGPIPE ƃéƒöŕé ţĥé ŵŕîţé éṽéñ ŕéţüŕñš, ĝîṽîñĝ ţĥé çöñṽéñţîöñàļ 141 éẋîţ; éîţĥéŕ ŵàý ñöţĥîñĝ îš þŕîñţéđ.
Ţĥé ŵŕîţé ƒàîļéđ: à ƒüļļ đîšķ, à çļöšéđ ƒîļé, àñ üñŵŕîţàƃļé đéšţîñàţîöñÖñé ḿéššàĝé öñ šţđéŕŕ (öŕ ţĥé ĴŠÖÑ éŕŕöŕ éñṽéļöþé) ñàḿîñĝ ţĥé šţŕéàḿ àñđ çöüñţîñĝ ŵĥàţ ĝöţ ţĥŕöüĝĥ, àñđ à ñöñ-žéŕö éẋîţ. À çöñšüḿéŕ ḿüšţ ñéṽéŕ ƃéļîéṽé à ţŕüñçàţéđ šţŕéàḿ.
$ kapi up --json > /mnt/full/out.ndjson
Error: kapi up --json: the event stream truncated: 6 record(s) written, 12 lost: write /dev/stdout: no space left on device
$ echo $?
1

Ţĥé đîšţîñçţîöñ îš đŕàŵñ šţŕüçţüŕàļļý (errors.Is àĝàîñšţ syscall.EPIPE àñđ io.ErrClosedPipe, þļüš ţĥé Ŵîñđöŵš ƃŕöķéñ-þîþé éŕŕñöš), ñéṽéŕ ƃý ḿàţçĥîñĝ ţĥé ḿéššàĝé ţéẋţ. Üñđéŕ --progress jsonl ţĥé éẋîţ çöđé îš ţĥé šîĝñàļ ţö ŕéàđ: ŵĥéñ ţĥé ƒàîļîñĝ ŵŕîţéŕ îš šţđéŕŕ, ţĥé ḿéššàĝé ĥàš ñöŵĥéŕé ţö ļàñđ.

Šţŕéàḿîñĝ îñšþéçţîöñ: kapi inspect --jsonl​

Ƒöŕ šţŕéàḿîñĝ ƃļöçķ çöñţéñţ, kapi inspect --jsonl éḿîţš öñé ĴŠÖÑ öƃĵéçţ þéŕ ƃļöçķ, ŵîţĥöüţ ĤŢḾĻ éšçàþîñĝ, šö <x id="…"/> þļàçéĥöļđéŕš ŕéàđ àš ŵŕîţţéñ. Éàçĥ ŕéçöŕđ îš ţĥé ŕéàđ ŕéçöŕđ öƒ ţĥé çĥàñĝé çöñţŕàçţ: ref (doc, block, àñđ edition ƒöŕ à ţŕàñšļàţîöñ), rev, text, codes, structures, editions àñđ ops, ŵîţĥ ţĥé ƃļöçķ'š role àñđ level; ŕüñ kapi inspect --help ƒöŕ éàçĥ ƒîéļđ. Îñšîđé à þŕöĵéçţ (-p, öŕ ţĥé öñé đîšçöṽéŕý ƒîñđš) doc îš à ƒîļé'š þŕöĵéçţ-ŕéļàţîṽé þàţĥ, öŕ ţĥé àƃšöļüţé þàţĥ öƒ à ƒîļé öüţšîđé ţĥé þŕöĵéçţ, àñđ kapi apply îñ ţĥé šàḿé þŕöĵéçţ ŕéšöļṽéš ƃöţĥ.

Çĥàñĝé šéţš: kapi apply​

kapi apply ŕéàđš à kapi.change/v1 çĥàñĝé šéţ: öñé ĴŠÖÑ öƃĵéçţ ŵîţĥ îţš öþéŕàţîöñš üñđéŕ ops, ĴŠÖÑĻ ŵîţĥ ţĥé éñṽéļöþé ƒîéļđš öñ ţĥé ƒîŕšţ ļîñé àñđ öñé öþéŕàţîöñ þéŕ ļîñé, öŕ à ĴŠÖÑ àŕŕàý öƒ öþéŕàţîöñš. kapi apply --schema þŕîñţš îţš ĴŠÖÑ Šçĥéḿà, ĝéñéŕàţéđ ƒŕöḿ ţĥé Ĝö ţýþéš àñđ þîññéđ ƃý à ĝöļđéñ ƒîļé (core/change/testdata/schema.golden.json). Đéçöđîñĝ îš šţŕîçţ: àñ üñķñöŵñ ƒîéļđ öŕ öþéŕàţîöñ îš ŕéƒüšéđ ŵîţĥ îţš ĴŠÖÑ þöîñţéŕ. Àñ éñţŕý öƒ ţĥé éàŕļîéŕ šĥàþé (kind, file, id, content_hash) îš ŕéƒüšéđ ŵîţĥ à ḿéššàĝé ñàḿîñĝ ţĥé öþéŕàţîöñ ţĥàţ ţàķéš îţš þļàçé. À çĥàñĝé šéţ ŵîţĥ ñö öþéŕàţîöñ ("ops": []) àþþļîéš àñđ çĥàñĝéš ñöţĥîñĝ.

Éṽéŕý þöšîţîöñ îñ à çĥàñĝé šéţ ñàḿéš ţĥé éđîţîöñ àţ ţĥé ŕéṽîšîöñ îţš öþéŕàţîöñ'š if_match ñàḿéš: àñ éđîţ'š start àñđ end, à ŕüñ range, àñđ ţĥé ŕüñ îñđéẋ öƒ à path. Ŵĥéñ àñ éàŕļîéŕ öþéŕàţîöñ öƒ ţĥé šéţ çĥàñĝéđ ţĥé šàḿé éđîţîöñ, kapi apply ḿöṽéš éàçĥ þöšîţîöñ þàšţ ţĥàţ çĥàñĝé, šö ţĥé ƒîẋéš kapi check --json þŕîñţš ƒöŕ đéŕéñţ ŵöŕđš öƒ öñé ƃļöçķ àþþļý ţöĝéţĥéŕ (kapi check --json | jq '{ops: [.findings[].fix | select(.)]}' | kapi apply -). À þöšîţîöñ îñšîđé ţéẋţ àñ éàŕļîéŕ öþéŕàţîöñ çĥàñĝéđ îš ŕéƒüšéđ àš guard ŵîţĥ šüƃçöđé overlap, ñàḿîñĝ ƃöţĥ öþéŕàţîöñš. À find ḿàţçĥéš ţĥé ţéẋţ àš ţĥé éàŕļîéŕ öþéŕàţîöñš ļéƒţ îţ.

--json þŕîñţš ţĥé ŕéšüļţ àš kapi.change-result/v1: ţĥé šéţ'š status (applied, refused, previewed öŕ partial), éàçĥ đöçüḿéñţ'š đîĝéšţš ƃéƒöŕé àñđ àƒţéŕ, àñđ öñé ŕéšüļţ þéŕ öþéŕàţîöñ ŵîţĥ îţš status (applied, unchanged, refused, not_applied öŕ previewed), îţš ŕéṽîšîöñš, àñđ öñ à ŕéƒüšàļ àñ error ŵĥöšé code îš öñé öƒ à çļöšéđ šéţ. À stale ŕéƒüšàļ çàŕŕîéš ţĥé éđîţîöñ'š current ŕéṽîšîöñ àñđ ţéẋţ. À çĥàñĝé šéţ ţĥàţ đöéš ñöţ đéçöđé, öŕ çöñţŕàđîçţš îţšéļƒ (çöđé çöḿḿéñţš ƃéšîđé đöçüḿéñţš, à ƒîļé öüţšîđé ţĥé þŕöĵéçţ ƃéšîđé öñé îñ îţ), îš àñšŵéŕéđ ŵîţĥ ţĥé šàḿé šĥàþé, status refused, ñö öþéŕàţîöñš, àñđ ţĥé error, ŵîţĥ îţš ĴŠÖÑ pointer ŵĥéŕé à ƒîéļđ îš àţ ƒàüļţ, àñđ éẋîţš 2. --dry-run ŵŕîţéš ñöţĥîñĝ àñđ ĝîṽéš éàçĥ đöçüḿéñţ îţš diff; --print-ops þŕîñţš ţĥé çĥàñĝé šéţ àš đéçöđéđ àñđ àþþļîéš ñöţĥîñĝ.

Ţĥé éẋîţ šţàţüš ƒöļļöŵš ţĥé ŕéšüļţ: 0 ŵĥéñ ţĥé çĥàñĝé šéţ àþþļîéđ öŕ þŕéṽîéŵéđ; 2 ŵĥéñ îţ đöéš ñöţ đéçöđé, çöñţŕàđîçţš îţšéļƒ, öŕ àñ öþéŕàţîöñ îš ŕéƒüšéđ invalid; 5 ŵĥéñ à ƃàçķéñđ đîđ ñöţ àñšŵéŕ (unreachable); 3 ƒöŕ éṽéŕý öţĥéŕ ŕéƒüšàļ, ƒöŕ à çĥàñĝé šéţ ţĥàţ ļàñđéđ îñ þàŕţ, àñđ, üñđéŕ ţĥé éñƒöŕçîñĝ ĝàţé, ƒöŕ à ŵŕîţţéñ çöđé çöḿḿéñţ ŵĥöšé çĥéçķ ƒàîļš. À ŕéƒüšàļ ŵŕîţéš ñöţĥîñĝ. ksed --print-ops þŕîñţš à çĥàñĝé šéţ îñ ţĥé šàḿé çöñţŕàçţ, ŵĥîçĥ kapi apply àþþļîéš àš þŕîñţéđ, ƒŕöḿ àñý đîŕéçţöŕý öƒ ţĥé þŕöĵéçţ.

Ţĥé ƒļöŵ çöḿḿàñđš ţàķé --print-ops ţöö: kapi translate, kapi pseudo-translate, kapi run, kapi up (öñé þàšš, öñ ţĥîš ḿàçĥîñé) àñđ kapi exec <tool> ƒöŕ à ţööļ ţĥàţ ŵŕîţéš ƒîļéš. Ţĥé ŕüñ ŕéàđš àñđ ŕüñš îţš ţööļš àš îţ ŵöüļđ, ŵŕîţéš ñö ƒîļé öƒ ţĥé þŕöĵéçţ, ŕéçöŕđš ñö çĥàñĝé àñđ àƃšöŕƃš ñöţĥîñĝ îñţö ţĥé çöñţéñţ ḿéḿöŕý, àñđ þŕîñţš öñé çĥàñĝé šéţ: ƒöŕ éàçĥ đöçüḿéñţ, ţĥé đéŕéñçé ƃéţŵééñ éàçĥ ƃļöçķ àš îţ ŵàš ŕéàđ àñđ àš ţĥé ŕüñ ŵöüļđ ŵŕîţé îţ, éàçĥ öþéŕàţîöñ ĝüàŕđéđ ƃý ţĥé ŕéṽîšîöñ kapi inspect ŕéàđš, éàçĥ ţŕàñšļàţîöñ'š set_content çàŕŕýîñĝ îţš basis, àñđ éàçĥ öþéŕàţîöñ öñ à ţŕàñšļàţîöñ šţàţîñĝ îñ origin ţĥé ţööļ ţĥàţ þŕöđüçéđ îţ (tool, ŵîţĥ ţĥé kind àñđ engine îţ đŕéŵ öñ). kapi apply öƒ ţĥàţ çĥàñĝé šéţ ŵŕîţéš ţĥé ƃýţéš ţĥé ŕüñ ŵöüļđ ĥàṽé ŵŕîţţéñ, àñđ ŕéçöŕđš ţĥé éđîţ àš ţĥé àþþļîéŕ'š: ţĥé öŕîĝîñ îš ñöţ ķéþţ, àñđ öñçé ţĥé çĥàñĝé ļàñđš kapi apply þŕîñţš à öñé-ļîñé note: öñ šţđéŕŕ ñàḿîñĝ ţĥé ţööļš àñđ šàýîñĝ šö. À ŕüñ ţĥàţ ŵöüļđ çĥàñĝé ñöţĥîñĝ þŕîñţš à çĥàñĝé šéţ ŵîţĥ ñö öþéŕàţîöñ, ŵĥîçĥ àþþļîéš àñđ ŵŕîţéš ñöţĥîñĝ. Éṽéŕý ƒîļé ţĥé çĥàñĝé šéţ ļéàṽéš öüţ îš ñàḿéđ öñ šţđéŕŕ: à ţàŕĝéţ ƒîļé kapi apply ŵöüļđ ŵŕîţé öţĥéŕ ƃýţéš îñţö ţĥàñ ţĥé ŕüñ (ţĥé ŕüñ ŵŕîţéš îţ ŵĥöļé ƒŕöḿ îţš šöüŕçé, šö àñ éñţŕý öñļý ţĥé ţàŕĝéţ ĥöļđš, öŕ à ƃļöçķ ţĥé šöüŕçé ĝàîñéđ ţĥàţ kapi apply çàññöţ àđđ ţö ţĥé ƒîļé, öŕ àđđš îñ àñöţĥéŕ þļàçé), à ƒîļé ţĥé þŕöĵéçţ đöéš ñöţ ķééþ ţĥé éđîţîöñ îñ (àñ -o þàţĥ), à çöñṽéŕšîöñ, àñ éẋþöŕţ, àñ àŕçĥîṽé, àñđ ţĥé ƒîļéš öƒ à ļöçàļé kapi up ŵöüļđ ĥöļđ ƃàçķ àţ îţš šĥîþ ĝàţé. Îñ à þŕöĵéçţ, kapi translate, kapi pseudo-translate àñđ kapi run ŵîţĥöüţ -o ŵŕîţé ñö ƒîļé àñđ þŕîñţ àñ éḿþţý çĥàñĝé šéţ. kapi exec öṽéŕ à ƒîļé öƒ ţĥé þŕöĵéçţ ţĥé çöḿḿàñđ ŕéšöļṽéš ñàḿéš îţ àš kapi apply îñ ţĥàţ þŕöĵéçţ đöéš.

Éṽéŕý ƒļöŵ çöḿḿàñđ ŵŕîţéš à ƒîļé öñļý ŵĥîļé îţ šţîļļ ĥöļđš ŵĥàţ îţ ĥéļđ ŵĥéñ ţĥé ŕüñ ƃéĝàñ. À ƒîļé ţĥàţ çĥàñĝéđ ḿéàñŵĥîļé ķééþš îţš ƃýţéš; îñšîđé à þŕöĵéçţ ţĥé ŕüñ àþþļîéš îţš öŵñ çĥàñĝéš ţö îţ àĝàîñ, àñđ ŵĥéñ àñ éđîţîöñ ţĥé ŕüñ çĥàñĝéđ ĥàš ḿöṽéđ ţöö ţĥé ƒîļé îš ļéƒţ àš îţ îš àñđ ţĥé çöḿḿàñđ ƒàîļš, ñàḿîñĝ îţ.

Đŕîṽîñĝ ķàþî ƒŕöḿ àñ àþþļîçàţîöñ​

Àñ àþþļîçàţîöñ ŕéàđš àñđ çĥàñĝéš çöñţéñţ ţĥŕöüĝĥ öñé öƒ ƒöüŕ çĥàññéļš. Éàçĥ çàŕŕîéš ţĥé çĥàñĝé çöñţŕàçţ (É-09): à ŕéàđ ĝîṽéš éṽéŕý ƃļöçķ îţš ref àñđ rev, àñđ à ŵŕîţé îš à kapi.change/v1 çĥàñĝé šéţ, ĥéļđ ţö ţĥé šàḿé ŕüļéš ŵĥîçĥéṽéŕ çĥàññéļ šéñđš îţ.

ÇĥàññéļƑöŕĤöŵ
Ţĥé Ĝö ļîƃŕàŕýà Ĝö þŕöĝŕàḿhost.App.ChangeService ƃüîļđš ţĥé çĥàñĝé šéŕṽîçé ƒöŕ à þŕöĵéçţ, ŵîţĥ ţĥé ŕéçîþé'š ƒöŕḿàţš, îţš ĝöṽéŕñàñçé àñđ îţš ĥîšţöŕý; core/change ŵîţĥ core/change/filehome ƃüîļđš öñé öṽéŕ à đîŕéçţöŕý. Ţĥé šéŕṽîçé ĥàš Read, Apply, Describe àñđ History.
kapi apply -à þŕöĝŕàḿ îñ àñý ļàñĝüàĝé ţĥàţ çàñ šţàŕţ à þŕöçéššŵŕîţé à çĥàñĝé šéţ ţö šţàñđàŕđ îñþüţ; ŵîţĥ --json ţĥé kapi.change-result/v1 ŕéšüļţ àŕŕîṽéš öñ šţàñđàŕđ öüţþüţ, àñđ ţĥé éẋîţ šţàţüš ƒöļļöŵš Çĥàñĝé šéţš. kapi inspect --jsonl îš ţĥé ḿàţçĥîñĝ ŕéàđ.
ḾÇÞ öṽéŕ šţàñđàŕđ îñþüţ àñđ öüţþüţàñ àĝéñţ ĥöšţ, öŕ àñý ḾÇÞ çļîéñţkapi mcp šéŕṽéš read_blocks, apply_edits, describe_format àñđ ţĥé ŕéšţ öƒ ţĥé ḾÇÞ ţööļš.
Ţĥé ƃŕöŵšéŕ ƃüîļđà ŵéƃ þàĝé@neokapi/engine ļöàđš ţĥé ŴéƃÀššéḿƃļý ƃüîļđ öƒ ķàþî àñđ çàļļš ţĥé ƒüñçţîöñš öƒ îţš éñĝîñé ÀƂÎ.

ḾÇÞ šüŕƒàçé šţàƃîļîţý​

Ţĥé ḾÇÞ šéŕṽéŕ (kapi mcp) îš þàŕţ öƒ ţĥé šàḿé çöñţŕàçţ: îţš ţööļ ñàḿéš àñđ îñþüţ šçĥéḿàš àŕé à šţàƃļé šüŕƒàçé ƒöŕ àĝéñţ îñţéĝŕàţîöñš, ļöçķéđ ƃý à šñàþšĥöţ ţéšţ (kapi/cmd/kapi/mcp_snapshot_test.go). Ñéŵ ţööļš àñđ ñéŵ öþţîöñàļ ƒîéļđš ḿàý ƃé àđđéđ; éẋîšţîñĝ ţööļš àŕé ñöţ ŕéñàḿéđ öŕ ŕéḿöṽéđ, àñđ éẋîšţîñĝ ƒîéļđš đö ñöţ çĥàñĝé ţýþé, ŵîţĥöüţ àñ éẋþļîçîţ, đöçüḿéñţéđ đéçîšîöñ.

Ţĥé kapi.change/v1 ƒŕééžé îš öñé šüçĥ đéçîšîöñ. apply_edits ŕéàđš find àš þļàçéĥöļđéŕ ţéẋţ, ţàķéš àñ öþţîöñàļ path öñ à replace_text öþéŕàţîöñ, àñđ ñàḿéš à þîéçé öƒ éṽîđéñçé'š ƃļöçķ evidence[].block; context_note ñàḿéš îţ block ţöö. kapi/cmd/kapi/testdata/mcp_tools.frozen.json ĥöļđš ţĥé ƒŕöžéñ šüŕƒàçé: à ţéšţ ŕéƒüšéš à ţööļ ţĥàţ îš ĝöñé àñđ àñ îñþüţ šçĥéḿà ţĥàţ ñö ļöñĝéŕ éẋţéñđš îţš ƒŕöžéñ öñé, àñđ ţĥé ĝöļđéñ, ŵĥîçĥ ţĥé šñàþšĥöţ ţéšţ ŕéĝéñéŕàţéš, šĥöŵš éṽéŕý çĥàñĝé îñ ŕéṽîéŵ. apply_edits đéçļàŕéš îţš ŕéšüļţ ŵîţĥ ţĥé ĝéñéŕàţéđ kapi.change-result/v1 šçĥéḿà.

check_text àççéþţš àñ öþţîöñàļ context_path, à þŕöĵéçţ-ŕéļàţîṽé đéšţîñàţîöñ ŵĥöšé ṽöîçé àñđ ţéŕḿš àþþļý ţö ţĥé šüþþļîéđ đŕàƒţ. Îţ ŕéǫüîŕéš à ƃöüñđ þŕöĵéçţ àñđ çàññöţ ƃé çöḿƃîñéđ ŵîţĥ profile_file öŕ profile_pack. Ţĥé ŕéšüļţ ķééþš target.kind: "text" àñđ ŕéçöŕđš ţĥé đéšţîñàţîöñ îñ target.context_path; ţĥé đéšţîñàţîöñ ñééđ ñöţ éẋîšţ. Üñšçöþéđ šñîþþéţ çĥéçķš ŕéţàîñ ţĥéîŕ éẋþļîçîţ þŕöƒîļé öþţîöñš. Šéé Çĥéçķš ƒöŕ ŕéþöŕţ çöṽéŕàĝé.

Ţĥé çĥéçķ ŕéþöŕţ šçĥéḿà îš kapi.check/v2. Îţš summary çàŕŕîéš findings, failing, reporting àñđ score. Éàçĥ ƒîñđîñĝ çàŕŕîéš fails (à ƃööļéàñ ţĥé ŕüļé ţĥàţ ŕàîšéđ îţ šéţš) àñđ, ŵĥéñ à šüĝĝéšţéđ ŕüļé ŕàîšéđ îţ, suggested: true. Ƒîñđîñĝš šöŕţ ƒàîļîñĝ ƒîŕšţ, ţĥéñ ƃý ŕüļé. Ţĥé ṽéŕđîçţ ƒàîļš ŵĥéñ àţ ļéàšţ öñé ƒîñđîñĝ ƒàîļš; ţĥé šçöŕé îš îñƒöŕḿàţîöñàļ àñđ đöéš ñöţ đéţéŕḿîñé ţĥé ṽéŕđîçţ. kapi check --ship ƒîñđîñĝš çàŕŕý ţĥé šàḿé fails, àñđ îţš šüḿḿàŕý çöüñţš failing àñđ reporting.

Ţĥé öþţîöñàļ execution.contexts àŕŕàý àđđš þéŕ-îñþüţ ĝüîđàñçé šéļéçţîöñ ţö kapi.check/v2 ŵîţĥöüţ çĥàñĝîñĝ ţĥé öţĥéŕ ŕéþöŕţ ƒîéļđš. Éñţŕîéš çöñţàîñ file öŕ context_path, voice (selection, applied, öþţîöñàļ name, source, profile àñđ channel), terms_applied, àñđ, ŵĥéñ à þŕöĵéçţ ŕéšöļṽéđ ţĥé ĝüîđàñçé, point (profile, channel, àñđ comments ƒöŕ ţĥé þöîñţ à ƒîļé'š çöḿḿéñţš šîţ àţ). Ƒîñđîñĝš, îñçļüđîñĝ ţĥöšé öƒ kapi check --ship, çàŕŕý ţĥé šàḿé öþţîöñàļ point. voice.selection îš project, override öŕ none. Ḿîššîñĝ çöñţéẋţ ḿéţàđàţà ḿéàñš üñŕéþöŕţéđ šéļéçţîöñ. ÇĻÎ ƒîļé çĥéçķš, ḾÇÞ ƒîļé/đŕàƒţ çĥéçķš àñđ šöüŕçé-çöñţéñţ ŕéļéàšé çĥéçķš šüþþļý îţ. Éẋþļîçîţ ṽöîçé öṽéŕŕîđéš ŕéţàîñ ţĥéîŕ ƃéĥàṽîöŕ àñđ àŕé îđéñţîƒîéđ àš override; ḾÇÞ ƒîéļđ đéšçŕîþţîöñš šţàţé ţĥàţ öḿîţţîñĝ öṽéŕŕîđéš þŕéšéŕṽéš ƒîļé-šçöþéđ þŕöĵéçţ ĝüîđàñçé. Šéé Çĥéçķš ƒöŕ îñţéŕþŕéţàţîöñ.

Ţĥé öþţîöñàļ evaluation öƃĵéçţ îš àđđîţîṽé ţö kapi.check/v2 àñđ šàýš ŵĥàţ ţĥé ŕüñ ŵàš éṽàļüàţéđ àĝàîñšţ. Îţ çöñţàîñš at (ŔƑÇ 3339 îñ ÜŢÇ), tool (name, version, commit) àñđ analyzers, àñ éñţŕý þéŕ àñàļýžéŕ ŵîţĥ id, ran àñđ, ƒöŕ ţĥé îñþüţš îţ þŕöđüçéđ ñö üšàƃļé ŕéšüļţ ƒöŕ, not_run éñţŕîéš çàŕŕýîñĝ status, reason àñđ inputs. À ŕüñ îñšîđé à þŕöĵéçţ àļšö çàŕŕîéš context (project, name, revision, stale, stale_reason), ţĥé šàḿé šĥàþé ţĥé ḾÇÞ çöñţéẋţ ŕéþļîéš çàŕŕý àš provenance, àñđ à ŕüñ à þļüĝîñ šéŕṽéđ çàŕŕîéš plugins (name, version, serves). Decide ñéṽéŕ ŕéàđš ţĥé ŕéçöŕđ, šö îţ ļéàṽéš pass, verdict, summary àñđ ţĥé éẋîţ çöđé àš ţĥéý àŕé, àñđ ţĥé ĥüḿàñ öüţþüţ çàŕŕîéš ñöñé öƒ îţ. Éṽéŕý þŕöđüçéŕ öƒ à kapi.check/v2 Ŕéþöŕţ šüþþļîéš îţ: kapi check ŵĥöļé öŕ šçöþéđ ţö à đ, àñđ ţĥé ḾÇÞ check_file àñđ check_text ţööļš. kapi check --ship ŕéþöŕţš ĝàţéš, ñöţ à Ŕéþöŕţ, àñđ çàŕŕîéš ţĥé šàḿé evaluation öƃĵéçţ àţ îţš ţöþ ļéṽéļ, àššéḿƃļéđ öñçé ƒöŕ ţĥé ŵĥöļé ŕüñ: analyzers çöṽéŕš ţĥé àñàļýžéŕš öƒ éṽéŕý ĝàţé, àñđ plugins ñàḿéš éṽéŕý þļüĝîñ àñý ĝàţé ŕéàçĥéđ, ŵĥéţĥéŕ îţ ŕéàđ à ƒöŕḿàţ, ļöçàţéđ à ļàñĝüàĝé'š çöḿḿéñţš öŕ ŕàñ àñ àñàļýšîš. Ţĥé ƒîñđîñĝš ŕöļļ-üþ öƒ kapi exec <check> çàŕŕîéš ñöñé. Ţĥé ship_gates ĝöļđéñ üñđéŕ host/testdata/evaluation/ þîñš ţĥé ĝàţé öüţþüţ ŵîţĥ ţĥé ŕéçöŕđ. Šéé Çĥéçķš ƒöŕ ţĥé ƒîéļđš.

Ţĥé öþţîöñàļ warnings àŕŕàý îš àļšö àđđîţîṽé ţö kapi.check/v2, àñđ ţĥé kapi check --ship ŕéšüļţ çàŕŕîéš ţĥé šàḿé àŕŕàý àţ îţš ţöþ ļéṽéļ. Éàçĥ éñţŕý çöñţàîñš code, message, source àñđ, ŵĥéñ ţĥé ŵàŕñîñĝ çöñçéŕñš öñé ķéý, key. Ţĥé àŕŕàý îš öḿîţţéđ ŵĥéñ à ŕüñ ĥàš ñöñé. Ŵàŕñîñĝš đéšçŕîƃé ţĥé çöñƒîĝüŕàţîöñ à çĥéçķ ŕàñ üñđéŕ, àñđ ţĥéý ñéṽéŕ çĥàñĝé pass, verdict, summary öŕ ţĥé éẋîţ çöđé. Ţĥé ḾÇÞ check_text àñđ check_file ţööļš ŕéţüŕñ ţĥéḿ îñ ţĥé šàḿé ŕéþöŕţ, àñđ ţĥé check_report_warnings ĝöļđéñ îñ cli/contract_golden_test.go þîñš ţĥé šĥàþé. Šéé Çĥéçķš ƒöŕ ţĥé çöđéš.

Ţĥé éđîţ ţööļš çàŕŕý ţĥé çĥàñĝé çöñţŕàçţ (É-09). read_blocks ŕéàđš à đöçüḿéñţ'š ƃļöçķš ŵîţĥ ţĥé ref àñđ rev éàçĥ öþéŕàţîöñ ñàḿéš, àñđ review_block ŕéàđš öñé ƃļöçķ'š ŕéṽîéŵ þîçţüŕé ŵîţĥ ţĥé ref àñđ rev öƒ ţĥé éđîţîöñ üñđéŕ ŕéṽîéŵ, àñđ ţĥé ƃļöçķ îţšéļƒ üñđéŕ block. apply_edits ţàķéš à kapi.change/v1 çĥàñĝé šéţ: îţš îñþüţ šçĥéḿà îš ţĥé çĥàñĝé-šéţ šçĥéḿà, ŵĥîçĥ ţĥé šñàþšĥöţ ŕéçöŕđš îñ ƒüļļ, ŵîţĥ ţĥé þéŕ-çàļļ project àđđéđ. Îţš ŕéšüļţ îš à kapi.change-result/v1 đöçüḿéñţ, àñ éŕŕöŕ ŕéšüļţ ŵĥéñ ţĥé çĥàñĝé šéţ îš ŕéƒüšéđ öŕ ļàñđš öñļý îñ þàŕţ. describe_format ŕéþöŕţš ŵĥàţ éàçĥ öþéŕàţîöñ šüþþöŕţš îñ à ƒöŕḿàţ. À þŕé-ŕéṽîéŵ îš à decide öþéŕàţîöñ ŵîţĥ öüţçöḿé advise šéñţ ţĥŕöüĝĥ apply_edits. review_queue ŕöŵš çàŕŕý ţĥé ref ţĥàţ review_block ţàķéš.

À þéŕšöñ šéñđš ţĥé šàḿé çĥàñĝé šéţš ŵîţĥ kapi apply (šéé Çĥàñĝé šéţš). À çĥàñĝé šéţ ţàķéš àñ öþţîöñàļ evidence ƒîéļđ. À ţéŕḿ öŕ à çöñţéñţ-ḿéḿöŕý þàîŕ îš à đéçîšîöñ àƃöüţ ţĥé þŕöĵéçţ: àþþļýîñĝ öñé ŕéçöŕđš öñé edit öþéŕàţîöñ îñ ţĥàţ þŕöĵéçţ'š ĥîšţöŕý, éšţàƃļîšĥéđ ƒŕöḿ ţĥé šţàŕţ, àñđ evidence šàýš ŵĥéŕé ţĥé ŵöŕđîñĝ ƃéĥîñđ îţ ŵàš šééñ: à ƒîļé (path, block, quote) öŕ à ŵéƃ þàĝé (url). À çĥàñĝé šéţ ţàķéš ñö àçţöŕ: apply_edits šéñđš éṽéŕý çĥàñĝé šéţ àš ţĥé çàļļîñĝ àĝéñţ îñ ţĥé šéŕṽéŕ'š šéššîöñ, šö ţĥé çĥàñĝé þöļîçý ŕéƒüšéš îţš ţéŕḿ, çöñţéñţ-ḿéḿöŕý àñđ ŕéçîþé öþéŕàţîöñš, à decide öţĥéŕ ţĥàñ advise, àñ if_match öƒ * àñđ ţĥé report ĝàţé, àñđ kapi apply ŕéçöŕđš ţĥé þéŕšöñ öŕ àĝéñţ îţš éñṽîŕöñḿéñţ ñàḿéš. Šéé Ĝŕöŵîñĝ çöñţéẋţ.

Ţŵö ţööļš ŕéçöŕđ àñđ ŕéàđ à þŕöĵéçţ'š çöñţéẋţ ĥîšţöŕý: context_note àñđ context_session_summary, îñ þàŕîţý ŵîţĥ kapi context note àñđ kapi context log --session this. context_note ŕéçöŕđš ŵĥàţ ţĥé àĝéñţ ñöţîçéđ (text, öŕ term ŵîţĥ instead_of), à çĥàñĝé à þéŕšöñ ḿàđé (from àñđ to), öŕ, ŵîţĥ withdraw, ţàķéš ƃàçķ à ñöţé öƒ ţĥé šàḿé šéššîöñ. Éàçĥ ŵŕàþš ţĥé çöñţéẋţ-öþéŕàţîöñš ÀÞÎ îñ ţĥé ĥöšţ àñđ ţàķéš ţĥé šàḿé öþţîöñàļ project àš éṽéŕý öţĥéŕ þŕöĵéçţ-šçöþéđ ţööļ. context_read ŕéţüŕñš éẋàçţļý ţĥé ţéẋţ ţĥé context://<path> ŕéšöüŕçé ŕéţüŕñš, ƒöŕ à çļîéñţ ţĥàţ ļîšţš ñö ŕéšöüŕçéš ƒŕöḿ à ţéḿþļàţé, àñđ îţš comments ƒîéļđ, ļîķé ţĥé ŕéšöüŕçé'š comments ǫüéŕý þàŕàḿéţéŕ àñđ kapi context <path> --comments, àñšŵéŕš ƒöŕ ţĥé çöḿḿéñţš îñ à ƒîļé. Ŵîţĥöüţ session, context_session_summary šüḿḿàŕîžéš ţĥé šéššîöñ ŵîţĥ ţĥé þŕöĵéçţ'š ļàţéšţ çĥéçķ ŕüñ, öŕ ţĥé šéššîöñ ţĥàţ ŕéçöŕđéđ ļàšţ ŵĥéñ ñö šéššîöñ ĥöļđš à çĥéçķ ŕüñ, àñđ ñàḿéš îţ, ţĥé ŕüļé ţĥàţ àþþļîéđ àñđ ŵĥéñ îţ ļàšţ ŕéçöŕđéđ îñ chosen; à ļöĝ ŵîţĥ ñö šéššîöñ'š öþéŕàţîöñš àñšŵéŕš ŵîţĥ öñé ļîñé îñ report.

context_note ţööķ ţĥé þļàçé öƒ context_observe, context_correct àñđ context_withdraw ƃéƒöŕé 1.3.0 šĥîþþéđ: àñ éẋþļîçîţ đéçîšîöñ ţö ĝîṽé ţĥé àĝéñţ öñé ŕéçöŕđîñĝ ţööļ, ŵîţĥ ţĥé ƒŕöžéñ šüŕƒàçé éđîţéđ ƃý ĥàñđ ţö ḿàţçĥ.

Ñöñé öƒ ţĥéḿ ţàķéš àñ àçţöŕ. Ţĥé ķîñđ îš agent, ţĥé ñàḿé îš ţĥé çļîéñţ'š öŵñ initialize ñàḿé, àñđ ţĥé šéššîöñ îš ḿîñţéđ öñçé þéŕ šéŕṽéŕ þŕöçéšš, šö àñ àŕĝüḿéñţ ñàḿîñĝ àñ àçţöŕ öŕ à šéššîöñ îš ŕéƒüšéđ ƃý ţĥé šçĥéḿà. Éṽîđéñçé îš ŕéǫüîŕéđ ŵĥéŕé à ŕüļé îš šţàţéđ: context_note ŕéƒüšéš à ţéŕḿ ŕüļé, öŕ à çĥàñĝé ƒŕöḿ öñé ŵöŕđîñĝ ţö àñöţĥéŕ, ŵîţĥ ñö path. À ŕéçöŕđéđ öþéŕàţîöñ îš à šüĝĝéšţîöñ, šö à çĥéçķ ŕéþöŕţš îţ ŵîţĥ "fails": false àñđ "suggested": true, àñđ îţ ĥöļđš öñļý àţ ţĥé þàŕţ öƒ ţĥé þŕöĵéçţ îţš path ƃéļöñĝš ţö üñţîļ à þéŕšöñ ŵîđéñš îţ. Ţĥé ŕéçöŕđ çàŕŕîéš contested_by ŵĥéñ îţ đîšàĝŕééš ŵîţĥ àñöţĥéŕ ŕüļé.

Ţĥé ḾÇÞ ţööļ šéţ éẋçļüđéš ķééþîñĝ, đŕöþþîñĝ, ŵîđéñîñĝ, ŕéšéţţîñĝ àñđ šýñçîñĝ. Ţĥé çöñţéẋţ þöļîçý ŕéšéŕṽéš ţĥöšé öþéŕàţîöñš ƒöŕ þéöþļé, ŵĥö ḿàķé ţĥéḿ ŵîţĥ kapi context review, kapi context reset àñđ kapi context sync. À withdraw ţàķéš ƃàçķ öñļý ŵĥàţ ţĥé šàḿé šéššîöñ ŕéçöŕđéđ. À ƃý-ļöçàţîöñ çöñţéẋţ àñšŵéŕ àñđ à context_search àñšŵéŕ çàŕŕý à suggestions àŕŕàý, éàçĥ éñţŕý ŵîţĥ status suggested öŕ contested, contested_by àñđ suggested_by. Šéé Ĝŕöŵîñĝ çöñţéẋţ.

Ţĥé ŕéĝîšţŕý ţööļš öñ ţĥàţ šüŕƒàçé àŕé éẋàçţļý ţĥé ÇĻÎ-ṽîšîƃļé öñéš: à ƃüîļţ-îñ ţööļ àþþéàŕš üñđéŕ kapi exec, îñ kapi tools list, àñđ àš àñ ḾÇÞ ţööļ ŵĥéñ îţ ŕéĝîšţéŕš à çöñƒîĝ ƒàçţöŕý àñđ đöéš ñöţ đéçļàŕé îţšéļƒ îñţéŕñàļ (registry.ToolRegistry.CLITools). Ŵîŕîñĝ à ƒàçţöŕý ƒöŕ à ţööļ ţĥàţ ļàçķéđ öñé îš ţĥéŕéƒöŕé àñ àđđîţîṽé šüŕƒàçé çĥàñĝé: îţ àđđš ţĥé ţööļ ţö àļļ ţĥŕéé àţ öñçé, àñđ ţĥé šñàþšĥöţ ḿöṽéš. whitespace-correct ĝàîñéđ öñé ţĥîš ŵàý, àñđ dnt-check, placeholder-check, xml-validation, create-target, remove-target, inline-codes-remove àñđ external-command ƒöļļöŵéđ.

Ţĥé up ţööļ ţàķéš àñ öþţîöñàļ local ƒîéļđ, ḿîŕŕöŕîñĝ kapi up --local: îñ à þŕöĵéçţ çöññéçţéđ ţö à šéŕṽéŕ ţĥé ŕüñ ĥàþþéñš àţ ţĥàţ ṽéñüé ƃý đéƒàüļţ (ţĥé šàḿé đéçîšîöñ ţĥé çöḿḿàñđ ḿàķéš) àñđ local ķééþš ţĥé ļööþ öñ ţĥîš ḿàçĥîñé, þüšĥîñĝ ţĥé ŕéšüļţš àƒţéŕŵàŕđš.

review_queue ţàķéš àñ öþţîöñàļ language ƒîéļđ, ḿîŕŕöŕîñĝ kapi status --review --lang: ţĥé ǫüéüé ĥöļđš éṽéŕý ļàñĝüàĝé ţĥé þŕöĵéçţ ĥàš ŵöŕķ îñ, šö language ñàŕŕöŵš îţ ţö öñé, ţĥé þŕöĵéçţ'š šöüŕçé ļàñĝüàĝé îñçļüđéđ. Ţĥé ŕöŵš çàŕŕý language, isSource, status àñđ held, àñđ ţĥé ŕéšüļţ çàŕŕîéš languages ŵîţĥ ţĥé þéñđîñĝ çöüñţ þéŕ ļàñĝüàĝé.

Ŕüññîñĝ çöḿḿàñđš à ŕéçîþé ñàḿéš​

external-command àñđ script ŕüñ çöđé ţĥé çöñƒîĝüŕàţîöñ çĥööšéš. Ţĥéý šţàý àṽàîļàƃļé öñ éṽéŕý šüŕƒàçé ŵĥéŕé ţĥé àŕĝṽ îš ţĥé üšéŕ'š öŵñ: kapi exec external-command --command … ŕüñš ŵĥàţ îţ ŵàš ţöļđ ţö, üñçĥàñĝéđ.

Ŵĥàţ à ŕéçîþé đöéš ŵîţĥ ţĥéḿ îš ĝàţéđ. À þŕöĵéçţ ŵĥöšé ŕéçîþé ñàḿéš éîţĥéŕ ţööļ þŕöḿþţš öñçé, šĥöŵîñĝ ţĥé çöḿḿàñđ îţ ŵöüļđ ŕüñ, àñđ ţĥé àñšŵéŕ îš ŕéḿéḿƃéŕéđ üñđéŕ ţĥé ķàþî çöñƒîĝ đîŕéçţöŕý àĝàîñšţ à ƒîñĝéŕþŕîñţ öƒ ŵĥàţ ŵàš àþþŕöṽéđ, šö àñ üñŕéļàţéđ ŕéçîþé éđîţ ķééþš ţĥé àþþŕöṽàļ àñđ à çĥàñĝéđ çöḿḿàñđ àšķš àĝàîñ. Ŵîţĥ ñö ţéŕḿîñàļ àţţàçĥéđ, ķàþî ŕéƒüšéš àñđ àššüḿéš ñö çöñšéñţ; KAPI_TRUST_EXEC=1 îš ţĥé öþţ-îñ ƒöŕ àüţöḿàţîöñ, àñđ ţĥé ĝéñéŕàļ --yes ƒļàĝ đöéš ñöţ ĝŕàñţ îţ. Ţĥé ḾÇÞ ţööļ šüŕƒàçé ŕéƒüšéš ţĥéšé ţööļš öüţŕîĝĥţ. Šéé É-06.

kapi formats explain --json <file>... ŕéţüŕñš {files[]}, öñé éñţŕý þéŕ þàţĥ: {path, format?, engine?, rule?, content?, order?[], candidates?[], error?}, éàçĥ çàñđîđàţé {format, engine}. rule îš ţĥé ŕéĝîšţŕý'š ŕüļé (native first, engine override, engine preference, engine default, format engine, engine order) öŕ content item format / format flag ŵĥéñ ţĥé ƒöŕḿàţ ŵàš ñàḿéđ, ñöţ đéţéçţéđ; à þàţĥ ñö ƒöŕḿàţ ŕéàđš çàŕŕîéš error àñđ ñö format. kapi formats --json éñţŕîéš çàŕŕý engine ƃéšîđé source àñđ shared_extensions, ţĥé éẋţéñšîöñš àñöţĥéŕ éñĝîñé àļšö çļàîḿš. Ļöçķéđ ƃý cli/testdata/contract/formats_explain.golden.json.

kapi trust ŕéàđš àñđ çĥàñĝéš ţĥé ŕéçöŕđ. kapi trust list --json ŕéţüŕñš {record, entries[]}, éàçĥ éñţŕý {path, kind, decision, recorded_at, digest, status, detail?} ŵîţĥ kind öñé öƒ recipe öŕ formatter àñđ status öñé öƒ current, changed, missing, unreadable öŕ unverified. kapi trust show --json ŕéţüŕñš {path, sites[], digest?, status, recorded?, env_granted?, record}, éàçĥ šîţé {where, kind, name, detail?}, status öñé öƒ allowed, declined, undecided, changed öŕ nothing_to_decide, àñđ recorded {decision, recorded_at, digest} ŵĥéñ ţĥé ŕéçöŕđ ĥöļđš àñ éñţŕý ƒöŕ ţĥé þàţĥ. kapi trust revoke àñđ kapi trust allow ŕéţüŕñ {path, removed, decision?, record} àñđ {path, sites[], digest?, recorded, reason?, record}. Ƃöţĥ đöçüḿéñţš àŕé ļöçķéđ ƃý cli/testdata/contract/trust_*.golden.json.

Ţööļ ŕéĝîšţŕàţîöñ îñṽàŕîàñţš​

Ƒöüŕ þŕöþéŕţîéš öƒ à ƃüîļţ-îñ ţööļ'š ŕéĝîšţŕàţîöñ àŕé àššéŕţéđ öṽéŕ ţĥé þöþüļàţéđ ŕéĝîšţŕý, îñ core/tools/registration_invariants_test.go, ƃéçàüšé éàçĥ öñé ƒàîļš šîļéñţļý ŵĥéñ îţ îš ļéƒţ ţö ŕéṽîéŵ:

  • À ţööļ ţĥàţ đéçļàŕéš šéţţàƃļé šçĥéḿà ƒîéļđš ŕéĝîšţéŕš à çöñƒîĝ ƒàçţöŕý. Ŵîţĥöüţ öñé, NewToolWithConfig çàļļš ţĥé žéŕö-àŕĝ ƒàçţöŕý àñđ đîšçàŕđš ţĥé šţéþ'š config: ḿàþ ŵîţĥöüţ à ŵöŕđ, àñđ ţĥé ţööļ'š đöçüḿéñţéđ þàŕàḿéţéŕš đö ñöţĥîñĝ.
  • À ƃîļîñĝüàļ ţööļ'š ţàŕĝéţ ļöçàļé çöḿéš ƒŕöḿ ţĥé ŕüñ. --target-lang öüţŕàñķš àñý ļöçàļé ŵŕîţţéñ îñţö à šţéþ'š çöñƒîĝ, šö öñé ƒļöŵ šéŕṽéš éṽéŕý ļöçàļé îţ îš ŕüñ ƒöŕ. À ƒàçţöŕý ţĥàţ þîñš à ļöçàļé ļéàṽéš ţĥé ţööļ þŕöçéššîñĝ çöñţéñţ ţĥé ŕüñ ñéṽéŕ àšķéđ ƒöŕ, àñđ ŕéþöŕţîñĝ šüççéšš.
  • À ÇĻÎ-ṽîšîƃļé ţööļ ţĥàţ ŕéŵŕîţéš çöñţéñţ đéçļàŕéš writesOutput. kapi exec ĝŕöŵš -o / --output-dir öñļý ƒöŕ ţööļš ţĥàţ đö; ŵîţĥöüţ îţ àñ éẋéç ŕüñ ŕéŵŕîţéš ţĥé çöñţéñţ îñ ḿéḿöŕý, éẋîţš 0, àñđ ŵŕîţéš ñöţĥîñĝ. À ţööļ ŵĥöšé þŕöđüçéđ þöŕţš àŕé àļļ ƒîñđîñĝš (host.WritesFindingsOnly) ŵŕîţéš à ƒîļé öñļý ŵĥéŕé -o öŕ --output-dir ñàḿéš öñé.
  • À ḿöñöļîñĝüàļ ţööļ đéçļàŕéš ţĥé ţàŕĝéţ ļàñĝüàĝé îţ ŕéàđš, àñđ öñļý ţĥàţ. kapi exec öƒƒéŕš --target-lang ţö à ƃîļîñĝüàļ ţööļ àñđ ţö à ḿöñöļîñĝüàļ öñé ŵĥöšé ToolMeta àççéþţš öŕ ŕéǫüîŕéš target-language. À ḿöñöļîñĝüàļ ţööļ ŵĥöšé çöñƒîĝ ƒàçţöŕý ŕéàđš ţĥé ŕüñ'š ţàŕĝéţ ļàñĝüàĝé ŵîţĥöüţ đéçļàŕîñĝ îţ ĥàš à ţàŕĝéţ šçöþé ñöƃöđý çàñ ŕéàçĥ ƒŕöḿ ţĥé çöḿḿàñđ ļîñé; öñé ţĥàţ đéçļàŕéš îţ ŵîţĥöüţ ŕéàđîñĝ îţ öƒƒéŕš à ƒļàĝ ţĥàţ đöéš ñöţĥîñĝ.

Ŵîţĥĥöļđîñĝ à ţööļ ƒŕöḿ ţĥé ÇĻÎ îš à šéþàŕàţé đéçîšîöñ, đéçļàŕéđ ŵîţĥ internal: true öñ îţš ToolMeta àñđ ñéṽéŕ éẋþŕéššéđ ƃý öḿîţţîñĝ à çöñƒîĝ ƒàçţöŕý, ŵĥîçĥ ŵöüļđ ḿàķé à ƒöŕĝöţţéñ ţööļ îñđîšţîñĝüîšĥàƃļé ƒŕöḿ öñé đéļîƃéŕàţéļý ŵîţĥĥéļđ. Àñ îñţéŕñàļ ţööļ îš šţîļļ çöñƒîĝüŕàƃļé: à ƒļöŵ ḿàý ñàḿé îţ àš à šţéþ.

Šţéþ çöñƒîĝ ķéýš àŕé ţĥé çöñƒîĝ šţŕüçţ'š ĴŠÖÑ ñàḿéš, ŵĥîçĥ àŕé çàḿéļÇàšé (normalizeSpaces, flagExtra, textUnitIDs). Àþþļîçàţîöñ îš à json.Unmarshal, šö àñ üñŕéçöĝñîžéđ ķéý (à šñàķé_çàšé šþéļļîñĝ, öŕ à ƒîéļđ ţĥé ţööļ đöéš ñöţ ĥàṽé) îš šîļéñţļý îĝñöŕéđ.