From 686ca5326fab21de9c096fd0e7a37fcf99118c29 Mon Sep 17 00:00:00 2001 From: Danila Poyarkov Date: Thu, 14 May 2026 22:05:43 +0300 Subject: [PATCH] chore: enforce Vue style and state boundaries --- AGENTS.md | 2 +- scripts/steiger-rules.ts | 23 +++++++++++++++++++++ src/app.css | 26 ++++++++++++++++++++++++ src/components/CodePanel.vue | 26 +----------------------- steiger.config.ts | 2 ++ tests/e2e/color-picker/demo-card.spec.ts | 3 +-- tests/e2e/stroke-picker/basic.spec.ts | 3 +-- 7 files changed, 55 insertions(+), 30 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index e4aeb68d0..3191c72fc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -238,7 +238,7 @@ Release commits are the exception: keep using `Release v0.x.y`. ## Code conventions - Do not place code or tests ad hoc. Before adding or moving files, inspect the existing folder structure and nearby patterns, then put changes in the established domain-specific location. If no proper location exists, create one deliberately and update docs/conventions as needed. -- Architecture boundaries are enforced by Steiger (`bun run check:arch`). App code must use public workspace package exports, workspace packages must not import app `src/` code, package-local aliases (`#core`, `#vue`, `#cli`, `#mcp`) are only for their owning package, core must stay framework-agnostic, app service/domain code (`src/app/**`) must not import app component/view layers, components must not import views, shared UI (`src/components/ui/**`) must not import app services/stores, property-panel internals must stay inside the property panel, canvas/editor overlay code must not import property-panel internals, committed code must not import scratch/generated/vendor internals, and durable docs belong under `packages/docs/**` unless the root Markdown allowlist is deliberately updated. +- Architecture boundaries are enforced by Steiger (`bun run check:arch`). App code must use public workspace package exports, workspace packages must not import app `src/` code, package-local aliases (`#core`, `#vue`, `#cli`, `#mcp`) are only for their owning package, core must stay framework-agnostic, app service/domain code (`src/app/**`) must not import app component/view layers, components must not import views, shared UI (`src/components/ui/**`) must not import app services/stores, property-panel internals must stay inside the property panel, canvas/editor overlay code must not import property-panel internals, Vue components must not use ` diff --git a/steiger.config.ts b/steiger.config.ts index 1e137d73b..f149a3611 100644 --- a/steiger.config.ts +++ b/steiger.config.ts @@ -22,6 +22,8 @@ export default defineConfig([ { rules: { 'open-pencil/prefer-domain-folders-over-filename-prefixes': 'error', + 'open-pencil/no-vue-style-blocks': 'error', + 'open-pencil/no-direct-selection-tool-state-mutation': 'error', 'open-pencil/strict-test-file-placement': 'error', 'open-pencil/no-engine-only-assertions-in-e2e': 'error', 'open-pencil/no-e2e-imports-in-engine-tests': 'error', diff --git a/tests/e2e/color-picker/demo-card.spec.ts b/tests/e2e/color-picker/demo-card.spec.ts index 30aa1670f..96c01de74 100644 --- a/tests/e2e/color-picker/demo-card.spec.ts +++ b/tests/e2e/color-picker/demo-card.spec.ts @@ -39,8 +39,7 @@ async function selectDemoCard(page: Parameters[0]['page'], canvas: .map((n) => `${n.name}:${n.type}`) .join(', ')}` ) - store.state.selectedIds = new Set([card.id]) - store.requestRender() + store.select([card.id]) }) await canvas.waitForRender() diff --git a/tests/e2e/stroke-picker/basic.spec.ts b/tests/e2e/stroke-picker/basic.spec.ts index 33ec30c5e..e598eb962 100644 --- a/tests/e2e/stroke-picker/basic.spec.ts +++ b/tests/e2e/stroke-picker/basic.spec.ts @@ -103,8 +103,7 @@ test('stroke picker hsb saturation and brightness sliders update stroke color on align: 'INSIDE' } store.updateNodeWithUndo(card.id, { strokes: [stroke] }, 'Add demo card stroke') - store.state.selectedIds = new Set([card.id]) - store.requestRender() + store.select([card.id]) }) await canvas.waitForRender()