9.5 KiB
tooling Specification
Purpose
Build and development tooling. Vite 7 build system, oxlint linting, oxfmt formatting, typescript-go type checking, and Tailwind CSS 4 integration.
Requirements
Requirement: Vite 7 build system
The project SHALL use Vite 7 as the build tool with dev server at port 1420 and HMR support. Documentation lives in packages/docs/ as @open-pencil/docs workspace package with its own dev/build/preview scripts.
Scenario: Dev server
- WHEN
bun run devis executed - THEN Vite dev server starts at http://localhost:1420 with hot module replacement
Scenario: Docs dev
- WHEN
cd packages/docs && bun run devis executed - THEN VitePress dev server starts for the documentation site
Scenario: Docs build
- WHEN
cd packages/docs && bun run buildis executed - THEN VitePress builds the documentation site to
packages/docs/.vitepress/dist/
Scenario: Docs preview
- WHEN
cd packages/docs && bun run previewis executed - THEN a static server previews the built documentation site
Requirement: oxlint linting
The project SHALL use oxlint for fast linting with project-specific configuration in oxlint.json.
Scenario: Lint check
- WHEN
bun run lintis executed - THEN oxlint checks src/ for issues based on oxlint.json rules
Requirement: oxfmt formatting
The project SHALL use oxfmt for code formatting with configuration in .oxfmtrc.json.
Scenario: Format code
- WHEN
bun run formatis executed - THEN oxfmt formats all files in src/ according to project rules
Requirement: typescript-go type checking
The project SHALL use typescript-go (tsgo) for type checking via bun run typecheck.
Scenario: Type check
- WHEN
bun run typecheckis executed - THEN tsgo --noEmit checks all TypeScript files for type errors
Requirement: Combined check command
bun run check SHALL run both lint and typecheck sequentially.
Scenario: Full check
- WHEN
bun run checkis executed - THEN oxlint runs first, then tsgo, and both must pass
Requirement: Tailwind CSS 4 integration
Tailwind CSS 4 SHALL be integrated via @tailwindcss/vite plugin.
Scenario: Tailwind classes work
- WHEN a Vue component uses Tailwind utility classes
- THEN the corresponding CSS is generated and applied
Requirement: @/ import alias
The project SHALL configure a @/ → src/ path alias in both vite.config.ts (resolve.alias) and tsconfig.json (paths). All cross-directory imports SHALL use @/ instead of relative ../ paths. Same-directory ./ imports are kept as-is.
Scenario: Import with alias
- WHEN a component in
src/components/imports fromsrc/engine/ - THEN the import uses
@/engine/instead of../../engine/
Requirement: Shared types module
Shared primitive types (Vector, Matrix, Rect) SHALL be defined in src/types.ts and imported across the codebase. Window API declarations (File System Access, queryLocalFonts) SHALL be in src/global.d.ts. Inline type duplicates SHALL be eliminated.
Scenario: Shared Vector type
- WHEN multiple files need a 2D point type
- THEN they import
Vectorfrom@/typesinstead of defining their own
Requirement: Zero lint and type errors
The codebase SHALL maintain 0 oxlint warnings and 0 tsgo type errors. bun run check SHALL pass cleanly.
Scenario: Clean check
- WHEN
bun run checkis executed - THEN both lint and typecheck pass with zero issues
Requirement: Bun workspace monorepo
The project SHALL use Bun workspaces with packages: root (app), packages/core (@open-pencil/core), packages/cli (@open-pencil/cli), packages/docs (@open-pencil/docs). The workspace is configured in the root package.json. CLI is runnable via bun open-pencil in the workspace.
Scenario: Workspace packages resolve
- WHEN the app imports from @open-pencil/core
- THEN Bun resolves it to packages/core/ via workspace linking
Requirement: npm publishing preparation
@open-pencil/core and @open-pencil/cli SHALL have proper package.json fields for npm publishing: name, version, description, exports, main, types, files, license, repository.
Requirement: Copy-paste detection
The project SHALL use jscpd for copy-paste detection. The bun run jscpd command SHALL scan for duplicated code blocks.
Scenario: Detect duplicates
- WHEN
bun run jscpdis run - THEN duplicated code blocks are reported with locations and percentages
Requirement: Kiwi serialization consolidation
Shared kiwi serialization logic (sceneNodeToKiwi, buildFigKiwi, parseFigKiwiChunks, decompressFigKiwiDataAsync) SHALL be extracted to packages/core/src/kiwi-serialize.ts. The app's src/kiwi/ SHALL re-export from core, eliminating the vendored kiwi-schema copy.
Scenario: Clipboard and fig-export share serialization
- WHEN clipboard.ts and fig-export.ts serialize nodes to kiwi
- THEN both use the shared kiwi-serialize.ts functions
Requirement: Test coverage script
The project SHALL include a test:coverage script for measuring code coverage.
Scenario: Run coverage
- WHEN
bun run test:coverageis run - THEN test coverage metrics are reported
Requirement: Unified tool definitions
The project SHALL define design tools once in packages/core/src/tools/ and adapt them for AI, CLI, and MCP contexts.
Scenario: Canonical tool schema
- WHEN a new tool is added
- THEN it is defined in
packages/core/src/tools/schema.tsas the single source of truth
Scenario: AI adapter
- WHEN AI assistant needs tool definitions
- THEN
packages/core/src/tools/ai-adapter.tsconverts schema to LLM-compatible format
Scenario: CLI adapter
- WHEN CLI commands use tools
- THEN citty commands consume tool schema directly
Scenario: MCP adapter (future)
- WHEN MCP server integration is added
- THEN MCP protocol adapter converts tool schema to MCP format
Requirement: Tool schema structure
Tool schemas SHALL be defined in packages/core/src/tools/schema.ts with name, description, parameters (with types and descriptions), and handler function.
Scenario: Tool definition format
- WHEN defining a tool in schema.ts
- THEN structure includes
{ name, description, parameters: { <param>: { type, description } }, handler: (params) => result }
Scenario: Type-safe parameters
- WHEN tool is invoked
- THEN parameters are validated against schema types
Requirement: Deduplication of AI tools
The project SHALL eliminate duplication in src/ai/tools.ts by using FigmaAPI.toJSON() for node serialization and shared color parsing from packages/core/src.
Scenario: Node serialization
- WHEN AI tool returns node data
- THEN it uses
figmaAPI.toJSON(node)instead of custom JSON builders
Scenario: Color parsing
- WHEN AI tool parses color input
- THEN it uses
parseColor()from core instead of inline regex
Scenario: Code reduction
- WHEN AI tools are refactored
- THEN 311 lines are removed from
src/ai/tools.tsvia deduplication
Requirement: Shared tool testing
The project SHALL provide test suites for tools in tests/engine/tools.test.ts, tests/engine/tools-ai-adapter.test.ts, and tests/engine/tools-cli.test.ts.
Scenario: Tool schema tests
- WHEN
tests/engine/tools.test.tsruns - THEN each tool schema is validated for structure and handler execution
Scenario: AI adapter tests
- WHEN
tests/engine/tools-ai-adapter.test.tsruns - THEN AI tool format conversion is verified
Scenario: CLI adapter tests
- WHEN
tests/engine/tools-cli.test.tsruns - THEN CLI command integration with tool schema is verified
Requirement: Tool handler execution
Tool handlers SHALL receive parameters as plain objects and return structured results (success/error, data).
Scenario: Successful tool execution
- WHEN tool handler is invoked with valid params
- THEN it returns
{ success: true, data: <result> }
Scenario: Tool execution error
- WHEN tool handler encounters error
- THEN it returns
{ success: false, error: "message" }
Requirement: Tool documentation
Each tool in schema.ts SHALL have clear description and parameter documentation for AI/human comprehension.
Scenario: Tool description
- WHEN AI queries available tools
- THEN description explains what the tool does (e.g., "Create a rectangle with specified dimensions and position")
Scenario: Parameter descriptions
- WHEN AI reads parameter schema
- THEN each parameter has type and description (e.g.,
width: { type: 'number', description: 'Rectangle width in pixels' })
Requirement: CHANGELOG
The project SHALL maintain a CHANGELOG.md in the root following Keep a Changelog conventions.
Scenario: Changelog exists
- WHEN user reads CHANGELOG.md
- THEN version history with categorized changes (Editor, CLI, File Format, etc.) is listed
Requirement: npm trusted publishing
Package configs SHALL include repository field and provenance: true for npm trusted publishing via GitHub Actions.
Scenario: Publish with provenance
- WHEN GitHub Actions release workflow runs
- THEN packages are published to npm with provenance attestation
Requirement: CI app deployment
The project SHALL have a GitHub Actions workflow (app.yml) for deploying the web app to app.openpencil.dev.
Scenario: App deploys on push
- WHEN code is pushed to main branch
- THEN GitHub Actions builds and deploys the app