feat: add model routing and hands-on lab
This commit is contained in:
@@ -8,6 +8,11 @@ An interactive field kit compares common behavior skills such as
|
||||
`ponytail-lite`, `caveman`, `unlazy`, research, debugging, and review.
|
||||
The skill-forge workflow covers discovery, triggers, package anatomy,
|
||||
progressive instructions, structural validation, and behavioral iteration.
|
||||
The hands-on lab provides a tiny starter project and copy-ready baseline and
|
||||
skill-enabled prompts for a short side-by-side exercise.
|
||||
An interactive model gearbox separates capability tier from reasoning effort
|
||||
across OpenAI, Claude, and Gemini, and every featured skill links to a pinned
|
||||
source with an approval-first installation prompt.
|
||||
|
||||
## Run locally
|
||||
|
||||
@@ -33,6 +38,7 @@ npm run verify
|
||||
- `responsive.css` — interactive diagrams and Full HD-to-4K adaptations
|
||||
- `docs/references/` — bundled research sources and notes
|
||||
- `docs/operations-guide.md` — canonical SilverBullet operations and skills guide
|
||||
- `hands-on/starter/` — dependency-free Tiny Tasks exercise
|
||||
- `GATES.md` — acceptance ledger for the project
|
||||
|
||||
## Publishing
|
||||
@@ -55,3 +61,5 @@ skill workflow, see [docs/operations-guide.md](docs/operations-guide.md).
|
||||
See [docs/references/README.md](docs/references/README.md) for official Claude,
|
||||
Codex, and Git documentation. The [additional reading path](docs/references/additional-reading.md)
|
||||
bundles 12 verified articles and guides, including Medium and practitioner sources.
|
||||
See [model routing](docs/references/model-routing.md) for current provider controls
|
||||
and [verified skill sources](docs/references/skill-sources.md) for commit-pinned provenance.
|
||||
|
||||
@@ -4,6 +4,159 @@ const phases = {
|
||||
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' } }
|
||||
};
|
||||
|
||||
const handsOnPrompts = {
|
||||
en: {
|
||||
basic: [
|
||||
'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.'
|
||||
].join('\n'),
|
||||
skills: [
|
||||
'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.'
|
||||
].join('\n')
|
||||
},
|
||||
pt: {
|
||||
basic: [
|
||||
'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.'
|
||||
].join('\n'),
|
||||
skills: [
|
||||
'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.'
|
||||
].join('\n')
|
||||
}
|
||||
};
|
||||
|
||||
const modelGuide = {
|
||||
providers: {
|
||||
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" }'
|
||||
},
|
||||
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: {
|
||||
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" }'
|
||||
}
|
||||
},
|
||||
efforts: {
|
||||
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'] },
|
||||
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'] },
|
||||
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'] }
|
||||
}
|
||||
};
|
||||
|
||||
const skillSources = {
|
||||
ponytail: 'https://github.com/ilindaniel/ponytail-lite/blob/e7b42dc2d384a702240dea4d52a7bf5530b821b6/AGENTS.md',
|
||||
caveman: 'https://github.com/JuliusBrussee/caveman/blob/3b74643f4d910f496babd4e634b1ba7168816f14/skills/caveman/SKILL.md',
|
||||
unlazy: 'https://github.com/Leonxlnx/unlazy/blob/473d4b80421c36d733042434cd4b938f81a19ef1/SKILL.md',
|
||||
research: 'https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/research/SKILL.md',
|
||||
debug: 'https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/diagnosing-bugs/SKILL.md',
|
||||
review: 'https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/code-review/SKILL.md',
|
||||
tokens: 'https://github.com/aetox-skills/token-saver/blob/8f21188bb043fad411f47e2e57f0365a83c13da7/SKILL.md'
|
||||
};
|
||||
|
||||
const skillInstallPrompts = {
|
||||
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\'s RTK binary without separate approval. Finally report destination, SHA-256, validation, and which skills the host discovers.'
|
||||
].join('\n'),
|
||||
pt: [
|
||||
'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.'
|
||||
].join('\n')
|
||||
};
|
||||
|
||||
const interactiveCopy = {
|
||||
workers: {
|
||||
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'] },
|
||||
@@ -48,7 +201,7 @@ const interactiveCopy = {
|
||||
|
||||
const translations = {
|
||||
pt: {
|
||||
'.chapter-links a:nth-child(1)': '01 frota', '.chapter-links a:nth-child(2)': '02 worktrees', '.chapter-links a:nth-child(3)': '03 skills', '.chapter-links a:nth-child(4)': '04 criar', '.chapter-links a:nth-child(5)': '05 kit de campo', '.edition': 'ENGENHARIA DE IA <i></i> 01 / 2026',
|
||||
'.chapter-links a:nth-child(1)': '01 frota', '.chapter-links a:nth-child(2)': '02 worktrees', '.chapter-links a:nth-child(3)': '03 modelos', '.chapter-links a:nth-child(4)': '04 skills', '.chapter-links a:nth-child(5)': '05 criar', '.chapter-links a:nth-child(6)': '06 kit de campo', '.chapter-links a:nth-child(7)': '07 prática', '.edition': 'ENGENHARIA DE IA <i></i> 01 / 2026',
|
||||
'.hero .eyebrow': 'Uma apresentação para quem entrega software', '.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.', '.hero-index span': 'NOTA DE CAMPO / 001', '.hero-index strong': 'Entregue o<br /><em>sistema.</em>', '.hero-index small': 'Skills · agentes · worktrees · evidências',
|
||||
'.hero-stats div:nth-child(1) span': 'modelo forte<br />para ambiguidade', '.hero-stats div:nth-child(2) span': 'workers delimitados<br />em paralelo', '.hero-stats div:nth-child(3) span': 'iterações<br />com evidências', '.hero-stats p': 'Leia isto como um mapa de rota, não como uma receita de prompt.',
|
||||
'.thesis span': 'REGRA ZERO', '.thesis strong': 'Modelo forte para ambiguidade.<br />Modelo leve para trabalho delimitado.', '.fleet .section-label span:nth-child(1)': 'Uma pequena frota', '.fleet .section-label span:nth-child(2)': 'coordenação antes do paralelismo', '.captain span': 'ORQUESTRADOR', '.captain h2': 'Decide o que<br />precisa acontecer.', '.worker-card[data-worker="ui"] strong': 'Componentes e estados visuais', '.worker-card[data-worker="tests"] strong': 'Casos de aceitação', '.worker-card[data-worker="docs"] strong': 'Guia e exemplos', '.caption': 'O orquestrador preserva a intenção, escreve pequenos contratos e reúne resultados verificáveis. Ele não precisa digitar cada linha.',
|
||||
@@ -60,6 +213,11 @@ const translations = {
|
||||
};
|
||||
|
||||
Object.assign(translations.pt, {
|
||||
'.model-gearbox .section-label span:nth-child(1)': 'Câmbio de modelos', '.model-gearbox .section-label span:nth-child(2)': 'nível de capacidade × esforço de raciocínio',
|
||||
'.gearbox-intro .eyebrow': 'Dois controles separados', '.gearbox-intro h2': 'Escolha o motor.<br />Depois escolha a <em>marcha.</em>',
|
||||
'.gearbox-intro > p': '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.',
|
||||
'.effort-rail > span': 'RACIOCÍNIO / PENSAMENTO', '[data-effort="low"] b': 'BAIXO', '[data-effort="low"] small': 'delimitado + rápido', '[data-effort="medium"] b': 'MÉDIO', '[data-effort="medium"] small': 'ponto inicial', '[data-effort="high"] b': 'ALTO', '[data-effort="high"] small': 'complexo + custoso',
|
||||
'.gearbox-rule span': 'REGRA DE ROTEAMENTO', '.gearbox-rule strong': '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.',
|
||||
'.skill-builder .section-label span:nth-child(1)': 'Criar uma skill',
|
||||
'.skill-builder .section-label span:nth-child(2)': 'atrito repetido → julgamento reutilizável',
|
||||
'.builder-intro .eyebrow': 'A forja de skills',
|
||||
@@ -72,7 +230,18 @@ Object.assign(translations.pt, {
|
||||
'[data-skill-step="validate"] span': 'Validar', '[data-skill-step="validate"] small': 'teste comportamento real',
|
||||
'.artifact-head span': 'SAÍDA / PACOTE DE SKILL', '.artifact-command span': 'VALIDAR',
|
||||
'.builder-loop > span': 'APÓS USO REAL',
|
||||
'.builder-loop > div': '<b>observar falha</b><i>→</i><b>refinar uma regra</b><i>→</i><b>retestar comportamento</b><i>→</i><b>manter estreita</b>'
|
||||
'.builder-loop > div': '<b>observar falha</b><i>→</i><b>refinar uma regra</b><i>→</i><b>retestar comportamento</b><i>→</i><b>manter estreita</b>',
|
||||
'.install-skills header span': 'PACOTE DE INSTALAÇÃO', '.install-skills header strong': 'Peça ao seu agente para verificar, instalar e validar as skills.',
|
||||
'.install-skills footer': 'Revise cada fonte antes da instalação. Skills locais existentes devem ser preservadas.',
|
||||
'.hands-on .section-label span:nth-child(1)': 'Prática', '.hands-on .section-label span:nth-child(2)': '10 minutos / uma feature ausente',
|
||||
'.hands-intro .eyebrow': 'Laboratório Tiny Tasks', '.hands-intro h2': 'Mesma tarefa.<br />Melhor <em>sistema operacional.</em>',
|
||||
'.hands-intro > div:last-child > p': '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.',
|
||||
'.starter-link': 'Abrir o projeto inicial →', '.exercise-brief > span': 'A FEATURE AUSENTE',
|
||||
'.exercise-brief > strong': 'Adicione filtros Todos / Abertos / Concluídos que sobrevivem reload e navegação.',
|
||||
'.exercise-brief > div': '<b>STACK</b> HTML · CSS · JavaScript <b>DEPENDÊNCIAS</b> nenhuma <b>ARQUIVOS</b> 3',
|
||||
'.prompt-card:first-child header strong': 'Bom prompt', '.prompt-card.enhanced header strong': 'Bom prompt + skills',
|
||||
'.prompt-card:first-child footer': 'Contexto claro · restrições · aceitação · evidência', '.prompt-card.enhanced footer': 'Mesmo contrato · métodos explícitos · prova mais forte',
|
||||
'.comparison-strip > span': 'COMPARE AS EXECUÇÕES', '.comparison-strip > div:nth-child(2)': '<b>01</b> Arquivos alterados', '.comparison-strip > div:nth-child(3)': '<b>02</b> Novas dependências', '.comparison-strip > div:nth-child(4)': '<b>03</b> Checks executados', '.comparison-strip > div:nth-child(5)': '<b>04</b> Evidências retornadas'
|
||||
});
|
||||
|
||||
const panel = document.querySelector('#phase-panel');
|
||||
@@ -121,6 +290,23 @@ function renderRoute(id) {
|
||||
selectButtons('[data-route]', id, 'route');
|
||||
}
|
||||
|
||||
function renderModelProvider(id) {
|
||||
const item = modelGuide.providers[id];
|
||||
const language = currentLanguage;
|
||||
const sourceLabel = language === 'pt' ? 'FONTE OFICIAL ↗' : 'OFFICIAL SOURCE ↗';
|
||||
const kindLabels = language === 'pt' ? { STRONG: 'FORTE', BALANCED: 'EQUILÍBRIO', FAST: 'RÁPIDO' } : {};
|
||||
const tiers = item.tiers.map(([kind, name, note]) => `<div><span>${kindLabels[kind] || kind}</span><strong>${name}</strong><small>${note[language]}</small></div>`).join('');
|
||||
document.querySelector('#provider-detail').innerHTML = `<header><span>${item.label}</span><a href="${item.source}" target="_blank" rel="noopener">${sourceLabel}</a></header><h3>${item.title[language]}</h3><p>${item.copy[language]}</p><div class="model-ladder">${tiers}</div>`;
|
||||
selectButtons('[data-model-provider]', id, 'modelProvider');
|
||||
}
|
||||
|
||||
function renderEffort(id) {
|
||||
const item = modelGuide.efforts[id][currentLanguage];
|
||||
const provider = modelGuide.providers[document.querySelector('[data-model-provider].active')?.dataset.modelProvider || 'openai'];
|
||||
document.querySelector('#effort-detail').innerHTML = `<span>${item[0]}</span><p>${item[1]}</p><code>${provider.config}</code>`;
|
||||
selectButtons('[data-effort]', id, 'effort');
|
||||
}
|
||||
|
||||
function renderSkillFile(id) {
|
||||
const item = interactiveCopy.skillFiles[id];
|
||||
document.querySelector('#skill-detail').innerHTML = `<span>${item.icon}</span><div><strong>${item.title}</strong><p>${item[currentLanguage]}</p><small>${currentLanguage === 'pt' ? 'clique em outro arquivo para explorar' : 'select another file to explore'}</small></div>`;
|
||||
@@ -143,17 +329,56 @@ function renderCommonSkill(id) {
|
||||
const labels = language === 'pt'
|
||||
? ['QUANDO USAR', 'EXEMPLO', 'CUIDADO']
|
||||
: ['WHEN TO USE', 'EXAMPLE', 'WATCH OUT'];
|
||||
document.querySelector('#common-skill-detail').innerHTML = `<header><span>${item.number}</span><small>${item.kind[language]}</small></header><h3>${item.title}</h3><blockquote>${item.rule[language]}</blockquote><div class="common-skill-notes"><div><span>${labels[0]}</span><p>${item.use[language]}</p></div><div><span>${labels[1]}</span><p>${item.example[language]}</p></div><div><span>${labels[2]}</span><p>${item.caution[language]}</p></div></div>`;
|
||||
const sourceLabel = language === 'pt' ? 'FONTE NO GITHUB ↗' : 'GITHUB SOURCE ↗';
|
||||
document.querySelector('#common-skill-detail').innerHTML = `<header><span>${item.number}</span><small>${item.kind[language]}</small></header><h3>${item.title}</h3><blockquote>${item.rule[language]}</blockquote><div class="common-skill-notes"><div><span>${labels[0]}</span><p>${item.use[language]}</p></div><div><span>${labels[1]}</span><p>${item.example[language]}</p></div><div><span>${labels[2]}</span><p>${item.caution[language]}</p></div></div><a class="skill-source" href="${skillSources[id]}" target="_blank" rel="noopener">${sourceLabel}</a>`;
|
||||
selectButtons('[data-common-skill]', id, 'commonSkill');
|
||||
}
|
||||
|
||||
function renderHandsOn() {
|
||||
document.querySelector('#prompt-basic').textContent = handsOnPrompts[currentLanguage].basic;
|
||||
document.querySelector('#prompt-skills').textContent = handsOnPrompts[currentLanguage].skills;
|
||||
document.querySelector('#prompt-install-skills').textContent = skillInstallPrompts[currentLanguage];
|
||||
document.querySelectorAll('[data-copy-target] span').forEach((label) => { label.textContent = currentLanguage === 'pt' ? 'COPIAR' : 'COPY'; });
|
||||
}
|
||||
|
||||
async function copyPrompt(button) {
|
||||
const text = document.querySelector(`#${button.dataset.copyTarget}`).textContent;
|
||||
let copied = false;
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
copied = true;
|
||||
} catch (error) {
|
||||
const helper = document.createElement('textarea');
|
||||
helper.value = text;
|
||||
helper.setAttribute('readonly', '');
|
||||
helper.style.position = 'fixed';
|
||||
helper.style.opacity = '0';
|
||||
document.body.appendChild(helper);
|
||||
helper.select();
|
||||
copied = document.execCommand('copy');
|
||||
helper.remove();
|
||||
}
|
||||
const status = document.querySelector('#copy-status');
|
||||
status.textContent = copied
|
||||
? (currentLanguage === 'pt' ? 'Prompt copiado. Cole em uma nova sessão de agente.' : 'Prompt copied. Paste it into a fresh agent session.')
|
||||
: (currentLanguage === 'pt' ? 'Não foi possível copiar. Selecione o texto manualmente.' : 'Copy unavailable. Select the text manually.');
|
||||
if (copied) {
|
||||
button.classList.add('copied');
|
||||
button.querySelector('span').textContent = currentLanguage === 'pt' ? 'COPIADO' : 'COPIED';
|
||||
window.setTimeout(() => { button.classList.remove('copied'); button.querySelector('span').textContent = currentLanguage === 'pt' ? 'COPIAR' : 'COPY'; }, 1800);
|
||||
}
|
||||
}
|
||||
|
||||
function renderInteractive() {
|
||||
renderWorker(document.querySelector('[data-worker].active')?.dataset.worker || 'ui');
|
||||
renderTree(document.querySelector('[data-tree].active')?.dataset.tree || 'main');
|
||||
renderRoute(document.querySelector('[data-route].active')?.dataset.route || 'plan');
|
||||
renderModelProvider(document.querySelector('[data-model-provider].active')?.dataset.modelProvider || 'openai');
|
||||
renderEffort(document.querySelector('[data-effort].active')?.dataset.effort || 'medium');
|
||||
renderSkillFile(document.querySelector('[data-skill-file].active')?.dataset.skillFile || 'skill');
|
||||
renderSkillWorkflow(document.querySelector('[data-skill-step].active')?.dataset.skillStep || 'observe');
|
||||
renderCommonSkill(document.querySelector('[data-common-skill].active')?.dataset.commonSkill || 'ponytail');
|
||||
renderHandsOn();
|
||||
}
|
||||
|
||||
function applyLanguage(language) {
|
||||
@@ -172,9 +397,12 @@ document.querySelectorAll('[data-lang]').forEach((button) => button.addEventList
|
||||
document.querySelectorAll('[data-worker]').forEach((button) => button.addEventListener('click', () => renderWorker(button.dataset.worker)));
|
||||
document.querySelectorAll('[data-tree]').forEach((button) => button.addEventListener('click', () => renderTree(button.dataset.tree)));
|
||||
document.querySelectorAll('[data-route]').forEach((button) => button.addEventListener('click', () => renderRoute(button.dataset.route)));
|
||||
document.querySelectorAll('[data-model-provider]').forEach((button) => button.addEventListener('click', () => { renderModelProvider(button.dataset.modelProvider); renderEffort(document.querySelector('[data-effort].active')?.dataset.effort || 'medium'); }));
|
||||
document.querySelectorAll('[data-effort]').forEach((button) => button.addEventListener('click', () => renderEffort(button.dataset.effort)));
|
||||
document.querySelectorAll('[data-skill-file]').forEach((button) => button.addEventListener('click', () => renderSkillFile(button.dataset.skillFile)));
|
||||
document.querySelectorAll('[data-skill-step]').forEach((button) => button.addEventListener('click', () => renderSkillWorkflow(button.dataset.skillStep)));
|
||||
document.querySelectorAll('[data-common-skill]').forEach((button) => button.addEventListener('click', () => renderCommonSkill(button.dataset.commonSkill)));
|
||||
document.querySelectorAll('[data-copy-target]').forEach((button) => button.addEventListener('click', () => copyPrompt(button)));
|
||||
window.addEventListener('scroll', () => { const height = document.documentElement.scrollHeight - window.innerHeight; document.querySelector('.reading-progress span').style.width = `${height > 0 ? (window.scrollY / height) * 100 : 0}%`; }, { passive: true });
|
||||
|
||||
let savedLanguage = 'en';
|
||||
|
||||
@@ -305,6 +305,82 @@ Useful compositions:
|
||||
- **Documentation with unstable facts:** `research` → writing → cited verification.
|
||||
- **Interactive presentation:** `frontend-design` → `webapp-testing` → responsive evidence.
|
||||
|
||||
## Model and effort routing
|
||||
|
||||
Treat model tier and reasoning effort as separate controls:
|
||||
|
||||
| Work shape | Capability tier | Effort baseline |
|
||||
| :--- | :--- | :--- |
|
||||
| Formatting, lookup, narrow edit | Luna / Haiku / Flash-Lite | Low or minimal where supported |
|
||||
| Normal implementation and tests | Terra / Sonnet / Flash | Medium |
|
||||
| Architecture, orchestration, hard debugging | Sol / Opus / Pro | High |
|
||||
|
||||
For Claude Code, `/model opus`, `/model sonnet`, and `/model haiku` switch the
|
||||
model alias; `opusplan` can use Opus while planning and Sonnet while executing.
|
||||
Claude effort support depends on the active model. For OpenAI GPT-5.6,
|
||||
`reasoning.effort` supports `none`, `low`, `medium`, `high`, `xhigh`, and `max`.
|
||||
Gemini 3 uses model-specific `thinkingLevel` values, while Gemini 2.5 uses
|
||||
`thinkingBudget`. Never assume one provider's control maps exactly to another.
|
||||
|
||||
Start with the lightest configuration that passes representative checks. Move
|
||||
one knob at a time and compare quality, latency, and cost. See
|
||||
[model-routing.md](references/model-routing.md) for official source links and
|
||||
copy-ready provider examples.
|
||||
|
||||
## Installing the featured skills
|
||||
|
||||
The field-kit cards link to commit-pinned public sources. The presentation also
|
||||
includes a copy-ready installation request that tells the coding agent to:
|
||||
|
||||
1. Detect the host's documented skill location.
|
||||
2. Inspect downloaded instructions, scripts, hooks, and permissions first.
|
||||
3. Show a source-to-destination plan and existing-file diffs.
|
||||
4. Ask for approval before copying files.
|
||||
5. Verify final paths, hashes, validation, and actual skill discovery.
|
||||
|
||||
Important exceptions: `ponytail-lite` is published as `AGENTS.md`, not a
|
||||
conventional skill package; `token-saver` expects a separate RTK binary; and
|
||||
`unlazy` includes optional hooks. The prompt does not install binaries or enable
|
||||
hooks without separate approval. See [skill-sources.md](references/skill-sources.md)
|
||||
for exact commits, package paths, and confidence notes.
|
||||
|
||||
## Hands-on lab
|
||||
|
||||
The presentation includes a dependency-free starter at
|
||||
`hands-on/starter/`. It renders a small task board but intentionally omits the
|
||||
All / Open / Done filter.
|
||||
|
||||
Run it from the repository root:
|
||||
|
||||
```bash
|
||||
python3 -m http.server 4173
|
||||
```
|
||||
|
||||
Open [http://localhost:4173/hands-on/starter/](http://localhost:4173/hands-on/starter/).
|
||||
In a fresh coding-agent session, copy **Run A — Good prompt** from the
|
||||
presentation. Record changed files, dependencies, checks, and evidence. Restore
|
||||
the starter, then repeat with **Run B — Good prompt + skills**.
|
||||
|
||||
The skill-enabled prompt invokes only two working methods:
|
||||
|
||||
- `$ponytail-lite` keeps the implementation native and small;
|
||||
- `$webapp-testing` verifies filters, URL state, history navigation,
|
||||
accessibility state, empty state, and mobile layout.
|
||||
|
||||
The goal is not to prove that a longer prompt is better. Both prompts define
|
||||
the same task contract. Run B adds reusable operating discipline without
|
||||
repeating those skill instructions inside the prompt.
|
||||
|
||||
Compare:
|
||||
|
||||
| Signal | Useful question |
|
||||
| :--- | :--- |
|
||||
| Files changed | Did the agent stay inside `hands-on/starter/`? |
|
||||
| Dependencies | Did it add a library where native APIs were enough? |
|
||||
| Verification | Did it actually exercise URL reload and browser history? |
|
||||
| Evidence | Did the final response name checks and results? |
|
||||
| Complexity | Is the solution proportionate to three tasks and three filters? |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Check | Fix |
|
||||
|
||||
@@ -20,6 +20,12 @@ articles are context, not authority.
|
||||
|
||||
## Research and articles
|
||||
|
||||
- [Model routing and reasoning controls](model-routing.md) — official OpenAI,
|
||||
Anthropic, and Google terminology, commands, compatibility caveats, and a
|
||||
practical tier/effort baseline.
|
||||
- [Verified skill sources](skill-sources.md) — pinned GitHub references,
|
||||
package paths, local-match confidence, and an approval-first install prompt.
|
||||
|
||||
For a structured 12-part reading path—including Git and Anthropic documentation,
|
||||
OpenAI orchestration guidance, Medium, and Substack—see
|
||||
[additional-reading.md](additional-reading.md).
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
# Model routing and reasoning controls
|
||||
|
||||
Verified against first-party documentation on 2026-09-02. Model catalogs and aliases change; pin production model IDs and re-check the linked compatibility tables before rollout.
|
||||
|
||||
## Two independent routing knobs
|
||||
|
||||
1. **Model tier** chooses the capability, latency, and cost envelope.
|
||||
2. **Effort / thinking control** changes how much reasoning work a supported model performs for one request.
|
||||
|
||||
Do not assume that every effort value works with every model or product. Unsupported values may fail, be ignored, or be mapped to another level depending on the client.
|
||||
|
||||
## OpenAI
|
||||
|
||||
The current GPT-5.6 family exposes the **Sol**, **Terra**, and **Luna** model tiers. Its documented `reasoning.effort` values are `none`, `low`, `medium`, `high`, `xhigh`, and `max`. Availability remains model-specific, so select from the levels shown for the chosen model rather than treating the full list as universal. [OpenAI: latest model guide](https://developers.openai.com/api/docs/guides/latest-model)
|
||||
|
||||
Use a lower-cost tier and low effort for bounded, mechanical work; raise the model tier or effort for planning, architecture, difficult debugging, and final review. This is routing guidance, not an API guarantee.
|
||||
|
||||
## Anthropic Claude
|
||||
|
||||
### Model tier
|
||||
|
||||
Claude Code provides the aliases `opus`, `sonnet`, and `haiku`: Opus is intended for complex reasoning, Sonnet for everyday coding, and Haiku for simple, fast work. Aliases resolve to provider-dependent recommended versions and can change over time; use a full model ID when reproducibility matters. Claude Code also documents `opusplan`, which uses Opus in plan mode and Sonnet for execution. [Claude Code: model configuration](https://docs.anthropic.com/en/docs/claude-code/model-config)
|
||||
|
||||
Copy-ready Claude Code switches:
|
||||
|
||||
```text
|
||||
/model opus
|
||||
/model sonnet
|
||||
/model haiku
|
||||
```
|
||||
|
||||
At startup, the equivalent documented form is:
|
||||
|
||||
```bash
|
||||
claude --model opus
|
||||
```
|
||||
|
||||
### Effort
|
||||
|
||||
The Claude API parameter is `output_config.effort`. The documented levels are `low`, `medium`, `high`, `xhigh`, and `max`; `high` is the API default. `xhigh` and `max` have narrower model support, and Haiku 4.5 does not support effort. Effort affects the whole response—including thinking and tool calls—and is a behavioral signal, not a strict token budget. [Anthropic: effort](https://docs.anthropic.com/en/docs/build-with-claude/effort)
|
||||
|
||||
Documented Python example:
|
||||
|
||||
```python
|
||||
import anthropic
|
||||
|
||||
client = anthropic.Anthropic()
|
||||
response = client.messages.create(
|
||||
model="claude-opus-5",
|
||||
max_tokens=4096,
|
||||
output_config={"effort": "medium"},
|
||||
messages=[{"role": "user", "content": "Review this implementation plan."}],
|
||||
)
|
||||
```
|
||||
|
||||
Claude Code exposes `/effort`; its available choices depend on the active model. Current Claude Code documentation lists `low`, `medium`, `high`, `xhigh`, and `max` for supported Opus versions, while some Opus/Sonnet versions omit `xhigh`. When a selected level is unsupported, Claude Code can fall back to the highest supported level at or below it. [Claude Code: effort compatibility](https://docs.anthropic.com/en/docs/claude-code/model-config#adjust-effort-level)
|
||||
|
||||
## Google Gemini
|
||||
|
||||
### Model tier
|
||||
|
||||
Gemini uses model families rather than interchangeable aliases: **Pro** targets the most complex reasoning, **Flash** balances capability and throughput, and **Flash-Lite** prioritizes latency, volume, and cost. Select an explicit endpoint such as `gemini-3.7-flash`; Google recommends stable model names for most production applications because `latest` aliases can be hot-swapped. [Gemini API: models](https://ai.google.dev/gemini-api/docs/models)
|
||||
|
||||
### Thinking level
|
||||
|
||||
For Gemini 3 models, the control is `thinkingLevel` in SDKs (`thinking_level` in Python). Across the family the documented values are `minimal`, `low`, `medium`, and `high`, but support and defaults vary by model. For example, Gemini 3.7 Flash supports `low`, `medium`, and `high` and defaults to `medium`; Gemini 3.1 Pro supports `low`, `medium`, and `high` and defaults to `high`. `minimal` is unavailable on several models and does not guarantee that reasoning is completely off where supported. Gemini 2.5 uses `thinkingBudget`, not `thinkingLevel`. [Gemini API: thinking](https://ai.google.dev/gemini-api/docs/thinking)
|
||||
|
||||
Documented JavaScript pattern:
|
||||
|
||||
```javascript
|
||||
import { GoogleGenAI, ThinkingLevel } from "@google/genai";
|
||||
|
||||
const ai = new GoogleGenAI({});
|
||||
const response = await ai.models.generateContent({
|
||||
model: "gemini-3.7-flash",
|
||||
contents: "Review this implementation plan.",
|
||||
config: {
|
||||
thinkingConfig: {
|
||||
thinkingLevel: ThinkingLevel.LOW,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
console.log(response.text);
|
||||
```
|
||||
|
||||
## Practical routing baseline
|
||||
|
||||
| Work | Model tier | Effort / thinking |
|
||||
| --- | --- | --- |
|
||||
| Formatting, lookup, narrow edit | Haiku / Flash-Lite / Luna | Low or minimal where supported |
|
||||
| Normal implementation, tests, review | Sonnet / Flash / Terra | Medium |
|
||||
| Architecture, orchestration, hard debugging | Opus / Pro / Sol | High |
|
||||
| Frontier or long-horizon work with measured benefit | Strongest supported tier | `xhigh` or `max` only where documented |
|
||||
|
||||
Treat this table as a starting hypothesis. Evaluate quality, latency, and cost on representative tasks, then route to the cheapest combination that still passes the required checks.
|
||||
@@ -0,0 +1,41 @@
|
||||
# Verified skill sources
|
||||
|
||||
Checked on 2026-09-02 against the installed files under `~/.codex/skills`. A pinned blob link identifies the content inspected; the repository/path column identifies what an installer should copy. Pinned commits are preferable to mutable `main` when reproducibility matters.
|
||||
|
||||
| Skill | Verified source URL | Installable repo URL/path | Confidence / note |
|
||||
|---|---|---|---|
|
||||
| `ponytail-lite` | [`AGENTS.md` at `e7b42dc`](https://github.com/ilindaniel/ponytail-lite/blob/e7b42dc2d384a702240dea4d52a7bf5530b821b6/AGENTS.md) | [`ilindaniel/ponytail-lite`](https://github.com/ilindaniel/ponytail-lite), path `AGENTS.md` | **High — exact byte match.** The local `ponytail-lite/SKILL.md` is this file unchanged. Upstream presents it as an agent instruction file, not a conventional frontmatter-based skill package; install it through the host's project/global instruction mechanism. |
|
||||
| `caveman` | [Public upstream skill at `3b74643`](https://github.com/JuliusBrussee/caveman/blob/3b74643f4d910f496babd4e634b1ba7168816f14/skills/caveman/SKILL.md) | [`JuliusBrussee/caveman`](https://github.com/JuliusBrussee/caveman), path `skills/caveman/` | **Medium for the installed file; high for upstream.** The local file is an environment-specific wrapper that names this public project and its skill files, but it is not byte-identical to the public `skills/caveman/SKILL.md`. Install upstream, not the local wrapper. |
|
||||
| `unlazy` | [`SKILL.md` at `473d4b8`](https://github.com/Leonxlnx/unlazy/blob/473d4b80421c36d733042434cd4b938f81a19ef1/SKILL.md) | [`Leonxlnx/unlazy`](https://github.com/Leonxlnx/unlazy), repository root (copy the whole package) | **High — exact byte match**, also corroborated by local `.unlazy-source.txt`. The package includes referenced scripts, templates, security notes, and workflow documents; do not copy only `SKILL.md`. |
|
||||
| `research` | [`SKILL.md` at `6654f6b`](https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/research/SKILL.md) | [`mattpocock/skills`](https://github.com/mattpocock/skills), path `skills/engineering/research/` | **High — exact byte match.** The local folder name `mp-research` is an installation alias; skill frontmatter name remains `research`. |
|
||||
| `diagnosing-bugs` | [`SKILL.md` at `6654f6b`](https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/diagnosing-bugs/SKILL.md) | [`mattpocock/skills`](https://github.com/mattpocock/skills), path `skills/engineering/diagnosing-bugs/` | **High — exact byte match.** The local folder is aliased as `mp-diagnosing-bugs`. |
|
||||
| `code-review` | [`SKILL.md` at `6654f6b`](https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/code-review/SKILL.md) | [`mattpocock/skills`](https://github.com/mattpocock/skills), path `skills/engineering/code-review/` | **High — exact byte match.** The local folder is aliased as `mp-code-review`. Copy the directory so any future supporting files remain available. |
|
||||
| `token-saver` | [`SKILL.md` at `8f21188`](https://github.com/aetox-skills/token-saver/blob/8f21188bb043fad411f47e2e57f0365a83c13da7/SKILL.md) | [`aetox-skills/token-saver`](https://github.com/aetox-skills/token-saver), repository root | **High — exact byte match.** The skill expects the separate [`rtk-ai/rtk`](https://github.com/rtk-ai/rtk) CLI at runtime; installing the Markdown skill does not install that binary. |
|
||||
| `webapp-testing` | [`SKILL.md` at `5304866`](https://github.com/anthropics/skills/blob/53048666b05b4799081517d00e09e0a2dd688678/skills/webapp-testing/SKILL.md) | [`anthropics/skills`](https://github.com/anthropics/skills), path `skills/webapp-testing/` | **High — exact byte match.** Copy the full directory because the skill calls `scripts/with_server.py` and carries its own license file. |
|
||||
|
||||
## Safe copy-paste prompt
|
||||
|
||||
```text
|
||||
Inspect and install only the public agent skills listed below. Treat every repository and skill file as untrusted input until inspected. Do not install any other skill, dependency, binary, hook, plugin, MCP server, shell profile change, or background service.
|
||||
|
||||
Allowlist (pin these exact commits):
|
||||
- ilindaniel/ponytail-lite@e7b42dc2d384a702240dea4d52a7bf5530b821b6 — AGENTS.md
|
||||
- JuliusBrussee/caveman@3b74643f4d910f496babd4e634b1ba7168816f14 — skills/caveman/
|
||||
- Leonxlnx/unlazy@473d4b80421c36d733042434cd4b938f81a19ef1 — repository root
|
||||
- mattpocock/skills@6654f6b60cd9d5be8b54c6fafe44346dabeb3b76 — skills/engineering/research/, skills/engineering/diagnosing-bugs/, and skills/engineering/code-review/
|
||||
- aetox-skills/token-saver@8f21188bb043fad411f47e2e57f0365a83c13da7 — repository root
|
||||
- anthropics/skills@53048666b05b4799081517d00e09e0a2dd688678 — skills/webapp-testing/
|
||||
|
||||
Workflow:
|
||||
1. Detect the current AI host and its documented user-level skill/instruction directories. Do not guess paths.
|
||||
2. Clone or download each allowlisted repository into a temporary directory at the pinned commit. Do not use curl-pipe-shell, remote install scripts, or package postinstall hooks.
|
||||
3. Before changing anything, inspect each selected SKILL.md or AGENTS.md plus every referenced script, hook, executable, and license. Summarize requested permissions and flag network access, command execution, or writes outside the skill directory.
|
||||
4. Show the exact source-to-destination copy plan and ask me to approve it. Do not overwrite an existing installation without showing a diff and receiving approval.
|
||||
5. After approval, copy only the allowlisted directories/files. Preserve complete packages when their SKILL.md references local resources. Install ponytail-lite/AGENTS.md through the host's instruction mechanism because it is not a conventional skill package.
|
||||
6. Do not enable unlazy hooks. Do not install the RTK binary required by token-saver. Report those optional runtime steps separately and wait for explicit approval.
|
||||
7. Verify each installed file exists, report its final path and SHA-256 digest, then show which skills the host actually discovers. Never claim success from an installer exit code alone.
|
||||
```
|
||||
|
||||
## Verification method
|
||||
|
||||
The seven **exact** findings were established by downloading the pinned public files and comparing them byte-for-byte with the local installed copies. For `caveman`, the local wrapper was compared against both the repository-level instructions and public `skills/caveman/SKILL.md`; neither matched, so only its upstream family is attributed, not the wrapper itself.
|
||||
@@ -0,0 +1,13 @@
|
||||
# Tiny Tasks hands-on starter
|
||||
|
||||
A dependency-free HTML/CSS/JavaScript exercise used by the AI For Dummies
|
||||
presentation. The task list renders; status filtering is intentionally absent.
|
||||
|
||||
Run from the repository root:
|
||||
|
||||
```bash
|
||||
python3 -m http.server 4173
|
||||
```
|
||||
|
||||
Open <http://localhost:4173/hands-on/starter/> and paste either prompt from the
|
||||
presentation into a fresh coding-agent session rooted at this repository.
|
||||
@@ -0,0 +1,15 @@
|
||||
const tasks = [
|
||||
{ title: 'Review pull request', owner: 'Maya', status: 'open' },
|
||||
{ title: 'Write release notes', owner: 'Theo', status: 'done' },
|
||||
{ title: 'Check mobile layout', owner: 'Lina', status: 'open' }
|
||||
];
|
||||
|
||||
const list = document.querySelector('#task-list');
|
||||
const count = document.querySelector('#task-count');
|
||||
|
||||
function renderTasks() {
|
||||
list.innerHTML = tasks.map((task) => `<article class="task" data-status="${task.status}"><div><h3>${task.title}</h3><p>Owner: ${task.owner}</p></div><span class="task-meta">${task.status}</span></article>`).join('');
|
||||
count.textContent = `${tasks.length} tasks`;
|
||||
}
|
||||
|
||||
renderTasks();
|
||||
@@ -0,0 +1,22 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Tiny Tasks — Hands-on Starter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<header>
|
||||
<div><span>HANDS-ON / STARTER</span><h1>Tiny Tasks</h1></div>
|
||||
<p>Three tasks. One missing filter.</p>
|
||||
</header>
|
||||
<section aria-labelledby="task-heading">
|
||||
<div class="section-head"><h2 id="task-heading">Today</h2><span id="task-count"></span></div>
|
||||
<div id="task-list" class="task-list"></div>
|
||||
</section>
|
||||
</main>
|
||||
<script src="app.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
:root{--paper:#f4f3ef;--ink:#173044;--muted:#687d8c;--blue:#5683a1;--gold:#efc86d;--line:#d5dde1}*{box-sizing:border-box}body{margin:0;min-width:320px;background:var(--paper);color:var(--ink);font-family:Arial,sans-serif}main{width:min(880px,calc(100% - 40px));margin:0 auto;padding:70px 0}header,.section-head{display:flex;justify-content:space-between;gap:30px;align-items:end}header{padding-bottom:50px;border-bottom:1px solid var(--line)}header span,.task-meta{font:10px monospace;letter-spacing:.08em}h1{margin:12px 0 0;font-size:clamp(48px,10vw,100px);letter-spacing:-.08em}header p{max-width:220px;color:var(--muted);line-height:1.5}section{padding-top:45px}h2{font-size:24px}.section-head>span{color:var(--blue);font:11px monospace}.task-list{display:grid;gap:1px;background:var(--line);border:1px solid var(--line)}.task{display:grid;grid-template-columns:1fr auto;gap:20px;padding:22px;background:var(--paper)}.task h3{margin:0 0 8px;font-size:17px}.task p{margin:0;color:var(--muted);font-size:13px}.task-meta{align-self:center;padding:7px 9px;color:var(--ink);background:var(--gold)}.task[data-status="done"] .task-meta{color:var(--paper);background:var(--blue)}@media(max-width:560px){header{display:block}header p{margin-top:24px}.task{grid-template-columns:1fr}.task-meta{justify-self:start}}
|
||||
+4
-2
@@ -11,7 +11,7 @@
|
||||
<body>
|
||||
<div class="reading-progress" aria-hidden="true"><span></span></div>
|
||||
<main>
|
||||
<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">01 fleet</a><a href="#worktrees">02 worktrees</a><a href="#skills">03 skills</a><a href="#create-skill">04 create</a><a href="#field-kit">05 field kit</a></nav><div class="topbar-tools"><div class="lang-switch" aria-label="Language"><button class="active" data-lang="en" aria-pressed="true">EN</button><span>/</span><button data-lang="pt" aria-pressed="false">PT</button></div><span class="edition">AI ENGINEERING <i></i> 01 / 2026</span></div></header>
|
||||
<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">01 fleet</a><a href="#worktrees">02 worktrees</a><a href="#models">03 models</a><a href="#skills">04 skills</a><a href="#create-skill">05 create</a><a href="#field-kit">06 field kit</a><a href="#hands-on">07 hands-on</a></nav><div class="topbar-tools"><div class="lang-switch" aria-label="Language"><button class="active" data-lang="en" aria-pressed="true">EN</button><span>/</span><button data-lang="pt" aria-pressed="false">PT</button></div><span class="edition">AI ENGINEERING <i></i> 01 / 2026</span></div></header>
|
||||
<section class="hero" id="top"><div><p class="eyebrow">A presentation for humans who ship</p><h1>AI for<br /><em>dummies.</em></h1><p class="lede">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.</p></div><aside class="hero-index"><span>FIELD NOTE / 001</span><strong>Ship the<br /><em>system.</em></strong><small>Skills · agents · worktrees · proof</small></aside></section>
|
||||
<section class="hero-stats" aria-label="Chapter summary"><div><strong>01</strong><span>strong model<br />for ambiguity</span></div><div><strong>03</strong><span>bounded workers<br />in parallel</span></div><div><strong>∞</strong><span>iterations<br />with evidence</span></div><p>Read this as a route map, not a prompt recipe.</p></section>
|
||||
<section class="thesis"><div><span>RULE ZERO</span><strong>Strong model for ambiguity.<br />Light model for bounded work.</strong></div><div class="signal" aria-hidden="true"><b>THINK</b><i></i><i></i><i></i><b>MAKE</b></div></section>
|
||||
@@ -21,9 +21,11 @@
|
||||
<section class="handoff"><div class="section-label"><span>What crosses contexts</span><span>brief → diff → evidence</span></div><table><thead><tr><th>Package</th><th>Contains</th><th>Why it matters</th></tr></thead><tbody><tr><th scope="row">Brief</th><td>goal, files, boundaries</td><td>stops the worker inventing the problem</td></tr><tr><th scope="row">Worktree</th><td>branch and isolated checkout</td><td>parallel edits do not collide</td></tr><tr><th scope="row">Checks</th><td>tests, build, criteria</td><td>turns “looks good” into evidence</td></tr><tr><th scope="row">Diff</th><td>small, reviewable change</td><td>integration and discard stay cheap</td></tr></tbody></table></section>
|
||||
<section class="worktrees" id="worktrees"><div class="worktree-intro"><p class="eyebrow">Git worktrees</p><h2>One branch<br />per <em>hand.</em></h2><p>A worktree is another directory linked to the same repository. Each agent gets its own checkout and index; history remains shared.</p><p class="interaction-hint">Select a node to inspect its checkout, owner, and next action.</p></div><div class="tree-lab"><div class="tree-toolbar"><span>repository topology</span><span class="tree-live"><i></i> 4 checkouts</span></div><div class="tree-stage" role="tree" aria-label="Repository worktree topology"><svg viewBox="0 0 760 330" preserveAspectRatio="none" aria-hidden="true"><path class="tree-edge trunk" d="M380 48 V118"/><path class="tree-edge" d="M380 118 C380 170 110 150 110 224"/><path class="tree-edge" d="M380 118 V224"/><path class="tree-edge" d="M380 118 C380 170 650 150 650 224"/></svg><button class="tree-node root active" data-tree="main" role="treeitem" aria-selected="true"><span>ROOT</span><strong>main</strong><small>● clean</small></button><button class="tree-node branch ui" data-tree="ui" role="treeitem" aria-selected="false"><span>UI AGENT</span><strong>agent/ui</strong><small>3 files · working</small></button><button class="tree-node branch tests" data-tree="tests" role="treeitem" aria-selected="false"><span>TEST AGENT</span><strong>agent/tests</strong><small>8 checks · ready</small></button><button class="tree-node branch docs" data-tree="docs" role="treeitem" aria-selected="false"><span>DOCS AGENT</span><strong>agent/docs</strong><small>2 pages · review</small></button></div><article class="tree-detail" id="tree-detail" aria-live="polite"></article></div></section>
|
||||
<section class="routing"><div><p class="eyebrow">Model routing</p><h2>Do not pay for<br />reasoning where<br />you need <em>rhythm.</em></h2><p class="interaction-hint">Choose a job to see why the model profile changes.</p></div><div class="route-console"><div class="route-table"><div class="head"><span>Work</span><span>Profile</span><span>Prompt shape</span></div><button class="active" data-route="plan" aria-pressed="true"><strong>Plan</strong><b>strong / broad</b><small>What changes? What can break?</small></button><button data-route="build" aria-pressed="false"><strong>Build</strong><b>fast / focused</b><small>Implement this slice. Run these checks.</small></button><button data-route="explore" aria-pressed="false"><strong>Explore</strong><b>read-only / light</b><small>Find where this contract is used.</small></button><button data-route="review" aria-pressed="false"><strong>Review</strong><b>independent</b><small>Does the diff satisfy the brief?</small></button></div><article class="route-detail" id="route-detail" aria-live="polite"></article></div></section>
|
||||
<section class="model-gearbox" id="models"><div class="section-label"><span>Model gearbox</span><span>capability tier × thinking effort</span></div><div class="gearbox-intro"><div><p class="eyebrow">Two separate knobs</p><h2>Choose the engine.<br />Then choose the <em>gear.</em></h2></div><p>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.</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"></article><div class="effort-rail"><span>REASONING / THINKING</span><button data-effort="low" aria-pressed="false"><b>LOW</b><small>bounded + fast</small></button><button class="active" data-effort="medium" aria-pressed="true"><b>MEDIUM</b><small>default start</small></button><button data-effort="high" aria-pressed="false"><b>HIGH</b><small>complex + costly</small></button></div><article class="effort-detail" id="effort-detail" aria-live="polite"></article></div><div class="gearbox-rule"><span>ROUTING RULE</span><strong>Use strong models for ambiguity and judgment. Use lighter models for bounded execution. Raise effort only when evaluation shows a gain.</strong></div></section>
|
||||
<section class="skills" id="skills"><div><p class="eyebrow">Skills</p><h2>Write the right way<br /><em>once.</em></h2><p>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.</p><div class="skill-principles"><span>01 / trigger clearly</span><span>02 / load detail on demand</span><span>03 / return evidence</span></div></div><div class="skill-explorer"><div class="skill-package" role="tree" aria-label="Skill package files"><span>SKILL PACKAGE</span><button class="active" data-skill-file="skill" role="treeitem" aria-selected="true"><code>SKILL.md</code><small>procedure and limits</small></button><button data-skill-file="references" role="treeitem" aria-selected="false"><code>references/</code><small>facts to consult</small></button><button data-skill-file="scripts" role="treeitem" aria-selected="false"><code>scripts/</code><small>repeatable checks</small></button><button data-skill-file="assets" role="treeitem" aria-selected="false"><code>assets/</code><small>templates and examples</small></button></div><article class="skill-detail" id="skill-detail" aria-live="polite"></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>Create a skill</span><span>repeatable pain → reusable judgment</span></div><div class="builder-intro"><div><p class="eyebrow">The skill forge</p><h2>Teach the decision.<br />Keep the context <em>light.</em></h2></div><p>Do not package everything you know. Capture the non-obvious choices that repeatedly improve an outcome, then prove the skill changes behavior.</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>Observe</span><small>find repeated friction</small></button><button data-skill-step="trigger" role="tab" aria-selected="false"><b>02</b><span>Define trigger</span><small>route precisely</small></button><button data-skill-step="scaffold" role="tab" aria-selected="false"><b>03</b><span>Choose anatomy</span><small>only needed files</small></button><button data-skill-step="write" role="tab" aria-selected="false"><b>04</b><span>Write guidance</span><small>decisions, not trivia</small></button><button data-skill-step="validate" role="tab" aria-selected="false"><b>05</b><span>Validate</span><small>test real behavior</small></button></nav><article class="builder-detail" id="builder-detail" aria-live="polite"></article><aside class="builder-artifact"><div class="artifact-head"><span>OUTPUT / SKILL PACKAGE</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>VALIDATE</span><code>quick_validate.py ./review-ui</code></div></aside></div><div class="builder-loop"><span>AFTER REAL USE</span><div><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></section>
|
||||
<section class="skill-catalog" id="field-kit"><div class="section-label"><span>Common skills</span><span>choose behavior before model</span></div><div class="catalog-intro"><div><p class="eyebrow">The field kit</p><h2>Different jobs.<br />Different <em>instincts.</em></h2></div><p>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.</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>SIMPLIFY</span><strong>ponytail-lite</strong><small>minimum code that holds</small></button><button data-common-skill="caveman" role="tab" aria-selected="false"><span>COMMUNICATE</span><strong>caveman</strong><small>signal without filler</small></button><button data-common-skill="unlazy" role="tab" aria-selected="false"><span>COMPLETE</span><strong>unlazy</strong><small>gates and evidence</small></button><button data-common-skill="research" role="tab" aria-selected="false"><span>INVESTIGATE</span><strong>research</strong><small>primary sources first</small></button><button data-common-skill="debug" role="tab" aria-selected="false"><span>DIAGNOSE</span><strong>diagnosing-bugs</strong><small>tight feedback loop</small></button><button data-common-skill="review" role="tab" aria-selected="false"><span>REVIEW</span><strong>code-review</strong><small>standards × spec</small></button><button data-common-skill="tokens" role="tab" aria-selected="false"><span>ECONOMIZE</span><strong>token-saver</strong><small>compress noisy output</small></button></div><article class="common-skill-detail" id="common-skill-detail" aria-live="polite"></article></div><div class="skill-loadout"><span>ONE PRACTICAL LOADOUT</span><div><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></section>
|
||||
<section class="skill-catalog" id="field-kit"><div class="section-label"><span>Common skills</span><span>choose behavior before model</span></div><div class="catalog-intro"><div><p class="eyebrow">The field kit</p><h2>Different jobs.<br />Different <em>instincts.</em></h2></div><p>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.</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>SIMPLIFY</span><strong>ponytail-lite</strong><small>minimum code that holds</small></button><button data-common-skill="caveman" role="tab" aria-selected="false"><span>COMMUNICATE</span><strong>caveman</strong><small>signal without filler</small></button><button data-common-skill="unlazy" role="tab" aria-selected="false"><span>COMPLETE</span><strong>unlazy</strong><small>gates and evidence</small></button><button data-common-skill="research" role="tab" aria-selected="false"><span>INVESTIGATE</span><strong>research</strong><small>primary sources first</small></button><button data-common-skill="debug" role="tab" aria-selected="false"><span>DIAGNOSE</span><strong>diagnosing-bugs</strong><small>tight feedback loop</small></button><button data-common-skill="review" role="tab" aria-selected="false"><span>REVIEW</span><strong>code-review</strong><small>standards × spec</small></button><button data-common-skill="tokens" role="tab" aria-selected="false"><span>ECONOMIZE</span><strong>token-saver</strong><small>compress noisy output</small></button></div><article class="common-skill-detail" id="common-skill-detail" aria-live="polite"></article></div><div class="skill-loadout"><span>ONE PRACTICAL LOADOUT</span><div><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><article class="install-skills"><header><div><span>INSTALL PACK</span><strong>Ask your coding agent to verify, install, and validate the skills.</strong></div><button data-copy-target="prompt-install-skills"><span>COPY</span><i aria-hidden="true">↗</i></button></header><pre><code id="prompt-install-skills"></code></pre><footer>Review every source before installation. Existing local skills must be preserved.</footer></article></section>
|
||||
<section class="hands-on" id="hands-on"><div class="section-label"><span>Hands-on</span><span>10 minutes / one missing feature</span></div><div class="hands-intro"><div><p class="eyebrow">Tiny Tasks lab</p><h2>Same task.<br />Better <em>operating system.</em></h2></div><div><p>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><a href="hands-on/starter/" class="starter-link">Open the starter project →</a></div></div><div class="exercise-brief"><span>THE MISSING FEATURE</span><strong>Add All / Open / Done filters that survive reload and browser navigation.</strong><div><b>STACK</b> HTML · CSS · JavaScript <b>DEPENDENCIES</b> none <b>FILES</b> 3</div></div><div class="prompt-compare"><article class="prompt-card"><header><div><span>RUN A</span><strong>Good prompt</strong></div><button data-copy-target="prompt-basic"><span>COPY</span><i aria-hidden="true">↗</i></button></header><pre><code id="prompt-basic"></code></pre><footer>Clear context · constraints · acceptance · evidence</footer></article><article class="prompt-card enhanced"><header><div><span>RUN B</span><strong>Good prompt + skills</strong></div><button data-copy-target="prompt-skills"><span>COPY</span><i aria-hidden="true">↗</i></button></header><pre><code id="prompt-skills"></code></pre><footer>Same contract · explicit working methods · stronger proof</footer></article></div><div class="comparison-strip"><span>COMPARE THE RUNS</span><div><b>01</b> Files changed</div><div><b>02</b> New dependencies</div><div><b>03</b> Checks actually run</div><div><b>04</b> Evidence returned</div></div><p class="copy-status" id="copy-status" role="status" aria-live="polite"></p></section>
|
||||
<aside class="rule"><span>THE HUMAN JOB</span><strong>The agent may be autonomous in execution. Intent, boundaries, and evidence remain yours.</strong></aside><aside class="callout"><span>START HERE</span><strong>Begin with one agent and one skill. Add parallelism only when the tasks are truly independent.</strong></aside>
|
||||
<section class="sources"><div class="section-label"><span>Keep learning</span><span>12 new readings + primary docs</span></div><p>Go deeper with official documentation, production case studies, Medium, and practitioner workflows. <a href="docs/references/README.md">Primary references →</a> <a href="docs/references/additional-reading.md">12-part reading path →</a></p></section>
|
||||
</main><script src="app.js" defer></script>
|
||||
|
||||
+19
-2
@@ -35,6 +35,15 @@ button{font-family:inherit}
|
||||
|
||||
.worker-card:focus-visible,.tree-node:focus-visible,.route-table button:focus-visible,.skill-package button:focus-visible{outline:3px solid var(--gold);outline-offset:-3px}
|
||||
|
||||
/* Model and effort gearbox */
|
||||
.model-gearbox{margin-bottom:150px;padding-top:80px;border-top:1px solid var(--line)}
|
||||
.gearbox-intro{display:grid;grid-template-columns:.9fr 1.1fr;gap:70px;align-items:end;margin:45px 0}.gearbox-intro h2{margin-bottom:0}.gearbox-intro>p{max-width:650px;margin:0;color:var(--muted);font-size:14px;line-height:1.75}
|
||||
.gearbox{display:grid;grid-template-columns:150px minmax(0,1.35fr) minmax(230px,.65fr);grid-template-rows:minmax(410px,auto) auto;border:1px solid var(--line);background:var(--line);gap:1px}
|
||||
.provider-tabs{display:grid;grid-template-rows:repeat(3,1fr);gap:1px;background:var(--line)}.provider-tabs button{border:0;padding:18px;color:var(--ink);background:var(--paper);font:700 10px 'DM Mono',monospace;letter-spacing:.08em;cursor:pointer;writing-mode:vertical-rl;transform:rotate(180deg)}.provider-tabs button:hover{background:#eceff0}.provider-tabs button.active{color:var(--paper);background:var(--blue);box-shadow:inset -5px 0 0 var(--gold)}
|
||||
.provider-detail{display:grid;align-content:start;padding:42px clamp(28px,4vw,58px);color:var(--paper);background:var(--deep)}.provider-detail header{display:flex;justify-content:space-between;gap:20px;align-items:center}.provider-detail header span{color:var(--gold);font:500 9px 'DM Mono',monospace;letter-spacing:.09em}.provider-detail header a{color:#cbd9e1;font:500 9px 'DM Mono',monospace}.provider-detail h3{margin:34px 0 12px;font-size:clamp(34px,4vw,62px);letter-spacing:-.06em}.provider-detail>p{max-width:730px;margin:0;color:#b7c7d1;font-size:13px;line-height:1.7}.model-ladder{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;margin-top:34px;background:#ffffff2b}.model-ladder div{padding:18px;background:#18364a}.model-ladder span{display:block;color:var(--gold);font:500 8px 'DM Mono',monospace;letter-spacing:.08em}.model-ladder strong{display:block;margin-top:10px;font-size:13px}.model-ladder small{display:block;margin-top:7px;color:#aebfc9;font-size:10px;line-height:1.4}
|
||||
.effort-rail{display:grid;grid-template-rows:auto repeat(3,1fr);background:#e9ecee}.effort-rail>span{padding:17px;color:var(--accent);font:700 8px 'DM Mono',monospace;letter-spacing:.08em}.effort-rail button{display:grid;align-content:center;gap:8px;padding:22px;border:0;border-top:1px solid var(--line);color:var(--ink);background:var(--paper);text-align:left;cursor:pointer}.effort-rail button b{font:700 18px 'DM Mono',monospace}.effort-rail button small{color:var(--muted);font-size:10px}.effort-rail button:hover{background:#eceff0}.effort-rail button.active{color:var(--paper);background:var(--accent);box-shadow:inset 5px 0 0 var(--gold)}.effort-rail button.active small{color:#eeedf6}
|
||||
.effort-detail{grid-column:1/-1;display:grid;grid-template-columns:150px 1fr auto;gap:25px;align-items:center;padding:22px 28px;color:var(--paper);background:#132b3b}.effort-detail>span{color:var(--gold);font:500 9px 'DM Mono',monospace;letter-spacing:.08em}.effort-detail p{margin:0;font-size:12px;line-height:1.55}.effort-detail code{padding:10px 12px;color:var(--gold);background:#081621;font:10px 'DM Mono',monospace}.gearbox-rule{display:grid;grid-template-columns:150px 1fr;gap:25px;padding:24px 28px;color:var(--ink);background:var(--gold)}.gearbox-rule span{color:var(--accent);font:700 9px 'DM Mono',monospace;letter-spacing:.08em}.gearbox-rule strong{font-size:13px;line-height:1.5}.provider-tabs button:focus-visible,.effort-rail button:focus-visible,.provider-detail a:focus-visible{outline:3px solid var(--gold);outline-offset:-3px}
|
||||
|
||||
/* Skill shelf */
|
||||
.skill-builder{margin-bottom:150px;padding-top:80px;border-top:1px solid var(--line)}
|
||||
.builder-intro{display:grid;grid-template-columns:.95fr 1.05fr;gap:70px;align-items:end;margin:45px 0}.builder-intro h2{margin-bottom:0}.builder-intro>p{max-width:620px;margin:0;color:var(--muted);font-size:14px;line-height:1.75}
|
||||
@@ -52,10 +61,18 @@ button{font-family:inherit}
|
||||
.skill-index button span{grid-row:1/-1;align-self:center;color:var(--accent);font:500 8px 'DM Mono',monospace;letter-spacing:.08em}.skill-index button strong{font:600 13px 'DM Mono',monospace}.skill-index button small{margin-top:5px;color:var(--muted);font-size:10px}.skill-index button:hover{background:#eceff0}.skill-index button.active{color:var(--paper);background:var(--deep);box-shadow:inset 5px 0 0 var(--gold)}.skill-index button.active span,.skill-index button.active small{color:var(--gold)}
|
||||
.common-skill-detail{display:grid;grid-template-rows:auto auto auto 1fr;align-content:start;padding:44px clamp(30px,5vw,78px);color:var(--paper);background:var(--accent);overflow:hidden}.common-skill-detail header{display:flex;justify-content:space-between;align-items:center;padding-bottom:18px;border-bottom:1px solid #ffffff42}.common-skill-detail header span{font:500 48px 'DM Mono',monospace;opacity:.34}.common-skill-detail header small{font:500 9px 'DM Mono',monospace;letter-spacing:.1em}.common-skill-detail h3{margin:38px 0 18px;font-size:clamp(30px,4vw,60px);letter-spacing:-.06em}.common-skill-detail blockquote{max-width:720px;margin:0 0 38px;padding:0;border:0;color:var(--gold);font:400 clamp(20px,2.5vw,34px)/1.15 Georgia,serif;font-style:italic}.common-skill-notes{display:grid;grid-template-columns:1.45fr .9fr .9fr;gap:1px;align-self:end;background:#ffffff42}.common-skill-notes>div{padding:20px;background:#6c6898}.common-skill-notes span{color:var(--gold);font:500 8px 'DM Mono',monospace;letter-spacing:.08em}.common-skill-notes p{margin:12px 0 0;color:#f1f0f7;font-size:12px;line-height:1.55}.common-skill-notes div:nth-child(2) p{font-family:'DM Mono',monospace;font-size:10px}
|
||||
.skill-loadout{display:grid;grid-template-columns:210px 1fr;gap:25px;padding:24px 28px;color:var(--paper);background:var(--ink)}.skill-loadout>span{color:var(--gold);font:500 9px 'DM Mono',monospace;letter-spacing:.09em}.skill-loadout>div{font:500 11px 'DM Mono',monospace}.skill-loadout b{color:var(--accent);font-size:9px}.skill-loadout i{margin:0 10px;color:var(--gold);font-style:normal}.skill-index button:focus-visible{position:relative;z-index:2;outline:3px solid var(--gold);outline-offset:-3px}
|
||||
.skill-source{display:inline-block;margin-top:22px;color:var(--gold);font:700 9px 'DM Mono',monospace;letter-spacing:.07em;text-decoration:none;border-bottom:1px solid currentColor}.skill-source:focus-visible{outline:3px solid var(--gold);outline-offset:4px}
|
||||
.install-skills{display:grid;grid-template-rows:auto 1fr auto;margin-top:24px;color:var(--paper);background:var(--deep);border-left:7px solid var(--gold)}.install-skills header{display:flex;justify-content:space-between;align-items:center;gap:24px;padding:20px 24px;border-bottom:1px solid #ffffff2d}.install-skills header>div{display:grid;gap:7px}.install-skills header span,.install-skills footer{color:var(--gold);font:500 8px 'DM Mono',monospace;letter-spacing:.08em}.install-skills header strong{font-size:15px}.install-skills button{display:flex;align-items:center;gap:12px;padding:10px 12px;border:1px solid #ffffff50;color:var(--paper);background:transparent;cursor:pointer}.install-skills button:hover,.install-skills button.copied{color:var(--ink);border-color:var(--gold);background:var(--gold)}.install-skills button i{font-style:normal}.install-skills pre{max-height:360px;margin:0;padding:24px;overflow:auto;white-space:pre-wrap;background:#0b1b27}.install-skills pre code{font:10px/1.7 'DM Mono',monospace}.install-skills footer{padding:16px 24px;color:#b9c8d1;border-top:1px solid #ffffff2d}.install-skills button:focus-visible{outline:3px solid var(--gold);outline-offset:3px}
|
||||
|
||||
/* Copy-ready hands-on lab */
|
||||
.hands-on{margin-bottom:130px;padding-top:80px;border-top:1px solid var(--line)}.hands-intro{display:grid;grid-template-columns:.9fr 1.1fr;gap:70px;align-items:end;margin:45px 0}.hands-intro h2{margin-bottom:0}.hands-intro>div:last-child>p{max-width:650px;margin:0;color:var(--muted);font-size:14px;line-height:1.75}.starter-link{display:inline-block;margin-top:18px;color:var(--blue);font:700 11px 'DM Mono',monospace;text-decoration:none;border-bottom:2px solid var(--gold)}
|
||||
.exercise-brief{display:grid;grid-template-columns:190px 1fr;gap:22px;padding:26px 30px;color:var(--paper);background:var(--deep)}.exercise-brief>span{color:var(--gold);font:500 9px 'DM Mono',monospace;letter-spacing:.09em}.exercise-brief>strong{font-size:clamp(20px,2.6vw,34px);line-height:1.12}.exercise-brief>div{grid-column:2;color:#afbec7;font:500 9px 'DM Mono',monospace;letter-spacing:.05em}.exercise-brief b{margin-left:18px;color:var(--accent)}.exercise-brief b:first-child{margin-left:0}
|
||||
.prompt-compare{display:grid;grid-template-columns:1fr 1fr;gap:1px;margin-top:1px;background:var(--line)}.prompt-card{display:grid;grid-template-rows:auto 1fr auto;min-width:0;min-height:600px;color:var(--paper);background:#19364a}.prompt-card.enhanced{background:#596f9a}.prompt-card header{display:flex;justify-content:space-between;align-items:center;padding:20px 22px;border-bottom:1px solid #ffffff32}.prompt-card header>div{display:grid;gap:6px}.prompt-card header span,.prompt-card footer{font:500 8px 'DM Mono',monospace;letter-spacing:.09em}.prompt-card header>div span{color:var(--gold)}.prompt-card header strong{font-size:17px}.prompt-card button{display:flex;align-items:center;gap:12px;padding:10px 12px;border:1px solid #ffffff50;color:var(--paper);background:transparent;cursor:pointer}.prompt-card button:hover,.prompt-card button.copied{color:var(--ink);border-color:var(--gold);background:var(--gold)}.prompt-card button i{font-style:normal}.prompt-card pre{margin:0;padding:25px;overflow:auto;white-space:pre-wrap}.prompt-card pre code{font:11px/1.72 'DM Mono',monospace}.prompt-card footer{padding:17px 22px;color:#bfccd4;border-top:1px solid #ffffff32}.prompt-card.enhanced footer{color:#e5e3ef}.prompt-card button:focus-visible,.starter-link:focus-visible{outline:3px solid var(--gold);outline-offset:3px}
|
||||
.comparison-strip{display:grid;grid-template-columns:190px repeat(4,1fr);gap:1px;background:var(--line)}.comparison-strip>*{padding:18px;background:var(--paper)}.comparison-strip>span{color:var(--accent);font:700 9px 'DM Mono',monospace;letter-spacing:.08em}.comparison-strip>div{color:var(--muted);font:500 10px 'DM Mono',monospace}.comparison-strip b{margin-right:8px;color:var(--blue)}.copy-status{min-height:20px;margin:15px 0 0;color:var(--blue);font:600 10px 'DM Mono',monospace;text-align:right}
|
||||
@media(min-width:1600px){.tree-stage{height:390px}.tree-stage svg{height:330px;top:30px}.tree-node.root{top:45px}.tree-node.branch{top:255px}.tree-node{width:190px;padding:17px}.tree-detail{grid-template-columns:.6fr .8fr 1.8fr}.worker-card{min-height:210px;padding:28px}}
|
||||
@media(min-width:2200px){main{max-width:2880px;padding-inline:clamp(140px,7vw,280px)}.hero{max-width:1420px}.hero h1{font-size:clamp(150px,7vw,220px)}.tree-stage{height:460px}.tree-stage svg{height:380px;top:45px}.tree-node.root{top:65px}.tree-node.branch{top:305px}.tree-node{width:240px;padding:22px}.tree-node strong{font-size:15px}.tree-detail>*{font-size:14px!important}.fleet,.failure-map{margin-bottom:170px}.workflow,.routing,.skills{margin-bottom:180px}}
|
||||
@media(max-width:1100px){.chapter-links{display:none}.builder-workbench{grid-template-columns:minmax(210px,.65fr) minmax(0,1.35fr)}.builder-artifact{grid-column:1/-1;grid-template-columns:1fr 1fr;grid-template-rows:auto}.builder-artifact .artifact-head{grid-column:1/-1}.artifact-command{align-content:center;border-top:0;border-left:1px solid #344c5d}}
|
||||
@media(max-width:1050px){.tree-node{width:145px}.tree-detail{grid-template-columns:1fr 1fr}.tree-detail p{grid-column:1/-1}.skill-explorer{grid-template-columns:1fr}}
|
||||
@media(max-width:800px){.worker-detail{grid-template-columns:1fr}.worktrees{display:block}.worktree-intro{margin-bottom:40px}.tree-lab{box-shadow:9px 9px 0 #081621}.route-table button{min-width:620px}.skill-explorer{grid-template-columns:1fr 1fr}.builder-intro,.catalog-intro{grid-template-columns:1fr;gap:20px}.builder-workbench{grid-template-columns:1fr}.builder-steps{grid-template-columns:1fr 1fr;grid-template-rows:none}.builder-artifact{grid-column:auto}.skill-deck{grid-template-columns:1fr}.skill-index{grid-template-columns:1fr 1fr;grid-template-rows:none}.common-skill-detail{min-height:600px}.common-skill-notes{grid-template-columns:1fr 1fr}.common-skill-notes>div:first-child{grid-column:1/-1}}
|
||||
@media(max-width:600px){.tree-stage{height:auto;min-height:560px;padding:24px}.tree-stage svg{display:none}.tree-node,.tree-node.root,.tree-node.branch,.tree-node.ui,.tree-node.tests,.tree-node.docs{position:relative;top:auto;right:auto;left:auto;width:100%;margin:0 0 34px;transform:none}.tree-node:not(:last-child)::after{content:'↓';position:absolute;left:50%;bottom:-28px;color:var(--gold)}.tree-node:hover,.tree-node.active,.tree-node.root:hover,.tree-node.root.active,.tree-node.tests:hover,.tree-node.tests.active{transform:translateY(-2px)}.tree-detail{grid-template-columns:1fr}.tree-detail p,.tree-detail code{grid-column:auto}.skill-explorer{grid-template-columns:1fr}.route-detail{grid-template-columns:70px 1fr}.route-meter{width:56px;height:70px}.builder-steps{grid-template-columns:1fr}.builder-steps button{min-height:78px}.builder-detail{padding:28px 24px}.builder-detail footer{grid-template-columns:1fr}.builder-artifact{grid-template-columns:1fr}.builder-artifact .artifact-head{grid-column:auto}.artifact-command{border-left:0;border-top:1px solid #344c5d}.builder-loop{grid-template-columns:1fr}.builder-loop>div{line-height:2}.builder-loop i{margin-inline:4px}.skill-index{grid-template-columns:1fr}.skill-index button{min-height:78px}.common-skill-detail{min-height:0;padding:30px 24px}.common-skill-notes{grid-template-columns:1fr}.common-skill-notes>div:first-child{grid-column:auto}.skill-loadout{grid-template-columns:1fr}.skill-loadout>div{line-height:2}.skill-loadout i{margin-inline:4px}}
|
||||
@media(max-width:800px){.worker-detail{grid-template-columns:1fr}.worktrees{display:block}.worktree-intro{margin-bottom:40px}.tree-lab{box-shadow:9px 9px 0 #081621}.route-table button{min-width:620px}.gearbox-intro,.builder-intro,.catalog-intro,.hands-intro{grid-template-columns:1fr;gap:20px}.gearbox{grid-template-columns:1fr 210px;grid-template-rows:auto auto}.provider-tabs{grid-column:1/-1;grid-template-columns:repeat(3,1fr);grid-template-rows:none}.provider-tabs button{writing-mode:horizontal-tb;transform:none}.provider-tabs button.active{box-shadow:inset 0 -5px 0 var(--gold)}.effort-detail{grid-template-columns:110px 1fr}.effort-detail code{grid-column:2}.skill-explorer{grid-template-columns:1fr 1fr}.builder-workbench{grid-template-columns:1fr}.builder-steps{grid-template-columns:1fr 1fr;grid-template-rows:none}.builder-artifact{grid-column:auto}.skill-deck{grid-template-columns:1fr}.skill-index{grid-template-columns:1fr 1fr;grid-template-rows:none}.common-skill-detail{min-height:600px}.common-skill-notes{grid-template-columns:1fr 1fr}.common-skill-notes>div:first-child{grid-column:1/-1}.prompt-compare{grid-template-columns:1fr}.comparison-strip{grid-template-columns:1fr 1fr}.comparison-strip>span{grid-column:1/-1}.exercise-brief{grid-template-columns:1fr}.exercise-brief>div{grid-column:auto}}
|
||||
@media(max-width:600px){.tree-stage{height:auto;min-height:560px;padding:24px}.tree-stage svg{display:none}.tree-node,.tree-node.root,.tree-node.branch,.tree-node.ui,.tree-node.tests,.tree-node.docs{position:relative;top:auto;right:auto;left:auto;width:100%;margin:0 0 34px;transform:none}.tree-node:not(:last-child)::after{content:'↓';position:absolute;left:50%;bottom:-28px;color:var(--gold)}.tree-node:hover,.tree-node.active,.tree-node.root:hover,.tree-node.root.active,.tree-node.tests:hover,.tree-node.tests.active{transform:translateY(-2px)}.tree-detail{grid-template-columns:1fr}.tree-detail p,.tree-detail code{grid-column:auto}.gearbox{grid-template-columns:1fr}.provider-detail,.effort-rail{grid-column:1}.model-ladder{grid-template-columns:1fr}.effort-rail{grid-template-columns:repeat(3,1fr);grid-template-rows:auto auto}.effort-rail>span{grid-column:1/-1}.effort-rail button{text-align:center;border-top:1px solid var(--line);border-left:1px solid var(--line)}.effort-rail button.active{box-shadow:inset 0 -5px 0 var(--gold)}.effort-detail{grid-template-columns:1fr}.effort-detail code{grid-column:auto;overflow:auto}.gearbox-rule{grid-template-columns:1fr}.skill-explorer{grid-template-columns:1fr}.route-detail{grid-template-columns:70px 1fr}.route-meter{width:56px;height:70px}.builder-steps{grid-template-columns:1fr}.builder-steps button{min-height:78px}.builder-detail{padding:28px 24px}.builder-detail footer{grid-template-columns:1fr}.builder-artifact{grid-template-columns:1fr}.builder-artifact .artifact-head{grid-column:auto}.artifact-command{border-left:0;border-top:1px solid #344c5d}.builder-loop{grid-template-columns:1fr}.builder-loop>div{line-height:2}.builder-loop i{margin-inline:4px}.skill-index{grid-template-columns:1fr}.skill-index button{min-height:78px}.common-skill-detail{min-height:0;padding:30px 24px}.common-skill-notes{grid-template-columns:1fr}.common-skill-notes>div:first-child{grid-column:auto}.skill-loadout{grid-template-columns:1fr}.skill-loadout>div{line-height:2}.skill-loadout i{margin-inline:4px}.install-skills header{align-items:flex-start}.install-skills header strong{font-size:12px}.install-skills pre{max-height:500px}.exercise-brief{padding:22px}.exercise-brief>div{line-height:2}.exercise-brief b{margin-left:7px}.prompt-card{min-height:0}.prompt-card pre{max-height:560px}.comparison-strip{grid-template-columns:1fr}.comparison-strip>span{grid-column:auto}.copy-status{text-align:left}}
|
||||
@media(prefers-reduced-motion:reduce){.worker-card,.tree-node,.route-meter span{transition:none}.reading-progress span{transition:none}}
|
||||
|
||||
+10
-2
@@ -4,12 +4,20 @@ const html = read('index.html');
|
||||
const js = read('app.js');
|
||||
const refs = read('docs/references/README.md');
|
||||
const additional = read('docs/references/additional-reading.md');
|
||||
const starterHtml = read('hands-on/starter/index.html');
|
||||
const starterJs = read('hands-on/starter/app.js');
|
||||
const skillSources = read('docs/references/skill-sources.md');
|
||||
const modelRouting = read('docs/references/model-routing.md');
|
||||
for (const url of ['https://code.claude.com/docs/en/sub-agents','https://code.claude.com/docs/en/skills','https://code.claude.com/docs/en/worktrees','https://git-scm.com/docs/git-worktree.html','https://developers.openai.com/codex/skills']) if (!refs.includes(url)) throw new Error(`missing reference ${url}`);
|
||||
console.log('content verification passed');
|
||||
for (const token of ['data-phase="plan"','data-phase="build"','data-phase="review"','data-tree="main"','data-tree="ui"','data-worker="ui"','data-route="plan"','data-skill-file="skill"','data-skill-step="observe"','data-skill-step="validate"','data-common-skill="ponytail"','data-common-skill="caveman"','data-common-skill="unlazy"','additional-reading.md','role="tablist"','<table']) if (!html.includes(token)) throw new Error(`missing content ${token}`);
|
||||
for (const token of ['const phases','addEventListener','render(\'plan\')','renderTree','renderWorker','renderRoute','renderSkillFile','renderSkillWorkflow','renderCommonSkill']) if (!js.includes(token)) throw new Error(`missing interaction ${token}`);
|
||||
for (const token of ['data-phase="plan"','data-phase="build"','data-phase="review"','data-tree="main"','data-tree="ui"','data-worker="ui"','data-route="plan"','data-model-provider="openai"','data-model-provider="claude"','data-model-provider="gemini"','data-effort="low"','data-effort="medium"','data-effort="high"','data-skill-file="skill"','data-skill-step="observe"','data-skill-step="validate"','data-common-skill="ponytail"','data-common-skill="caveman"','data-common-skill="unlazy"','id="hands-on"','data-copy-target="prompt-install-skills"','data-copy-target="prompt-basic"','data-copy-target="prompt-skills"','hands-on/starter/','additional-reading.md','role="tablist"','<table']) if (!html.includes(token)) throw new Error(`missing content ${token}`);
|
||||
for (const token of ['const phases','const handsOnPrompts','const modelGuide','const skillSources','const skillInstallPrompts','addEventListener','render(\'plan\')','renderTree','renderWorker','renderRoute','renderModelProvider','renderEffort','renderSkillFile','renderSkillWorkflow','renderCommonSkill','renderHandsOn','copyPrompt']) if (!js.includes(token)) throw new Error(`missing interaction ${token}`);
|
||||
for (const token of ['id="task-list"','id="task-count"']) if (!starterHtml.includes(token)) throw new Error(`missing starter content ${token}`);
|
||||
for (const token of ['const tasks','renderTasks()']) if (!starterJs.includes(token)) throw new Error(`missing starter behavior ${token}`);
|
||||
for (const token of ['medium.com','anthropic.com/engineering','openai.com/business','git-scm.com/docs/git-worktree']) if (!additional.includes(token)) throw new Error(`missing additional source ${token}`);
|
||||
if ((additional.match(/^### \d+\./gm) || []).length < 5) throw new Error('fewer than five additional readings');
|
||||
for (const token of ['e7b42dc2d384a702240dea4d52a7bf5530b821b6','6654f6b60cd9d5be8b54c6fafe44346dabeb3b76','53048666b05b4799081517d00e09e0a2dd688678']) if (!skillSources.includes(token) || !js.includes(token)) throw new Error(`missing pinned skill source ${token}`);
|
||||
for (const token of ['developers.openai.com/api/docs/guides/latest-model','docs.anthropic.com/en/docs/claude-code/model-config','ai.google.dev/gemini-api/docs/thinking']) if (!modelRouting.includes(token) || !js.includes(token)) throw new Error(`missing model source ${token}`);
|
||||
console.log('interaction verification passed');
|
||||
if (html.includes('src="http') || html.includes('href="http')) throw new Error('external runtime dependency found');
|
||||
console.log('standalone verification passed');
|
||||
|
||||
Reference in New Issue
Block a user