Skip to content

Contributing to Cinatra

Thanks for your interest. Cinatra is the open source AI workspace for teams, and external contributions — bug reports, agent extensions, connectors, documentation, code — are welcome.

This document covers how to contribute. For the developer setup itself, see Installation.


Cinatra plans and drives work with GSD (“Git. Ship. Done”) — the open-gsd spec-driven development framework (@opengsd/gsd-core). Its disciplined phase loop — discuss → plan → execute → verify — is how work moves from idea to merged PR: align on the problem in an issue, agree the approach, then implement and verify. The issue-first conventions below follow directly from that loop.


Open a GitHub issue with:

  • What you expected to happen
  • What actually happened
  • The minimum reproduction (steps, sample input, environment)
  • Versions: Node, pnpm, Docker, and the commit hash of the Cinatra working tree

For security issues, do not open a public issue. See Security for the private disclosure path.

Open a GitHub issue with the use case first. Explain the user problem and the shape of the solution; we will discuss the design before any implementation. Large feature work without prior alignment tends to require significant rework.

Pull requests are welcome. Before working on a PR:

  • For a bug fix: open an issue first only if the bug is non-obvious or you need clarification.
  • For a feature or refactor: open an issue or discussion first. We will agree on the approach before you invest time.

PRs should:

  • Pass pnpm typecheck and pnpm lint cleanly.
  • Touch the smallest surface that achieves the goal. Bundle related changes; do not bundle unrelated changes.
  • Update or add documentation when the change affects what an external user sees.
  • Include tests when the change touches code that already has tests in its directory.

Cinatra is designed to host third-party agent extensions. To publish one:

  1. Author the agent as an Open Agent Specification (OAS) Flow file under agents/<vendor>/<slug>/cinatra/oas.json.
  2. Add a package.json with your namespace, version, and Cinatra metadata.
  3. Test locally by installing into your dev instance.
  4. Publish to the hosted public registry (or your private one). See Building packages and Developing agents for the authoring conventions.

Agent extensions do not need to live in this repository — the platform installs from any compatible npm-style registry. Contributing a package to this repository is the right move only if it is broadly useful and you are willing to maintain it.

Working on the WordPress plugin / Drupal module

Section titled “Working on the WordPress plugin / Drupal module”

The Cinatra WordPress plugin and Drupal module live in their own repos (cinatra-ai/wordpress-plugin, cinatra-ai/drupal-module), consumed locally as gitignored clones. Where your commit goes (extracted repo vs cinatra), contract-version bumps, dirty-tree recovery, and the volume-scoped dev migration are all covered in wp-drupal-plugin-development.md.

UAT override label. PRs touching the contract / plugin-integration paths trigger the Playwright UAT hard gate (wp-drupal-uat.yml). A planned migration that knowingly breaks a UAT may land with the override-wp-drupal-uat label, which requires both owners’ review and a PR-body section stating: what breaks, the expected follow-up PR(s), and the rollback path. Use it rarely.


AI-agent-assisted development (Cinatra dev-skills)

Section titled “AI-agent-assisted development (Cinatra dev-skills)”

The @cinatra-ai/dev package installs a set of Claude Code skills that carry Cinatra’s accumulated development knowledge — conventions, setup steps, domain gotchas, extension-authoring rules — directly into an AI coding agent. Installing the skills means the agent (Claude Code) already knows the org process and can guide you through it from first clone to merged PR. You do not need to memorise the conventions; the agent does.

Clone the public dev-skills repo and run the installer:

Terminal window
git clone https://github.com/cinatra-ai/dev
cd dev
node bin/install.mjs --claude --global --dry-run # preview — nothing is written
node bin/install.mjs --claude --global # apply

A successful run prints [install] OK — staged N skill(s), N agent(s) into <path>.

If you already have the repo cloned, pass --source . from inside it to skip the internal re-clone the installer performs as its access gate:

Terminal window
node bin/install.mjs --claude --global --source .

To remove the skills:

Terminal window
node bin/uninstall.mjs --claude --global

Note: the clone-and-run path above is the current working route. A one-step npx @cinatra-ai/dev --claude --global path will be available once the package is published to npm.

Skills activate on natural-language trigger phrases inside Claude Code — no slash commands needed. After installation, start a Claude Code session in the Cinatra repo and say one of the trigger phrases below. The recommended starting sequence is: dev-onboardingdev-setupdev-cinatra-dev-env → then dev-extension-conventions or dev-domain-gotchas as the work requires.

Installed skill ID Trigger phrase What it does
dev-onboarding “install the dev skills pack” / “onboard to the dev workflow” Step-by-step walkthrough from bare machine to first shipped change
dev-setup “set up my cinatra machine” / “bootstrap my dev environment” Doctor probe + toolchain install + Claude baseline config (dry-run by default)
dev-cinatra-dev-env “run cinatra locally” / “spin up the verify stack” Brings up the local dev/verify stack; explains extension locks and LLM credential rules
dev-extension-conventions “create-cinatra-extension” / “extension repo conventions” Five-kind extension architecture, scaffolding, and pin choreography
dev-domain-gotchas “design repo asset conformance” / “docs repo convention” Per-repo non-obvious traps: design spec, release CI, schema migrations, CodeQL, cold-compile, container-URL split

For the full skills reference and changelog, see the cinatra-ai/dev README.

