A notation for system designs, written with your coding agent.

Sigil describes how a system is wired: its components, data, events, actors and stores, and the calls, events and failures between them, in a few lines of text. Its tools lint a design, flag the risks it leaves unhandled, draw it in the terminal and step through its paths. The plugin teaches your coding agent to read and write it.


    

Behind the editor, sigil view redraws after every line in all four of its views. Scroll on and each one comes forward in turn; focus sharpens them here.

One design, four ways to look at it: each is a plane from behind the editor, brought forward. All four draw the URL shortener.

1 graph

The whole design at once: layered boxes coloured by glyph, every arrow its own stroke.

sigil view shortener.sigil --graph

2 tree

What holds what: the composition as an outline, each flow a lane in the gutter.

sigil view shortener.sigil --tree

3 flow

Who calls whom: the call graph left to right, each payload on its wire.

sigil view shortener.sigil  # flow, the default

4 run

What happens: one run as a timeline, a lane per participant, time left to right. Here the happy run, then the one where the lookup fails.

sigil view shortener.sigil --run --sim happy

--- language ---

Sigil describes the wiring of a system — what exists, what talks to what, what fails where — and nothing about how it is coded. It is a notation for people and agents to think in, not a language to run.

the URL shortener, line by line

(User) -> [Shortener] : shorten({Url}) => {Code}a user sends a URL, gets a code
[Shortener] -> |Links| : save({Code}, {Url})the pair is stored
(Visitor) -> [Redirect] : follow({Code})a visitor follows a code
[Redirect] -> |Links| : lookup({Code}) => {Url}it’s looked up
!> (Visitor) : <NotFound>missing: not found
-> (Visitor) : redirect({Url})found: redirected
~> <Clicked> -> [Stats]each click, async, to stats

A line that starts with an arrow continues from the subject above. Simulate it in the playground below: happy, and Redirect.lookup:fails, which ends on the !> route.

glyphs — the things

[Checkout]component — anything with identity that does work
{Order}data, a record type
<OrderPlaced>event, a message
(Shopper)actor, or a system outside yours
|Ledger|store, persistence
[?]a hole — "something goes here", allowed while sketching

arrows — the flows

->call, request
~>async, fire and forget
=>returns, produces
!>the failure path
?>conditional branch
*>broadcast, fan-out
<->both ways, RPC

After a flow, : payload says what travels; modifiers like ×3 @timeout(2s) say how.

composition — the parts

[Shop] := { … }zoom in: the inside of a component
\-& {Health}has a component
\-*-> [Bullet]spawns instances
\-{shattered}-? [Shard]exists only when
\-_ [StandbyPsp]one of a group is active
\-(3)-> [ZoneA]a weighted share

Also > contains (the default), $ from data, @ attached, ! alerts when, = gathers — and paths like [Bullet]/{Transform}.

state, driven by events

state {Order} {
  +     -<Placed>->  Open
  Open  -<Paid>->    Settled
}

Any glyph can own a state machine. An event whose name matches a trigger drives it — the viewer draws a dashed wire from the event to what it drives.

modes — how strict

#!sketchpartial: holes allowed, defaults assumed
#!craftwork in progress with an agent, gaps surfaced as you go
#!specbinding: every element is a constraint, holes are errors

The linter checks every document against its mode, and a dialect can add vocabulary for one domain without changing the core.

--- playground ---

Write a design and watch it draw, lint, check and run. This is not a copy of the tools: the repository's own sigil package — viewer, linter, checker and simulator — runs in your browser on Pyodide (Python compiled to WebAssembly — about 10 MB, fetched once when you start).

--- viewer ---

Keep a design open in one pane and sigil view in another: it redraws on every save. Zero dependencies — Python's standard library and a terminal with truecolor.

graph view

The flows as a layered graph, boxes colour-coded by glyph, every arrow type its own stroke. Payloads ride their edges as chips (p), events wire with a dashed edge to the owners whose state they drive, and := expansions open as sections below, as deep as you ask.

sigil view design.sigil --graph --depth all

tree view

The composition tree as an outline with every flow as a lane in a gutter beside it — a hierarchy and a wired graph at the same time. Comments become margin callouts.

sigil view design.sigil --tree --notes callouts

flow view

The call graph read left to right, like the toy graphs behind this page: bare glyph labels in columns by call depth, bent wires between them, each flow's chip on its wire. The quickest way to read who calls whom.

sigil view design.sigil  # the default view

run view

One simulated run as a timeline: a lane per participant, instance and recursion level, time left to right. A bar while each one works or waits, every call at the tick it was sent, retries as repeated segments, spawned instances forking off their spawner — what did happen, where the other views draw what can. Without a scenario, the happy run.

sigil view design.sigil --run --sim happy

simulate

Walk the design: tokens travel its flows in every view — the happy path, each failure route, branch arm and race, one named scenario at a time. Calls wait for their return, !> fires only on failure, events move the state machines. A line under the drawing says each step in plain words, after the path of hops so far, numbered by branch. No values are computed: it walks the wiring, not your code.

sigil view design.sigil --once --tree --sim happy

calls

Who runs what, and what comes back: ↺ a self-call, ↻ recursion, ↩ a call's return, ⇱ an op the host provides — opaque, and it may fail. The executions.sigil example above shows them all.

sigil view site/examples/05-executions.sigil --payloads

1 2 3 4 graph / tree / flow / run t next view x simulate d depth u unroll n notes e triggers v events s spacing p payloads m modifiers a access o layout: auto / wrap / pan f flip wrap ↔ pan l lint q quit · drag to pan · --once prints a frame for agents and CI · --theme picks the same YAML themes as this page.

--- skill ---

Sigil ships as an agent skill with two commands. Once installed, your coding agent reaches for it whenever a conversation turns to architecture — and keeps the design in a file you can both edit.

compress

Turn a prose spec, a meeting's notes or an existing codebase into a one-screen sketch.

craft

Design together in #!craft mode: the agent proposes structure, leaves named holes, and asks about the gaps.

expand

Turn a sketch back into prose for a design doc, unambiguously — the notation is the source of truth.

compare

Diff two designs structurally: what moved, what is new, which flows changed shape.

lint & normalise

Validate against the spec and tighten hand-written sketches into normal form.

draw

Check the drawing with sigil view --once, or emit Mermaid for docs with sigil export --mermaid.

export

Turn a ready #!spec into a build skeleton with sigil export: a folder per system, a manifest of hashes, and on a re-export the systems to redo.

Commands: sigil-view <file> draws a document; sigil-lint <file> checks it. Names vary slightly per agent — /sigil:sigil-view in Claude Code, $sigil-view in Codex.

--- install ---

Release pending — these commands go live with the first tagged release (v0.6.1). Until then, build the archives from a clone with ./build.py.

curl -LO https://github.com/no-tably/sigil/releases/download/v0.6.1/sigil-claude-marketplace-0.6.1.zip
unzip sigil-claude-marketplace-0.6.1.zip

then, inside Claude Code:

/plugin marketplace add ./sigil-claude-marketplace-0.6.1
/plugin install sigil@sigil

Commands appear as /sigil:sigil-view and /sigil:sigil-lint.