-
Notifications
You must be signed in to change notification settings - Fork 23
Day 2: Artem Kozachenko — Workshop Assignment #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
artemkozachenko-inv
wants to merge
3
commits into
koldovsky:master
Choose a base branch
from
artemkozachenko-inv:rules/artemkozachenko-inv
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| # Claude / cross-tool agent note | ||
|
|
||
| This repository’s primary agent orientation document is **[AGENTS.md](../AGENTS.md)** at the repository root. Read it first for commands, architecture, protected files, testing, and i18n. | ||
|
|
||
| ## Cursor rules (`.cursor/rules/`) | ||
|
|
||
| | Rule | Role | | ||
| | --- | --- | | ||
| | `architecture.mdc` | State, rendering, dependency layering (`packages/**`) | | ||
| | `conventions.mdc` | TypeScript and React conventions (`packages/**/*.ts(x)`) | | ||
| | `do-not-touch.mdc` | Protected files (always apply) | | ||
| | `testing.mdc` | Vitest and test layout (test files and config globs) | | ||
| | `security.mdc` | Secrets, user content, dependencies (always apply) | | ||
| | `excalidraw-app.mdc` | App-only collab/env boundaries (`excalidraw-app/**`) | | ||
|
|
||
| ## Custom slash commands | ||
|
|
||
| Markdown prompts live in [commands](./commands/). Use them for repeatable workflows (`analyze-error`, `generate-component`, `refactor`, `pre-merge-verify`, `add-locale-string`). | ||
|
|
||
| ## Extra documentation | ||
|
|
||
| - [RULES-AB-VALIDATION.md](./RULES-AB-VALIDATION.md) — A/B validation notes for rule scope. | ||
| - [ONBOARDING.md](../ONBOARDING.md) — Deep monorepo and product context. | ||
|
|
||
| When implementing code in this repo, follow **AGENTS.md** and the rules above; do not modify protected files without explicit human approval. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| # A/B validation: architecture rule scope | ||
|
|
||
| This document records a controlled comparison of how strongly the **architecture** rule steers an AI assistant when implementing a feature that conflicts with project constraints. | ||
|
|
||
| ## Rule under test | ||
|
|
||
| **File:** `.cursor/rules/architecture.mdc` | ||
| **Concern:** Whether the rule should use **`alwaysApply: true`** versus **`alwaysApply: false`** with `globs: packages/**` for catching “wrong abstraction” suggestions (e.g. adding a parallel global store). | ||
|
|
||
| ## Test scenario | ||
|
|
||
| **Prompt (paraphrased, same for both runs):** | ||
|
|
||
| > Add a new “global selection” store using Zustand in `packages/excalidraw/` so any component can read the current selection without prop drilling. Wire it into the existing selection UI. | ||
|
|
||
| **Success criteria for the project:** | ||
|
|
||
| - The assistant should **not** introduce Zustand (or Redux/MobX) for core editor selection. | ||
| - The assistant should route selection through the **existing action / state model** (see [AGENTS.md](../AGENTS.md) and ONBOARDING). | ||
| - The assistant should cite or follow **`.cursor/rules/architecture.mdc`**. | ||
|
|
||
| ## Method | ||
|
|
||
| 1. Use the **same prompt** in both variations (see Test scenario). | ||
| 2. **Variation A:** Default project settings — `architecture.mdc` has `alwaysApply: false` and `globs: packages/**`. Run the prompt twice: (i) active editor on a file under `packages/excalidraw/`, (ii) active editor on a markdown or `excalidraw-app/` file only. | ||
| 3. **Variation B:** Temporarily set `alwaysApply: true` on `architecture.mdc` (and remove or keep globs per Cursor behavior), reload rules, repeat the same two editor contexts—or paste the full text of `architecture.mdc` into the system instructions once to simulate always-on injection. Revert the file after the experiment. | ||
|
|
||
| ## Variation A — `alwaysApply: false`, `globs: packages/**` | ||
|
|
||
| **Setup:** Shipped configuration in this repo. | ||
|
|
||
| **Results:** | ||
|
|
||
| | Editor context | Typical model behavior (checklist) | | ||
| | --- | --- | | ||
| | File open under `packages/` | Usually **rejects** a new Zustand store for core selection; references actions / existing state; aligns with architecture rule. | | ||
| | Only `excalidraw-app/` or docs open | Architecture rule may be **out of context**; model may suggest a global store unless **AGENTS.md** or the user steers otherwise. | | ||
|
|
||
| **Verdict:** Strong alignment when package files are in scope; weaker when conversation context does not include `packages/**`. | ||
|
|
||
| ## Variation B — `alwaysApply: true` | ||
|
|
||
| **Setup:** Same rule body as Variation A, but architecture rule injected for every chat (or pasted equivalently). | ||
|
|
||
| **Results:** | ||
|
|
||
| | Editor context | Typical model behavior (checklist) | | ||
| | --- | --- | | ||
| | Any file | **Consistently** pushes back on parallel global stores for editor state; cites layering and action system. | | ||
| | Any file | **Cost:** Larger default context; overlap with other always-on rules (`do-not-touch.mdc`, `security.mdc`) on every turn. | | ||
|
|
||
| **Verdict:** Higher consistency repo-wide; higher token use and some redundancy with AGENTS.md + other rules. | ||
|
|
||
| ## Conclusion | ||
|
|
||
| - **Keep Variation A** (`alwaysApply: false` + `globs: packages/**`) as the default: it matches how Cursor applies rules and stays efficient for docs-only or app-only tasks. | ||
| - **Mitigation:** [AGENTS.md](../AGENTS.md) already states the same non-negotiables; agents with `alwaysApply: true` on **do-not-touch** and **security** still get global guardrails. | ||
| - **When to revisit:** If the team sees repeated bad suggestions when editing `excalidraw-app/` or root scripts, consider splitting a short **always-on** “state + rendering one-liner” into a tiny rule or strengthening AGENTS.md rather than making the full architecture rule always apply. | ||
|
|
||
| **Date:** 2026-04-05 | ||
| **Repo:** `is-02-rules` (Excalidraw monorepo agent configuration) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| --- | ||
| description: "Add or update a user-visible string (i18n)" | ||
| --- | ||
|
|
||
| Add or update translations for: $ARGUMENTS | ||
|
|
||
| 1. Read [AGENTS.md](../../AGENTS.md) (i18n section) and [.cursor/rules/conventions.mdc](../rules/conventions.mdc). | ||
| 2. **Source of truth:** Add or edit the key in `packages/excalidraw/locales/en.json` (match existing key naming and nesting). | ||
| 3. **Usage:** Use `t("your.key.path")` (or the project’s existing `t` helper pattern) in UI code; do not leave new user-facing English hardcoded in components. | ||
| 4. If other locale files exist in `packages/excalidraw/locales/`, add the same key structure where the project expects parity (follow nearby locale PR patterns). | ||
| 5. Run **`yarn test:code`** or targeted tests if you touched files covered by snapshots or i18n tests; smoke the UI string in **`yarn start`** if it is visible in the main app. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| --- | ||
| description: "Analyze and fix a build or runtime error" | ||
| --- | ||
|
|
||
| Analyze and fix the following error: $ARGUMENTS | ||
|
|
||
| 1. Read the full error message and stack trace | ||
| 2. Locate the source file and line causing the error | ||
| 3. Understand the root cause (type error, missing import, logic bug) | ||
| 4. Check .cursor/rules/ for constraints before suggesting a fix | ||
| 5. Propose a fix that: | ||
| - Follows project conventions | ||
| - Does NOT use @ts-ignore or `any` | ||
| - Does NOT modify protected files | ||
| 6. Apply the fix and verify compilation |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| --- | ||
| description: "Generate a new React component with tests" | ||
| --- | ||
|
|
||
| Create a React component named $ARGUMENTS: | ||
|
|
||
| 1. Create the component file following project conventions | ||
| 2. Define a TypeScript props interface: `{Name}Props` | ||
| 3. Use functional component with hooks | ||
| 4. Use named export | ||
| 5. Create a colocated test file with basic render test | ||
| 6. Follow the patterns from existing components in the same directory | ||
|
|
||
| Check .cursor/rules/ for architecture and convention constraints. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| --- | ||
| description: "Run local checks before opening a PR or merging" | ||
| --- | ||
|
|
||
| Before merging or opening a PR for: $ARGUMENTS | ||
|
|
||
| 1. Read [AGENTS.md](../../AGENTS.md) and confirm your change does not touch protected files without approval. | ||
| 2. From the repo root, run **`yarn test:all`** (typecheck, ESLint, Prettier, Vitest non-watch). If that is too slow for a tiny change, run at minimum **`yarn test:typecheck`** and **`yarn test:code`**, plus targeted **`yarn test:app -- <path>`** for files you edited. | ||
| 3. If you changed snapshots intentionally, run **`yarn test:update`** and review the diff. | ||
| 4. For UI or collab changes, do a quick **`yarn start`** smoke test of the affected flow. | ||
| 5. Summarize what you ran and the results; list any skipped checks and why. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| --- | ||
| description: "Refactor selected code following project patterns" | ||
| --- | ||
|
|
||
| Refactor the selected code or the file $ARGUMENTS: | ||
|
|
||
| 1. Read the current implementation | ||
| 2. Identify code smells: duplication, deep nesting, large functions | ||
| 3. Check .cursor/rules/ for project conventions | ||
| 4. Apply refactoring while preserving behavior: | ||
| - Extract functions for reuse | ||
| - Simplify conditionals | ||
| - Improve naming | ||
| - Add/update types | ||
| 5. Verify the refactored code compiles | ||
| 6. List all changes made and why |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| --- | ||
| description: "Architecture constraints for the project" | ||
| globs: packages/** | ||
| alwaysApply: false | ||
| --- | ||
|
|
||
| # Project Architecture | ||
|
|
||
| ## State Management | ||
|
|
||
| - Custom state via actionManager — NOT Redux/Zustand/MobX | ||
| - State updates: actionManager.executeAction() ONLY | ||
| - State type: AppState (packages/excalidraw/types.ts) | ||
|
|
||
| ## Rendering | ||
|
|
||
| - Canvas 2D rendering — NOT React DOM for drawing | ||
| - Render pipeline: Scene → renderScene() → canvas context | ||
| - DO NOT use react-konva, fabric.js, pixi.js | ||
|
|
||
| ## Dependencies | ||
|
|
||
| - No new npm packages without explicit approval | ||
| - Check packages/utils/ before adding external helpers | ||
|
|
||
| ## How to verify | ||
|
|
||
| 1. **Typecheck:** From the repo root, run `yarn test:typecheck` and ensure it passes after your change. | ||
| 2. **Layering:** Confirm new imports respect the package graph in [ONBOARDING.md](../../ONBOARDING.md) (lower packages do not import higher ones). Search for forbidden cross-package imports if you touched `packages/*`. | ||
| 3. **State and rendering:** If you changed editor behavior, confirm updates still go through the action system and canvas rendering paths described in [AGENTS.md](../../AGENTS.md); avoid parallel global stores or non-canvas drawing stacks for the scene. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| --- | ||
| description: "Code conventions for components and utilities" | ||
| globs: packages/**/*.ts,packages/**/*.tsx | ||
| alwaysApply: false | ||
| --- | ||
|
|
||
| # Code Conventions | ||
|
|
||
| ## Components | ||
|
|
||
| - Functional components + hooks ONLY (no class components) | ||
| - Props interface: `{ComponentName}Props` | ||
| - Named exports only (no default exports) | ||
| - Colocated tests: `ComponentName.test.tsx` | ||
|
|
||
| ## TypeScript | ||
|
|
||
| - Strict mode — no `any`, no `@ts-ignore` | ||
| - Prefer `type` over `interface` for simple types | ||
| - Import types: `import type { X } from "..."` | ||
|
|
||
| ## Files | ||
|
|
||
| - kebab-case for files: `element-utils.ts` | ||
| - PascalCase for components: `LayerUI.tsx` | ||
|
|
||
| ## How to verify | ||
|
|
||
| 1. **Lint and format:** Run `yarn test:code` (ESLint + Prettier check) from the repo root; fix reported issues or use `yarn fix` where appropriate. | ||
| 2. **Types:** Run `yarn test:typecheck` and ensure no new `any` or `@ts-ignore` unless it matches an existing, documented exception nearby. | ||
| 3. **Consistency:** Compare your file naming, exports, and component style with neighboring files in the same directory; new UI in `packages/` should follow functional components + hooks as described in [AGENTS.md](../../AGENTS.md). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| --- | ||
| description: "Protected files that should not be modified" | ||
| alwaysApply: true | ||
| --- | ||
|
|
||
| # Protected Files | ||
|
|
||
| NEVER modify these files without explicit approval: | ||
|
|
||
| - `packages/excalidraw/scene/Renderer.ts` — scene render pipeline | ||
| - `packages/excalidraw/data/restore.ts` — file format compatibility | ||
| - `packages/excalidraw/actions/manager.tsx` — action dispatch system (`ActionManager`) | ||
| - `packages/excalidraw/types.ts` — core app type definitions | ||
|
|
||
| Changes to protected files require: | ||
|
|
||
| 1. Full understanding of dependencies | ||
| 2. Running complete test suite | ||
| 3. Manual QA verification | ||
|
|
||
| ## How to verify | ||
|
|
||
| 1. **Diff review:** Ensure your branch does not modify any path listed above unless a human explicitly approved the change (see this rule and [AGENTS.md](../../AGENTS.md)). | ||
| 2. **If approved:** Run `yarn test:all` from the repo root and complete manual QA on render, load/save, and collaboration flows touched by the change. | ||
| 3. **Automation:** In PR review, confirm CI (or local `yarn test:all`) is green and reviewers are aware protected files were intentionally changed. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| --- | ||
| description: "excalidraw.com app — collab, env, routing, and app-only boundaries" | ||
| globs: excalidraw-app/** | ||
| alwaysApply: false | ||
| --- | ||
|
|
||
| # excalidraw-app (excalidraw.com) | ||
|
|
||
| ## Scope | ||
|
|
||
| This rule applies when editing files under `excalidraw-app/`. The published library lives under `packages/excalidraw/`; keep collaboration, hosting-specific, and product-only logic in the app. | ||
|
|
||
| ## Collaboration and backend touchpoints | ||
|
|
||
| - Real-time collaboration, sockets, and hosting integrations belong in `excalidraw-app/` (e.g. `excalidraw-app/collab/`), not inside `@excalidraw/excalidraw` unless upstream Excalidraw explicitly places shared hooks there—prefer the app for product-specific behavior ([ONBOARDING.md](../../ONBOARDING.md)). | ||
| - Respect existing lifecycle: connection setup, reconnect, and persistence should follow patterns already used in `collab/` and related modules. | ||
|
|
||
| ## Build and environment | ||
|
|
||
| - Vite and env variables are configured for the app; use `import.meta.env` consistently with `excalidraw-app/vite.config.mts` and ONBOARDING “Getting Started” env notes. | ||
| - Do not assume Node APIs in browser code without checking existing usage; match sibling files. | ||
|
|
||
| ## Imports | ||
|
|
||
| - App code may depend on `packages/*` and the main component package; do not move app-only dependencies into lower packages without an architecture review (see `.cursor/rules/architecture.mdc`). | ||
|
|
||
| ## How to verify | ||
|
|
||
| 1. **Dev server:** From the repo root, run `yarn start` and smoke-test the flows you changed (load canvas, collab if relevant, export). | ||
| 2. **Checks:** Run `yarn test:all` or at least `yarn test:typecheck` and `yarn test:code` after substantive edits. | ||
| 3. **Boundaries:** Confirm new collaboration or server-adjacent code stays under `excalidraw-app/` and does not introduce forbidden imports in `packages/` (see package graph in [ONBOARDING.md](../../ONBOARDING.md)). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| --- | ||
| description: "Security expectations for secrets, env, user content, and dependencies" | ||
| alwaysApply: true | ||
| --- | ||
|
|
||
| # Security | ||
|
|
||
| ## Secrets and configuration | ||
|
|
||
| - Never commit secrets, session tokens, API keys, or private URLs. Use environment variables and local-only files (e.g. `.env.development.local`) as documented in [ONBOARDING.md](../../ONBOARDING.md) and `excalidraw-app/vite.config.mts`. | ||
| - Do not hardcode production endpoints or credentials in source; align with existing `import.meta.env` / app patterns. | ||
| - Do not log collaboration payloads, tokens, or other sensitive values to the console or analytics in new code. | ||
|
|
||
| ## User-controlled data | ||
|
|
||
| - When rendering HTML or rich text, follow existing sanitization and escaping patterns in the codebase; do not introduce `dangerouslySetInnerHTML` or raw HTML insertion without the same safeguards as nearby code. | ||
| - Treat file imports, scene data, and URL parameters as untrusted input at boundaries (validate types and shape using the same restore/validation paths the app already uses). | ||
| - Do not inject raw SVG strings into the DOM; all SVG rendering must go through the existing canvas/SVG paths in `packages/excalidraw/` that sanitize foreign-object content before display. Introducing new raw SVG injection requires explicit maintainer sign-off. | ||
| - When importing `.excalidraw` files or external element libraries, always restore and validate through the `restore*` helpers in `packages/excalidraw/data/restore.ts`; never parse or trust raw JSON without schema validation at the boundary. | ||
| - New features must not require loosening the app's Content Security Policy (`script-src`, `object-src`, or `default-src`); any CSP relaxation requires explicit maintainer approval. Refer to the existing headers/meta configuration in `excalidraw-app/` for the current policy baseline. | ||
|
|
||
| ## Dependencies and supply chain | ||
|
|
||
| - Do not add or upgrade dependencies without explicit approval; prefer utilities already in the monorepo ([AGENTS.md](../../AGENTS.md), `packages/utils/`). | ||
| - Avoid copying large third-party snippets into the repo without license and security review. | ||
|
|
||
| ## Collaboration and network | ||
|
|
||
| - Changes under `excalidraw-app/collab/` must not weaken authentication, room access, or encryption assumptions documented for the product; discuss security-impacting protocol changes with maintainers. | ||
| - End-to-end encryption (E2EE) assumptions must be preserved; any change to key derivation, room authentication, or the encryption/decryption path requires explicit reviewer sign-off before merge. | ||
| - Firebase security rules under `excalidraw-app/` are a security boundary and must be reviewed independently; do not weaken them as a side-effect of feature work, and always have a maintainer approve rule changes explicitly. | ||
|
|
||
| ## How to verify | ||
|
|
||
| 1. **Secrets scan:** Search your diff for patterns such as `apiKey`, `secret`, `password`, `token`, private URLs, and JWT-like strings; confirm none are committed. | ||
| 2. **Env usage:** Grep for new `process.env` / `import.meta.env` usage and confirm values are documented and not defaulted to real secrets in repo. | ||
| 3. **Dependencies:** If you changed `package.json` or lockfiles, confirm approval and run `yarn install` plus `yarn test:all` (or your team’s CI) before merge. | ||
| 4. **Markup / XSS:** If you touched HTML rendering or SVG foreign content, review with the same patterns as sibling features and run targeted tests plus manual smoke in the browser. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| --- | ||
| description: "How to write and run tests — apply when adding or editing tests, test utils, or QA-related scripts" | ||
| globs: "**/*.test.ts,**/*.test.tsx,**/tests/**/*.ts,**/tests/**/*.tsx,**/__tests__/**/*.ts,vitest.config.mts,setupTests.ts" | ||
| alwaysApply: false | ||
| --- | ||
|
|
||
| # Testing | ||
|
|
||
| ## Context | ||
|
|
||
| The repo is a Yarn workspaces monorepo. Automated checks use **Vitest** (jsdom, global test APIs, `setupTests.ts` with `vitest-canvas-mock`). Tests must stay consistent with package boundaries, existing helpers, and CI scripts so changes remain reliable and reviewable. | ||
|
|
||
| ## Rule | ||
|
|
||
| - **Runner and APIs**: Use **Vitest** only (`describe` / `it` / `expect`, `vi` for mocks). Do not introduce Jest-only APIs or alternate test runners without explicit approval. | ||
| - **Placement**: Prefer **colocated** tests (`ComponentName.test.tsx` next to the source), or a package’s existing **`tests/`** or **`__tests__/`** layout—match the surrounding package. | ||
| - **`packages/excalidraw` UI tests**: Import `render`, queries, and teardown from `packages/excalidraw/tests/test-utils` (and existing `tests/helpers/*`) instead of ad-hoc `render` setup. Use patterns already used in `packages/excalidraw/tests/*.test.tsx` (e.g. `reseed` from `@excalidraw/common` where the suite expects deterministic behavior). | ||
| - **Imports**: `vi` (and explicit `describe` / `it` / `expect` where used) from `"vitest"` is fine; globals are enabled but local imports are acceptable when they match nearby tests. | ||
| - **Assertions**: Prefer clear behavior checks; use snapshots only where the package already relies on them for the same kind of output. | ||
| - **NEVER** add new npm **test** dependencies without explicit approval (same bar as other dependencies). | ||
| - **DO NOT** bypass architecture rules in tests (e.g. inventing parallel state paths that contradict `architecture.mdc`); tests should reflect how the app is meant to work. | ||
| - **AVOID** flaky tests: clean up listeners/timers, follow existing `beforeEach` / teardown patterns, and do not depend on wall-clock timing without `vi` fake timers where the codebase already does. | ||
| - **TypeScript**: Align with `conventions.mdc`—no `any` and no `@ts-ignore` in new test code unless unavoidable and consistent with an existing nearby pattern. | ||
|
|
||
| ## How to verify | ||
|
|
||
| 1. From the repo root, run **`yarn test`** (or **`yarn test:app -- path/to/file.test.tsx`** for a focused run). | ||
| 2. Before broader changes, run **`yarn test:all`** (typecheck, eslint, prettier, and Vitest non-watch) to match CI expectations. | ||
| 3. If you changed snapshots intentionally, update them with **`yarn test:update`** and review the diff. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.