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 artboardframe— 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:
- 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】 - 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
pagesarray 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 bybuildLayerTree() - The hierarchy is assembled bottom-up: layers → artboards → pages → sketch, then serialized to
.sketchformat
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →