Add oxlint, oxfmt, typescript-go
- oxlint with react, react-hooks, typescript, import, unicorn plugins
- oxfmt (no trailing commas, single quotes, sorted imports)
- tsgo (typescript-go native preview) for fast typechecking
- Fix all lint warnings: non-null assertions, unused expressions, stale closures
- Scripts: lint, format, typecheck, check
2026-02-27 12:52:04 +00:00
|
|
|
{
|
|
|
|
|
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
2026-05-18 15:41:01 +00:00
|
|
|
"plugins": [
|
|
|
|
|
"typescript",
|
|
|
|
|
"import",
|
|
|
|
|
"unicorn",
|
|
|
|
|
"vue",
|
|
|
|
|
"promise",
|
|
|
|
|
"node"
|
|
|
|
|
],
|
|
|
|
|
"jsPlugins": [
|
|
|
|
|
"./lint/plugin.js"
|
|
|
|
|
],
|
Add oxlint, oxfmt, typescript-go
- oxlint with react, react-hooks, typescript, import, unicorn plugins
- oxfmt (no trailing commas, single quotes, sorted imports)
- tsgo (typescript-go native preview) for fast typechecking
- Fix all lint warnings: non-null assertions, unused expressions, stale closures
- Scripts: lint, format, typecheck, check
2026-02-27 12:52:04 +00:00
|
|
|
"env": {
|
|
|
|
|
"browser": true,
|
|
|
|
|
"es2024": true
|
|
|
|
|
},
|
|
|
|
|
"rules": {
|
|
|
|
|
"no-unused-vars": "warn",
|
2026-05-05 23:05:02 +00:00
|
|
|
"no-console": [
|
|
|
|
|
"warn",
|
|
|
|
|
{
|
2026-05-18 15:41:01 +00:00
|
|
|
"allow": [
|
|
|
|
|
"warn",
|
|
|
|
|
"error",
|
|
|
|
|
"debug",
|
|
|
|
|
"time",
|
|
|
|
|
"timeEnd"
|
|
|
|
|
]
|
2026-05-05 23:05:02 +00:00
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
"eqeqeq": [
|
|
|
|
|
"error",
|
|
|
|
|
"always",
|
|
|
|
|
{
|
|
|
|
|
"null": "ignore"
|
|
|
|
|
}
|
|
|
|
|
],
|
2026-03-16 10:54:07 +00:00
|
|
|
"prefer-const": "error",
|
|
|
|
|
"radix": "error",
|
2026-03-15 10:15:31 +00:00
|
|
|
"no-restricted-imports": [
|
|
|
|
|
"error",
|
|
|
|
|
{
|
|
|
|
|
"paths": [
|
|
|
|
|
{
|
|
|
|
|
"name": "@/types",
|
|
|
|
|
"message": "Import types directly from @open-pencil/core."
|
2026-05-19 08:12:01 +00:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "node:module",
|
|
|
|
|
"importNames": [
|
|
|
|
|
"createRequire"
|
|
|
|
|
],
|
|
|
|
|
"message": "Use ESM imports or import.meta.resolve instead of createRequire/require."
|
2026-03-15 10:15:31 +00:00
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
"patterns": [
|
|
|
|
|
{
|
2026-05-18 15:41:01 +00:00
|
|
|
"group": [
|
|
|
|
|
"@/engine/*"
|
|
|
|
|
],
|
2026-03-15 10:15:31 +00:00
|
|
|
"message": "Import from @open-pencil/core unless the module adds platform-specific logic.",
|
2026-05-18 15:41:01 +00:00
|
|
|
"allowImportNames": [
|
|
|
|
|
"loadFont",
|
|
|
|
|
"listFamilies",
|
|
|
|
|
"listFonts",
|
|
|
|
|
"preloadFonts"
|
|
|
|
|
]
|
2026-03-15 10:15:31 +00:00
|
|
|
},
|
|
|
|
|
{
|
2026-05-18 15:41:01 +00:00
|
|
|
"group": [
|
|
|
|
|
"../../packages/*",
|
|
|
|
|
"../../../packages/*"
|
|
|
|
|
],
|
2026-03-15 10:15:31 +00:00
|
|
|
"message": "Use the workspace package name (e.g. @open-pencil/core) instead of relative paths to packages/."
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
],
|
2026-03-09 06:16:07 +00:00
|
|
|
"no-empty-function": "error",
|
2026-03-15 10:15:31 +00:00
|
|
|
"max-lines": [
|
|
|
|
|
"warn",
|
|
|
|
|
{
|
|
|
|
|
"max": 600
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
"complexity": [
|
|
|
|
|
"error",
|
|
|
|
|
{
|
|
|
|
|
"max": 20
|
|
|
|
|
}
|
|
|
|
|
],
|
2026-05-05 21:25:49 +00:00
|
|
|
"typescript/no-explicit-any": "error",
|
|
|
|
|
"typescript/no-non-null-assertion": "error",
|
2026-03-08 20:04:44 +00:00
|
|
|
"typescript/no-floating-promises": "error",
|
Harden oxlint: consistent-type-imports, no-duplicates, no-misused-promises, prefer-optional-chain
Add 6 new lint rules: typescript/consistent-type-imports,
typescript/no-unnecessary-type-assertion, typescript/prefer-optional-chain,
typescript/no-misused-promises, import/no-duplicates, import/no-mutable-exports.
Ban @/types shim via no-restricted-imports.
Fix all violations: replace inline import() annotations with proper
type imports, merge duplicate module imports, add void to fire-and-forget
promises, convert && chains to optional chaining.
2026-03-09 06:05:04 +00:00
|
|
|
"typescript/no-misused-promises": "error",
|
|
|
|
|
"typescript/consistent-type-imports": "error",
|
2026-03-09 06:16:07 +00:00
|
|
|
"typescript/consistent-return": "error",
|
|
|
|
|
"typescript/no-unnecessary-condition": "error",
|
Harden oxlint: consistent-type-imports, no-duplicates, no-misused-promises, prefer-optional-chain
Add 6 new lint rules: typescript/consistent-type-imports,
typescript/no-unnecessary-type-assertion, typescript/prefer-optional-chain,
typescript/no-misused-promises, import/no-duplicates, import/no-mutable-exports.
Ban @/types shim via no-restricted-imports.
Fix all violations: replace inline import() annotations with proper
type imports, merge duplicate module imports, add void to fire-and-forget
promises, convert && chains to optional chaining.
2026-03-09 06:05:04 +00:00
|
|
|
"typescript/no-unnecessary-type-assertion": "error",
|
2026-03-09 06:16:07 +00:00
|
|
|
"typescript/no-unnecessary-type-parameters": "error",
|
2026-03-09 07:05:18 +00:00
|
|
|
"typescript/no-unnecessary-boolean-literal-compare": "error",
|
|
|
|
|
"typescript/no-unnecessary-template-expression": "error",
|
|
|
|
|
"typescript/no-unnecessary-type-arguments": "error",
|
Harden oxlint: consistent-type-imports, no-duplicates, no-misused-promises, prefer-optional-chain
Add 6 new lint rules: typescript/consistent-type-imports,
typescript/no-unnecessary-type-assertion, typescript/prefer-optional-chain,
typescript/no-misused-promises, import/no-duplicates, import/no-mutable-exports.
Ban @/types shim via no-restricted-imports.
Fix all violations: replace inline import() annotations with proper
type imports, merge duplicate module imports, add void to fire-and-forget
promises, convert && chains to optional chaining.
2026-03-09 06:05:04 +00:00
|
|
|
"typescript/prefer-optional-chain": "error",
|
2026-03-09 06:16:07 +00:00
|
|
|
"typescript/prefer-for-of": "error",
|
Add oxlint, oxfmt, typescript-go
- oxlint with react, react-hooks, typescript, import, unicorn plugins
- oxfmt (no trailing commas, single quotes, sorted imports)
- tsgo (typescript-go native preview) for fast typechecking
- Fix all lint warnings: non-null assertions, unused expressions, stale closures
- Scripts: lint, format, typecheck, check
2026-02-27 12:52:04 +00:00
|
|
|
"import/no-cycle": "error",
|
|
|
|
|
"import/no-self-import": "error",
|
Harden oxlint: consistent-type-imports, no-duplicates, no-misused-promises, prefer-optional-chain
Add 6 new lint rules: typescript/consistent-type-imports,
typescript/no-unnecessary-type-assertion, typescript/prefer-optional-chain,
typescript/no-misused-promises, import/no-duplicates, import/no-mutable-exports.
Ban @/types shim via no-restricted-imports.
Fix all violations: replace inline import() annotations with proper
type imports, merge duplicate module imports, add void to fire-and-forget
promises, convert && chains to optional chaining.
2026-03-09 06:05:04 +00:00
|
|
|
"import/no-duplicates": "error",
|
|
|
|
|
"import/no-mutable-exports": "error",
|
Add oxlint, oxfmt, typescript-go
- oxlint with react, react-hooks, typescript, import, unicorn plugins
- oxfmt (no trailing commas, single quotes, sorted imports)
- tsgo (typescript-go native preview) for fast typechecking
- Fix all lint warnings: non-null assertions, unused expressions, stale closures
- Scripts: lint, format, typecheck, check
2026-02-27 12:52:04 +00:00
|
|
|
"unicorn/no-instanceof-array": "error",
|
2026-03-08 20:08:27 +00:00
|
|
|
"unicorn/no-typeof-undefined": "error",
|
2026-03-09 06:16:07 +00:00
|
|
|
"unicorn/no-nested-ternary": "error",
|
2026-03-09 07:05:18 +00:00
|
|
|
"unicorn/no-useless-fallback-in-spread": "error",
|
|
|
|
|
"unicorn/no-length-as-slice-end": "error",
|
|
|
|
|
"unicorn/no-unnecessary-await": "error",
|
|
|
|
|
"unicorn/prefer-string-starts-ends-with": "error",
|
2026-03-09 06:16:07 +00:00
|
|
|
"unicorn/consistent-existence-index-check": "error",
|
2026-03-08 20:08:27 +00:00
|
|
|
"vue/no-arrow-functions-in-watch": "error",
|
|
|
|
|
"vue/no-deprecated-destroyed-lifecycle": "error",
|
|
|
|
|
"vue/no-export-in-script-setup": "error",
|
|
|
|
|
"vue/no-lifecycle-after-await": "error",
|
|
|
|
|
"vue/no-import-compiler-macros": "error",
|
|
|
|
|
"vue/prefer-import-from-vue": "error",
|
|
|
|
|
"vue/valid-define-emits": "error",
|
|
|
|
|
"vue/valid-define-props": "error",
|
|
|
|
|
"vue/no-required-prop-with-default": "error",
|
2026-03-09 06:20:01 +00:00
|
|
|
"vue/no-multiple-slot-args": "error",
|
2026-03-08 20:08:27 +00:00
|
|
|
"vue/define-emits-declaration": "error",
|
2026-05-15 08:57:38 +00:00
|
|
|
"vue/define-props-declaration": "error",
|
2026-03-08 20:08:27 +00:00
|
|
|
"vue/define-props-destructuring": "error",
|
2026-05-18 15:41:01 +00:00
|
|
|
"vue/max-props": [
|
|
|
|
|
"error",
|
|
|
|
|
{
|
|
|
|
|
"maxProps": 16
|
|
|
|
|
}
|
|
|
|
|
],
|
2026-05-15 08:57:38 +00:00
|
|
|
"vue/require-default-export": "error",
|
2026-03-09 06:41:28 +00:00
|
|
|
"vue/require-typed-ref": "error",
|
2026-03-15 10:15:31 +00:00
|
|
|
"open-pencil/no-inline-named-types": [
|
|
|
|
|
"error",
|
|
|
|
|
{
|
|
|
|
|
"Vector": "x:number,y:number",
|
|
|
|
|
"Color": "a:number,b:number,g:number,r:number",
|
|
|
|
|
"GUID": "localID:number,sessionID:number",
|
|
|
|
|
"Rect": "height:number,width:number,x:number,y:number",
|
|
|
|
|
"Matrix": "m00:number,m01:number,m02:number,m10:number,m11:number,m12:number"
|
|
|
|
|
}
|
|
|
|
|
],
|
2026-03-09 06:41:28 +00:00
|
|
|
"open-pencil/no-structuredclone-scene-arrays": "error",
|
2026-05-14 19:22:07 +00:00
|
|
|
"open-pencil/no-vue-style-blocks": "error",
|
2026-05-15 09:21:08 +00:00
|
|
|
"open-pencil/no-raw-test-id-string-props": "error",
|
2026-05-15 09:47:01 +00:00
|
|
|
"open-pencil/no-dynamic-data-test-id-in-vue": "error",
|
|
|
|
|
"open-pencil/no-test-id-helper-bind-in-vue": "error",
|
2026-05-15 09:07:58 +00:00
|
|
|
"open-pencil/no-invalid-test-id-attributes": "error",
|
2026-05-15 14:10:35 +00:00
|
|
|
"open-pencil/no-raw-test-id-selectors-in-tests": "error",
|
2026-05-15 10:14:51 +00:00
|
|
|
"open-pencil/no-generated-test-id-literals": "error",
|
2026-05-15 14:47:40 +00:00
|
|
|
"open-pencil/no-browser-side-effects-in-vue": "error",
|
2026-05-15 08:49:18 +00:00
|
|
|
"open-pencil/no-document-query-selector-in-vue": "error",
|
2026-05-14 19:22:07 +00:00
|
|
|
"open-pencil/no-direct-selection-tool-state-mutation": "error",
|
2026-03-09 07:05:18 +00:00
|
|
|
"open-pencil/no-math-random": "error",
|
2026-05-17 15:05:07 +00:00
|
|
|
"open-pencil/no-hardcoded-color-constants": "error",
|
Lint CLI code: no-raw-console-format rule, fix all violations
Add no-raw-console-format lint rule for CLI commands — bans template
literals and string concatenation in console.log, forcing use of
agentfmt helpers (bold, dim, kv, entity, fmtTree, fmtList, etc.).
Extend lint target to include packages/cli/src/.
Fix all 22 lint errors in CLI code:
- Replace string concatenation with agentfmt (clusters, typography, variables)
- Mark optional CLI args as required: false (citty type accuracy)
- Remove unnecessary type assertions and optional chains
- Merge duplicate @open-pencil/core imports in headless.ts
- Extract exportViaApp/exportFromFile to reduce export.ts complexity
- Remove unused imports (formatType, printError)
- void runMain() for floating promise
2026-03-09 09:54:53 +00:00
|
|
|
"open-pencil/no-hand-rolled-color": "error",
|
2026-03-13 07:03:12 +00:00
|
|
|
"open-pencil/no-raw-console-format": "off",
|
2026-03-16 10:54:07 +00:00
|
|
|
"open-pencil/no-silent-catch": "error",
|
Refactor architecture boundaries across core, app, and packages (#234)
* refactor(core): decompose editor factory and action modules
Split the monolithic editor factory and large action modules into focused
domain helpers:
- create.ts assembles context through bridge modules (clipboard,
components, structure, undo) and delegates to graph-reads, graph-events,
layout-runner, component-sync, and state factory
- structure.ts delegates to group, container-wrap, auto-layout-wrap,
reorder, and state-toggle helpers
- selection.ts delegates to hit-test, overlays, container navigation,
and read helpers
- clipboard.ts delegates to subtree-history, images, export, copy,
fonts, and placement helpers
- shapes.ts delegates to pen actions and section-adopt
- components.ts delegates to focus and instances helpers
- alignment.ts delegates to flip-rotate helper
- text.ts uses explicit TextEditSession for snapshot comparison
New focused modules: nudge, variable-bindings, layout-mode,
page-viewports, tool-registry, color-space
Undo: history/position and history/snapshot helpers, hardened
batch/rollback with nested batch support and configurable limit
* refactor(core): split tool definitions by domain
Split the monolithic tool registry into domain-specific modules:
- read/ — selection, find, pages, fonts, components, nodes, query, jsx
- create/ — basic shapes, components, vector, JSX render
- modify/ — paint, effects, geometry, layout, state, text, update
- structure/ — basic, arrange, batch, hierarchy, replace, tree
- variables/ — bindings, collections, read, values
- vector/ — boolean, path, export, viewport
- analyze/ — colors, typography, spacing, clusters, diff, eval
- describe/ — summaries, tree, roles, layout-issues
- stock-photo/ — providers, requests, apply
- codegen/ — component-map, tokens
Split registry into core/extended tiers; refine schema and AI adapter
* refactor(core): restructure kiwi codec and instance overrides
Reorganize the Kiwi .fig codec into domain subdirectories:
- binary/ — codec, schema, protocol
- fig/ — file, import, parse (core, worker, transfer)
- node-change/ — convert, export-node, serialize, plugin-data
- instance-overrides/ — constraints, dsd, populate, props, resolve,
symbol-overrides, symbol-props, sync, types
Vendored kiwi-schema/ left isolated
* refactor(core): split profiler, icons, IO, and add subpath exports
Profiler: speedscope-export, capture-session, hud-controller
Icons: api, svg, types, render, create-icons tool
IO: format registry and subpath exports
Canvas/color/text/vector: targeted cleanup
Add deliberate subpath exports: random, xpath, vector, color, canvas,
scene-graph, kiwi, design-jsx, io, tools, editor, layout, canvaskit,
profiler, text, lint, rpc, figma-api, constants
* refactor(vue): decompose canvas input, surface lifecycle, and controls
Canvas surface: gl-surface, kit-loader, render-loop, resize-observer
Canvas input handlers:
- move: drop-target, move-snap, duplicate-drag
- select: select-move, select-hover, select-hit
- resize: resize-rect, resize-vector, resize-start
- transform: rotation, marquee, pan, text-selection
- text-edit: navigation, clipboard, textarea lifecycle
- Shared: click-count, space-key, pan, pan-zoom, draw, raf-scheduler
Editor composition:
- commands split: actions, context, metadata, edit, selection, view
- menu-model split: command-groups, builders, types
- Gradient stop composable reuse in primitive root
Controls: fill, layout, typography, appearance, effects, stroke,
okhcl, prop-scrub, node-props, undo-batch, color-variable-binding
Variables/i18n/document/export helpers
Organize canvas, primitives, controls, editor, and variables into
cohesive module directories with package-local import aliases
Expose MenuActionNode/MenuSeparatorNode from public API
* refactor(app): split document IO, editor session, and automation bridge
Document IO: source-state, naming, writer, reload-source, reload-state,
imported-document, watch-targets, save-targets
Editor session: create, modules, types, accessors, computed, refs
Editor canvas: loader-overlay, collaboration-awareness,
context-selection, menu-actions, menu-model
Automation bridge: eval, tools, exports, files, selection, RPC fallback
AI/ACP: transport, map-update, permission, debug, chat effects/storage
Collab: awareness, graph-bindings, yjs-sync, follow, session, types
Shell keyboard: actions, bindings, clipboard, focus, nudging,
raw-events, registry, reserved, shortcuts, space-tool
Shell menu: app-menu, document-name, entry, files
Demo: colors, effects, helpers, section builders (components,
app-preview, effects, standalone, variables) — document.ts reduced
from 981 to 32 lines as pure orchestrator
Move app modules under src/app/ with organized domain structure:
editor, document, ai, collab, shell, automation, demo, tabs
* refactor(app): decompose UI components with provide/inject context
Split monolithic components using Reka UI-inspired namespace folders
with scoped provide/inject context — no prop drilling:
- CollabPanel/ — context, avatars, share, connected, join
- ColorPickerPanel/ — context, area, format, field groups, sliders
- MobileHud/ — context, action toast, tool badge, file menu, presence
- ProviderSettings/ — context, API key/type, endpoint, tokens, photos
- Toolbar/ — actions, types, desktop, mobile, tool button, flyout
- LayoutSection/ — types, auto-layout, flex, grid, padding, size, clip
Properties helpers: fill-okhcl adapter, fill-label, color-style-row
Menu: entry helpers, document-name rename, stale type removal
* refactor(mcp): split server into focused modules
- browser-rpc — WebSocket client management
- mcp-sessions — session lifecycle
- tool-output — response formatting
- tool-schema — Zod schema generation from ToolDefs
- jsx-preprocess — JSX source transformation
- result — result helpers
- tool-registration — MCP tool wiring
- auth — API key validation
- http-options — CORS/request handling
- stdio-bridge — stdio transport adapter
* refactor(cli): split analyze subcommands and shared helpers
- Analyze subcommands: clusters, colors, spacing, typography
- RPC data loading helper
- Migrate imports to targeted core subpath exports
* refactor(docs): split VitePress config and shared table component
Config helpers: sdk-sidebar, seo, labels, sidebars, locale-theme,
root-theme, locales
Shared SdkDataTable component replaces duplicated table markup in
SdkPropsTable, SdkEventsTable, and SdkSlotsTable
Update contributing and testing docs
* refactor(tauri): decompose desktop entrypoint
Split lib.rs into focused service modules:
- fig_container.rs — .fig archive/compression commands
- fonts.rs — font cache and system font enumeration
- menu.rs — native menu construction
- menu_events.rs — menu event dispatch and devtools toggle
- window.rs — main window show/focus lifecycle
* test: share domain test factories and migrate fixtures
New shared helpers:
- tests/helpers/scene.ts — makeSceneGraph factory
- tests/helpers/vector-network.ts — vertex/segment/network builders
- tests/helpers/fig-traversal.ts — all-node collection, type counts
- tests/helpers/undo.ts — undo test utilities
- tests/helpers/editor-history.ts — editor history test helpers
Migrate render, vector, fig-roundtrip, and undo tests to use shared
factories instead of inline fixture construction
* build: add structural lint rules, split vite config, update docs
Structural lint (oxlint.structure.json + lint/plugin.js):
- 20+ custom rules enforcing package boundaries, lifecycle patterns,
naming conventions, and import discipline
Vite config split: raw-markdown, canvaskit-assets, pwa, server,
aliases, automation plugins
Remove legacy shims and utils superseded by SDK/core modules
Update AGENTS.md, CONTRIBUTING.md, eval-command docs, tsconfig
* fix(vue): normalize canvas directory casing and remove duplicate export
- Rename Canvas/ to canvas/ in git index to match #vue/canvas/* imports
(PascalCase was correct for component primitives but canvas/ is a
non-component domain directory)
- Remove duplicate ./random subpath export in core package.json
* fix: add #vue and #core Vite resolve aliases for dev server
* refactor(core): reduce remaining large modules
Split the remaining large core hotspots into cohesive domain modules while preserving public facades and behavior.
- Extract scene graph types, variables, node defaults, and vector-network helpers
- Decompose canvas renderer orchestration, state, paints, colors, lifecycle, labels, and delegated domain methods into renderer/ and labels/ subfolders
- Split Kiwi node-change, binary variable binding, layout, RPC, vector, JSX export, clipboard, design JSX, and Figma proxy helpers
- Replace collision-driven *Fn import aliases with namespace imports and enforce the pattern in lint
Validation:
- bun run check
- bun --filter @open-pencil/vue build
- bun run test:dupes
* fix(app): forward color input attrs
* fix(app): cover section drawing errors
* fix(editor): undo option-drag duplicates
* docs: document domain subfolder convention
* fix(app): handle undo redo on keydown
* refactor(app): dispatch shortcuts from keydown
* refactor: group prefixed domain modules
* refactor(app): use tinykeys for shortcuts
* refactor(core): group symbol override modules
* refactor(core): group fig kiwi container helper
* refactor(canvas): split overlay rendering modules
* refactor(vue): remove unused internal barrels
* fix(app): lay out demo components before instancing
* fix(app): restore demo badge spacing
* perf(canvas): split scene and overlay rendering
* refactor(vue): wrap wheel gesture lifecycle
* fix(canvas): wait for fonts before hiding loader
* docs: update unreleased changelog
2026-04-30 12:14:19 +00:00
|
|
|
"open-pencil/no-typeof-window-check": "error",
|
|
|
|
|
"open-pencil/no-vue-self-package-imports": "error",
|
|
|
|
|
"open-pencil/no-cross-package-source-imports": "error",
|
|
|
|
|
"open-pencil/no-app-imports-in-packages": "error",
|
|
|
|
|
"open-pencil/no-core-framework-imports": "error",
|
|
|
|
|
"open-pencil/no-direct-storage-access": "error",
|
2026-05-05 23:05:02 +00:00
|
|
|
"open-pencil/no-deep-parent-relative-imports": "error",
|
Refactor architecture boundaries across core, app, and packages (#234)
* refactor(core): decompose editor factory and action modules
Split the monolithic editor factory and large action modules into focused
domain helpers:
- create.ts assembles context through bridge modules (clipboard,
components, structure, undo) and delegates to graph-reads, graph-events,
layout-runner, component-sync, and state factory
- structure.ts delegates to group, container-wrap, auto-layout-wrap,
reorder, and state-toggle helpers
- selection.ts delegates to hit-test, overlays, container navigation,
and read helpers
- clipboard.ts delegates to subtree-history, images, export, copy,
fonts, and placement helpers
- shapes.ts delegates to pen actions and section-adopt
- components.ts delegates to focus and instances helpers
- alignment.ts delegates to flip-rotate helper
- text.ts uses explicit TextEditSession for snapshot comparison
New focused modules: nudge, variable-bindings, layout-mode,
page-viewports, tool-registry, color-space
Undo: history/position and history/snapshot helpers, hardened
batch/rollback with nested batch support and configurable limit
* refactor(core): split tool definitions by domain
Split the monolithic tool registry into domain-specific modules:
- read/ — selection, find, pages, fonts, components, nodes, query, jsx
- create/ — basic shapes, components, vector, JSX render
- modify/ — paint, effects, geometry, layout, state, text, update
- structure/ — basic, arrange, batch, hierarchy, replace, tree
- variables/ — bindings, collections, read, values
- vector/ — boolean, path, export, viewport
- analyze/ — colors, typography, spacing, clusters, diff, eval
- describe/ — summaries, tree, roles, layout-issues
- stock-photo/ — providers, requests, apply
- codegen/ — component-map, tokens
Split registry into core/extended tiers; refine schema and AI adapter
* refactor(core): restructure kiwi codec and instance overrides
Reorganize the Kiwi .fig codec into domain subdirectories:
- binary/ — codec, schema, protocol
- fig/ — file, import, parse (core, worker, transfer)
- node-change/ — convert, export-node, serialize, plugin-data
- instance-overrides/ — constraints, dsd, populate, props, resolve,
symbol-overrides, symbol-props, sync, types
Vendored kiwi-schema/ left isolated
* refactor(core): split profiler, icons, IO, and add subpath exports
Profiler: speedscope-export, capture-session, hud-controller
Icons: api, svg, types, render, create-icons tool
IO: format registry and subpath exports
Canvas/color/text/vector: targeted cleanup
Add deliberate subpath exports: random, xpath, vector, color, canvas,
scene-graph, kiwi, design-jsx, io, tools, editor, layout, canvaskit,
profiler, text, lint, rpc, figma-api, constants
* refactor(vue): decompose canvas input, surface lifecycle, and controls
Canvas surface: gl-surface, kit-loader, render-loop, resize-observer
Canvas input handlers:
- move: drop-target, move-snap, duplicate-drag
- select: select-move, select-hover, select-hit
- resize: resize-rect, resize-vector, resize-start
- transform: rotation, marquee, pan, text-selection
- text-edit: navigation, clipboard, textarea lifecycle
- Shared: click-count, space-key, pan, pan-zoom, draw, raf-scheduler
Editor composition:
- commands split: actions, context, metadata, edit, selection, view
- menu-model split: command-groups, builders, types
- Gradient stop composable reuse in primitive root
Controls: fill, layout, typography, appearance, effects, stroke,
okhcl, prop-scrub, node-props, undo-batch, color-variable-binding
Variables/i18n/document/export helpers
Organize canvas, primitives, controls, editor, and variables into
cohesive module directories with package-local import aliases
Expose MenuActionNode/MenuSeparatorNode from public API
* refactor(app): split document IO, editor session, and automation bridge
Document IO: source-state, naming, writer, reload-source, reload-state,
imported-document, watch-targets, save-targets
Editor session: create, modules, types, accessors, computed, refs
Editor canvas: loader-overlay, collaboration-awareness,
context-selection, menu-actions, menu-model
Automation bridge: eval, tools, exports, files, selection, RPC fallback
AI/ACP: transport, map-update, permission, debug, chat effects/storage
Collab: awareness, graph-bindings, yjs-sync, follow, session, types
Shell keyboard: actions, bindings, clipboard, focus, nudging,
raw-events, registry, reserved, shortcuts, space-tool
Shell menu: app-menu, document-name, entry, files
Demo: colors, effects, helpers, section builders (components,
app-preview, effects, standalone, variables) — document.ts reduced
from 981 to 32 lines as pure orchestrator
Move app modules under src/app/ with organized domain structure:
editor, document, ai, collab, shell, automation, demo, tabs
* refactor(app): decompose UI components with provide/inject context
Split monolithic components using Reka UI-inspired namespace folders
with scoped provide/inject context — no prop drilling:
- CollabPanel/ — context, avatars, share, connected, join
- ColorPickerPanel/ — context, area, format, field groups, sliders
- MobileHud/ — context, action toast, tool badge, file menu, presence
- ProviderSettings/ — context, API key/type, endpoint, tokens, photos
- Toolbar/ — actions, types, desktop, mobile, tool button, flyout
- LayoutSection/ — types, auto-layout, flex, grid, padding, size, clip
Properties helpers: fill-okhcl adapter, fill-label, color-style-row
Menu: entry helpers, document-name rename, stale type removal
* refactor(mcp): split server into focused modules
- browser-rpc — WebSocket client management
- mcp-sessions — session lifecycle
- tool-output — response formatting
- tool-schema — Zod schema generation from ToolDefs
- jsx-preprocess — JSX source transformation
- result — result helpers
- tool-registration — MCP tool wiring
- auth — API key validation
- http-options — CORS/request handling
- stdio-bridge — stdio transport adapter
* refactor(cli): split analyze subcommands and shared helpers
- Analyze subcommands: clusters, colors, spacing, typography
- RPC data loading helper
- Migrate imports to targeted core subpath exports
* refactor(docs): split VitePress config and shared table component
Config helpers: sdk-sidebar, seo, labels, sidebars, locale-theme,
root-theme, locales
Shared SdkDataTable component replaces duplicated table markup in
SdkPropsTable, SdkEventsTable, and SdkSlotsTable
Update contributing and testing docs
* refactor(tauri): decompose desktop entrypoint
Split lib.rs into focused service modules:
- fig_container.rs — .fig archive/compression commands
- fonts.rs — font cache and system font enumeration
- menu.rs — native menu construction
- menu_events.rs — menu event dispatch and devtools toggle
- window.rs — main window show/focus lifecycle
* test: share domain test factories and migrate fixtures
New shared helpers:
- tests/helpers/scene.ts — makeSceneGraph factory
- tests/helpers/vector-network.ts — vertex/segment/network builders
- tests/helpers/fig-traversal.ts — all-node collection, type counts
- tests/helpers/undo.ts — undo test utilities
- tests/helpers/editor-history.ts — editor history test helpers
Migrate render, vector, fig-roundtrip, and undo tests to use shared
factories instead of inline fixture construction
* build: add structural lint rules, split vite config, update docs
Structural lint (oxlint.structure.json + lint/plugin.js):
- 20+ custom rules enforcing package boundaries, lifecycle patterns,
naming conventions, and import discipline
Vite config split: raw-markdown, canvaskit-assets, pwa, server,
aliases, automation plugins
Remove legacy shims and utils superseded by SDK/core modules
Update AGENTS.md, CONTRIBUTING.md, eval-command docs, tsconfig
* fix(vue): normalize canvas directory casing and remove duplicate export
- Rename Canvas/ to canvas/ in git index to match #vue/canvas/* imports
(PascalCase was correct for component primitives but canvas/ is a
non-component domain directory)
- Remove duplicate ./random subpath export in core package.json
* fix: add #vue and #core Vite resolve aliases for dev server
* refactor(core): reduce remaining large modules
Split the remaining large core hotspots into cohesive domain modules while preserving public facades and behavior.
- Extract scene graph types, variables, node defaults, and vector-network helpers
- Decompose canvas renderer orchestration, state, paints, colors, lifecycle, labels, and delegated domain methods into renderer/ and labels/ subfolders
- Split Kiwi node-change, binary variable binding, layout, RPC, vector, JSX export, clipboard, design JSX, and Figma proxy helpers
- Replace collision-driven *Fn import aliases with namespace imports and enforce the pattern in lint
Validation:
- bun run check
- bun --filter @open-pencil/vue build
- bun run test:dupes
* fix(app): forward color input attrs
* fix(app): cover section drawing errors
* fix(editor): undo option-drag duplicates
* docs: document domain subfolder convention
* fix(app): handle undo redo on keydown
* refactor(app): dispatch shortcuts from keydown
* refactor: group prefixed domain modules
* refactor(app): use tinykeys for shortcuts
* refactor(core): group symbol override modules
* refactor(core): group fig kiwi container helper
* refactor(canvas): split overlay rendering modules
* refactor(vue): remove unused internal barrels
* fix(app): lay out demo components before instancing
* fix(app): restore demo badge spacing
* perf(canvas): split scene and overlay rendering
* refactor(vue): wrap wheel gesture lifecycle
* fix(canvas): wait for fonts before hiding loader
* docs: update unreleased changelog
2026-04-30 12:14:19 +00:00
|
|
|
"open-pencil/no-broad-double-cast": "error",
|
2026-05-05 21:25:49 +00:00
|
|
|
"open-pencil/no-unknown-record-double-cast": "error",
|
2026-05-05 21:42:45 +00:00
|
|
|
"open-pencil/no-ts-suppression-comments": "error",
|
2026-05-05 21:48:57 +00:00
|
|
|
"open-pencil/no-reflect-delete-global-this-outside-tests": "error",
|
Refactor architecture boundaries across core, app, and packages (#234)
* refactor(core): decompose editor factory and action modules
Split the monolithic editor factory and large action modules into focused
domain helpers:
- create.ts assembles context through bridge modules (clipboard,
components, structure, undo) and delegates to graph-reads, graph-events,
layout-runner, component-sync, and state factory
- structure.ts delegates to group, container-wrap, auto-layout-wrap,
reorder, and state-toggle helpers
- selection.ts delegates to hit-test, overlays, container navigation,
and read helpers
- clipboard.ts delegates to subtree-history, images, export, copy,
fonts, and placement helpers
- shapes.ts delegates to pen actions and section-adopt
- components.ts delegates to focus and instances helpers
- alignment.ts delegates to flip-rotate helper
- text.ts uses explicit TextEditSession for snapshot comparison
New focused modules: nudge, variable-bindings, layout-mode,
page-viewports, tool-registry, color-space
Undo: history/position and history/snapshot helpers, hardened
batch/rollback with nested batch support and configurable limit
* refactor(core): split tool definitions by domain
Split the monolithic tool registry into domain-specific modules:
- read/ — selection, find, pages, fonts, components, nodes, query, jsx
- create/ — basic shapes, components, vector, JSX render
- modify/ — paint, effects, geometry, layout, state, text, update
- structure/ — basic, arrange, batch, hierarchy, replace, tree
- variables/ — bindings, collections, read, values
- vector/ — boolean, path, export, viewport
- analyze/ — colors, typography, spacing, clusters, diff, eval
- describe/ — summaries, tree, roles, layout-issues
- stock-photo/ — providers, requests, apply
- codegen/ — component-map, tokens
Split registry into core/extended tiers; refine schema and AI adapter
* refactor(core): restructure kiwi codec and instance overrides
Reorganize the Kiwi .fig codec into domain subdirectories:
- binary/ — codec, schema, protocol
- fig/ — file, import, parse (core, worker, transfer)
- node-change/ — convert, export-node, serialize, plugin-data
- instance-overrides/ — constraints, dsd, populate, props, resolve,
symbol-overrides, symbol-props, sync, types
Vendored kiwi-schema/ left isolated
* refactor(core): split profiler, icons, IO, and add subpath exports
Profiler: speedscope-export, capture-session, hud-controller
Icons: api, svg, types, render, create-icons tool
IO: format registry and subpath exports
Canvas/color/text/vector: targeted cleanup
Add deliberate subpath exports: random, xpath, vector, color, canvas,
scene-graph, kiwi, design-jsx, io, tools, editor, layout, canvaskit,
profiler, text, lint, rpc, figma-api, constants
* refactor(vue): decompose canvas input, surface lifecycle, and controls
Canvas surface: gl-surface, kit-loader, render-loop, resize-observer
Canvas input handlers:
- move: drop-target, move-snap, duplicate-drag
- select: select-move, select-hover, select-hit
- resize: resize-rect, resize-vector, resize-start
- transform: rotation, marquee, pan, text-selection
- text-edit: navigation, clipboard, textarea lifecycle
- Shared: click-count, space-key, pan, pan-zoom, draw, raf-scheduler
Editor composition:
- commands split: actions, context, metadata, edit, selection, view
- menu-model split: command-groups, builders, types
- Gradient stop composable reuse in primitive root
Controls: fill, layout, typography, appearance, effects, stroke,
okhcl, prop-scrub, node-props, undo-batch, color-variable-binding
Variables/i18n/document/export helpers
Organize canvas, primitives, controls, editor, and variables into
cohesive module directories with package-local import aliases
Expose MenuActionNode/MenuSeparatorNode from public API
* refactor(app): split document IO, editor session, and automation bridge
Document IO: source-state, naming, writer, reload-source, reload-state,
imported-document, watch-targets, save-targets
Editor session: create, modules, types, accessors, computed, refs
Editor canvas: loader-overlay, collaboration-awareness,
context-selection, menu-actions, menu-model
Automation bridge: eval, tools, exports, files, selection, RPC fallback
AI/ACP: transport, map-update, permission, debug, chat effects/storage
Collab: awareness, graph-bindings, yjs-sync, follow, session, types
Shell keyboard: actions, bindings, clipboard, focus, nudging,
raw-events, registry, reserved, shortcuts, space-tool
Shell menu: app-menu, document-name, entry, files
Demo: colors, effects, helpers, section builders (components,
app-preview, effects, standalone, variables) — document.ts reduced
from 981 to 32 lines as pure orchestrator
Move app modules under src/app/ with organized domain structure:
editor, document, ai, collab, shell, automation, demo, tabs
* refactor(app): decompose UI components with provide/inject context
Split monolithic components using Reka UI-inspired namespace folders
with scoped provide/inject context — no prop drilling:
- CollabPanel/ — context, avatars, share, connected, join
- ColorPickerPanel/ — context, area, format, field groups, sliders
- MobileHud/ — context, action toast, tool badge, file menu, presence
- ProviderSettings/ — context, API key/type, endpoint, tokens, photos
- Toolbar/ — actions, types, desktop, mobile, tool button, flyout
- LayoutSection/ — types, auto-layout, flex, grid, padding, size, clip
Properties helpers: fill-okhcl adapter, fill-label, color-style-row
Menu: entry helpers, document-name rename, stale type removal
* refactor(mcp): split server into focused modules
- browser-rpc — WebSocket client management
- mcp-sessions — session lifecycle
- tool-output — response formatting
- tool-schema — Zod schema generation from ToolDefs
- jsx-preprocess — JSX source transformation
- result — result helpers
- tool-registration — MCP tool wiring
- auth — API key validation
- http-options — CORS/request handling
- stdio-bridge — stdio transport adapter
* refactor(cli): split analyze subcommands and shared helpers
- Analyze subcommands: clusters, colors, spacing, typography
- RPC data loading helper
- Migrate imports to targeted core subpath exports
* refactor(docs): split VitePress config and shared table component
Config helpers: sdk-sidebar, seo, labels, sidebars, locale-theme,
root-theme, locales
Shared SdkDataTable component replaces duplicated table markup in
SdkPropsTable, SdkEventsTable, and SdkSlotsTable
Update contributing and testing docs
* refactor(tauri): decompose desktop entrypoint
Split lib.rs into focused service modules:
- fig_container.rs — .fig archive/compression commands
- fonts.rs — font cache and system font enumeration
- menu.rs — native menu construction
- menu_events.rs — menu event dispatch and devtools toggle
- window.rs — main window show/focus lifecycle
* test: share domain test factories and migrate fixtures
New shared helpers:
- tests/helpers/scene.ts — makeSceneGraph factory
- tests/helpers/vector-network.ts — vertex/segment/network builders
- tests/helpers/fig-traversal.ts — all-node collection, type counts
- tests/helpers/undo.ts — undo test utilities
- tests/helpers/editor-history.ts — editor history test helpers
Migrate render, vector, fig-roundtrip, and undo tests to use shared
factories instead of inline fixture construction
* build: add structural lint rules, split vite config, update docs
Structural lint (oxlint.structure.json + lint/plugin.js):
- 20+ custom rules enforcing package boundaries, lifecycle patterns,
naming conventions, and import discipline
Vite config split: raw-markdown, canvaskit-assets, pwa, server,
aliases, automation plugins
Remove legacy shims and utils superseded by SDK/core modules
Update AGENTS.md, CONTRIBUTING.md, eval-command docs, tsconfig
* fix(vue): normalize canvas directory casing and remove duplicate export
- Rename Canvas/ to canvas/ in git index to match #vue/canvas/* imports
(PascalCase was correct for component primitives but canvas/ is a
non-component domain directory)
- Remove duplicate ./random subpath export in core package.json
* fix: add #vue and #core Vite resolve aliases for dev server
* refactor(core): reduce remaining large modules
Split the remaining large core hotspots into cohesive domain modules while preserving public facades and behavior.
- Extract scene graph types, variables, node defaults, and vector-network helpers
- Decompose canvas renderer orchestration, state, paints, colors, lifecycle, labels, and delegated domain methods into renderer/ and labels/ subfolders
- Split Kiwi node-change, binary variable binding, layout, RPC, vector, JSX export, clipboard, design JSX, and Figma proxy helpers
- Replace collision-driven *Fn import aliases with namespace imports and enforce the pattern in lint
Validation:
- bun run check
- bun --filter @open-pencil/vue build
- bun run test:dupes
* fix(app): forward color input attrs
* fix(app): cover section drawing errors
* fix(editor): undo option-drag duplicates
* docs: document domain subfolder convention
* fix(app): handle undo redo on keydown
* refactor(app): dispatch shortcuts from keydown
* refactor: group prefixed domain modules
* refactor(app): use tinykeys for shortcuts
* refactor(core): group symbol override modules
* refactor(core): group fig kiwi container helper
* refactor(canvas): split overlay rendering modules
* refactor(vue): remove unused internal barrels
* fix(app): lay out demo components before instancing
* fix(app): restore demo badge spacing
* perf(canvas): split scene and overlay rendering
* refactor(vue): wrap wheel gesture lifecycle
* fix(canvas): wait for fonts before hiding loader
* docs: update unreleased changelog
2026-04-30 12:14:19 +00:00
|
|
|
"open-pencil/no-core-browser-globals": "error",
|
2026-05-06 07:38:03 +00:00
|
|
|
"open-pencil/no-direct-open-pencil-window-internals": "error",
|
2026-05-06 09:19:39 +00:00
|
|
|
"open-pencil/no-direct-open-pencil-browser-store": "error",
|
Refactor architecture boundaries across core, app, and packages (#234)
* refactor(core): decompose editor factory and action modules
Split the monolithic editor factory and large action modules into focused
domain helpers:
- create.ts assembles context through bridge modules (clipboard,
components, structure, undo) and delegates to graph-reads, graph-events,
layout-runner, component-sync, and state factory
- structure.ts delegates to group, container-wrap, auto-layout-wrap,
reorder, and state-toggle helpers
- selection.ts delegates to hit-test, overlays, container navigation,
and read helpers
- clipboard.ts delegates to subtree-history, images, export, copy,
fonts, and placement helpers
- shapes.ts delegates to pen actions and section-adopt
- components.ts delegates to focus and instances helpers
- alignment.ts delegates to flip-rotate helper
- text.ts uses explicit TextEditSession for snapshot comparison
New focused modules: nudge, variable-bindings, layout-mode,
page-viewports, tool-registry, color-space
Undo: history/position and history/snapshot helpers, hardened
batch/rollback with nested batch support and configurable limit
* refactor(core): split tool definitions by domain
Split the monolithic tool registry into domain-specific modules:
- read/ — selection, find, pages, fonts, components, nodes, query, jsx
- create/ — basic shapes, components, vector, JSX render
- modify/ — paint, effects, geometry, layout, state, text, update
- structure/ — basic, arrange, batch, hierarchy, replace, tree
- variables/ — bindings, collections, read, values
- vector/ — boolean, path, export, viewport
- analyze/ — colors, typography, spacing, clusters, diff, eval
- describe/ — summaries, tree, roles, layout-issues
- stock-photo/ — providers, requests, apply
- codegen/ — component-map, tokens
Split registry into core/extended tiers; refine schema and AI adapter
* refactor(core): restructure kiwi codec and instance overrides
Reorganize the Kiwi .fig codec into domain subdirectories:
- binary/ — codec, schema, protocol
- fig/ — file, import, parse (core, worker, transfer)
- node-change/ — convert, export-node, serialize, plugin-data
- instance-overrides/ — constraints, dsd, populate, props, resolve,
symbol-overrides, symbol-props, sync, types
Vendored kiwi-schema/ left isolated
* refactor(core): split profiler, icons, IO, and add subpath exports
Profiler: speedscope-export, capture-session, hud-controller
Icons: api, svg, types, render, create-icons tool
IO: format registry and subpath exports
Canvas/color/text/vector: targeted cleanup
Add deliberate subpath exports: random, xpath, vector, color, canvas,
scene-graph, kiwi, design-jsx, io, tools, editor, layout, canvaskit,
profiler, text, lint, rpc, figma-api, constants
* refactor(vue): decompose canvas input, surface lifecycle, and controls
Canvas surface: gl-surface, kit-loader, render-loop, resize-observer
Canvas input handlers:
- move: drop-target, move-snap, duplicate-drag
- select: select-move, select-hover, select-hit
- resize: resize-rect, resize-vector, resize-start
- transform: rotation, marquee, pan, text-selection
- text-edit: navigation, clipboard, textarea lifecycle
- Shared: click-count, space-key, pan, pan-zoom, draw, raf-scheduler
Editor composition:
- commands split: actions, context, metadata, edit, selection, view
- menu-model split: command-groups, builders, types
- Gradient stop composable reuse in primitive root
Controls: fill, layout, typography, appearance, effects, stroke,
okhcl, prop-scrub, node-props, undo-batch, color-variable-binding
Variables/i18n/document/export helpers
Organize canvas, primitives, controls, editor, and variables into
cohesive module directories with package-local import aliases
Expose MenuActionNode/MenuSeparatorNode from public API
* refactor(app): split document IO, editor session, and automation bridge
Document IO: source-state, naming, writer, reload-source, reload-state,
imported-document, watch-targets, save-targets
Editor session: create, modules, types, accessors, computed, refs
Editor canvas: loader-overlay, collaboration-awareness,
context-selection, menu-actions, menu-model
Automation bridge: eval, tools, exports, files, selection, RPC fallback
AI/ACP: transport, map-update, permission, debug, chat effects/storage
Collab: awareness, graph-bindings, yjs-sync, follow, session, types
Shell keyboard: actions, bindings, clipboard, focus, nudging,
raw-events, registry, reserved, shortcuts, space-tool
Shell menu: app-menu, document-name, entry, files
Demo: colors, effects, helpers, section builders (components,
app-preview, effects, standalone, variables) — document.ts reduced
from 981 to 32 lines as pure orchestrator
Move app modules under src/app/ with organized domain structure:
editor, document, ai, collab, shell, automation, demo, tabs
* refactor(app): decompose UI components with provide/inject context
Split monolithic components using Reka UI-inspired namespace folders
with scoped provide/inject context — no prop drilling:
- CollabPanel/ — context, avatars, share, connected, join
- ColorPickerPanel/ — context, area, format, field groups, sliders
- MobileHud/ — context, action toast, tool badge, file menu, presence
- ProviderSettings/ — context, API key/type, endpoint, tokens, photos
- Toolbar/ — actions, types, desktop, mobile, tool button, flyout
- LayoutSection/ — types, auto-layout, flex, grid, padding, size, clip
Properties helpers: fill-okhcl adapter, fill-label, color-style-row
Menu: entry helpers, document-name rename, stale type removal
* refactor(mcp): split server into focused modules
- browser-rpc — WebSocket client management
- mcp-sessions — session lifecycle
- tool-output — response formatting
- tool-schema — Zod schema generation from ToolDefs
- jsx-preprocess — JSX source transformation
- result — result helpers
- tool-registration — MCP tool wiring
- auth — API key validation
- http-options — CORS/request handling
- stdio-bridge — stdio transport adapter
* refactor(cli): split analyze subcommands and shared helpers
- Analyze subcommands: clusters, colors, spacing, typography
- RPC data loading helper
- Migrate imports to targeted core subpath exports
* refactor(docs): split VitePress config and shared table component
Config helpers: sdk-sidebar, seo, labels, sidebars, locale-theme,
root-theme, locales
Shared SdkDataTable component replaces duplicated table markup in
SdkPropsTable, SdkEventsTable, and SdkSlotsTable
Update contributing and testing docs
* refactor(tauri): decompose desktop entrypoint
Split lib.rs into focused service modules:
- fig_container.rs — .fig archive/compression commands
- fonts.rs — font cache and system font enumeration
- menu.rs — native menu construction
- menu_events.rs — menu event dispatch and devtools toggle
- window.rs — main window show/focus lifecycle
* test: share domain test factories and migrate fixtures
New shared helpers:
- tests/helpers/scene.ts — makeSceneGraph factory
- tests/helpers/vector-network.ts — vertex/segment/network builders
- tests/helpers/fig-traversal.ts — all-node collection, type counts
- tests/helpers/undo.ts — undo test utilities
- tests/helpers/editor-history.ts — editor history test helpers
Migrate render, vector, fig-roundtrip, and undo tests to use shared
factories instead of inline fixture construction
* build: add structural lint rules, split vite config, update docs
Structural lint (oxlint.structure.json + lint/plugin.js):
- 20+ custom rules enforcing package boundaries, lifecycle patterns,
naming conventions, and import discipline
Vite config split: raw-markdown, canvaskit-assets, pwa, server,
aliases, automation plugins
Remove legacy shims and utils superseded by SDK/core modules
Update AGENTS.md, CONTRIBUTING.md, eval-command docs, tsconfig
* fix(vue): normalize canvas directory casing and remove duplicate export
- Rename Canvas/ to canvas/ in git index to match #vue/canvas/* imports
(PascalCase was correct for component primitives but canvas/ is a
non-component domain directory)
- Remove duplicate ./random subpath export in core package.json
* fix: add #vue and #core Vite resolve aliases for dev server
* refactor(core): reduce remaining large modules
Split the remaining large core hotspots into cohesive domain modules while preserving public facades and behavior.
- Extract scene graph types, variables, node defaults, and vector-network helpers
- Decompose canvas renderer orchestration, state, paints, colors, lifecycle, labels, and delegated domain methods into renderer/ and labels/ subfolders
- Split Kiwi node-change, binary variable binding, layout, RPC, vector, JSX export, clipboard, design JSX, and Figma proxy helpers
- Replace collision-driven *Fn import aliases with namespace imports and enforce the pattern in lint
Validation:
- bun run check
- bun --filter @open-pencil/vue build
- bun run test:dupes
* fix(app): forward color input attrs
* fix(app): cover section drawing errors
* fix(editor): undo option-drag duplicates
* docs: document domain subfolder convention
* fix(app): handle undo redo on keydown
* refactor(app): dispatch shortcuts from keydown
* refactor: group prefixed domain modules
* refactor(app): use tinykeys for shortcuts
* refactor(core): group symbol override modules
* refactor(core): group fig kiwi container helper
* refactor(canvas): split overlay rendering modules
* refactor(vue): remove unused internal barrels
* fix(app): lay out demo components before instancing
* fix(app): restore demo badge spacing
* perf(canvas): split scene and overlay rendering
* refactor(vue): wrap wheel gesture lifecycle
* fix(canvas): wait for fonts before hiding loader
* docs: update unreleased changelog
2026-04-30 12:14:19 +00:00
|
|
|
"open-pencil/no-function-alias-imports": "error",
|
2026-05-05 23:05:02 +00:00
|
|
|
"open-pencil/max-composition-root-lines": [
|
|
|
|
|
"error",
|
|
|
|
|
{
|
|
|
|
|
"max": 260
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
"open-pencil/no-core-parent-relative-imports": "error",
|
|
|
|
|
"open-pencil/no-mcp-parent-relative-imports": "error",
|
|
|
|
|
"open-pencil/no-vue-parent-relative-imports": "error",
|
|
|
|
|
"open-pencil/no-cli-parent-relative-imports": "error",
|
|
|
|
|
"open-pencil/no-mcp-core-barrel-imports": "error",
|
|
|
|
|
"open-pencil/no-cli-core-barrel-imports": "error",
|
|
|
|
|
"open-pencil/no-script-core-barrel-imports": "error",
|
|
|
|
|
"open-pencil/no-core-self-package-imports": "error",
|
|
|
|
|
"open-pencil/no-inline-prompt-constants": "error",
|
|
|
|
|
"open-pencil/no-app-vue-core-barrel-imports": "error",
|
|
|
|
|
"open-pencil/no-direct-graph-emitter-subscriptions": "error",
|
|
|
|
|
"open-pencil/no-on-unmounted-in-composition-roots": "error",
|
|
|
|
|
"open-pencil/no-composable-state-wrappers": "error",
|
|
|
|
|
"open-pencil/prefer-vueuse-intervals": "error",
|
|
|
|
|
"open-pencil/prefer-vueuse-timeouts": "error",
|
|
|
|
|
"open-pencil/vue-component-file-pascal-case": "error",
|
|
|
|
|
"open-pencil/component-namespace-pascal-case": "error",
|
|
|
|
|
"open-pencil/non-component-source-directories-kebab-case": "error",
|
|
|
|
|
"open-pencil/no-component-root-sibling-folder": "error",
|
2026-05-05 23:13:18 +00:00
|
|
|
"open-pencil/no-flat-kiwi-modules": "error",
|
2026-05-06 11:27:21 +00:00
|
|
|
"open-pencil/no-top-level-prefixed-test-files": "error",
|
2026-05-18 15:41:01 +00:00
|
|
|
"open-pencil/no-sibling-domain-prefixed-files": "error",
|
|
|
|
|
"array-callback-return": "error",
|
|
|
|
|
"block-scoped-var": "error",
|
|
|
|
|
"default-case-last": "error",
|
|
|
|
|
"default-param-last": "error",
|
|
|
|
|
"no-array-constructor": "error",
|
|
|
|
|
"no-case-declarations": "error",
|
|
|
|
|
"no-caller": "error",
|
|
|
|
|
"no-constructor-return": "error",
|
|
|
|
|
"no-else-return": "error",
|
|
|
|
|
"no-empty-pattern": "error",
|
|
|
|
|
"no-eval": "error",
|
|
|
|
|
"no-extend-native": "error",
|
|
|
|
|
"no-extra-bind": "error",
|
|
|
|
|
"no-extra-label": "error",
|
|
|
|
|
"no-implied-eval": "error",
|
|
|
|
|
"no-iterator": "error",
|
|
|
|
|
"no-labels": "error",
|
|
|
|
|
"no-lone-blocks": "error",
|
|
|
|
|
"no-multi-str": "error",
|
|
|
|
|
"no-new": "error",
|
|
|
|
|
"no-new-wrappers": "error",
|
|
|
|
|
"no-object-constructor": "error",
|
|
|
|
|
"no-proto": "error",
|
|
|
|
|
"no-return-assign": "error",
|
|
|
|
|
"no-script-url": "error",
|
|
|
|
|
"no-self-compare": "error",
|
|
|
|
|
"no-sequences": "error",
|
|
|
|
|
"no-template-curly-in-string": "error",
|
|
|
|
|
"no-unmodified-loop-condition": "error",
|
|
|
|
|
"no-unneeded-ternary": "error",
|
|
|
|
|
"no-unused-expressions": "error",
|
|
|
|
|
"no-useless-assignment": "error",
|
|
|
|
|
"no-useless-call": "error",
|
|
|
|
|
"no-useless-computed-key": "error",
|
|
|
|
|
"no-useless-concat": "error",
|
|
|
|
|
"no-useless-constructor": "error",
|
|
|
|
|
"no-useless-rename": "error",
|
|
|
|
|
"no-useless-return": "error",
|
|
|
|
|
"prefer-numeric-literals": "error",
|
|
|
|
|
"prefer-object-has-own": "error",
|
|
|
|
|
"prefer-promise-reject-errors": "error",
|
|
|
|
|
"prefer-regex-literals": "error",
|
|
|
|
|
"prefer-rest-params": "error",
|
|
|
|
|
"prefer-spread": "error",
|
|
|
|
|
"symbol-description": "error",
|
|
|
|
|
"unicode-bom": "error",
|
|
|
|
|
"yoda": "error",
|
|
|
|
|
"typescript/adjacent-overload-signatures": "error",
|
|
|
|
|
"typescript/await-thenable": "error",
|
|
|
|
|
"typescript/ban-ts-comment": "error",
|
|
|
|
|
"typescript/ban-tslint-comment": "error",
|
|
|
|
|
"typescript/no-array-delete": "error",
|
|
|
|
|
"typescript/no-base-to-string": "error",
|
|
|
|
|
"typescript/no-confusing-non-null-assertion": "error",
|
|
|
|
|
"typescript/no-duplicate-enum-values": "error",
|
|
|
|
|
"typescript/no-duplicate-type-constituents": "error",
|
|
|
|
|
"typescript/no-extraneous-class": "error",
|
|
|
|
|
"typescript/no-extra-non-null-assertion": "error",
|
|
|
|
|
"typescript/no-for-in-array": "error",
|
|
|
|
|
"typescript/no-implied-eval": "error",
|
|
|
|
|
"typescript/no-invalid-void-type": "error",
|
|
|
|
|
"typescript/no-meaningless-void-operator": "error",
|
|
|
|
|
"typescript/no-misused-new": "error",
|
|
|
|
|
"typescript/no-misused-spread": "error",
|
|
|
|
|
"typescript/no-mixed-enums": "error",
|
|
|
|
|
"typescript/no-non-null-asserted-nullish-coalescing": "error",
|
|
|
|
|
"typescript/no-non-null-asserted-optional-chain": "error",
|
|
|
|
|
"typescript/no-redundant-type-constituents": "error",
|
|
|
|
|
"typescript/no-this-alias": "error",
|
|
|
|
|
"typescript/no-unnecessary-parameter-property-assignment": "error",
|
|
|
|
|
"typescript/no-unnecessary-qualifier": "error",
|
|
|
|
|
"typescript/no-unnecessary-type-constraint": "error",
|
|
|
|
|
"typescript/no-unsafe-enum-comparison": "error",
|
|
|
|
|
"typescript/no-unsafe-function-type": "error",
|
|
|
|
|
"typescript/no-unsafe-unary-minus": "error",
|
|
|
|
|
"typescript/no-useless-default-assignment": "error",
|
|
|
|
|
"typescript/no-useless-empty-export": "error",
|
|
|
|
|
"typescript/no-var-requires": "error",
|
|
|
|
|
"typescript/no-wrapper-object-types": "error",
|
|
|
|
|
"typescript/only-throw-error": "error",
|
|
|
|
|
"typescript/prefer-as-const": "error",
|
|
|
|
|
"typescript/prefer-find": "error",
|
|
|
|
|
"typescript/prefer-function-type": "error",
|
|
|
|
|
"typescript/prefer-promise-reject-errors": "error",
|
|
|
|
|
"typescript/prefer-reduce-type-parameter": "error",
|
|
|
|
|
"typescript/prefer-return-this-type": "error",
|
|
|
|
|
"typescript/prefer-ts-expect-error": "error",
|
|
|
|
|
"typescript/require-array-sort-compare": "error",
|
|
|
|
|
"typescript/triple-slash-reference": "error",
|
|
|
|
|
"import/no-absolute-path": "error",
|
|
|
|
|
"import/no-amd": "error",
|
|
|
|
|
"import/no-commonjs": "error",
|
|
|
|
|
"import/no-dynamic-require": "error",
|
|
|
|
|
"import/no-empty-named-blocks": "error",
|
|
|
|
|
"import/no-webpack-loader-syntax": "error",
|
|
|
|
|
"promise/no-callback-in-promise": "error",
|
|
|
|
|
"promise/no-multiple-resolved": "error",
|
|
|
|
|
"promise/no-new-statics": "error",
|
|
|
|
|
"promise/no-promise-in-callback": "error",
|
|
|
|
|
"promise/no-return-in-finally": "error",
|
|
|
|
|
"promise/no-return-wrap": "error",
|
|
|
|
|
"promise/valid-params": "error",
|
|
|
|
|
"node/no-exports-assign": "error",
|
|
|
|
|
"node/no-new-require": "error",
|
|
|
|
|
"node/no-path-concat": "error",
|
|
|
|
|
"oxc/approx-constant": "error",
|
|
|
|
|
"oxc/missing-throw": "error",
|
|
|
|
|
"oxc/no-accumulating-spread": "error",
|
|
|
|
|
"oxc/no-async-endpoint-handlers": "error",
|
|
|
|
|
"oxc/no-map-spread": "error",
|
|
|
|
|
"oxc/number-arg-out-of-range": "error",
|
|
|
|
|
"oxc/uninvoked-array-callback": "error",
|
|
|
|
|
"unicorn/consistent-assert": "error",
|
|
|
|
|
"unicorn/consistent-date-clone": "error",
|
|
|
|
|
"unicorn/consistent-empty-array-spread": "error",
|
|
|
|
|
"unicorn/consistent-template-literal-escape": "error",
|
|
|
|
|
"unicorn/custom-error-definition": "error",
|
|
|
|
|
"unicorn/error-message": "error",
|
|
|
|
|
"unicorn/new-for-builtins": "error",
|
|
|
|
|
"unicorn/no-abusive-eslint-disable": "error",
|
|
|
|
|
"unicorn/no-accessor-recursion": "error",
|
|
|
|
|
"unicorn/no-anonymous-default-export": "error",
|
|
|
|
|
"unicorn/no-array-method-this-argument": "error",
|
|
|
|
|
"unicorn/no-await-in-promise-methods": "error",
|
|
|
|
|
"unicorn/no-console-spaces": "error",
|
|
|
|
|
"unicorn/no-document-cookie": "error",
|
|
|
|
|
"unicorn/no-empty-file": "error",
|
|
|
|
|
"unicorn/no-instanceof-builtins": "error",
|
|
|
|
|
"unicorn/no-invalid-fetch-options": "error",
|
|
|
|
|
"unicorn/no-invalid-remove-event-listener": "error",
|
|
|
|
|
"unicorn/no-magic-array-flat-depth": "error",
|
|
|
|
|
"unicorn/no-negation-in-equality-check": "error",
|
|
|
|
|
"unicorn/no-new-array": "error",
|
|
|
|
|
"unicorn/no-new-buffer": "error",
|
|
|
|
|
"unicorn/no-single-promise-in-promise-methods": "error",
|
|
|
|
|
"unicorn/no-static-only-class": "error",
|
|
|
|
|
"unicorn/no-thenable": "error",
|
|
|
|
|
"unicorn/no-this-assignment": "error",
|
|
|
|
|
"unicorn/no-unnecessary-array-flat-depth": "error",
|
|
|
|
|
"unicorn/no-unnecessary-array-splice-count": "error",
|
|
|
|
|
"unicorn/no-unnecessary-slice-end": "error",
|
|
|
|
|
"unicorn/no-unreadable-iife": "error",
|
|
|
|
|
"unicorn/no-useless-collection-argument": "error",
|
|
|
|
|
"unicorn/no-useless-error-capture-stack-trace": "error",
|
|
|
|
|
"unicorn/no-useless-iterator-to-array": "error",
|
|
|
|
|
"unicorn/no-useless-length-check": "error",
|
|
|
|
|
"unicorn/no-useless-promise-resolve-reject": "error",
|
|
|
|
|
"unicorn/no-useless-spread": "error",
|
|
|
|
|
"unicorn/no-useless-switch-case": "error",
|
|
|
|
|
"unicorn/prefer-array-find": "error",
|
|
|
|
|
"unicorn/prefer-array-flat": "error",
|
|
|
|
|
"unicorn/prefer-array-flat-map": "error",
|
|
|
|
|
"unicorn/prefer-array-index-of": "error",
|
|
|
|
|
"unicorn/prefer-array-some": "error",
|
|
|
|
|
"unicorn/prefer-blob-reading-methods": "error",
|
|
|
|
|
"unicorn/prefer-classlist-toggle": "error",
|
|
|
|
|
"unicorn/prefer-date-now": "error",
|
|
|
|
|
"unicorn/prefer-event-target": "error",
|
|
|
|
|
"unicorn/prefer-keyboard-event-key": "error",
|
|
|
|
|
"unicorn/prefer-modern-dom-apis": "error",
|
|
|
|
|
"unicorn/prefer-negative-index": "error",
|
|
|
|
|
"unicorn/prefer-native-coercion-functions": "error",
|
|
|
|
|
"unicorn/prefer-object-from-entries": "error",
|
|
|
|
|
"unicorn/prefer-optional-catch-binding": "error",
|
|
|
|
|
"unicorn/prefer-prototype-methods": "error",
|
|
|
|
|
"unicorn/prefer-regexp-test": "error",
|
|
|
|
|
"unicorn/prefer-set-size": "error",
|
|
|
|
|
"unicorn/prefer-string-slice": "error",
|
|
|
|
|
"unicorn/prefer-string-trim-start-end": "error",
|
|
|
|
|
"unicorn/prefer-structured-clone": "error",
|
|
|
|
|
"unicorn/prefer-type-error": "error",
|
|
|
|
|
"unicorn/require-array-join-separator": "error",
|
|
|
|
|
"unicorn/require-number-to-fixed-digits-argument": "error",
|
|
|
|
|
"unicorn/throw-new-error": "error",
|
|
|
|
|
"vue/no-deprecated-data-object-declaration": "error",
|
|
|
|
|
"vue/no-deprecated-delete-set": "error",
|
|
|
|
|
"vue/no-deprecated-events-api": "error",
|
|
|
|
|
"vue/no-deprecated-model-definition": "error",
|
|
|
|
|
"vue/no-deprecated-vue-config-keycodes": "error",
|
|
|
|
|
"vue/no-this-in-before-route-enter": "error",
|
|
|
|
|
"vue/return-in-computed-property": "error",
|
|
|
|
|
"unicorn/require-post-message-target-origin": "error",
|
|
|
|
|
"unicorn/prefer-set-has": "error",
|
|
|
|
|
"unicorn/prefer-modern-math-apis": "error",
|
|
|
|
|
"unicorn/prefer-node-protocol": "error",
|
|
|
|
|
"unicorn/prefer-number-properties": "error",
|
|
|
|
|
"prefer-exponentiation-operator": "error",
|
|
|
|
|
"no-promise-executor-return": "error",
|
|
|
|
|
"typescript/no-empty-object-type": "error",
|
|
|
|
|
"typescript/return-await": "error",
|
|
|
|
|
"typescript/restrict-plus-operands": "error",
|
|
|
|
|
"unicorn/prefer-includes": "error",
|
|
|
|
|
"no-loop-func": "error",
|
|
|
|
|
"typescript/no-dynamic-delete": "error"
|
Add oxlint, oxfmt, typescript-go
- oxlint with react, react-hooks, typescript, import, unicorn plugins
- oxfmt (no trailing commas, single quotes, sorted imports)
- tsgo (typescript-go native preview) for fast typechecking
- Fix all lint warnings: non-null assertions, unused expressions, stale closures
- Scripts: lint, format, typecheck, check
2026-02-27 12:52:04 +00:00
|
|
|
},
|
|
|
|
|
"overrides": [
|
2026-05-01 14:11:50 +00:00
|
|
|
{
|
2026-05-18 15:41:01 +00:00
|
|
|
"files": [
|
|
|
|
|
"src/**/*.ts",
|
|
|
|
|
"packages/*/src/**/*.ts"
|
|
|
|
|
],
|
2026-05-01 14:11:50 +00:00
|
|
|
"rules": {
|
|
|
|
|
"open-pencil/no-useless-pass-through-wrappers": "error"
|
|
|
|
|
}
|
|
|
|
|
},
|
2026-03-16 10:54:07 +00:00
|
|
|
{
|
2026-05-18 15:41:01 +00:00
|
|
|
"files": [
|
|
|
|
|
"**/kiwi/kiwi-schema/**"
|
|
|
|
|
],
|
Fix all lint, typecheck, and formatting issues
- 0 lint warnings (was 66), 0 type errors (was 30+)
- Add typed interfaces for Paint.stops/transform, Effect.blendMode,
NodeChange.strokeCap/strokeJoin/dashPattern in kiwi codec
- Add CompiledSchema.encodePaint/encodeNodeChange methods
- Remove all no-explicit-any: use Window declaration merging for
queryLocalFonts, showOpenFilePicker, showSaveFilePicker
- Remove all non-null assertions: add guards, use ?. operator,
?? fallbacks throughout
- Add SceneGraph.copyProp typed helper for instance sync
- Suppress kiwi-schema lint warnings via oxlint override
- Remove unused imports, variables, parameters
- Use proper CanvasKit StrokeCap/StrokeJoin enums in renderer
- Run oxfmt with import sorting
2026-02-28 19:57:33 +00:00
|
|
|
"rules": {
|
|
|
|
|
"typescript/no-explicit-any": "off",
|
2026-03-09 10:18:08 +00:00
|
|
|
"typescript/no-non-null-assertion": "off",
|
2026-03-12 10:07:43 +00:00
|
|
|
"typescript/no-implied-eval": "off",
|
2026-03-09 10:18:08 +00:00
|
|
|
"typescript/prefer-for-of": "off",
|
|
|
|
|
"typescript/prefer-optional-chain": "off",
|
|
|
|
|
"typescript/consistent-type-imports": "off",
|
|
|
|
|
"typescript/no-unnecessary-condition": "off",
|
|
|
|
|
"import/no-mutable-exports": "off",
|
2026-03-16 10:54:07 +00:00
|
|
|
"complexity": "off",
|
|
|
|
|
"prefer-const": "off",
|
|
|
|
|
"eqeqeq": "off",
|
|
|
|
|
"radix": "off"
|
Fix all lint, typecheck, and formatting issues
- 0 lint warnings (was 66), 0 type errors (was 30+)
- Add typed interfaces for Paint.stops/transform, Effect.blendMode,
NodeChange.strokeCap/strokeJoin/dashPattern in kiwi codec
- Add CompiledSchema.encodePaint/encodeNodeChange methods
- Remove all no-explicit-any: use Window declaration merging for
queryLocalFonts, showOpenFilePicker, showSaveFilePicker
- Remove all non-null assertions: add guards, use ?. operator,
?? fallbacks throughout
- Add SceneGraph.copyProp typed helper for instance sync
- Suppress kiwi-schema lint warnings via oxlint override
- Remove unused imports, variables, parameters
- Use proper CanvasKit StrokeCap/StrokeJoin enums in renderer
- Run oxfmt with import sorting
2026-02-28 19:57:33 +00:00
|
|
|
}
|
2026-03-09 07:11:11 +00:00
|
|
|
},
|
|
|
|
|
{
|
2026-05-18 15:41:01 +00:00
|
|
|
"files": [
|
|
|
|
|
"packages/cli/src/**",
|
|
|
|
|
"packages/mcp/src/**"
|
|
|
|
|
],
|
2026-03-16 10:54:07 +00:00
|
|
|
"rules": {
|
|
|
|
|
"no-console": "off"
|
|
|
|
|
}
|
|
|
|
|
},
|
Lint CLI code: no-raw-console-format rule, fix all violations
Add no-raw-console-format lint rule for CLI commands — bans template
literals and string concatenation in console.log, forcing use of
agentfmt helpers (bold, dim, kv, entity, fmtTree, fmtList, etc.).
Extend lint target to include packages/cli/src/.
Fix all 22 lint errors in CLI code:
- Replace string concatenation with agentfmt (clusters, typography, variables)
- Mark optional CLI args as required: false (citty type accuracy)
- Remove unnecessary type assertions and optional chains
- Merge duplicate @open-pencil/core imports in headless.ts
- Extract exportViaApp/exportFromFile to reduce export.ts complexity
- Remove unused imports (formatType, printError)
- void runMain() for floating promise
2026-03-09 09:54:53 +00:00
|
|
|
{
|
2026-05-18 15:41:01 +00:00
|
|
|
"files": [
|
|
|
|
|
"packages/cli/src/commands/**"
|
|
|
|
|
],
|
Lint CLI code: no-raw-console-format rule, fix all violations
Add no-raw-console-format lint rule for CLI commands — bans template
literals and string concatenation in console.log, forcing use of
agentfmt helpers (bold, dim, kv, entity, fmtTree, fmtList, etc.).
Extend lint target to include packages/cli/src/.
Fix all 22 lint errors in CLI code:
- Replace string concatenation with agentfmt (clusters, typography, variables)
- Mark optional CLI args as required: false (citty type accuracy)
- Remove unnecessary type assertions and optional chains
- Merge duplicate @open-pencil/core imports in headless.ts
- Extract exportViaApp/exportFromFile to reduce export.ts complexity
- Remove unused imports (formatType, printError)
- void runMain() for floating promise
2026-03-09 09:54:53 +00:00
|
|
|
"rules": {
|
|
|
|
|
"open-pencil/no-raw-console-format": "error"
|
|
|
|
|
}
|
2026-05-05 23:05:02 +00:00
|
|
|
},
|
2026-05-05 23:33:31 +00:00
|
|
|
{
|
|
|
|
|
"files": [
|
|
|
|
|
"tests/e2e/perf/basic.spec.ts",
|
|
|
|
|
"tests/e2e/viewport/zoom-pan.spec.ts",
|
|
|
|
|
"tests/engine/visual-*.ts"
|
|
|
|
|
],
|
|
|
|
|
"rules": {
|
|
|
|
|
"no-console": "off"
|
|
|
|
|
}
|
|
|
|
|
},
|
2026-05-05 23:05:02 +00:00
|
|
|
{
|
2026-05-18 15:41:01 +00:00
|
|
|
"files": [
|
|
|
|
|
"scripts/**/*.ts"
|
|
|
|
|
],
|
2026-05-05 23:05:02 +00:00
|
|
|
"rules": {
|
2026-05-06 13:41:40 +00:00
|
|
|
"no-console": "off"
|
2026-05-05 23:05:02 +00:00
|
|
|
}
|
2026-05-18 15:41:01 +00:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"files": [
|
|
|
|
|
"packages/core/src/io/formats/fig/export.ts",
|
|
|
|
|
"packages/core/src/kiwi/fig/parse/worker.ts"
|
|
|
|
|
],
|
|
|
|
|
"rules": {
|
|
|
|
|
"unicorn/require-post-message-target-origin": "off"
|
|
|
|
|
}
|
Add oxlint, oxfmt, typescript-go
- oxlint with react, react-hooks, typescript, import, unicorn plugins
- oxfmt (no trailing commas, single quotes, sorted imports)
- tsgo (typescript-go native preview) for fast typechecking
- Fix all lint warnings: non-null assertions, unused expressions, stale closures
- Scripts: lint, format, typecheck, check
2026-02-27 12:52:04 +00:00
|
|
|
}
|
|
|
|
|
],
|
2026-05-18 15:41:01 +00:00
|
|
|
"ignorePatterns": [
|
|
|
|
|
"node_modules",
|
|
|
|
|
"dist",
|
|
|
|
|
"desktop",
|
|
|
|
|
"*.config.*"
|
|
|
|
|
],
|
|
|
|
|
"categories": {
|
|
|
|
|
"correctness": "error"
|
|
|
|
|
}
|
Add oxlint, oxfmt, typescript-go
- oxlint with react, react-hooks, typescript, import, unicorn plugins
- oxfmt (no trailing commas, single quotes, sorted imports)
- tsgo (typescript-go native preview) for fast typechecking
- Fix all lint warnings: non-null assertions, unused expressions, stale closures
- Scripts: lint, format, typecheck, check
2026-02-27 12:52:04 +00:00
|
|
|
}
|