Skip to content

Latest commit

 

History

History
37 lines (24 loc) · 1.97 KB

File metadata and controls

37 lines (24 loc) · 1.97 KB

Design Principles

Decisions that guide contributions. Read this before opening a PR.

Core

  • Offline-first. The app must work fully without network access or API keys. Network-dependent features are optional enhancements, never requirements.
  • No assumed inference. Tool identification, naming, and categorisation must not assume a specific ML model or remote service. These features should be behind pluggable interfaces with manual/simple fallbacks as the default.
  • Coordinate system discipline. SVG/layout Y is down; manifold3d Y is up. Always negate Y when crossing that boundary. See docs/gotchas.md.

Architecture

  • Keep PRs focused. One concern per PR. If you're touching unrelated files (sidebar width, dev scripts, polish), split them out.
  • Backward compatible schemas. New fields must have defaults. Existing data must load without migration.
  • Tests must actually run. Run pytest and check for failures before submitting, not just py_compile.

Frontend

  • State complexity budget. If a component has more than ~8 useState hooks, extract related state into a custom hook or sub-component.
  • No polling when SSE/websockets fit. For background tasks that update UI, prefer server-sent events over polling loops.

Backend

  • Atomic data operations. Anything that replaces user data must be atomic (swap, not clear-then-copy). Partial failure must not lose data.
  • Single source of truth for config. Use pydantic-settings. Don't read env vars directly alongside Settings.

Linting

Run make lint before submitting a PR. CI enforces the same checks on all PRs and pushes to main.

| Layer | Tool | Config | |-|-| | Python | ruff | pyproject.toml -- E/F/W/I rules, E402+E501 ignored | | TypeScript | ESLint + eslint-config-next | frontend/eslint.config.mjs | | Types | tsc --noEmit | frontend/tsconfig.json |

Targets: make lint-backend, make lint-frontend, make lint-fix (auto-fix where possible).