

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
1# Chatwoot Development Guidelines23## Build / Test / Lint45- **Setup**: `bundle install && pnpm install`6- **Run Dev**: `pnpm dev` or `overmind start -f ./Procfile.dev`7- **Seed Local Test Data**: `bundle exec rails db:seed` (quickly populates minimal data for standard feature verification)8- **Seed Search Test Data**: `bundle exec rails search:setup_test_data` (bulk fixture generation for search/performance/manual load scenarios)9- **Seed Account Sample Data (richer test data)**: `Seeders::AccountSeeder` is available as an internal utility and is exposed through Super Admin `Accounts#seed`, but can be used directly in dev workflows too:10 - UI path: Super Admin → Accounts → Seed (enqueues `Internal::SeedAccountJob`).11 - CLI path: `bundle exec rails runner "Internal::SeedAccountJob.perform_now(Account.find(<id>))"` (or call `Seeders::AccountSeeder.new(account: Account.find(<id>)).perform!` directly).12- **Lint JS/Vue**: `pnpm eslint` / `pnpm eslint:fix`13- **Lint Ruby**: `bundle exec rubocop -a`14- **Test JS**: `pnpm test` or `pnpm test:watch`15- **Test Ruby**: `bundle exec rspec spec/path/to/file_spec.rb`16- **Single Test**: `bundle exec rspec spec/path/to/file_spec.rb:LINE_NUMBER`17- **Run Project**: `overmind start -f Procfile.dev`18- **Ruby Version**: Manage Ruby via `rbenv` and install the version listed in `.ruby-version` (e.g., `rbenv install $(cat .ruby-version)`)19- **rbenv setup**: Before running any `bundle` or `rspec` commands, init rbenv in your shell (`eval "$(rbenv init -)"`) so the correct Ruby/Bundler versions are used20- Always prefer `bundle exec` for Ruby CLI tasks (rspec, rake, rubocop, etc.)2122## Code Style2324- **Ruby**: Follow RuboCop rules (150 character max line length)25- **Vue/JS**: Use ESLint (Airbnb base + Vue 3 recommended)26- **Vue Components**: Use PascalCase27- **Events**: Use camelCase28- **I18n**: No bare strings in templates; use i18n29- **Error Handling**: Use custom exceptions (`lib/custom_exceptions/`)30- **Models**: Validate presence/uniqueness, add proper indexes31- **Type Safety**: Use PropTypes in Vue, strong params in Rails32- **Naming**: Use clear, descriptive names with consistent casing33- **Vue API**: Always use Composition API with `<script setup>` at the top3435## Styling3637- **Tailwind Only**:38 - Do not write custom CSS39 - Do not use scoped CSS40 - Do not use inline styles41 - Always use Tailwind utility classes42- **Colors**: Refer to `tailwind.config.js` for color definitions4344## General Guidelines4546- Prefer the smallest production-ready change that solves the current problem.47- Build for the expected production path first. Do not add speculative guards, fallbacks, retries, or edge-case handling unless the caller can actually hit that case or production has proven it necessary.48- Enforce eligibility and exclusivity rules at the earliest shared entry point. Do not repeat backup guards across downstream jobs, callbacks, services, or writes unless a proven independent path bypasses that point.49- When an impossible or misconfigured state would indicate a setup/deployment bug, let it fail loudly instead of silently skipping behavior.50- For locked/internal configs that must exist in production, prefer direct reads (`find`, `find_by!`, required hash keys) over silent fallbacks.51- Do not add validation or response checks unless the code uses the result or the check changes behavior meaningfully.52- Prefer existing repo dependencies/client libraries over hand-rolled protocol code for auth, signing, parsing, or API plumbing.53- Avoid one-use private helpers unless they hide real complexity or make the main flow meaningfully easier to read.54- Prefer minimal, readable code over elaborate abstractions; clarity beats cleverness55- Break down complex tasks into small, testable units56- Iterate after confirmation57- Avoid writing specs unless explicitly asked58- In specs, avoid custom helper methods for setup/data. Prefer `let` values and direct per-example setup; only add a helper when it removes meaningful repeated complexity.59- Remove dead/unreachable/unused code60- Don’t write multiple versions or backups for the same logic — pick the best approach and implement it61- Prefer `with_modified_env` (from spec helpers) over stubbing `ENV` directly in specs62- Specs in parallel/reloading environments: prefer comparing `error.class.name` over constant class equality when asserting raised errors6364## Codex Worktree Workflow6566- Use a separate git worktree + branch per task to keep changes isolated.67- Keep Codex-specific local setup under `.codex/` and use `Procfile.worktree` for worktree process orchestration.68- The setup workflow in `.codex/environments/environment.toml` should dynamically generate per-worktree DB/port values (Rails, Vite, Redis DB index) to avoid collisions.69- Start each worktree with its own Overmind socket/title so multiple instances can run at the same time.7071## Commit Messages7273- Prefer Conventional Commits: `type(scope): subject` (scope optional)74- Example: `feat(auth): add user authentication`75- Don't reference Claude in commit messages7677## PR Description Format7879- Start with a short, user-facing paragraph describing the product change.80- Add a `Closes` section with relevant issue links (GitHub, Linear, etc.).81- For feature PRs, add `How to test` from a product/UX standpoint.82- For bugfix PRs, use `How to reproduce` when helpful.83- Optionally add a `What changed` section for implementation highlights.84- Do not add a `How this was tested` section listing specs/commands.8586## Project-Specific8788- **Translations**:89 - For product and source-string changes, only update `en.yml` and `en.json`; other languages are handled through Crowdin and the community90 - Crowdin-generated translation sync PRs may update non-English locale files; do not flag those changes solely for modifying translated locale files91 - Preserve product and brand names, OAuth scopes, API values, and other machine-readable identifiers unless an official localized form exists92 - When reviewing Crowdin syncs, verify protected terms remain unchanged. Add newly introduced product names, brand names, and machine-readable identifiers to the Crowdin glossary as non-translatable, and keep the glossary current93 - Backend i18n → `en.yml`, Frontend i18n → `en.json`94- **Frontend**:95 - Use `components-next/` for message bubbles (the rest is being deprecated)9697## Ruby Best Practices9899- Use compact `module/class` definitions; avoid nested styles100101## Enterprise Edition Notes102103- Chatwoot has an Enterprise overlay under `enterprise/` that extends/overrides OSS code.104- When you add or modify core functionality, always check for corresponding files in `enterprise/` and keep behavior compatible.105- Follow the Enterprise development practices documented here:106 - https://chatwoot.help/hc/handbook/articles/developing-enterprise-edition-features-38107108Practical checklist for any change impacting core logic or public APIs109- Search for related files in both trees before editing (e.g., `rg -n "FooService|ControllerName|ModelName" app enterprise`).110- If adding new endpoints, services, or models, consider whether Enterprise needs:111 - An override (e.g., `enterprise/app/...`), or112 - An extension point (e.g., `prepend_mod_with`, hooks, configuration) to avoid hard forks.113- Avoid hardcoding instance- or plan-specific behavior in OSS; prefer configuration, feature flags, or extension points consumed by Enterprise.114- Keep request/response contracts stable across OSS and Enterprise; update both sets of routes/controllers when introducing new APIs.115- When renaming/moving shared code, mirror the change in `enterprise/` to prevent drift.116- Tests: Add Enterprise-specific specs under `spec/enterprise`, mirroring OSS spec layout where applicable.117- When modifying existing OSS features for Enterprise-only behavior, add an Enterprise module (via `prepend_mod_with`/`include_mod_with`) instead of editing OSS files directly—especially for policies, controllers, and services. For Enterprise-exclusive features, place code directly under `enterprise/`.118119## Branding / White-labeling note120121- For user-facing strings that currently contain "Chatwoot" but should adapt to branded/self-hosted installs, prefer applying `replaceInstallationName` from `shared/composables/useBranding` in the UI layer (for example tooltip and suggestion labels) instead of adding hardcoded brand-specific copy.122
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| mui/material-uiAGENTS.md · 99k | AGENTS.md | setupbuildtestlint-format+9 | 100/100 | 14 days ago | |
| elastic/elasticsearchx-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/AGENTS.md · 78k | AGENTS.md | buildtestlint-formatstyle+2 | 100/100 | 14 days ago | |
| TryGhost/Ghoste2e/AGENTS.md · 55k | AGENTS.md | setupteststylearch+2 | 100/100 | today | |
| n8n-io/n8npackages/@n8n/agents/AGENTS.md · 201k | AGENTS.md | buildteststylearch+3 | 100/100 | 14 days ago | |
| duckduckgo/content-scope-scriptsspecial-pages/AGENTS.md · 70 | AGENTS.md | buildteststylearch+3 | 100/100 | 14 days ago | |
| deepseek-ai/deepseek-harnessnative/landlock-run/AGENTS.md · 104k | AGENTS.md | setupteststylearch+3 | 100/100 | today | |
| code-yeongyu/oh-my-openagentpackages/web/AGENTS.md · 68k | AGENTS.md | setupbuildtestlint-format+6 | 100/100 | 13 days ago | |
| rails/railsAGENTS.md · 59k | AGENTS.md | teststylearchgit+4 | 100/100 | 14 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/chatwoot-chatwoot-agents)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.