Danila Poyarkov
921d2d35c5
Export IS_BROWSER from core, replace all raw typeof window checks
...
- Add IS_BROWSER constant to core/constants.ts, rewrite IS_TAURI to use it
- Replace 9 raw 'typeof window' checks across canvaskit, fig-export,
figma-api, fig-file, fonts, SafariBanner, use-chat
- Promote no-typeof-window-check lint rule from warn to error
- Extract array mutation helpers (updateArrayItem, removeArrayItem,
toggleArrayVisibility) into useMultiProps — DRY up FillSection and
StrokeSection (removes 20+ duplicated for-loops)
2026-03-16 14:05:24 +03:00
Danila Poyarkov
c06ed32990
Harden linting: add eqeqeq, prefer-const, radix, no-console, no-typeof-window-check
...
New built-in rules:
- eqeqeq (null-safe) — prevent loose equality coercions
- prefer-const — catch unused let declarations
- radix — require parseInt radix parameter
- no-console — warn on console.log in app code (CLI/MCP exempted)
New custom rule:
- no-typeof-window-check — flag raw typeof window checks, prefer
IS_BROWSER/IS_TAURI constants (warn-level, constants.ts + fonts.ts
exempted)
Fix 4 violations caught by new rules.
2026-03-16 13:54:07 +03:00
Danila Poyarkov
dfb050538c
Spawn MCP server as subprocess instead of SSR module
...
Replace ssrLoadModule hack with simple child_process.spawn.
Same approach as production (Tauri sidecar) — just run the MCP
server entry point directly. No re-evaluation on HMR, no
WebSocket reconnect storms, no globalThis guards.
2026-03-15 16:42:49 +03:00
Anton A S
160d5474c9
Fix lint errors: eliminate all any casts, fix complexity and nested ternaries
2026-03-13 10:20:54 +03:00
Danila Poyarkov
353c867d03
Add no-silent-catch lint rule, fix silent failures
...
- New oxlint rule: open-pencil/no-silent-catch — errors on empty catch blocks
- Replace all 8 empty catch blocks with console.warn() logging
- Add worker timeout (30s) and main-thread fallback for .fig parsing
- Fix null crash in renderer filter/picture cache cleanup
- Buffer copy before worker transfer for safe fallback
2026-03-13 10:03:12 +03:00
Danila Poyarkov
59981709ba
Reduce cyclomatic complexity below 20 in all core functions
...
Refactor 24 complex functions across 14 files by extracting
dispatch branches and property-group handlers into focused helpers.
kiwi/kiwi-convert.ts (4 functions, was 22-81):
- nodeChangeToProps → 6 property-group converters
- convertOverrideToProps → 5 override applicators
- importStyleRuns → 3 style-run helpers
- mapNodeType → NODE_TYPE_MAP lookup table
kiwi/instance-overrides.ts (3 functions, was 28-44):
- applyDerivedSymbolData → resolveDsd* helpers
- applyComponentProperties → assignment/override applicators
- propagateOverridesTransitively → clone/sync helpers
kiwi/fig-import.ts (2 functions, was 34-40):
- importNodeChanges → buildChangeMaps, importPages, etc.
- importVariables → importCollections, resolveVariableType, etc.
render/export-jsx.ts (2 functions, was 70-85):
- collectProps → property-category extractors
- collectTailwindClasses → Tailwind class-group extractors
render/renderer.ts: propsToOverrides (78) → style-category helpers
renderer/scene.ts: renderNode (46), renderShapeUncached (30) →
phase extractors (transforms, content, children, strokes)
renderer/renderer.ts: buildParagraph (34) → buildTruncateOpts,
addStyledRuns
svg-export.ts: split into svg-export.ts + svg-export-defs.ts +
svg-export-paths.ts; renderNode/renderTextNode/nodeShapeElements
all reduced via helper extraction
kiwi-serialize.ts: sceneNodeToKiwi (44) → 6 property serializers
clipboard.ts: importClipboardNodes (36) → 5 focused helpers
scene-graph.ts: hitTestChildren (31) → containsPoint,
hitTestOpaqueContainer, hitTestTransparentContainer
tools/analyze.ts: serializeNodeProps (23) → 4 prop serializers
2026-03-09 13:40:57 +03:00
Danila Poyarkov
f3eac5ac8b
Lint all packages: fix 193 errors across core, mcp, acp
...
Extend lint coverage from src/ to all packages (178 files, 140 rules).
Core (37 files):
- Remove 98 unnecessary conditions (dead ?./?? on non-nullish values)
- Remove 38 unnecessary type assertions (! and as casts)
- Convert 12 patterns to optional chain (a && a.b → a?.b)
- Fix 10 consistent-type-imports (merge duplicates, inline type keyword)
- Add parentheses to 16 nested ternaries
- Convert 4 indexed for-loops to for-of
- Merge 4 duplicate import statements
MCP (3 files):
- Replace typeof undefined check with 'in' operator
- Capture graph in local const to avoid ! assertions
ACP (1 file):
- Fix 5 TypeScript errors (type predicates, object shapes, dead code)
- Remove unnecessary template expression
Vendored kiwi-schema gets broader rule overrides to avoid touching it.
Core complexity stays as warning (24 functions over limit).
2026-03-09 13:18:08 +03:00
Danila Poyarkov
d9154ef29d
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 12:54:53 +03:00
Danila Poyarkov
96784e2895
Enforce complexity limit as error
2026-03-09 11:31:36 +03:00
Danila Poyarkov
4abc73eb47
Add max-lines, complexity, and more lint rules
2026-03-09 10:11:11 +03:00
Danila Poyarkov
2f06c65c7c
Revert lint plugin to .js (oxlint uses Node.js internally), add new rules
...
Oxlint's JS plugin loader uses Node.js, not Bun — .ts fails in CI
with ERR_UNKNOWN_FILE_EXTENSION.
New rules:
- no-hand-rolled-color: flags rgba()/rgb() in template literals outside
color.ts — use colorToCSS()/colorToHex() helpers instead
- typescript/no-unnecessary-boolean-literal-compare
- typescript/no-unnecessary-template-expression
- typescript/no-unnecessary-type-arguments
- unicorn/no-useless-fallback-in-spread
- unicorn/no-length-as-slice-end
- unicorn/no-unnecessary-await
- unicorn/prefer-string-starts-ends-with
Fixed violations: visible !== false → fill.visible in analyze.ts,
removed ?? {} fallbacks in style-runs.ts spread.
2026-03-09 10:05:18 +03:00
Danila Poyarkov
5ef7111998
Rename lint plugin to .ts
2026-03-09 09:46:45 +03:00
Danila Poyarkov
cd614ef8f7
Add custom JS lint rules, replace inline types with named imports
...
Three oxlint JS plugin rules in lint/plugin.js:
- no-inline-named-types: configurable shape→name map catches inline
{ x: number; y: number } etc. and suggests Vector, Color, GUID,
Rect, Matrix from @open-pencil/core
- no-structuredclone-scene-arrays: flags structuredClone on
fills/strokes/effects — use typed copy helpers instead
- no-math-random: bans Math.random() in favor of crypto
Fixed 40 violations across 13 files: replaced inline type literals
with named imports, switched figma-api.ts structuredClone calls to
copyFills/copyStrokes/copyEffects.
2026-03-09 09:41:28 +03:00
Danila Poyarkov
4969447669
Add vue/no-multiple-slot-args rule
2026-03-09 09:20:01 +03:00
Danila Poyarkov
17faf4df93
Add strict lint rules to catch AI-generated slop at compile time
...
New rules:
- typescript/no-unnecessary-condition: catches redundant ?., ??, and
always-true/false branches (22 violations fixed)
- typescript/consistent-return: mixed return/no-return in functions
- typescript/no-unnecessary-type-parameters: unused generic params
- typescript/prefer-for-of: use for-of instead of indexed loops
- unicorn/no-nested-ternary: forbid nested ternaries
- unicorn/consistent-existence-index-check: !== -1 over >= 0
- no-empty-function: no empty function bodies
Fixed all 32 violations: removed unnecessary optional chaining on
non-nullish values, tightened Record types to Partial<Record> where
index access can return undefined, replaced nested ternary with
lookup table, added exhaustive default cases.
2026-03-09 09:16:07 +03:00
Danila Poyarkov
f96fffb83f
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 09:05:04 +03:00
Danila Poyarkov
9c110bff92
Add Vue linting rules and fix all violations
...
Enable 12 vue/ rules in oxlint: lifecycle, props, emits, imports.
Convert 9 components from `const props = defineProps()` to
destructured form (Vue 3.5+ reactive destructuring).
2026-03-08 23:08:27 +03:00
Danila Poyarkov
7a334268d0
Fix all type-aware lint warnings
...
Add void prefix to 23 fire-and-forget promises across 10 files.
Fix no-base-to-string in bridge.ts by using Buffer.from().toString().
Promote no-floating-promises from warn to error.
2026-03-08 23:04:44 +03:00
Danila Poyarkov
fa3d7b8a8f
Enable type-aware linting with tsgo in oxlint
...
Add oxlint-tsgolint dependency and --type-aware --type-check flags.
This replaces the separate tsgo --noEmit step — oxlint now handles
both linting and type checking in a single pass.
Add typescript/no-floating-promises as a warning rule.
2026-03-08 23:02:25 +03:00
Danila Poyarkov
18609e00c3
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 22:57:33 +03:00
Danila Poyarkov
23f00189e8
Rename src-tauri → desktop, symlink for CLI compat
2026-02-28 08:10:09 +03:00
Danila Poyarkov
323a1f90c4
Migrate React → Vue 3 + VueUse + Reka UI
...
- Vue 3 SFC components with <script setup>
- Reactive store (Vue reactivity) replacing React refs/state
- Composables: useCanvas, useCanvasInput, useKeyboard
- Components: EditorCanvas, LayersPanel, PropertiesPanel, Toolbar
- Floating toolbar (Figma UI3 style) with pill shape + shadow
- Properties panel with Design/Prototype tabs + zoom display
- Sections: Position, Rotation, Layout, Appearance, Fill, Stroke, Effects, Export
- CSS custom properties for theming (--panel-bg, --border, --accent, etc.)
- Add Figma UI3 CDP inspection findings (toolbar, panels, sections)
2026-02-27 21:25:31 +03:00
Danila Poyarkov
c123dad50c
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 15:52:55 +03:00