SLOPSHOPPER

flow-progress

Faixa acima do prompt com tasks concluídas/total e a fase atual do TSG Flow (dev, review, bloqueada, integração).

newbandtimer
★ 7v0.1.0no licenseupdated 2026-10-06tassosgomes/my-skills/mods/flow-progress
A shopper browsing a rack in a slop shop
README

my-skills

Repositório de skills que utilizo no meu dia a dia. skills/ é a fonte canônica: cada skill ativa vive em skills/<nome>/SKILL.md e segue o formato com frontmatter (name, description) seguido do corpo normativo. novas/ é apenas staging para comparação e não deve ser usado como fonte de instalação.

Comece pela ordem de execução do TSG Flow, com rotas para produto novo, feature isolada e frontend. O guia de uso detalha contratos, retomada e ADRs permanentes em docs/adr/. O diagrama do fluxo mostra a cadeia e o ciclo por task.


Instalação

Para instalar todas as skills deste repositório:

npx skills add tassosgomes/my-skills

Para instalar uma skill específica:

npx skills add tassosgomes/my-skills/<nome-da-skill>

Exemplos:

npx skills add tassosgomes/my-skills/flow-qa-orchestrator
npx skills add tassosgomes/my-skills/tsg-flow-prd-creator
npx skills add tassosgomes/my-skills/tsg-flow-techspec-creator
npx skills add tassosgomes/my-skills/tsg-flow-task-creator
npx skills add tassosgomes/my-skills/mermaid
npx skills add tassosgomes/my-skills/java

Funciona com qualquer harness suportado pela CLI skills (Claude Code, Codex, GitHub Copilot, Cursor, Windsurf, etc.) — use -a <agente> para direcionar um harness específico ou -a '*' para todos os detectados. Repositórios privados funcionam via SSH (git@github.com:...) ou HTTPS com gh auth login / GITHUB_TOKEN.

Instalação por grupo

O repositório declara grupos de skills em .claude-plugin/marketplace.json: tsg-flow, flow-qa, java e react. Rodando npx skills add tassosgomes/my-skills sem -s, o picker interativo agrupa as skills por família e permite selecionar um grupo inteiro de uma vez (ex.: todo o tsg-flow, para não instalar tsg-flow-implementer sem tsg-flow-orchestrator). Cada SKILL.md do grupo também documenta a família no próprio frontmatter (metadata.group) — é só uma convenção legível para humanos, quem decide o agrupamento real no instalador é o marketplace.json.

O agrupamento é uma conveniência de instalação, não uma dependência obrigatória: -s <skill> continua instalando skills avulsas normalmente.


Mods

mods/ guarda mods do Claude Code (plugins de hooks que desenham painéis, faixas e status na própria interface). Não são skills: não passam pelo npx skills.

ModPropósito
flow-progressFaixa acima do prompt com tasks concluídas/total e a fase atual do TSG Flow: ⚙ desenvolvimento, 🔍 review, ⛔ bloqueada, 🔀 integração

Instalação dos mods

Pelo marketplace deste repositório, dentro do Claude Code:

/plugin marketplace add tassosgomes/my-skills
/plugin install flow-progress@my-skills

Para testar a partir de um clone local, sem instalar:

claude --plugin-dir mods/flow-progress

flow-progress

Exemplo da faixa: prd-xyz ████░░░░░░ 4/10 🔍 review (task 5.0).

  • PRD ativo: o tasks/prd-*/flow-state.json modificado por último, relido a cada 3 segundos. Rode o Claude Code na raiz do projeto que contém tasks/.
  • Realizado/total: checkboxes do tasks.md.
  • Fase: status: do frontmatter de <num>_task.md (in_progress, validating, blocked, done). Com todas as tasks done, mostra integração até o phase do flow-state.json indicar conclusão.
  • A faixa some quando não há PRD em orquestração; o botão Ocultar a esconde na sessão.

Testes: claude plugin test mods/flow-progress. Validação: claude plugin validate mods/flow-progress.


Visão geral das skills

:star: Skills de minha autoria.

Pipeline TSG de Produto e Implementação

