Files
ai-for-dummies/full-guide/index.html
T
Marcos Paulo 47f4de8757 chore: publish 25ef5af
Built from main 25ef5af63e
fix: refuse to publish a build that logged a vite error
2026-09-06 09:22:05 +00:00

834 lines
106 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html><html lang="en"> <head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>AI For Dummies — Field Guide</title><meta name="description" content="AI For Dummies: a field guide to skills, models, subagents, and worktrees."><link rel="stylesheet" href="/ai-for-dummies/_astro/tokens.CVOStimI.css"><link rel="stylesheet" href="/ai-for-dummies/fonts/fonts.css"><link rel="stylesheet" href="/ai-for-dummies/_astro/full-guide.Dpq4G4E0.css">
<link rel="stylesheet" href="/ai-for-dummies/_astro/full-guide.DFfyKRWU.css"></head> <body> <div class="reading-progress" aria-hidden="true"> <span data-reading-progress-span></span> </div> <script>(function(){const selector = ".reading-progress span";
// ReadingProgress island — passive scroll listener.
// Wire-once guard mirrors CopyPrompt: a page that renders the bar
// twice would otherwise stack two scroll handlers on `window`.
(function () {
if (window.__readingProgressWired) return;
window.__readingProgressWired = true;
const span = document.querySelector(selector);
if (!span) return;
function update() {
const height = document.documentElement.scrollHeight - window.innerHeight;
span.style.transform = `scaleX(${height > 0 ? window.scrollY / height : 0})`;
}
// `{ passive: true }` is non-negotiable. The legacy app.js binds
// this listener passive, and a non-passive scroll handler on the
// top edge of the document is exactly the kind of input latency
// that fails INP. See `.agents/rules/animation.md`.
window.addEventListener('scroll', update, { passive: true });
// Set initial state — important when the user navigates with
// #hash deep links and lands partway down a long page.
update();
})();
})();</script> <main id="full-guide"> <header class="topbar"> <a class="brand" href="#top"><span class="mark">A</span> field guide</a> <nav class="chapter-links" aria-label="Chapter sections"> <a href="#fleet"><span data-language-content="en">01 fleet</span><span data-language-content="pt" hidden>01 frota</span></a><a href="#worktrees"><span data-language-content="en">02 worktrees</span><span data-language-content="pt" hidden>02 worktrees</span></a><a href="#models"><span data-language-content="en">03 models</span><span data-language-content="pt" hidden>03 modelos</span></a><a href="#skills"><span data-language-content="en">04 skills</span><span data-language-content="pt" hidden>04 skills</span></a><a href="#create-skill"><span data-language-content="en">05 create</span><span data-language-content="pt" hidden>05 criar</span></a><a href="#field-kit"><span data-language-content="en">06 field kit</span><span data-language-content="pt" hidden>06 kit de campo</span></a><a href="#hands-on"><span data-language-content="en">07 hands-on</span><span data-language-content="pt" hidden>07 prática</span></a><a href="#verification">08 verify</a> </nav> <div class="topbar-tools"> <a class="skills-review-link" href="/ai-for-dummies/skills-review/">review submissions ↗</a><div class="lang-switch" aria-label="Language" data-language-toggle> <button class="active" data-lang="en" aria-pressed="true">EN</button> <span>/</span> <button data-lang="pt" aria-pressed="false">PT</button> </div> <script type="module">function o(t){const n=t.querySelectorAll("[data-lang]");function l(e){document.documentElement.lang=e==="pt"?"pt-BR":"en",n.forEach(a=>{const u=a.dataset.lang===e;a.classList.toggle("active",u),a.setAttribute("aria-pressed",String(u))}),document.querySelectorAll("[data-language-content]").forEach(a=>{a.hidden=a.dataset.languageContent!==e}),window.dispatchEvent(new CustomEvent("ai-for-dummies:languagechange",{detail:{language:e}}))}function g(e){return e==="pt"?"pt":"en"}n.forEach(e=>{e.addEventListener("click",()=>{const a=g(e.dataset.lang);l(a);try{localStorage.setItem("ai-for-dummies-language",a)}catch{}})});let c="en";try{c=localStorage.getItem("ai-for-dummies-language")||"en"}catch{}l(g(c))}document.querySelectorAll("[data-language-toggle]").forEach(t=>{"requestIdleCallback"in window?window.requestIdleCallback(()=>o(t)):setTimeout(()=>o(t),0)});</script><span class="edition"><span data-language-content="en">AI ENGINEERING <i></i> 01 / 2026</span><span data-language-content="pt" hidden>ENGENHARIA DE IA <i></i> 01 / 2026</span></span> </div> </header> <section class="hero" id="top" data-language-content="en"> <div> <p class="eyebrow"> <span data-language-content="en">A presentation for humans who ship</span><span data-language-content="pt" hidden>Uma apresentação para quem entrega software</span> </p><h1>
AI for<br><em>dummies.</em> </h1><p class="lede"> <span data-language-content="en">You do not need an army of models. You need a system: one mind to frame the work,
several hands to execute it, and a clean boundary between every task.</span> <span data-language-content="pt" hidden>Você não precisa de um exército de modelos. Precisa de um sistema: uma mente para
enquadrar o trabalho, várias mãos para executá-lo e uma fronteira clara entre cada
tarefa.</span> </p> </div><aside class="hero-index"> <span><span data-language-content="en">FIELD NOTE / 001</span><span data-language-content="pt" hidden>NOTA DE CAMPO / 001</span></span><strong><span data-language-content="en">Ship the<br><em>system.</em></span><span data-language-content="pt" hidden>Entregue o<br><em>sistema.</em></span></strong><small><span data-language-content="en">Skills · agents · worktrees · proof</span><span data-language-content="pt" hidden>Skills · agentes · worktrees · evidências</span></small> </aside> </section> <section class="hero" id="top-pt" data-language-content="pt" hidden> <div> <p class="eyebrow">Uma apresentação para quem entrega software</p><h1>
AI for<br><em>dummies.</em> </h1><p class="lede">
Você não precisa de um exército de modelos. Precisa de um sistema: uma mente para
enquadrar o trabalho, várias mãos para executá-lo e uma fronteira clara entre cada tarefa.
</p> </div><aside class="hero-index"> <span>NOTA DE CAMPO / 001</span><strong>Entregue o<br><em>sistema.</em></strong><small>Skills · agentes · worktrees · evidências</small> </aside> </section> <section class="hero-stats" aria-label="Chapter summary" data-language-content="en"> <div> <strong>01</strong><span><span data-language-content="en">strong model<br>for ambiguity</span><span data-language-content="pt" hidden>modelo forte<br>para ambiguidade</span></span> </div><div> <strong>03</strong><span><span data-language-content="en">bounded workers<br>in parallel</span><span data-language-content="pt" hidden>workers delimitados<br>em paralelo</span></span> </div><div> <strong></strong><span><span data-language-content="en">iterations<br>with evidence</span><span data-language-content="pt" hidden>iterações<br>com evidências</span></span> </div><p> <span data-language-content="en">Read this as a route map, not a prompt recipe.</span><span data-language-content="pt" hidden>Leia isto como um mapa de rota, não como uma receita de prompt.</span> </p> </section> <section class="hero-stats" aria-label="Resumo dos capítulos" data-language-content="pt" hidden> <div><strong>01</strong><span>modelo forte<br>para ambiguidade</span></div><div> <strong>03</strong><span>workers delimitados<br>em paralelo</span> </div><div><strong></strong><span>iterações<br>com evidências</span></div><p>
Leia isto como um mapa de rota, não como uma receita de prompt.
</p> </section> <section class="thesis" data-language-content="en"> <div> <span><span data-language-content="en">RULE ZERO</span><span data-language-content="pt" hidden>REGRA ZERO</span></span><strong><span data-language-content="en">Strong model for ambiguity.<br>Light model for bounded work.</span><span data-language-content="pt" hidden>Modelo forte para ambiguidade.<br>Modelo leve para trabalho delimitado.</span></strong> </div><div class="signal" aria-hidden="true"> <b>THINK</b><i></i><i></i><i></i><b>MAKE</b> </div> </section> <section class="thesis" data-language-content="pt" hidden> <div> <span>REGRA ZERO</span><strong>Modelo forte para ambiguidade.<br>Modelo leve para trabalho delimitado.</strong> </div><div class="signal" aria-hidden="true"> <b>THINK</b><i></i><i></i><i></i><b>MAKE</b> </div> </section> <section class="fleet" id="fleet"> <div class="section-label"> <span><span data-language-content="en">A small fleet</span><span data-language-content="pt" hidden>Uma pequena frota</span></span><span><span data-language-content="en">coordination before parallelism</span><span data-language-content="pt" hidden>coordenação antes do paralelismo</span></span> </div><div class="fleet-grid" data-astro-cid-ql7sfpu4> <article class="captain" data-astro-cid-ql7sfpu4> <span class="captain-eyebrow" data-astro-cid-ql7sfpu4> <span data-language-content="en" data-astro-cid-ql7sfpu4>ORCHESTRATOR</span> <span data-language-content="pt" hidden data-astro-cid-ql7sfpu4> ORQUESTRADOR </span> </span> <h2 data-language-content="en" data-astro-cid-ql7sfpu4>Decides what<br />needs to happen.</h2> <h2 data-language-content="pt" hidden data-astro-cid-ql7sfpu4>Decide o que<br />precisa acontecer.</h2> <code data-astro-cid-ql7sfpu4>Opus / reasoning</code> </article> <div class="arrow" aria-hidden="true" data-astro-cid-ql7sfpu4></div> <div class="workers" role="group" aria-label="Worker agents" data-astro-cid-ql7sfpu4> <button class="worker-card active" data-worker="ui" aria-pressed="true" data-astro-cid-ql7sfpu4> <span data-astro-cid-ql7sfpu4> UI </span> <strong data-astro-cid-ql7sfpu4> <span data-language-content="en" data-astro-cid-ql7sfpu4>Component and visual states</span> <span data-language-content="pt" hidden data-astro-cid-ql7sfpu4> Componentes e estados visuais </span> </strong> <code data-astro-cid-ql7sfpu4>agent/ui</code> </button><button class="worker-card" data-worker="tests" aria-pressed="false" data-astro-cid-ql7sfpu4> <span data-astro-cid-ql7sfpu4> TEST </span> <strong data-astro-cid-ql7sfpu4> <span data-language-content="en" data-astro-cid-ql7sfpu4>Acceptance cases</span> <span data-language-content="pt" hidden data-astro-cid-ql7sfpu4> Casos de aceitação </span> </strong> <code data-astro-cid-ql7sfpu4>agent/tests</code> </button><button class="worker-card" data-worker="docs" aria-pressed="false" data-astro-cid-ql7sfpu4> <span data-astro-cid-ql7sfpu4> DOCS </span> <strong data-astro-cid-ql7sfpu4> <span data-language-content="en" data-astro-cid-ql7sfpu4>Guide and examples</span> <span data-language-content="pt" hidden data-astro-cid-ql7sfpu4> Guia e exemplos </span> </strong> <code data-astro-cid-ql7sfpu4>agent/docs</code> </button> </div> </div> <div class="worker-detail" id="worker-detail" aria-live="polite"> <span>Interface worker</span><strong>Receives: component contract + visual states</strong><small>Returns: focused diff + viewport evidence</small> </div><p class="caption"> <span data-language-content="en">The orchestrator preserves intent, writes small contracts, and gathers results that can
be verified. It does not need to type every line.</span><span data-language-content="pt" hidden>O orquestrador preserva a intenção, escreve pequenos contratos e reúne resultados
verificáveis. Ele não precisa digitar cada linha.</span> </p> </section> <section class="failure-map"> <div class="section-label"> <span><span data-language-content="en">Why the boundary matters</span><span data-language-content="pt" hidden>Por que a fronteira importa</span></span><span><span data-language-content="en">one vague task / three predictable failures</span><span data-language-content="pt" hidden>uma tarefa vaga / três falhas previsíveis</span></span> </div><div class="failure-grid"> <article> <span>01</span><strong><span data-language-content="en">Context soup</span><span data-language-content="pt" hidden>Sopa de contexto</span></strong><p> <span data-language-content="en">Every worker reads everything. Nobody knows which facts are load-bearing.</span><span data-language-content="pt" hidden>Cada worker lê tudo. Ninguém sabe quais fatos são essenciais.</span> </p> </article><article> <span>02</span><strong><span data-language-content="en">Branch collision</span><span data-language-content="pt" hidden>Colisão de branches</span></strong><p> <span data-language-content="en">Two agents touch the same checkout. The fastest path becomes conflict resolution.</span><span data-language-content="pt" hidden>Dois agentes usam o mesmo checkout. O caminho mais rápido vira resolução de
conflitos.</span> </p> </article><article> <span>03</span><strong><span data-language-content="en">Confident drift</span><span data-language-content="pt" hidden>Desvio confiante</span></strong><p> <span data-language-content="en">The diff is polished, but no one checks whether it solved the original problem.</span><span data-language-content="pt" hidden>O diff parece ótimo, mas ninguém verifica se resolveu o problema original.</span> </p> </article> </div> </section> <section class="workflow" aria-labelledby="workflow-title"> <div class="copy"> <p class="eyebrow"> <span data-language-content="en">The subagent loop</span><span data-language-content="pt" hidden>O ciclo de subagentes</span> </p><h2 id="workflow-title"> <span data-language-content="en">Click a phase.<br><em>See the handoff.</em></span><span data-language-content="pt" hidden>Clique em uma fase.<br><em>Veja a passagem.</em></span> </h2><!-- The legacy PT render paints this paragraph twice; preserve that output. --> <p> <span data-language-content="en">Delegation means moving one bounded task into a smaller context—not giving away
responsibility.</span><span data-language-content="pt" hidden>Delegar é mover uma tarefa delimitada para um contexto menor — não abrir mão da
responsabilidade.</span> </p> </div><div class="phase-tabs" role="tablist" aria-label="Workflow phases" data-astro-cid-bnqeb2kd> <button class="phase-tab active" data-phase="plan" role="tab" aria-selected="true" data-astro-cid-bnqeb2kd> <b data-astro-cid-bnqeb2kd>01</b> PLAN </button><button class="phase-tab" data-phase="build" role="tab" aria-selected="false" data-astro-cid-bnqeb2kd> <b data-astro-cid-bnqeb2kd>02</b> BUILD </button><button class="phase-tab" data-phase="review" role="tab" aria-selected="false" data-astro-cid-bnqeb2kd> <b data-astro-cid-bnqeb2kd>03</b> REVIEW </button> </div> <article class="phase-panel" id="phase-panel" aria-live="polite" data-astro-cid-bnqeb2kd> <div class="phase-meta" data-astro-cid-bnqeb2kd> <span data-astro-cid-bnqeb2kd> OPUS / REASONING </span> <small data-astro-cid-bnqeb2kd> context: isolated </small> </div> <h3 data-astro-cid-bnqeb2kd> Turn ambiguity into work </h3> <p data-astro-cid-bnqeb2kd> Inspect the repository, choose the architecture, split the request, and write acceptance criteria. </p> <code data-astro-cid-bnqeb2kd>plan → decompose → define acceptance</code> </article> </section> <section class="handoff"> <div class="section-label"> <span><span data-language-content="en">What crosses contexts</span><span data-language-content="pt" hidden>O que atravessa contextos</span></span><span><span data-language-content="en">brief → diff → evidence</span><span data-language-content="pt" hidden>brief → diff → evidência</span></span> </div><table class="handoff-table" data-astro-cid-wb7dc3qx> <thead data-astro-cid-wb7dc3qx> <tr data-astro-cid-wb7dc3qx> <th data-astro-cid-wb7dc3qx> <span data-language-content="en" data-astro-cid-wb7dc3qx>Package</span> <span data-language-content="pt" hidden data-astro-cid-wb7dc3qx> Pacote </span> </th> <th data-astro-cid-wb7dc3qx> <span data-language-content="en" data-astro-cid-wb7dc3qx>Contains</span> <span data-language-content="pt" hidden data-astro-cid-wb7dc3qx> Contém </span> </th> <th data-astro-cid-wb7dc3qx> <span data-language-content="en" data-astro-cid-wb7dc3qx>Why it matters</span> <span data-language-content="pt" hidden data-astro-cid-wb7dc3qx> Por que importa </span> </th> </tr> </thead> <tbody data-astro-cid-wb7dc3qx> <tr data-astro-cid-wb7dc3qx> <th scope="row" data-astro-cid-wb7dc3qx> Brief </th> <td data-astro-cid-wb7dc3qx> goal, files, boundaries </td> <td data-astro-cid-wb7dc3qx> stops the worker inventing the problem </td> </tr><tr data-astro-cid-wb7dc3qx> <th scope="row" data-astro-cid-wb7dc3qx> Worktree </th> <td data-astro-cid-wb7dc3qx> branch and isolated checkout </td> <td data-astro-cid-wb7dc3qx> parallel edits do not collide </td> </tr><tr data-astro-cid-wb7dc3qx> <th scope="row" data-astro-cid-wb7dc3qx> Checks </th> <td data-astro-cid-wb7dc3qx> tests, build, criteria </td> <td data-astro-cid-wb7dc3qx> turns “looks good” into evidence </td> </tr><tr data-astro-cid-wb7dc3qx> <th scope="row" data-astro-cid-wb7dc3qx> Diff </th> <td data-astro-cid-wb7dc3qx> small, reviewable change </td> <td data-astro-cid-wb7dc3qx> integration and discard stay cheap </td> </tr> </tbody> </table> </section> <section class="worktrees" id="worktrees"> <div class="worktree-intro"> <p class="eyebrow"> <span data-language-content="en">Git worktrees</span><span data-language-content="pt" hidden>Git worktrees</span> </p><h2> <span data-language-content="en">One branch<br>per <em>hand.</em></span><span data-language-content="pt" hidden>Uma branch<br>por <em>mão.</em></span> </h2><p> <span data-language-content="en">A worktree is another directory linked to the same repository. Each agent gets its own
checkout and index; history remains shared.</span><span data-language-content="pt" hidden>Um worktree é outro diretório ligado ao mesmo repositório. Cada agente recebe seu
próprio checkout e índice; o histórico continua compartilhado.</span> </p><p class="interaction-hint"> <span data-language-content="en">Select a node to inspect its checkout, owner, and next action.</span><span data-language-content="pt" hidden>Selecione um nó para inspecionar checkout, responsável e próxima ação.</span> </p> </div><div class="tree-lab"> <div class="tree-toolbar"> <span><span data-language-content="en">repository topology</span><span data-language-content="pt" hidden>topologia do repositório</span></span><span class="tree-live"><span data-language-content="en"><i></i> 4 checkouts</span><span data-language-content="pt" hidden><i></i> 4 checkouts</span></span> </div><div class="tree-stage" role="tree" aria-label="Repository worktree topology" data-astro-cid-lsutp3lb> <svg viewBox="0 0 760 330" preserveAspectRatio="none" aria-hidden="true" data-astro-cid-lsutp3lb> <path class="tree-edge trunk" d="M380 48 V118" data-astro-cid-lsutp3lb></path> <path class="tree-edge" d="M380 118 C380 170 110 150 110 224" data-astro-cid-lsutp3lb></path> <path class="tree-edge" d="M380 118 V224" data-astro-cid-lsutp3lb></path> <path class="tree-edge" d="M380 118 C380 170 650 150 650 224" data-astro-cid-lsutp3lb></path> </svg> <button class="tree-node root active" data-tree="main" role="treeitem" aria-selected="true" data-astro-cid-lsutp3lb> <span data-astro-cid-lsutp3lb> <span data-language-content="en" data-astro-cid-lsutp3lb>ROOT</span> <span data-language-content="pt" hidden data-astro-cid-lsutp3lb> RAIZ </span> </span> <strong data-astro-cid-lsutp3lb>main</strong> <small data-astro-cid-lsutp3lb> <span data-language-content="en" data-astro-cid-lsutp3lb>● clean</span> <span data-language-content="pt" hidden data-astro-cid-lsutp3lb> ● limpo </span> </small> </button> <button class="tree-node branch ui" data-tree="ui" role="treeitem" aria-selected="false" data-astro-cid-lsutp3lb> <span data-astro-cid-lsutp3lb> <span data-language-content="en" data-astro-cid-lsutp3lb>UI AGENT</span> <span data-language-content="pt" hidden data-astro-cid-lsutp3lb> AGENTE DE UI </span> </span> <strong data-astro-cid-lsutp3lb>agent/ui</strong> <small data-astro-cid-lsutp3lb> <span data-language-content="en" data-astro-cid-lsutp3lb>3 files · working</span> <span data-language-content="pt" hidden data-astro-cid-lsutp3lb> 3 arquivos · trabalhando </span> </small> </button><button class="tree-node branch tests" data-tree="tests" role="treeitem" aria-selected="false" data-astro-cid-lsutp3lb> <span data-astro-cid-lsutp3lb> <span data-language-content="en" data-astro-cid-lsutp3lb>TEST AGENT</span> <span data-language-content="pt" hidden data-astro-cid-lsutp3lb> AGENTE DE TESTES </span> </span> <strong data-astro-cid-lsutp3lb>agent/tests</strong> <small data-astro-cid-lsutp3lb> <span data-language-content="en" data-astro-cid-lsutp3lb>8 checks · ready</span> <span data-language-content="pt" hidden data-astro-cid-lsutp3lb> 8 verificações · pronto </span> </small> </button><button class="tree-node branch docs" data-tree="docs" role="treeitem" aria-selected="false" data-astro-cid-lsutp3lb> <span data-astro-cid-lsutp3lb> <span data-language-content="en" data-astro-cid-lsutp3lb>DOCS AGENT</span> <span data-language-content="pt" hidden data-astro-cid-lsutp3lb> AGENTE DE DOCS </span> </span> <strong data-astro-cid-lsutp3lb>agent/docs</strong> <small data-astro-cid-lsutp3lb> <span data-language-content="en" data-astro-cid-lsutp3lb>2 pages · review</span> <span data-language-content="pt" hidden data-astro-cid-lsutp3lb> 2 páginas · revisão </span> </small> </button> </div> <article class="tree-detail" id="tree-detail" aria-live="polite"> <div><span>OWNER</span><strong>Orchestrator</strong></div><div> <span>CHECKOUT</span><strong>./project</strong> </div><p>Shared history and integration point. Workers never edit here.</p><code>git worktree list</code> </article> </div> </section> <section class="routing"> <div> <p class="eyebrow"> <span data-language-content="en">Model routing</span><span data-language-content="pt" hidden>Roteamento de modelos</span> </p><h2> <span data-language-content="en">Do not pay for<br>reasoning where<br>you need <em>rhythm.</em></span><span data-language-content="pt" hidden>Não pague por<br>raciocínio onde precisa<br>de <em>ritmo.</em></span> </h2><p class="interaction-hint"> <span data-language-content="en">Choose a job to see why the model profile changes.</span><span data-language-content="pt" hidden>Escolha um trabalho para entender por que o perfil do modelo muda.</span> </p> </div><div class="route-console"> <div class="route-table" data-astro-cid-xg74pkf4> <div class="head" data-astro-cid-xg74pkf4> <span data-astro-cid-xg74pkf4> <span data-language-content="en" data-astro-cid-xg74pkf4>Work</span> <span data-language-content="pt" hidden data-astro-cid-xg74pkf4> Trabalho </span> </span> <span data-astro-cid-xg74pkf4> <span data-language-content="en" data-astro-cid-xg74pkf4>Profile</span> <span data-language-content="pt" hidden data-astro-cid-xg74pkf4> Perfil </span> </span> <span data-astro-cid-xg74pkf4> <span data-language-content="en" data-astro-cid-xg74pkf4>Prompt shape</span> <span data-language-content="pt" hidden data-astro-cid-xg74pkf4> Formato do prompt </span> </span> </div> <button class="route-row active" data-route="plan" aria-pressed="true" data-astro-cid-xg74pkf4> <strong data-astro-cid-xg74pkf4> <span data-language-content="en" data-astro-cid-xg74pkf4>Plan</span> <span data-language-content="pt" hidden data-astro-cid-xg74pkf4> Planejar </span> </strong> <b data-astro-cid-xg74pkf4> strong / broad </b> <small data-astro-cid-xg74pkf4> What changes? What can break? </small> </button><button class="route-row" data-route="build" aria-pressed="false" data-astro-cid-xg74pkf4> <strong data-astro-cid-xg74pkf4> <span data-language-content="en" data-astro-cid-xg74pkf4>Build</span> <span data-language-content="pt" hidden data-astro-cid-xg74pkf4> Construir </span> </strong> <b data-astro-cid-xg74pkf4> fast / focused </b> <small data-astro-cid-xg74pkf4> Implement this slice. Run these checks. </small> </button><button class="route-row" data-route="explore" aria-pressed="false" data-astro-cid-xg74pkf4> <strong data-astro-cid-xg74pkf4> <span data-language-content="en" data-astro-cid-xg74pkf4>Explore</span> <span data-language-content="pt" hidden data-astro-cid-xg74pkf4> Explorar </span> </strong> <b data-astro-cid-xg74pkf4> read-only / light </b> <small data-astro-cid-xg74pkf4> Find where this contract is used. </small> </button><button class="route-row" data-route="review" aria-pressed="false" data-astro-cid-xg74pkf4> <strong data-astro-cid-xg74pkf4> <span data-language-content="en" data-astro-cid-xg74pkf4>Review</span> <span data-language-content="pt" hidden data-astro-cid-xg74pkf4> Revisar </span> </strong> <b data-astro-cid-xg74pkf4> independent </b> <small data-astro-cid-xg74pkf4> Does the diff satisfy the brief? </small> </button> </div> <article class="route-detail" id="route-detail" aria-live="polite"> <div class="route-meter"><span style="--score:92%"></span></div><div> <small>REASONING LOAD · 92</small><strong>High ambiguity</strong><p>Architecture and decomposition have a wide error surface. Spend reasoning here.</p> </div> </article> </div> </section> <section class="model-gearbox" id="models"> <div class="section-label"> <span><span data-language-content="en">Model gearbox</span><span data-language-content="pt" hidden>Câmbio de modelos</span></span><span><span data-language-content="en">capability tier × thinking effort</span><span data-language-content="pt" hidden>nível de capacidade × esforço de raciocínio</span></span> </div> <div class="gearbox-intro"> <div> <p class="eyebrow"> <span data-language-content="en">Two separate knobs</span><span data-language-content="pt" hidden>Dois controles separados</span> </p> <h2> <span data-language-content="en">Choose the engine.<br>Then choose the <em>gear.</em></span><span data-language-content="pt" hidden>Escolha o motor.<br>Depois escolha a <em>marcha.</em></span> </h2> </div> <p> <span data-language-content="en">A stronger model changes the capability ceiling. Higher reasoning effort gives that
model more room to work. Start with the lightest combination that passes your real
checks, then move one knob at a time.</span><span data-language-content="pt" hidden>Um modelo mais forte muda o teto de capacidade. Mais esforço de raciocínio dá mais
espaço para esse modelo trabalhar. Comece com a combinação mais leve que passa seus
checks e mova um controle por vez.</span> </p> </div> <div class="gearbox"> <div class="provider-tabs" role="tablist" aria-label="Model providers"> <button class="active" data-model-provider="openai" role="tab" aria-selected="true">OPENAI</button><button data-model-provider="claude" role="tab" aria-selected="false">CLAUDE</button><button data-model-provider="gemini" role="tab" aria-selected="false">GEMINI</button> </div><article class="provider-detail" id="provider-detail" aria-live="polite"> <header> <span>OpenAI</span><a href="https://developers.openai.com/api/docs/guides/latest-model" target="_blank" rel="noopener">OFFICIAL SOURCE ↗</a> </header><h3>Sol · Terra · Luna</h3><p>GPT-5.6 separates capability tier from reasoning effort. Sol is flagship, Terra balances performance and cost, and Luna targets efficient high-volume work.</p> </article><div class="effort-rail" role="tablist" aria-label="Reasoning effort"> <span><span data-language-content="en">REASONING / THINKING</span><span data-language-content="pt" hidden>RACIOCÍNIO / PENSAMENTO</span></span> <button data-effort="low" role="tab" aria-selected="false"><b><span data-language-content="en">LOW</span><span data-language-content="pt" hidden>BAIXO</span></b><small><span data-language-content="en">bounded + fast</span><span data-language-content="pt" hidden>delimitado + rápido</span></small></button><button class="active" data-effort="medium" role="tab" aria-selected="true"><b><span data-language-content="en">MEDIUM</span><span data-language-content="pt" hidden>MÉDIO</span></b><small><span data-language-content="en">default start</span><span data-language-content="pt" hidden>ponto inicial</span></small></button><button data-effort="high" role="tab" aria-selected="false"><b><span data-language-content="en">HIGH</span><span data-language-content="pt" hidden>ALTO</span></b><small><span data-language-content="en">complex + costly</span><span data-language-content="pt" hidden>complexo + custoso</span></small></button> </div><article class="effort-detail" id="effort-detail" aria-live="polite"> <span>MEDIUM</span><p>Balanced starting point for normal implementation, tests, and review. Measure before moving up.</p><code>reasoning: { effort: &quot;medium&quot; }</code> </article> </div> <div class="gearbox-rule"> <span><span data-language-content="en">ROUTING RULE</span><span data-language-content="pt" hidden>REGRA DE ROTEAMENTO</span></span> <strong><span data-language-content="en">Use strong models for ambiguity and judgment. Use lighter models for bounded execution.
Raise effort only when evaluation shows a gain.</span><span data-language-content="pt" hidden>Use modelos fortes para ambiguidade e julgamento. Use modelos leves para execução
delimitada. Aumente o esforço apenas quando a avaliação mostrar ganho.</span></strong> </div> </section> <section class="skills" id="skills"> <div> <p class="eyebrow"> <span data-language-content="en">Skills</span><span data-language-content="pt" hidden>Uma skill é um procedimento reutilizável. Ela pode carregar instruções, referências,
scripts e assets. Não é memória mágica e não substitui critérios de aceitação.</span> </p><h2> <span data-language-content="en">Write the right way<br><em>once.</em></span><span data-language-content="pt" hidden>Escreva do jeito certo<br><em>uma vez.</em></span> </h2><p> <span data-language-content="en">A skill is a reusable procedure. It can carry instructions, references, scripts, and
assets. It is not magical memory, and it does not replace acceptance criteria.</span> <span data-language-content="pt" hidden>Uma skill é um procedimento reutilizável. Ela pode carregar instruções, referências,
scripts e assets. Não é memória mágica e não substitui critérios de aceitação.</span> </p><div class="skill-principles"> <span data-language-content="en">01 / trigger clearly</span><span data-language-content="pt" hidden>01 / defina o gatilho</span> <span data-language-content="en">02 / load detail on demand</span><span data-language-content="pt" hidden>02 / carregue detalhes sob demanda</span> <span data-language-content="en">03 / return evidence</span><span data-language-content="pt" hidden>03 / devolva evidências</span> </div> </div><div class="skill-explorer"> <div class="skill-package" role="tree" aria-label="Skill package files" data-astro-cid-fhsz22do> <span class="skill-package-label" data-astro-cid-fhsz22do> <span data-language-content="en" data-astro-cid-fhsz22do>SKILL PACKAGE</span> <span data-language-content="pt" hidden data-astro-cid-fhsz22do> PACOTE DE SKILL </span> </span> <button class="skill-package-row active" data-skill-file="skill" role="treeitem" aria-selected="true" data-astro-cid-fhsz22do> <code data-astro-cid-fhsz22do>SKILL.md</code> <small data-astro-cid-fhsz22do> procedure and limits </small> </button><button class="skill-package-row" data-skill-file="references" role="treeitem" aria-selected="false" data-astro-cid-fhsz22do> <code data-astro-cid-fhsz22do>references/</code> <small data-astro-cid-fhsz22do> facts to consult </small> </button><button class="skill-package-row" data-skill-file="scripts" role="treeitem" aria-selected="false" data-astro-cid-fhsz22do> <code data-astro-cid-fhsz22do>scripts/</code> <small data-astro-cid-fhsz22do> repeatable checks </small> </button><button class="skill-package-row" data-skill-file="assets" role="treeitem" aria-selected="false" data-astro-cid-fhsz22do> <code data-astro-cid-fhsz22do>assets/</code> <small data-astro-cid-fhsz22do> templates and examples </small> </button> </div> <article class="skill-detail" id="skill-detail" aria-live="polite"> <span></span><div> <strong>SKILL.md</strong><p>Trigger, procedure, constraints, and the exact evidence the agent must return.</p><small>select another file to explore</small> </div> </article> </div><pre><code>name: review-ui · check focus, mobile, reduced motion · run verification · return evidence</code></pre> </section> <section class="skill-builder" id="create-skill"> <div class="section-label"> <span><span data-language-content="en">Create a skill</span><span data-language-content="pt" hidden>Criar uma skill</span></span><span><span data-language-content="en">repeatable pain → reusable judgment</span><span data-language-content="pt" hidden>atrito repetido → julgamento reutilizável</span></span> </div><div class="builder-intro"> <div> <p class="eyebrow"> <span data-language-content="en">The skill forge</span><span data-language-content="pt" hidden>A forja de skills</span> </p><h2> <span data-language-content="en">Teach the decision.<br>Keep the context <em>light.</em></span><span data-language-content="pt" hidden>Ensine a decisão.<br>Mantenha o contexto <em>leve.</em></span> </h2> </div><p> <span data-language-content="en">Do not package everything you know. Capture the non-obvious choices that repeatedly
improve an outcome, then prove the skill changes behavior.</span><span data-language-content="pt" hidden>Não empacote tudo o que você sabe. Capture as escolhas não óbvias que melhoram
resultados repetidamente e prove que a skill muda o comportamento.</span> </p> </div><div class="builder-workbench"> <nav class="builder-steps" role="tablist" aria-label="Skill creation workflow"> <button class="active" data-skill-step="observe" role="tab" aria-selected="true"> <b>01</b> <span> <span data-language-content="en">Observe</span> <span data-language-content="pt" hidden> Observar </span> </span> <small> <span data-language-content="en">find repeated friction</span> <span data-language-content="pt" hidden> encontre atrito repetido </span> </small> </button><button data-skill-step="trigger" role="tab" aria-selected="false"> <b>02</b> <span> <span data-language-content="en">Define trigger</span> <span data-language-content="pt" hidden> Definir gatilho </span> </span> <small> <span data-language-content="en">route precisely</span> <span data-language-content="pt" hidden> roteie com precisão </span> </small> </button><button data-skill-step="scaffold" role="tab" aria-selected="false"> <b>03</b> <span> <span data-language-content="en">Choose anatomy</span> <span data-language-content="pt" hidden> Escolher anatomia </span> </span> <small> <span data-language-content="en">only needed files</span> <span data-language-content="pt" hidden> apenas arquivos necessários </span> </small> </button><button data-skill-step="write" role="tab" aria-selected="false"> <b>04</b> <span> <span data-language-content="en">Write guidance</span> <span data-language-content="pt" hidden> Escrever orientação </span> </span> <small> <span data-language-content="en">decisions, not trivia</span> <span data-language-content="pt" hidden> decisões, não trivialidades </span> </small> </button><button data-skill-step="validate" role="tab" aria-selected="false"> <b>05</b> <span> <span data-language-content="en">Validate</span> <span data-language-content="pt" hidden> Validar </span> </span> <small> <span data-language-content="en">test real behavior</span> <span data-language-content="pt" hidden> teste comportamento real </span> </small> </button> </nav><article class="builder-detail" id="builder-detail" aria-live="polite"> <header> <span>01</span><small>QUESTION</small> </header><h3>Start from repeated friction</h3><blockquote> Which non-obvious decision keeps being rediscovered? </blockquote><div class="builder-action"> <span>ACTION</span><p>Collect two or three realistic requests. Separate durable judgment from one projects temporary details.</p> </div><footer> <div> <span>ARTIFACT</span><strong>A narrow capability and concrete examples.</strong> </div><div> <span>PROOF</span><strong>Without the skill, agents repeatedly make the same avoidable mistake.</strong> </div> </footer> </article><aside class="builder-artifact"> <div class="artifact-head"> <span><span data-language-content="en">OUTPUT / SKILL PACKAGE</span><span data-language-content="pt" hidden>SAÍDA / PACOTE DE SKILL</span></span><i></i> </div><pre aria-label="Example skill structure"><code>review-ui/<br>├── SKILL.md<br>├── agents/<br>│ └── openai.yaml<br>├── references/<br>│ └── accessibility.md<br>└── scripts/<br> └── verify.mjs</code></pre><div class="artifact-command"> <span><span data-language-content="en">VALIDATE</span><span data-language-content="pt" hidden>VALIDAR</span></span><code>quick_validate.py ./review-ui</code> </div> </aside> </div><div class="builder-loop"> <span><span data-language-content="en">AFTER REAL USE</span><span data-language-content="pt" hidden>APÓS USO REAL</span></span><div data-language-content="en"> <b>observe failure</b><i></i><b>sharpen one rule</b><i></i><b>retest behavior</b><i></i><b>keep it narrow</b> </div><div data-language-content="pt" hidden> <b>observar falha</b><i></i><b>refinar uma regra</b><i></i><b>retestar comportamento</b><i></i><b>manter estreita</b> </div> </div> </section> <section class="skill-catalog" id="field-kit"> <div class="section-label"> <span><span data-language-content="en">Common skills</span><span data-language-content="pt" hidden>Skills comuns</span></span><span><span data-language-content="en">choose behavior before model</span><span data-language-content="pt" hidden>escolha o comportamento antes do modelo</span></span> </div><div class="catalog-intro"> <div> <p class="eyebrow"> <span data-language-content="en">The field kit</span><span data-language-content="pt" hidden>O kit de campo</span> </p> <h2> <span data-language-content="en">Different jobs.<br>Different <em>instincts.</em></span><span data-language-content="pt" hidden>Trabalhos diferentes.<br>Instintos <em>diferentes.</em></span> </h2> </div> <p> <span data-language-content="en">A skill changes how an agent approaches work. Some shape communication. Others enforce
research, debugging, review, or completion discipline. Select one to inspect its
operating rule and verified source.</span><span data-language-content="pt" hidden>Uma skill muda como o agente aborda o trabalho. Algumas moldam a comunicação. Outras
impõem pesquisa, diagnóstico, revisão ou disciplina de conclusão. Selecione uma para
inspecionar sua regra operacional.</span> </p> </div><div class="skill-deck"> <div class="skill-index" role="tablist" aria-label="Common agent skills"> <button class="active" data-common-skill="ponytail" role="tab" aria-selected="true"> <span> <span data-language-content="en">SIMPLIFY</span> <span data-language-content="pt" hidden> SIMPLIFICAR </span> </span> <strong>ponytail-lite</strong> <small> <span data-language-content="en">minimum code that holds</span> <span data-language-content="pt" hidden> código mínimo que funciona </span> </small> </button><button data-common-skill="caveman" role="tab" aria-selected="false"> <span> <span data-language-content="en">COMMUNICATE</span> <span data-language-content="pt" hidden> COMUNICAR </span> </span> <strong>caveman</strong> <small> <span data-language-content="en">signal without filler</span> <span data-language-content="pt" hidden> sinal sem excesso </span> </small> </button><button data-common-skill="unlazy" role="tab" aria-selected="false"> <span> <span data-language-content="en">COMPLETE</span> <span data-language-content="pt" hidden> CONCLUIR </span> </span> <strong>unlazy</strong> <small> <span data-language-content="en">gates and evidence</span> <span data-language-content="pt" hidden> gates e evidências </span> </small> </button><button data-common-skill="research" role="tab" aria-selected="false"> <span> <span data-language-content="en">INVESTIGATE</span> <span data-language-content="pt" hidden> INVESTIGAR </span> </span> <strong>research</strong> <small> <span data-language-content="en">primary sources first</span> <span data-language-content="pt" hidden> fontes primárias primeiro </span> </small> </button><button data-common-skill="debug" role="tab" aria-selected="false"> <span> <span data-language-content="en">DIAGNOSE</span> <span data-language-content="pt" hidden> DIAGNOSTICAR </span> </span> <strong>diagnosing-bugs</strong> <small> <span data-language-content="en">tight feedback loop</span> <span data-language-content="pt" hidden> ciclo curto de feedback </span> </small> </button><button data-common-skill="review" role="tab" aria-selected="false"> <span> <span data-language-content="en">REVIEW</span> <span data-language-content="pt" hidden> REVISAR </span> </span> <strong>code-review</strong> <small> <span data-language-content="en">standards × spec</span> <span data-language-content="pt" hidden> padrões × especificação </span> </small> </button><button data-common-skill="tokens" role="tab" aria-selected="false"> <span> <span data-language-content="en">ECONOMIZE</span> <span data-language-content="pt" hidden> ECONOMIZAR </span> </span> <strong>token-saver</strong> <small> <span data-language-content="en">compress noisy output</span> <span data-language-content="pt" hidden> comprima saídas ruidosas </span> </small> </button> </div><article class="common-skill-detail" id="common-skill-detail" aria-live="polite"> <header> <span>01</span><small>SIMPLIFICATION INSTINCT</small> </header><h3>ponytail-lite</h3><blockquote> Stop at the first rung that holds. </blockquote><div class="common-skill-notes"> <div> <span>WHEN TO USE</span><p>Use when a request invites frameworks, dependencies, abstractions, or speculative scaffolding. It checks reuse, standard library, and native platform features before adding code.</p> </div><div> <span>EXAMPLE</span><p>Date picker? Start with &amp;lt;input type=&quot;date&quot;&amp;gt;.</p> </div><div> <span>WATCH OUT</span><p>Never simplify away security, accessibility, validation, or real edge cases.</p> </div> </div><a class="skill-source" href="https://github.com/ilindaniel/ponytail-lite/blob/e7b42dc2d384a702240dea4d52a7bf5530b821b6/AGENTS.md" target="_blank" rel="noopener">GITHUB SOURCE ↗</a> </article> </div><div class="skill-loadout"> <span data-language-content="en">ONE PRACTICAL LOADOUT</span><span data-language-content="pt" hidden>UM LOADOUT PRÁTICO</span> <div data-language-content="en"> <b>PLAN</b> unlazy <i></i> <b>BUILD</b> ponytail-lite <i></i> <b>DEBUG</b> diagnosing-bugs <i></i> <b>REPORT</b> caveman
</div> <div data-language-content="pt" hidden> <b>PLANEJAR</b> unlazy <i></i> <b>CONSTRUIR</b> ponytail-lite <i></i> <b>DIAGNOSTICAR</b> diagnosing-bugs <i></i> <b>REPORTAR</b> caveman
</div> </div><article class="install-skills"> <header> <div> <span><span data-language-content="en">INSTALL PACK</span><span data-language-content="pt" hidden>PACOTE DE INSTALAÇÃO</span></span><strong><span data-language-content="en">Ask your coding agent to verify, install, and validate the skills.</span><span data-language-content="pt" hidden>Peça ao seu agente para verificar, instalar e validar as skills.</span></strong> </div><button class="copy-prompt-button" data-copy-target="prompt-install-skills" data-copy-prompt-button type="button" data-astro-cid-um2hulj3> <span data-copy-prompt-label data-astro-cid-um2hulj3>COPY</span> <i aria-hidden="true" data-astro-cid-um2hulj3></i> </button> <script>
// CopyPrompt island — click handler.
// Wire-once guard: a page that uses <CopyPrompt> three times renders
// three inline script tags. Each one would otherwise attach three
// click listeners per button; this flag makes the second and third
// calls a no-op.
(function () {
if (window.__copyPromptWired) return;
window.__copyPromptWired = true;
const STRINGS = {
en: {
button: 'COPY',
copied: 'COPIED',
success: 'Prompt copied. Paste it into a fresh agent session.',
failure: 'Copy unavailable. Select the text manually.',
},
pt: {
button: 'COPIAR',
copied: 'COPIADO',
success: 'Prompt copiado. Cole em uma nova sessão de agente.',
failure: 'Não foi possível copiar. Selecione o texto manualmente.',
},
};
function currentLang() {
return document.documentElement.lang === 'pt-BR' ? 'pt' : 'en';
}
function labels() {
return STRINGS[currentLang()];
}
function setStatus(copied) {
const status = document.querySelector('#copy-status');
if (!status) return;
const l = labels();
status.textContent = copied ? l.success : l.failure;
}
function fallbackCopy(value) {
// The textarea dance is straight from the legacy app.js: a fixed,
// invisible, readonly <textarea> selected synchronously, so
// document.execCommand('copy') sees a real selection. Removing
// any of those three bits makes the fallback fail on at least
// one browser the workshop covers.
const helper = document.createElement('textarea');
helper.value = value;
helper.setAttribute('readonly', '');
helper.style.position = 'fixed';
helper.style.opacity = '0';
document.body.appendChild(helper);
helper.select();
let copied = false;
try {
copied = document.execCommand('copy');
} catch {
copied = false;
}
helper.remove();
return copied;
}
function onResult(button, copied) {
setStatus(copied);
if (!copied) return;
const l = labels();
const span = button.querySelector('span');
if (span) span.textContent = l.copied;
button.classList.add('copied');
// 1800ms matches the legacy copyPrompt. Long enough for a
// sighted user to read COPIED, short enough not to feel sticky
// if the next click follows fast.
window.setTimeout(function () {
button.classList.remove('copied');
if (span) span.textContent = labels().button;
}, 1800);
}
function copyPrompt(button) {
const id = button.dataset.copyTarget;
if (!id) return;
const target = document.querySelector('#' + id);
if (!target) return;
const visible = target.querySelector(':scope > [data-language-content]:not([hidden])');
const value = visible?.textContent || target.textContent || '';
if (
typeof navigator !== 'undefined' &&
navigator.clipboard &&
typeof navigator.clipboard.writeText === 'function'
) {
// navigator.clipboard.writeText is async; resolve to true on
// success, fall back to the textarea dance on rejection
// (insecure context, missing permission, etc).
navigator.clipboard.writeText(value).then(
function () {
onResult(button, true);
},
function () {
onResult(button, fallbackCopy(value));
},
);
return;
}
onResult(button, fallbackCopy(value));
}
function syncLabels() {
const l = labels();
const buttons = document.querySelectorAll('[data-copy-prompt-button]');
for (let i = 0; i < buttons.length; i++) {
const btn = buttons[i];
// Mid-feedback buttons (1800ms COPIED state) keep their
// swapped label until the timer fires; otherwise the toggle
// would visibly flicker the COPIED text back to the default.
if (btn.classList.contains('copied')) continue;
const span = btn.querySelector('span');
if (span) span.textContent = l.button;
}
}
const buttons = document.querySelectorAll('[data-copy-prompt-button]');
for (let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener(
'click',
(function (button) {
return function () {
copyPrompt(button);
};
})(buttons[i]),
);
}
// Pick up external language changes (task 15c's toggle) without
// owning the toggle itself. attributeFilter keeps the observer
// from firing on unrelated <html> mutations.
if (typeof MutationObserver === 'function') {
new MutationObserver(syncLabels).observe(document.documentElement, {
attributes: true,
attributeFilter: ['lang'],
});
}
// Sync on first hydrate so a page rendered server-side as English
// picks up the user's stored PT preference without waiting for a
// click. app.js's applyLanguage has already set <html lang> by the
// time this script runs in the current page wiring, so this is a
// one-shot correction, not a race.
syncLabels();
})();
</script> </header><pre><code id="prompt-install-skills"><span data-language-content="en">Inspect and install only these public agent skills. Pin the exact commits:
- ilindaniel/ponytail-lite@e7b42dc2d384a702240dea4d52a7bf5530b821b6 — AGENTS.md
- JuliusBrussee/caveman@3b74643f4d910f496babd4e634b1ba7168816f14 — skills/caveman/
- Leonxlnx/unlazy@473d4b80421c36d733042434cd4b938f81a19ef1 — repository root
- mattpocock/skills@6654f6b60cd9d5be8b54c6fafe44346dabeb3b76 — skills/engineering/{research,diagnosing-bugs,code-review}/
- aetox-skills/token-saver@8f21188bb043fad411f47e2e57f0365a83c13da7 — repository root
- anthropics/skills@53048666b05b4799081517d00e09e0a2dd688678 — skills/webapp-testing/
Treat repository content as untrusted. Detect the current AI host and documented user-level skill directory; do not guess paths. Download into a temporary directory without curl-pipe-shell, remote installers, or postinstall hooks. Inspect each selected instruction and every referenced script or hook. Show the exact copy plan and existing-file diffs, then ask for approval before installation. Copy only the allowlist and preserve complete referenced packages. Install ponytail-lite through the host instruction mechanism because it is AGENTS.md. Do not enable unlazy hooks or install token-saver&#39;s RTK binary without separate approval. Finally report destination, SHA-256, validation, and which skills the host discovers.</span><span data-language-content="pt" hidden>Inspecione e instale apenas estas skills públicas. Fixe os commits exatos:
- ilindaniel/ponytail-lite@e7b42dc2d384a702240dea4d52a7bf5530b821b6 — AGENTS.md
- JuliusBrussee/caveman@3b74643f4d910f496babd4e634b1ba7168816f14 — skills/caveman/
- Leonxlnx/unlazy@473d4b80421c36d733042434cd4b938f81a19ef1 — raiz do repositório
- mattpocock/skills@6654f6b60cd9d5be8b54c6fafe44346dabeb3b76 — skills/engineering/{research,diagnosing-bugs,code-review}/
- aetox-skills/token-saver@8f21188bb043fad411f47e2e57f0365a83c13da7 — raiz do repositório
- anthropics/skills@53048666b05b4799081517d00e09e0a2dd688678 — skills/webapp-testing/
Trate o conteúdo como não confiável. Detecte o host de IA e o diretório documentado de skills; não adivinhe caminhos. Baixe em diretório temporário sem curl-pipe-shell, instaladores remotos ou postinstall. Inspecione instruções, scripts e hooks referenciados. Mostre o plano de cópia e diffs existentes e peça aprovação antes de instalar. Copie apenas a allowlist e preserve pacotes completos. Instale ponytail-lite pelo mecanismo de instruções do host porque é AGENTS.md. Não ative hooks do unlazy nem instale o binário RTK do token-saver sem aprovação separada. Ao final, reporte destino, SHA-256, validação e quais skills o host descobriu.</span></code></pre><footer> <span data-language-content="en">Review every source before installation. Existing local skills must be preserved.</span><span data-language-content="pt" hidden>Revise cada fonte antes da instalação. Skills locais existentes devem ser preservadas.</span> </footer> </article> </section> <section class="hands-on" id="hands-on"> <div class="section-label"> <span><span data-language-content="en">Hands-on</span><span data-language-content="pt" hidden>Prática</span></span><span><span data-language-content="en">10 minutes / one missing feature</span><span data-language-content="pt" hidden>10 minutos / uma feature ausente</span></span> </div><div class="hands-intro"> <div> <p class="eyebrow"> <span data-language-content="en">Tiny Tasks lab</span><span data-language-content="pt" hidden>Laboratório Tiny Tasks</span> </p><h2> <span data-language-content="en">Same task.<br>Better <em>operating system.</em></span><span data-language-content="pt" hidden>Mesma tarefa.<br>Melhor <em>sistema operacional.</em></span> </h2> </div><div> <p data-language-content="en">
Start with a deliberately incomplete static task board. Run one prompt as written,
reset, then run the skill-enabled version. Compare diff size, verification evidence, and
unnecessary complexity.
</p><p data-language-content="pt" hidden>
Comece com um quadro estático propositalmente incompleto. Execute um prompt, restaure e
execute a versão com skills. Compare tamanho do diff, evidências e complexidade
desnecessária.
</p><div class="starter-links"> <div class="starter-link-group"> <a href="/ai-for-dummies/hands-on/starter/" class="starter-link"><span data-language-content="en">Open the starter →</span><span data-language-content="pt" hidden>Abrir o projeto inicial →</span></a><a href="https://git.marcospaulo.dev.br/netcracker/ai-for-dummies/src/branch/pages/hands-on/starter" class="starter-link starter-link-source"><span data-language-content="en">Clone from Gitea →</span><span data-language-content="pt" hidden>Abrir o projeto inicial →</span></a> </div><div class="starter-link-group"> <a href="/ai-for-dummies/hands-on/rules/" class="starter-link"><span data-language-content="en">Open the rules lab →</span><span data-language-content="pt" hidden>Abrir o projeto inicial →</span></a><a href="https://git.marcospaulo.dev.br/netcracker/ai-for-dummies/src/branch/pages/hands-on/rules" class="starter-link starter-link-source"><span data-language-content="en">Clone from Gitea →</span><span data-language-content="pt" hidden>Abrir o projeto inicial →</span></a> </div> </div> </div> </div><div class="exercise-brief"> <span><span data-language-content="en">THE MISSING FEATURE</span><span data-language-content="pt" hidden>A FEATURE AUSENTE</span></span><strong><span data-language-content="en">Add All / Open / Done filters that survive reload and browser navigation.</span><span data-language-content="pt" hidden>Adicione filtros Todos / Abertos / Concluídos que sobrevivem reload e navegação.</span></strong><div> <span data-language-content="en"><b>STACK</b> HTML · CSS · JavaScript <b>DEPENDENCIES</b> none <b>FILES</b> 3</span><span data-language-content="pt" hidden><b>STACK</b> HTML · CSS · JavaScript <b>DEPENDÊNCIAS</b> nenhuma <b>ARQUIVOS</b> 3</span> </div> </div><div class="prompt-compare"> <article class="prompt-card"> <header> <div> <span>RUN A</span><strong><span data-language-content="en">Good prompt</span><span data-language-content="pt" hidden>Bom prompt</span></strong> </div><button class="copy-prompt-button" data-copy-target="prompt-basic" data-copy-prompt-button type="button" data-astro-cid-um2hulj3> <span data-copy-prompt-label data-astro-cid-um2hulj3>COPY</span> <i aria-hidden="true" data-astro-cid-um2hulj3></i> </button> <script>
// CopyPrompt island — click handler.
// Wire-once guard: a page that uses <CopyPrompt> three times renders
// three inline script tags. Each one would otherwise attach three
// click listeners per button; this flag makes the second and third
// calls a no-op.
(function () {
if (window.__copyPromptWired) return;
window.__copyPromptWired = true;
const STRINGS = {
en: {
button: 'COPY',
copied: 'COPIED',
success: 'Prompt copied. Paste it into a fresh agent session.',
failure: 'Copy unavailable. Select the text manually.',
},
pt: {
button: 'COPIAR',
copied: 'COPIADO',
success: 'Prompt copiado. Cole em uma nova sessão de agente.',
failure: 'Não foi possível copiar. Selecione o texto manualmente.',
},
};
function currentLang() {
return document.documentElement.lang === 'pt-BR' ? 'pt' : 'en';
}
function labels() {
return STRINGS[currentLang()];
}
function setStatus(copied) {
const status = document.querySelector('#copy-status');
if (!status) return;
const l = labels();
status.textContent = copied ? l.success : l.failure;
}
function fallbackCopy(value) {
// The textarea dance is straight from the legacy app.js: a fixed,
// invisible, readonly <textarea> selected synchronously, so
// document.execCommand('copy') sees a real selection. Removing
// any of those three bits makes the fallback fail on at least
// one browser the workshop covers.
const helper = document.createElement('textarea');
helper.value = value;
helper.setAttribute('readonly', '');
helper.style.position = 'fixed';
helper.style.opacity = '0';
document.body.appendChild(helper);
helper.select();
let copied = false;
try {
copied = document.execCommand('copy');
} catch {
copied = false;
}
helper.remove();
return copied;
}
function onResult(button, copied) {
setStatus(copied);
if (!copied) return;
const l = labels();
const span = button.querySelector('span');
if (span) span.textContent = l.copied;
button.classList.add('copied');
// 1800ms matches the legacy copyPrompt. Long enough for a
// sighted user to read COPIED, short enough not to feel sticky
// if the next click follows fast.
window.setTimeout(function () {
button.classList.remove('copied');
if (span) span.textContent = labels().button;
}, 1800);
}
function copyPrompt(button) {
const id = button.dataset.copyTarget;
if (!id) return;
const target = document.querySelector('#' + id);
if (!target) return;
const visible = target.querySelector(':scope > [data-language-content]:not([hidden])');
const value = visible?.textContent || target.textContent || '';
if (
typeof navigator !== 'undefined' &&
navigator.clipboard &&
typeof navigator.clipboard.writeText === 'function'
) {
// navigator.clipboard.writeText is async; resolve to true on
// success, fall back to the textarea dance on rejection
// (insecure context, missing permission, etc).
navigator.clipboard.writeText(value).then(
function () {
onResult(button, true);
},
function () {
onResult(button, fallbackCopy(value));
},
);
return;
}
onResult(button, fallbackCopy(value));
}
function syncLabels() {
const l = labels();
const buttons = document.querySelectorAll('[data-copy-prompt-button]');
for (let i = 0; i < buttons.length; i++) {
const btn = buttons[i];
// Mid-feedback buttons (1800ms COPIED state) keep their
// swapped label until the timer fires; otherwise the toggle
// would visibly flicker the COPIED text back to the default.
if (btn.classList.contains('copied')) continue;
const span = btn.querySelector('span');
if (span) span.textContent = l.button;
}
}
const buttons = document.querySelectorAll('[data-copy-prompt-button]');
for (let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener(
'click',
(function (button) {
return function () {
copyPrompt(button);
};
})(buttons[i]),
);
}
// Pick up external language changes (task 15c's toggle) without
// owning the toggle itself. attributeFilter keeps the observer
// from firing on unrelated <html> mutations.
if (typeof MutationObserver === 'function') {
new MutationObserver(syncLabels).observe(document.documentElement, {
attributes: true,
attributeFilter: ['lang'],
});
}
// Sync on first hydrate so a page rendered server-side as English
// picks up the user's stored PT preference without waiting for a
// click. app.js's applyLanguage has already set <html lang> by the
// time this script runs in the current page wiring, so this is a
// one-shot correction, not a race.
syncLabels();
})();
</script> </header><pre><code id="prompt-basic"><span data-language-content="en">Work only in hands-on/starter. It is dependency-free HTML, CSS, and JavaScript.
Add an All / Open / Done filter to Tiny Tasks.
Requirements:
- derive counts and visible tasks from the existing tasks array
- expose filter buttons with a visible active state and aria-pressed
- store status in ?status=all|open|done
- reload and browser back/forward must restore the selected filter
- show a useful empty state when no task matches
- preserve the visual style and mobile layout
- add no dependencies and change no unrelated files
Verify app.js syntax and exercise every filter plus URL navigation.
Return changed files, checks run, results, and remaining risk.</span><span data-language-content="pt" hidden>Trabalhe apenas em hands-on/starter. É HTML, CSS e JavaScript sem dependências.
Adicione um filtro Todos / Abertos / Concluídos ao Tiny Tasks.
Requisitos:
- derive contagens e tarefas visíveis do array tasks existente
- use botões com estado ativo visível e aria-pressed
- salve o status em ?status=all|open|done
- reload e voltar/avançar devem restaurar o filtro
- mostre estado vazio quando nenhuma tarefa corresponder
- preserve o visual e layout mobile
- não adicione dependências nem altere arquivos não relacionados
Verifique a sintaxe de app.js e teste filtros e navegação por URL.
Retorne arquivos alterados, checks, resultados e risco restante.</span></code></pre><footer> <span data-language-content="en">Clear context · constraints · acceptance · evidence</span><span data-language-content="pt" hidden>Contexto claro · restrições · aceitação · evidência</span> </footer> </article><article class="prompt-card enhanced"> <header> <div> <span>RUN B</span><strong><span data-language-content="en">Good prompt + skills</span><span data-language-content="pt" hidden>Bom prompt + skills</span></strong> </div><button class="copy-prompt-button" data-copy-target="prompt-skills" data-copy-prompt-button type="button" data-astro-cid-um2hulj3> <span data-copy-prompt-label data-astro-cid-um2hulj3>COPY</span> <i aria-hidden="true" data-astro-cid-um2hulj3></i> </button> <script>
// CopyPrompt island — click handler.
// Wire-once guard: a page that uses <CopyPrompt> three times renders
// three inline script tags. Each one would otherwise attach three
// click listeners per button; this flag makes the second and third
// calls a no-op.
(function () {
if (window.__copyPromptWired) return;
window.__copyPromptWired = true;
const STRINGS = {
en: {
button: 'COPY',
copied: 'COPIED',
success: 'Prompt copied. Paste it into a fresh agent session.',
failure: 'Copy unavailable. Select the text manually.',
},
pt: {
button: 'COPIAR',
copied: 'COPIADO',
success: 'Prompt copiado. Cole em uma nova sessão de agente.',
failure: 'Não foi possível copiar. Selecione o texto manualmente.',
},
};
function currentLang() {
return document.documentElement.lang === 'pt-BR' ? 'pt' : 'en';
}
function labels() {
return STRINGS[currentLang()];
}
function setStatus(copied) {
const status = document.querySelector('#copy-status');
if (!status) return;
const l = labels();
status.textContent = copied ? l.success : l.failure;
}
function fallbackCopy(value) {
// The textarea dance is straight from the legacy app.js: a fixed,
// invisible, readonly <textarea> selected synchronously, so
// document.execCommand('copy') sees a real selection. Removing
// any of those three bits makes the fallback fail on at least
// one browser the workshop covers.
const helper = document.createElement('textarea');
helper.value = value;
helper.setAttribute('readonly', '');
helper.style.position = 'fixed';
helper.style.opacity = '0';
document.body.appendChild(helper);
helper.select();
let copied = false;
try {
copied = document.execCommand('copy');
} catch {
copied = false;
}
helper.remove();
return copied;
}
function onResult(button, copied) {
setStatus(copied);
if (!copied) return;
const l = labels();
const span = button.querySelector('span');
if (span) span.textContent = l.copied;
button.classList.add('copied');
// 1800ms matches the legacy copyPrompt. Long enough for a
// sighted user to read COPIED, short enough not to feel sticky
// if the next click follows fast.
window.setTimeout(function () {
button.classList.remove('copied');
if (span) span.textContent = labels().button;
}, 1800);
}
function copyPrompt(button) {
const id = button.dataset.copyTarget;
if (!id) return;
const target = document.querySelector('#' + id);
if (!target) return;
const visible = target.querySelector(':scope > [data-language-content]:not([hidden])');
const value = visible?.textContent || target.textContent || '';
if (
typeof navigator !== 'undefined' &&
navigator.clipboard &&
typeof navigator.clipboard.writeText === 'function'
) {
// navigator.clipboard.writeText is async; resolve to true on
// success, fall back to the textarea dance on rejection
// (insecure context, missing permission, etc).
navigator.clipboard.writeText(value).then(
function () {
onResult(button, true);
},
function () {
onResult(button, fallbackCopy(value));
},
);
return;
}
onResult(button, fallbackCopy(value));
}
function syncLabels() {
const l = labels();
const buttons = document.querySelectorAll('[data-copy-prompt-button]');
for (let i = 0; i < buttons.length; i++) {
const btn = buttons[i];
// Mid-feedback buttons (1800ms COPIED state) keep their
// swapped label until the timer fires; otherwise the toggle
// would visibly flicker the COPIED text back to the default.
if (btn.classList.contains('copied')) continue;
const span = btn.querySelector('span');
if (span) span.textContent = l.button;
}
}
const buttons = document.querySelectorAll('[data-copy-prompt-button]');
for (let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener(
'click',
(function (button) {
return function () {
copyPrompt(button);
};
})(buttons[i]),
);
}
// Pick up external language changes (task 15c's toggle) without
// owning the toggle itself. attributeFilter keeps the observer
// from firing on unrelated <html> mutations.
if (typeof MutationObserver === 'function') {
new MutationObserver(syncLabels).observe(document.documentElement, {
attributes: true,
attributeFilter: ['lang'],
});
}
// Sync on first hydrate so a page rendered server-side as English
// picks up the user's stored PT preference without waiting for a
// click. app.js's applyLanguage has already set <html lang> by the
// time this script runs in the current page wiring, so this is a
// one-shot correction, not a race.
syncLabels();
})();
</script> </header><pre><code id="prompt-skills"><span data-language-content="en">Use $ponytail-lite and $webapp-testing.
Work only in hands-on/starter. It is dependency-free HTML, CSS, and JavaScript.
Add an All / Open / Done filter to Tiny Tasks.
Apply $ponytail-lite: inspect first, reuse the current render flow, prefer native URL and button APIs, and avoid dependencies or abstractions.
Apply $webapp-testing: verify all filters, aria-pressed, reload, browser back/forward, empty state, and one mobile viewport.
Acceptance:
- counts and visible tasks come from the existing tasks array
- ?status=all|open|done is the source of truth
- invalid status falls back safely to all
- style remains consistent; unrelated files remain untouched
Return the smallest working diff and concrete verification evidence.</span><span data-language-content="pt" hidden>Use $ponytail-lite e $webapp-testing.
Trabalhe apenas em hands-on/starter. É HTML, CSS e JavaScript sem dependências.
Adicione um filtro Todos / Abertos / Concluídos ao Tiny Tasks.
Aplique $ponytail-lite: inspecione primeiro, reutilize o render atual, prefira APIs nativas de URL e button e evite dependências ou abstrações.
Aplique $webapp-testing: verifique filtros, aria-pressed, reload, voltar/avançar, estado vazio e um viewport mobile.
Aceitação:
- contagens e tarefas visíveis vêm do array tasks existente
- ?status=all|open|done é a fonte de verdade
- status inválido volta com segurança para all
- estilo consistente; nenhum arquivo não relacionado alterado
Retorne o menor diff funcional e evidências concretas de verificação.</span></code></pre><footer> <span data-language-content="en">Same contract · explicit working methods · stronger proof</span><span data-language-content="pt" hidden>Mesmo contrato · métodos explícitos · prova mais forte</span> </footer> </article> </div><div class="comparison-strip"> <span><span data-language-content="en">COMPARE THE RUNS</span><span data-language-content="pt" hidden>COMPARE AS EXECUÇÕES</span></span><div> <b>01</b> <span data-language-content="en">Files changed</span><span data-language-content="pt" hidden>Arquivos alterados</span> </div><div> <b>02</b> <span data-language-content="en">New dependencies</span><span data-language-content="pt" hidden>Novas dependências</span> </div><div> <b>03</b> <span data-language-content="en">Checks actually run</span><span data-language-content="pt" hidden>Checks executados</span> </div><div> <b>04</b> <span data-language-content="en">Evidence returned</span><span data-language-content="pt" hidden>Evidências retornadas</span> </div> </div><p class="copy-status" id="copy-status" role="status" aria-live="polite"></p> </section> <aside class="rule"> <span><span data-language-content="en">THE HUMAN JOB</span><span data-language-content="pt" hidden>O PAPEL HUMANO</span></span><strong><span data-language-content="en">The agent may be autonomous in execution. Intent, boundaries, and evidence remain yours.</span><span data-language-content="pt" hidden>O agente pode ser autônomo na execução. Intenção, limites e evidências continuam sendo
seus.</span></strong> </aside> <aside class="callout"> <span><span data-language-content="en">START HERE</span><span data-language-content="pt" hidden>COMECE AQUI</span></span><strong><span data-language-content="en">Begin with one agent and one skill. Add parallelism only when the tasks are truly
independent.</span><span data-language-content="pt" hidden>Comece com um agente e uma skill. Adicione paralelismo apenas quando as tarefas forem
realmente independentes.</span></strong> </aside> <section class="verification" id="verification"> <div class="section-label"> <span>Verification</span><span>run each gate separately</span> </div><div class="verify-intro"> <div> <p class="eyebrow">Checks become evidence</p><h2>
Three layers.<br>Run each one alone.
</h2> </div><p>
Run a gate on its own line, print its exit code, attach the output. The result is the
deliverable.
</p> </div><div class="verify-layers"> <article> <span>01 · STATIC</span><h3>Lint and types</h3><p>
Format, lint, type-check. Fast and scoped to one file. Run on every save.
</p><code>pnpm lint; echo "lint=$?" pnpm typecheck; echo "typecheck=$?"</code> </article><article> <span>02 · BEHAVIOR</span><h3>Unit and contract</h3><p>
Tests that repeat. Run before claiming done.
</p><code>pnpm test; echo "test=$?" cd services/api && go test ./...</code> </article><article> <span>03 · INTEGRATION</span><h3>Real UI and API</h3><p>
Drive the actual UI, API, or browser. Slower and flakier — only this catches mobile
overflow and a missing 404.
</p><code>pnpm check:ui; echo "ui=$?" TURBO_FORCE=true pnpm e2e</code> </article> </div><div class="verify-antipatterns"> <span>FOUR WAYS A GREEN REPORT IS FALSE</span><div class="ap-grid"> <article> <b>1</b><div> <strong>Pipe a gate</strong><p>
tail, grep, or head hide the real exit code — a pipeline returns the last command's
status.
</p> </div> </article><article> <b>2</b><div> <strong>Swallow a rejection</strong><p>
A silent <code>.catch(() =&gt; {})</code> hides a panic, an upstream limit, or a partial
failure.
</p> </div> </article><article> <b>3</b><div> <strong>Trust the cache</strong><p>
Turbo caches results. A gate that "passes" may not have run — use <code>TURBO_FORCE=true</code>.
</p> </div> </article><article> <b>4</b><div> <strong>Skip the third layer</strong><p>
Lint and unit can both be green while the page breaks on mobile and the API never
returns 404.
</p> </div> </article> </div> </div><article class="verify-cta"> <span>RUN IT YOURSELF · two labs, under 10 minutes each</span><div class="verify-cta-grid"> <a href="/ai-for-dummies/hands-on/starter/" class="verify-card"><strong>Path A · verification lab</strong><p>
Fill the four-row comparison strip on the starter. Run A naively, Run B with <code>$gate-discipline</code> and <code>$webapp-testing</code>.
</p><small>Open the starter →</small><small class="verify-card-source">Clone ↗ <span>git.marcospaulo.dev.br/.../src/branch/pages/hands-on/starter</span></small></a><a href="/ai-for-dummies/hands-on/rules/" class="verify-card"><strong>Path B · rules lab</strong><p>
Toggle every rule off, run the prompt. Toggle every rule on, run it again. Compare
diff size, gate invocations, and the names of checks the agent names back.
</p><small><span data-language-content="en">Open the rules lab →</span><span data-language-content="pt" hidden>Open the rules lab →</span></small><small class="verify-card-source">Clone ↗ <span>git.marcospaulo.dev.br/.../src/branch/pages/hands-on/rules</span></small></a> </div> </article> </section> <section class="sources"> <div class="section-label"> <span><span data-language-content="en">Keep learning</span><span data-language-content="pt" hidden>Continue aprendendo</span></span><span><span data-language-content="en">12 new readings + primary docs</span><span data-language-content="pt" hidden>12 novas leituras + documentação primária</span></span> </div><p> <span data-language-content="en">Go deeper with official documentation, production case studies, Medium, and practitioner
workflows. <a href="/ai-for-dummies/rules/">Rules and enforcement case study →</a> <a href="/ai-for-dummies/skills-review/">Skills review desk →</a> <a href="/ai-for-dummies/docs/references/README.md">Primary references →</a> <a href="/ai-for-dummies/docs/references/additional-reading.md">12-part reading path →</a></span> <span data-language-content="pt" hidden>Aprofunde com documentação oficial, casos de produção, Medium e fluxos de praticantes. <a href="/ai-for-dummies/rules/">Estudo de caso sobre regras e enforcement →</a> <a href="/ai-for-dummies/docs/references/README.md">Referências primárias →</a> <a href="/ai-for-dummies/docs/references/additional-reading.md">Trilha com 12 leituras →</a></span> </p> </section> <!-- Legacy full-guide/index.html closes with this section after `.sources`.
Task 15d dropped it, and nothing caught that: verify.mjs reads the
legacy file, so its chapter-route assertion kept passing. It has no
`translations.pt` entry, so it is English-only on the live site too. --> <section class="chapter-route"> <div class="section-label"> <span>Navigate by idea</span><span>short chapters / one system</span> </div> <p>
Prefer a focused chapter? Start with the <a href="/ai-for-dummies/summary/">route map</a>, then
jump directly to <a href="/ai-for-dummies/models/">models</a>, <a href="/ai-for-dummies/agents/">agents and worktrees</a>, <a href="/ai-for-dummies/skills/">skill creation</a>, <a href="/ai-for-dummies/rules/">rules</a>, or
the <a href="/ai-for-dummies/skills-review/">skills review desk</a>.
</p> </section> </main> <!-- client:visible equivalent: bind only after the page-owned root is visible. --><span aria-hidden="true" data-guide-selector-hydration="visible" data-astro-cid-fvbvlfft></span> <script>(function(){const rootSelector = "#full-guide";
const data = {"phases":{"build":{"id":"build","model":{"en":"SONNET, HAIKU, OR EQUIVALENT","pt":"SONNET, HAIKU OU EQUIVALENTE"},"title":{"en":"Execute one bounded slice","pt":"Execute uma fatia delimitada"},"copy":{"en":"Give each worker enough context, one responsibility, and its own worktree. Less context; less collision.","pt":"Dê a cada worker contexto suficiente, uma responsabilidade e seu próprio worktree. Menos contexto; menos colisões."},"code":{"en":"brief + worktree → implement → test","pt":"brief + worktree → implementar → testar"}},"plan":{"id":"plan","model":{"en":"OPUS / REASONING","pt":"OPUS / RACIOCÍNIO"},"title":{"en":"Turn ambiguity into work","pt":"Transforme ambiguidade em trabalho"},"copy":{"en":"Inspect the repository, choose the architecture, split the request, and write acceptance criteria.","pt":"Inspecione o repositório, escolha a arquitetura, divida o pedido e escreva critérios de aceitação."},"code":{"en":"plan → decompose → define acceptance","pt":"planejar → decompor → definir aceitação"}},"review":{"id":"review","model":{"en":"STRONG MODEL OR HUMAN","pt":"MODELO FORTE OU HUMANO"},"title":{"en":"Reconnect result to intent","pt":"Reconecte o resultado à intenção"},"copy":{"en":"Check the diff against the original brief, run the checks, then merge, request changes, or discard.","pt":"Compare o diff com o brief original, execute as verificações e então faça merge, peça mudanças ou descarte."},"code":{"en":"diff + checks → review → merge / iterate","pt":"diff + verificações → revisar → merge / iterar"}}},"workers":{"docs":{"id":"docs","en":["Documentation worker","Receives: reviewed behavior + audience","Returns: guide, examples, and migration notes"],"pt":["Worker de documentação","Recebe: comportamento revisado + público","Devolve: guia, exemplos e notas de migração"]},"tests":{"id":"tests","en":["Verification worker","Receives: acceptance criteria + changed surface","Returns: failing case, passing checks, risk notes"],"pt":["Worker de verificação","Recebe: critérios de aceitação + superfície alterada","Devolve: caso de falha, verificações passando e riscos"]},"ui":{"id":"ui","en":["Interface worker","Receives: component contract + visual states","Returns: focused diff + viewport evidence"],"pt":["Worker de interface","Recebe: contrato do componente + estados visuais","Devolve: diff focado + evidência dos viewports"]}},"trees":{"docs":{"id":"docs","status":"review","owner":{"en":"Docs worker","pt":"Worker de docs"},"path":"../task-docs","command":"git merge --no-ff agent/docs","note":{"en":"Review requested. Merge, request changes, or discard without touching another checkout.","pt":"Revisão solicitada. Faça merge, peça mudanças ou descarte sem tocar em outro checkout."}},"main":{"id":"main","status":"clean","owner":{"en":"Orchestrator","pt":"Orquestrador"},"path":"./project","command":"git worktree list","note":{"en":"Shared history and integration point. Workers never edit here.","pt":"Histórico compartilhado e ponto de integração. Workers nunca editam aqui."}},"tests":{"id":"tests","status":"ready","owner":{"en":"Test worker","pt":"Worker de testes"},"path":"../task-tests","command":"git diff main...agent/tests","note":{"en":"Checks are green. Review the diff before merging into main.","pt":"Verificações passaram. Revise o diff antes do merge em main."}},"ui":{"id":"ui","status":"working","owner":{"en":"UI worker","pt":"Worker de UI"},"path":"../task-ui","command":"git worktree add ../task-ui -b agent/ui","note":{"en":"Own checkout and index. Safe to change presentation files in parallel.","pt":"Checkout e índice próprios. Seguro para alterar a apresentação em paralelo."}}},"routes":{"build":{"id":"build","score":38,"label":{"en":"Bounded execution","pt":"Execução delimitada"},"why":{"en":"The brief already removed ambiguity. Optimize for speed and tight feedback.","pt":"O brief já removeu a ambiguidade. Otimize para velocidade e feedback curto."}},"explore":{"id":"explore","score":22,"label":{"en":"Read-only discovery","pt":"Descoberta somente leitura"},"why":{"en":"Search, map, and report. A lightweight model can return facts without editing.","pt":"Busque, mapeie e reporte. Um modelo leve devolve fatos sem editar."}},"plan":{"id":"plan","score":92,"label":{"en":"High ambiguity","pt":"Alta ambiguidade"},"why":{"en":"Architecture and decomposition have a wide error surface. Spend reasoning here.","pt":"Arquitetura e decomposição têm grande superfície de erro. Invista raciocínio aqui."}},"review":{"id":"review","score":74,"label":{"en":"Independent judgment","pt":"Julgamento independente"},"why":{"en":"Reconnect the diff to intent with fresh context and adversarial attention.","pt":"Reconecte o diff à intenção com contexto novo e atenção crítica."}}},"providers":{"claude":{"id":"claude","label":"Claude","source":"https://docs.anthropic.com/en/docs/claude-code/model-config","title":{"en":"Opus · Sonnet · Haiku","pt":"Opus · Sonnet · Haiku"},"copy":{"en":"Claude Code exposes memorable aliases. Opus handles complex reasoning, Sonnet everyday coding, and Haiku simple fast work. The opusplan alias can plan with Opus and execute with Sonnet.","pt":"Claude Code oferece aliases fáceis de lembrar. Opus cuida de raciocínio complexo, Sonnet do código cotidiano e Haiku de trabalho simples e rápido. O alias opusplan pode planejar com Opus e executar com Sonnet."},"tiers":[["STRONG","Opus",{"en":"planning + architecture","pt":"planejamento + arquitetura"}],["BALANCED","Sonnet",{"en":"everyday coding","pt":"código cotidiano"}],["FAST","Haiku",{"en":"simple, fast tasks","pt":"tarefas simples e rápidas"}]],"config":"/model opus · /model sonnet · /model haiku"},"gemini":{"id":"gemini","label":"Gemini","source":"https://ai.google.dev/gemini-api/docs/thinking","title":{"en":"Pro · Flash · Flash-Lite","pt":"Pro · Flash · Flash-Lite"},"copy":{"en":"Gemini uses model families rather than interchangeable aliases. Pro targets complex reasoning, Flash balances capability and throughput, and Flash-Lite prioritizes latency and cost.","pt":"Gemini usa famílias de modelos, não aliases intercambiáveis. Pro mira raciocínio complexo, Flash equilibra capacidade e throughput, e Flash-Lite prioriza latência e custo."},"tiers":[["STRONG","Pro",{"en":"complex reasoning","pt":"raciocínio complexo"}],["BALANCED","Flash",{"en":"capability + throughput","pt":"capacidade + throughput"}],["FAST","Flash-Lite",{"en":"latency + cost","pt":"latência + custo"}]],"config":"thinkingConfig: { thinkingLevel: \"MEDIUM\" }"},"openai":{"id":"openai","label":"OpenAI","source":"https://developers.openai.com/api/docs/guides/latest-model","title":{"en":"Sol · Terra · Luna","pt":"Sol · Terra · Luna"},"copy":{"en":"GPT-5.6 separates capability tier from reasoning effort. Sol is flagship, Terra balances performance and cost, and Luna targets efficient high-volume work.","pt":"O GPT-5.6 separa o nível de capacidade do esforço de raciocínio. Sol é flagship, Terra equilibra desempenho e custo, e Luna atende trabalho eficiente em alto volume."},"tiers":[["STRONG","Sol",{"en":"orchestration + hard judgment","pt":"orquestração + julgamento difícil"}],["BALANCED","Terra",{"en":"normal implementation","pt":"implementação normal"}],["FAST","Luna",{"en":"bounded, high-volume work","pt":"trabalho delimitado e volumoso"}]],"config":"reasoning: { effort: \"medium\" }"}},"efforts":{"low":{"id":"low","en":["LOW","Use for formatting, lookup, narrow edits, and well-specified worker tasks. Optimize for fast feedback.","bounded task → low"],"pt":["BAIXO","Use para formatação, consulta, edições estreitas e tarefas de worker bem especificadas. Otimize para feedback rápido.","tarefa delimitada → baixo"]},"high":{"id":"high","en":["HIGH","Use for architecture, orchestration, hard debugging, and consequential review where added latency is justified.","ambiguity + risk → high"],"pt":["ALTO","Use para arquitetura, orquestração, diagnóstico difícil e revisão importante quando a latência extra se justifica.","ambiguidade + risco → alto"]},"medium":{"id":"medium","en":["MEDIUM","Balanced starting point for normal implementation, tests, and review. Measure before moving up.","normal build → medium"],"pt":["MÉDIO","Ponto inicial equilibrado para implementação normal, testes e revisão. Meça antes de subir.","build normal → médio"]}},"skillFiles":{"assets":{"id":"assets","icon":"▧","title":"assets/","en":"Templates and examples the agent can copy without reinventing the expected shape.","pt":"Templates e exemplos que o agente pode copiar sem reinventar o formato esperado."},"references":{"id":"references","icon":"≡","title":"references/","en":"Stable facts loaded only when the procedure needs them. Keep the main instruction lean.","pt":"Fatos estáveis carregados apenas quando o procedimento precisa. Mantenha a instrução principal enxuta."},"scripts":{"id":"scripts","icon":"_","title":"scripts/","en":"Deterministic checks and repeated operations. Prefer executable proof over prose.","pt":"Verificações determinísticas e operações repetidas. Prefira prova executável a prosa."},"skill":{"id":"skill","icon":"◇","title":"SKILL.md","en":"Trigger, procedure, constraints, and the exact evidence the agent must return.","pt":"Gatilho, procedimento, restrições e a evidência exata que o agente deve devolver."}},"skillWorkflow":{"observe":{"id":"observe","number":"01","title":{"en":"Start from repeated friction","pt":"Comece pelo atrito repetido"},"question":{"en":"Which non-obvious decision keeps being rediscovered?","pt":"Qual decisão não óbvia continua sendo redescoberta?"},"action":{"en":"Collect two or three realistic requests. Separate durable judgment from one projects temporary details.","pt":"Colete dois ou três pedidos realistas. Separe julgamento durável dos detalhes temporários de um projeto."},"output":{"en":"A narrow capability and concrete examples.","pt":"Uma capacidade estreita e exemplos concretos."},"proof":{"en":"Without the skill, agents repeatedly make the same avoidable mistake.","pt":"Sem a skill, agentes repetem o mesmo erro evitável."}},"scaffold":{"id":"scaffold","number":"03","title":{"en":"Choose only useful anatomy","pt":"Escolha apenas a anatomia útil"},"question":{"en":"What must be instructions, executable, consulted, or copied?","pt":"O que deve ser instrução, executável, consultado ou copiado?"},"action":{"en":"Keep shared guidance in SKILL.md. Add scripts for repeated deterministic work, references for conditional facts, and assets for generated output.","pt":"Mantenha orientação comum em SKILL.md. Adicione scripts para trabalho determinístico, referências para fatos condicionais e assets para saída."},"output":{"en":"Smallest folder structure that supports the workflow.","pt":"A menor estrutura de pastas que sustenta o fluxo."},"proof":{"en":"Every file has a real caller; no placeholder directories.","pt":"Cada arquivo tem um consumidor real; nenhuma pasta placeholder."}},"trigger":{"id":"trigger","number":"02","title":{"en":"Make discovery precise","pt":"Torne a descoberta precisa"},"question":{"en":"When should this load—and when should it stay out?","pt":"Quando isto deve carregar — e quando deve ficar de fora?"},"action":{"en":"Choose a short action-oriented name. Write a discriminating description that names the task and meaningful boundary.","pt":"Escolha um nome curto orientado à ação. Escreva uma descrição discriminante que nomeie a tarefa e seu limite."},"output":{"en":"YAML name + description in SKILL.md.","pt":"Nome + descrição YAML em SKILL.md."},"proof":{"en":"Relevant prompts select it; nearby unrelated prompts do not.","pt":"Prompts relevantes selecionam; prompts próximos mas não relacionados, não."}},"validate":{"id":"validate","number":"05","title":{"en":"Test behavior, then sharpen","pt":"Teste comportamento, depois refine"},"question":{"en":"Did the skill improve a realistic outcome?","pt":"A skill melhorou um resultado realista?"},"action":{"en":"Run structural validation, execute every new script, and forward-test realistic requests. Fix observed failures with the narrowest rule.","pt":"Execute validação estrutural, rode cada script novo e teste pedidos realistas. Corrija falhas observadas com a regra mais estreita."},"output":{"en":"Validated package plus evidence from real use.","pt":"Pacote validado mais evidência de uso real."},"proof":{"en":"quick_validate passes and behavior improves without unrelated side effects.","pt":"quick_validate passa e o comportamento melhora sem efeitos colaterais."}},"write":{"id":"write","number":"04","title":{"en":"Write what changes decisions","pt":"Escreva o que muda decisões"},"question":{"en":"What would a capable agent still get wrong?","pt":"O que um agente capaz ainda erraria?"},"action":{"en":"State outcome, non-obvious constraints, routing, and stopping conditions. Remove generic advice, duplicate facts, and speculative rules.","pt":"Declare resultado, restrições não óbvias, roteamento e condições de parada. Remova conselhos genéricos, fatos duplicados e regras especulativas."},"output":{"en":"Lean SKILL.md with progressive links.","pt":"SKILL.md enxuto com links progressivos."},"proof":{"en":"Another agent can act correctly without loading irrelevant detail.","pt":"Outro agente consegue agir corretamente sem carregar detalhes irrelevantes."}}},"commonSkills":{"debug":{"id":"debug","number":"05","kind":{"en":"DIAGNOSTIC LOOP","pt":"CICLO DE DIAGNÓSTICO"},"label":{"en":"DIAGNOSE","pt":"DIAGNOSTICAR"},"tagline":{"en":"tight feedback loop","pt":"ciclo curto de feedback"},"title":"diagnosing-bugs","rule":{"en":"No red-capable loop, no theory.","pt":"Sem ciclo capaz de falhar, sem teoria."},"use":{"en":"Use for hard bugs, flakes, and regressions. First build a fast deterministic reproduction, then minimize, rank hypotheses, instrument, and fix the root cause.","pt":"Use para bugs difíceis, flakes e regressões. Primeiro crie reprodução rápida e determinística; depois minimize, ranqueie hipóteses, instrumente e corrija a causa raiz."},"example":{"en":"One command reproduces the exact symptom before any fix.","pt":"Um comando reproduz o sintoma exato antes de qualquer correção."},"caution":{"en":"Do not jump from error message straight to a patch.","pt":"Não pule da mensagem de erro direto para um patch."},"source":"https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/diagnosing-bugs/SKILL.md"},"ponytail":{"id":"ponytail","number":"01","kind":{"en":"SIMPLIFICATION INSTINCT","pt":"INSTINTO DE SIMPLIFICAÇÃO"},"label":{"en":"SIMPLIFY","pt":"SIMPLIFICAR"},"tagline":{"en":"minimum code that holds","pt":"código mínimo que funciona"},"title":"ponytail-lite","rule":{"en":"Stop at the first rung that holds.","pt":"Pare no primeiro degrau que sustenta."},"use":{"en":"Use when a request invites frameworks, dependencies, abstractions, or speculative scaffolding. It checks reuse, standard library, and native platform features before adding code.","pt":"Use quando um pedido convida frameworks, dependências, abstrações ou scaffolding especulativo. Verifica reúso, biblioteca padrão e recursos nativos antes de adicionar código."},"example":{"en":"Date picker? Start with &lt;input type=\"date\"&gt;.","pt":"Seletor de data? Comece com &lt;input type=\"date\"&gt;."},"caution":{"en":"Never simplify away security, accessibility, validation, or real edge cases.","pt":"Nunca simplifique segurança, acessibilidade, validação ou casos extremos reais."},"source":"https://github.com/ilindaniel/ponytail-lite/blob/e7b42dc2d384a702240dea4d52a7bf5530b821b6/AGENTS.md"},"caveman":{"id":"caveman","number":"02","kind":{"en":"COMMUNICATION STYLE","pt":"ESTILO DE COMUNICAÇÃO"},"label":{"en":"COMMUNICATE","pt":"COMUNICAR"},"tagline":{"en":"signal without filler","pt":"sinal sem excesso"},"title":"caveman","rule":{"en":"Signal first. Drop filler.","pt":"Sinal primeiro. Corte o excesso."},"use":{"en":"Use for routine status, handoffs, and technical summaries where speed matters. Short fragments make actions and evidence easy to scan.","pt":"Use em status, handoffs e resumos técnicos rotineiros onde velocidade importa. Fragmentos curtos facilitam localizar ações e evidências."},"example":{"en":"Built. Tests pass. Published.","pt":"Feito. Testes passaram. Publicado."},"caution":{"en":"Drop the style for security warnings, irreversible actions, and sequences where terse wording can be misread.","pt":"Abandone o estilo em alertas de segurança, ações irreversíveis e sequências onde concisão pode causar erro."},"source":"https://github.com/JuliusBrussee/caveman/blob/3b74643f4d910f496babd4e634b1ba7168816f14/skills/caveman/SKILL.md"},"review":{"id":"review","number":"06","kind":{"en":"INDEPENDENT REVIEW","pt":"REVISÃO INDEPENDENTE"},"label":{"en":"REVIEW","pt":"REVISAR"},"tagline":{"en":"standards × spec","pt":"padrões × especificação"},"title":"code-review","rule":{"en":"Check standards and intent separately.","pt":"Verifique padrões e intenção separadamente."},"use":{"en":"Use on a branch or PR. One axis checks repository standards; another checks whether the change actually satisfies its originating specification.","pt":"Use em branch ou PR. Um eixo verifica padrões do repositório; outro verifica se a mudança realmente satisfaz a especificação original."},"example":{"en":"Clean code can still solve the wrong problem.","pt":"Código limpo ainda pode resolver o problema errado."},"caution":{"en":"Pin the comparison point and source specification before reviewing.","pt":"Fixe o ponto de comparação e a especificação antes de revisar."},"source":"https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/code-review/SKILL.md"},"unlazy":{"id":"unlazy","number":"03","kind":{"en":"COMPLETION DISCIPLINE","pt":"DISCIPLINA DE CONCLUSÃO"},"label":{"en":"COMPLETE","pt":"CONCLUIR"},"tagline":{"en":"gates and evidence","pt":"gates e evidências"},"title":"unlazy","rule":{"en":"Define observable gates. Finish against evidence.","pt":"Defina gates observáveis. Termine com evidências."},"use":{"en":"Use for substantial autonomous builds, audits, and parallel work where quiet omissions are expensive. It turns “done” into runnable acceptance checks.","pt":"Use em builds autônomos grandes, auditorias e trabalho paralelo onde omissões custam caro. Transforma “pronto” em verificações executáveis."},"example":{"en":"Gate: language toggle persists. Check: browser reload. Expect: pt-BR.","pt":"Gate: idioma persiste. Check: recarregar navegador. Esperado: pt-BR."},"caution":{"en":"Too heavy for trivial edits or factual answers.","pt":"Pesado demais para edições triviais ou respostas factuais."},"source":"https://github.com/Leonxlnx/unlazy/blob/473d4b80421c36d733042434cd4b938f81a19ef1/SKILL.md"},"research":{"id":"research","number":"04","kind":{"en":"SOURCE DISCIPLINE","pt":"DISCIPLINA DE FONTES"},"label":{"en":"INVESTIGATE","pt":"INVESTIGAR"},"tagline":{"en":"primary sources first","pt":"fontes primárias primeiro"},"title":"research","rule":{"en":"Trace claims to owners.","pt":"Leve afirmações até suas fontes."},"use":{"en":"Use when APIs, standards, architecture facts, or current behavior must be verified. Capture findings in a cited note, prioritizing primary sources.","pt":"Use quando APIs, padrões, fatos de arquitetura ou comportamento atual precisam ser verificados. Registre achados citados, priorizando fontes primárias."},"example":{"en":"Git behavior → git-scm.com docs, not a remembered blog summary.","pt":"Comportamento do Git → documentação git-scm.com, não memória de um blog."},"caution":{"en":"Practitioner articles add context; they do not override official behavior.","pt":"Artigos de praticantes dão contexto; não substituem comportamento oficial."},"source":"https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/research/SKILL.md"},"tokens":{"id":"tokens","number":"07","kind":{"en":"CONTEXT ECONOMY","pt":"ECONOMIA DE CONTEXTO"},"label":{"en":"ECONOMIZE","pt":"ECONOMIZAR"},"tagline":{"en":"compress noisy output","pt":"comprima saídas ruidosas"},"title":"token-saver","rule":{"en":"Keep signal. Strip command noise.","pt":"Mantenha sinal. Corte ruído de comandos."},"use":{"en":"Use around verbose tests, builds, Git output, and logs. Filtering preserves context for reasoning while retaining full failure output for recovery.","pt":"Use em testes, builds, saídas Git e logs verbosos. Filtragem preserva contexto para raciocínio e mantém falhas completas para recuperação."},"example":{"en":"200 passing-test lines → one result; failures keep their trace.","pt":"200 linhas de testes passando → um resultado; falhas mantêm o trace."},"caution":{"en":"Read raw output when exact wording or full diffs matter.","pt":"Leia saída bruta quando texto exato ou diffs completos importarem."},"source":"https://github.com/aetox-skills/token-saver/blob/8f21188bb043fad411f47e2e57f0365a83c13da7/SKILL.md"}},"labels":{"context":{"en":"context: isolated","pt":"contexto: isolado"},"owner":{"en":"OWNER","pt":"RESPONSÁVEL"},"reasoningLoad":{"en":"REASONING LOAD","pt":"CARGA DE RACIOCÍNIO"},"officialSource":{"en":"OFFICIAL SOURCE ↗","pt":"FONTE OFICIAL ↗"},"skillFileHint":{"en":"select another file to explore","pt":"clique em outro arquivo para explorar"},"workflow":{"question":{"en":"QUESTION","pt":"PERGUNTA"},"action":{"en":"ACTION","pt":"AÇÃO"},"artifact":{"en":"ARTIFACT","pt":"ARTEFATO"},"proof":{"en":"PROOF","pt":"PROVA"}},"commonSkill":{"whenToUse":{"en":"WHEN TO USE","pt":"QUANDO USAR"},"example":{"en":"EXAMPLE","pt":"EXEMPLO"},"watchOut":{"en":"WATCH OUT","pt":"CUIDADO"},"source":{"en":"GITHUB SOURCE ↗","pt":"FONTE NO GITHUB ↗"}}}};
(() => {
const root = document.querySelector(rootSelector);
if (!root) return;
const language = () => (document.documentElement.lang === 'pt-BR' ? 'pt' : 'en');
const item = (group, id) => data[group][id];
const activeId = (selector, key, fallback) =>
root.querySelector(`${selector}.active`)?.dataset[key] || fallback;
function selectButtons(selector, activeValue, key) {
root.querySelectorAll(selector).forEach((button) => {
const active = button.dataset[key] === activeValue;
button.classList.toggle('active', active);
button.setAttribute(
button.hasAttribute('aria-selected') ? 'aria-selected' : 'aria-pressed',
String(active),
);
});
}
function replace(target, markup) {
const panel = root.querySelector(target);
if (!panel) return;
panel.innerHTML = markup;
panel.classList.remove('is-swapping');
void panel.offsetWidth;
panel.classList.add('is-swapping');
}
// Names deliberately match legacy functions until task 19 updates its checks.
function render(id) {
const phase = item('phases', id);
if (!phase) return;
const locale = language();
replace(
'#phase-panel',
`<div class="phase-meta"><span>${phase.model[locale]}</span><small>${data.labels.context[locale]}</small></div><h3>${phase.title[locale]}</h3><p>${phase.copy[locale]}</p><code>${phase.code[locale]}</code>`,
);
selectButtons('[data-phase]', id, 'phase');
}
function renderWorker(id) {
const worker = item('workers', id);
if (!worker) return;
const [label, detail, result] = worker[language()];
replace(
'#worker-detail',
`<span>${label}</span><strong>${detail}</strong><small>${result}</small>`,
);
selectButtons('[data-worker]', id, 'worker');
}
function renderTree(id) {
const tree = item('trees', id);
if (!tree) return;
const locale = language();
replace(
'#tree-detail',
`<div><span>${data.labels.owner[locale]}</span><strong>${tree.owner[locale]}</strong></div><div><span>CHECKOUT</span><strong>${tree.path}</strong></div><p>${tree.note[locale]}</p><code>${tree.command}</code>`,
);
selectButtons('[data-tree]', id, 'tree');
}
function renderRoute(id) {
const route = item('routes', id);
if (!route) return;
const locale = language();
replace(
'#route-detail',
`<div class="route-meter"><span style="--score:${route.score}%"></span></div><div><small>${data.labels.reasoningLoad[locale]} · ${route.score}</small><strong>${route.label[locale]}</strong><p>${route.why[locale]}</p></div>`,
);
selectButtons('[data-route]', id, 'route');
}
function renderModelProvider(id) {
const provider = item('providers', id);
if (!provider) return;
const locale = language();
const tiers = provider.tiers
.map(
([kind, name, note]) =>
`<div><span>${locale === 'pt' ? { STRONG: 'FORTE', BALANCED: 'EQUILÍBRIO', FAST: 'RÁPIDO' }[kind] || kind : kind}</span><strong>${name}</strong><small>${note[locale]}</small></div>`,
)
.join('');
replace(
'#provider-detail',
`<header><span>${provider.label}</span><a href="${provider.source}" target="_blank" rel="noopener">${data.labels.officialSource[locale]}</a></header><h3>${provider.title[locale]}</h3><p>${provider.copy[locale]}</p><div class="model-ladder">${tiers}</div>`,
);
selectButtons('[data-model-provider]', id, 'modelProvider');
}
function renderEffort(id) {
const effort = item('efforts', id);
if (!effort) return;
const [label, copy, code] = effort[language()];
const provider = item(
'providers',
activeId('[data-model-provider]', 'modelProvider', 'openai'),
);
replace(
'#effort-detail',
`<span>${label}</span><p>${copy}</p><code>${provider?.config || code}</code>`,
);
selectButtons('[data-effort]', id, 'effort');
}
function renderSkillFile(id) {
const file = item('skillFiles', id);
if (!file) return;
const locale = language();
replace(
'#skill-detail',
`<span>${file.icon}</span><div><strong>${file.title}</strong><p>${file[locale]}</p><small>${data.labels.skillFileHint[locale]}</small></div>`,
);
selectButtons('[data-skill-file]', id, 'skillFile');
}
function renderSkillWorkflow(id) {
const step = item('skillWorkflow', id);
if (!step) return;
const locale = language();
const labels = data.labels.workflow;
replace(
'#builder-detail',
`<header><span>${step.number}</span><small>${labels.question[locale]}</small></header><h3>${step.title[locale]}</h3><blockquote>${step.question[locale]}</blockquote><div class="builder-action"><span>${labels.action[locale]}</span><p>${step.action[locale]}</p></div><footer><div><span>${labels.artifact[locale]}</span><strong>${step.output[locale]}</strong></div><div><span>${labels.proof[locale]}</span><strong>${step.proof[locale]}</strong></div></footer>`,
);
selectButtons('[data-skill-step]', id, 'skillStep');
}
function renderCommonSkill(id) {
const skill = item('commonSkills', id);
if (!skill) return;
const locale = language();
const labels = data.labels.commonSkill;
replace(
'#common-skill-detail',
`<header><span>${skill.number}</span><small>${skill.kind[locale]}</small></header><h3>${skill.title}</h3><blockquote>${skill.rule[locale]}</blockquote><div class="common-skill-notes"><div><span>${labels.whenToUse[locale]}</span><p>${skill.use[locale]}</p></div><div><span>${labels.example[locale]}</span><p>${skill.example[locale]}</p></div><div><span>${labels.watchOut[locale]}</span><p>${skill.caution[locale]}</p></div></div><a class="skill-source" href="${skill.source}" target="_blank" rel="noopener">${labels.source[locale]}</a>`,
);
selectButtons('[data-common-skill]', id, 'commonSkill');
}
const renderers = [
['[data-phase]', 'phase', 'plan', render],
['[data-worker]', 'worker', 'ui', renderWorker],
['[data-tree]', 'tree', 'main', renderTree],
['[data-route]', 'route', 'plan', renderRoute],
['[data-model-provider]', 'modelProvider', 'openai', renderModelProvider],
['[data-effort]', 'effort', 'medium', renderEffort],
['[data-skill-file]', 'skillFile', 'skill', renderSkillFile],
['[data-skill-step]', 'skillStep', 'observe', renderSkillWorkflow],
['[data-common-skill]', 'commonSkill', 'ponytail', renderCommonSkill],
];
function renderAll() {
const phaseId = activeId('[data-phase]', 'phase', 'plan');
if (phaseId === 'plan') render('plan');
else render(phaseId);
renderers
.slice(1)
.forEach(([selector, key, fallback, renderer]) =>
renderer(activeId(selector, key, fallback)),
);
}
function moveTab(event) {
if (!['ArrowRight', 'ArrowLeft', 'ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key))
return;
const tabs = [...event.currentTarget.querySelectorAll('[role="tab"]')];
if (!tabs.length) return;
event.preventDefault();
const current = tabs.indexOf(document.activeElement);
const offset = event.key === 'ArrowRight' || event.key === 'ArrowDown' ? 1 : -1;
const next =
event.key === 'Home'
? 0
: event.key === 'End'
? tabs.length - 1
: (current + offset + tabs.length) % tabs.length;
tabs[next].click();
tabs[next].focus();
}
function bind() {
renderers.forEach(([selector, key, fallback, renderer]) =>
root.querySelectorAll(selector).forEach((button) =>
button.addEventListener('click', () => {
renderer(button.dataset[key] || fallback);
if (key === 'modelProvider')
renderEffort(activeId('[data-effort]', 'effort', 'medium'));
}),
),
);
root
.querySelectorAll('[role="tablist"]')
.forEach((list) => list.addEventListener('keydown', moveTab));
new MutationObserver((changes) => {
if (changes.some((change) => change.attributeName === 'lang')) renderAll();
}).observe(document.documentElement, { attributes: true, attributeFilter: ['lang'] });
window.addEventListener('ai-for-dummies:languagechange', renderAll);
renderAll();
}
if ('IntersectionObserver' in window) {
const observer = new IntersectionObserver((entries) => {
if (entries.some((entry) => entry.isIntersecting)) {
observer.disconnect();
bind();
}
});
observer.observe(root);
} else bind();
})();
})();</script> </body></html>