The installer is idempotent — re-running it is safe. It makes two changes to your global Claude Code setup:

  • Skills are staged to ~/.claude/skills/dev-<name>/SKILL.md, one directory per skill.
  • A FileChanged hook is deep-merged into ~/.claude/settings.json so Claude Code reloads automatically when .cinatra-dev/config.json changes. This merge uses a keyed sentinel and never overwrites your existing GSD or personal settings block.

The installer also writes a managed org block to ~/.claude/CLAUDE.md covering the truthful-attribution direction and the no-AI-co-authorship rule. Any block already written by a previous install is updated in place; your personal content is left untouched.

For extension authoring, see extension-authoring.md and developing-agents.md.


See Installation.

After the platform is running, verify the toolchain:

Terminal window
pnpm typecheck # fast type check via tsgo
pnpm lint # ESLint
pnpm build # production build

When you pull new code, your local dependencies and dev database schema can fall behind it — a forgotten pnpm install or schema migration is the usual cause of a “column does not exist” crash. Reconcile both with one command:

Terminal window
git pull
make refresh # equivalently: pnpm refresh:dev / pnpm exec cinatra dev refresh

make refresh is dev-only and never touches git — you manage branches; it only brings dependencies and the dev database in sync with the code on disk. Concretely it:

  • brings the bundled docker stack up (skipped automatically for isolated worktrees/clones and external infra; --docker=always forces it, --no-docker skips it),
  • runs pnpm install,
  • runs the idempotent dev setup: applies additive schema changes, then runs the versioned core migration chain (migrations/core/, recorded in the pgmigrations ledger) so transformational changes (renames/backfills) apply automatically too, and ensure-settings.

It does not rebuild images. Hand-run release-note migrations are retired — the old src/lib/migrations/ one-shot directory no longer exists; the core migration chain reconciles the schema for you. Restart with make dev afterwards.

The codebase follows the conventions documented in AGENTS.md at the repository root. Highlights:

  • TypeScript first. Strict mode is on (noImplicitAny: false). Always use import type for type-only imports.
  • Kebab-case file names. PascalCase types and components; camelCase functions and variables.
  • Packages communicate through capability surfaces, not by importing each other’s internals. If you need functionality from another package, call its Model Context Protocol (MCP) primitives through the deterministic client.
  • Server actions live next to the surface that uses them. Never split a server action into a separate package just to “share” it; if it is shared, expose it through an MCP primitive.
  • UI uses shadcn/ui components. Do not introduce raw HTML elements where a shadcn component exists. Do not hardcode Tailwind palette colors — use semantic tokens.

Every full-page screen wraps in the standard three-component shell (Main, PageHeader, PageContent). Do not bypass this with raw <div> wrappers; the layout primitives enforce visual consistency across the platform.

Each package owns its tests in __tests__/ or tests/ subdirectories. Run them with pnpm --filter <package> test.

There is no global test runner currently — tests are package-local.

  • Commit messages describe the why, not just the what.
  • Atomic commits are preferred over large bundles.
  • Branch off main. The default branch protection requires linear history.

PR titles should be short and descriptive. PR bodies should include:

  • Summary — what changed and why
  • Testing — what you did to verify it works
  • Screenshots — for UI changes, before and after

Avoid merging your own PRs without review. Wait for a maintainer.


  • GitHub issues for bugs, feature requests, and design discussions
  • GitHub discussions (when enabled on the repo) for open-ended questions
  • Pull requests for code changes
  • Email for private security disclosure (Security)

We aim to triage issues and PRs within a few business days. If something has been quiet for over a week, a polite ping is welcome.


This section is about contributing to the cinatra-ai/docs repository itself — the source for docs.cinatra.ai — as opposed to the Cinatra product covered above.

A first-party integration’s documentation hub on docs.cinatra.ai (for example /integrations/wordpress/) is authored in the integration’s own repository under docs/, not in this repository — see The integration docs contract for the required six-page shape, frontmatter, and content rules.

references/design/design-system.html in this repository is a published, byte-for-byte mirror of Cinatra’s canonical design-system spec; the editable source lives upstream. Do not hand-edit design-system.html here — changes are overwritten the next time it is synced from the canonical spec. If the mirror and the canonical spec disagree, that is a CI-caught drift, not a hand-edit target — fix the upstream spec instead. To re-run the local drift/token checks:

Terminal window
node scripts/design/snapshot-tokens.mjs --check # warns if token retune is needed
node scripts/design/scan-raw-colors.mjs # warns if a new raw-color leak appears
node scripts/design/scan-status-render.mjs # warns if a new ad-hoc status renderer appears

Keeping published pages free of meta-commentary

Section titled “Keeping published pages free of meta-commentary”

Pages under guides/, references/, integrations/, and resources/ describe Cinatra the product for readers — not how this documentation site itself is authored, generated, or maintained. Notes like the two above (generation mechanics, sync/mirror caveats, contract/compile pipelines) belong in this section, not on a published page. A CI check enforces this on every pull request; a reviewed, time-boxed allowlist (.github/meta-commentary-gate-allowlist.json) covers genuine false positives.


The Cinatra code (the cinatra-ai/cinatra repository) is licensed under the Apache License 2.0. By contributing code there, you agree that your contributions will be licensed under those same terms.

The documentation content in this repository is licensed under the Creative Commons Attribution 4.0 International License (CC-BY-4.0) — see the LICENSE file at this repository’s root. Code snippets embedded in the documentation are licensed under Apache-2.0, matching the code repository. By contributing to the documentation, you agree that your prose and diagram contributions will be licensed under CC-BY-4.0 and any embedded code snippets under Apache-2.0.

Docs content licensed under CC-BY-4.0; embedded code snippets under Apache-2.0.