@itsthecsguy/linework 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE +11 -0
- package/README.md +206 -2
- package/assets/drawio/LICENSE +201 -0
- package/assets/drawio/VERSION +1 -0
- package/assets/drawio/favicon.ico +0 -0
- package/assets/drawio/images/1x1.png +0 -0
- package/assets/drawio/images/2x2.png +0 -0
- package/assets/drawio/images/3x3.png +0 -0
- package/assets/drawio/images/ajax-loader.gif +0 -0
- package/assets/drawio/images/android-chrome-512x512.png +0 -0
- package/assets/drawio/images/apple-touch-icon.png +0 -0
- package/assets/drawio/images/aui-wait.gif +0 -0
- package/assets/drawio/images/broken.png +0 -0
- package/assets/drawio/images/browserconfig.xml +9 -0
- package/assets/drawio/images/close.png +0 -0
- package/assets/drawio/images/cloud-connector-atlas.png +0 -0
- package/assets/drawio/images/collapsed.gif +0 -0
- package/assets/drawio/images/delete.png +0 -0
- package/assets/drawio/images/document-google-drive-icon-80.png +0 -0
- package/assets/drawio/images/draw-search.png +0 -0
- package/assets/drawio/images/drawio.svg +19 -0
- package/assets/drawio/images/drawlogo-color.svg +50 -0
- package/assets/drawio/images/drawlogo-gray.svg +18 -0
- package/assets/drawio/images/drawlogo-text-bottom.svg +75 -0
- package/assets/drawio/images/drawlogo.svg +18 -0
- package/assets/drawio/images/drawlogo128.png +0 -0
- package/assets/drawio/images/drawlogo144.png +0 -0
- package/assets/drawio/images/drawlogo256.png +0 -0
- package/assets/drawio/images/drawlogo48-gray.png +0 -0
- package/assets/drawio/images/drawlogo48.png +0 -0
- package/assets/drawio/images/drawlogo80.png +0 -0
- package/assets/drawio/images/droptarget.png +0 -0
- package/assets/drawio/images/edit.gif +0 -0
- package/assets/drawio/images/edit16.png +0 -0
- package/assets/drawio/images/edit32.png +0 -0
- package/assets/drawio/images/edit80.png +0 -0
- package/assets/drawio/images/embed-icon.png +0 -0
- package/assets/drawio/images/expanded.gif +0 -0
- package/assets/drawio/images/facebook.png +0 -0
- package/assets/drawio/images/favicon-16x16.png +0 -0
- package/assets/drawio/images/favicon-32x32.png +0 -0
- package/assets/drawio/images/file.png +0 -0
- package/assets/drawio/images/folder.png +0 -0
- package/assets/drawio/images/gadget-screenshot.png +0 -0
- package/assets/drawio/images/gadget-thumb.png +0 -0
- package/assets/drawio/images/github-logo-white.svg +6 -0
- package/assets/drawio/images/github-logo.svg +17 -0
- package/assets/drawio/images/gitlab-logo-white.svg +1 -0
- package/assets/drawio/images/gitlab-logo.svg +1 -0
- package/assets/drawio/images/glyphicons_blogger.png +0 -0
- package/assets/drawio/images/glyphicons_facebook.png +0 -0
- package/assets/drawio/images/glyphicons_github.png +0 -0
- package/assets/drawio/images/glyphicons_google.png +0 -0
- package/assets/drawio/images/glyphicons_star.png +0 -0
- package/assets/drawio/images/glyphicons_twitter.png +0 -0
- package/assets/drawio/images/glyphicons_youtube.png +0 -0
- package/assets/drawio/images/google-drive-connector-atlas.png +0 -0
- package/assets/drawio/images/google-drive-connector-atlas.svg +121 -0
- package/assets/drawio/images/google-drive-logo-white.svg +9 -0
- package/assets/drawio/images/google-drive-logo.svg +17 -0
- package/assets/drawio/images/google-share.png +0 -0
- package/assets/drawio/images/icon-192-maskable.png +0 -0
- package/assets/drawio/images/icon-192.png +0 -0
- package/assets/drawio/images/icon-512-maskable.png +0 -0
- package/assets/drawio/images/icon-512.png +0 -0
- package/assets/drawio/images/icon-search.svg +21 -0
- package/assets/drawio/images/img-hi-res.png +0 -0
- package/assets/drawio/images/img-lo-res.png +0 -0
- package/assets/drawio/images/list.svg +16 -0
- package/assets/drawio/images/locked.png +0 -0
- package/assets/drawio/images/log.png +0 -0
- package/assets/drawio/images/logo-confluence.png +0 -0
- package/assets/drawio/images/logo-flat-small.png +0 -0
- package/assets/drawio/images/logo-flat.png +0 -0
- package/assets/drawio/images/logo-jira.png +0 -0
- package/assets/drawio/images/logo-small.gif +0 -0
- package/assets/drawio/images/logo-white.png +0 -0
- package/assets/drawio/images/logo.png +0 -0
- package/assets/drawio/images/manifest.json +25 -0
- package/assets/drawio/images/move.png +0 -0
- package/assets/drawio/images/notion-logo-white.svg +1 -0
- package/assets/drawio/images/notion-logo.svg +1 -0
- package/assets/drawio/images/onedrive-connector-atlas.png +0 -0
- package/assets/drawio/images/onedrive-connector-atlas.svg +248 -0
- package/assets/drawio/images/onedrive-logo-white.svg +29 -0
- package/assets/drawio/images/onedrive-logo.svg +29 -0
- package/assets/drawio/images/osa_database.png +0 -0
- package/assets/drawio/images/osa_drive-harddisk.png +0 -0
- package/assets/drawio/images/plant-uml-atlas.png +0 -0
- package/assets/drawio/images/samepage-icon-color.svg +37 -0
- package/assets/drawio/images/save.png +0 -0
- package/assets/drawio/images/sidebar-android.png +0 -0
- package/assets/drawio/images/sidebar-archimate.png +0 -0
- package/assets/drawio/images/sidebar-arrows.png +0 -0
- package/assets/drawio/images/sidebar-arrows2.png +0 -0
- package/assets/drawio/images/sidebar-basic.png +0 -0
- package/assets/drawio/images/sidebar-c4.png +0 -0
- package/assets/drawio/images/sidebar-cabinets.png +0 -0
- package/assets/drawio/images/sidebar-cumulus.png +0 -0
- package/assets/drawio/images/sidebar-dfd.png +0 -0
- package/assets/drawio/images/sidebar-dynamics365.png +0 -0
- package/assets/drawio/images/sidebar-eip.png +0 -0
- package/assets/drawio/images/sidebar-er.png +0 -0
- package/assets/drawio/images/sidebar-floorplans.png +0 -0
- package/assets/drawio/images/sidebar-flowchart.png +0 -0
- package/assets/drawio/images/sidebar-gcp3.png +0 -0
- package/assets/drawio/images/sidebar-general.png +0 -0
- package/assets/drawio/images/sidebar-kubernetes.png +0 -0
- package/assets/drawio/images/sidebar-leanmapping.png +0 -0
- package/assets/drawio/images/sidebar-mockups.png +0 -0
- package/assets/drawio/images/sidebar-network.png +0 -0
- package/assets/drawio/images/sidebar-network2.png +0 -0
- package/assets/drawio/images/sidebar-openstack.png +0 -0
- package/assets/drawio/images/sidebar-sitemap.png +0 -0
- package/assets/drawio/images/sidebar-threatmodeling.png +0 -0
- package/assets/drawio/images/sidebar-uml.png +0 -0
- package/assets/drawio/images/sketch-logo128.png +0 -0
- package/assets/drawio/images/spin.gif +0 -0
- package/assets/drawio/images/sprites.png +0 -0
- package/assets/drawio/images/stop-flat-icon-80.png +0 -0
- package/assets/drawio/images/submenu.gif +0 -0
- package/assets/drawio/images/touch-submenu.png +0 -0
- package/assets/drawio/images/transparent.gif +0 -0
- package/assets/drawio/images/trello-logo-white-orange.svg +6 -0
- package/assets/drawio/images/trello-logo-white.svg +6 -0
- package/assets/drawio/images/trello-logo.svg +1 -0
- package/assets/drawio/images/tweet.png +0 -0
- package/assets/drawio/images/update16.png +0 -0
- package/assets/drawio/images/update32.png +0 -0
- package/assets/drawio/images/update80.png +0 -0
- package/assets/drawio/images/youtube.png +0 -0
- package/assets/drawio/img/clipart/Battery_0_128x128.png +0 -0
- package/assets/drawio/img/clipart/Battery_100_128x128.png +0 -0
- package/assets/drawio/img/clipart/Battery_50_128x128.png +0 -0
- package/assets/drawio/img/clipart/Battery_75_128x128.png +0 -0
- package/assets/drawio/img/clipart/Battery_allstates_128x128.png +0 -0
- package/assets/drawio/img/clipart/Bluetooth_128x128.png +0 -0
- package/assets/drawio/img/clipart/Earth_globe_128x128.png +0 -0
- package/assets/drawio/img/clipart/Empty_Folder_128x128.png +0 -0
- package/assets/drawio/img/clipart/Full_Folder_128x128.png +0 -0
- package/assets/drawio/img/clipart/Gear_128x128.png +0 -0
- package/assets/drawio/img/clipart/Keys_128x128.png +0 -0
- package/assets/drawio/img/clipart/Lock_128x128.png +0 -0
- package/assets/drawio/img/clipart/Mouse_Pointer_128x128.png +0 -0
- package/assets/drawio/img/clipart/Plug_128x128.png +0 -0
- package/assets/drawio/img/clipart/Ships_Wheel_128x128.png +0 -0
- package/assets/drawio/img/clipart/Star_128x128.png +0 -0
- package/assets/drawio/img/clipart/Tire_128x128.png +0 -0
- package/assets/drawio/index.html +92 -0
- package/assets/drawio/js/PostConfig.js +7 -0
- package/assets/drawio/js/PreConfig.js +13 -0
- package/assets/drawio/js/app.min.js +18466 -0
- package/assets/drawio/js/bootstrap.js +428 -0
- package/assets/drawio/js/diagramly/LibavoidRouting.js +4459 -0
- package/assets/drawio/js/export-init.js +21 -0
- package/assets/drawio/js/extensions.min.js +10478 -0
- package/assets/drawio/js/libavoid-js/LICENSE +505 -0
- package/assets/drawio/js/libavoid-js/libavoid-routing.js +1633 -0
- package/assets/drawio/js/libavoid-js/libavoid.min.js +59 -0
- package/assets/drawio/js/main.js +22 -0
- package/assets/drawio/js/rough/rough.min.js +1 -0
- package/assets/drawio/js/shapes-14-6-5.min.js +3457 -0
- package/assets/drawio/js/stencils.min.js +447 -0
- package/assets/drawio/mxgraph/css/common.css +147 -0
- package/assets/drawio/resources/dia.txt +2901 -0
- package/assets/drawio/styles/dark-default.xml +109 -0
- package/assets/drawio/styles/default-old.xml +109 -0
- package/assets/drawio/styles/default.xml +203 -0
- package/assets/drawio/styles/fonts/ArchitectsDaughter-Regular.ttf +0 -0
- package/assets/drawio/styles/grapheditor.css +4501 -0
- package/assets/drawio/styles/high-contrast.css +128 -0
- package/assets/drawio/styles/thumb_horz.png +0 -0
- package/assets/drawio/styles/thumb_vertical.png +0 -0
- package/assets/fonts/ibm-plex-mono-LICENSE.txt +93 -0
- package/assets/fonts/ibm-plex-sans-LICENSE.txt +93 -0
- package/assets/fonts/kalam-400.woff2 +0 -0
- package/assets/fonts/kalam-700.woff2 +0 -0
- package/assets/fonts/kalam-LICENSE.txt +93 -0
- package/assets/fonts/plex-mono-400.woff2 +0 -0
- package/assets/fonts/plex-mono-600.woff2 +0 -0
- package/assets/fonts/plex-sans-400.woff2 +0 -0
- package/assets/fonts/plex-sans-600.woff2 +0 -0
- package/dist/api.js +218 -0
- package/dist/cli.js +275 -0
- package/dist/drawio/icons.js +121 -0
- package/dist/drawio/merge.js +309 -0
- package/dist/drawio/read.js +180 -0
- package/dist/drawio/show.js +501 -0
- package/dist/drawio/theme.js +425 -0
- package/dist/drawio/write.js +300 -0
- package/dist/edit/server.js +212 -0
- package/dist/git.js +46 -0
- package/dist/import/mermaid.js +569 -0
- package/dist/layout/layout.js +212 -0
- package/dist/layout/sequence.js +333 -0
- package/dist/layout/text.js +73 -0
- package/dist/lint/check.js +188 -0
- package/dist/lint/fixlabels.js +128 -0
- package/dist/mcp/server.js +239 -0
- package/dist/publish.js +121 -0
- package/dist/render/browser.js +236 -0
- package/dist/render/fonts.js +66 -0
- package/dist/report.js +36 -0
- package/dist/spec/model.js +53 -0
- package/dist/spec/parse.js +497 -0
- package/package.json +71 -4
- package/skills/linework/SKILL.md +233 -0
- package/skills/linework/examples/billing-er.yaml +31 -0
- package/skills/linework/examples/checkout.yaml +28 -0
- package/skills/linework/examples/pay-sequence.yaml +28 -0
- package/skills/linework/examples/payment-state.yaml +22 -0
- package/skills/linework/examples/refund-flow.yaml +29 -0
- package/skills/linework/examples/serverless-aws.yaml +23 -0
- package/skills/linework/references/google-docs.md +46 -0
- package/skills/linework/references/spec.md +312 -0
- package/skills/linework/references/style-guide.md +53 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: linework
|
|
3
|
+
description: Draw software diagrams (architecture, system design, data flow, flowcharts, state machines, sequence diagrams, ER and database schemas) as .drawio.svg files that render in Markdown, HTML and GitHub and that people can edit by hand in draw.io. Use whenever a design doc, README, ADR, wiki page or PR needs a diagram, when asked to draw, visualize or diagram a system, when converting a Mermaid diagram, or when changing an existing .drawio.svg. Use it instead of writing Mermaid, PlantUML or ASCII art unless the user asks for one of those.
|
|
4
|
+
compatibility: Needs Node 20+, a Chromium-based browser (Chrome, Edge, or Playwright's Chromium via `linework install-browser`) and network access to fetch the package with npx.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Linework
|
|
8
|
+
|
|
9
|
+
You describe the diagram as a small YAML spec. Linework does the layout, styling and rendering, and writes a `.drawio.svg`. That's a normal SVG for docs, with the editable draw.io model embedded inside it. Never write coordinates, SVG or draw.io XML yourself.
|
|
10
|
+
|
|
11
|
+
Use Linework instead of Mermaid, PlantUML or ASCII art. Write Mermaid only if the user asks for it, or if the doc lives somewhere that renders Mermaid and can't show images.
|
|
12
|
+
|
|
13
|
+
## Running it
|
|
14
|
+
|
|
15
|
+
In this guide, `linework` means `npx -y @itsthecsguy/linework`. Run plain `linework` only if `command -v linework` (or `where linework` on Windows) finds it. `/tmp` stands for your temp directory (`%TEMP%` on Windows). Keep specs and preview PNGs there, not in the repo.
|
|
16
|
+
|
|
17
|
+
If a command fails:
|
|
18
|
+
- **The download fails** (`ENOTFOUND`, `EAI_AGAIN`, `ETIMEDOUT`, `403`): you probably have no network, often because of a sandbox. Ask the user to let the command run with network access, or to run `npm install -g @itsthecsguy/linework` themselves.
|
|
19
|
+
- **"none was found":** no browser is installed. Run `linework install-browser`, or ask the user to install Chrome.
|
|
20
|
+
- **"found a Chromium-based browser but it could not start":** a sandbox is blocking it. Ask the user to run `npx -y @itsthecsguy/linework install-browser` once outside the sandbox (Linework's own Chromium starts inside Codex's sandbox), or to let the command run outside the sandbox. Don't tell them to install Chrome; they already have a browser.
|
|
21
|
+
- **An option or field is rejected that this guide says exists:** this guide may be newer or older than the installed package. Run `linework skill` to get the path of the guide that ships with the package, and read its SKILL.md. That copy always matches.
|
|
22
|
+
|
|
23
|
+
Never fall back to writing SVG or draw.io XML by hand. Tell the user what failed and what they can do about it.
|
|
24
|
+
|
|
25
|
+
## Workflow
|
|
26
|
+
|
|
27
|
+
1. **Look for existing diagrams first.** Search the repo for `*.drawio.svg`. If one already shows what you need, change it (see "Editing an existing diagram") instead of drawing a new one. Save new diagrams where the existing ones live. With none yet, use `docs/diagrams/`, or the folder of the doc you're editing if the repo has no `docs/`.
|
|
28
|
+
2. **Decide what the diagram is for.** One diagram makes one point. Pick the type:
|
|
29
|
+
- `architecture`: components and how they talk. Services, data stores, queues, external systems, trust boundaries.
|
|
30
|
+
- `flow`: a process with steps and decisions.
|
|
31
|
+
- `state`: the lifecycle of one thing, like an order, payment or job.
|
|
32
|
+
- `sequence`: who calls whom, in what order, for one scenario.
|
|
33
|
+
- `er`: database tables, their columns and how they relate.
|
|
34
|
+
|
|
35
|
+
If the doc already has a Mermaid diagram, convert it instead of rewriting it: `linework import doc.md --block 1 -o docs/diagrams/x.drawio.svg`.
|
|
36
|
+
3. **Write the spec** to `/tmp/spec.yaml`, or pipe it on stdin with `-` as the file. Start from the closest file in `examples/` next to this guide: `checkout.yaml` (architecture), `serverless-aws.yaml` (architecture with AWS icons), `refund-flow.yaml` (flow), `payment-state.yaml` (state), `pay-sequence.yaml` (sequence), `billing-er.yaml` (ER). The `.drawio.svg` is the source of truth, so you don't need to keep the YAML.
|
|
37
|
+
4. **Build with a preview:**
|
|
38
|
+
```bash
|
|
39
|
+
linework build /tmp/spec.yaml -o docs/diagrams/checkout.drawio.svg --png /tmp/checkout.png
|
|
40
|
+
```
|
|
41
|
+
5. **Read the output.** `spec error` lines tell you exactly what to fix. `check:` lists layout problems. Fix every `error` and the warnings that matter, then rebuild.
|
|
42
|
+
6. **Look at the PNG** if you can view images. Check that the diagram tells the story you meant, flows in a sensible direction and doesn't sprawl. If `check` says `too-wide`, remove `direction` (or set `TB`) or split it. If you can't view images, rely on `check` and keep the diagram small.
|
|
43
|
+
7. **Embed the `.drawio.svg`**, never the PNG (see "Putting it in a doc").
|
|
44
|
+
8. **Tell the user** where the file is, what it shows, and that they can edit it by hand in draw.io.
|
|
45
|
+
|
|
46
|
+
## Spec
|
|
47
|
+
|
|
48
|
+
```yaml
|
|
49
|
+
type: architecture # architecture | flow | state | sequence | er
|
|
50
|
+
title: Checkout # optional
|
|
51
|
+
direction: auto # auto (default) | TB | LR | BT | RL
|
|
52
|
+
theme: clean # clean (default) | soft | dark | sketch | blueprint | c4
|
|
53
|
+
groups: # optional boxes around nodes; can nest with `in`
|
|
54
|
+
vpc: { label: Production VPC }
|
|
55
|
+
data: { label: Data tier, in: vpc }
|
|
56
|
+
nodes: # id: { label, kind, tech, in } (all optional)
|
|
57
|
+
user: { label: Shopper, kind: person }
|
|
58
|
+
web: { label: Web app, kind: client, tech: Next.js }
|
|
59
|
+
api: { label: Checkout API, tech: Go, in: vpc, highlight: true }
|
|
60
|
+
queue: { label: order-events, kind: queue, tech: Kafka, in: vpc }
|
|
61
|
+
db: { label: Orders, kind: database, tech: Postgres, in: data }
|
|
62
|
+
stripe: { kind: external, tech: Payments API } # label defaults to "Stripe"
|
|
63
|
+
edges: # "from ARROW to: label"
|
|
64
|
+
- user -> web
|
|
65
|
+
- web ==> api: HTTPS # ==> highlighted: the path the doc is about
|
|
66
|
+
- api -> db: SQL
|
|
67
|
+
- api -.-> queue: OrderPlaced # -.-> async/event, dashed
|
|
68
|
+
- api -> stripe: charge
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
- Ids use letters, digits, `_`, `.` and `-`. The label defaults to the id with its first letter capitalized.
|
|
72
|
+
- Arrows: `->` call or flow, `==>` the same but highlighted, `-.->` async or event, `<->` two-way, `--` no arrowhead. Put spaces around the arrow.
|
|
73
|
+
- `tech` is the small, quieter second line. Use it for the technology, not a description.
|
|
74
|
+
- Node order matters a little. Layout tries to keep the declaration order, so list nodes roughly in reading order.
|
|
75
|
+
- Quote an edge if its label contains `: ` or `#`, for example `- "api -> db: SELECT: orders"`.
|
|
76
|
+
- Architecture nodes can carry a cloud icon: `icon: aws.lambda`, `gcp.cloud_run`, `k8s.pod`, `azure.<name>`. Run `linework icons aws lambda` to search names. Use icons when the doc is about a specific cloud; leave them off for logical diagrams.
|
|
77
|
+
- Styles (`theme:`): use `clean` unless asked. It's minimal: white boxes, hairline borders, groups as gray grounds, IBM Plex Sans, and color only where it means something.
|
|
78
|
+
- `soft`: borderless pastel cards, tinted by kind. For slides and docs that want color coding.
|
|
79
|
+
- `dark`: for dark-mode docs and slides.
|
|
80
|
+
- `sketch`: hand-drawn lines and handwriting. For early proposals ("this is a draft") and whiteboard-style explainers.
|
|
81
|
+
- `blueprint`: light lines on deep blue, monospace. For technical deep dives that want a distinct look.
|
|
82
|
+
- `c4`: C4-model conventions; labels each box with its element type.
|
|
83
|
+
- Color is for meaning, so most nodes stay neutral:
|
|
84
|
+
- `highlight: true` on a node, group or participant, or `==>` on an edge or message, makes it the first thing a reader sees. Highlight the one path or component the surrounding text is about: often one node and the 2 or 3 edges into and out of it. `build` warns when you highlight so much that nothing stands out.
|
|
85
|
+
- `color: <name>` tints a node, group or edge to mark a category, like red for failure paths or green for what's new in this proposal. Say what the color means in the doc text. Names: `blue`, `violet`, `pink`, `red`, `orange`, `amber`, `green`, `teal`, `gray`.
|
|
86
|
+
- Kinds `error` and `success` are red and green in every style.
|
|
87
|
+
- An edge with a color uses the object form: `- { from: api, to: dlq, label: on failure, style: async, color: red }`.
|
|
88
|
+
|
|
89
|
+
Node kinds, also listed by `linework kinds`:
|
|
90
|
+
|
|
91
|
+
| type | kinds (default first) |
|
|
92
|
+
|---|---|
|
|
93
|
+
| architecture | `service`, `person`, `client`, `function`, `database`, `cache`, `storage`, `queue`, `external` |
|
|
94
|
+
| flow | `step`, `decision`, `terminal`, `data`, `error` |
|
|
95
|
+
| state | `state`, `success`, `error` (start and end come from `[*]`) |
|
|
96
|
+
| sequence | `service`, `person`, `client`, `function`, `database`, `queue`, `external` |
|
|
97
|
+
| er | `entity`, `view`, `external` |
|
|
98
|
+
|
|
99
|
+
Flow and state specifics:
|
|
100
|
+
|
|
101
|
+
```yaml
|
|
102
|
+
type: flow
|
|
103
|
+
nodes:
|
|
104
|
+
start: { label: Refund requested, kind: terminal }
|
|
105
|
+
window: { label: Within 30 days?, kind: decision }
|
|
106
|
+
refund: { label: Issue refund }
|
|
107
|
+
deny: { label: Deny with reason, kind: error }
|
|
108
|
+
edges:
|
|
109
|
+
- start -> window
|
|
110
|
+
- window -> refund: "yes" # label every edge leaving a decision
|
|
111
|
+
- window -> deny: "no"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
```yaml
|
|
115
|
+
type: state
|
|
116
|
+
nodes:
|
|
117
|
+
pending: {}
|
|
118
|
+
paid: { kind: success }
|
|
119
|
+
failed: { kind: error }
|
|
120
|
+
edges:
|
|
121
|
+
- "[*] -> pending" # quote edges that use [*]
|
|
122
|
+
- pending -> paid: payment_succeeded
|
|
123
|
+
- pending -> failed: declined
|
|
124
|
+
- "paid -> [*]"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Sequence diagrams use `participants` (in left-to-right order) and `messages`:
|
|
128
|
+
|
|
129
|
+
```yaml
|
|
130
|
+
type: sequence
|
|
131
|
+
participants:
|
|
132
|
+
web: { label: Web app, kind: client }
|
|
133
|
+
api: { label: Checkout API }
|
|
134
|
+
stripe: { kind: external }
|
|
135
|
+
messages:
|
|
136
|
+
- web ==> api: POST /checkout # -> call; ==> highlighted call
|
|
137
|
+
- api -> stripe: create PaymentIntent
|
|
138
|
+
- stripe --> api: client_secret # --> reply (dashed)
|
|
139
|
+
- api --> web: 200 OK
|
|
140
|
+
- note over api, stripe: retried with an idempotency key
|
|
141
|
+
- alt: # alt and par take branches
|
|
142
|
+
- when: payment succeeded
|
|
143
|
+
do:
|
|
144
|
+
- stripe -.-> api: webhook # -.-> async
|
|
145
|
+
- when: declined
|
|
146
|
+
do:
|
|
147
|
+
- api --> web: 402
|
|
148
|
+
- loop: every 30s # loop, opt, critical, break take one block
|
|
149
|
+
do:
|
|
150
|
+
- web -> api: poll status
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Activation bars come from call/reply pairs automatically: each `a -> b` closed by a later `b --> a`. Participants take `color` and `highlight` like nodes.
|
|
154
|
+
|
|
155
|
+
ER diagrams put `fields` on nodes and use Mermaid's crow's-foot notation for edges:
|
|
156
|
+
|
|
157
|
+
```yaml
|
|
158
|
+
type: er
|
|
159
|
+
nodes:
|
|
160
|
+
users:
|
|
161
|
+
fields:
|
|
162
|
+
- id: uuid pk
|
|
163
|
+
- org_id: uuid fk
|
|
164
|
+
- email: text unique
|
|
165
|
+
orgs:
|
|
166
|
+
label: organizations
|
|
167
|
+
fields: [ "id: uuid pk", "name: text" ]
|
|
168
|
+
edges:
|
|
169
|
+
- users }o--|| orgs: belongs to # many users to exactly one org
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Field flags: `pk`, `fk`, `unique`, `null`. Cardinality ends: `||` one, `|o` zero or one, `}o` / `o{` many, `}|` / `|{` one or many. Use `--` for identifying relationships, `..` for the rest.
|
|
173
|
+
|
|
174
|
+
Every option and more examples are in `references/spec.md`, and full specs for each type are in `examples/`. Read `references/style-guide.md` before drawing anything non-trivial.
|
|
175
|
+
|
|
176
|
+
## Editing an existing diagram
|
|
177
|
+
|
|
178
|
+
Always start from the file, never from an old copy of the spec:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
linework show docs/diagrams/checkout.drawio.svg > /tmp/spec.yaml # current spec, hand edits included
|
|
182
|
+
# edit /tmp/spec.yaml; keep the "# linework-base:" line at the top
|
|
183
|
+
linework build /tmp/spec.yaml -o docs/diagrams/checkout.drawio.svg --png /tmp/checkout.png
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
If someone has arranged the diagram by hand in draw.io, `build` merges your changes into their layout instead of starting over. (For sequence diagrams, hand-placed lifeline columns stay; rows always follow message order.)
|
|
187
|
+
- Existing nodes stay exactly where they are.
|
|
188
|
+
- New nodes go next to the node they connect to.
|
|
189
|
+
- Removed nodes disappear.
|
|
190
|
+
- Groups grow to fit new members.
|
|
191
|
+
- Only new edges, and edges whose routes went stale, get rerouted.
|
|
192
|
+
- Their colours, label edits and notes survive.
|
|
193
|
+
|
|
194
|
+
The `merged into the existing layout:` line tells you what happened. Mention it to the user.
|
|
195
|
+
|
|
196
|
+
The `# linework-base:` line tells `build` your spec includes the latest hand edits. Without it, `build` won't delete shapes someone added by hand that your spec doesn't mention. It keeps them and prints a note. If you see that note, run `show` again and redo your edit from its output.
|
|
197
|
+
|
|
198
|
+
`--relayout` throws the hand-made layout away and lays everything out from scratch. **Only use it if the user asks,** because it undoes their layout work.
|
|
199
|
+
|
|
200
|
+
If someone moved shapes by hand and left edges crossing through boxes, `linework tidy file.drawio.svg` reroutes just the broken edges and changes nothing else.
|
|
201
|
+
|
|
202
|
+
## Putting it in a doc
|
|
203
|
+
|
|
204
|
+
- Markdown (GitHub, GitLab, most renderers): ``
|
|
205
|
+
- HTML: `<img src="diagrams/checkout.drawio.svg" alt="Checkout API calls Stripe to charge cards and writes orders to Postgres">`
|
|
206
|
+
- Write alt text that says what the diagram shows, in one sentence, not just its title. Someone using a screen reader should get the point from it.
|
|
207
|
+
- If you used `color:` for categories, add a sentence under the diagram saying what each color means.
|
|
208
|
+
- Tell the user they can edit it by hand: open the file in VS Code with the "Draw.io Integration" extension, in draw.io desktop, or at app.diagrams.net. It saves back into the same file, and your later edits will keep their layout.
|
|
209
|
+
- In a git repo, offer to run `linework git-setup` once, so `git diff` on diagrams shows readable spec changes.
|
|
210
|
+
- Google Docs can't hold SVG. `linework publish file.drawio.svg` copies it into the user's Google Drive folder, and draw.io's Google Docs add-on inserts it from there and refreshes it after changes. Setup and the update steps are in `references/google-docs.md`; walk the user through them the first time.
|
|
211
|
+
|
|
212
|
+
## Letting the user edit
|
|
213
|
+
|
|
214
|
+
If the user wants to adjust a diagram by hand, `linework edit file.drawio.svg` opens it in draw.io in their browser, served from their machine. Saving there writes the file. When they say they're done, run `show` and carry on from its output; their changes are in it.
|
|
215
|
+
|
|
216
|
+
## Commands
|
|
217
|
+
|
|
218
|
+
| command | does |
|
|
219
|
+
|---|---|
|
|
220
|
+
| `build <spec\|-> -o out.drawio.svg [--png p.png] [--relayout]` | layout (or merge into an existing file), write, lint |
|
|
221
|
+
| `show <file> [--geometry]` | print the spec, stamped with `linework-base` |
|
|
222
|
+
| `tidy <file>` | reroute edges that pass through nodes; nothing else changes |
|
|
223
|
+
| `import <file.mmd\|doc.md> [--block N] [-o out.drawio.svg]` | convert Mermaid (flowchart, state, sequence, ER) |
|
|
224
|
+
| `icons <aws\|gcp\|k8s\|azure> [filter]` | list icon names |
|
|
225
|
+
| `edit <file>` | open the diagram in draw.io in the user's browser; saving writes the file |
|
|
226
|
+
| `publish <file...> [--to dir] [--pull]` | copy diagrams into Google Drive for the Docs add-on; `--pull` brings Drive edits back |
|
|
227
|
+
| `git-setup` | make `git diff` show diagram changes as spec changes |
|
|
228
|
+
| `render <file> -o out.png [--scale 2]` | preview image |
|
|
229
|
+
| `check <file>` | lint only; exit 1 on errors |
|
|
230
|
+
| `kinds [type]` | list node kinds |
|
|
231
|
+
| `schema` | JSON Schema of the spec |
|
|
232
|
+
| `skill` | print the path of the guide that matches the installed version |
|
|
233
|
+
| `install-browser` | download the headless Chromium this version uses |
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
type: er
|
|
2
|
+
title: Billing schema
|
|
3
|
+
nodes:
|
|
4
|
+
orgs:
|
|
5
|
+
label: organizations
|
|
6
|
+
fields:
|
|
7
|
+
- id: uuid pk
|
|
8
|
+
- name: text
|
|
9
|
+
- plan: text
|
|
10
|
+
users:
|
|
11
|
+
fields:
|
|
12
|
+
- id: uuid pk
|
|
13
|
+
- org_id: uuid fk
|
|
14
|
+
- email: text unique
|
|
15
|
+
- created_at: timestamptz
|
|
16
|
+
subscriptions:
|
|
17
|
+
fields:
|
|
18
|
+
- id: uuid pk
|
|
19
|
+
- org_id: uuid fk
|
|
20
|
+
- stripe_id: text unique
|
|
21
|
+
- status: text
|
|
22
|
+
invoices:
|
|
23
|
+
fields:
|
|
24
|
+
- id: uuid pk
|
|
25
|
+
- subscription_id: uuid fk
|
|
26
|
+
- amount_cents: int
|
|
27
|
+
- paid_at: timestamptz null
|
|
28
|
+
edges:
|
|
29
|
+
- users }o--|| orgs: belongs to
|
|
30
|
+
- subscriptions }o--|| orgs: billed to
|
|
31
|
+
- invoices }o--|| subscriptions: issued for
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
type: architecture
|
|
2
|
+
title: Checkout
|
|
3
|
+
|
|
4
|
+
groups:
|
|
5
|
+
vpc: { label: Production VPC }
|
|
6
|
+
data: { label: Data tier, in: vpc }
|
|
7
|
+
nodes:
|
|
8
|
+
user: { label: Shopper, kind: person }
|
|
9
|
+
web: { label: Web app, kind: client, tech: Next.js }
|
|
10
|
+
gw: { label: API gateway, kind: service, tech: Envoy, in: vpc }
|
|
11
|
+
api: { label: Checkout API, kind: service, tech: Go, in: vpc, highlight: true }
|
|
12
|
+
worker: { label: Fulfillment worker, kind: service, tech: Go, in: vpc }
|
|
13
|
+
queue: { label: order-events, kind: queue, tech: Kafka, in: vpc }
|
|
14
|
+
db: { label: Orders, kind: database, tech: Postgres, in: data }
|
|
15
|
+
cache: { label: Session cache, kind: cache, tech: Redis, in: data }
|
|
16
|
+
stripe: { label: Stripe, kind: external, tech: Payments API }
|
|
17
|
+
email: { label: SendGrid, kind: external, tech: Email }
|
|
18
|
+
edges:
|
|
19
|
+
- user -> web: browses
|
|
20
|
+
- web ==> gw: HTTPS
|
|
21
|
+
- gw ==> api: gRPC
|
|
22
|
+
- api -> cache: read session
|
|
23
|
+
- api -> db: SQL
|
|
24
|
+
- api ==> stripe: charge
|
|
25
|
+
- api -.-> queue: OrderPlaced
|
|
26
|
+
- queue -.-> worker: consume
|
|
27
|
+
- worker -> db: update status
|
|
28
|
+
- worker -> email: receipt
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
type: sequence
|
|
2
|
+
title: Card payment
|
|
3
|
+
participants:
|
|
4
|
+
user: { label: Shopper, kind: person }
|
|
5
|
+
web: { label: Web app, kind: client }
|
|
6
|
+
api: { label: Checkout API, highlight: true }
|
|
7
|
+
stripe: { label: Stripe, kind: external }
|
|
8
|
+
db: { label: Orders DB, kind: database }
|
|
9
|
+
messages:
|
|
10
|
+
- user -> web: Click "Pay"
|
|
11
|
+
- web ==> api: POST /checkout
|
|
12
|
+
- api -> db: insert order (pending)
|
|
13
|
+
- db --> api: order id
|
|
14
|
+
- api -> stripe: create PaymentIntent
|
|
15
|
+
- stripe --> api: client_secret
|
|
16
|
+
- api --> web: client_secret
|
|
17
|
+
- web -> stripe: confirmCardPayment
|
|
18
|
+
- alt:
|
|
19
|
+
- when: succeeded
|
|
20
|
+
do:
|
|
21
|
+
- stripe -.-> api: webhook payment_succeeded
|
|
22
|
+
- api -> db: mark paid
|
|
23
|
+
- note over api, db: idempotent on event id
|
|
24
|
+
- when: declined
|
|
25
|
+
do:
|
|
26
|
+
- stripe --> web: card_declined
|
|
27
|
+
- web -> web: show error
|
|
28
|
+
- web --> user: result page
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
type: state
|
|
2
|
+
title: Payment lifecycle
|
|
3
|
+
nodes:
|
|
4
|
+
created: { label: Created }
|
|
5
|
+
authorizing: { label: Authorizing }
|
|
6
|
+
authorized: { label: Authorized }
|
|
7
|
+
captured: { label: Captured, kind: success }
|
|
8
|
+
failed: { label: Failed, kind: error }
|
|
9
|
+
voided: { label: Voided }
|
|
10
|
+
refunded: { label: Refunded }
|
|
11
|
+
edges:
|
|
12
|
+
- "[*] -> created"
|
|
13
|
+
- created -> authorizing: submit
|
|
14
|
+
- authorizing -> authorized: approved
|
|
15
|
+
- authorizing -> failed: declined
|
|
16
|
+
- authorized -> captured: capture
|
|
17
|
+
- authorized -> voided: void
|
|
18
|
+
- captured -> refunded: refund
|
|
19
|
+
- failed -> created: retry
|
|
20
|
+
- "captured -> [*]"
|
|
21
|
+
- "voided -> [*]"
|
|
22
|
+
- "refunded -> [*]"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
type: flow
|
|
2
|
+
title: Refund request
|
|
3
|
+
|
|
4
|
+
nodes:
|
|
5
|
+
start: { label: Refund requested, kind: terminal }
|
|
6
|
+
lookup: { label: Look up order }
|
|
7
|
+
window: { label: Within 30 days?, kind: decision }
|
|
8
|
+
amount: { label: Over $500?, kind: decision }
|
|
9
|
+
auto: { label: Auto-approve }
|
|
10
|
+
review: { label: Queue for manual review }
|
|
11
|
+
approved: { label: Approved?, kind: decision }
|
|
12
|
+
refund: { label: Issue refund via Stripe, highlight: true }
|
|
13
|
+
notify: { label: Email customer }
|
|
14
|
+
deny: { label: Deny with reason, kind: error }
|
|
15
|
+
done: { label: Done, kind: terminal }
|
|
16
|
+
edges:
|
|
17
|
+
- start -> lookup
|
|
18
|
+
- lookup -> window
|
|
19
|
+
- window -> amount: "yes"
|
|
20
|
+
- window -> deny: "no"
|
|
21
|
+
- amount -> auto: "no"
|
|
22
|
+
- amount -> review: "yes"
|
|
23
|
+
- review -> approved
|
|
24
|
+
- approved -> refund: "yes"
|
|
25
|
+
- approved -> deny: "no"
|
|
26
|
+
- auto -> refund
|
|
27
|
+
- refund -> notify
|
|
28
|
+
- deny -> notify
|
|
29
|
+
- notify -> done
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
type: architecture
|
|
2
|
+
title: Image pipeline
|
|
3
|
+
groups:
|
|
4
|
+
aws: { label: AWS account }
|
|
5
|
+
nodes:
|
|
6
|
+
user: { label: Uploader, kind: person, icon: aws.users }
|
|
7
|
+
api: { label: Upload API, icon: aws.api_gateway, in: aws }
|
|
8
|
+
sign: { label: Presign, kind: function, icon: aws.lambda, in: aws }
|
|
9
|
+
bucket: { label: Raw images, kind: storage, icon: aws.s3, in: aws }
|
|
10
|
+
queue: { label: resize-jobs, kind: queue, icon: aws.sqs, in: aws }
|
|
11
|
+
resize: { label: Resizer, kind: function, icon: aws.lambda, in: aws }
|
|
12
|
+
table: { label: Image index, kind: database, icon: aws.dynamodb, in: aws }
|
|
13
|
+
cdn: { label: CDN, icon: aws.cloudfront, in: aws }
|
|
14
|
+
edges:
|
|
15
|
+
- user -> api: POST /uploads
|
|
16
|
+
- api -> sign: invoke
|
|
17
|
+
- sign -> bucket: presigned PUT
|
|
18
|
+
- user -> bucket: upload
|
|
19
|
+
- bucket -.-> queue: ObjectCreated
|
|
20
|
+
- queue -.-> resize: poll
|
|
21
|
+
- resize -> bucket: write variants
|
|
22
|
+
- resize -> table: index
|
|
23
|
+
- cdn -> bucket: origin
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Diagrams in Google Docs
|
|
2
|
+
|
|
3
|
+
Google Docs can't hold an SVG, and it strips the metadata out of images you paste in. So a diagram in a Doc is always a picture of a file that lives somewhere else. The trick is to make that somewhere else a Google Drive file that the doc can refresh from.
|
|
4
|
+
|
|
5
|
+
draw.io's Google Docs add-on does the refreshing. It inserts a `.drawio.svg` from Drive as an image, remembers which file it came from, and updates the image when the file changes. `linework publish` puts your diagrams in Drive at a fixed path, so each new version replaces the old file instead of creating a copy.
|
|
6
|
+
|
|
7
|
+
## One-time setup
|
|
8
|
+
|
|
9
|
+
1. Install [Google Drive for desktop](https://www.google.com/drive/download/). It syncs a local folder with your Drive, so publishing is a file copy and needs no Google login in linework.
|
|
10
|
+
2. In a Google Doc, open Extensions > Add-ons > Get add-ons and install "draw.io for Docs" by JGraph.
|
|
11
|
+
|
|
12
|
+
The add-on renders diagrams through draw.io's export service at convert.diagrams.net. If your diagrams can't leave your machine, use the PNG route at the end of this page instead.
|
|
13
|
+
|
|
14
|
+
## Put a diagram in a doc
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
linework publish docs/diagrams/checkout.drawio.svg
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
This copies the file to `My Drive/linework/<project>/docs/diagrams/checkout.drawio.svg`. `<project>` is the git repository's folder name. With several Google accounts, or to use another synced folder, pass `--to <folder>`.
|
|
21
|
+
|
|
22
|
+
Then, in the doc: Extensions > draw.io > Insert diagrams, and pick the file. If the picker doesn't list it, look in its "All files" tab.
|
|
23
|
+
|
|
24
|
+
## After the diagram changes
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
linework build spec.yaml -o docs/diagrams/checkout.drawio.svg # or a hand edit in draw.io
|
|
28
|
+
linework publish docs/diagrams/checkout.drawio.svg
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Give Drive a few seconds to sync. Then, in the doc: Extensions > draw.io > Update diagrams. Every image whose file changed refreshes in place.
|
|
32
|
+
|
|
33
|
+
## Editing from the doc
|
|
34
|
+
|
|
35
|
+
Select the diagram and choose Extensions > draw.io > Edit selected. draw.io opens the Drive file, and saving writes it back to Drive. The repo copy is now behind. Bring the edit back with:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
linework publish --pull docs/diagrams/checkout.drawio.svg
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`publish` refuses to overwrite a Drive copy that someone edited after the last publish. It says so, and you choose `--pull` to take their version or `--force` to replace it.
|
|
42
|
+
|
|
43
|
+
## Without Drive for desktop
|
|
44
|
+
|
|
45
|
+
- Upload the `.drawio.svg` at drive.google.com and insert it with the add-on as above. To update it later, use the file's Manage versions > Upload new version in Drive. Uploading it again as a new file breaks the link to the doc.
|
|
46
|
+
- Or skip the add-on: `linework render docs/diagrams/checkout.drawio.svg -o checkout.png --scale 2`, insert the PNG, and put a link to the source file under it. You'll replace the image by hand when it changes.
|