Saltar al contenido principal

Contribuir

El repositorio es Hoyasumii/plane, gestionado con pnpm (Node.js 20 o una versión posterior).

pnpm install # dependencias, más los git hooks (husky)
pnpm build # compila a dist/ y empaqueta dist/types.bundle.d.ts
pnpm dev # tsc --watch
pnpm test:unit # tests unitarios (no necesita una instancia de Plane)
pnpm check:lint # oxlint (`pnpm fix:lint` corrige lo que puede)
pnpm check:format # oxfmt, 120 columnas (`pnpm fix:format` reescribe)
pnpm check:knip # archivos, exports y dependencias sin usar

Las comprobaciones se ejecutan en local mediante git hooks. pre-commit ejecuta check:lint y check:format, commit-msg ejecuta commitlint con la configuración convencional (feat: …, fix(mcp): …), y pre-push ejecuta check:types, check:knip y test:unit.

Cada push a main ejecuta el workflow de Continuous Delivery (.github/workflows/cd.yml). Ejecuta las mismas comprobaciones y el build, y después:

  • publica en npm la versión de package.json cuando aún no está en el registro (mediante Trusted Publishing, con provenance), la etiqueta como v<versión> y crea una release en GitHub;
  • construye el sitio y lo despliega en la rama gh-pages cuando el push toca website/ o src/ (una ejecución manual del workflow siempre lo despliega).

Para publicar una versión, sube version en package.json y haz merge en main.

Compilar desde el código fuente​

pnpm build ejecuta tsc hacia dist/, empaqueta las definiciones de tipos en dist/types.bundle.d.ts y compara los exports de ese bundle con scripts/__fixtures__/types-bundle-exports.snapshot.txt. Si cambiaste los exports públicos a propósito, actualiza el snapshot. Para una recompilación limpia:

pnpm clean # borra dist/ y node_modules/
pnpm install
pnpm build

Después de cambiar cualquier cosa en src/api/v2/, ejecuta pnpm codegen:mcp para regenerar el catálogo de métodos que lee el servidor MCP (src/mcp/generated/catalog.json). src/api/v2/generated/constants.ts se genera con pnpm codegen:v2 a partir del documento OpenAPI de api_v2: nunca edites ninguno de los dos a mano.

Para probar la compilación en local, ejecuta node dist/cli/index.js --help, o enlázala con npm link y ejecuta plane --help. npm pack --dry-run lista exactamente lo que se publicaría.

Tests​

Los tests viven en tests/unit/ y tests/e2e/. Los tests unitarios no necesitan una instancia de Plane. Los tests de extremo a extremo necesitan un .env.test con ids reales:

cp env.example .env.test

Luego completa TEST_WORKSPACE_SLUG, TEST_PROJECT_ID, TEST_USER_ID, TEST_WORK_ITEM_ID, TEST_CUSTOMER_ID y los demás ids que pidan las suites.

pnpm test # todo
pnpm test:unit # solo tests unitarios
pnpm test:e2e # solo tests de extremo a extremo
pnpm test tests/unit/page.test.ts # un archivo

Los tests se ejecutan de uno en uno, para no superar el límite de peticiones de Plane.

Cómo se mantiene honesta la superficie v2​

La superficie v2 son 90 clases de recursos, y nada de ella se revisa por muestreo. Los rule sweeps se ejecutan sobre todas las clases, enumeradas a partir del código fuente de TypeScript, y cada uno se demuestra introduciendo la infracción y viendo cómo el sweep la señala:

SweepQué rechaza
Forma de la llamadaun método que no empieza con los ids de ruta de su URL, en el orden de la ruta
fields / expanduna operación que ofrece una proyección que el SDK no expone
Filtros de consultaun ?filter= que la API acepta y que ningún tipo de params declara
order_byun orden de clasificación que falta, o un tipo de params apuntando al enum de otra operación
Paginaciónuna mitad inalcanzable del sobre de paginación, incluido un paginate sin cursor para gastarlo
Correspondencia de operacionesun método sin entrada en operations, exento en silencio de todo lo anterior
Solidez de la proyecciónun método que acepta fields y de todos modos devuelve la fila completa
Enrutamiento del loaderun método que devuelve filas en una clase navegable y se salta load()
Rutas alternativasun método que declara un override de extraPaths y lo ignora
Lookupsun findBy* que filtra por algo que la API no permite filtrar

Otros dos sweeps cubren el árbol en vez de las clases: la completitud de banda exige que todo recurso esté conectado a la raíz que nombra la plantilla de su URL (y que nada ajeno lo esté), y la completitud de navegación exige que un recurso que conecta un hijo devuelva filas navegables, con una propiedad por hijo y ninguna propiedad que tape un campo real. Cada método también verifica su URL de petición exacta contra un servidor simulado.

La documentación también se comprueba. tests/unit/v2/readme-samples.test.ts verifica en tiempo de compilación cada fence de TypeScript en README.md, CLAUDE.md, AGENTS.MD y cada página de este sitio, en todos los idiomas, contra el código fuente del SDK. También comprueba las afirmaciones en prosa que son hechos sobre el repositorio: scripts que existen, rutas que existen, nombres de v2. que se exportan y límites de lote que coinciden con el kernel.

Este sitio​

El sitio vive en website/, un paquete del workspace construido con Docusaurus. Las guías son Markdown en website/docs/, cada traducción las refleja en website/i18n/<locale>/, y la referencia de la API se genera desde src/ con TypeDoc en cada compilación.

pnpm docs:dev # vista previa en vivo, en inglés
pnpm docs:dev --locale pt-BR # vista previa en vivo en otro idioma (pt-PT, es-ES, zh-Hans, …)
pnpm docs:build # todos los idiomas, en website/build/
GIT_USER=<github-user> pnpm docs:deploy # compila y publica en la rama gh-pages

La búsqueda (Ctrl/Cmd+K) usa un índice offline, uno por idioma, que genera pnpm docs:build; no funciona con pnpm docs:dev, así que pruébala con pnpm docs:serve después de un build. La referencia de la API queda fuera del índice. El build en inglés también genera llms.txt y llms-full.txt en la raíz del sitio, a partir de las guías en inglés, para que las lean las herramientas de IA. Ambos son salida del build: nunca los subas al repositorio ni los escribas a mano.