SkillEtapaPropósito
:star: tsg-flow-vision-creatorVisionDefine a visão macro e os limites do sistema
:star: tsg-flow-domain-decomposerDomain MapDecompõe a visão em bounded contexts conceituais
:star: tsg-flow-architecture-baselineBaselineDefine restrições arquiteturais reutilizáveis
:star: tsg-flow-capability-backlogCapacidadesPrioriza MVP e evolução por capacidades de negócio
:star: tsg-flow-domain-creatorDomainDetalha um domínio, suas features e regras de negócio
:star: tsg-flow-prd-creatorPRDConduz discovery e cria requisitos de produto rastreáveis
:star: tsg-flow-contract-creatorIntegration ContractsDefine contratos OpenAPI, AsyncAPI e ODCS para a implementação da feature
:star: tsg-flow-techspec-creatorTechSpecTraduz o PRD em fatias, contratos e decisões — backend, frontend ou full-stack
:star: tsg-flow-task-creatorTasksGera tasks verticais, rastreáveis e prontas para agentes

O fluxo de execução utiliza ainda tsg-flow-orchestrator, tsg-flow-implementer, tsg-flow-validator e tsg-flow-integrator. As skills flow-qa-* pertencem ao pipeline de QA e permanecem com esse namespace nesta etapa.

Pipeline de QA

SkillTipoPropósito
:star: flow-qa-orchestratorOrquestradorCoordena pipeline de QA E2E (entrevista → plano → execução → relatório)
:star: flow-qa-task-runnerSubagenteExecuta testes de uma user story (UI/API/DB) com fidelidade total
:star: flow-qa-report-builderConsolidadorGera relatório final consolidado (Markdown/PDF) da sessão de QA

Documentação

SkillTipoPropósito
mermaidGeradorGera diagramas Mermaid de alta qualidade a partir de documentos de requisitos e especificações de arquitetura
find-docsUtilitárioBusca documentação atualizada de qualquer lib via Context7 MCP ou CLI

Testes

SkillTipoPropósito
test-guideGuiaEscreve e audita testes em todas as camadas (unit, integration, E2E) — stack-agnóstico

Segurança

SkillTipoPropósito
:star: security-audit-workflowWorkflowAuditoria de segurança stack-agnóstica via sub-agents e Docker

Java / Spring Boot

SkillTipoPropósito
:star: javaNormativoPadrão único: Clean Architecture multi-módulo Maven, casos de uso, JPA/Flyway, outbox RabbitMQ, observabilidade, performance, testes e gates executáveis (enforcer, forbiddenapis, NullAway, ArchUnit)

React / Vite / TypeScript

SkillTipoPropósito
:star: reactNormativoPadrao unico: estrutura e fronteiras de feature (via ESLint), camada de API, estado, formularios, erros, qualidade, testes, runtime config 12-factor, container, subpath e telemetria

flow-qa-orchestrator

Papel: QA Lead que conduz uma sessão completa de testes a partir de um PRD/TechSpec.

Fluxo (8 fases):

  1. Recebimento — lê PRD/techspec e identifica user stories, endpoints, fluxos.
  2. Entrevista — extrai expectativas do usuário (escopo, ambiente, auth, banco, formato do relatório).
  3. Análise & Planejamento — monta tasks por user story (qa_task_NN_<slug>), identifica dependências e fases (paralelo/sequencial).
  4. Aprovação do plano — apresenta o plano e aguarda revisão.
  5. Autorização de execução — exige confirmação explícita antes de iniciar.
  6. Setup — cria qa-evidence/, grava qa_test_plan.md em disco (plano aprovado completo) e qa_session.json (sem credenciais hardcoded; só nomes de env vars). O plano é sempre persistido antes de qualquer subagente ser disparado.
  7. Execução — dispara flow-qa-task-runner por task, respeitando dependências.
  8. Consolidação — chama flow-qa-report-builder para gerar o relatório final.

Regras-chave: não escreve código de produção, não sugere correções, não inicia sem aprovação, não expande escopo por conta própria.

Relatório em PDF: para gerar o qa_report_consolidated.pdf o flow-qa-report-builder depende da skill pdf. Instale-a com npx skills add pdf caso queira saída em PDF além de Markdown.


flow-qa-task-runner

Papel: QA Engineer que executa os testes de uma única user story.

Capacidades:

  • API via cURL (request/response logado em requests.log).
  • UI via Playwright (screenshots em momentos críticos, vídeos, console do browser).
  • Banco via Docker CLI (PostgreSQL/MySQL/MongoDB) para validar persistência.

Fluxo: lê qa_session.json → planeja casos (happy path + bordas + negativos em test_plan.md) → autentica se necessário → executa cada CT → gera qa_report_task_NN.md.

