|
| 1 | +# Blink Development |
| 2 | + |
| 3 | +## 1 Repository Overview |
| 4 | + |
| 5 | +Blink is a Bun-powered monorepo managed via Bun workspaces (see `package.json → workspaces`). Each top-level package has a focused responsibility: |
| 6 | + |
| 7 | +| Package | Purpose | |
| 8 | +| -------------------- | ------------------------------------------------------------------------- | |
| 9 | +| `packages/site/` | Next.js App Router front-end (Tailwind, React server & client components) | |
| 10 | +| `packages/worker/` | Cloudflare Worker back-end (chat, webhooks, file uploads, etc.) | |
| 11 | +| `packages/database/` | Drizzle-based PostgreSQL access layer & migrations | |
| 12 | +| Other `packages/*` | Supporting SDKs, CLIs, event helpers, etc. | |
| 13 | + |
| 14 | +Top-level scripts (`/scripts/*.ts`) orchestrate local tasks (DB, data dumps, etc.). `main` is always deployable. |
| 15 | + |
| 16 | +## 2 Local Development |
| 17 | + |
| 18 | +@cmux: Always run `bun i` when beginning to install packages. Pull all submodules before you begin as well. They are needed for development. |
| 19 | + |
| 20 | +Test: `bun test` |
| 21 | +Format: `bun format` |
| 22 | +Typecheck: `bun typecheck` |
| 23 | + |
| 24 | +All three _must_ work before CI will pass. |
| 25 | + |
| 26 | +## 3 Coding Conventions |
| 27 | + |
| 28 | +• **Formatting & linting** – Prettier is the single source of style; run `bun format` before committing. No ESLint rules are enforced beyond TS‐strictness. |
| 29 | + |
| 30 | +• **Imports** – Use absolute path aliases: |
| 31 | + |
| 32 | +- Front-end: `@/lib/foo`, `@/components/Bar`. |
| 33 | +- DB: `@database/...` (provided by `packages/database/tsconfig.json`). |
| 34 | +- Worker: `@worker/...`. |
| 35 | + Relative `../..` chains are discouraged except inside tests. |
| 36 | + |
| 37 | +• **React / Next** |
| 38 | + |
| 39 | +- Functional components only. |
| 40 | +- Tailwind for styling; avoid extra CSS files. Rare global styles go in `packages/site/app/globals.css`. |
| 41 | +- Memoisation (`React.memo`, `useMemo`) only where **obviously** valuable. |
| 42 | + |
| 43 | +• **Comments** – Keep them Go-style (`//`) and minimal. Code should be self-explanatory. |
| 44 | + |
| 45 | +• **Logging** – `console.log` is sufficient for now; avoid external logging services unless discussed first. |
| 46 | + |
| 47 | +• **Testing** |
| 48 | + |
| 49 | +- No wait/sleep – favor determinism. |
| 50 | +- Flat structure – avoid deeply nested `describe` blocks. |
| 51 | +- No duplicative naming – if a file is named "Example", the tests do not need to start with "Example –". |
| 52 | +- Isolation – never call external network APIs in unit tests. Use local mocks (see `packages/*/*.mock.ts`). |
| 53 | +- Database – use the helpers in `packages/database/test.ts` for setup/teardown. Never hit a live DB. |
| 54 | + |
| 55 | +• **Database** |
| 56 | + |
| 57 | +- Never write queries outside of `querier.ts`. These are centralized for easy migrations. |
| 58 | +- NEVER write manual migrations. Always adjust `schema.ts` and use `cd packages/database/ && bun generate`. Format afterwards. |
| 59 | + |
| 60 | +• **API** |
| 61 | + |
| 62 | +- All API routes go in `packages/api/`. These are consumed and injected by the Worker, but are intentionally separated. |
| 63 | +- Do not make API routes in `packages/site/` - ever. |
| 64 | + |
| 65 | +## 4 Commit & PR Etiquette |
| 66 | + |
| 67 | +• Write clear, concise commit messages (prefixes like `feat:`, `fix:` are welcome but optional). Squash or merge—author’s choice. |
| 68 | + |
| 69 | +• CI (GitHub Actions) runs `bun format:check`, `bun typecheck`, and `bun test` on every PR; **all must pass** before merging. There are **no pre-commit hooks**, so run these commands locally or let CI catch issues. |
| 70 | + |
| 71 | +• Keep the default branch (`main`) green; avoid merging failing builds. |
| 72 | + |
| 73 | +• Mention any migrations or required env-vars in the PR description. |
| 74 | + |
| 75 | +## 5 AI-Generated Content Attribution |
| 76 | + |
| 77 | +When creating public operations (commits, PRs, issues), always include: |
| 78 | + |
| 79 | +- 🤖 emoji in the title |
| 80 | +- "_Generated with `cmux`_" in the body (if applicable) |
| 81 | + |
| 82 | +This ensures transparency about AI-generated contributions. |
| 83 | + |
| 84 | +--- |
| 85 | + |
| 86 | +## 6 PR Management |
| 87 | + |
| 88 | +After submitting or updating PRs, **always check merge status**: |
| 89 | + |
| 90 | +```bash |
| 91 | +gh pr view <number> --json mergeable,mergeStateStatus | jq '.' |
| 92 | +``` |
| 93 | + |
| 94 | +This is especially important with rapid development where branches quickly fall behind. |
| 95 | + |
| 96 | +**Wait for PR checks to complete:** |
| 97 | + |
| 98 | +```bash |
| 99 | +./scripts/wait_pr_checks.sh <pr_number> |
| 100 | +``` |
| 101 | + |
| 102 | +This script polls every 5 seconds and fails immediately on CI failure, bad merge status, or unresolved review comments. It will notify you when the PR is ready to merge. |
| 103 | + |
| 104 | +**Key status values:** |
| 105 | + |
| 106 | +- `mergeable: "MERGEABLE"` = No conflicts, can merge |
| 107 | +- `mergeable: "CONFLICTING"` = Has conflicts, needs resolution |
| 108 | +- `mergeStateStatus: "CLEAN"` = Ready to merge ✅ |
| 109 | +- `mergeStateStatus: "BLOCKED"` = Waiting for CI checks |
| 110 | +- `mergeStateStatus: "BEHIND"` = Branch is behind base, rebase needed |
| 111 | +- `mergeStateStatus: "DIRTY"` = Has conflicts |
| 112 | + |
| 113 | +**If branch is behind:** |
| 114 | + |
| 115 | +```bash |
| 116 | +git fetch origin |
| 117 | +git rebase origin/main |
| 118 | +git push --force-with-lease |
| 119 | +``` |
| 120 | + |
| 121 | +**ALWAYS AWAIT PRs UNTIL THEY PASS, OR YOU GET STUCK** |
| 122 | + |
| 123 | +### ⚠️ NEVER Auto-Merge PRs |
| 124 | + |
| 125 | +**DO NOT** enable auto-merge (`gh pr merge --auto`) or merge PRs (`gh pr merge`) without **explicit user instruction**. |
| 126 | + |
| 127 | +Reason: PRs may need human review, discussion, or additional changes based on review comments (e.g., Codex feedback). Always: |
| 128 | + |
| 129 | +1. Submit the PR |
| 130 | +2. Wait for checks to pass |
| 131 | +3. Report PR status to user |
| 132 | +4. **Wait for user to decide** whether to merge |
| 133 | + |
| 134 | +Only merge if the user explicitly says "merge it" or similar. |
| 135 | + |
| 136 | +### Writing PR Descriptions |
| 137 | + |
| 138 | +Write PR bodies for **busy reviewers**. Be concise and avoid redundancy: |
| 139 | + |
| 140 | +- **Each section should add new information** - Don't restate the same thing in different words |
| 141 | +- **Structure emerges from content** - Some fixes need problem/solution/testing, others just need "what changed and why" |
| 142 | +- **If it's obvious, omit it** - Problem obvious from solution? Don't state it. Solution obvious from problem? Skip to implementation details. |
| 143 | + |
| 144 | +❌ **Bad** (redundant): |
| 145 | + |
| 146 | +``` |
| 147 | +Problem: Markdown rendering is slow, causing 50ms tasks |
| 148 | +Solution: Make markdown rendering faster |
| 149 | +Impact: Reduces task time to <16ms |
| 150 | +``` |
| 151 | + |
| 152 | +✅ **Good** (each section adds value): |
| 153 | + |
| 154 | +``` |
| 155 | +ReactMarkdown was re-parsing content on every parent render because plugin arrays |
| 156 | +were created fresh each time. Moved to module scope for stable references. |
| 157 | +
|
| 158 | +Verify with React DevTools Profiler - MarkdownCore should only re-render when content changes. |
| 159 | +``` |
| 160 | + |
| 161 | +## 7 Design |
| 162 | + |
| 163 | +- **Avoid using too many font sizes** - this makes it visually difficult for the user. |
| 164 | +- **Avoid using bold** - Bold expresses a really strong signal to the user, only use bold when it's truly very important to. |
| 165 | +- **Density** - Blink is a platform for developers - developers use interfaces like VS Code and Cursor, which have visual density and highly idiomatic user-experience. |
| 166 | +- **Styling** - Aim to make things beautiful by making them simple. Think like Apple. |
0 commit comments