From 39dcefb060fd3937e9703afc1c64c6ad91720f79 Mon Sep 17 00:00:00 2001 From: Lee Overy Date: Thu, 4 Jun 2026 20:04:26 +0100 Subject: [PATCH] feat(render): deterministic renderer core + signpost slice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First slice of the deterministic renderer (idea #32). Adds skills/workflow-render — a library+CLI sharing one wrap/width core: - core: fillTo, wrap (greedy + hard-split), wrapWithPrefix (budget = width - prefix.length, the single home of the gutter-budget bug) - shapes: signpost (step/sub-step markers), box (phase-title) - CLI (Claude, via Bash) + library (scripts require() in-process) - SKILL.md API reference; 17 tests Proven byte-exact against live hand-drawn markers/borders pulled from skills; surfaced existing 50-char sub-step drift the renderer normalises. Co-Authored-By: Claude Opus 4.8 (1M context) --- skills/workflow-render/SKILL.md | 74 ++++++++++ skills/workflow-render/scripts/render.cjs | 171 ++++++++++++++++++++++ tests/scripts/test-render.cjs | 130 ++++++++++++++++ 3 files changed, 375 insertions(+) create mode 100644 skills/workflow-render/SKILL.md create mode 100644 skills/workflow-render/scripts/render.cjs create mode 100644 tests/scripts/test-render.cjs diff --git a/skills/workflow-render/SKILL.md b/skills/workflow-render/SKILL.md new file mode 100644 index 000000000..3229f4de7 --- /dev/null +++ b/skills/workflow-render/SKILL.md @@ -0,0 +1,74 @@ +--- +name: workflow-render +user-invocable: false +allowed-tools: Bash(node .claude/skills/workflow-render/scripts/render.cjs) +--- + +# Workflow Render + +Deterministic renderer for fixed-shape workflow output. Layout that is fully determined by data is computed here, in code, and emitted verbatim — never re-derived character-by-character on every render. The wrap/width math lives here once, so the gutter-budget bug can exist in only one place. + +Two ways in: + +- **CLI** — Claude invokes it via Bash for trivial-input shapes (a label, a title). Print the result verbatim to the user. +- **Library** — other scripts `require()` it and call the functions in-process. The data-owner (e.g. `discovery.cjs`) builds the structure and calls the renderer; Claude never assembles the input. + +The output is for display. Never read a rendered block back to extract a decision — decision data comes from structured state, not from parsing the rendered text. + +## Invocation + +```bash +node .claude/skills/workflow-render/scripts/render.cjs [args] +``` + +All shapes are a fixed `--width` (default `49`, the canonical workflow width). + +## Commands + +### `signpost