DocsReference
Schema reference
The diagram your agent writes. stackmap computes the layout, so there are never coordinates, and objects are strict: an unknown key is an error.
Diagram
The top level. kind picks the layout; the arrays hold everything the diagram draws. Objects are strict, so an unknown key is an error.
$schemastringOptional; set it to
https://unpkg.com/@omsimos/stackmap@0.4.0/dist/stackmap.schema.jsonfor editor completionkindenumrequiredOne of
architecture,dataflow,workflow,lifecycle,sequencedensityenumArchitecture and dataflow: compact cards (title, subtitle, brand, tag) for long chains or summaries. One of
compacttitlestringrequiredNon-blank
subtitlestringNon-blank
sourceobjectBase URL for evidence links:
<url>/<file>#L<line>. See sourcedirectionenumLayout flow. Default RIGHT; prefer DOWN for tiered/grouped diagrams. One of
RIGHT,DOWN
What it holds
At most 200.
Workflow and lifecycle: swimlanes, top to bottom. At most 20.
Ordered stages: header bands over columns (workflow, lifecycle), stage bands in flow order (architecture, dataflow) or time bands (sequence). At most 20.
At least 1. At most 500.
Connections. In a sequence, the messages, in time order. At most 2000.
At most 50.
Takeaways about the diagram, shown in the inspector. At most 6.
{ "$schema": "https://unpkg.com/@omsimos/stackmap@0.4.0/dist/stackmap.schema.json", "kind": "architecture", "title": "Bookshop", "subtitle": "Web storefront and order pipeline", "direction": "DOWN", "groups": [ … 4 ], "nodes": [ … 10 ], "edges": [ … 10 ], "views": [ … 2 ]}Nodes
One per runtime unit the reader must tell apart: a service, a store, a queue, a person, a state.
idstringrequiredId
typeenumrequiredSets the card color. Never color by brand. Lifecycle diagrams use the state types (start, active, waiting, decision, success, failure, neutral); every other kind uses the component types. One of
client,service,gateway,database,cache,queue,storage,external,security,start,active,waiting,decision,success,failure,neutralgroupstringId of the group the node sits in
lanestringWorkflow and lifecycle: id of the lane the node sits in (required there)
cardobjectrequiredSee nodes[].card
evidencearraySource locations backing this node; listed in the inspector. At most 8. See nodes[].evidence[]
[ { "id": "api", "type": "service", "card": { "title": "shop-api", "subtitle": "REST API" }, "evidence": [{ "file": "services/api/src/server.ts", "line": 12 }] }, { "id": "orders", "type": "database", "group": "data", "card": { "title": "Orders DB", "subtitle": "PostgreSQL", "brand": "postgresql" }, "evidence": [{ "file": "infra/orders/postgres.tf", "line": 12 }] }]Cards
What a node’s card shows. Only title is required; add parts when they carry what a reader needs at a glance. Text never wraps: anything too long is an error, card-fit/overflow. A brand is one of the 146 brand slugs. The viewer’s sample card, with every part:
titlestringrequiredCard title. Must fit the card;
stackmap validatereports the character budget. Non-blanksubtitlestringNon-blank
brandstringSimple-icons slug shown in the icon tile, e.g. "postgresql"
rowsarrayKey/value rows.
monorenders the value in Geist Mono (ports, IPs). At most 6. See nodes[].card.rows[]statsarrayStat tiles, e.g. Replica counts. At most 3. See nodes[].card.stats[]
statsNotestringLine under the stat tiles; only shown with stats. Non-blank
footerobjectctaobjectSee nodes[].card.cta
tagstringCompact cards only (workflow, lifecycle, sequence, or density "compact"): a short pill, e.g. "human gate". Non-blank
{ "title": "Orders", "subtitle": "PostgreSQL cluster", "brand": "postgresql", "stats": [ { "value": "1", "label": "Primary" }, { "value": "2", "label": "Read replicas" } ], "statsNote": "2 replication links", "footer": { "left": { "text": "EU West", "icon": "region" }, "right": { "text": "3 members", "icon": "members" } }, "cta": { "label": "Open cluster", "href": "https://console.example.com/clusters/orders" }}Card parts
Rows are key and value pairs, mono for ports and paths. Stats are a value and a label, at most three. The footer takes a left and a right item, each a text and an optional icon (region, secure, members). A call to action takes a label and an http(s) link.
rows[]
labelstringrequiredNon-blank
valuestringrequiredNon-blank
monoboolean—
stats[]
valuestringrequiredNon-blank
labelstringrequiredNon-blank
footer.left and footer.right
textstringrequiredNon-blank
iconenumOne of
region,secure,members
cta
labelstringrequiredNon-blank
hrefstringHttp(s) URL
{ "title": "API", "rows": [ { "label": "Instances", "value": "3" }, { "label": "Port", "value": ":8080", "mono": true } ], "stats": [ { "value": "1", "label": "Primary" }, { "value": "2", "label": "Read replicas" } ], "footer": { "left": { "text": "EU West", "icon": "region" }, "right": { "text": "3 members", "icon": "members" } }, "cta": { "label": "Open cluster", "href": "https://console.example.com/clusters/orders" }}Evidence
Where a node came from: a file, a line and a note. The inspector lists it, and with source.url set, every entry links to its line.
filestringrequiredRepo-relative path, e.g. "src/orders/api.ts". Repo-relative path (no
..,\,://or leading/)lineinteger> 0
notestringNon-blank
[ { "file": "services/api/src/server.ts", "line": 12, "note": "Express app and routes" }, { "file": "infra/orders/postgres.tf", "line": 12, "note": "Primary + 2 read replicas" }, { "file": "services/api/src/db.ts", "line": 8 }]Source links
Set source.url on the diagram and every evidence entry links to <url>/<file>#L<line>. Use a commit, not a branch, so the lines stay right.
urlstringrequiredHttp(s) URL
{ "url": "https://github.com/omsimos/stackmap/blob/a2111f0590892de04f16c2d2f11ad877a502d89b"}Connections
From the initiator to what it calls (architecture), or the way the data moves (dataflow). Plain for a call, async for queues and events, return for a reply or a roll back.
idstringrequiredId
fromstringrequiredSource node id
tostringrequiredTarget node id
labelstringShort label; use sparingly. Non-blank. At most 24 characters
kindenumAsync renders dashed; return (a reply, a roll back) renders dotted. One of
sync,async,returntoneenumMain marks the happy path; security and error paths take those tints. Use sparingly. One of
main,security,error
[ { "id": "web-cdn", "from": "web", "to": "cdn", "label": "HTTPS" }, { "id": "api-jobs", "from": "api", "to": "jobs", "label": "enqueue", "kind": "async" }, { "id": "e1", "from": "commit", "to": "pull-request", "tone": "main" }, { "id": "ok", "from": "fraud", "to": "api", "label": "low risk", "kind": "return" }]Groups
Boundaries a reader should see: tiers, trust zones, VPCs, clusters. Nest them with parent; "tone": "security" marks a trust zone.
idstringrequiredId
labelstringrequiredShown above the frame. Non-blank
parentstringId of the enclosing group, for nesting
toneenumA trust boundary (private network, PII zone). One of
security
[ { "id": "blocking-checks", "label": "Blocking checks" }, { "id": "recovery", "label": "Recovery path", "tone": "security" }]Lanes
Workflow and lifecycle swimlanes: full-width rows, top to bottom in the order you list them.
idstringrequiredId
labelstringrequiredNon-blank
toneenumA lane for failure and recovery paths. One of
exception
[ { "id": "dev", "label": "Developer" }, { "id": "ci", "label": "Continuous integration" }, { "id": "exceptions", "label": "Failure and rollback", "tone": "exception" }]Phases
Labelled stretches: columns over lanes (workflow), stages of a pipeline (architecture, dataflow), bands of time (sequence).
idstringrequiredId
labelstringrequiredNon-blank
nodesarrayWorkflow and lifecycle: the nodes whose columns this phase spans. Architecture and dataflow: the nodes in this stage. Items: lowercase id:
a-z,0-9,-,_; starts with a letter or digitedgesarraySequence: the messages this time band spans. Items: lowercase id:
a-z,0-9,-,_; starts with a letter or digit
[ { "id": "change", "label": "Change", "nodes": ["commit", "pull-request"] }, { "id": "request", "label": "Request", "edges": ["open", "get", "verify", "claims"] }]Views
Named focus sets, one tab each. A view dims everything else and fits its members; Overview is always first.
idstringrequiredId
labelstringrequiredNon-blank
captionstringNon-blank
nodesarrayrequiredNode ids this guided view focuses; the rest are dimmed. Items: lowercase id:
a-z,0-9,-,_; starts with a letter or digit
[ { "id": "checkout", "label": "Checkout path", "caption": "What a purchase touches", "nodes": ["web", "cdn", "api", "stripe", "db"] }, { "id": "state", "label": "State", "caption": "Where data lives", "nodes": ["db", "cache", "jobs"] }]Notes
The diagram’s takeaways, listed in the inspector. Two or three, a few short items each: what the picture means, not what it shows.
titlestringrequiredNon-blank
itemsarrayrequiredAt least 1. At most 6. Items: non-blank
[ { "title": "One happy path", "items": [ "Every change is reviewed before a reproducible build", "Blocking checks must be green before human approval" ] }, { "title": "Stop conditions", "items": [ "Test or security failure stops promotion", "Production health can reverse a release" ] }]