-
Notifications
You must be signed in to change notification settings - Fork 23
Day 2 / Andriy Zhmaylo Workshop Assignment #6
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| --- | ||
| description: "Add tests for a React component" | ||
| --- | ||
|
|
||
| Add or update tests for the React component named $ARGUMENTS: | ||
|
|
||
| 1. Locate the component and existing related tests in the same directory. | ||
| 2. Follow `.cursor/rules/` and `AGENTS.md` conventions before editing. | ||
| 3. Create or update a colocated `ComponentName.test.tsx` file. | ||
| 4. Add basic render coverage plus key behavior/state interaction tests. | ||
| 5. Reuse existing test utilities and patterns already used in this package. | ||
| 6. Run relevant tests (or provide exact command) and summarize results. | ||
| 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 | ||
|
Comment on lines
+7
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line 7-12: команда створює компонент і тест, але не вимагає виконати nearest test suite/конкретну команду верифікації. Для воркфлоу це критично, інакше результат може лишитись неперевіреним. Based on learnings: "Run the nearest relevant test file/suite after changes." 🤖 Prompt for AI Agents |
||
|
|
||
| Check .cursor/rules/ for architecture and convention constraints. | ||
|
Comment on lines
+5
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line 5-14: додай H1 після frontmatter і один trailing newline в кінці файлу. 🧰 Tools🪛 markdownlint-cli2 (0.22.0)[warning] 5-5: First line in a file should be a top-level heading (MD041, first-line-heading, first-line-h1) [warning] 14-14: Files should end with a single newline character (MD047, single-trailing-newline) 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| --- | ||
| description: "Refactoring for a component" | ||
| --- | ||
|
|
||
| Refactor a React component named $ARGUMENTS: | ||
|
|
||
| 1. Read a files | ||
| 2. Check .cursor/rules to match it | ||
| 3. Check for DRY and code smell | ||
| 4. Propose changes regarding what was finded | ||
| 5. Check that new code compiles | ||
| 6. Describe what changes been done | ||
|
Comment on lines
+5
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line 5-12: інструкції загальні, з граматичними помилками, і без чіткого expected result/прикладу запуску (що саме має бути на виході після рефакторингу). As per coding guidelines: " 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| --- | ||
| description: "Run a project security check" | ||
| --- | ||
|
|
||
| Perform a security check for this project: | ||
|
|
||
| 1. Inspect current changes and identify security-sensitive files. | ||
| 2. Scan for obvious secrets, unsafe patterns, and risky defaults. | ||
| 3. Review auth, input handling, and data exposure paths in touched code. | ||
| 4. Check dependencies and scripts for known risky usage. | ||
| 5. Report findings by severity with file paths and concrete fixes. | ||
| 6. If no issues are found, state that clearly and note residual risks. | ||
|
Comment on lines
+7
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line 7-12: зараз чекліст загальний. Додай явні перевірки для Excalidraw (SVG/XSS, імпорт Based on learnings: "Flag security-sensitive behavior changes in PR/summary notes." 🧰 Tools🪛 markdownlint-cli2 (0.22.0)[warning] 12-12: Files should end with a single newline character (MD047, single-trailing-newline) 🤖 Prompt for AI Agents |
||
|
|
||
| Check `.cursor/rules/` and `AGENTS.md` for project guardrails before suggesting changes. | ||
|
Comment on lines
+5
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line 5-14: додай top-level heading після frontmatter і один newline в кінці файлу. 🧰 Tools🪛 markdownlint-cli2 (0.22.0)[warning] 5-5: First line in a file should be a top-level heading (MD041, first-line-heading, first-line-h1) [warning] 12-12: Files should end with a single newline character (MD047, single-trailing-newline) 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,25 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❌ Відсутня обов'язкова секція "How to verify" Згідно з чеклістом завдання День 2, кожне правило має містити секцію "How to verify" — як перевірити, що правило працює. Це критична вимога для всіх файлів у Поточні конвенції (functional components, named exports, strict TypeScript) — це універсальні практики для будь-якого React-проєкту. Для Excalidraw краще додати специфічні правила, наприклад:
📝 Приклад доповнення з секцією верифікації ## Files
- kebab-case for files: `element-utils.ts`
- PascalCase for components: `LayerUI.tsx`
+
+## Excalidraw-Specific Patterns
+
+- Element utilities: prefer pure functions in `packages/element/`
+- Canvas operations: wrap in try-catch, handle context loss
+- Action creators: use `actionManager.dispatch()`, not direct state mutation
+
+## How to Verify
+
+1. Run `yarn test:code` — має пройти без помилок
+2. Перевір, що нові компоненти експортуються named exports
+3. Перевір `git diff` — нові файли мають kebab-case/PascalCase відповідно
+4. Запусти `yarn test:typecheck` — не має бути `any` або `@ts-ignore`Як per coding guidelines для 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| --- | ||
| description: "CSS styling conventions and guardrails" | ||
| globs: **/*.css,**/*.scss | ||
| alwaysApply: false | ||
| --- | ||
|
|
||
| # CSS Conventions | ||
|
|
||
| ## Maintainability | ||
|
|
||
| - Keep selectors shallow; avoid deeply nested or overly specific selectors. | ||
| - Prefer class selectors over tag selectors for component styling. | ||
| - Keep related declarations grouped and ordered consistently. | ||
|
|
||
| ## Tokens and Values | ||
|
|
||
| - Prefer CSS variables (design tokens) over hardcoded colors, spacing, and sizes. | ||
| - Avoid magic numbers unless they are clearly documented by context. | ||
| - Reuse existing utility classes and shared styles before adding new ones. | ||
|
|
||
| ## Safety and Scope | ||
|
|
||
| - Avoid `!important` unless there is no safe alternative. | ||
| - Do not introduce global resets or broad overrides without explicit need. | ||
| - Keep styles scoped to the feature/component to reduce side effects. | ||
|
Comment on lines
+3
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line 3-25: правило корисне як база, але не прив’язане до реалій Excalidraw (editor/canvas-патерни) і не містить "How to verify". Також As per coding guidelines: "Тіло правила конкретне та стосується Excalidraw", "Є секція 'How to verify'", "Якщо є 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| --- | ||
| alwaysApply: true | ||
| --- | ||
|
Comment on lines
+1
to
+3
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❌ Правило фактично порожнє і не проходить критерії Дня 2 Line 1-3: є лише As per coding guidelines: " 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| --- | ||
| 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.dispatch() ONLY | ||
| - State type: AppState (src/types.ts) | ||
|
Comment on lines
+12
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❌ Невірні API/шляхи: це зламає згенерований код Line 12-13: Based on learnings: "Canvas rendering pipeline is authoritative for drawing; do not replace drawing flow with React DOM-based drawing" і "Read relevant files and existing local patterns first before implementing code changes." 🤖 Prompt for AI Agents |
||
|
|
||
| ## 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 src/utils/ before adding external helpers | ||
|
Comment on lines
+18
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line 18-24: формулювання As per coding guidelines: "Тіло правила конкретне та стосується Excalidraw" і "Є секція 'How to verify'." 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| --- | ||
| description: "Security guardrails for code and reviews" | ||
| globs: packages/**/*.ts,packages/**/*.tsx,excalidraw-app/**/*.ts,excalidraw-app/**/*.tsx | ||
| alwaysApply: false | ||
| --- | ||
|
|
||
| # Security Rules | ||
|
|
||
| ## Secrets and Sensitive Data | ||
|
|
||
| - Never hardcode secrets, tokens, passwords, or private keys. | ||
| - Do not commit credentials or `.env` values into source files or tests. | ||
| - Redact sensitive values in logs, test fixtures, and examples. | ||
|
|
||
| ## Input and Output Safety | ||
|
|
||
| - Treat all external/user input as untrusted and validate/sanitize it. | ||
| - Avoid unsafe HTML injection patterns; do not bypass sanitization intentionally. | ||
| - Validate URLs and external resource identifiers before use. | ||
|
|
||
| ## Access and Permissions | ||
|
|
||
| - Follow least-privilege principles when adding new capabilities. | ||
| - Do not broaden data access or permissions without explicit justification. | ||
|
|
||
| ## Dependencies and Risky Changes | ||
|
|
||
| - No new dependencies without explicit approval. | ||
| - Flag security-sensitive behavior changes in PR/summary notes. | ||
| - Add tests for security-relevant logic (validation, sanitization, permissions). | ||
|
Comment on lines
+7
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line 7-30: зміст занадто загальний. Для цього репозиторію потрібні конкретні пункти про SVG/XSS, безпечний імпорт As per coding guidelines: " 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| --- | ||
| description: "Testing standards for unit and component tests" | ||
| globs: **/*.test.ts,**/*.test.tsx | ||
| alwaysApply: false | ||
| --- | ||
|
|
||
| # Testing Conventions | ||
|
|
||
| ## Coverage Expectations | ||
|
|
||
| - Add or update tests for any behavior change. | ||
| - Prefer focused tests near the changed code over broad snapshot-only tests. | ||
| - Cover happy path and at least one failure/edge path when applicable. | ||
|
|
||
| ## Test Quality | ||
|
|
||
| - Use clear test names that describe behavior, not implementation details. | ||
| - Assert observable outcomes (rendered output, callbacks, state effects). | ||
| - Keep tests deterministic; avoid real timers/network unless explicitly needed. | ||
| - Reuse existing test utilities from the package before adding new helpers. | ||
|
|
||
| ## Safety | ||
|
|
||
| - Do not use `it.only`/`describe.only` or leave skipped tests unintentionally. | ||
| - Avoid overly broad snapshots that hide regressions. | ||
| - Keep test data minimal and readable. | ||
|
|
||
| ## Agent Verification | ||
|
|
||
| - Run the nearest relevant test file/suite after changes. | ||
| - For shared/type-heavy changes, also run lint and typecheck. | ||
|
Comment on lines
+1
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Чеклист завдання вимагає секцію з назвою "How to verify". Хоча "Agent Verification" семантично близька, краще дотримуватись точної назви для консистентності з іншими правилами. Поточні конвенції (clear test names, deterministic tests, avoid snapshots) — універсальні для будь-якого проєкту. Для Excalidraw варто додати специфічні патерни тестування:
♻️ Приклад доповнення ## Safety
- Do not use `it.only`/`describe.only` or leave skipped tests unintentionally.
- Avoid overly broad snapshots that hide regressions.
- Keep test data minimal and readable.
+
+## Excalidraw-Specific Testing Patterns
+
+- **Canvas rendering**: Mock `getContext("2d")` or use test utilities from `packages/excalidraw/tests/`
+- **Action flows**: Test via `actionManager.dispatch()`, verify state changes in `appState`/`elements`
+- **Geometry/math**: Use property-based testing for coordinate transforms where applicable
+- **Collaboration**: Test socket message handling, conflict resolution, multi-user state sync
-## Agent Verification
+## How to Verify
- Run the nearest relevant test file/suite after changes.
- For shared/type-heavy changes, also run lint and typecheck.
+- Example: After editing `LayerUI.tsx`, run `yarn test LayerUI.test.tsx`
+- Verify no `it.only` left: `rg "it\.only|describe\.only" --glob "**/*.test.{ts,tsx}"`Як per coding guidelines для 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,115 @@ | ||||||||
| # AGENTS.md | ||||||||
|
|
||||||||
| This file provides project-specific guidance for coding agents working in this repository. | ||||||||
|
|
||||||||
| ## Quick Facts | ||||||||
|
|
||||||||
| - Monorepo name: `excalidraw-monorepo` | ||||||||
| - Package manager: `yarn@1.22.22` (use `yarn`, not `npm`) | ||||||||
| - Node: `>=18.0.0` | ||||||||
| - Main workspace areas: | ||||||||
| - `excalidraw-app/` - app shell and app-specific runtime | ||||||||
| - `packages/excalidraw/` - core editor package | ||||||||
| - `packages/common/`, `packages/element/`, `packages/math/`, `packages/utils/` - shared modules | ||||||||
| - `examples/` - integration examples | ||||||||
| - `scripts/` - build/release/tooling scripts | ||||||||
|
|
||||||||
|
Comment on lines
+1
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❌ Відсутня секція "Project Overview" Згідно з вимогами завдання, У "Quick Facts" згадується лише
📋 Приклад доповненняДодай на початку файлу (після заголовка): # AGENTS.md
This file provides project-specific guidance for coding agents working in this repository.
+
+## Project Overview
+
+Excalidraw is an open-source virtual whiteboard for sketching hand-drawn diagrams and collaborating in real-time. The editor provides an infinite canvas with primitive shapes (rectangles, ellipses, arrows, text, freehand), supports multi-user collaboration via WebRTC/WebSocket, and renders everything to HTML5 Canvas. The project is built as a monorepo containing the core editor package, app shell, and shared utility libraries.
## Quick Facts
- Monorepo name: `excalidraw-monorepo`
- Package manager: `yarn@1.22.22` (use `yarn`, not `npm`)
- Node: `>=18.0.0`
+
+## Tech Stack
+
+- **UI Framework**: React 18+ (functional components, hooks)
+- **Language**: TypeScript (strict mode)
+- **Build Tool**: Vite (dev server + production builds)
+- **Testing**: Vitest (unit/integration), React Testing Library
+- **Monorepo**: Yarn workspaces
+- **Rendering**: HTML5 Canvas API (native, no abstraction libraries)
+
- Main workspace areas:Як per coding guidelines для 🤖 Prompt for AI Agents |
||||||||
| ## Most Used Commands | ||||||||
|
|
||||||||
| Run from repo root unless noted otherwise. | ||||||||
|
|
||||||||
| ### Setup | ||||||||
|
|
||||||||
| - Install dependencies: `yarn install` | ||||||||
| - Fresh reinstall: `yarn clean-install` | ||||||||
|
|
||||||||
| ### Development | ||||||||
|
|
||||||||
| - Start app dev server: `yarn start` | ||||||||
| - Start production-like app server: `yarn start:production` | ||||||||
| - Build app: `yarn build` | ||||||||
| - Build all packages: `yarn build:packages` | ||||||||
| - Build only core package: `yarn build:excalidraw` | ||||||||
|
|
||||||||
| ### Testing and Quality | ||||||||
|
|
||||||||
| - Main test run: `yarn test` | ||||||||
| - Full CI-like checks: `yarn test:all` | ||||||||
| - Unit/integration tests: `yarn test:app` | ||||||||
| - Typecheck: `yarn test:typecheck` | ||||||||
| - Lint: `yarn test:code` | ||||||||
| - Format check: `yarn test:other` | ||||||||
| - Coverage: `yarn test:coverage` | ||||||||
| - Update snapshots: `yarn test:update` | ||||||||
| - Auto-fix lint and format: `yarn fix` | ||||||||
|
|
||||||||
| ### Cleanup and Maintenance | ||||||||
|
|
||||||||
| - Remove build artifacts: `yarn rm:build` | ||||||||
| - Remove `node_modules`: `yarn rm:node_modules` | ||||||||
|
|
||||||||
| ## Code Conventions | ||||||||
|
|
||||||||
| - TypeScript strict mode; avoid `any` and `@ts-ignore`. | ||||||||
| - Use functional React components and hooks. | ||||||||
| - Use named exports (no default exports). | ||||||||
| - Name props as `{ComponentName}Props` for components. | ||||||||
| - Keep tests colocated where practical (`ComponentName.test.tsx`). | ||||||||
| - Use `import type { ... }` for type-only imports. | ||||||||
|
|
||||||||
| ## Architecture Rules | ||||||||
|
|
||||||||
| - State management uses internal action flow: | ||||||||
| - Use `actionManager.dispatch()` for state updates. | ||||||||
| - Do not introduce Redux, Zustand, MobX, or similar global stores. | ||||||||
| - Rendering architecture: | ||||||||
| - Canvas rendering pipeline is authoritative for drawing. | ||||||||
| - Do not replace drawing flow with React DOM-based drawing. | ||||||||
| - Do not add canvas abstraction libraries (react-konva, fabric.js, pixi.js). | ||||||||
|
|
||||||||
| ## Guardrails (Must Follow) | ||||||||
|
|
||||||||
| - Do not add new npm/yarn dependencies without explicit approval. | ||||||||
| - Do not modify protected core files unless explicitly requested and validated: | ||||||||
| - `src/core/renderer.ts` | ||||||||
| - `src/data/restore.ts` | ||||||||
| - `src/actions/manager.ts` | ||||||||
| - `src/types.ts` | ||||||||
| - If protected files are changed, run complete tests and perform manual verification. | ||||||||
|
|
||||||||
| ## Agent Workflow Expectations | ||||||||
|
|
||||||||
| When implementing code changes: | ||||||||
|
|
||||||||
| 1. Read relevant files and existing local patterns first. | ||||||||
| 2. Follow `.cursor/rules/*.mdc` and this file before editing. | ||||||||
| 3. Keep changes focused and avoid unrelated refactors. | ||||||||
| 4. Reuse existing utilities before introducing new abstractions. | ||||||||
| 5. After edits, run targeted checks first, then broader checks if needed. | ||||||||
| 6. Report what changed, why, and any residual risks. | ||||||||
|
|
||||||||
| ## Testing Strategy for Agents | ||||||||
|
|
||||||||
| - For small isolated component changes: | ||||||||
| - Run targeted tests first (nearest suite/file). | ||||||||
| - Run lint/typecheck if types or shared interfaces changed. | ||||||||
| - For broader/editor-impacting changes: | ||||||||
| - Run `yarn test:all` when feasible. | ||||||||
| - Minimum expected verification for most PR-sized changes: | ||||||||
| - `yarn test:code` | ||||||||
| - `yarn test:typecheck` | ||||||||
| - Relevant `yarn test` coverage for touched areas | ||||||||
|
|
||||||||
| ## Pull Request and Review Notes | ||||||||
|
|
||||||||
| - Keep PRs scoped and descriptive. | ||||||||
| - Include rationale, not only a list of file changes. | ||||||||
| - Flag behavior changes, migration implications, and follow-up tasks. | ||||||||
| - Prefer adding or updating tests alongside behavior changes. | ||||||||
|
|
||||||||
| ## Security and Reliability Basics | ||||||||
|
|
||||||||
| - Never commit secrets, credentials, or private tokens. | ||||||||
| - Validate and sanitize untrusted inputs where relevant. | ||||||||
| - Avoid risky defaults that can leak data or broaden permissions. | ||||||||
| - Call out security-sensitive changes explicitly in summaries. | ||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Файл має закінчуватися одним порожнім рядком (newline character). Це стандарт POSIX та вимога більшості linters. 🔧 ВиправленняДодай порожній рядок в кінці файлу після останнього речення: - Call out security-sensitive changes explicitly in summaries.
+Based on learnings from static analysis tools: markdownlint-cli2 flags MD047 (single-trailing-newline). 📝 Committable suggestion
Suggested change
🧰 Tools🪛 markdownlint-cli2 (0.22.0)[warning] 115-115: Files should end with a single newline character (MD047, single-trailing-newline) 🤖 Prompt for AI Agents |
||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| import clsx from "clsx"; | ||
|
|
||
| import { CLASSES } from "@excalidraw/common"; | ||
|
|
||
| import type { | ||
| NonDeletedElementsMap, | ||
| NonDeletedSceneElementsMap, | ||
| } from "@excalidraw/element/types"; | ||
|
|
||
| import { CompactShapeActions, SelectedShapeActions } from "./Actions"; | ||
| import { Island } from "./Island"; | ||
| import { useStylesPanelMode } from "./App"; | ||
|
|
||
| import type { ActionManager } from "../actions/manager"; | ||
| import type { AppClassProperties, AppState, UIAppState } from "../types"; | ||
|
|
||
| type ElementPropertiesPanelProps = { | ||
| appState: UIAppState; | ||
| elementsMap: NonDeletedElementsMap | NonDeletedSceneElementsMap; | ||
| renderAction: ActionManager["renderAction"]; | ||
| app: AppClassProperties; | ||
| setAppState: React.Component<any, AppState>["setState"]; | ||
| maxHeight: number; | ||
| }; | ||
|
|
||
| export const ElementPropertiesPanel = ({ | ||
| appState, | ||
| elementsMap, | ||
| renderAction, | ||
| app, | ||
| setAppState, | ||
| maxHeight, | ||
| }: ElementPropertiesPanelProps) => { | ||
| const isCompactStylesPanel = useStylesPanelMode() === "compact"; | ||
|
|
||
| if (isCompactStylesPanel) { | ||
| return ( | ||
| <Island | ||
| className={clsx("compact-shape-actions-island")} | ||
| padding={0} | ||
| style={{ maxHeight: `${maxHeight}px` }} | ||
| > | ||
| <CompactShapeActions | ||
| appState={appState} | ||
| elementsMap={elementsMap} | ||
| renderAction={renderAction} | ||
| app={app} | ||
| setAppState={setAppState} | ||
| /> | ||
| </Island> | ||
| ); | ||
| } | ||
|
|
||
| return ( | ||
| <Island | ||
| className={CLASSES.SHAPE_ACTIONS_MENU} | ||
| padding={2} | ||
| style={{ maxHeight: `${maxHeight}px` }} | ||
| > | ||
| <SelectedShapeActions | ||
| appState={appState} | ||
| elementsMap={elementsMap} | ||
| renderAction={renderAction} | ||
| app={app} | ||
| /> | ||
| </Island> | ||
| ); | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line 5: markdownlint MD041 валідно сигналізує, що після frontmatter має бути H1-заголовок.
As per coding guidelines: "
.cursor/commands/*.md... Файл містить чіткий опис, що команда робить" (для цього краще почати з явного H1).🧰 Tools
🪛 markdownlint-cli2 (0.22.0)
[warning] 5-5: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
🤖 Prompt for AI Agents