diff --git a/.opencode/skills/backend.md b/.opencode/skills/backend.md new file mode 100644 index 0000000000..d67681735b --- /dev/null +++ b/.opencode/skills/backend.md @@ -0,0 +1,28 @@ +--- +name: penpot-backend +description: Guidelines and workflows for the Penpot Clojure JVM backend. +--- + +# Penpot Backend Skill + +This skill provides guidelines and workflows for the Penpot Clojure JVM backend. + +## Testing & Validation +- **Isolated tests:** `clojure -M:dev:test --focus backend-tests.my-ns-test` (for a specific test namespace) +- **Regression tests:** `clojure -M:dev:test` (ensure the suite passes without regressions) +- **Eval expresion:** `clojure -M:dev -e "(here-the-expresion)"` + +## Code Quality +- **Linting:** `pnpm run lint:clj` +- **Formatting:** + - Check: `pnpm run check-fmt` + - Fix: `pnpm run fmt` +- **Type Hinting:** Use explicit JVM type hints (e.g., `^String`, `^long`) in performance-critical paths to avoid reflection overhead. + +## Architecture & Conventions +- Uses Integrant for dependency injection (`src/app/main.clj`). +- PostgreSQL for storage, Redis for messaging/caching. +- **RPC:** Commands are under `app.rpc.commands.*`. Use the `get-` prefix on RPC names when we want READ operations. +- **Database:** `app.db` wraps next.jdbc. Queries use a SQL builder. + - Helpers: `db/get`, `db/query`, `db/insert!`, `db/update!`, `db/delete!` +- **Performance Macros:** Always prefer these macros from `app.common.data.macros` over `clojure.core` equivalents: `dm/select-keys`, `dm/get-in`, `dm/str`. diff --git a/.opencode/skills/common.md b/.opencode/skills/common.md new file mode 100644 index 0000000000..a61c996ce0 --- /dev/null +++ b/.opencode/skills/common.md @@ -0,0 +1,25 @@ +--- +name: penpot-common +description: Guidelines and workflows for the Penpot Common shared module. +--- + +# Penpot Common Skill + +This skill provides guidelines and workflows for the Penpot Common shared module (Clojure/ClojureScript/JS). + +## Testing & Validation +- **JS (Node) Isolated tests:** Edit `test/common_tests/runner.cljs` then run `pnpm run test:js` +- **JS (Node) Regression tests:** `pnpm run test:js` +- **JVM Isolated tests:** `pnpm run test:jvm --focus common-tests.my-ns-test` +- **JVM Regression tests:** `pnpm run test:jvm` + +## Code Quality +- **Linting:** `pnpm run lint:clj` +- **Formatting:** + - Check: `pnpm run check-fmt:clj`, `pnpm run check-fmt:js` + - Fix: `pnpm run fmt:clj`, `pnpm run fmt:js` + +## Architecture & Conventions +- Multiplatform code used by frontend, backend, and exporter. +- Uses Clojure reader conditionals (`#?(:clj ... :cljs ...)`). +- Modifying common code requires testing across consumers (frontend, backend, exporter). diff --git a/.opencode/skills/frontend.md b/.opencode/skills/frontend.md new file mode 100644 index 0000000000..8adc82396a --- /dev/null +++ b/.opencode/skills/frontend.md @@ -0,0 +1,28 @@ +--- +name: penpot-frontend +description: Guidelines and workflows for the Penpot ClojureScript React frontend. +--- + +# Penpot Frontend Skill + +This skill provides guidelines and workflows for the Penpot ClojureScript React frontend. + +## Testing & Validation +- **Isolated tests:** Edit `test/frontend_tests/runner.cljs` to narrow the test suite, then run `pnpm run test` +- **Regression tests:** `pnpm run test` (without modifications on the runner) +- **Integration tests:** `pnpm run test:e2e` or `pnpm run test:e2e --grep "pattern"` (do not modify e2e tests unless explicitly asked). + +## Code Quality +- **Linting:** + - `pnpm run lint:clj` + - `pnpm run lint:js` + - `pnpm run lint:scss` +- **Formatting:** + - Check: `pnpm run check-fmt:clj`, `pnpm run check-fmt:js`, `pnpm run check-fmt:scss` + - Fix: `pnpm run fmt:clj`, `pnpm run fmt:js`, `pnpm run fmt:scss` + +## Architecture & Conventions +- Uses React and RxJS (Potok for state management). +- Modern components use the `*` suffix (e.g., `my-component*`) and the `mf/defc` macro. +- Hooks: `mf/use-state`, `mf/use-effect`, `mf/use-memo`, `mf/use-fn`. Prefer macros `mf/with-effect` and `mf/with-memo`. +- Styles: Use CSS custom properties from `_sizes.scss` and tokens from `ds/colors.scss`. Avoid deep selector nesting. diff --git a/.opencode/skills/render-wasm.md b/.opencode/skills/render-wasm.md new file mode 100644 index 0000000000..3b6763d1a1 --- /dev/null +++ b/.opencode/skills/render-wasm.md @@ -0,0 +1,22 @@ +--- +name: penpot-render-wasm +description: Guidelines and workflows for the Penpot Rust to WebAssembly renderer. +--- + +# Penpot Render-WASM Skill + +This skill provides guidelines and workflows for the Penpot Rust to WebAssembly renderer. + +## Commands +- **Build:** `./build` (Compiles Rust → WASM. Requires Emscripten environment. Automatically sources `_build_env`) +- **Watch:** `./watch` (Incremental rebuild on file change) +- **Test (All):** `./test` (Runs cargo test) +- **Test (Single):** `cargo test my_test_name` or `cargo test shapes::` +- **Lint:** `./lint` (`clippy -D warnings`) +- **Format:** `cargo fmt --check` + +## Architecture & Conventions +- **Global state:** Accessed EXCLUSIVELY through `with_state!` / `with_state_mut!` macros. Never access `unsafe static mut State` directly. +- **Tile-based rendering:** Only 512×512 tiles within the viewport are drawn each frame. +- **Two-phase updates:** Shape data is written via exported setter functions, then a single `render_frame()` triggers the actual Skia draw calls. +- **Frontend Integration:** The WASM module is loaded by `app.render-wasm.*` namespaces. Do not change export function signatures without updating the corresponding ClojureScript bridge.