feat: assemble astro full guide
This commit is contained in:
@@ -0,0 +1,597 @@
|
|||||||
|
---
|
||||||
|
// /full-guide/ — assembled from typed guide collections and the task 10 blocks.
|
||||||
|
// This route deliberately never imports the legacy full-guide HTML: task 20 removes
|
||||||
|
// that tree, and both locales must be present in the server-rendered document.
|
||||||
|
import { getCollection } from 'astro:content';
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
import FleetDiagram from '../components/blocks/FleetDiagram.astro';
|
||||||
|
import HandoffTable from '../components/blocks/HandoffTable.astro';
|
||||||
|
import PhasePanel from '../components/blocks/PhasePanel.astro';
|
||||||
|
import RouteTable from '../components/blocks/RouteTable.astro';
|
||||||
|
import SkillPackage from '../components/blocks/SkillPackage.astro';
|
||||||
|
import WorktreeMap from '../components/blocks/WorktreeMap.astro';
|
||||||
|
import CopyPrompt from '../components/islands/CopyPrompt.astro';
|
||||||
|
import GuideSelector from '../components/islands/GuideSelector.astro';
|
||||||
|
import LanguageToggle from '../components/islands/LanguageToggle.astro';
|
||||||
|
import ReadingProgress from '../components/islands/ReadingProgress.astro';
|
||||||
|
import '../../styles.css';
|
||||||
|
import '../../responsive.css';
|
||||||
|
import '../../full-guide/audit.css';
|
||||||
|
|
||||||
|
type Entry<T extends { id: string }> = { data: T };
|
||||||
|
const toRecord = <T extends { id: string }>(entries: Entry<T>[]) =>
|
||||||
|
Object.fromEntries(entries.map(({ data }) => [data.id, data]));
|
||||||
|
const [
|
||||||
|
phaseEntries,
|
||||||
|
workerEntries,
|
||||||
|
treeEntries,
|
||||||
|
routeEntries,
|
||||||
|
providerEntries,
|
||||||
|
effortEntries,
|
||||||
|
skillFileEntries,
|
||||||
|
workflowEntries,
|
||||||
|
commonSkillEntries,
|
||||||
|
promptEntries,
|
||||||
|
installEntries,
|
||||||
|
] = await Promise.all([
|
||||||
|
getCollection('phases'),
|
||||||
|
getCollection('workers'),
|
||||||
|
getCollection('trees'),
|
||||||
|
getCollection('routes'),
|
||||||
|
getCollection('providers'),
|
||||||
|
getCollection('efforts'),
|
||||||
|
getCollection('skillFiles'),
|
||||||
|
getCollection('skillWorkflow'),
|
||||||
|
getCollection('commonSkills'),
|
||||||
|
getCollection('handsOnPrompts'),
|
||||||
|
getCollection('skillInstallPrompts'),
|
||||||
|
]);
|
||||||
|
const phases = toRecord(phaseEntries);
|
||||||
|
const workers = toRecord(workerEntries);
|
||||||
|
const trees = toRecord(treeEntries);
|
||||||
|
const routes = toRecord(routeEntries);
|
||||||
|
const providers = toRecord(providerEntries);
|
||||||
|
const efforts = toRecord(effortEntries);
|
||||||
|
const skillFiles = toRecord(skillFileEntries);
|
||||||
|
const skillWorkflow = toRecord(workflowEntries);
|
||||||
|
const commonSkills = toRecord(commonSkillEntries);
|
||||||
|
const handsOn = promptEntries.find(({ data }) => data.id === 'tiny-tasks')?.data;
|
||||||
|
const install = installEntries.find(({ data }) => data.id === 'install')?.data;
|
||||||
|
if (!handsOn || !install) throw new Error('full-guide content collections are incomplete');
|
||||||
|
|
||||||
|
// Selector chrome is page-specific, so it remains an inline bilingual constant.
|
||||||
|
const 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 selectorData = {
|
||||||
|
phases,
|
||||||
|
workers,
|
||||||
|
trees,
|
||||||
|
routes,
|
||||||
|
providers,
|
||||||
|
efforts,
|
||||||
|
skillFiles,
|
||||||
|
skillWorkflow,
|
||||||
|
commonSkills,
|
||||||
|
labels,
|
||||||
|
};
|
||||||
|
const workerCards = [
|
||||||
|
{ id: 'ui', label: 'UI', strong: 'Component and visual states', code: 'agent/ui' },
|
||||||
|
{ id: 'tests', label: 'TEST', strong: 'Acceptance cases', code: 'agent/tests' },
|
||||||
|
{ id: 'docs', label: 'DOCS', strong: 'Guide and examples', code: 'agent/docs' },
|
||||||
|
];
|
||||||
|
const treeBranches = [
|
||||||
|
{ id: 'ui', label: 'UI AGENT', strong: 'agent/ui', small: '3 files · working', tone: 'ui' },
|
||||||
|
{
|
||||||
|
id: 'tests',
|
||||||
|
label: 'TEST AGENT',
|
||||||
|
strong: 'agent/tests',
|
||||||
|
small: '8 checks · ready',
|
||||||
|
tone: 'tests',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'docs',
|
||||||
|
label: 'DOCS AGENT',
|
||||||
|
strong: 'agent/docs',
|
||||||
|
small: '2 pages · review',
|
||||||
|
tone: 'docs',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const base = import.meta.env.BASE_URL;
|
||||||
|
---
|
||||||
|
|
||||||
|
<BaseLayout
|
||||||
|
title="AI For Dummies — Field Guide"
|
||||||
|
description="AI For Dummies: a field guide to skills, models, subagents, and worktrees."
|
||||||
|
>
|
||||||
|
<ReadingProgress />
|
||||||
|
<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">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><a href="#verification">08 verify</a>
|
||||||
|
</nav>
|
||||||
|
<div class="topbar-tools">
|
||||||
|
<a class="skills-review-link" href={`${base}skills-review/`}>review submissions ↗</a
|
||||||
|
><LanguageToggle /><span class="edition">AI ENGINEERING <i></i> 01 / 2026</span>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="hero" id="top" data-language-content="en">
|
||||||
|
<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" id="top-pt" data-language-content="pt" hidden>
|
||||||
|
<div>
|
||||||
|
<p class="eyebrow">Uma apresentação para quem entrega software</p><h1>
|
||||||
|
IA para<br /><em>iniciantes.</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>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="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>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>
|
||||||
|
<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>PENSE</b><i></i><i></i><i></i><b>FAÇA</b>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="fleet" id="fleet">
|
||||||
|
<div class="section-label">
|
||||||
|
<span>A small fleet</span><span>coordination before parallelism</span>
|
||||||
|
</div><FleetDiagram
|
||||||
|
orchestrator={{
|
||||||
|
eyebrow: 'ORCHESTRATOR',
|
||||||
|
title: 'Decides what<br />needs to happen.',
|
||||||
|
code: 'Opus / reasoning',
|
||||||
|
}}
|
||||||
|
workers={workerCards}
|
||||||
|
/><div class="worker-detail" id="worker-detail" aria-live="polite">
|
||||||
|
<span>{workers.ui.en[0]}</span><strong>{workers.ui.en[1]}</strong><small
|
||||||
|
>{workers.ui.en[2]}</small>
|
||||||
|
</div><p class="caption">
|
||||||
|
The orchestrator preserves intent, writes small contracts, and gathers results that can be
|
||||||
|
verified. It does not need to type every line.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
<section class="failure-map">
|
||||||
|
<div class="section-label">
|
||||||
|
<span>Why the boundary matters</span><span
|
||||||
|
>one vague task / three predictable failures</span>
|
||||||
|
</div><div class="failure-grid">
|
||||||
|
<article>
|
||||||
|
<span>01</span><strong>Context soup</strong><p>
|
||||||
|
Every worker reads everything. Nobody knows which facts are load-bearing.
|
||||||
|
</p>
|
||||||
|
</article><article>
|
||||||
|
<span>02</span><strong>Branch collision</strong><p>
|
||||||
|
Two agents touch the same checkout. The fastest path becomes conflict resolution.
|
||||||
|
</p>
|
||||||
|
</article><article>
|
||||||
|
<span>03</span><strong>Confident drift</strong><p>
|
||||||
|
The diff is polished, but no one checks whether it solved the original problem.
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="workflow" aria-labelledby="workflow-title">
|
||||||
|
<div class="copy">
|
||||||
|
<p class="eyebrow">The subagent loop</p><h2 id="workflow-title">
|
||||||
|
Click a phase.<br /><em>See the handoff.</em>
|
||||||
|
</h2><p>
|
||||||
|
Delegation means moving one bounded task into a smaller context—not giving away
|
||||||
|
responsibility.
|
||||||
|
</p>
|
||||||
|
</div><PhasePanel
|
||||||
|
phases={[
|
||||||
|
{
|
||||||
|
id: 'plan',
|
||||||
|
label: 'PLAN',
|
||||||
|
number: '01',
|
||||||
|
title: phases.plan.title.en,
|
||||||
|
body: phases.plan.copy.en,
|
||||||
|
meta: { deliverable: phases.plan.model.en, gate: labels.context.en },
|
||||||
|
evidence: phases.plan.code.en,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'build',
|
||||||
|
label: 'BUILD',
|
||||||
|
number: '02',
|
||||||
|
title: phases.build.title.en,
|
||||||
|
body: phases.build.copy.en,
|
||||||
|
meta: { deliverable: phases.build.model.en, gate: labels.context.en },
|
||||||
|
evidence: phases.build.code.en,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'review',
|
||||||
|
label: 'REVIEW',
|
||||||
|
number: '03',
|
||||||
|
title: phases.review.title.en,
|
||||||
|
body: phases.review.copy.en,
|
||||||
|
meta: { deliverable: phases.review.model.en, gate: labels.context.en },
|
||||||
|
evidence: phases.review.code.en,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
<section class="handoff">
|
||||||
|
<div class="section-label">
|
||||||
|
<span>What crosses contexts</span><span>brief → diff → evidence</span>
|
||||||
|
</div><HandoffTable
|
||||||
|
columns={['Package', 'Contains', 'Why it matters']}
|
||||||
|
rows={[
|
||||||
|
{
|
||||||
|
package: 'Brief',
|
||||||
|
contains: 'goal, files, boundaries',
|
||||||
|
why: 'stops the worker inventing the problem',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
package: 'Worktree',
|
||||||
|
contains: 'branch and isolated checkout',
|
||||||
|
why: 'parallel edits do not collide',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
package: 'Checks',
|
||||||
|
contains: 'tests, build, criteria',
|
||||||
|
why: 'turns “looks good” into evidence',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
package: 'Diff',
|
||||||
|
contains: 'small, reviewable change',
|
||||||
|
why: 'integration and discard stay cheap',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</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><WorktreeMap branches={treeBranches} /><article
|
||||||
|
class="tree-detail"
|
||||||
|
id="tree-detail"
|
||||||
|
aria-live="polite"
|
||||||
|
>
|
||||||
|
<div><span>{labels.owner.en}</span><strong>{trees.main.owner.en}</strong></div><div>
|
||||||
|
<span>CHECKOUT</span><strong>{trees.main.path}</strong>
|
||||||
|
</div><p>{trees.main.note.en}</p><code>{trees.main.command}</code>
|
||||||
|
</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">
|
||||||
|
<RouteTable
|
||||||
|
routes={[
|
||||||
|
{
|
||||||
|
id: 'plan',
|
||||||
|
strong: 'Plan',
|
||||||
|
profile: 'strong / broad',
|
||||||
|
prompt: 'What changes? What can break?',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'build',
|
||||||
|
strong: 'Build',
|
||||||
|
profile: 'fast / focused',
|
||||||
|
prompt: 'Implement this slice. Run these checks.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'explore',
|
||||||
|
strong: 'Explore',
|
||||||
|
profile: 'read-only / light',
|
||||||
|
prompt: 'Find where this contract is used.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'review',
|
||||||
|
strong: 'Review',
|
||||||
|
profile: 'independent',
|
||||||
|
prompt: 'Does the diff satisfy the brief?',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/><article class="route-detail" id="route-detail" aria-live="polite">
|
||||||
|
<div class="route-meter"><span style={`--score:${routes.plan.score}%`}></span></div><div>
|
||||||
|
<small>{labels.reasoningLoad.en} · {routes.plan.score}</small><strong
|
||||||
|
>{routes.plan.label.en}</strong
|
||||||
|
><p>{routes.plan.why.en}</p>
|
||||||
|
</div>
|
||||||
|
</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">
|
||||||
|
<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>{providers.openai.label}</span><a
|
||||||
|
href={providers.openai.source}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener">{labels.officialSource.en}</a>
|
||||||
|
</header><h3>{providers.openai.title.en}</h3><p>{providers.openai.copy.en}</p>
|
||||||
|
</article><div class="effort-rail" role="tablist" aria-label="Reasoning effort">
|
||||||
|
<button data-effort="low" role="tab" aria-selected="false">LOW</button><button
|
||||||
|
class="active"
|
||||||
|
data-effort="medium"
|
||||||
|
role="tab"
|
||||||
|
aria-selected="true">MEDIUM</button
|
||||||
|
><button data-effort="high" role="tab" aria-selected="false">HIGH</button>
|
||||||
|
</div><article class="effort-detail" id="effort-detail" aria-live="polite">
|
||||||
|
<span>{efforts.medium.en[0]}</span><p>{efforts.medium.en[1]}</p><code
|
||||||
|
>{providers.openai.config}</code>
|
||||||
|
</article>
|
||||||
|
</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><div class="skill-explorer">
|
||||||
|
<SkillPackage
|
||||||
|
files={[
|
||||||
|
{ id: 'skill', path: 'SKILL.md', small: 'procedure and limits' },
|
||||||
|
{ id: 'references', path: 'references/', small: 'facts to consult' },
|
||||||
|
{ id: 'scripts', path: 'scripts/', small: 'repeatable checks' },
|
||||||
|
{ id: 'assets', path: 'assets/', small: 'templates and examples' },
|
||||||
|
]}
|
||||||
|
/><article class="skill-detail" id="skill-detail" aria-live="polite">
|
||||||
|
<span>{skillFiles.skill.icon}</span><div>
|
||||||
|
<strong>{skillFiles.skill.title}</strong><p>{skillFiles.skill.en}</p><small
|
||||||
|
>{labels.skillFileHint.en}</small>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</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-workbench">
|
||||||
|
<nav class="builder-steps" role="tablist" aria-label="Skill creation workflow">
|
||||||
|
{
|
||||||
|
Object.values(skillWorkflow).map((step) => (
|
||||||
|
<button
|
||||||
|
class:list={{ active: step.id === 'observe' }}
|
||||||
|
data-skill-step={step.id}
|
||||||
|
role="tab"
|
||||||
|
aria-selected={step.id === 'observe'}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
<b>{step.number}</b>
|
||||||
|
<span>{step.title.en}</span>
|
||||||
|
</>
|
||||||
|
</button>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</nav><article class="builder-detail" id="builder-detail" aria-live="polite">
|
||||||
|
<header>
|
||||||
|
<span>{skillWorkflow.observe.number}</span><small>{labels.workflow.question.en}</small>
|
||||||
|
</header><h3>{skillWorkflow.observe.title.en}</h3><blockquote>
|
||||||
|
{skillWorkflow.observe.question.en}
|
||||||
|
</blockquote><div class="builder-action">
|
||||||
|
<span>{labels.workflow.action.en}</span><p>{skillWorkflow.observe.action.en}</p>
|
||||||
|
</div><footer>
|
||||||
|
<div>
|
||||||
|
<span>{labels.workflow.artifact.en}</span><strong
|
||||||
|
>{skillWorkflow.observe.output.en}</strong>
|
||||||
|
</div><div>
|
||||||
|
<span>{labels.workflow.proof.en}</span><strong
|
||||||
|
>{skillWorkflow.observe.proof.en}</strong>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</article>
|
||||||
|
</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="skill-deck">
|
||||||
|
<div class="skill-index" role="tablist" aria-label="Common agent skills">
|
||||||
|
{
|
||||||
|
Object.values(commonSkills).map((skill) => (
|
||||||
|
<button
|
||||||
|
class:list={{ active: skill.id === 'ponytail' }}
|
||||||
|
data-common-skill={skill.id}
|
||||||
|
role="tab"
|
||||||
|
aria-selected={skill.id === 'ponytail'}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
<span>{skill.kind.en}</span>
|
||||||
|
<strong>{skill.title}</strong>
|
||||||
|
<small>{skill.use.en}</small>
|
||||||
|
</>
|
||||||
|
</button>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div><article class="common-skill-detail" id="common-skill-detail" aria-live="polite">
|
||||||
|
<header>
|
||||||
|
<span>{commonSkills.ponytail.number}</span><small
|
||||||
|
>{commonSkills.ponytail.kind.en}</small>
|
||||||
|
</header><h3>{commonSkills.ponytail.title}</h3><blockquote>
|
||||||
|
{commonSkills.ponytail.rule.en}
|
||||||
|
</blockquote><div class="common-skill-notes">
|
||||||
|
<div>
|
||||||
|
<span>{labels.commonSkill.whenToUse.en}</span><p>{commonSkills.ponytail.use.en}</p>
|
||||||
|
</div><div>
|
||||||
|
<span>{labels.commonSkill.example.en}</span><p>{commonSkills.ponytail.example.en}</p>
|
||||||
|
</div><div>
|
||||||
|
<span>{labels.commonSkill.watchOut.en}</span><p>{commonSkills.ponytail.caution.en}</p>
|
||||||
|
</div>
|
||||||
|
</div><a
|
||||||
|
class="skill-source"
|
||||||
|
href={commonSkills.ponytail.source}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener">{labels.commonSkill.source.en}</a>
|
||||||
|
</article>
|
||||||
|
</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><CopyPrompt target="prompt-install-skills" />
|
||||||
|
</header><pre><code id="prompt-install-skills">{install.en}</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.
|
||||||
|
</p><div class="starter-links">
|
||||||
|
<a href={`${base}hands-on/starter/`} class="starter-link">Open the starter →</a><a
|
||||||
|
href={`${base}hands-on/rules/`}
|
||||||
|
class="starter-link">Open the rules lab →</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div><div class="prompt-compare">
|
||||||
|
<article class="prompt-card">
|
||||||
|
<header>
|
||||||
|
<div><span>RUN A</span><strong>Good prompt</strong></div><CopyPrompt
|
||||||
|
target="prompt-basic"
|
||||||
|
/>
|
||||||
|
</header><pre><code id="prompt-basic">{handsOn.en.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><CopyPrompt
|
||||||
|
target="prompt-skills"
|
||||||
|
/>
|
||||||
|
</header><pre><code id="prompt-skills">{handsOn.en.skills}</code></pre><footer>
|
||||||
|
Same contract · explicit working methods · stronger proof
|
||||||
|
</footer>
|
||||||
|
</article>
|
||||||
|
</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>
|
||||||
|
<section class="verification" id="verification">
|
||||||
|
<div class="section-label">
|
||||||
|
<span>Verification</span><span>run each gate separately</span>
|
||||||
|
</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.
|
||||||
|
</p><code>pnpm lint; echo "lint=$?"</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=$?"</code>
|
||||||
|
</article><article>
|
||||||
|
<span>03 · INTEGRATION</span><h3>Real UI and API</h3><p>
|
||||||
|
Drive the actual UI, API, or browser.
|
||||||
|
</p><code>pnpm check:ui; echo "ui=$?"</code>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<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={`${base}rules/`}>Rules and enforcement case study →</a>
|
||||||
|
<a href={`${base}skills-review/`}>Skills review desk →</a>
|
||||||
|
<a href={`${base}docs/references/additional-reading.md`}>12-part reading path →</a>
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<GuideSelector rootSelector="#full-guide" data={selectorData} />
|
||||||
|
</BaseLayout>
|
||||||
Reference in New Issue
Block a user