Merge branch 'refactor/task-translation-review-translation-review'
Brings the i18n translation review into main: - Five feat(i18n) commits translating the chapters collection (landing, summary, models, agents, skills). - One feat(i18n) commit wiring audit-translations.mjs into pnpm run verify, with an 18-entry allowlist for intentional identicals (numeric card labels, product nouns, model-tier series names). Together: 122 untranslated pt fields fixed (across 5 files), 18 intentional identicals documented, audit-translations now part of the gate. English strings are byte-identical to origin/main. Recall section in skills.json preserved byte-identical. Reviewed-by: site owner (translation tone approved commit-by-commit). Closes: chapters collection pt === en regression.
This commit is contained in:
@@ -0,0 +1,112 @@
|
|||||||
|
{
|
||||||
|
"entries": [
|
||||||
|
{
|
||||||
|
"collection": "chapters",
|
||||||
|
"file": "agents.json",
|
||||||
|
"field": "sections.1.steps.0.label",
|
||||||
|
"reason": "Handoff step label (\"Brief\"); kept English by glossary convention."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "chapters",
|
||||||
|
"file": "landing.json",
|
||||||
|
"field": "cards.0.label",
|
||||||
|
"reason": "Numeric card label (\"01\"); identical across locales by design."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "chapters",
|
||||||
|
"file": "landing.json",
|
||||||
|
"field": "cards.1.label",
|
||||||
|
"reason": "Numeric card label (\"02\"); identical across locales by design."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "chapters",
|
||||||
|
"file": "landing.json",
|
||||||
|
"field": "cards.2.label",
|
||||||
|
"reason": "Numeric card label (\"03\"); identical across locales by design."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "chapters",
|
||||||
|
"file": "landing.json",
|
||||||
|
"field": "cards.2.title",
|
||||||
|
"reason": "Product noun (\"Skills\"); kept English by glossary convention."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "chapters",
|
||||||
|
"file": "landing.json",
|
||||||
|
"field": "cards.3.label",
|
||||||
|
"reason": "Numeric card label (\"04\"); identical across locales by design."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "chapters",
|
||||||
|
"file": "landing.json",
|
||||||
|
"field": "cards.4.label",
|
||||||
|
"reason": "Numeric card label (\"05\"); identical across locales by design."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "chapters",
|
||||||
|
"file": "landing.json",
|
||||||
|
"field": "cards.5.label",
|
||||||
|
"reason": "Numeric card label (\"06\"); identical across locales by design."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "chapters",
|
||||||
|
"file": "summary.json",
|
||||||
|
"field": "cards.0.label",
|
||||||
|
"reason": "Numeric card label (\"01\"); identical across locales by design."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "chapters",
|
||||||
|
"file": "summary.json",
|
||||||
|
"field": "cards.1.label",
|
||||||
|
"reason": "Numeric card label (\"02\"); identical across locales by design."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "chapters",
|
||||||
|
"file": "summary.json",
|
||||||
|
"field": "cards.2.label",
|
||||||
|
"reason": "Numeric card label (\"03\"); identical across locales by design."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "chapters",
|
||||||
|
"file": "summary.json",
|
||||||
|
"field": "cards.2.title",
|
||||||
|
"reason": "Product noun (\"Skills\"); kept English by glossary convention."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "chapters",
|
||||||
|
"file": "summary.json",
|
||||||
|
"field": "cards.3.label",
|
||||||
|
"reason": "Numeric card label (\"04\"); identical across locales by design."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "chapters",
|
||||||
|
"file": "summary.json",
|
||||||
|
"field": "cards.4.label",
|
||||||
|
"reason": "Numeric card label (\"05\"); identical across locales by design."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "chapters",
|
||||||
|
"file": "summary.json",
|
||||||
|
"field": "cards.5.label",
|
||||||
|
"reason": "Numeric card label (\"06\"); identical across locales by design."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "providers",
|
||||||
|
"file": "claude.json",
|
||||||
|
"field": "title",
|
||||||
|
"reason": "Model-tier series name (\"Opus · Sonnet · Haiku\"); kept English as product name."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "providers",
|
||||||
|
"file": "gemini.json",
|
||||||
|
"field": "title",
|
||||||
|
"reason": "Model-tier series name (\"Pro · Flash · Flash-Lite\"); kept English as product name."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "providers",
|
||||||
|
"file": "openai.json",
|
||||||
|
"field": "title",
|
||||||
|
"reason": "Model-tier series name (\"Sol · Terra · Luna\"); kept English as product name."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -7,16 +7,25 @@
|
|||||||
// node .agents/scripts/audit-translations.mjs # walks src/content
|
// node .agents/scripts/audit-translations.mjs # walks src/content
|
||||||
// node .agents/scripts/audit-translations.mjs src/content/ # explicit root
|
// node .agents/scripts/audit-translations.mjs src/content/ # explicit root
|
||||||
//
|
//
|
||||||
// Exits non-zero if any pair is identical. The output is grouped by
|
// Exits non-zero if any unallowed pair is identical. The output is grouped
|
||||||
// collection, then by file, then by field path, so the report reads like
|
// by collection, then by file, then by field path, so the report reads like
|
||||||
// a translation backlog rather than a wall of strings.
|
// a translation backlog rather than a wall of strings.
|
||||||
//
|
//
|
||||||
// This is the sibling of extract-strings.mjs: that one proves the
|
// This is the sibling of extract-strings.mjs: that one proves the
|
||||||
// migration moved every string; this one proves every string actually
|
// migration moved every string; this one proves every string actually
|
||||||
// differs across locales.
|
// differs across locales.
|
||||||
|
//
|
||||||
|
// Allowlist: a sibling `.agents/scripts/audit-translations.allowlist.json`
|
||||||
|
// lists (collection, file, field) tuples that are intentionally identical
|
||||||
|
// across locales (numeric card labels, product nouns, model-tier series
|
||||||
|
// names, etc.). Entries in the allowlist are listed under "ALLOWED" in the
|
||||||
|
// output and do not affect the exit code. Adding to the allowlist is a
|
||||||
|
// deliberate edit + commit; future translators can see it and understand
|
||||||
|
// which identicals are intentional.
|
||||||
|
|
||||||
import { readFileSync, readdirSync, statSync } from 'node:fs';
|
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
||||||
import { join, relative } from 'node:path';
|
import { dirname, join, relative } from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
const ROOT = process.argv[2] ?? 'src/content';
|
const ROOT = process.argv[2] ?? 'src/content';
|
||||||
|
|
||||||
@@ -69,9 +78,27 @@ const collectionOf = (file, root) => {
|
|||||||
return parts.length >= 2 ? parts[0] : '(root)';
|
return parts.length >= 2 ? parts[0] : '(root)';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Load the allowlist. The file lives next to this script and lists
|
||||||
|
// intentional identicals (numeric labels, product nouns, model-tier series
|
||||||
|
// names, etc.). Missing file is OK — the audit still runs.
|
||||||
|
const here = dirname(fileURLToPath(import.meta.url));
|
||||||
|
const allowlistPath = join(here, 'audit-translations.allowlist.json');
|
||||||
|
const allowlist = new Set();
|
||||||
|
const allowlistReasons = new Map();
|
||||||
|
|
||||||
|
if (existsSync(allowlistPath)) {
|
||||||
|
const { entries } = JSON.parse(readFileSync(allowlistPath, 'utf8'));
|
||||||
|
for (const { collection, file, field, reason } of entries) {
|
||||||
|
allowlist.add(`${collection}${file}${field}`);
|
||||||
|
allowlistReasons.set(`${collection}${file}${field}`, reason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const groups = new Map();
|
const groups = new Map();
|
||||||
|
const allowedGroups = new Map();
|
||||||
let totalLocalized = 0;
|
let totalLocalized = 0;
|
||||||
let totalIdentical = 0;
|
let totalReal = 0;
|
||||||
|
let totalAllowed = 0;
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
let data;
|
let data;
|
||||||
@@ -84,40 +111,78 @@ for (const file of files) {
|
|||||||
const pairs = collect(data);
|
const pairs = collect(data);
|
||||||
if (pairs.length === 0) continue;
|
if (pairs.length === 0) continue;
|
||||||
|
|
||||||
const offenders = pairs.filter(([, en, pt]) => same(en, pt));
|
|
||||||
if (offenders.length === 0) continue;
|
|
||||||
|
|
||||||
totalLocalized += pairs.length;
|
|
||||||
totalIdentical += offenders.length;
|
|
||||||
|
|
||||||
const collection = collectionOf(file, ROOT);
|
const collection = collectionOf(file, ROOT);
|
||||||
const filename = relative(ROOT, file);
|
const filename = relative(ROOT, file);
|
||||||
|
// Allowlist entries key on the file's name within its collection
|
||||||
|
// (e.g. `landing.json`), so strip the collection prefix from
|
||||||
|
// `filename` when matching. The full relative path is still used
|
||||||
|
// for the report display.
|
||||||
|
const collectionFile = filename.startsWith(collection + '/')
|
||||||
|
? filename.slice(collection.length + 1)
|
||||||
|
: filename;
|
||||||
|
|
||||||
if (!groups.has(collection)) groups.set(collection, []);
|
// Split identical pairs into real offenders (fail the gate) and
|
||||||
groups.get(collection).push({ file: filename, pairs: offenders });
|
// allowlisted ones (listed under ALLOWED, do not affect exit code).
|
||||||
|
const real = [];
|
||||||
|
const allowed = [];
|
||||||
|
for (const [field, en, pt] of pairs) {
|
||||||
|
if (!same(en, pt)) continue;
|
||||||
|
const key = `${collection}${collectionFile}${field}`;
|
||||||
|
if (allowlist.has(key)) {
|
||||||
|
allowed.push([field, en, allowlistReasons.get(key)]);
|
||||||
|
} else {
|
||||||
|
real.push([field, en, null]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (groups.size === 0) {
|
totalLocalized += pairs.length;
|
||||||
|
|
||||||
|
if (real.length > 0) {
|
||||||
|
totalReal += real.length;
|
||||||
|
if (!groups.has(collection)) groups.set(collection, []);
|
||||||
|
groups.get(collection).push({ file: filename, pairs: real });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allowed.length > 0) {
|
||||||
|
totalAllowed += allowed.length;
|
||||||
|
if (!allowedGroups.has(collection)) allowedGroups.set(collection, []);
|
||||||
|
allowedGroups.get(collection).push({ file: filename, pairs: allowed });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const printGroup = (entries, label) => {
|
||||||
|
for (const [collection, list] of entries) {
|
||||||
|
console.log(`\n[${collection}]`);
|
||||||
|
for (const { file, pairs } of list) {
|
||||||
|
console.log(` ${file}`);
|
||||||
|
for (const [field, en, reason] of pairs) {
|
||||||
|
const sample = typeof en === 'string' ? JSON.stringify(en).slice(0, 80) : '<non-string>';
|
||||||
|
const suffix = reason ? ` [${label}: ${reason}]` : '';
|
||||||
|
console.log(` - ${field.padEnd(28)} ${sample}${suffix}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Clean case: no identicals at all.
|
||||||
|
if (totalReal === 0 && totalAllowed === 0) {
|
||||||
console.log('OK: no identical en/pt pairs found under', ROOT);
|
console.log('OK: no identical en/pt pairs found under', ROOT);
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print grouped report.
|
// Show allowed entries first, then real offenders (if any).
|
||||||
for (const [collection, entries] of groups) {
|
printGroup(allowedGroups, 'ALLOWED');
|
||||||
console.log(`\n[${collection}]`);
|
|
||||||
for (const { file, pairs } of entries) {
|
|
||||||
console.log(` ${file}`);
|
|
||||||
for (const [field, en, pt] of pairs) {
|
|
||||||
const sample = typeof en === 'string' ? JSON.stringify(en).slice(0, 80) : '<non-string>';
|
|
||||||
console.log(` - ${field.padEnd(28)} ${sample}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (totalReal > 0) {
|
||||||
|
printGroup(groups, 'REAL');
|
||||||
console.log(
|
console.log(
|
||||||
`\nFAIL: ${totalIdentical} identical localized field(s) across ${groups.size} collection(s) of ${ROOT}`,
|
`\nFAIL: ${totalReal} unallowed identical localized field(s) across ${groups.size} collection(s) of ${ROOT}`,
|
||||||
);
|
);
|
||||||
console.log(
|
console.log(
|
||||||
'A `pt` identical to `en` is how a bilingual site becomes monolingual. Translate, then re-run.',
|
'A `pt` identical to `en` is how a bilingual site becomes monolingual. Translate, then re-run.',
|
||||||
);
|
);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`\nOK: ${totalAllowed} identical field(s) found, all on the allowlist.`);
|
||||||
|
process.exit(0);
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@
|
|||||||
"check": "astro check",
|
"check": "astro check",
|
||||||
"lint": "eslint . --max-warnings=0 && stylelint --allow-empty-input 'src/**/*.css' --max-warnings=0",
|
"lint": "eslint . --max-warnings=0 && stylelint --allow-empty-input 'src/**/*.css' --max-warnings=0",
|
||||||
"format": "prettier --write .",
|
"format": "prettier --write .",
|
||||||
"verify": "node scripts/verify.mjs && node scripts/audit-ui.mjs && node .agents/scripts/check-tokens.mjs",
|
"verify": "node .agents/scripts/audit-translations.mjs && node scripts/verify.mjs && node scripts/audit-ui.mjs && node .agents/scripts/check-tokens.mjs",
|
||||||
"gate": "./.agents/scripts/gate.sh",
|
"gate": "./.agents/scripts/gate.sh",
|
||||||
"snapshot": "node .agents/scripts/snapshot-route.mjs",
|
"snapshot": "node .agents/scripts/snapshot-route.mjs",
|
||||||
"prepare": "husky"
|
"prepare": "husky"
|
||||||
|
|||||||
+7
-5
@@ -271,11 +271,13 @@ if (!allPages.every(([, page]) => page.includes('name="viewport"')))
|
|||||||
throw new Error('a built route lacks a viewport declaration');
|
throw new Error('a built route lacks a viewport declaration');
|
||||||
if (allPages.some(([, page]) => /<(script|link)[^>]+(src|href)="https?:[^\"]+"/i.test(page)))
|
if (allPages.some(([, page]) => /<(script|link)[^>]+(src|href)="https?:[^\"]+"/i.test(page)))
|
||||||
throw new Error('a built route has an external runtime dependency');
|
throw new Error('a built route has an external runtime dependency');
|
||||||
if (
|
// `pnpm run verify` may now prepend `node .agents/scripts/audit-translations.mjs &&`
|
||||||
!read('package.json').includes(
|
// for fail-fast translation checks. Allow an optional audit-translations prefix
|
||||||
'"verify": "node scripts/verify.mjs && node scripts/audit-ui.mjs && node .agents/scripts/check-tokens.mjs"',
|
// while still requiring the three core scripts in order.
|
||||||
)
|
const verifyChain = read('package.json');
|
||||||
)
|
const verifyShape =
|
||||||
|
/\"verify\":\s*\"(?:node \.agents\/scripts\/audit-translations\.mjs && )?node scripts\/verify\.mjs && node scripts\/audit-ui\.mjs && node \.agents\/scripts\/check-tokens\.mjs\"/;
|
||||||
|
if (!verifyShape.test(verifyChain))
|
||||||
throw new Error('pnpm verify no longer runs audit-ui and check-tokens');
|
throw new Error('pnpm verify no longer runs audit-ui and check-tokens');
|
||||||
if (!read('.agents/scripts/gate.sh').includes('pnpm run verify'))
|
if (!read('.agents/scripts/gate.sh').includes('pnpm run verify'))
|
||||||
throw new Error('the gate no longer runs the output contract');
|
throw new Error('the gate no longer runs the output contract');
|
||||||
|
|||||||
@@ -2,57 +2,57 @@
|
|||||||
"id": "agents",
|
"id": "agents",
|
||||||
"eyebrow": {
|
"eyebrow": {
|
||||||
"en": "Subagent workflow",
|
"en": "Subagent workflow",
|
||||||
"pt": "Subagent workflow"
|
"pt": "Fluxo de subagentes"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"en": "One branch<br>per <em>hand.</em>",
|
"en": "One branch<br>per <em>hand.</em>",
|
||||||
"pt": "One branch<br>per <em>hand.</em>"
|
"pt": "Uma branch<br>por <em>mão.</em>"
|
||||||
},
|
},
|
||||||
"lede": {
|
"lede": {
|
||||||
"en": "Agents work when roles, files, and evidence are bounded. A worktree gives each worker its own checkout while the orchestrator protects intent.",
|
"en": "Agents work when roles, files, and evidence are bounded. A worktree gives each worker its own checkout while the orchestrator protects intent.",
|
||||||
"pt": "Agents work when roles, files, and evidence are bounded. A worktree gives each worker its own checkout while the orchestrator protects intent."
|
"pt": "Agentes funcionam quando papéis, arquivos e evidências são delimitados. Um worktree dá a cada agente seu próprio checkout enquanto o orquestrador protege a intenção."
|
||||||
},
|
},
|
||||||
"cards": [
|
"cards": [
|
||||||
{
|
{
|
||||||
"label": {
|
"label": {
|
||||||
"en": "FRAME",
|
"en": "FRAME",
|
||||||
"pt": "FRAME"
|
"pt": "ENQUADRAR"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"en": "Orchestrator",
|
"en": "Orchestrator",
|
||||||
"pt": "Orchestrator"
|
"pt": "Orquestrador"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Owns scope, task graph, boundaries, and integration.",
|
"en": "Owns scope, task graph, boundaries, and integration.",
|
||||||
"pt": "Owns scope, task graph, boundaries, and integration."
|
"pt": "Dono do escopo, do grafo de tarefas, das fronteiras e da integração."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": {
|
"label": {
|
||||||
"en": "HAND OFF",
|
"en": "HAND OFF",
|
||||||
"pt": "HAND OFF"
|
"pt": "PASSAR"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"en": "Worker",
|
"en": "Worker",
|
||||||
"pt": "Worker"
|
"pt": "Agente"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Owns one coherent slice and one worktree.",
|
"en": "Owns one coherent slice and one worktree.",
|
||||||
"pt": "Owns one coherent slice and one worktree."
|
"pt": "Dono de uma fatia coerente e de um worktree."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": {
|
"label": {
|
||||||
"en": "PROVE",
|
"en": "PROVE",
|
||||||
"pt": "PROVE"
|
"pt": "COMPROVAR"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"en": "Verifier",
|
"en": "Verifier",
|
||||||
"pt": "Verifier"
|
"pt": "Verificador"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Re-runs gates and reports remaining gaps.",
|
"en": "Re-runs gates and reports remaining gaps.",
|
||||||
"pt": "Re-runs gates and reports remaining gaps."
|
"pt": "Roda gates novamente e reporta o que ainda falta."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -60,29 +60,29 @@
|
|||||||
{
|
{
|
||||||
"eyebrow": {
|
"eyebrow": {
|
||||||
"en": "The tree",
|
"en": "The tree",
|
||||||
"pt": "The tree"
|
"pt": "A árvore"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"en": "Split at<br>the <em>seam.</em>",
|
"en": "Split at<br>the <em>seam.</em>",
|
||||||
"pt": "Split at<br>the <em>seam.</em>"
|
"pt": "Divida na<br><em>costura.</em>"
|
||||||
},
|
},
|
||||||
"panelLabel": {
|
"panelLabel": {
|
||||||
"en": "MAIN / ORCHESTRATOR",
|
"en": "MAIN / ORCHESTRATOR",
|
||||||
"pt": "MAIN / ORCHESTRATOR"
|
"pt": "MAIN / ORQUESTRADOR"
|
||||||
},
|
},
|
||||||
"panelCode": {
|
"panelCode": {
|
||||||
"en": "├── agent/ui → components + visual states\n├── agent/tests → acceptance + regressions\n└── agent/docs → guide + examples\n\nmerge after each leaf returns a diff and evidence",
|
"en": "├── agent/ui → components + visual states\n├── agent/tests → acceptance + regressions\n└── agent/docs → guide + examples\n\nmerge after each leaf returns a diff and evidence",
|
||||||
"pt": "├── agent/ui → components + visual states\n├── agent/tests → acceptance + regressions\n└── agent/docs → guide + examples\n\nmerge after each leaf returns a diff and evidence"
|
"pt": "├── agent/ui → componentes + estados visuais\n├── agent/tests → aceitação + regressões\n└── agent/docs → guia + exemplos\n\nfaça merge depois que cada folha devolver um diff e evidências"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"eyebrow": {
|
"eyebrow": {
|
||||||
"en": "Handoff",
|
"en": "Handoff",
|
||||||
"pt": "Handoff"
|
"pt": "Passagem"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"en": "Context that<br>can <em>travel.</em>",
|
"en": "Context that<br>can <em>travel.</em>",
|
||||||
"pt": "Context that<br>can <em>travel.</em>"
|
"pt": "Contexto que<br>pode <em>viajar.</em>"
|
||||||
},
|
},
|
||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
@@ -92,27 +92,27 @@
|
|||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Goal, owned files, dependencies, non-goals, acceptance.",
|
"en": "Goal, owned files, dependencies, non-goals, acceptance.",
|
||||||
"pt": "Goal, owned files, dependencies, non-goals, acceptance."
|
"pt": "Objetivo, arquivos sob sua posse, dependências, fora de escopo, aceitação."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": {
|
"label": {
|
||||||
"en": "Isolation",
|
"en": "Isolation",
|
||||||
"pt": "Isolation"
|
"pt": "Isolamento"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "One branch and worktree per independent change.",
|
"en": "One branch and worktree per independent change.",
|
||||||
"pt": "One branch and worktree per independent change."
|
"pt": "Uma branch e um worktree por mudança independente."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": {
|
"label": {
|
||||||
"en": "Evidence",
|
"en": "Evidence",
|
||||||
"pt": "Evidence"
|
"pt": "Evidência"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Commands, result, changed files, screenshots, gaps.",
|
"en": "Commands, result, changed files, screenshots, gaps.",
|
||||||
"pt": "Commands, result, changed files, screenshots, gaps."
|
"pt": "Comandos, resultado, arquivos alterados, capturas de tela, lacunas."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,83 +1,89 @@
|
|||||||
{
|
{
|
||||||
"id": "landing",
|
"id": "landing",
|
||||||
"eyebrow": { "en": "The short route", "pt": "The short route" },
|
"eyebrow": {
|
||||||
"title": { "en": "Ship the<br><em>system.</em>", "pt": "Ship the<br><em>system.</em>" },
|
"en": "The short route",
|
||||||
|
"pt": "A rota curta"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"en": "Ship the<br><em>system.</em>",
|
||||||
|
"pt": "Entregue o<br><em>sistema.</em>"
|
||||||
|
},
|
||||||
"lede": {
|
"lede": {
|
||||||
"en": "Start with the map. Then open the one chapter that matches the decision in front of you: model, agent, worktree, skill, rule, or proof.",
|
"en": "Start with the map. Then open the one chapter that matches the decision in front of you: model, agent, worktree, skill, rule, or proof.",
|
||||||
"pt": "Start with the map. Then open the one chapter that matches the decision in front of you: model, agent, worktree, skill, rule, or proof."
|
"pt": "Comece pelo mapa. Depois abra o capítulo que combina com a decisão à sua frente: modelo, agente, worktree, skill, regra ou prova."
|
||||||
},
|
},
|
||||||
"threadLabel": {
|
"threadLabel": {
|
||||||
"en": "THE THREAD",
|
"en": "THE THREAD",
|
||||||
"pt": "THE THREAD"
|
"pt": "O FIO"
|
||||||
},
|
},
|
||||||
"threadText": {
|
"threadText": {
|
||||||
"en": "Frame uncertainty → isolate execution → preserve judgment → verify the change.",
|
"en": "Frame uncertainty → isolate execution → preserve judgment → verify the change.",
|
||||||
"pt": "Frame uncertainty → isolate execution → preserve judgment → verify the change."
|
"pt": "Enquadre a incerteza → isole a execução → preserve o julgamento → verifique a mudança."
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"en": "The route map is now the default entry. The full guide remains available whenever you want the whole narrative.",
|
"en": "The route map is now the default entry. The full guide remains available whenever you want the whole narrative.",
|
||||||
"pt": "The route map is now the default entry. The full guide remains available whenever you want the whole narrative."
|
"pt": "O mapa de rotas é agora a entrada padrão. O guia completo segue disponível sempre que você quiser a narrativa inteira."
|
||||||
},
|
},
|
||||||
"cards": [
|
"cards": [
|
||||||
{
|
{
|
||||||
"label": { "en": "01", "pt": "01" },
|
"label": { "en": "01", "pt": "01" },
|
||||||
"title": { "en": "Models", "pt": "Models" },
|
"title": { "en": "Models", "pt": "Modelos" },
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Capability and effort are separate knobs.",
|
"en": "Capability and effort are separate knobs.",
|
||||||
"pt": "Capability and effort are separate knobs."
|
"pt": "Capacidade e esforço são controles separados."
|
||||||
},
|
},
|
||||||
"href": "models/",
|
"href": "models/",
|
||||||
"cta": { "en": "Open chapter →", "pt": "Open chapter →" }
|
"cta": { "en": "Open chapter →", "pt": "Abrir capítulo →" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": { "en": "02", "pt": "02" },
|
"label": { "en": "02", "pt": "02" },
|
||||||
"title": { "en": "Agents & trees", "pt": "Agents & trees" },
|
"title": { "en": "Agents & trees", "pt": "Agentes e árvores" },
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Bound roles, handoffs, and worktrees.",
|
"en": "Bound roles, handoffs, and worktrees.",
|
||||||
"pt": "Bound roles, handoffs, and worktrees."
|
"pt": "Limite papéis, handoffs e worktrees."
|
||||||
},
|
},
|
||||||
"href": "agents/",
|
"href": "agents/",
|
||||||
"cta": { "en": "Open chapter →", "pt": "Open chapter →" }
|
"cta": { "en": "Open chapter →", "pt": "Abrir capítulo →" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": { "en": "03", "pt": "03" },
|
"label": { "en": "03", "pt": "03" },
|
||||||
"title": { "en": "Skills", "pt": "Skills" },
|
"title": { "en": "Skills", "pt": "Skills" },
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Capture repeatable decisions in small packages.",
|
"en": "Capture repeatable decisions in small packages.",
|
||||||
"pt": "Capture repeatable decisions in small packages."
|
"pt": "Capture decisões repetíveis em pacotes pequenos."
|
||||||
},
|
},
|
||||||
"href": "skills/",
|
"href": "skills/",
|
||||||
"cta": { "en": "Open chapter →", "pt": "Open chapter →" }
|
"cta": { "en": "Open chapter →", "pt": "Abrir capítulo →" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": { "en": "04", "pt": "04" },
|
"label": { "en": "04", "pt": "04" },
|
||||||
"title": { "en": "Rules", "pt": "Rules" },
|
"title": { "en": "Rules", "pt": "Regras" },
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Connect guidance to enforcement.",
|
"en": "Connect guidance to enforcement.",
|
||||||
"pt": "Connect guidance to enforcement."
|
"pt": "Conecte orientação a enforcement."
|
||||||
},
|
},
|
||||||
"href": "rules/",
|
"href": "rules/",
|
||||||
"cta": { "en": "Open chapter →", "pt": "Open chapter →" }
|
"cta": { "en": "Open chapter →", "pt": "Abrir capítulo →" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": { "en": "05", "pt": "05" },
|
"label": { "en": "05", "pt": "05" },
|
||||||
"title": { "en": "Hands-on", "pt": "Hands-on" },
|
"title": { "en": "Hands-on", "pt": "Prática" },
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Compare a strong prompt with skill-enabled work.",
|
"en": "Compare a strong prompt with skill-enabled work.",
|
||||||
"pt": "Compare a strong prompt with skill-enabled work."
|
"pt": "Compare um prompt forte com trabalho assistido por skills."
|
||||||
},
|
},
|
||||||
"href": "hands-on/starter/",
|
"href": "hands-on/starter/",
|
||||||
"cta": { "en": "Open lab →", "pt": "Open lab →" }
|
"cta": { "en": "Open lab →", "pt": "Abrir lab →" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": { "en": "06", "pt": "06" },
|
"label": { "en": "06", "pt": "06" },
|
||||||
"title": { "en": "Review desk", "pt": "Review desk" },
|
"title": { "en": "Review desk", "pt": "Mesa de revisão" },
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Browse original packages, references, scripts, and improvements.",
|
"en": "Browse original packages, references, scripts, and improvements.",
|
||||||
"pt": "Browse original packages, references, scripts, and improvements."
|
"pt": "Explore pacotes originais, referências, scripts e melhorias."
|
||||||
},
|
},
|
||||||
"href": "skills-review/",
|
"href": "skills-review/",
|
||||||
"cta": { "en": "Open desk →", "pt": "Open desk →" }
|
"cta": { "en": "Open desk →", "pt": "Abrir mesa →" }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,57 +2,57 @@
|
|||||||
"id": "models",
|
"id": "models",
|
||||||
"eyebrow": {
|
"eyebrow": {
|
||||||
"en": "Model routing",
|
"en": "Model routing",
|
||||||
"pt": "Model routing"
|
"pt": "Roteamento de modelos"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"en": "Choose the<br><em>engine.</em>",
|
"en": "Choose the<br><em>engine.</em>",
|
||||||
"pt": "Choose the<br><em>engine.</em>"
|
"pt": "Escolha o<br><em>motor.</em>"
|
||||||
},
|
},
|
||||||
"lede": {
|
"lede": {
|
||||||
"en": "A model has a capability ceiling. Effort controls how much room it gets to reason. Route by uncertainty and verification cost.",
|
"en": "A model has a capability ceiling. Effort controls how much room it gets to reason. Route by uncertainty and verification cost.",
|
||||||
"pt": "A model has a capability ceiling. Effort controls how much room it gets to reason. Route by uncertainty and verification cost."
|
"pt": "Um modelo tem um teto de capacidade. O esforço controla quanto espaço ele ganha para raciocinar. Roteie por incerteza e custo de verificação."
|
||||||
},
|
},
|
||||||
"cards": [
|
"cards": [
|
||||||
{
|
{
|
||||||
"label": {
|
"label": {
|
||||||
"en": "LOW",
|
"en": "LOW",
|
||||||
"pt": "LOW"
|
"pt": "BAIXO"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"en": "Bounded rhythm",
|
"en": "Bounded rhythm",
|
||||||
"pt": "Bounded rhythm"
|
"pt": "Ritmo delimitado"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Lookup, small edits, formatting, and transformations with clear checks.",
|
"en": "Lookup, small edits, formatting, and transformations with clear checks.",
|
||||||
"pt": "Lookup, small edits, formatting, and transformations with clear checks."
|
"pt": "Consultas, edições pequenas, formatação e transformações com checagens claras."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": {
|
"label": {
|
||||||
"en": "MEDIUM",
|
"en": "MEDIUM",
|
||||||
"pt": "MEDIUM"
|
"pt": "MÉDIO"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"en": "Default work",
|
"en": "Default work",
|
||||||
"pt": "Default work"
|
"pt": "Trabalho padrão"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Normal implementation where the contract is clear but context matters.",
|
"en": "Normal implementation where the contract is clear but context matters.",
|
||||||
"pt": "Normal implementation where the contract is clear but context matters."
|
"pt": "Implementação normal em que o contrato é claro, mas o contexto importa."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": {
|
"label": {
|
||||||
"en": "HIGH",
|
"en": "HIGH",
|
||||||
"pt": "HIGH"
|
"pt": "ALTO"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"en": "Ambiguity",
|
"en": "Ambiguity",
|
||||||
"pt": "Ambiguity"
|
"pt": "Ambiguidade"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Planning, architecture, security judgment, and hard failures.",
|
"en": "Planning, architecture, security judgment, and hard failures.",
|
||||||
"pt": "Planning, architecture, security judgment, and hard failures."
|
"pt": "Planejamento, arquitetura, julgamento de segurança e falhas difíceis."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -60,59 +60,59 @@
|
|||||||
{
|
{
|
||||||
"eyebrow": {
|
"eyebrow": {
|
||||||
"en": "Two knobs",
|
"en": "Two knobs",
|
||||||
"pt": "Two knobs"
|
"pt": "Dois controles"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"en": "Capability<br>× effort",
|
"en": "Capability<br>× effort",
|
||||||
"pt": "Capability<br>× effort"
|
"pt": "Capacidade<br>× esforço"
|
||||||
},
|
},
|
||||||
"panelLabel": {
|
"panelLabel": {
|
||||||
"en": "ROUTING RULE",
|
"en": "ROUTING RULE",
|
||||||
"pt": "ROUTING RULE"
|
"pt": "REGRA DE ROTEAMENTO"
|
||||||
},
|
},
|
||||||
"panelCode": {
|
"panelCode": {
|
||||||
"en": "strong model + high effort → frame ambiguity\nlight model + low effort → bounded execution\nraise one knob at a time → compare evidence",
|
"en": "strong model + high effort → frame ambiguity\nlight model + low effort → bounded execution\nraise one knob at a time → compare evidence",
|
||||||
"pt": "strong model + high effort → frame ambiguity\nlight model + low effort → bounded execution\nraise one knob at a time → compare evidence"
|
"pt": "modelo forte + esforço alto → enquadrar ambiguidade\nmodelo leve + esforço baixo → execução delimitada\nsuba um controle por vez → compare evidências"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"eyebrow": {
|
"eyebrow": {
|
||||||
"en": "Sequence",
|
"en": "Sequence",
|
||||||
"pt": "Sequence"
|
"pt": "Sequência"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"en": "Spend judgment<br>where it <em>compounds.</em>",
|
"en": "Spend judgment<br>where it <em>compounds.</em>",
|
||||||
"pt": "Spend judgment<br>where it <em>compounds.</em>"
|
"pt": "Invista julgamento<br>onde ele <em>compensa.</em>"
|
||||||
},
|
},
|
||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"label": {
|
"label": {
|
||||||
"en": "Plan",
|
"en": "Plan",
|
||||||
"pt": "Plan"
|
"pt": "Planejar"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Strong model: scope, risks, acceptance, and worktree split.",
|
"en": "Strong model: scope, risks, acceptance, and worktree split.",
|
||||||
"pt": "Strong model: scope, risks, acceptance, and worktree split."
|
"pt": "Modelo forte: escopo, riscos, aceitação e divisão de worktrees."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": {
|
"label": {
|
||||||
"en": "Build",
|
"en": "Build",
|
||||||
"pt": "Build"
|
"pt": "Construir"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Focused worker: smallest context and lightest model that can pass.",
|
"en": "Focused worker: smallest context and lightest model that can pass.",
|
||||||
"pt": "Focused worker: smallest context and lightest model that can pass."
|
"pt": "Worker focado: o menor contexto e o modelo mais leve que passa."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": {
|
"label": {
|
||||||
"en": "Review",
|
"en": "Review",
|
||||||
"pt": "Review"
|
"pt": "Revisar"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Independent pass when missed issues cost more than the call.",
|
"en": "Independent pass when missed issues cost more than the call.",
|
||||||
"pt": "Independent pass when missed issues cost more than the call."
|
"pt": "Revisão independente quando erros perdidos custam mais que a chamada."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,56 +1,56 @@
|
|||||||
{
|
{
|
||||||
"id": "skills",
|
"id": "skills",
|
||||||
"eyebrow": { "en": "Reusable judgment", "pt": "Reusable judgment" },
|
"eyebrow": { "en": "Reusable judgment", "pt": "Julgamento reutilizável" },
|
||||||
"title": { "en": "Teach the<br><em>decision.</em>", "pt": "Teach the<br><em>decision.</em>" },
|
"title": { "en": "Teach the<br><em>decision.</em>", "pt": "Ensine a<br><em>decisão.</em>" },
|
||||||
"lede": {
|
"lede": {
|
||||||
"en": "A skill changes behavior. Keep the trigger precise, put the workflow in <code>SKILL.md</code>, and move conditional facts, scripts, and examples into focused files.",
|
"en": "A skill changes behavior. Keep the trigger precise, put the workflow in <code>SKILL.md</code>, and move conditional facts, scripts, and examples into focused files.",
|
||||||
"pt": "A skill changes behavior. Keep the trigger precise, put the workflow in <code>SKILL.md</code>, and move conditional facts, scripts, and examples into focused files."
|
"pt": "Uma skill muda comportamento. Mantenha o gatilho preciso, coloque o workflow em <code>SKILL.md</code> e mova fatos condicionais, scripts e exemplos para arquivos focados."
|
||||||
},
|
},
|
||||||
"sections": [
|
"sections": [
|
||||||
{
|
{
|
||||||
"eyebrow": { "en": "Package anatomy", "pt": "Package anatomy" },
|
"eyebrow": { "en": "Package anatomy", "pt": "Anatomia do pacote" },
|
||||||
"title": {
|
"title": {
|
||||||
"en": "One job.<br>More than<br>one <em>file.</em>",
|
"en": "One job.<br>More than<br>one <em>file.</em>",
|
||||||
"pt": "One job.<br>More than<br>one <em>file.</em>"
|
"pt": "Um trabalho.<br>Mais que<br>um <em>arquivo.</em>"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Choose a file to see why it belongs in the package.",
|
"en": "Choose a file to see why it belongs in the package.",
|
||||||
"pt": "Choose a file to see why it belongs in the package."
|
"pt": "Escolha um arquivo para ver por que ele pertence ao pacote."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"eyebrow": { "en": "Create a skill", "pt": "Create a skill" },
|
"eyebrow": { "en": "Create a skill", "pt": "Crie uma skill" },
|
||||||
"title": {
|
"title": {
|
||||||
"en": "Observe →<br>trigger →<br>validate",
|
"en": "Observe →<br>trigger →<br>validate",
|
||||||
"pt": "Observe →<br>trigger →<br>validate"
|
"pt": "Observe →<br>defina o gatilho →<br>valide"
|
||||||
},
|
},
|
||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"label": { "en": "Observe friction", "pt": "Observe friction" },
|
"label": { "en": "Observe friction", "pt": "Observe o atrito" },
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Find a repeated decision or failure.",
|
"en": "Find a repeated decision or failure.",
|
||||||
"pt": "Find a repeated decision or failure."
|
"pt": "Encontre uma decisão ou falha repetida."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": { "en": "Define the trigger", "pt": "Define the trigger" },
|
"label": { "en": "Define the trigger", "pt": "Defina o gatilho" },
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Say when it should load and when it should stay out.",
|
"en": "Say when it should load and when it should stay out.",
|
||||||
"pt": "Say when it should load and when it should stay out."
|
"pt": "Diga quando deve carregar e quando deve ficar de fora."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": { "en": "Choose anatomy", "pt": "Choose anatomy" },
|
"label": { "en": "Choose anatomy", "pt": "Escolha a anatomia" },
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Use references for facts and scripts for deterministic mechanics.",
|
"en": "Use references for facts and scripts for deterministic mechanics.",
|
||||||
"pt": "Use references for facts and scripts for deterministic mechanics."
|
"pt": "Use referências para fatos e scripts para mecânicas determinísticas."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": { "en": "Evaluate behavior", "pt": "Evaluate behavior" },
|
"label": { "en": "Evaluate behavior", "pt": "Avalie o comportamento" },
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Test realistic prompts, edge cases, safety, and evidence.",
|
"en": "Test realistic prompts, edge cases, safety, and evidence.",
|
||||||
"pt": "Test realistic prompts, edge cases, safety, and evidence."
|
"pt": "Teste prompts realistas, casos extremos, segurança e evidência."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,75 +1,135 @@
|
|||||||
{
|
{
|
||||||
"id": "summary",
|
"id": "summary",
|
||||||
"eyebrow": { "en": "Start here", "pt": "Start here" },
|
"eyebrow": {
|
||||||
"title": { "en": "Ship the<br><em>system.</em>", "pt": "Ship the<br><em>system.</em>" },
|
"en": "Start here",
|
||||||
|
"pt": "Comece aqui"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"en": "Ship the<br><em>system.</em>",
|
||||||
|
"pt": "Entregue o<br><em>sistema.</em>"
|
||||||
|
},
|
||||||
"lede": {
|
"lede": {
|
||||||
"en": "This guide turns AI work into a shape: frame the problem, choose the model and agent, isolate changes, teach repeatable decisions, and verify the result.",
|
"en": "This guide turns AI work into a shape: frame the problem, choose the model and agent, isolate changes, teach repeatable decisions, and verify the result.",
|
||||||
"pt": "This guide turns AI work into a shape: frame the problem, choose the model and agent, isolate changes, teach repeatable decisions, and verify the result."
|
"pt": "Este guia transforma trabalho com IA em uma forma: enquadre o problema, escolha o modelo e o agente, isole mudanças, ensine decisões repetíveis e verifique o resultado."
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"en": "Each chapter stands alone; the order follows a real task becoming a reliable change.",
|
"en": "Each chapter stands alone; the order follows a real task becoming a reliable change.",
|
||||||
"pt": "Each chapter stands alone; the order follows a real task becoming a reliable change."
|
"pt": "Cada capítulo se sustenta sozinho; a ordem segue uma tarefa real se tornando uma mudança confiável."
|
||||||
},
|
},
|
||||||
"cards": [
|
"cards": [
|
||||||
{
|
{
|
||||||
"label": { "en": "01", "pt": "01" },
|
"label": {
|
||||||
"title": { "en": "Models", "pt": "Models" },
|
"en": "01",
|
||||||
|
"pt": "01"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"en": "Models",
|
||||||
|
"pt": "Modelos"
|
||||||
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Capability and effort are separate knobs.",
|
"en": "Capability and effort are separate knobs.",
|
||||||
"pt": "Capability and effort are separate knobs."
|
"pt": "Capacidade e esforço são controles separados."
|
||||||
},
|
},
|
||||||
"href": "../models/",
|
"href": "../models/",
|
||||||
"cta": { "en": "Open chapter →", "pt": "Open chapter →" }
|
"cta": {
|
||||||
|
"en": "Open chapter →",
|
||||||
|
"pt": "Abrir capítulo →"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": { "en": "02", "pt": "02" },
|
"label": {
|
||||||
"title": { "en": "Agents & trees", "pt": "Agents & trees" },
|
"en": "02",
|
||||||
|
"pt": "02"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"en": "Agents & trees",
|
||||||
|
"pt": "Agentes e árvores"
|
||||||
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Bound roles, handoffs, and worktrees.",
|
"en": "Bound roles, handoffs, and worktrees.",
|
||||||
"pt": "Bound roles, handoffs, and worktrees."
|
"pt": "Limite papéis, handoffs e worktrees."
|
||||||
},
|
},
|
||||||
"href": "../agents/",
|
"href": "../agents/",
|
||||||
"cta": { "en": "Open chapter →", "pt": "Open chapter →" }
|
"cta": {
|
||||||
|
"en": "Open chapter →",
|
||||||
|
"pt": "Abrir capítulo →"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": { "en": "03", "pt": "03" },
|
"label": {
|
||||||
"title": { "en": "Skills", "pt": "Skills" },
|
"en": "03",
|
||||||
|
"pt": "03"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"en": "Skills",
|
||||||
|
"pt": "Skills"
|
||||||
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Capture repeatable decisions.",
|
"en": "Capture repeatable decisions.",
|
||||||
"pt": "Capture repeatable decisions."
|
"pt": "Capture decisões repetíveis."
|
||||||
},
|
},
|
||||||
"href": "../skills/",
|
"href": "../skills/",
|
||||||
"cta": { "en": "Open chapter →", "pt": "Open chapter →" }
|
"cta": {
|
||||||
|
"en": "Open chapter →",
|
||||||
|
"pt": "Abrir capítulo →"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": { "en": "04", "pt": "04" },
|
"label": {
|
||||||
"title": { "en": "Rules", "pt": "Rules" },
|
"en": "04",
|
||||||
|
"pt": "04"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"en": "Rules",
|
||||||
|
"pt": "Regras"
|
||||||
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Connect guidance to enforcement.",
|
"en": "Connect guidance to enforcement.",
|
||||||
"pt": "Connect guidance to enforcement."
|
"pt": "Conecte orientação a enforcement."
|
||||||
},
|
},
|
||||||
"href": "../rules/",
|
"href": "../rules/",
|
||||||
"cta": { "en": "Open chapter →", "pt": "Open chapter →" }
|
"cta": {
|
||||||
|
"en": "Open chapter →",
|
||||||
|
"pt": "Abrir capítulo →"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": { "en": "05", "pt": "05" },
|
"label": {
|
||||||
"title": { "en": "Practice", "pt": "Practice" },
|
"en": "05",
|
||||||
|
"pt": "05"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"en": "Practice",
|
||||||
|
"pt": "Prática"
|
||||||
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Compare prompts and skill-enabled runs.",
|
"en": "Compare prompts and skill-enabled runs.",
|
||||||
"pt": "Compare prompts and skill-enabled runs."
|
"pt": "Compare prompts e execuções com skills."
|
||||||
},
|
},
|
||||||
"href": "../hands-on/starter/",
|
"href": "../hands-on/starter/",
|
||||||
"cta": { "en": "Open lab →", "pt": "Open lab →" }
|
"cta": {
|
||||||
|
"en": "Open lab →",
|
||||||
|
"pt": "Abrir lab →"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": { "en": "06", "pt": "06" },
|
"label": {
|
||||||
"title": { "en": "Review desk", "pt": "Review desk" },
|
"en": "06",
|
||||||
|
"pt": "06"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"en": "Review desk",
|
||||||
|
"pt": "Mesa de revisão"
|
||||||
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"en": "Browse original files and improved drafts.",
|
"en": "Browse original files and improved drafts.",
|
||||||
"pt": "Browse original files and improved drafts."
|
"pt": "Explore arquivos originais e rascunhos melhorados."
|
||||||
},
|
},
|
||||||
"href": "../skills-review/",
|
"href": "../skills-review/",
|
||||||
"cta": { "en": "Open desk →", "pt": "Open desk →" }
|
"cta": {
|
||||||
|
"en": "Open desk →",
|
||||||
|
"pt": "Abrir mesa →"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user