Gate anti-jeitinho (regra absoluta): proibido modificar testes para forçar PASS, usar try/catch silencioso, ignorar assertions, alterar dados no banco para validar, ou sugerir correções de código. Ao falhar: para imediatamente, captura todas as evidências, registra expected vs actual com precisão.

Retry: apenas para instabilidade de rede/timeout (máx 2 retentativas, 2s entre elas). Nunca para erro de lógica de negócio.


flow-qa-report-builder

Papel: Último passo do pipeline QA — escreve o relatório executivo consolidado.

Inputs: qa_session.json + lista de qa_report_task_NN.md + formato (markdown | pdf | ambos).

Estrutura do relatório (qa_report_consolidated.md):

  • Sumário executivo — métricas agregadas + resultado binário (APROVADO só se zero falhas).
  • Features testadas — tabela com status por task.
  • Escopo excluído — registra o que foi acordado não testar.
  • Resultado por feature — casos executados, status, evidências.
  • Detalhes das falhas — expected vs actual, erro completo, console do browser, caminhos de evidência (screenshot/vídeo/log).
  • Recomendações de investigação — aponta o que investigar (sem sugerir como corrigir).
  • Índice de evidências — árvore de arquivos.

Regras: nunca omite falha, nunca suaviza linguagem ("falhou" é "falhou"), nunca sugere correções, sempre cita evidências com caminho específico.


test-guide

Papel: Guia normativo para escrita e auditoria de testes em todas as camadas — unit, integration e E2E. Stack-agnóstico.

Dois modos de uso:

Escrita de testes — aplica critérios de valor antes de escrever qualquer teste:

  • Vale testar: lógica com branching, fronteiras de segurança, integridade de dados, tratamento de erros, fluxos críticos, race conditions, edge cases, integrações externas.
  • Não vale testar: comportamento de framework, passthrough de validação, mirror tests, cobertura duplicada entre camadas, wiring sem transformação, estrutura estática.
  • Limite de 3 mocks por teste; acima disso, reescrever como integração.

Auditoria de testes — 3 fases:

  1. Entender — lê configs de teste, CI e convenções do projeto antes de julgar.
  2. Explorar, contar e classificar — lê o código de produção para ter contexto, mapeia todos os arquivos de teste, distribui por agentes paralelos, cada um classifica cada caso como Remover / Manter / Ausente.
  3. Relatório — tabela de métricas agregadas, lista de testes a remover (com categoria e motivo), testes críticos ausentes e saúde de mocks.

Modos de execução da auditoria: Report only (padrão) · Report + Delete · Report + Scaffold · Full automation.


mermaid

Papel: Especialista em diagramas técnicos — gera diagramas Mermaid de alta qualidade a partir de PRDs e especificações de arquitetura.

Fluxo (9 fases):

  1. Análise profunda do PRD — lê o documento completo, detecta idioma, extrai atores, endpoints, fluxos, decisões, contratos e itens fora de escopo.
  2. Avaliação de significância — filtra candidatos a diagrama por cinco critérios (fluxo principal, parte difícil, decisão arquitetural, contrato público, relação entre componentes). Diagrama elegível apenas se passar em ao menos um critério.
  3. Seleção de tipo — escolhe sequenceDiagram, flowchart TD, flowchart LR, classDiagram ou erDiagram conforme o que melhor comunica cada elemento.
  4. Poda e otimização — limita a 6–8 diagramas (máx. 10); remove redundâncias; divide visões densas (>10 nós).
  5. Preparação de rótulos — máx. 3 palavras por nó, acentos corretos no idioma do PRD, termos técnicos mantidos em inglês.
  6. Geração do documento — produz um único arquivo [output-folder]/[prd-name]-diagrams.md com todos os diagramas embutidos.
  7. Qualidade Mermaid — aplica guardrails de sintaxe (sem \\n em rótulos, IDs ASCII, aspas em subgraphs com espaços, sem expressões complexas como min(, ++).
  8. Revisão interna — relê o PRD e o documento gerado, corrige inconsistências silenciosamente antes de gravar.
  9. Validação — checklist final: idioma, acentos, contagem de diagramas, sem itens inventados, sem itens excluídos.

Regras-chave: nunca inventa elementos ausentes no PRD; sem emojis em nenhum lugar; saída sempre em arquivo único; não inclui seções Analysis/Rationale/Design Decisions no final.


security-audit-workflow

Papel: Workflow normativo de auditoria de segurança orientado por sub-agents reais com execução em Docker.

Stacks suportadas: Java, Node/TS, Python, Go, Rust, .NET, containers, IaC (Terraform/Kubernetes).

Fluxo (5 fases):

  • Fase 0 — Reconhecimento: detecta stack(s) e superfície de ataque (API REST, worker, CLI, persistência, auth, cripto, HTTP outbound). Produz security_profile.json.
  • Fase 1 — Scope Resolution: se houver PRD/TechSpec/OpenAPI, deriva escopo dirigido; senão, fallback para superfície completa com aviso. Precedência: --scope manual > docs > full. Produz scope.json.
  • Fase 2 — Test Case Design: cruza escopo com OWASP Top 10 2021 (A01–A10), gera matriz aplicável, casos não aplicáveis ficam skipped (não removidos), apresenta test_plan.md para aprovação humana.
  • Fase 3 — Sub-agents (paralelo): sast-agent (Semgrep), sca-agent (Trivy/OWASP DC), secrets-agent (Gitleaks), container-agent (Hadolint + Trivy image), auth-agent, crypto-agent, iac-agent (Checkov). Cada um recebe contrato YAML padronizado em templates/contracts/.
  • Fase 4 — Consolidação: normaliza para SARIF 2.1.0, deduplica cross-tool por partialFingerprints, prioriza por severidade × asset_multiplier × exploitability_factor, gera security_report.md com tiers CRITICAL/HIGH/MEDIUM/LOW.

Execução zero-install: ferramentas rodam via imagens Docker oficiais com versões pinadas em tools/tools.json, orquestradas pelo wrapper Python tools/run.py (multiplataforma).

Hard rules: Fase 3 não roda sem test_plan.md aprovado (exceto --auto-approve em CI/CD); sub-agents nunca travam o pipeline (marcam NOT_EXECUTED e seguem); SARIF é o formato canônico; toda execução produz security_report.md.

Estrutura interna:

security-audit-workflow/
├── SKILL.md                 # workflow normativo
├── templates/
│   ├── contracts/           # contratos YAML por sub-agent
│   └── outputs/             # exemplos: security_profile, scope, test_plan, security_report
└── tools/
    ├── README.md
    ├── tools.json           # mapping tool → image → comando
    └── run.py               # wrapper Docker multiplataforma

java

Papel: Padrão único para Java 25 / Spring Boot 4.1 — a decisão, não o tutorial. Substitui as sete skills java-*.

Modelo: Clean Architecture em módulos Maven (domain, application, api, um infra-* por tecnologia), pacote por agregado dentro de cada módulo e visibilidade package-private como fronteira. Uma classe concreta por caso de uso (@UseCase), sem dispatcher nem interface por caso de uso; modelo JPA separado do domínio; UUIDv7 gerado no domínio; Clock injetado; outbox obrigatório com Spring AMQP.

Gates executáveis (assets/): POM raiz com maven-enforcer-plugin (pacotes proibidos), forbiddenapis (UUID.randomUUID(), now() sem Clock, Jackson 2, locale padrão), Error Prone + NullAway sobre JSpecify, Spotless, architecture-tests com ArchUnit e o gate de imutabilidade de migrations Flyway — verificados contra JDK 25 e Boot 4.1.1.

Referências sob demanda: arquitetura, persistência, mensageria, testes, operação e formatos (Monolito Modular com Spring Modulith, Microsserviços).


find-docs

Papel: Busca documentação atualizada, referências de API e exemplos de código para qualquer tecnologia, via Context7.

Método de acesso (prioridade):

  1. Context7 MCP — se mcp__plugin_context7_context7__resolve-library-id estiver disponível, usa diretamente sem CLI.
  2. ctx7 CLI — fallback quando o MCP não está disponível (npx ctx7@latest).

Fluxo em dois passos: resolve o nome da biblioteca para um ID Context7 → consulta a documentação com esse ID.

Quando usar: qualquer pergunta sobre sintaxe de API, opções de configuração, migração de versão, debugging de comportamento específico de biblioteca ou setup de CLI — mesmo para libs conhecidas como React, Next.js, Prisma ou Spring Boot, pois o training data pode estar desatualizado.


react

Papel: Padrao unico de React + Vite + TypeScript. Consolida as sete skills anteriores (react-architecture, react-code-quality, react-observability, react-production-readiness, react-runtime-config, react-subpath-deploy, react-testing).

Forma: declara a decisao, nao ensina a implementar. O modelo ja sabe escrever o codigo; a skill diz qual das alternativas equivalentes este projeto usa e onde cada coisa mora.

Arquitetura: derivada do bulletproof-react, com dois desvios deliberados e declarados — config de runtime por window.RUNTIME_ENV em vez de import.meta.env (12-factor, imagem imutavel) e zonas de ESLint geradas a partir de src/features em vez de escritas a mao.

Pilares:

  • Estrutura unica (sem niveis "pequeno/medio/grande"): app/, components/, config/, features/, hooks/, lib/, stores/, testing/, types/, utils/.
  • Tres fronteiras executaveis, nao convencionais: fluxo unidirecional (compartilhado -> features -> app), sem import entre features e sem barrel — todas garantidas por assets/eslint.config.js.
  • Camada de API: um arquivo por endpoint em features/*/api/, exportando schema Zod, fetcher e hook React Query.
  • Estado por natureza do dado: componente, aplicacao, cache de servidor, formulario e URL — dado de servidor nunca em store global.
  • Testes: integracao como centro de gravidade; MSW como unica fronteira de mock.
  • Runtime e deploy: uma imagem para todos os ambientes; subpath como propriedade da aplicacao.

Assets verificados: eslint.config.js (testado contra violacoes reais e contra falso positivo), tsconfig.json (compila em TypeScript 7, sem baseUrl), Dockerfile, nginx.conf.template, docker/40-runtime-env.sh e ingress.yaml (validados em container, incluindo deep link em subpath).

Quando acionar: qualquer trabalho React — criar projeto ou feature, revisar diff, escrever teste, containerizar, servir em subpath ou instrumentar.

Source 3 files
hooks/register.tsx 98 lines
1import { atom, read, update } from 'claude-code'
2import type { Register } from 'claude-code'
3
4import type { Phase, Progress } from '../types'
5import { parseChecklist, parseStatus, summarize } from './progress'
6import type { FlowState, TaskInfo } from './progress'
7
8const progress = atom({ plugin: 'flow-progress', key: 'progress' } as const, null)
9const isHidden = atom({ plugin: 'flow-progress', key: 'isHidden' } as const, false)
10
11const POLL_MS = 3000
12const LABEL: Record<Phase, string> = {
13  dev: '⚙ desenvolvimento',
14  review: '🔍 review',
15  blocked: '⛔ bloqueada',
16  integration: '🔀 integração',
17  done: '✅ concluído',
18  idle: '⏸ aguardando',
19}
20
21// The newest `tasks/prd-*/flow-state.json` is the PRD being orchestrated.
22async function scan($: any): Promise<Progress | null> {
23  const entries = await $.fs.list('tasks').catch(() => [])
24  let best: { dir: string; mtime: number } | null = null
25
26  for (const entry of entries) {
27    if (entry.kind !== 'directory' || !entry.name.startsWith('prd-')) continue
28    const dir = `tasks/${entry.name}`
29    const stat = await $.fs.stat(`${dir}/flow-state.json`).catch(() => null)
30    if (stat && (!best || stat.mtimeMs > best.mtime)) best = { dir, mtime: stat.mtimeMs }
31  }
32  if (!best) return null
33
34  const state: FlowState | null = await $.fs
35    .read(`${best.dir}/flow-state.json`)
36    .then((t: string) => JSON.parse(t))
37    .catch(() => null)
38  const checklist: TaskInfo[] = await $.fs
39    .read(`${best.dir}/tasks.md`)
40    .then(parseChecklist)
41    .catch(() => [])
42
43  // Frontmatter status is finer than the checkbox (in_progress, validating, blocked).
44  const tasks = await Promise.all(
45    checklist.map(async t => {
46      const status = await $.fs
47        .read(`${best.dir}/${t.id.split('.')[0]}_task.md`)
48        .then(parseStatus)
49        .catch(() => null)
50      return { id: t.id, status: t.status === 'done' ? 'done' : (status ?? t.status) }
51    }),
52  )
53
54  return summarize(best.dir.replace('tasks/', ''), tasks, state)
55}
56
57export const register: Register = on => {
58  on('session.start', async ($, e, next) => {
59    const refresh = async () => {
60      const found = await scan($)
61      await update($, progress, () => found)
62    }
63    await refresh()
64    $.clock.every(POLL_MS, refresh)
65
66    return next(e)
67  })
68
69  on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
70    const p = (await read($, progress)) as Progress | null
71
72    if (e.props.hasSurvey || !p || p.total === 0 || (await read($, isHidden))) {
73      return next(e)
74    }
75
76    const { Box, Button, Text } = $.ui.resolve(e)
77    const width = 10
78    const filled = Math.round((p.done / p.total) * width)
79    const bar = '█'.repeat(filled) + '░'.repeat(width - filled)
80    const color =
81      p.phase === 'blocked' ? 'red' : p.phase === 'done' ? 'green' : p.phase === 'review' ? 'yellow' : 'cyan'
82
83    return (
84      <Box>
85        <Text dimColor>{p.prd} </Text>
86        <Text>
87          {bar} {p.done}/{p.total}{' '}
88        </Text>
89        <Text color={color}>
90          {LABEL[p.phase]}
91          {p.task ? ` (task ${p.task})` : ''}{' '}
92        </Text>
93        <Button key="hide" label="Ocultar" onPress={() => update($, isHidden, () => true)} />
94      </Box>
95    )
96  })
97}
98
hooks/progress.ts 77 lines
1import type { Phase, Progress } from '../types'
2
3export type TaskInfo = { id: string; status: string }
4
5export type FlowState = {
6  phase?: string
7  active_task?: string | null
8  last_result?: unknown
9}
10
11// `- [x] 1.0 Título` under tasks.md; the checkbox is the Integrator's record of done.
12export const parseChecklist = (md: string): TaskInfo[] =>
13  [...md.matchAll(/^\s*- \[([ xX])\]\s+(\d+(?:\.\d+)*)/gm)].map(m => ({
14    id: m[2],
15    status: m[1] === ' ' ? 'pending' : 'done',
16  }))
17
18// Canonical frontmatter values: pending | in_progress | validating | blocked | done.
19export const parseStatus = (md: string): string | null => {
20  const front = md.match(/^---\n([\s\S]*?)\n---/)
21  const line = front?.[1].match(/^status:\s*([a-z_]+)/m)
22  return line ? line[1] : null
23}
24
25const fromStatus = (status: string): Phase | null =>
26  status === 'in_progress'
27    ? 'dev'
28    : status === 'validating'
29      ? 'review'
30      : status === 'blocked'
31        ? 'blocked'
32        : null
33
34const fromPhase = (phase: string): Phase =>
35  /block/i.test(phase)
36    ? 'blocked'
37    : /integrat|full|complete|deliver/i.test(phase)
38      ? 'integration'
39      : /validat|review|revalid/i.test(phase)
40        ? 'review'
41        : /implement|fix|dev/i.test(phase)
42          ? 'dev'
43          : 'idle'
44
45export const summarize = (
46  prd: string,
47  tasks: TaskInfo[],
48  state: FlowState | null,
49): Progress => {
50  const done = tasks.filter(t => t.status === 'done').length
51  const total = tasks.length
52  const blocked = tasks.find(t => t.status === 'blocked')
53  const active =
54    tasks.find(t => t.id === state?.active_task) ??
55    tasks.find(t => fromStatus(t.status) !== null && t.status !== 'blocked')
56
57  let phase: Phase
58  let task: string | null = null
59
60  if (blocked) {
61    phase = 'blocked'
62    task = blocked.id
63  } else if (total > 0 && done === total) {
64    phase = /complete|done/i.test(state?.phase ?? '') && !/full|integrat/i.test(state?.phase ?? '')
65      ? 'done'
66      : 'integration'
67  } else if (active && fromStatus(active.status)) {
68    phase = fromStatus(active.status) as Phase
69    task = active.id
70  } else {
71    phase = state?.phase ? fromPhase(state.phase) : 'idle'
72    task = state?.active_task ?? null
73  }
74
75  return { prd, done, total, phase, task }
76}
77
types/index.d.ts 16 lines
1export type Phase = 'dev' | 'review' | 'blocked' | 'integration' | 'done' | 'idle'
2
3export type Progress = {
4  prd: string
5  done: number
6  total: number
7  phase: Phase
8  task: string | null
9}
10
11declare module 'claude-code' {
12  interface PluginState {
13    'flow-progress': { progress: Progress | null; isHidden: boolean }
14  }
15}
16