Shipflow

Convierte un ticket en un merge request con tu agente de IA. Tú traes el agente (Claude Code, Cursor, Gemini, Copilot, Codex); Shipflow pone los rieles deterministas: compuertas de arquitectura, generación de código por configuración y un pipeline reproducible de ticket → PR.

  ticket  ──►  analiza → diseña → implementa → corre gates → revisa  ──►  merge request

En una frase: el ticket entra por la izquierda y el merge request sale por la derecha. En medio hay pasos que siempre se hacen igual; shipflow es el riel que obliga ese orden y verifica la arquitectura en cada paso, mientras tu agente de IA (Claude Code · Cursor · Gemini · Copilot · Codex) hace el trabajo. El ticket puede venir de Asana / Jira / Linear / archivo; el diseño, de Figma / imagen / markup. Diagrama completo y por capas →

Shipflow es un paquete de Dart + CLI (ship) para proyectos Flutter. Es agnóstico a tu stack: manejador de estado (Riverpod / Bloc / GetX / Provider), fuente de tickets (Asana / Jira / Linear / archivo), fuente de diseño (Figma / imagen / markup) y proveedor de MR — todo se declara en un único archivo .ship.yaml.

⚠️ Léelo antes de instalar — qué es y qué no es

  • Shipflow no llama a ninguna IA por sí mismo. El paquete es 100% determinista (analizadores, matching, scaffolding). La parte de IA son prompts en markdown (core/commands/) que ejecuta el agente que tú ya usas. Si no tienes una CLI de IA, Shipflow sigue siendo útil como linter de arquitectura — pero el pipeline ticket→MR no funcionará.
  • El núcleo está probado; el pipeline está en vista previa. Ver Madurez más abajo — es importante que lo leas antes de decidir.

Madurez

Sé honesto sobre en qué confiar hoy:

Parte Qué es Estado
Núcleo deterministaship analyze, match, scaffold, inventory, las compuertas, los 17 analizadores El motor que revisa arquitectura, fidelidad de diseño y genera scaffolds Probado contra un proyecto real. La primera corrida de ship analyze sobre freya (app Flutter de producción) arrojó 890 hallazgos (1 bloqueador, 13 críticos, 847 mayores, 29 menores) — por eso existe el reporte HTML con triaje. 625 pruebas en verde.
Pipeline IA ticket→MR — los prompts de core/commands/ orquestados por tu agente El flujo completo "lee el ticket → implementa → revisa → abre el MR" 🧪 Vista previa. Funciona, pero trátalo como camino que puede requerir corrección humana: el tag 1.0.0 espera validar paridad de forma sistemática. Los reportes de bugs son bienvenidos.

v0.1.0. El tag 1.0.0 espera la validación de paridad del pipeline completo.


¿Es para ti?

Si eres… Shipflow te sirve para… Encaje
Equipo Flutter con arquitectura por capas (Clean Architecture u otra) Forzar invariantes de arquitectura en CI, generar scaffolds consistentes, y (preview) automatizar el flujo ticket→MR con IA ✅ Ideal
Dev que quiere un linter de arquitectura/diseño determinista para Flutter ship analyze + reporte HTML de triaje, sin tocar nada de IA ✅ Sí
Indie sin estructura por capas que busca "una IA que escriba mi app" Shipflow gobierna y verifica código sobre rieles; no es un generador de apps end-to-end ⚠️ Probablemente no

Sobre la arquitectura por capas: ship init autodetecta carpetas canónicas de Clean Architecture (lib/src/{domain,infrastructure,presentation}/), pero no estás obligado a usarlas — en .ship.yaml puedes declarar las capas y reglas de importación que tu proyecto realmente tenga (ver el ejemplo real en config/examples/sample_app.yaml). Si tu proyecto no tiene ninguna noción de capas, Shipflow no es para ti todavía.


Requisitos

