Deepwiki Rs
sopaco/deepwiki-rs
AI-powered Rust documentation generation engine for comprehensive codebase analysis, C4 architecture diagrams, and automated technical documentation.
A skill your agent uses when asked to create, edit, review, or debug a Lini diagram (a .lini file or its SVG) — architecture/box-and-arrow diagrams, flowcharts, mindmaps, org charts, ER schemas…
$ npx skills add monfa-red/lini --skill lini -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install monfa-red/lini lini --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
Claude Code skills documentation · loads skills from .claude/skills/
Install the "lini" agent skill from https://github.com/monfa-red/lini/tree/main into .claude/skills/lini/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "lini", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add monfa-red/lini --skill lini -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install monfa-red/lini lini --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "lini" agent skill from https://github.com/monfa-red/lini/tree/main into .agents/skills/lini/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "lini", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add monfa-red/lini --skill lini -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install monfa-red/lini lini --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "lini" agent skill from https://github.com/monfa-red/lini/tree/main into .cursor/skills/lini/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "lini", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add monfa-red/lini --skill lini -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install monfa-red/lini lini --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "lini" agent skill from https://github.com/monfa-red/lini/tree/main into .gemini/skills/lini/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "lini", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install monfa-red/lini liniInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add monfa-red/lini --skill lini -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "lini" agent skill from https://github.com/monfa-red/lini/tree/main into .github/skills/lini/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "lini", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add monfa-red/lini --skill lini -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install monfa-red/lini lini --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "lini" agent skill from https://github.com/monfa-red/lini/tree/main into .opencode/skills/lini/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "lini", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
liniA skill your agent uses when asked to create, edit, review, or debug a Lini diagram (a .lini file or its SVG) — architecture/box-and-arrow diagrams, flowcharts, mindmaps, org charts, ER schemas…
Lini is an agent skill from monfa-red/lini. Use when asked to create, edit, review, or debug a Lini diagram (a .lini file or its SVG) — architecture/box-and-arrow diagrams, flowcharts, mindmaps, org charts, ER schemas, tables, sequence diagrams, bar/line/area/pie/radar/scatter charts, engineering drawings, floor plans, circuit schematics, or pen-drawn artwork written in the Lini language.
Its SKILL.md is about 11k tokens, which your agent loads only when the skill is triggered. The skill folder holds 580 other files, including assets (for example `.github/ISSUE_TEMPLATE/bug_report.yml`, `.github/ISSUE_TEMPLATE/config.yml` and `.github/ISSUE_TEMPLATE/feature_request.yml`).
It sits in Development, covering Diagrams. It works with Rust. The repository describes itself as: One small language for every figure from plain text — diagrams, charts, sequences, mindmaps, trees, ER schemas, schematics, floor plans and dimensioned technical drawings —…. The licence is MIT.
7 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 0502d38. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
cargoFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Lini loads about 11k tokens when it runs. Until then it costs about 88 tokens; SKILL.md has 5,170 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from monfa-red/lini at commit 0502d38, republished under its MIT licence (© monfa-red). 5,170 words, ~10,903 tokens.
.claude/skills/lini/SKILL.md (or your agent's skills folder). This skill also uses 575 other files; get the full folder from GitHub.Lini compiles plain text to clean, themeable SVG: composable nodes, a CSS-like
cascade, compile-time layout. One core drives every diagram family. This file is
self-sufficient for real work; SPEC.md (the full language), ROUTING.md (wire
geometry), and samples/ (the showroom — one file per feature cluster) go deeper.
Write → compile → look at the render → refine. Never ship a diagram you haven't seen.
lini d.lini -o d.svg # compile; errors are file:line:col with fixes
lini --check --strict d.lini # full compile, nothing written; warnings fail — the pre-finish gate
lini fmt d.lini # canonical formatting in place (--check: exit 1 if it would change)
lini --static d.lini -o s.svg && resvg s.svg d.png # rasterize, then READ d.png--static inlines CSS variables and outlines text — required before resvg
(it can't resolve var()). Outlining covers the bundled Latin charset; a run
with CJK, Arabic, arrows, or emoji stays <text> and warns (O001) — check the
PNG for it. --strict / --no-warn bind every form (SVG, --check, --json
diagnostics for tooling). Also: --watch (with -o), --format html,
--embed-font (browser-only @font-face), --theme NAME|FILE|light/dark.
Exit codes: 0 ok · 1 error (or fmt --check would reformat) · 2 I/O · 3 bad CLI.
In this repo the binary is target/release/lini (cargo build --release if
missing). lini desugar d.lini prints the lowered form when sugar confuses;
lini serve opens a live playground.
A file is one optional { } stylesheet, then drawn statements in source
order. The stylesheet configures and styles; it draws nothing, and must come
first.
{ // the stylesheet — setup only
layout: grid; columns: repeat(2); gap: 30; // scene config (root declarations)
--brand: #ff6600; // a themeable colour variable
w = 120; scale(n) = (100 * 1.2^n); // bindings — baked numbers / functions
|box| { radius: 6; } // a rule: style every box
|-| { stroke: --gray-deep; } // a rule: style every link
.hot { stroke: --red-deep; } // a class definition
|svc::box| { fill: --teal-wash; stroke: --teal-ink; } // a define: new type over a base
|room::group| { gap: 40; } [ // a define with a BODY: intrinsic children + links,
|box#in| "in"; |box#out| "out" // re-materialised per instance; ids local,
in -> out "flows" // reachable from outside as `garden.out`
]
}
|svc#api| "API" // instances — the canvas
|cyl#db| "Postgres" { fill: --rose-wash; }
|room#garden|
api -> db "queries" .hot // a link with a label and a worn class
users -> api // undeclared id → auto-creates |box#users| "users"
garden.out -> api // a dot-path into a bodyEvery drawn statement is a node (|…|), a text leaf ("…"), or a link (bare
name + operator). The full node anatomy — only the bars are required, order
fixed — is |type#id| "label" .class1.class2 { key: value; } [ children ];
a link takes the same tail on a different head: a -> b "label" .cls { } [ ].
; and live only inside { }. A value runs to its
;, so it may span lines. (; optional right before }.); — two nodes on one line need the ;:
|topic| "A"; |topic| "B". Bare strings are self-delimiting ("a" "b" is
two text leaves). A { } or [ ] may span lines freely.\" \\ \n \t; leading/trailing
spaces are trimmed. A bare word is an identifier (keyword, colour name, id).
Single quotes are not strings. String-valued properties (title, hint,
href, src) need quotes even for one word.data: 9, 15, 24 (three values) · data: 10 20, 30 40
(two x-y points) · padding: 5 2 5 5 (one four-part value: N · v h ·
t r b l) · gap: 8 0 (row col — flow, grid, sequence alike) · translate: 10 -4.(…): padding: (8 * 2);
width: (w / 2). A call's own parens count, so an operator inside a call's
arguments needs no inner group: move(-tail - 1, -y), right(w / 2),
pattern: grid(1, 3, 0, pitch). Calls are bare (width: scale(3)), signed
numbers are bare (translate: -35 20). Inside a group: + - * / ^,
comparisons, a ? b : c, pi/e, 1e-6, locals (r = 40; 2 * r), a
top-level , makes a point, and the math library — sqrt exp ln log abs sin cos tan min max clamp floor round pow. Stylesheet bindings (w = 120;
wave(a, f) = (u * 320, a * sin(2 * pi * f * u));) read bare anywhere a value
goes — stroke-width: w, move(w, 0), pattern: grid(1, 3, 0, pitch).points: value may be one expression in the ambient
clock u (0 → 1), sampled samples: times — |line| { points: (u * 320, 24 * sin(2 * pi * 3 * u)); samples: 64 }, or points: wave(18, 2) from a
point-valued binding. Charts bind x the same way (below).|box| .hot — not |box.hot|.
The label comes before classes: |box#a| "A" .hot. First class spaced off the
head, further ones glued: .hot.loud.--name variables are visual only (colours, font-family). Sizes, gaps,
padding, font-size, letter-spacing, line-spacing, text-transform bake
at compile time — literals or bindings, never variables.pin: center; translate: x y (parent-local coordinates, y grows down) — or
layout: stack (below) when the whole scene is hand-placed.text-align — a text's lines align by its container's horizontal
packing knob: justify in a row, align in a column or grid — so align in
a card, which stacks. Split intents: wrap text in its own
|block| { justify: start; }.id.child paths glue (no spaces): kitchen.bowl. a:left forces a link
side. Paths resolve exactly in scope — never searched, never auto-created. An
anonymous container is scope-transparent: its children belong to the
enclosing scope and no path names it.// … only. Identifiers are [a-zA-Z_][a-zA-Z0-9_-]*,
case-sensitive. Ids may not start with lini-.Five tiers, most specific wins, ties → later wins:
type defaults/rules |box| { } → descendant rules |table| |box| { } → class
rules .hot { } → id rule #hero { } → the instance's own { } block.
Links walk the same ladder via |-| (#g |-| { } styles links written in #g);
(-) { } is the dimension subtype and beats |-| { } for dimensions only.
Values replace wholesale (no per-component merge). Text properties (font-*,
color, spacing, transform) plus clearance/routing/format/thickness
also inherit down the tree, nearest ancestor wins — set font-size once on
the root and everything scales, captions and link labels included.
layer: N overrides).padding each side (default 20 on framed
boxes, 0 on |block|). Explicit width/height are floors — content
never clips. Empty auto box = 2×padding (40×40).max-width: N wraps text to fit (text-wrap: nowrap forbids); the
wrapped size is the measured size.pin lifts a child out of flow onto a parent anchor: center, edges
(top …), corners (top left …). A pinned child is an overlay — paints above,
never grows the parent.translate: x y nudges any node after placement (layout-neutral);
rotate: N turns about the bbox centre. Both work on text too.direction: row | column (default row — source order flows
the way it reads; a closed shape's and a |topic|'s children are card
content and stack instead, so an icon sits over its label), gap (default
36; 12 in card content; gap: row col), align (cross axis) / justify
(main axis): start | center | end | stretch | evenly | origin — no-ops
without slack (explicit size or fixed tracks). Inside a drawing/floorplan/stack
scope a block that must lay out its own content states layout: flow itself
(|room::block| { layout: flow; direction: column; align: center }).columns required — columns: 80, auto, repeat(3), repeat(5, 80);
rows optional; children auto-flow, or cell: col row / span: cols rows
(span: 2 = 2 1) on any non-text child (bare text can't carry them — wrap it
in |block|). Empty "" holds a grid cell. Per-column alignment:
align: start, center, end (one entry per track).gap-fill: colour paints the gutters (gap: 1; gap-fill: --stroke =
hairline rules — how |table| works).Primitives: |block| (frameless base rect), |oval| (equal sides = circle:
|oval| { width: 40 }), |hex|, |slant|, |cyl|, |diamond|, |poly|
(points:), |line| (points:, marker*:), |path| (raw SVG path:),
|image| (src: + width/height; local files embed; fit: auto | contain | cover | stretch), |icon| (a Phosphor icon), |sketch| (draw: pen — see
Drawing). Text is not a node type — a bare "…" is a text leaf; wrap it in
|block| when it needs an id, border, padding, or pin.
Templates (all overridable; extend with |name::base| { … }):
| Type | What it is |
|---|---|
|box| | the default: rounded framed card (radius 8, padding 20) |
|rect| | sharp-cornered box |
|group| | dashed light frame for a captioned region |
|caption| · |footnote| · |sheet-caption| | small muted title pinned above the top-left corner (a group/table label becomes one) · at the bottom centre · inside the top-left corner (a schematic scope's label lowers to it) |
|badge| | small accent pill pinned over the top-right corner |
|row| / |column| / |grid| / |stack| | frameless layout wrappers |
|icon| / |sign| | Phosphor icon: symbol: bell or the label names the glyph — never both (|icon| "user" is the user glyph, unnamed on the page; a captioned icon is a box wrapping one: |box#cdn| "CDN" [ |icon| { symbol: cloud } ]). |sign| is the 64px standalone preset (fit: contain). Icons paint with fill (body) + stroke (line) — color: does nothing. An icon's [ ] text rides on the symbol as a badge and grows the square: |icon| { symbol: bell } [ "3" ] |
|table| | ruled grid; first row auto-becomes the header band; cells via bare strings |
|entity| | ER card: label = centred title, rows = "field" "type" (3 columns for a key gutter) |
|note| | folded-corner callout card (works in every layout) |
|topic| / |mindmap| | tree structure node / the full mindmap preset |
|chart| / |pie| / |sequence| / |drawing| / |floorplan| / |schematic| | layout presets (below) |
Shape extras: multiple: N (one offset duplicate behind — "several of these";
N is the offset, not a count), shadow: dx dy blur,
stroke-style: solid|dashed|dotted (+ drafting center/phantom on shapes,
wavy on links only) — one node, one stroke style: dashed interior geometry
is its own child — opacity: 0.75. href: "url" makes anything clickable;
hint: "…" adds a tooltip/accessible <title>. A standalone arrow is
|line| { points: 0 0, 50 0; marker-end: arrow; }.
a -> b // 1 link (labels boxes into existence)
a -> b -> c // chain: 2 links, every hop marked
a -> b & c // fan-out — shares one trunk at a's side
a & b -> c // fan-in
|group#g| [ |box#child| "C" ]
a:right -> g.child:left "label" // forced sides, path endpoint, label
client -> |cyl#db| // capsule endpoint: declare + link in one statementOperators are [marker][line][marker], glued. Lines: - solid, -- dashed,
--- dotted, ~ wavy. End markers: > arrow, < crow, * dot, <> diamond
(mirrored at the start: <-, <->, *-*…). ER cardinality (crow's-foot),
end-side forms: -+ one · -< many · -o+ zero-or-one · -+< one-or-many ·
-o< zero-or-many · -++ exactly one (mirror at the start: >o-o<). The
same set by name on marker: / marker-start: / marker-end: (overriding the
operator, and the only way on a standalone |line|): arrow dot circle diamond one crow exactly-one zero-or-one one-or-many zero-or-many datum none.
|-| { stroke: #888; stroke-width: 1.5; } for all,
a worn class per link (a -> b .loud), the link's own { } to override.
stroke* is the wire; color/font-* the labels.a -> b "hi"), several or styled ones in [ ]:
a -> b { along: 0.3, 0.7; } [ "near a" "near b" ]. Labels slide to dodge;
they never move the wire.clearance: N (min gap wire↔node; 16 in
flow, 10 in a schematic, 18 for dimensions) and routing: orthogonal | natural | straight sit on a container's { } and cascade. orthogonal (default) =
right-angle runs, rounded corners; natural = smooth direct curves (the
mindmap look — free crossings); straight = one trimmed segment. Per-link
routing: is an error.a -> a exits right, hooks over the top. Bodies are sealed: a
link inside [ ] connects that body's own children; cross-container links go
at the lowest scope seeing both ends, via dot-paths. Where a link is
written is its routing world: a link between two children of one group
routes inside that group only if written in its [ ] — written at root it
detours around the group's outside. Keep intra-group wires in the group.gap, shrinking clearance, or re-siding; nodes never move.Every colour is a light-dark() pair — dark mode is automatic; never
hardcode hex where a variable fits. Role variables (as values, write the
short form): --bg, --fill, --stroke, --stroke-dark (full drafting
black — pen geometry, walls, dimension linework), --stroke-light (thin
support tone — centrelines, extension lines), --accent, --muted,
--danger, --warn. fill: --bg on the root paints the backdrop (default is
none — transparent).
The palette is the beauty engine. Eleven hues — red rose orange amber lime green teal sky blue purple gray (aliases yellow→amber pink→rose indigo→purple cyan→teal) — each in five job-named tiers that survive the dark flip:
--teal-wash (palest — card/section backgrounds) · --teal-soft (pastel
fill, charts) · --teal (everyday pastel) · --teal-deep (strong — borders,
strokes, wires) · --teal-ink (deepest — text). The coloured-node recipe is
wash fill + ink (or deep) stroke + ink text: { fill: --teal-wash; stroke: --teal-ink; color: --teal-ink; }. red is reserved for danger; rose is the
decorative pink. Literal colours: #f80, CSS names, rgb(), hsl(280, 55%, 50%), oklch(0.72, 0.16, 25) (the palette's own space).
Gradients (on fill/stroke/gap-fill): gradient(--rose, --sky) auto-135°,
linear-gradient(135, --rose, --sky), radial-gradient(…). hatch(45) /
hatch(45, 6, --gray-deep) is the section-line fill texture. Declare your own
variables in the stylesheet: --brand: #ff6600; then fill: --brand.
Text: bundled Google Sans (default) and Google Sans Code (mono, via
font-family: "Google Sans Code"). font-weight: normal | medium | semibold | bold (or 400–700), font-style: italic, text-decoration: underline | line-through, text-shadow: dx dy blur colour, text-transform: uppercase | lowercase | capitalize, letter-spacing / line-spacing (px). Body default
15/medium; captions and link labels derive from the inherited size, so one root
font-size: scales everything.
Themes re-skin at render time — no file edits: --theme takes a builtin
(light · dark · high-contrast · blueprint, white linework on cyanotype
blue — the diazo print, for any diagram), a CSS file of --lini-* overrides,
or a light/dark pair. lini theme NAME prints a builtin as CSS to start your own.
layout: on any container (the root included): flow (default) · grid ·
stack · tree · sequence · chart · pie · drawing · floorplan ·
schematic. Everything core — cascade, paint, palette, links syntax — works
identically inside each.
|table#basket| { columns: 80, 140, 80; align: start, center, end; } [
"Fruit" "Quantity" "Notes" // first row → header band
"Apple" "12" "fresh"
"Mango" "3" { color: --red-ink } "ripe" // a styled cell
]
|entity#users| "Users" { columns: auto, auto, auto; } [
"PK" "id" "int"
"" "email" "varchar"
]
users -o< orders // crow's-foot relationship, lands on the card edgeStyle cells with |table| |cell| { … }, the header with |table| |header| { … }.
A cell needing an id (to wire a field) is written as one: |cell#uid| "user_id"
(a |block| there loses the cell inset).
Structure is |topic| nesting inside a layout: tree scope — exactly one root
topic; non-topic children are a topic's own content (an icon, a badge).
direction: column (org chart, default) · row (outline) · bilateral
(mindmap split; per-branch side: left|right overrides). Branch wires are
generated; style a whole arm with #branchid |-| { }; size a tier with
.lini-level-2 { font-size: 12; }.
|mindmap| "Root" [ |topic#ship| "Shipping" [ |topic| "Weekly train" ] … ] is
the preset worth reaching for: bilateral + routing: natural + an automatic
hue per first-level branch (wash fill, deep stroke and wires, ink text) +
depth-ramped sizes + max-width: 160 wrap. Authored cross-links stay neutral:
a.x:right --- b.y:right "relates" { along: 0.8; }.
layout: sequence reads links as time: participants across the top (declared,
or auto-created on first use), messages top-to-bottom in source order. ->
call (opens an activation bar) · --> return (closes it) · ~> async ·
a -> a self-message. A participant's own paint colours its lifeline and bars.
{ layout: sequence; }
|box#user| "Customer" { fill: --rose-wash; stroke: --rose-deep; } [
|icon| { symbol: user; fill: none; stroke: --rose-deep; }
]
|box#shop| "Storefront" { fill: --sky-wash; stroke: --sky-deep; }
|cyl#db| "Orders" { fill: --orange-wash; stroke: --orange-deep; }
user -> shop "place order"
|loop| "each item" [
shop -> db "reserve stock"
db --> shop "in stock"
]
|note| "rate-limited" { place: over shop db; }Frames: |loop| / |opt| / |alt| (+ |else| separators) hold their
messages in [ ] but open no scope — messages always wire the sequence's
participants. gap: row col spaces rows/columns. place: modes: over a
(one lifeline), over a b (span), left a / right a (beside). A named
actor is a box wrapping an icon (above) — a bare |icon#user| "user" spends
its label on the symbol name.
A chart fixes a shared scale from all children, then draws. Default size
360×220 (width/height set the whole box); radial/pie default 280 square.
|chart| "Cycle time (s)" { categories: "15", "30", "50"; } [
|bars| "1.8 kW" { data: 9, 15, 24; }
|bars| "2.3 kW" { data: 7, 13, 20; }
]|bars|, |line|, |area| (baseline: 40 floats the fill off
axis zero), |dots| (+ per-node |bubble| { at: x y; value: N; }; |slice| { value: N; } in a pie). Label = legend entry (auto-shown at ≥ 2). Data —
one of data: / fn:, never both: categorical data: 9, 15, 24 (must match
categories: count) · points data: 0 225, 60 221 · dates data: "2026-01-01" 18, … · formula in x sampled over the domain (samples:
count): fn: (min(100, x * 2)), a bare call fn: cure(18), or per-band
segments fn: (0.1 + u^2), 5, (2 * u) — one per |band|, each in its local
clock u (0 → 1). labels: "a", "b", … per-datum text needs explicit data:.fill: --sky-soft, stroke: --teal. Per-datum highlight on bars/
dots: fill: auto, auto, --red, auto.curve: linear (default) | smooth (monotone, never overshoots) | step;
marker: dot|circle|diamond puts a mark at every datum; tooltip: none|hover|auto|always.|axis#t| "Speed (mm/s)" { side: bottom; range: 0 133; unit: "%"; scale: log|time; step: 50; }
(step: month / 2 week on a time axis; ticks: an explicit list). Bind a
series with axis: t. range: 50 1 reverses; gridlines: none or a colour.
format: decimal 1 | significant 3 | percent 0 | scientific 2 | engineering 1 | fraction 8 | year|month|day|hour|minute on a scope, axis, series, or dimension —
inherits; presentation only, never measurement.|band| "Hold" { range: 1.5 4; axis: t; fill: --amber; } shades a region; a |mark| is a reference line (at: V),
a labelled point (at: x y), or label-only (marker: none) — style its rule
like a wire: |mark| "SLO 250 ms" { at: 250; axis: ms; stroke: --amber-deep; stroke-style: dashed; color: --amber-ink; }.direction: row flips bars horizontal; direction: radial makes radar
(lines close into polygons); bars: grouped (default) | stacked | overlay
combines bar series. |pie| { hole: 0.5 } is a donut.layout: stack arranges nothing: every child's origin lands on the container's
datum and translate: is the only offset. A symmetric primitive's origin is its
centre, so shapes stack concentric; a |sketch|'s is its pen origin, so several
sketches keep the frame they were drawn in — which flow throws away. Reach for it for
artwork (a logo), a hand-placed figure, or a diagram tuned past what an arranger will do.
{ layout: stack; unit: mm; density: 10; padding: 25; cap = 0.9; bowl = 2.5; }
|sketch#n| { draw: move(0, -3.4) arc(3.4, 3.4, 3.4) down(bowl) arc(cap, 180) up(bowl); mirror: y-axis; }
|sketch#dots| { draw: move(11, -9) down(1) arc(cap, -180) up(1) arc(cap, -180) close(); pattern: grid(1, 3, 0, 3); }|stack| is the node form. Links go to the router, so arrows and labels behave as
in a flow. gap/direction/align/justify are ignored (a root block refuses them).
Nested boxes are unaffected: a |box| inside a stack still lays out its own content.
Units: unit: px (the default) is 1 : 1; unit: mm plus a root density: (px
per mm, default 4) draws in millimetres — density: 10 renders a 24 mm mark 240 px
wide. layout: drawing is this engine plus drafting — mates, dimensions,
generated chrome. Same placement, so |sketch|, mirror: and pattern: work
identically in both; only a drawing draws a fused mirror's centreline.
layout: drawing places every child's origin on a shared datum (no flow);
links become dimensions/leaders; measured values are computed from the
geometry — never type a number a dimension can read. No auto-create.
{ layout: drawing; }
|rect#plate| { width: 120; height: 70; } [
|hole#pin| { width: 10; translate: -35 20; pattern: grid(2, 1, 70, 0); }
|hidden#bore| { draw: move(-20, -35) down(70); } // dashed interior geometry
]
plate:left (-) plate:right { side: bottom; } // → 120
plate:left (-) plate.pin { side: top; } // → 25
plate.pin (o) // → 2× ⌀10
plate.pin.2 <- "THRU" // leader to the 2nd pattern copyid{.id}[.index][:point]: :center (default), the four
sides, the four corners vertical-word-first (:top-right), or an authored
:segment/station. Pattern copies index plate.pin.2; mirror: copies are
not addressable.(-) linear (binary, chains share a row: a (-) b (-) c; a side or edge
anchor sets the axis, two point anchors — a corner, a hole — read the
aligned diagonal, so add project: horizontal | vertical to read one axis
and stack it on a side:) · (o) round (unary: ⌀ for round features, R for named arcs) · (<)
angle · leaders <- "text" (arrow) / *- "text" (dot on a face) / >- "A"
(datum triangle) — or node-first to a placed annotation: b1 -* housing:boss
(a |balloon#b1| "1"), plate.pin <- bore (a |note#bore|) · a:left || b:right { gap: 4 } mates part faces (moves geometry, draws nothing; negative
gap = inserted) and also seats an annotation on a face (finish || plate:top, gap: along the normal, translate: the lateral slide).|sketch| { draw: … }, and it works in any layout): calls run
left-to-right — move(x, y) starts a subpath, left/right/up/down(n),
line(dx, dy), angle(deg, n), curve(c1x, c1y, c2x, c2y, dx, dy),
circle(r), fillet(r) / chamfer(c) between two segments, point() (a
station: records the current point, draws nothing — beside a fillet it is the
sharp corner), close(). A second move() starts a subpath; fill is even-odd,
so an inner one reads as a hole. :name glued to any call — close():west,
point():m1 included — names that segment/station for dimensioning
(body:neck (o) → ⌀); built-in names (:left…) can't be authored; a duplicate
errors. Every argument is an expression (bindings read bare).up goes up), but move/line/
curve take raw y-down numbers — move(0, -14) is 14 above the origin.arc(dx, dy, r) is the minor
arc to a relative point — r > 0 sweeps clockwise, r < 0 counter-clockwise,
|r| ≥ half the chord. arc(r, deg) is a tangent arc: it continues the
current heading and sweeps deg (positive = clockwise), updating the heading.
Every run, line(), curve(), angle() or arc leaves a heading; a bare
move() leaves none — so open a tangent chain with a run or the two-point
form. Bearings are up = 0, clockwise (90 right, 180 down).mirror: reflects the node's path and its features about an axis
through its origin, then unions the copy — y-axis (left↔right), x-axis
(top↔bottom), a bearing, or a list applied left to right, each reflecting the
union so far (y-axis, x-axis = 4-fold). An open subpath is fused
(draw half, get the whole — both ends must sit on the axis) and generates the
axis |centerline| in a drawing; a closed one is duplicated (draw one
ear, get both). The default auto reflects iff an ancestor does; mirror: none opts a node and its subtree out.pattern: (any layout) — grid(cols, rows, dx, dy) where the seed is
copy one, so grid(1, 3, 0, 20) gives three, not four; radial(count, radius)
puts count copies on the circle about the node's position and draws the
|pitch-circle|.revolve: x-axis makes a turned part (centerline + shoulder lines auto);
|hole| punches and centre-marks itself (thread: 1.25 on it draws the ¾
thread arc). Generated chrome (|centerline|, |pitch-circle|, |breakline|,
|shoulder|, |projection|, |threadline|) is styled — or removed — by
the cascade: |sketch| |centerline| { stroke: none; fill: none } takes its
space back too. Each is also free to author by hand: |centerline| { points: 0 -20, 0 20; }.side: picks the stacking edge, tol: 0.1 / tol: +0.2 -0.05 /
tol: h6 appends tolerance, labels follow (pin (o) "H7") or replace
(two-ended) the value; a dimension's [ ] carries annotation nodes
(plate:top (-) plate:bottom [ |datum| "C" ]). Scale is three settings:
scale: 2 is the drafting ratio (a 2:1 view that still measures true),
unit: the physical size of one drawing unit (mm default here, also
cm/m/in/px), and root density: the pixels per mm (default 4) — the
engine's px-per-unit is their product, never authored. Magnitude is scale:'s
job: a 5 m beam on A4 is scale: 0.02. density: lives on the root; unit:
and scale: on the drawing / stack scope (the root itself when it is one).|drawing| children of a |page|:
|page| { sheet: a4; align: origin } [ |drawing#side| "Title" { scale: 2 } [ … ] side.a (-) side.b |title-block| { title: "…"; drawing-number: "…"; revision: "A"; sheet-number: "1/1"; date: "…"; author: "…"; } [ |image| { src: "logo.svg"; cell: 3 3; width: 12; height: 12 } ] ] (authored cells seat after the
generated fields; dimensions sit in the view or on the page). Multi-view rows
share axes with align: origin, and an unmarked - between anchors in
different views (side.screw:head - end.od:top) is the projection
construction line — the one legal cross-view link.thread: neck 1.25 dresses an ISO thread on a
revolved profile — a bare leader on that segment composes M8×1.25;
break: -40 40 cuts a long part's boring middle (the view compresses, dims
still read the unbroken model). A section / detail is a marker plus a view:
|plane#a| "A" { at: 40 } or |magnifier#c| "C" { width: 12 } on the
source, a sibling |drawing| { of: a } as the view — its title (A-A (1:1),
C (3:1)) composes itself. GD&T: |surface-finish| "Ra 1.6",
|feature-control| "position" { tol: 0.05; datums: A B; zone: diameter; material: maximum; modifiers: projected 10 } (+ |control| rows for a
composite frame; the ISO 1101 characteristic names validate), |datum| — seat
on a face with || or carry in a dimension's [ ]; datum letters come from
>- leaders (body:seat >- "A").layout: floorplan is the drawing engine in an architect's vocabulary —
same datum, scale:/unit:, anchors and dimensions. Build it in four passes:
walls → openings → fixtures → dimensions. Sizes you type are drawing units;
every built-in size is true physical mm converted through unit:.
{ layout: floorplan; unit: m; scale: 0.02 } // 1:50 — 80 px per metre
|wall#outer| { // draw: is the CENTRELINE
draw: move(0, 0) right(7.2):north down(4.8):east
left(7.2):south close():west;
} [ // openings ride the wall's [ ]
|window| { on: north; at: 2.7; width: 1.6 }
|door#entry| "D1" { on: south; at: 1.05; width: 0.95; swing: right }
// 'south' runs leftward: 'at' counts from its EAST end, and the pen's left
// is the outside — 'right' is what opens the door into the flat
]
|partition#bathwall| { // ends ON the shell, never across an opening
draw: move(4.9, 0) down(2.3):face right(2.3):side
} [
|door| { on: side; at: 0.15; width: 0.8 } // opens into the bathroom
]
|rect#counter| { width: 0.6; height: 1.4; translate: 6.8 3.2;
fill: --bg; stroke: --stroke-dark; stroke-width: 1 }
|bed| { rotate: 90; translate: 1.15 1.05 } // head to the west wall
|sofa| { symbol: two; rotate: 90; translate: 0.6 3.4 }
|dining| { symbol: round; translate: 3.3 3.3 }
|appliance| "F" { symbol: fridge; translate: 6.8 2.8 }
|bath| { symbol: shower; translate: 6.6 0.6 }
|bath| { symbol: toilet; rotate: 90; translate: 5.35 0.5 } // 0° backs WEST
"STUDIO 27 m²" { translate: 2.2 2.2 } // room names are plain sheet text
// Clear spans, face to face. 'face' runs south, so its 'out' face is the
// living side's and its 'in' face the bathroom's — read them the other way
// round and each dimension eats the partition.
outer:west-in (-) bathwall:face-out { side: top } // → 4.75 — the living space
bathwall:face-in (-) outer:east-in { side: top } // → 2.15 — the bathroom
outer:west-in (-) outer:east-in { side: top } // → 7 — the shell, clear
outer:north-in (-) outer:south-in { side: right } // → 4.6|wall| is a |sketch| whose draw: traces the centreline;
thickness: (200 mm default, inherits nearest-wins; authored per wall in
drawing units — thickness: 0.4 under unit: m) offsets it into the
mitred, solid-filled poché outline that takes the paint. |partition|
is the 100 mm interior define. fill: --bg; stroke: --stroke-dark is the
hollow double-line look, fill: hatch(45) the section convention. Walls bend
with arc(); curve() errors. Draw meeting walls as separate nodes —
paint order merges them seamlessly.|door| / |window| must sit in its wall's [ ], stationed
on: a straight named segment, at: the near jamb's distance from that
segment's start (mind the draw direction — a left(...) run measures from its
east end). They clip the wall and generate their chrome: hinge: start|end ×
swing: left|right (left of the pen's travel), symbol: single | double | sliding (a slider takes no hinge:/swing:). translate: on one is an error.rotate: turns a piece to its
wall — a toilet and a sink back west unturned, a sofa backs
north, a corner sofa seats a north-west corner; add 90° per
quarter-turn clockwise. The families: |bed| (queen·king·double·single) · |sofa|
(three·two·one·corner·stool — one is the armchair, stool the ⌀350 bar
seat) · |dining| (six·four·round — sized by its tabletop, ⌀1000 for
round; the pull-back chairs extend the bbox) · |bath|
(tub·shower·toilet·sink·double-sink — the last is one unit, two basins) ·
|appliance| (stove·fridge·washer·dishwasher) ·
|stairs| (steps: N ≥ 2 required; no symbol:). width/height are floors
that stretch the body. Each fills --bg, so furniture masks the floor
under it. Label seats: a fixture's hangs below the body — leave air
there; an |appliance|'s centres inside it ("F" / "DW" / "W/D");
an opening's sits beside the gap; each turns upright.|rect|s; a balcony deck, a north arrow or a scale bar is a
|sketch|; room names and areas are sheet text placed with translate: (a
two-line name over its area is a |block| { layout: flow; direction: column }).
A casework |rect| takes the core radius: for a softened counter — mind
that it is sheet-space pixels, not drawing units (at 1:50 and the default
density, radius: 4 is 50 mm).-in (the enclosed side
on a closed run, the left of the pen's travel on an open one) and -out —
and the bare :segment is the centreline, where a structural drawing
measures. Dimension inside faces, always: a room reads its clear
span and the overall the shell's clear interior — what a listing plan
publishes. Never a centreline, and never a span that runs through a wall:
take the face on the room's own side, so the room clears plus the partitions
sum to the overall (2.65 + 0.1 + 4.05 = 6.8). Which face that is follows
the run's draw direction, so check it — a partition drawn southward has its
-out face to the west. A name of your own ending -in/-out on a wall
errors. A named edge's extension line springs
from the end nearest the dimension line, so it leaves a corner and runs away
from the plan. Mind the axis — an edge dimensions across itself, so a
horizontal span names the two vertical runs. An id'd opening anchors at its
centre, which makes a location chain (outer:west-in (-) outer.entry (-) outer:east-in) — a setting-out drawing's dimension, not a room's, so reach
for it only when that is what the sheet is.--theme blueprint for white-on-cyanotype; a plan's default stays black-on-white.layout: schematic seats parts and lets the router draw square, junction-dotted
wires onto pins. 3+-pin parts (and anything with cell:) are anchors on
tracks; 1–2-pin parts and labels are satellites seated at the pin their wire
touches. The sheet is on a grid — gap is the part pitch (column and row,
default 100), and it is the one lever when a long value overhangs the column
beside it, since no part's ink ever moves another part. A schematic's
columns: is the wrap count (one integer, not a track list) and its cell: col row is ordinal — empty tracks collapse. clearance is 10 (past the
pin-pitch 20 it errors). No auto-create — unknown bare ids error.
{ layout: schematic; |vcc::label| { symbol: power } [ "5V" ] }
|component#u1| "AMS1117-3.3" [
|pin#vin| { side: left; number: 3; }
|space| { span: 2; } // empty rail slots — the datasheet's pin-group gap
|pin#en| "EN/~SHDN" { side: left; number: 4; } // label = displayed name (id shows when absent)
|pin#gnd| { side: bottom; number: 1; }
|pin#vout| { side: right; number: 2; }
]
|J#j1| "3V3 OUT" { pins: 4; rotate: 180; }
|C#c1| "22u"
|label#tach| "TACH"
u1.vin - |vcc| // the power-flag capsule, defined above
u1.vout - c1 - |gnd| // a chain PASSES THROUGH a 2-pin part: series circuit
u1.vout - j1.p3 "3V3" // net name = the wire's label, set beside the trace
j1.p1 -> "NSTDBY" // one-ended label wire; the marker sets the tag's shape
u1.en - "EN" // a plain name is a RUN of trace, not a stop
j1.p2 - tach; tach - j1.p4 // two wires to one declared label merge at its point|R| |C| |L| |D| |LED| |Q| |Y| |F| |FB| |SW| |BT| |V| |I| |M| |BZ| |TP| (pins p1 p2, or a k, b c e / g d s by symbol: variant — zener, npn, nfet, polarized…); |opamp|
(pins out inp inn, power hidden); |J| (pins: N — one left-facing
column); |component| + |pin| for anything else; |gnd|, |nc|,
|junction| built in. The id is the reference designator (#R5 reads R5);
anonymous parts auto-number (display only — give an id to wire it); prefix: "IC" on a define renames the family. |region::group| { layout: schematic }
makes a captioned sub-sheet — tile several on a |page| grid.rotate: is 90°-step: a satellite auto-poses to face its wire, and
a forced turn also sets which way its chain grows (|R| { rotate: 270 } off
a side pin stands the chain up); mirror: x-axis | y-axis flips a part
about its own axis before the turn — on a |J|, rotate: 180 moves pin 1 to
the bottom, mirror: y-axis faces it right with pin 1 still on top; a
transistor's collector swaps sides. Text stays upright, bar a net name, which
reads along a vertical trace.q1.s - d1.k - |gnd|). A 2-pin part between two placed pins is a bridge (u2.en - r5 - u2.vin). Naming a discrete's pin reserves it first, so u6.fb - r16.p1
beside u6.vout - r15 - r16.p1 - |gnd| taps between the resistors. A name
on a pin another statement wires rides that wire as its net label. :side
on any terminal is an error.shape: plain (default, no outline) | left | right | both | round; symbol: gnd | earth | chassis | power | nc | antenna (text beside
it; symbol + text = power flag, define it once as above). A plain run's
width: N lengthens the trace it names, side: picks its flank. The classic
look (green wires, yellow bodies, beige sheet) is automatic.The defaults are designed — a plain file already reads well. Beauty is mostly restraint plus a few deliberate moves:
|group| + its caption label (|group#edge| "Edge" { gap: 20; } [ … ]). Groups organize; boxes state.normal/medium; save bold and strong colour for titles, one hero node, a
|badge|. One gradient per scene at most (fill: gradient(--sky, --purple); stroke: none; color: white on the hero).pin+translate only for free-form canvases (ER graphs) and
overlays, stack for artwork. Force :side sparingly — reorder declarations
first. Charts: accept the palette walk unless colour has meaning.--> dashed = return/
cache/secondary, ~> wavy = async/event. Encode it as classes
(.async { stroke: --amber-deep; }) so the legend lives in one place.padding: 24–30; group gap 20–28; don't shrink the default
36 scene gap without reason. max-width on prose-y labels (~160–200).hint: on dense nodes, href: where a diagram lands in a doc, |icon|s for
recognition. Set root fill: --bg only when a backdrop plate is wanted.Errors carry did-you-mean suggestions — read them, they're usually exact. The ones whose fix is not in the message:
| Symptom | Fix |
|---|---|
text content takes no '[ ]' / 'pin' needs a box / 'cell' places a grid child | wrap the string in |block| |
'routing' is a scope's strategy | set routing: on the container, not the link |
| link endpoint not found | paths never auto-create; declare it or fix the path (the error lists candidates) |
impossible (a -> b): no legal route: … | a stray — drawn as a slanted dashed line, a warning unless --strict. Widen gap, drop a forced :side, move the link into the group whose children it joins, or lower clearance (a schematic already sits at 10) |
no bundled glyph for '你' … | --static kept that run as <text>; fine in a browser, boxes in resvg |
a tangent arc() right after move() | no heading yet — open with a run or arc(dx, dy, r) |
Warnings matter too (--check --strict before finishing): near-miss ids (cta
vs cat), split label blocks, never-worn classes, strays.
© monfa-red, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 575 other files (assets) in the repository root of monfa-red/lini.
Open the folder on GitHubat commit 0502d38
Lini next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Lini this skillmonfa-red/lini | 137 | — | ~11k | Automated safety check: Pass | MIT | |
| Deepwiki Rssopaco/deepwiki-rs | 3.1k | — | ~748 | Automated safety check: Pass | MIT | |
| Generating Documentationancoleman/ai-design-components | 525 | — | ~3k | Automated safety check: Pass | MIT | |
| Mermaid Graph Renderercuriositech/some_claude_skills | 244 | — | ~2.5k | Automated safety check: Notes | MIT | |
| Archify Diagramstt-a1i/archify | 81k | — | ~2.9k | Automated safety check: Pass | MIT | |
| JSON Canvasheyitsnoah/claudesidian | 2.6k | 18 repos | ~3.5k | Automated safety check: Pass | MIT |
sopaco/deepwiki-rs
AI-powered Rust documentation generation engine for comprehensive codebase analysis, C4 architecture diagrams, and automated technical documentation.
ancoleman/ai-design-components
Generate comprehensive technical documentation including API docs (OpenAPI/Swagger), code documentation (TypeDoc/Sphinx), documentation sites (Docusaurus/MkDocs), Architecture Decision Records…
curiositech/some_claude_skills
Renders Mermaid diagrams to SVG, PNG, and PDF in both web and offline contexts.
tt-a1i/archify
Creates interactive architecture, workflow, sequence, data-flow and lifecycle diagrams as standalone HTML with inline SVG, themes and image or video export.
heyitsnoah/claudesidian
Create and edit JSON Canvas files (.canvas) with nodes, edges, groups, and connections.
cathrynlavery/diagram-design
Creates branded diagrams, from architecture, flowchart and sequence to charts and maps, as self-contained HTML with inline SVG, with import from draw.io, Mermaid and Excalidraw.
Works with
Categories
A skill your agent uses when asked to create, edit, review, or debug a Lini diagram (a .lini file or its SVG) — architecture/box-and-arrow diagrams, flowcharts, mindmaps, org charts, ER schemas…. Lini is an agent skill from monfa-red/lini.lini file or its SVG) — architecture/box-and-arrow diagrams, flowcharts, mindmaps, org charts, ER schemas, tables, sequence diagrams, bar/line/area/pie/radar/scatter charts, engineering drawings, floor plans, circuit schematics, or pen-drawn artwork written in the Lini language.
Lini fits situations like: asked to create; debug a Lini diagram (a .lini file; its SVG) — architecture/box-and-arrow diagrams; sequence diagrams.
Run `npx skills add monfa-red/lini --skill lini -a claude-code`. Or copy the skill folder (the monfa-red/lini repository) into .claude/skills/lini in your project. Claude Code loads it when a task matches its description.
Run `npx skills add monfa-red/lini --skill lini -a codex`. Or copy the skill folder (the monfa-red/lini repository) into .agents/skills/lini in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add monfa-red/lini --skill lini -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/lini, .gemini/skills/lini, .github/skills/lini and .opencode/skills/lini in your project.
Going by SKILL.md and its folder, Lini needs the command-line tools its instructions call (cargo).
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Lini is published under the MIT licence (from the LICENSE file in the skill folder). It allows redistribution, so the full SKILL.md is shown on this page.
About 11k tokens (SKILL.md is roughly 44k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Lini: Deepwiki Rs (sopaco/deepwiki-rs, 3.1k stars), Generating Documentation (ancoleman/ai-design-components, 525 stars), Mermaid Graph Renderer (curiositech/some_claude_skills, 244 stars) and Archify Diagrams (tt-a1i/archify, 81k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
monfa-red (a GitHub user) maintains it in monfa-red/lini, which has 137 GitHub stars. The repository was last updated on October 9, 2026.
Source: monfa-red/lini on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.