How the CLI-Anything Layout Engine Calculates Intrinsic Sizes for Different Layer Types

The CLI-Anything layout engine derives intrinsic sizes through a type-aware algorithm implemented in the intrinsicSize function, which processes spacers, explicit dimensions, text content, and type-specific defaults before returning a { width, height } object.

The HKUDS/CLI-Anything repository provides a declarative layout system for CLI applications, where each layer's natural dimensions must be determined before positioning logic executes. Understanding how the layout engine calculates these intrinsic sizes is essential for building responsive terminal interfaces. The core logic resides in sketch/agent-harness/src/layout.js and handles multiple layer types through a cascading priority system.

Core Layout Logic in sketch/agent-harness/src/layout.js

The layout engine centers around the intrinsicSize function, which computes natural dimensions for any layer before the positioning algorithms (vertical-stack, horizontal-stack, or absolute) arrange elements on screen. This function implements a five-step resolution strategy that checks layer type and explicit specifications in priority order.

The intrinsicSize Function Entry Point

Located in sketch/agent-harness/src/layout.js, the intrinsicSize function accepts layer configuration parameters and returns an object containing calculated width and height values. The algorithm processes layers through specific type checks, starting with spacers and proceeding through explicit dimensions, text estimation, and finally applying type-specific defaults.

Layer-Type-Specific Size Resolution

The engine distinguishes between layer types to apply appropriate sizing logic. Each category follows distinct rules for determining natural dimensions when explicit values are absent.

Handling Spacer Layers with Flexible Gaps

When layer.type === 'spacer', the engine treats the element as a flexible gap rather than content. The function returns the explicitly provided width (or falls back to the parent container width) and the specified height, defaulting to 0 when height is unspecified. This allows spacers to absorb available space in stack layouts without requiring explicit pixel values.

Resolving Explicit Dimensions and Fill Width

For all layer types, the engine first examines layer.width and layer.height properties. If the width value equals the string 'fill', the engine substitutes the parent container width (with a fallback of 300 px if no parent exists). When a layer contains a layer._resolvedStyle object, the engine extracts width and height from these resolved styles, applying the same 'fill' substitution logic. This enables responsive designs where elements expand to match container boundaries.

Estimating Text Layer Dimensions

Text layers (layer.type === 'text') require special handling when dimensions remain undefined after explicit checks. The engine invokes estimateTextSize, which calculates width based on character count (distinguishing between ASCII and CJK characters) and derives height from the specified line-height or a default multiplier of the font size. These computed estimates populate missing width or height slots, ensuring text layers naturally size to their content without manual specification.

Default Sizing for Groups and Rectangles

If previous resolution steps fail to determine dimensions, the engine applies hardcoded defaults. Width defaults to 100 px for all layer types. Height defaults to 40 px for most layers, but group types receive a default height of 0 px because their final dimensions derive from the sum of child elements during the subsequent layout pass. This distinction prevents groups from reserving unnecessary space before their children are positioned.

Practical Code Examples

The following examples demonstrate how the intrinsic size logic behaves with different layer configurations. All examples assume the layout engine is imported from sketch/agent-harness/src/layout.js:

const { computeLayout } = require('./sketch/agent-harness/src/layout');

// Spacer inherits parent width when unspecified
const spacerSpec = [{ type: 'spacer', height: 20 }];
console.log(computeLayout(spacerSpec, { type: 'vertical-stack' }, 500, 300));
// → [{ index:0, x:0, y:0, width:500, height:20 }]
// Text layers calculate size from content when dimensions are missing
const textSpec = [{ type: 'text', value: 'Hello world!' }];
console.log(computeLayout(textSpec, { type: 'absolute' }, 400, 200));
// → width ≈ 84 px, height ≈ 19 px (based on estimateTextSize)
// 'fill' width matches parent container
const fillSpec = [{ type: 'image', width: 'fill', height: 150 }];
console.log(computeLayout(fillSpec, { type: 'absolute' }, 320, 240));
// → [{ index:0, x:0, y:0, width:320, height:150 }]
// Groups default height to 0, deriving final size from children
const groupSpec = [{
  type: 'group',
  layout: { type: 'vertical-stack', gap: 5 },
  children: [
    { type: 'text', value: 'One' },
    { type: 'text', value: 'Two' }
  ]
}];
console.log(computeLayout(groupSpec, { type: 'absolute' }, 200, 200));
// → group width = 100 (default), height = sum of child heights + gaps

Summary

  • The intrinsicSize function in sketch/agent-harness/src/layout.js serves as the central calculator for natural layer dimensions.
  • Spacer layers default to parent width and zero height, functioning as flexible gaps.
  • The 'fill' string value triggers substitution with the parent container width, enabling responsive layouts.
  • Text layers rely on estimateTextSize to compute dimensions based on character count and font metrics when explicit sizes are absent.
  • Groups uniquely default to 0 px height because they derive final dimensions from child layouts, while other layers default to 100 px width and 40 px height.

Frequently Asked Questions

What file contains the intrinsic size calculation logic?

The intrinsic size calculation logic resides in sketch/agent-harness/src/layout.js within the HKUDS/CLI-Anything repository. This file exports the intrinsicSize function alongside the estimateTextSize helper and three layout positioning algorithms.

How does CLI-Anything handle text layers without explicit dimensions?

When text layers lack explicit width or height values, the engine calls estimateTextSize to compute natural dimensions based on character count (distinguishing ASCII from CJK characters) and line-height metrics. These estimates ensure text renders at appropriate sizes without manual pixel specification.

What is the default size for groups versus other layers?

Groups default to 100 px width and 0 px height, while rectangles and other layer types default to 100 px width and 40 px height. The zero-height default for groups exists because their final dimensions are calculated from the sum of positioned children during the layout pass.

How does the 'fill' width value work in CLI-Anything layouts?

The string value 'fill' triggers the engine to substitute the parent container's width (with a fallback of 300 px if undefined). This substitution occurs both in direct layer.width properties and within layer._resolvedStyle objects, allowing elements to expand responsively within their containers.

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 →