From B Pipeline
Evaluate, label, and respond to GitHub issues before development starts. Use ALWAYS when a GitHub issue number or URL is mentioned as the starting point for work, when asked to "evaluate issue", "triage", "review issue", "revisar issue", "evaluar issue", "evaluar tarea N", "revisar tarea N", "check issue
How this skill is triggered — by the user, by Claude, or both
Slash command
/b-pipeline:b1-triage-issuesonnetExploreThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
```text
$ARGUMENTS
Skill
context: fork: el subagente solo ve esteSKILL.md. El placeholder$ARGUMENTSes la UNICA via por la que el numero de issue tipeado llega al fork — el harness lo sustituye. El primer token es el numero/URL del issue. Si aparece vacio o sin sustituir, abortar pidiendo el numero de issue.
Flag --auto (para orquestadores como b10-ship — modo desatendido, cero preguntas interactivas):
TRIAGE_RESULT {"issue":<N>,"verdict":"closed"}, sin preguntar.## Evaluacion de Issue previo) → NO preguntar si re-triagear. Si hay comentarios humanos NUEVOS posteriores al comentario de evaluacion, re-evaluar incorporandolos (caso tipico: el reporter respondio las preguntas de needs-info). Si no hay nada nuevo, reusar el veredicto existente y emitir el TRIAGE_RESULT correspondiente.Development that starts from a GitHub issue must understand, research, and enrich it before any code gets written. Poorly specified issues waste implementation cycles. The objective is three outputs:
In this project users often say "tarea N" meaning issue #N. Treat them as synonyms throughout this skill.
Start narrow — pull only what triage actually consumes:
gh issue view <N> --json number,title,body,state,labels,comments \
-q '{number,title,state,body,labels:[.labels[].name],firstComments:(.comments[:3]|map({author:.author.login,bot:(.author.login|test("\\[bot\\]$")),body})),commentCount:(.comments|length)}'
OJO:
gh issue view --json commentsNO exponeauthor.type(solologin) — detectar bots por el sufijo[bot]del login.
Title, body, labels, state, the first 3 comments, and a count. Most triages resolve here without ever reading the full thread.
Re-fetch all comments only if any of:
When you do re-fetch, filter noise:
gh issue view <N> --json comments \
-q '.comments[] | select(.author.login | test("\\[bot\\]$|^github-actions$|^renovate";"i") | not) | select((.body|length) > 20)'
This drops Renovate/dependabot/github-actions comments and reaction-only ones ("+1", "👍", emoji-only). They cost tokens without adding signal.
Closed issues: warn the user, proceed only if they insist. (Con --auto: abortar emitiendo TRIAGE_RESULT {"issue":<N>,"verdict":"closed"}.)
Before any research, decide if the work can short-circuit. Triage that races to "needs-info" or "duplicate" doesn't need codebase grep.
Already triaged? If labels include any of ready, needs-info, blocked, duplicate, OR a previous comment starts with ## Evaluacion de Issue / ## Issue Evaluation, surface the prior verdict and ask the user whether to re-triage. Don't redo research silently — it wastes tokens and risks contradicting prior alignment. (Con --auto: no preguntar — re-evaluar solo si hay comentarios humanos nuevos, si no reusar el veredicto. Ver Argumentos.)
Trivially incomplete? If body is empty or <100 chars and no acceptance criteria appear in the first comments, skip Steps 3-4 entirely and go straight to Step 6/7 as needs-info. There is nothing to ground.
Obvious duplicate? Run the single search from 4d first; if a hard match exists, classify as duplicate without further research.
Identify the primary language from body + comments. All GitHub responses (Step 7 comment) must be in that language. Terminal output stays in your default.
Spanish issue → Spanish comment. English → English. Mixed → use the body's language. Issue reporters read responses in their language; mismatched language signals a careless automated reply.
Only reach this step when Step 2 didn't short-circuit. The goal is grounding, not exhaustive exploration.
4a. Extract entities. Pull 1-3 nouns the issue is about (e.g., "productos", "ventas", "auth", "campaigns"). For each, one targeted grep:
rg -l "<entidad>" src/routes src/lib/server/db/schema
Open a file only when the match count justifies it (>1 hit, or the path is the obvious owner — e.g., src/routes/<entidad>/). Do not open the full directory tree. Do not read README unless the issue references concepts you don't recognize.
4b. Already implemented? If 4a lands on a feature route folder matching the request, read its +page.svelte and <entidad>.remote.ts only. If the function/screen exists → mark duplicate and stop researching.
4c. Affected files. List specific paths that would change. This grounds the complexity estimate and the risk checklist below.
4d. Related issues + PRs (one combined call).
gh search issues "<2-3 keywords> repo:$(gh repo view --json nameWithOwner -q .nameWithOwner)" --limit 10
One gh search issues covers both issues and PRs by relevance — replaces separate gh issue list + gh pr list calls.
Assess against these criteria:
| Criterion | Check |
|---|---|
| Entity clarity | Is it clear what data/entity is involved? |
| Operation clarity | What needs to happen? (CRUD, behavior change, UI addition) |
| Scope | Boundary defined or open-ended? |
| Vertical slice | Does it deliver a usable screen end-to-end, or is it a horizontal technical layer? (see below) |
| Acceptance criteria | How will anyone know it's done? |
| Dependencies | Does this need other work to land first? |
Classification: ready | needs-info | duplicate | blocked.
Este proyecto es screen-first / Vertical Slice Architecture: cada issue que entra a build debe ser una rebanada vertical — algo que un usuario puede USAR al mergearse, cruzando todo el stack (Drizzle → Remote Function → pantalla en src/routes). Un issue que entrega solo una capa técnica rompe el modelo: b2/b7 construyen y revisan por pantalla, no por capa, y un slice horizontal no se puede verificar en browser ni cierra nada útil.
Señales de capa horizontal (mal slice) en el título/cuerpo:
/<feature>) ni un journey de usuario.Acción cuando el issue es horizontal:
<X>). En este proyecto cada tarea debe entregar una pantalla usable end-to-end. ¿Lo reescribimos como slice vertical (ej. 'listar <entidad> en /<feature>') o lo partimos en slices con /b-pipeline:b0-conversation-to-issues?"Excepción — concerns transversales: auth, db, storage, notificaciones y audit son infra genuinamente transversal, no features. Un issue legítimamente backend (ej. "agregar índice a taVentas", "rotar el secreto de storage") NO es un mal slice — no exige pantalla. Marcar estos como ready normal; el ## Pantalla(s) del body se reemplaza por ## Remote functions / endpoints (mismo criterio que b0). La regla horizontal aplica a features de producto partidas por capa, no a infra transversal.
Walk this once using the file list from 4c. Each row produces at most one bullet in the evaluation comment IF its trigger fires. Most issues fire zero or one — that's expected.
| Trigger (path / change kind) | Flag in comment |
|---|---|
| Touches auth, permissions, sessions, OAuth | security: validate requireUser / requirePermission + structured error (AUTH_REQUIRED, FORBIDDEN) |
Touches *.remote.ts or src/lib/server/db/schema | data: needs Zod schema; if schema changes, include migration plan and app.route_permissions impact |
Adds a new route under src/routes | perms: must register in app.route_permissions + assignment, or the layout guard redirects to fallback |
| Affects public API or a core feature | docs: update docs/ (or a markdown colocated in the feature route folder) and CHANGELOG |
This single pass replaces three separate quality / security / docs review steps and only spends tokens where the change actually warrants attention.
Discover existing labels once per session (cache if you've already pulled them):
gh label list --limit 100 --json name -q '.[].name'
Use existing labels first. Only create when none match. Categories to cover:
feature, bug, enhancement, docsready, needs-info, blocked, duplicatesimple, medium, complex (maps to b2's 3-5 / 5-8 / 8-15 file scale)scope:<area> based on affected moduleLabel application and comment posting (Step 7) share the same verdict — emit them in the same turn with two parallel gh calls. Do not reason twice over the same evaluation.
gh issue edit <N> --add-label "ready" --add-label "feature" --add-label "scope:productos"
Creating a missing label (follow repo color/naming conventions):
gh label create "needs-info" --description "Issue needs clarification before work can start" --color "FBCA04"
Never remove existing labels — only add the missing ones.
Write the comment in the language detected in Step 3. Use the compact structure below. Full per-classification examples live in references/comment-templates.md — read that file only when actually drafting.
Compact structure:
## Evaluacion de Issue (or Issue Evaluation)
**Estado / Status**: <ready | needs-info | duplicate | blocked>
**Entendimiento / Understanding**: 2-3 lines. Cite relevant comments as #N when they refined the body.
**Archivos / Files**: bullets with exact paths from Step 4c.
**Complejidad / Complexity**: simple | medium | complex — one-line justification (simple = 3-5 files, medium = 5-8, complex = 8-15).
**Riesgos / Risks**: only the bullets the Step 5 checklist triggered. Omit the section entirely if none.
**Plan**: numbered steps (ready)
— OR —
**Preguntas / Questions**: numbered, concrete, codebase-grounded (needs-info).
Post via heredoc:
gh issue comment <N> --body "$(cat <<'EOF'
<contenido>
EOF
)"
For needs-info, anchor every question in the codebase. Bad: "¿puedes aclarar?". Good: "El issue menciona 'ventas' pero existen taVentas (cabecera) y taVentasDetalle (líneas). ¿Cuál entidad gestiona la pantalla?".
Marker obligatorio en needs-info: el comentario de preguntas termina SIEMPRE con un marker HTML invisible con timestamp UTC, para que la reanudacion automatica detecte respuestas posteriores comparando fechas de comentarios:
<!-- b10:questions 2026-06-10T15:30:00Z -->
Short summary, no markdown headings:
Ultima linea OBLIGATORIA machine-readable (la parsean orquestadores como b10-ship; fallback de ellos: leer labels del issue):
TRIAGE_RESULT {"issue":261,"verdict":"ready","complexity":"complex","type":"feature","scope":"campaigns","blocked_by":[]}
verdict: ready | needs-info | duplicate | blocked | closedcomplexity: simple | medium | complexblocked_by: numeros de issues que bloquean (de la seccion "Blocked by" del body o del analisis), [] si ningunoDefault model: sonnet. Most triages — duplicates, needs-info, simple/medium ready issues — don't need opus. Escalate to opus only if Step 5 lands on complex AND the issue spans multiple features with genuinely ambiguous boundaries. Spending opus on "this issue has no body" is waste.
needs-info via Step 2 short-circuit; a title alone is not a spec.npx claudepluginhub jporre/sveltekit-verticalslices --plugin b-pipelineProvides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.