102 lines
4.4 KiB
Markdown
102 lines
4.4 KiB
Markdown
# Molecule AI Codebase Conventions
|
|
|
|
These rules apply to every agent working on the Molecule AI / Molecule AI codebase.
|
|
They are lessons learned from real bugs — not style preferences. Violating them
|
|
causes production failures.
|
|
|
|
## Canvas (Next.js 15 App Router)
|
|
|
|
### `'use client'` — NON-NEGOTIABLE
|
|
Every `.tsx` file in `canvas/src/` that uses React hooks (`useState`, `useEffect`,
|
|
`useCallback`, `useMemo`, `useRef`), Zustand stores (`useCanvasStore`, `useSecretsStore`),
|
|
or event handlers (`onClick`, `onChange`) MUST have `'use client';` as the very first
|
|
line. Without it, Next.js renders the component as server HTML and React never hydrates
|
|
it — buttons appear but silently don't respond to clicks.
|
|
|
|
**This has caused two reverted PRs.** Always run this check before reporting done:
|
|
```bash
|
|
cd canvas
|
|
for f in $(grep -rl "useState\|useEffect\|useCallback\|useMemo\|useRef\|useStore\|onClick\|onChange" src/ --include="*.tsx"); do
|
|
head -3 "$f" | grep -q "use client" || echo "MISSING 'use client': $f"
|
|
done
|
|
```
|
|
|
|
### Zustand Selectors — No New Objects
|
|
Never call a function that returns a new object inside a Zustand selector:
|
|
```typescript
|
|
// BAD — creates new object every render → infinite re-renders
|
|
const grouped = useSecretsStore((s) => s.getGrouped());
|
|
|
|
// GOOD — use useMemo with stable selector values
|
|
const secrets = useSecretsStore((s) => s.secrets);
|
|
const grouped = useMemo(() => groupSecrets(secrets), [secrets]);
|
|
```
|
|
|
|
### Dark Zinc Theme — No Light Colors
|
|
The canvas is dark-themed. Every new component must use:
|
|
- Backgrounds: `zinc-900`, `zinc-950`, `#18181b`, `#09090b`
|
|
- Text: `zinc-300`, `zinc-400`, `#d4d4d8`, `#a1a1aa`
|
|
- Accents: `blue-500`, `blue-600`, `violet-500`
|
|
- Borders: `zinc-700`, `zinc-800`
|
|
- Never: `white`, `#ffffff`, `#f5f5f5`, or any light gray
|
|
|
|
### API Response Shapes
|
|
Always verify the actual platform API response format before writing fetch code.
|
|
Check the Go handler or test with curl — don't assume. Past bug: FE assumed
|
|
`GET /settings/secrets` returned a flat array but it returns `{ secrets: [...] }`.
|
|
|
|
## Platform (Go)
|
|
|
|
### SQL Safety
|
|
- Always use parameterized queries (`$1`, `$2`), never string concatenation
|
|
- Use `ExecContext` / `QueryContext` with context, never bare `Exec` / `Query`
|
|
- Always check `rows.Err()` after iterating result sets
|
|
- JSONB: convert `[]byte` to `string()` and use `::jsonb` cast
|
|
|
|
### Access Control
|
|
- Every endpoint touching workspace data must verify ownership
|
|
- A2A proxy calls go through `CanCommunicate()` — new proxy paths must respect it
|
|
- System callers (`webhook:*`, `system:*`, `test:*`) bypass via `isSystemCaller()`
|
|
|
|
### Container Lifecycle
|
|
- Use `ContainerRemove(Force: true)` to stop containers — never `ContainerStop` +
|
|
`ContainerRemove` separately (restart policy race condition causes zombies)
|
|
- Always reap zombie processes: `proc.wait()` after `proc.kill()` with a timeout
|
|
|
|
## Workspace Runtime (Python)
|
|
|
|
### Error Sanitization
|
|
Never emit raw exception messages or subprocess stderr to the user. Use
|
|
`sanitize_agent_error()` which exposes the exception class name but strips
|
|
the message body (which can leak tokens, paths, and stack traces).
|
|
|
|
### System Prompt Hot-Reload
|
|
System prompts are re-read from `/configs/system-prompt.md` on every message.
|
|
Always use `encoding="utf-8", errors="replace"` when reading prompt files.
|
|
|
|
## Inter-Agent Communication
|
|
|
|
### Parallel Delegation
|
|
Use `delegate_task_async` to send tasks to multiple peers simultaneously.
|
|
Don't serialize what can be parallel — fire all async delegations, then poll
|
|
`check_task_status` to collect results as they finish.
|
|
|
|
### Side Questions
|
|
Any agent can ask a peer a direct question via `delegate_task` (sync) without
|
|
going through the lead. FE can ask BE "what's the API response format?" mid-task.
|
|
Use this to avoid guessing — it's faster than getting it wrong.
|
|
|
|
### Proactive Updates
|
|
Use `send_message_to_user` to push status updates to the CEO's chat at any time.
|
|
Don't wait until everything is done to report — acknowledge immediately, update
|
|
during long work, deliver results when complete.
|
|
|
|
## Before Reporting Done
|
|
|
|
Every agent, regardless of role, must verify their own work before claiming completion:
|
|
1. Read back every file you changed — confirm it looks right
|
|
2. Run the relevant test suite (`npm test`, `go test`, `python -m pytest`)
|
|
3. Run the relevant build (`npm run build`, `go build`)
|
|
4. Check for framework-specific gotchas (the `'use client'` grep above)
|
|
5. If you can imagine a way your change could break, test that scenario
|