Antes del inicio rápido, confirma que tienes:

  • Dart SDK ≥ 3.12 (dart --version).
  • ~/.pub-cache/bin en tu PATH — tras dart pub global activate, ahí queda el ejecutable ship. Si ship --help da "command not found", agrega export PATH="$PATH":"$HOME/.pub-cache/bin" a tu shell.
  • Un proyecto Flutter o Dart con alguna estructura por capas (ver ¿Es para ti?).
  • (Solo para el pipeline ticket→MR) una CLI de IA con comandos invocables: Claude Code, Cursor, Gemini CLI, Copilot CLI o Codex. El núcleo determinista no la necesita.

Inicio rápido

De un proyecto Flutter existente a tu primer reporte de análisis, copiando y pegando desde la raíz de tu proyecto.

1 — Instalar Shipflow

dart pub global activate shipflow
ship --version       # verifica la instalación → imprime "ship 0.1.0"
ship --help          # (opcional) lista todos los subcomandos
Instalar desde el código fuente (o compilar a binario nativo)
git clone https://github.com/GuzCabQ/shipflow.git
cd shipflow
dart pub get
./tool/compile.sh    # opcional: produce bin/ship, un binario nativo autocontenido (~10 MB)

2 — Generar .ship.yaml desde tu proyecto

ship init --template config

Lee tu pubspec.yaml y escanea el sistema de archivos en busca de tus capas. Cada campo generado lleva un comentario que documenta su origen — así sabes qué ajustar:

# .ship.yaml (extracto generado)
state_management:
  style: riverpod_manual          # inferred from pubspec.yaml (flutter_riverpod)
architecture:
  layers:
    domain:
      paths:
        - lib/src/domain/         # detected at lib/src/domain/
      forbid_imports:
        - "package:flutter/"      # default — el dominio no debe depender de Flutter
    infrastructure:
      paths:
        - lib/data/               # PLACEHOLDER — no se detectó automáticamente

Abre .ship.yaml y resuelve los # PLACEHOLDER (los campos que Shipflow no pudo detectar). Para un proyecto con estructura no canónica (data/ en vez de infrastructure/, nombres en español, feature-first) habrá varios — es normal.

Atajo opcional con IA: el comando /ship-complete-config (ver Instalar los comandos en tu agente) construye el grafo de tu código y propone las rutas de capa y reglas de importación a partir de tus dependencias reales, mostrándote un diff para aprobar. Si aún no configuras tu agente, resuelve los placeholders a mano guiándote por config/examples/sample_app.yaml.

3 — Ejecutar el primer análisis

ship analyze --gate domain --format human

Salida esperada (ejemplo):

▶ Gate: domain   (analizadores: layer_integrity, …)

  ✗ blocker  lib/src/domain/user.dart:12
             domain importa package:flutter/material.dart (forbid_imports)
  ! major    lib/src/domain/order.dart:­8
             entidad sin test correspondiente (meaningful_test)

  1 blocker · 0 critical · 1 major · 0 minor   →  GATE FAILED

Un blocker o critical reprueba la compuerta (útil en CI); major/minor son informativos. Si aún no creaste las carpetas de capa, este es el momento en que se señalan: la compuerta es la fuente de verdad sobre si tu .ship.yaml coincide con la realidad.

Para proyectos grandes (recuerda: freya arrojó 890 hallazgos), el muro de terminal es inútil. Usa --format html:

ship analyze --gate full --format html -o ship-reports/

Escribe una carpeta autocontenida (index.html + styles.css + app.js + report.json). Abre ship-reports/index.html: muestra los pocos hallazgos bloqueantes por encima de los muchos informativos, con agrupación por severidad/archivo/analizador, filtros y búsqueda. Agrega ship-reports/ a tu .gitignore.

4 — (Opcional) Activar el flujo ticket → MR con tu agente de IA

Hasta aquí usaste solo el núcleo determinista. Para el pipeline ticket→MR necesitas una CLI de IA. La ruta completa es:

ship install-commands --platform claude   # 1. instala los prompts /ship-* en tu agente
/ship-complete-config                      # 2. (en tu agente) enriquece .ship.yaml desde el grafo del código
/ship-pipeline DEV-1234                    # 3. (en tu agente) ejecuta TICKET → MR de punta a punta

Los pasos 2 y 3 son slash-commands que se invocan dentro de tu CLI de IA, no en la terminal. Detalle completo en El pipeline ticket → MR.


¿Qué plantilla de init necesito?

Tu situación Comando Qué produce
Proyecto Flutter/Dart existente con código ship init --template config Solo .ship.yaml, desde tu pubspec.yaml + escaneo (el inicio rápido).
Proyecto recién creado con flutter create ship init --template project .ship.yaml + carpetas de capa vacías + stub de tokens de tema + stub de go_router + test/fakes/. Asume Riverpod + go_router.
Nuevo paquete feature en monorepo Melos / pub workspaces ship init feature_x --template feature Esqueleto de paquete Dart cuyo .ship.yaml apunta su catálogo de tokens a un design_system hermano (ADR-0011).

Otros comandos útiles

ship match color "#0066CC"                       # resolver un color contra tu catálogo de tokens
ship scaffold auth --layer presentation --style riverpod_manual   # generar un scaffold de feature
ship inventory --output widget_inventory.json    # inventariar widgets a JSON
ship context --run-directory .pipeline/runs/DEV-1234/   # construir el contexto para la siguiente llamada al agente
ship journal --run-directory .pipeline/runs/DEV-1234/   # inspeccionar el journal JSONL de una ejecución

El pipeline ticket → MR (vista previa)

🧪 Esta es la capa en vista previa (ver Madurez): aún no validada de extremo a extremo contra un proyecto real. El núcleo determinista que la sostiene sí lo está.

.ship.yaml habilita un pipeline de slash-commands en core/commands/: prompts en markdown que ejecuta tu CLI de IA. El paquete no llama a ninguna API de IA. El pipeline lee el ticket, genera un spec, implementa cada capa, corre las compuertas por capa, revisa y crea el MR. Todos los artefactos quedan en .pipeline/runs/<ticket_id>/.

Instalar los comandos en tu agente

ship install-commands instala de forma determinística los prompts en tu plataforma:

ship install-commands                       # menú interactivo
ship install-commands --platform claude     # o explícito
ship install-commands --platform all
ship install-commands --platform all --dry-run   # vista previa, sin tocar el disco
Plataforma Destino Notas
claude .claude/commands/<id>.md Frontmatter YAML description; $ARGUMENTS nativo
gemini .gemini/commands/<id>.toml TOML; $ARGUMENTS{{args}}
codex ~/.codex/prompts/<id>.md Instalación global — aplica a toda la máquina
cursor .cursor/commands/<id>.md Frontmatter YAML name + description

ship init --template config --platform claude hace el bootstrap de config + comandos en un solo paso. Para plataformas sin adaptador, ship commands-path imprime el directorio con los prompts + un INSTALL.md que tu agente puede seguir. Detalles en ADR-0021.

Ejecutar ticket → MR: /ship-pipeline

Este es el comando que orquesta todo el flujo. Una vez instalados los comandos, invócalo dentro de tu agente de IA (no en la terminal):

/ship-pipeline DEV-1234

Lee el ticket → genera el spec → implementa cada capa → corre las compuertas → revisa → abre el MR + handoff a QA. Reanuda desde la última fase completada si lo vuelves a invocar.

/ship-pipeline DEV-1234 [--ticket-file <ruta>] [--mode guided|semi|auto] [--reset]
  • --ticket-file <ruta> — usa un archivo local (adaptador file/) en vez de la fuente de tickets configurada.
  • --mode <modo> — sobrescribe pipeline.default_mode de .ship.yaml (ver Modos).
  • --reset — borra el directorio de la corrida y empieza de cero.

