How Artboards and Pages Are Structured in Sketch Documents Generated by HKUDS/CLI-Anything

HKUDS/CLI-Anything organizes Sketch documents in a hierarchical tree: Sketch → Page → Artboard → Layers, with each level created programmatically via the sketch-constructor library.

The sketch-harness CLI tool in the HKUDS/CLI-Anything repository generates .sketch files from JSON specifications. Understanding this hierarchy is essential for customizing document generation or debugging layout issues. The implementation relies on the sketch-constructor npm package to model the Sketch file format.

The Four-Level Document Hierarchy

1. Sketch — The Root Container

The Sketch class represents the entire .sketch file. It serves as the root object that aggregates all pages and handles final serialization to ZIP format.

In sketch/agent-harness/src/builder.js, the builder instantiates a single Sketch object at the start of processing, then accumulates pages before writing output【/cache/repos/github.com/HKUDS/CLI-Anything/main/sketch/agent-harness/src/builder.js#L76-L77】.

2. Page — Logical Grouping of Artboards

Each Page object groups related artboards. The builder creates pages by iterating over the pages array in the input JSON specification:

// From sketch/agent-harness/src/builder.js
for (const pageSpec of spec.pages) {
  const page = new Page({ name: pageSpec.name || 'Page' });
  // ...
}

This loop at lines 39-41 creates a Page instance for each entry, applying a default name if none is provided【/cache/repos/github.com/HKUDS/CLI-Anything/main/sketch/agent-harness/src/builder.js#L39-L41】.

3. Artboard — The Canvas for UI Design

Inside each page, the builder creates Artboard objects by iterating over pageSpec.artboards. The constructor receives:

  • name — identifier for the artboard
  • frame — positioning and dimensions (x, y, width, height)
  • backgroundColor — default fill color
// From sketch/agent-harness/src/builder.js
for (const abSpec of pageSpec.artboards) {
  const artboard = new Artboard({
    name: abSpec.name || 'Artboard',
    frame: {
      x: 0,
      y: 0,
      width: abSpec.width || 375,
      height: abSpec.height || 812,
    },
    backgroundColor: abSpec.backgroundColor || '#FFFFFF',
  });
  // ...
}

This implementation at lines 42-50 uses standard mobile viewport defaults (375×812) when dimensions are unspecified【/cache/repos/github.com/HKUDS/CLI-Anything/main/sketch/agent-harness/src/builder.js#L42-L50】.

4. Layers — Visual Elements Within Artboards

Each artboard receives a layer tree constructed by buildLayerTree(). Layers are attached using artboard.addLayer(layer):

// Layer attachment from sketch/agent-harness/src/builder.js
const layers = buildLayerTree(abSpec.layers, imageData);
for (const layer of layers) {
  artboard.addLayer(layer);
}

Lines 67-71 demonstrate how the layer hierarchy is flattened and appended to the artboard【/cache/repos/github.com/HKUDS/CLI-Anything/main/sketch/agent-harness/src/builder.js#L67-L71】.

Assembly and Serialization Flow

The builder completes the hierarchy through explicit parent-child attachment:

  1. Artboard → Page: page.addArtboard(artboard) at lines 73-74【/cache/repos/github.com/HKUDS/CLI-Anything/main/sketch/agent-harness/src/builder.js#L73-L74】
  2. Page → Sketch: sketch.addPage(page) at lines 76-77【/cache/repos/github.com/HKUDS/CLI-Anything/main/sketch/agent-harness/src/builder.js#L76-L77】

The final Sketch object serializes to a ZIP-packed .sketch file compatible with Sketch.app.

Visual Hierarchy Summary


Sketch (root document)
 └─ Page (name: "Login Flow")
      └─ Artboard (name: "iPhone 14", frame, backgroundColor)
           ├─ Layer (Rectangle: background)
           ├─ Layer (Text: title)
           └─ Layer (Symbol: button)

Key Source Files in HKUDS/CLI-Anything

File Purpose
sketch/agent-harness/src/builder.js Core orchestrator: parses JSON, instantiates Sketch/Page/Artboard objects, manages layer trees, writes .sketch output
sketch/agent-harness/src/cli.js CLI entry point; handles argument parsing (-i input, -o output) and delegates to builder
sketch/agent-harness/package.json Declares sketch-constructor dependency providing Sketch, Page, Artboard, and layer classes

Complete Builder Implementation

// Simplified excerpt from sketch/agent-harness/src/builder.js
const { Sketch, Page, Artboard } = require('sketch-constructor');

async function buildSketch(spec, imageData) {
  const sketch = new Sketch();
  
  for (const pageSpec of spec.pages) {
    const page = new Page({ name: pageSpec.name || 'Page' });
    
    for (const abSpec of pageSpec.artboards) {
      const artboard = new Artboard({
        name: abSpec.name || 'Artboard',
        frame: {
          x: 0,
          y: 0,
          width: abSpec.width || 375,
          height: abSpec.height || 812,
        },
        backgroundColor: abSpec.backgroundColor || '#FFFFFF',
      });
      
      const layers = buildLayerTree(abSpec.layers, imageData);
      for (const layer of layers) {
        artboard.addLayer(layer);
      }
      
      page.addArtboard(artboard);
    }
    
    sketch.addPage(page);
  }
  
  return sketch;
}

CLI Usage Example


# Generate Sketch document from JSON specification

node sketch/agent-harness/src/cli.js build \
  -i examples/login-page.json \
  -o output/login-page.sketch

Summary

  • Sketch objects act as the root container for all document content in HKUDS/CLI-Anything
  • Page instances group related artboards and are created from the pages array in input JSON
  • Artboard objects define design canvases with explicit frames and background colors, defaulting to 375×812 mobile dimensions
  • Layers attach to artboards via addLayer() after construction by buildLayerTree()
  • The hierarchy is assembled bottom-up: layers → artboards → pages → sketch, then serialized to .sketch format

Frequently Asked Questions

What library does HKUDS/CLI-Anything use to create Sketch files?

The repository uses sketch-constructor, a Node.js library that provides JavaScript classes matching the Sketch file format specification. This dependency is declared in sketch/agent-harness/package.json and exposes Sketch, Page, Artboard, and various layer types.

Can I customize the default artboard dimensions?

Yes. The builder in src/builder.js falls back to 375×812 only when abSpec.width or abSpec.height are omitted【/cache/repos/github.com/HKUDS/CLI-Anything/main/sketch/agent-harness/src/builder.js#L42-L50】. Provide explicit dimensions in your JSON specification to override these mobile defaults.

How are layers positioned within an artboard?

Layers are constructed by buildLayerTree() using coordinates relative to the artboard's origin. The function processes abSpec.layers from the input JSON and returns layer objects that are then attached via artboard.addLayer(layer)【/cache/repos/github.com/HKUDS/CLI-Anything/main/sketch/agent-harness/src/builder.js#L67-L71】.

Does the builder support multiple pages per document?

Yes. The outer loop in src/builder.js iterates over spec.pages and creates a Page instance for each array element, attaching all to the single Sketch root【/cache/repos/github.com/HKUDS/CLI-Anything/main/sketch/agent-harness/src/builder.js#L39-L41】【/cache/repos/github.com/HKUDS/CLI-Anything/main/sketch/agent-harness/src/builder.js#L76-L77】.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →