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

> Understand how HKUDS/CLI-Anything structures Sketch artboards and pages within Sketch documents. Explore the hierarchical organization from Sketch to layers, generated programmatically.

- Repository: [✨Data Intelligence Lab@HKU✨/CLI-Anything](https://github.com/HKUDS/CLI-Anything)
- Tags: internals
- Published: 2026-08-16

---

**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`](https://github.com/HKUDS/CLI-Anything/blob/main/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:

```javascript
// 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

```javascript
// 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)`:

```javascript
// 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`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/sketch/agent-harness/package.json) | Declares `sketch-constructor` dependency providing `Sketch`, `Page`, `Artboard`, and layer classes |

## Complete Builder Implementation

```javascript
// 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

```bash

# 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`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/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`](https://github.com/HKUDS/CLI-Anything/blob/main/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】.