Antes de la primera corrida conviene ejecutar /ship-complete-config para que el .ship.yaml quede afinado contra el grafo real de tu código.

Modos de ejecución

Vía .ship.yaml::pipeline.default_mode:

Modo Se detiene en
guided Cada compuerta — aprobación explícita antes de cada fase.
semi Compuerta 0 (spec) y Compuerta Final (revisión).
auto Solo cuando falla un validador.

Comandos del pipeline (cada uno invocable por separado)

ship-analyze-ticket (ticket → análisis) · ship-design-feature (análisis → spec) · ship-implement-{domain,infrastructure,presentation} (implementación por capa) · ship-implement-bugfix · ship-run-gates · ship-review-feature · ship-create-mr · ship-complete-config (enriquece .ship.yaml desde el grafo) · ship-review-diff (revisión sobre git diff, sin correr el pipeline).

Las fases consultan un grafo de conocimiento del código (ver glosario) como fuente de hechos verificados: estima impacto, encuentra candidatos de reutilización, señala posibles regresiones y advierte de hubs de alto acoplamiento. El motor del grafo vive en el paquete dart_source_graph (^0.1.0), del cual Shipflow depende — ver ADR-0019 y ADR-0022.


Glosario

Términos que aparecen arriba, en una línea:

  • Compuerta (gate): una verificación por capa (p. ej. domain). Corre un conjunto de analizadores y reprueba si hay hallazgos blocker/critical. Es lo que pones en CI.
  • Capa (layer): una división de tu código (domain, infrastructure, presentation, …) con reglas de qué puede importar qué. Tú las declaras en .ship.yaml.
  • Catálogo de design tokens: el inventario de colores/tipografía/espaciado de tu tema, contra el cual Shipflow valida que la UI no use valores fuera del sistema de diseño.
  • Adaptador: la pieza que conecta Shipflow con un sistema externo o framework concreto (un manejador de estado, una fuente de tickets…). Agregar soporte = escribir un adaptador.
  • Paquete de contexto (context packet): el bundle de información que Shipflow arma para pasarle a tu agente de IA en la siguiente llamada (código relevante, reglas, hechos del grafo).
  • Grafo de conocimiento del código: el mapa de dependencias reales de tu lib/ que Shipflow construye para razonar sobre impacto, reutilización y regresiones.

Documentación


Para contribuyentes — arquitectura interna

Shipflow sigue Puertos y Adaptadores (hexagonal): todo sistema externo es un adaptador, todo algoritmo es un servicio. Los límites los aplica el PackageBoundaryAnalyzer sobre el propio árbol de Shipflow en cada build de CI (Shipflow se aplica sus propias invariantes — ver .ship.yaml y ADR-0001).

bin/ship.dart (shim CLI)
   └─ lib/src/cli/        CommandRunner + 16 comandos
        └─ Servicios      lib/src/{scaffolding,resolvers,inventory,matching(puro),core}/
             └─ Contratos  lib/src/contracts/   ← la superficie estable; todos importan de aquí
                  └─ Adaptadores  lib/src/adapters/{code_gen,token_catalog,…}/  (uno por sistema externo)

Invariantes estrictas (aplicadas por CI): contracts/ y matching/ son puros (sin I/O); analyzers/, core/ y los servicios no pueden importar adapters/ — la selección de adaptador ocurre en runtime por búsqueda de nombre en ProjectConfig. La estructura completa del repo está en ARCHITECTURE.md.

Desarrollo

dart pub get
dart analyze
dart test                                   # 625 pruebas
dart run tool/check_shipflow_boundaries.dart   # Shipflow se valida a sí mismo
./tool/compile.sh                           # compilar a nativo

Licencia

Licencia MIT — ver LICENSE.

Libraries

matching
Shipflow — Pure matching library.
shipflow
shipflow — the Flutter pipeline tool from the Shipflow suite.