Skip to main content

Branching

master is the main branch and the usual PR target. Branch names in the history follow a type prefix:
Work merges into master through pull requests.

Before you push

Run the same checks CI does, in this order:
Both formatters rewrite files, so run them before committing rather than after review feedback. npm run format:check is the non-writing variant if you only want to know whether something is off.

CI

Two workflows live in .github/workflows, both triggered on pushes and pull requests targeting master or develop:
lint.yml does not currently enforce anything. Both steps run in write mode — vendor/bin/pint and npm run format rewrite files and exit 0 — and the git-auto-commit-action step that would have pushed the result is commented out. So the formatting is applied to a throwaway checkout and discarded.Neither formatter passes on the repository as it stands (pint --test and npm run format:check both report a large number of files), so switching the workflow to check mode needs a repo-wide formatting commit first. Until then, treat a green linter run as “the workflow completed”, not “the code is formatted”.
There is no frontend linting step. ESLint is not a dependency of this project — the old eslint.config.js was Vue configuration inherited from the laravel/vue-starter-kit skeleton and was removed once the app moved to React. Type safety comes from npm run typecheck instead.
develop is kept in the trigger list but does not currently exist as a remote branch. master is the live target.

Code conventions

  • PHP — Laravel Pint with the project’s default preset. Formatting is not negotiable; let Pint decide.
  • TypeScript — strict compilation via npm run typecheck. Prettier handles layout, with prettier-plugin-organize-imports sorting imports and prettier-plugin-tailwindcss ordering class names.
  • Routes — add to the file in routes/ that matches the concern rather than growing web.php. Always name routes; Ziggy exposes them to the frontend.
  • Provider calls — never in the request cycle. Dispatch a job and let the UI poll.
  • New provider costs — add the model to config/ai.php with cost_per_1k_tokens, or TokenUsageTracker will record spend as zero.

Tests

Pest, split into tests/Unit and tests/Feature. Feature tests cover the Inertia pages and settings flows — see PromptsPageTest, VisibilityPromptAnalyticsTest and OnboardingCompleteTest for the established patterns. The sync queue driver means dispatched jobs run inline, so assert against the resulting records rather than against the queue.
phpunit.xml’s in-memory SQLite setting is not currently taking effect — see Development › Tests. A local run against a .env pointing at MySQL migrates your development database and fails. Verify the suite’s state before treating a local failure as your own regression.