flowfig 0.7.0 → 0.8.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/README.md +55 -23
- package/dist/check.js +68 -6
- package/dist/cli.js +24 -13
- package/dist/code.d.ts +26 -0
- package/dist/code.js +568 -0
- package/dist/diff.js +12 -5
- package/dist/draw.js +1 -1
- package/dist/edges.d.ts +7 -0
- package/dist/edges.js +557 -0
- package/dist/geometry.d.ts +11 -2
- package/dist/geometry.js +255 -67
- package/dist/guide.d.ts +22 -2
- package/dist/guide.js +282 -219
- package/dist/imports.d.ts +11 -0
- package/dist/imports.js +235 -0
- package/dist/index.js +36 -28
- package/dist/load.d.ts +2 -0
- package/dist/load.js +24 -1
- package/dist/mcp.d.ts +7 -0
- package/dist/mcp.js +22 -9
- package/dist/model.d.ts +13 -2
- package/dist/model.js +54 -11
- package/dist/scene.d.ts +2 -0
- package/dist/source.d.ts +1 -1
- package/dist/source.js +3 -3
- package/dist/svg.js +49 -32
- package/dist/type-index.d.ts +55 -0
- package/dist/type-index.js +383 -0
- package/dist/types.d.ts +32 -0
- package/dist/types.js +733 -0
- package/dist/verify.d.ts +25 -3
- package/dist/verify.js +67 -22
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/guide.js
CHANGED
|
@@ -1,242 +1,203 @@
|
|
|
1
|
+
export const PLAIN_EXAMPLES = [
|
|
2
|
+
{
|
|
3
|
+
field: 'label',
|
|
4
|
+
rule: 'A box label names the role in 1 to 4 plain words.',
|
|
5
|
+
bad: 'authRateLimiter',
|
|
6
|
+
good: 'Rate limiter',
|
|
7
|
+
},
|
|
8
|
+
{ field: 'sub', rule: 'A `sub` line holds a short plain detail.', bad: 'redis.incr()', good: '5 tries a minute' },
|
|
9
|
+
{ field: 'edge', rule: 'An edge label names the action or the data.', bad: 'validateCredentials()', good: 'check password' },
|
|
10
|
+
{
|
|
11
|
+
field: 'say',
|
|
12
|
+
rule: 'No code names in labels or sentences. The code name goes in `source` and shows on hover.',
|
|
13
|
+
bad: 'loginHandler calls findUserByEmail',
|
|
14
|
+
good: 'The API finds the user by email',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
field: 'say',
|
|
18
|
+
rule: 'A `say` line or a caption has 15 words or fewer, with the actor first. The check warns above 20 words.',
|
|
19
|
+
bad: 'A session is made after the password check',
|
|
20
|
+
good: 'The API makes a session',
|
|
21
|
+
style: true,
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
field: 'step',
|
|
25
|
+
rule: 'A step label has 1 to 4 words. The check skips this rule.',
|
|
26
|
+
bad: 'How a user logs in',
|
|
27
|
+
good: 'Log in',
|
|
28
|
+
style: true,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
field: 'say',
|
|
32
|
+
rule: 'No filler words: seamless, robust, powerful, leverage, effortless.',
|
|
33
|
+
bad: 'seamless lookups',
|
|
34
|
+
good: 'cached lookups',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
field: 'data',
|
|
38
|
+
rule: 'Data shows real values from the code. The check skips this rule.',
|
|
39
|
+
bad: 'an error response',
|
|
40
|
+
good: '401 bad_credentials',
|
|
41
|
+
style: true,
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
const plainBullet = ({ field, rule, bad, good }) => {
|
|
45
|
+
const q = (t) => (field === 'say' || field === 'step' ? `"${t}"` : `\`"${t}"\``);
|
|
46
|
+
return `- ${rule} Bad: ${q(bad)}. Good: ${q(good)}.`;
|
|
47
|
+
};
|
|
1
48
|
export const GUIDE = `# flowfig guide
|
|
2
49
|
|
|
3
|
-
flowfig draws animated flow figures. A figure has boxes, the edges between the boxes, and steps. In each step, a packet moves
|
|
4
|
-
the edges. The output is one animated SVG with no script. The SVG plays in a GitHub README, in PR and issue
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
You write a JSON spec. You never write SVG by hand. The command \`npx flowfig\` checks the spec and renders it.
|
|
50
|
+
flowfig draws animated flow figures. A figure has boxes, the edges between the boxes, and steps. In each step, a packet moves
|
|
51
|
+
along the edges. The output is one animated SVG of 5 to 50 kB, with no script. The SVG plays in a GitHub README, in PR and issue
|
|
52
|
+
comments, and in blog posts.
|
|
8
53
|
|
|
9
|
-
|
|
54
|
+
You write a JSON spec. You never write SVG by hand. \`npx flowfig\` checks the spec, renders it and prints the figure back.
|
|
10
55
|
|
|
11
|
-
|
|
56
|
+
## Scope
|
|
12
57
|
|
|
13
|
-
|
|
14
|
-
- The map with a rail (\`"rail": true\`). The rail is a lifeline diagram under the map. It has one row for each message.
|
|
15
|
-
- The rail alone (\`"rail": "only"\`). Use it when the reader needs only the order of the messages, for example when the map is already in the same document.
|
|
58
|
+
flowfig draws how something works: parts, the messages between them, and the order of the messages.
|
|
16
59
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
answer with \`"async": true\`: every send to a queue or a topic, every emitted event, and every call the caller does not await.
|
|
60
|
+
- An architecture, a data flow or a pipeline: the map of boxes and edges. Group parts by service, network or trust boundary.
|
|
61
|
+
- A flowchart with branches: \`shape: "decision"\` for each branch, one step per path.
|
|
20
62
|
|
|
21
|
-
|
|
63
|
+
flowfig does not draw class or ER diagrams (fields, types, cardinality), charts of numbers or mind maps. If the user asks for one
|
|
64
|
+
of these, say so and suggest Mermaid (\`classDiagram\`, \`erDiagram\`). Draw nothing with flowfig.
|
|
22
65
|
|
|
23
|
-
|
|
66
|
+
## Topics
|
|
24
67
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
| An architecture, a data flow, a pipeline | The map. Group parts by service, network or trust boundary. \`store\` for data at rest. |
|
|
28
|
-
| A request lifecycle, a call chain | The map with \`"rail": true\`. One message per hop, with its real payload in \`data\`. |
|
|
29
|
-
| A sequence diagram only | \`"rail": "only"\`. |
|
|
30
|
-
| A state lifecycle, a state machine | One box per state, one edge per transition, labeled with its event. One step per path. Mark the first state with \`mark: "start"\` and each final state with \`mark: "end"\`. |
|
|
31
|
-
| A flowchart with branches | \`shape: "decision"\` for each branch. One step per path. |
|
|
32
|
-
| A roadmap or a timeline | \`timeline: true\`. One labeled group per track, in a \`column\` group. Items with \`from\` and \`to\` (dates), a milestone with \`from\` only, an edge for a dependency, \`today\` for the line. A dependent item starts after its source ends. |
|
|
33
|
-
| A process across roles (a ticket, an order, a refund) | \`lanes: true\`. One labeled group per role, in a \`column\` group. Put each step in the lane of the role that does it. Link each step with \`source\` to the SOP heading. If the steps do not fit the width, flowfig wraps the time columns into blocks and links the blocks with labeled stubs, so keep the whole process in one figure. Give the outcomes of one decision the same \`at\`. |
|
|
68
|
+
A topic gives the detail for one kind of figure. Before you write that kind of spec, print its topic with
|
|
69
|
+
\`npx flowfig docs <topic>\`.
|
|
34
70
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
71
|
+
- \`rail\`: a request lifecycle, a call chain or a Mermaid \`sequenceDiagram\`.
|
|
72
|
+
- \`marks\`: a state lifecycle, a state machine or a Mermaid \`stateDiagram\`.
|
|
73
|
+
- \`timeline\`: a roadmap, a plan with dates or a Mermaid \`gantt\`.
|
|
74
|
+
- \`lanes\`: a process that several roles do (a ticket, an order, a refund), or an SOP.
|
|
75
|
+
- \`verify\`: a verify finding in the render output, or a check in CI.
|
|
38
76
|
|
|
39
77
|
## Workflow
|
|
40
78
|
|
|
41
79
|
### 1. Pick the scope
|
|
42
80
|
|
|
43
|
-
If the code has more than one flow, name each flow in the reply.
|
|
44
|
-
|
|
45
|
-
every part. Keep each figure to 12 boxes or fewer.
|
|
81
|
+
If the code has more than one flow, name each flow in the reply. Draw one flow or one structure view. For the whole
|
|
82
|
+
system, draw one top view with groups, or a set of figures that covers every part. Keep each figure to 12 boxes or fewer.
|
|
46
83
|
|
|
47
84
|
### 2. Write the fact list
|
|
48
85
|
|
|
49
|
-
Before the spec,
|
|
50
|
-
|
|
86
|
+
Before the spec, list the facts that the figure must show. Use the code and its wiring (config, compose, route
|
|
87
|
+
and queue files) or the pasted Mermaid. Give each fact its \`file:line\`:
|
|
51
88
|
|
|
52
89
|
- every part (service, function, store, queue, external system);
|
|
53
|
-
- every call, in order,
|
|
54
|
-
|
|
55
|
-
- every
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
- for a process document (an SOP): every deadline, every message to a person (an email, a notice), every choice that a person
|
|
60
|
-
makes, and every wait for a reply. Put each one in a box \`sub\`, a step \`say\` or a \`data\` card. A small fact still counts.
|
|
61
|
-
Draw each path to its end: after a rejection, also draw the next step that the document gives. Give each path its own step.
|
|
62
|
-
|
|
63
|
-
If the code does not show a fact, leave the fact out. Do not guess a part, a name or an order.
|
|
90
|
+
- every call, in order, as \`caller → callee: payload (file:line of the call)\`;
|
|
91
|
+
- every call that does not wait for an answer, and every consumer of each queue or topic;
|
|
92
|
+
- every branch, every error path and every end state;
|
|
93
|
+
- for an SOP, the facts in the \`lanes\` topic.
|
|
94
|
+
|
|
95
|
+
If the code does not show a fact, leave it out. Do not guess a part, a name or an order.
|
|
64
96
|
|
|
65
97
|
### 3. Write the spec
|
|
66
98
|
|
|
67
|
-
Each fact becomes a box, an edge, a beat, a \`data\` card or a \`show\` row.
|
|
68
|
-
real example data from the code or its tests.
|
|
69
|
-
Give each box and edge that draws code a \`source\`, from the fact list: \`"src/auth/login.ts#verifyPassword"\`. A store or an outside part may have none.
|
|
70
|
-
A box that draws a step from a document links to that document: \`"docs/sop/refunds.md#step-3-approve-the-refund"\`, the heading as a GitHub anchor. \`verify\` checks it the same way.
|
|
99
|
+
Each fact becomes a box, an edge, a beat, a \`data\` card or a \`show\` row. Write each text in plain words (see "Plain text").
|
|
100
|
+
Use real example data from the code or its tests.
|
|
71
101
|
|
|
72
|
-
|
|
102
|
+
Give each box and edge that draws code a \`source\` from the fact list: \`"src/auth/login.ts#verifyPassword"\`. The code name goes
|
|
103
|
+
in \`source\`, and the reader sees it on hover. A method uses \`Owner.name\`: \`"src/auth/session.ts#Session.refresh"\`. An edge
|
|
104
|
+
\`source\` names the function that makes the call. An edge needs no \`source\` when the code of its \`from\` box makes the call.
|
|
73
105
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
| \`B-->>A: text\` (a reply) | a hop on the same edge with \`back: true\` |
|
|
79
|
-
| \`A-)B: text\` (async) | a hop with \`async: true\` |
|
|
80
|
-
| \`par ... and ... end\` | the hops of all branches in one beat |
|
|
81
|
-
| \`alt\` / \`opt\` | one step per path |
|
|
82
|
-
| \`stateDiagram\` states and transitions | boxes, and edges labeled with the event |
|
|
106
|
+
An edge across a process gets \`via\`: the name that both sides use in the code. The \`via\` is the queue or topic
|
|
107
|
+
(\`"order-paid"\`), the HTTP path (\`"/internal/users"\`), or the store name of the caller (\`"sales_facts"\`). A store box (a
|
|
108
|
+
table, a file, a cache key) may have no \`source\`. An edge to a store box still needs \`via\`. A route handler with no name keeps a file \`source\`. An
|
|
109
|
+
edge into it uses \`via\` with the route path. An edge out of it in the same process uses no \`via\`.
|
|
83
110
|
|
|
84
|
-
|
|
85
|
-
|
|
111
|
+
Mark a hop that does not wait for an answer with \`"async": true\`. This rule covers every send to a queue or topic, every
|
|
112
|
+
emitted event, and every call without \`await\`. A pasted Mermaid design wins over this rule: keep each arrow as the Mermaid draws it.
|
|
86
113
|
|
|
87
114
|
### 4. Render, then fix
|
|
88
115
|
|
|
116
|
+
Run the render from the repo root.
|
|
117
|
+
|
|
89
118
|
\`\`\`bash
|
|
90
119
|
npx flowfig - out.svg <<'SPEC'
|
|
91
120
|
{ "props": { "layout": ..., "edges": [...], "steps": [...] } }
|
|
92
121
|
SPEC
|
|
93
122
|
\`\`\`
|
|
94
123
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
- Fix a layout fault by changing the layout first: put parts in rows or columns, route an edge \`around\`, or change a gap.
|
|
99
|
-
Never remove a fact from the fact list to pass the check. If you must remove one, name it in the reply.
|
|
100
|
-
- If \`small-text\` appears, the figure is too wide. Put the parts in two rows, move a detail from \`label\` to \`sub\`, or split
|
|
101
|
-
the figure. Use more steps in one figure before you make a second figure. Keep the real name from the code in the label:
|
|
102
|
-
\`ReportsController\` stays \`ReportsController\`, not \`Controller\`. Do not change \`--width\` to pass the check: the
|
|
103
|
-
reader sees the figure at the real page width.
|
|
104
|
-
- If \`text-overflow\` appears, a text is wider than its box. Give the box a larger \`width\`, move a detail from \`label\` to
|
|
105
|
-
\`sub\`, or put the detail in the step \`say\`. Never cut a fact, a number or a unit to make a text fit: "within 30 days of
|
|
106
|
-
delivery" does not become "within 30 days". If you must shorten a text, keep every fact and name the change in the reply.
|
|
107
|
-
- Fix every other warning, or tell the user why it stays.
|
|
108
|
-
- Do not use \`--no-check\` to hide a fault.
|
|
124
|
+
If the check finds an error, the render writes no SVG. The render prints the check lines. Next come one line per edge
|
|
125
|
+
(\`from -> to: label\`) and one line per step (\`step "<label>": N hops\`). Last come the verify findings and counts. This
|
|
126
|
+
output is the read-back: you need no other command.
|
|
109
127
|
|
|
110
|
-
|
|
128
|
+
Fix the figure and render again:
|
|
111
129
|
|
|
112
|
-
|
|
113
|
-
|
|
130
|
+
- Compare the edge lines with the fact list. Each edge goes from the caller to the callee that its fact names.
|
|
131
|
+
- Fix each verify finding. The \`verify\` topic explains each one.
|
|
132
|
+
- Fix a layout fault in the layout first: rows, columns, \`around\` or a gap. Never remove a fact to pass the check.
|
|
133
|
+
- \`small-text\`: the figure is too wide. Use two rows, more steps, or two figures. Do not change \`--width\`.
|
|
134
|
+
- \`text-overflow\`: give the box a larger \`width\`, or move a detail to \`sub\` or \`say\`. Never cut a fact, a number or a
|
|
135
|
+
unit: "within 30 days of delivery" does not become "within 30 days".
|
|
136
|
+
- \`plain-text\`: write the text again in plain words. The message names the reason. Keep a product name.
|
|
137
|
+
- Fix every other warning, or tell the user why it stays. Never use \`--no-check\` to hide a fault.
|
|
114
138
|
|
|
115
|
-
|
|
139
|
+
### 5. Look at the SVG
|
|
116
140
|
|
|
117
|
-
|
|
141
|
+
If you can open a browser, take two screenshots of the SVG a few seconds apart. If the browser blocks \`file://\` URLs, run
|
|
142
|
+
\`python3 -m http.server\`. If you cannot open a browser, write "not looked at" in the reply. Never report a look that you did
|
|
143
|
+
not do.
|
|
118
144
|
|
|
119
|
-
|
|
120
|
-
screenshot. Wait a few seconds and take a second screenshot to see a later beat. If you cannot open a browser, write "not
|
|
121
|
-
looked at" in the reply. Never report a look that you did not do. A browser tool can block \`file://\` URLs. If it does, serve the folder
|
|
122
|
-
with \`python3 -m http.server\`.
|
|
123
|
-
|
|
124
|
-
### 7. Write the reply
|
|
145
|
+
### 6. Write the reply
|
|
125
146
|
|
|
126
147
|
The reply has these parts, in this order:
|
|
127
148
|
|
|
128
149
|
1. the path of each SVG;
|
|
129
|
-
2. what each figure shows
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
6. one line \`npx flowfig open <path>\` for each SVG, at the end of the reply. Do not run that command yourself.
|
|
150
|
+
2. what each figure shows, with the counts and names copied from the \`figure:\`, edge and step lines;
|
|
151
|
+
3. the flow you drew, why, and the other flows that exist;
|
|
152
|
+
4. each fact that the figure leaves out, and why;
|
|
153
|
+
5. the lines \`0 errors, 0 warnings\` and \`figure: ...\`, copied as printed, and whether you looked at the SVG;
|
|
154
|
+
6. the verify count line, copied as printed;
|
|
155
|
+
7. at the end, one line \`npx flowfig open <path>\` for each SVG. Do not run it yourself.
|
|
136
156
|
|
|
137
|
-
To change an SVG later, print its spec with
|
|
157
|
+
To change an SVG later, print its spec with \`npx flowfig --spec out.svg\`.
|
|
138
158
|
|
|
139
159
|
## Spec reference
|
|
140
160
|
|
|
141
|
-
\`props\` has
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
- \`
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
| --------- | --------------------------------------------------------------------------------------------------------- |
|
|
169
|
-
| \`id\` | Required. The name that edges and steps use. It must be unique in the figure. |
|
|
170
|
-
| \`label\` | Required. The title in the box. |
|
|
171
|
-
| \`sub\` | A smaller line under the label. |
|
|
172
|
-
| \`shape\` | \`"box"\` (default), \`"decision"\` (a diamond) or \`"store"\` (a database cylinder for data at rest). |
|
|
173
|
-
| \`at\` | In a \`lanes\` figure: the time column of the box, 0 first. Default: the order in which the steps first reach the box. |
|
|
174
|
-
| \`from\` | In a \`timeline\` figure: the start of the item, or the date of a milestone, as YYYY-MM-DD. |
|
|
175
|
-
| \`to\` | In a \`timeline\` figure: the last day of the item, as YYYY-MM-DD. Without it the box is a milestone. |
|
|
176
|
-
| \`width\` | Width in px. This overrides the width that the layout picks. |
|
|
177
|
-
| \`source\` | The code this draws: \`path\` or \`path#symbol\`, relative to the repo root. \`flowfig verify\` checks it. |
|
|
178
|
-
| \`lines\` | The least number of text lines that a content card keeps. The card still grows to fit its content. |
|
|
179
|
-
| \`tone\` | The state color of the box: a 1 px border and a light tint. Use \`blue\`, \`purple\`, \`green\`, \`orange\`, \`red\` or \`gray\`. |
|
|
180
|
-
| \`mark\` | \`"start"\` or \`"end"\` | A lifecycle mark: a filled dot before a start state, a ringed dot after an end state. |
|
|
181
|
-
|
|
182
|
-
### edges
|
|
183
|
-
|
|
184
|
-
An edge has these fields.
|
|
185
|
-
|
|
186
|
-
- \`id\`: the name that steps use. Default: \`from->to\`.
|
|
187
|
-
- \`from\` and \`to\`: the \`id\` of a box or a group.
|
|
188
|
-
- \`label\`: text on the edge, drawn as a small pill.
|
|
189
|
-
- \`around\`: \`"above"\` or \`"below"\`. This routes the edge over or under the boxes in between (loops, skip-ahead edges).
|
|
190
|
-
- \`quiet\`: if \`true\`, the SVG draws the edge only while a step uses it.
|
|
191
|
-
- \`source\`: the code this edge draws, as \`path\` or \`path#symbol\`. \`flowfig verify\` checks it.
|
|
192
|
-
|
|
193
|
-
### steps
|
|
194
|
-
|
|
195
|
-
A step has \`label\` and \`flow\`. It can also have \`caption\` (the line under the figure while no beat has a \`say\`) and \`nodes\` (ids of
|
|
196
|
-
boxes to highlight for the whole step).
|
|
197
|
-
|
|
198
|
-
\`flow\` is a list of beats. A beat is one of these:
|
|
199
|
-
|
|
200
|
-
- an edge id (a string);
|
|
201
|
-
- an array of edge ids, which run at the same time;
|
|
202
|
-
- an object \`{ edges?, say?, show?, light?, ms? }\`. A beat with no \`edges\` is a pause.
|
|
203
|
-
|
|
204
|
-
The beat fields:
|
|
205
|
-
|
|
206
|
-
- \`edges\`: an edge id, a hop object, or an array of these. A hop object is \`{ edge, back?, data?, tone?, async?, source? }\`.
|
|
207
|
-
- \`back: true\` runs the packet from the \`to\` box to the \`from\` box.
|
|
208
|
-
- \`data\` is a small card that moves with the packet.
|
|
209
|
-
- \`async: true\` marks a message that does not wait for an answer. The rail draws it dashed, with an \`async\` tag.
|
|
210
|
-
- \`tone\`: the color of this hop for its beat. The packet, the data card, the edge, the label pill and the arrival box take the color. The trail after the beat stays the accent.
|
|
211
|
-
- \`green\`: a success or a cache hit. \`orange\`: a warning, a miss or a retry. \`red\`: an error or a rejected input.
|
|
212
|
-
- \`gray\`: idle or skipped. \`purple\`: async or background. \`blue\`: the default row color.
|
|
213
|
-
- If the hop has no \`tone\`, the arrival box uses its box \`tone\`, then the accent. A hop \`tone\` wins over a box \`tone\`.
|
|
214
|
-
- \`say\`: the caption for the beat.
|
|
215
|
-
- \`show\`: \`{ boxId: [row, ...] }\`. This fills the content card of each named box. The card keeps the rows until the step ends.
|
|
216
|
-
- \`light\`: ids of boxes to highlight for this beat.
|
|
217
|
-
- \`ms\`: how long the beat lasts. Default: the time one packet needs to cross an edge.
|
|
218
|
-
|
|
219
|
-
A row of a content card is \`{ tag?, tone?, text, meta?, mark?, mono? }\`.
|
|
220
|
-
|
|
221
|
-
- \`tag\`: a short colored label at the start of the line.
|
|
222
|
-
- \`tone\`: the color of the tag: \`blue\` (default), \`purple\`, \`green\`, \`orange\`, \`red\` or \`gray\`.
|
|
223
|
-
- \`text\`: the main text.
|
|
224
|
-
- \`meta\`: muted text after the main text.
|
|
225
|
-
- \`mark\`: a mark at the right end of the line, such as a check or "new".
|
|
226
|
-
- \`mono\`: if \`true\`, the text uses a monospace font.
|
|
161
|
+
\`props\` has \`layout\` (required), \`edges\` (required), \`steps\`, \`speed\` and \`theme\`. \`speed\` is the ms for a packet to
|
|
162
|
+
cross one edge (default 900). \`theme\` sets \`accent\`, \`fg\`, \`muted\`, \`bg\`, \`surface\`, \`border\` and \`font\`. The topics
|
|
163
|
+
give \`rail\`, \`lanes\`, \`timeline\` and \`today\`.
|
|
164
|
+
|
|
165
|
+
A layout group has \`children\`, and optional \`id\` (an edge target), \`label\` (a framed title), \`direction\`, \`gap\` (px),
|
|
166
|
+
\`align\`. \`direction\` is \`"row"\` or \`"column"\`. \`align\` is \`"start"\`, \`"center"\` or \`"end"\`. Every other layout item
|
|
167
|
+
is a box.
|
|
168
|
+
|
|
169
|
+
A box has a unique \`id\` and a \`label\` (both required). Its optional fields are \`sub\` (a smaller line), \`shape\`,
|
|
170
|
+
\`width\` (px), \`source\`, \`lines\` and \`tone\`. \`shape\` is \`"box"\`, \`"decision"\` or \`"store"\`. \`source\` is
|
|
171
|
+
\`path#Owner.name\`, from the repo root. \`lines\` is the least lines of a content card. \`tone\` is \`blue\`, \`purple\`,
|
|
172
|
+
\`green\`, \`orange\`, \`red\` or \`gray\`. The topics give \`at\`, \`from\`, \`to\`
|
|
173
|
+
and \`mark\`.
|
|
174
|
+
|
|
175
|
+
An edge has \`from\` and \`to\` (a box or group \`id\`), and optional \`id\` (default \`from->to\`), \`label\`, \`source\` and \`via\`.
|
|
176
|
+
\`around: "above"\` or \`"below"\` routes it over or under the boxes between. \`quiet: true\` draws it only while a step uses it.
|
|
177
|
+
|
|
178
|
+
A step has \`label\` and \`flow\`, and optional \`caption\` and \`nodes\` (boxes to highlight). \`flow\` is a list of beats. A
|
|
179
|
+
beat is an edge id or an array of edge ids that run at the same time. A beat can also be
|
|
180
|
+
\`{ edges?, say?, show?, light?, ms? }\`.
|
|
181
|
+
|
|
182
|
+
- \`edges\`: an edge id, a hop, or an array of these. A hop is \`{ edge, back?, data?, tone?, async?, source?, via? }\`.
|
|
183
|
+
\`back: true\` runs the packet from \`to\` to \`from\`. \`data\` is a card that moves with the packet. \`tone\` is \`green\`
|
|
184
|
+
(success), \`orange\` (a retry), \`red\` (an error), \`gray\` (idle) or \`purple\` (async).
|
|
185
|
+
- \`say\`: the caption for the beat. \`light\`: boxes to highlight. \`ms\`: the beat length.
|
|
186
|
+
- \`show\`: \`{ boxId: [{ tag?, tone?, text, meta?, mark?, mono? }] }\`. The rows fill the content card of each box until the
|
|
187
|
+
step ends.
|
|
227
188
|
|
|
228
189
|
## Content rules
|
|
229
190
|
|
|
230
|
-
-
|
|
231
|
-
-
|
|
232
|
-
-
|
|
233
|
-
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
191
|
+
- Use \`shape: "store"\` for data at rest and \`shape: "decision"\` for a branch.
|
|
192
|
+
- Keep one main path, left to right. Put side parts in a \`column\` group.
|
|
193
|
+
- A \`quiet: true\` edge needs a beat that uses it.
|
|
194
|
+
- Keep an SVG to one or two steps: it loops with no controls. For tabs or pause, use the React player \`<Flow {...props} />\`.
|
|
195
|
+
|
|
196
|
+
### Plain text
|
|
197
|
+
|
|
198
|
+
The reader does not know the code.
|
|
199
|
+
|
|
200
|
+
${PLAIN_EXAMPLES.map(plainBullet).join('\n')}
|
|
240
201
|
|
|
241
202
|
## Example
|
|
242
203
|
|
|
@@ -252,11 +213,11 @@ A row of a content card is \`{ tag?, tone?, text, meta?, mark?, mono? }\`.
|
|
|
252
213
|
},
|
|
253
214
|
"edges": [
|
|
254
215
|
{ "id": "req", "from": "client", "to": "api", "label": "GET /users/42" },
|
|
255
|
-
{ "id": "q", "from": "api", "to": "db", "label": "
|
|
216
|
+
{ "id": "q", "from": "api", "to": "db", "label": "read user" }
|
|
256
217
|
],
|
|
257
218
|
"steps": [
|
|
258
219
|
{
|
|
259
|
-
"label": "
|
|
220
|
+
"label": "Read a user",
|
|
260
221
|
"flow": [
|
|
261
222
|
{ "edges": { "edge": "req", "data": "GET /users/42" }, "say": "The browser asks for user 42." },
|
|
262
223
|
{ "edges": "q", "show": { "db": [{ "tag": "row", "tone": "gray", "text": "Ada Lovelace" }] }, "say": "The API server reads the row." },
|
|
@@ -271,52 +232,154 @@ A row of a content card is \`{ tag?, tone?, text, meta?, mark?, mono? }\`.
|
|
|
271
232
|
## Commands
|
|
272
233
|
|
|
273
234
|
\`\`\`bash
|
|
274
|
-
npx flowfig
|
|
275
|
-
npx flowfig
|
|
276
|
-
npx flowfig
|
|
277
|
-
npx flowfig
|
|
278
|
-
npx flowfig
|
|
279
|
-
npx flowfig diff <old> <new> # list what changed in the spec between two figures
|
|
280
|
-
npx flowfig --spec out.svg # print the spec that an SVG carries
|
|
281
|
-
npx flowfig open out.svg # show the figure in the default browser
|
|
282
|
-
npx flowfig gif out.svg [out.gif] # write an animated GIF (needs Chrome, Edge, Chromium or Brave)
|
|
283
|
-
npx flowfig docs # print this guide
|
|
284
|
-
npx flowfig init # write these instructions for the coding agents of a repo
|
|
235
|
+
npx flowfig spec.json out.svg # render a spec file, or a .ts module whose default export is a spec
|
|
236
|
+
npx flowfig check <input> [--json] # list the faults of a spec or an SVG
|
|
237
|
+
npx flowfig --spec out.svg # print the spec that an SVG carries
|
|
238
|
+
npx flowfig gif out.svg [out.gif] # write an animated GIF (needs Chrome, Edge, Chromium or Brave)
|
|
239
|
+
npx flowfig docs [topic] # print this guide, or one topic
|
|
285
240
|
\`\`\`
|
|
286
241
|
|
|
287
|
-
|
|
288
|
-
\`--min-text\` sets the smallest text that the reader should get. \`--no-check\` skips the check.
|
|
242
|
+
\`--strict\` makes warnings errors. \`--width\` sets the page width. \`--no-check\` skips the check.
|
|
289
243
|
`;
|
|
244
|
+
export const TOPICS = {
|
|
245
|
+
rail: `# flowfig topic: rail
|
|
246
|
+
|
|
247
|
+
Read this topic for a request lifecycle, an API call chain or a Mermaid \`sequenceDiagram\`.
|
|
248
|
+
|
|
249
|
+
A spec has three forms.
|
|
250
|
+
|
|
251
|
+
- The map (the default). The map shows the boxes and the edges. A packet moves along an edge in each beat.
|
|
252
|
+
- The map with a rail (\`"rail": true\` in \`props\`). The rail is a lifeline diagram under the map. It has one row for each message.
|
|
253
|
+
- The rail alone (\`"rail": "only"\`). Use it when the reader needs only the message order, for example when the document
|
|
254
|
+
already has the map.
|
|
255
|
+
|
|
256
|
+
Rules for a rail:
|
|
257
|
+
|
|
258
|
+
- Put each message on an edge. Put each phase in a step. Put messages that run at the same time in one beat.
|
|
259
|
+
- Give each hop its real payload in \`data\`: \`"POST /login"\`, \`"sid cookie"\`.
|
|
260
|
+
- Mark a message that does not wait for an answer with \`"async": true\` on the hop. This rule covers every send to a queue or
|
|
261
|
+
topic, every emitted event, and every call without \`await\`. The rail draws such a message dashed, with an \`async\` tag.
|
|
262
|
+
- Draw a reply as a hop back on the same edge, with \`"back": true\`.
|
|
263
|
+
- Draw an error reply the same way, with the error in \`data\`. Example:
|
|
264
|
+
\`{ "edge": "login", "back": true, "data": "401 bad_credentials" }\`.
|
|
265
|
+
- A call that stays inside one part (a hash check, a guard) is not a message. Put it in \`say\` or in a \`show\` row of that part.
|
|
266
|
+
|
|
267
|
+
A Mermaid \`sequenceDiagram\` maps this way:
|
|
268
|
+
|
|
269
|
+
- \`participant\`: a box.
|
|
270
|
+
- \`A->>B: text\`: an edge from A to B, and a hop with \`"data": "text"\`.
|
|
271
|
+
- \`B-->>A: text\` (a reply): a hop on the same edge with \`"back": true\`.
|
|
272
|
+
- \`A-)B: text\`: a hop with \`"async": true\`.
|
|
273
|
+
- \`par ... and ... end\`: the hops of all branches in one beat.
|
|
274
|
+
- \`alt\` and \`opt\`: one step per path.
|
|
275
|
+
|
|
276
|
+
A pasted design wins over the async rule: keep each arrow as the Mermaid draws it. \`A->>B\` stays a plain hop, also for a send
|
|
277
|
+
to a queue. If you think the design is wrong, say so in the reply.
|
|
278
|
+
`,
|
|
279
|
+
timeline: `# flowfig topic: timeline
|
|
280
|
+
|
|
281
|
+
Read this topic for a roadmap, a plan with dates or a Mermaid \`gantt\`. Read the dates from the document.
|
|
282
|
+
|
|
283
|
+
- Set \`"timeline": true\` in \`props\`.
|
|
284
|
+
- Put one labeled group per track in a \`column\` group.
|
|
285
|
+
- Give each item box \`from\` and \`to\`, as YYYY-MM-DD. \`from\` is the first day of the item. \`to\` is the last day.
|
|
286
|
+
- A milestone is a box with \`from\` only.
|
|
287
|
+
- Draw a dependency as an edge from the first item to the dependent item. A dependent item starts after its source ends.
|
|
288
|
+
- Set \`today\` in \`props\`, as YYYY-MM-DD, to stop the today line at that date. Default: the last date of the items.
|
|
289
|
+
- A Mermaid \`gantt\` section becomes a track. Each task becomes an item, and each \`after\` becomes an edge.
|
|
290
|
+
`,
|
|
291
|
+
lanes: `# flowfig topic: lanes
|
|
292
|
+
|
|
293
|
+
Read this topic for a process that several roles do: a ticket, an order, a refund or an SOP.
|
|
294
|
+
|
|
295
|
+
- Set \`"lanes": true\` in \`props\`.
|
|
296
|
+
- Put one labeled group per role in a \`column\` group.
|
|
297
|
+
- Put each step box in the lane of the role that does it.
|
|
298
|
+
- The boxes run left to right in step order. The box field \`at\` sets the time column of a box, 0 first. Default: the order in
|
|
299
|
+
which the steps first reach the box.
|
|
300
|
+
- Give the outcomes of one decision the same \`at\`.
|
|
301
|
+
- Link each step box with \`source\` to the SOP heading: \`"docs/sop/refunds.md#step-3-approve-the-refund"\`. The part after
|
|
302
|
+
\`#\` is the heading as a GitHub anchor.
|
|
303
|
+
- If the steps do not fit the width, flowfig wraps the time columns into blocks. Labeled stubs link the blocks. Keep the
|
|
304
|
+
whole process in one figure.
|
|
305
|
+
- An SOP gives more facts: every deadline, message to a person, choice by a person, and wait for a reply.
|
|
306
|
+
Put each one in a box \`sub\`, a step \`say\` or a \`data\` card. Draw each path to its end, and give each path its own step.
|
|
307
|
+
`,
|
|
308
|
+
marks: `# flowfig topic: marks
|
|
309
|
+
|
|
310
|
+
Read this topic for a state lifecycle or a state machine.
|
|
311
|
+
|
|
312
|
+
- Draw one box per state. Draw one edge per transition, and label the edge with its event in plain words.
|
|
313
|
+
- Give each path through the states its own step.
|
|
314
|
+
- Mark the first state with \`"mark": "start"\` on the box. The figure draws a filled dot before the box.
|
|
315
|
+
- Mark each final state with \`"mark": "end"\` on the box. The figure draws a ringed dot after the box.
|
|
316
|
+
- In a Mermaid \`stateDiagram\`, only a top-level \`[*] --> A\` makes A the start state. A \`[*]\` inside a nested state gives
|
|
317
|
+
no start mark. \`B --> [*]\` makes B an end state.
|
|
318
|
+
- Use the box \`tone\` for the state color. Use \`green\` for a success state, \`red\` for a failed state and \`gray\` for an idle
|
|
319
|
+
state.
|
|
320
|
+
`,
|
|
321
|
+
verify: `# flowfig topic: verify
|
|
322
|
+
|
|
323
|
+
Read this topic when the render prints a verify finding, or to check figures in CI.
|
|
324
|
+
|
|
325
|
+
If a box or an edge has a \`source\` or a \`via\`, the render checks each one against the code. The render reads the code from the
|
|
326
|
+
folder where it runs, so run it from the repo root. \`--no-verify\` skips this part. A verify finding does not stop the render.
|
|
327
|
+
|
|
328
|
+
Fix each finding:
|
|
329
|
+
|
|
330
|
+
- \`missing-file\`: the \`source\` file does not exist. Fix the path. The path is relative to the repo root.
|
|
331
|
+
- \`missing-symbol\`: the file has no such symbol or heading. Fix the name. A method uses \`Owner.name\`.
|
|
332
|
+
- \`edge-not-found\`: the code does not make that call. Remove the edge, or point its \`source\` at the function that makes the call.
|
|
333
|
+
- An \`unsure\` edge is allowed. If a function with a typed receiver makes the call, point the edge \`source\` at that function.
|
|
334
|
+
- A \`not checked\` edge has no code to check. Give it a \`source\` or a \`via\` if one exists.
|
|
335
|
+
|
|
336
|
+
Do not invent an edge to make the verify pass.
|
|
337
|
+
|
|
338
|
+
The count line has this form:
|
|
339
|
+
|
|
340
|
+
\`\`\`
|
|
341
|
+
out.svg: 4 of 4 boxes defined; edges: 5 found, 0 not found, 1 unsure, 0 not checked
|
|
342
|
+
\`\`\`
|
|
343
|
+
|
|
344
|
+
Copy the count line into the reply as printed.
|
|
345
|
+
|
|
346
|
+
For CI, \`npx flowfig verify <svg>...\` runs the same check on SVG files. \`--root <folder>\` sets the repo root. \`--json\` prints
|
|
347
|
+
JSON. \`--strict\` makes warnings errors.
|
|
348
|
+
`,
|
|
349
|
+
};
|
|
290
350
|
export const AGENT_TEXT = `# Diagrams with flowfig
|
|
291
351
|
|
|
292
|
-
If the user names no other tool, use flowfig for every diagram, figure, flowchart or picture of how something works. Do not answer with a Mermaid block or ASCII art. Use it for an architecture, a data flow
|
|
293
|
-
a call sequence, a state lifecycle
|
|
352
|
+
If the user names no other tool, use flowfig for every diagram, figure, flowchart or picture of how something works. Do not answer with a Mermaid block or ASCII art. Use it for an architecture, a data flow, a pipeline or a request lifecycle.
|
|
353
|
+
Use it for a call sequence, a state lifecycle or a flowchart. flowfig also converts a pasted Mermaid flowchart, \`stateDiagram\` or
|
|
294
354
|
\`sequenceDiagram\`.
|
|
295
355
|
|
|
296
356
|
flowfig draws a roadmap or a timeline with dates (\`timeline: true\`), and converts a Mermaid \`gantt\` to it. flowfig does not
|
|
297
357
|
draw class or ER diagrams or charts of numbers. For those, tell the user so, suggest Mermaid (\`classDiagram\`, \`erDiagram\`),
|
|
298
358
|
and draw nothing with flowfig.
|
|
299
359
|
|
|
300
|
-
1. Run \`npx flowfig docs\` and read it. If the command fails, stop
|
|
301
|
-
\`npm install --save-dev flowfig
|
|
302
|
-
2. Pick the scope. If the code has more than one flow, name each flow in the reply
|
|
303
|
-
view and call it a structure view. If the user asks for the whole system, draw one top view with groups
|
|
304
|
-
that together cover every part. Keep each figure to 12 boxes or fewer. For a process that several roles do, use
|
|
360
|
+
1. Run \`npx flowfig docs\` and read it. If the command fails, stop. Tell the user that flowfig is not available.
|
|
361
|
+
Give them \`npm install --save-dev flowfig\`. Draw nothing with another tool.
|
|
362
|
+
2. Pick the scope. If the code has more than one flow, name each flow in the reply. Then draw one flow,
|
|
363
|
+
or draw one structure view and call it a structure view. If the user asks for the whole system, draw one top view with groups.
|
|
364
|
+
Or draw a set of figures that together cover every part. Keep each figure to 12 boxes or fewer. For a process that several roles do, use
|
|
305
365
|
\`lanes: true\`, one labeled group per role. For a plan or a roadmap, read the dates from the document and use \`timeline: true\`.
|
|
306
366
|
3. Write a fact list from the code and from its wiring (config, compose, route and queue files). Write each call as
|
|
307
367
|
\`caller → callee: payload (file:line of the call)\`, in order. Include each async call and every consumer of a queue, each
|
|
308
368
|
branch and error path, and each end state. Leave out what the code does not show.
|
|
309
|
-
4. Write the spec from the fact list, with the
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
369
|
+
4. Write the spec from the fact list, with plain words in the labels and real data. Give each box and edge that draws code a
|
|
370
|
+
\`source\` (\`file#symbol\`) from the fact list. The code name goes there, not in the label.
|
|
371
|
+
Mark each of these with \`async: true\`. Mark every send to a queue or a topic.
|
|
372
|
+
Mark every emitted event. Mark every call that the caller does not await.
|
|
373
|
+
5. Render it from the repo root with \`npx flowfig - out.svg <<'SPEC'\` and the JSON in the heredoc. The render prints the
|
|
374
|
+
check lines, one line per edge, one line per step and the verify findings. Compare the edge lines with the fact list.
|
|
375
|
+
Each edge must go from the caller to the callee that the fact names. Fix each fault and each verify finding, and render again.
|
|
376
|
+
Fix a layout fault by changing the layout first (rows, \`around\`, the gap). Never remove a fact to pass the check; if you
|
|
377
|
+
must remove one, name it in the reply. If \`small-text\` appears, use two rows or split the figure; do not change \`--width\`.
|
|
316
378
|
6. If you can open a browser, look at the SVG at two moments of the loop. If you cannot, write "not looked at" in the reply.
|
|
317
379
|
Never report a look that you did not do.
|
|
318
|
-
7. Reply with
|
|
319
|
-
the
|
|
380
|
+
7. Reply with these parts. First, the SVG path. Second, what the figure shows. Copy the counts from the \`figure:\` line.
|
|
381
|
+
Copy the names from the edge lines that the render printed. Third, what the figure leaves out, and why.
|
|
382
|
+
Fourth, the two lines that the render printed, \`0 errors, 0 warnings\` and \`figure: ...\`. Copy them as printed.
|
|
320
383
|
End the reply with one line \`npx flowfig open <path>\` for each SVG. Do not run that command yourself.
|
|
321
384
|
`;
|
|
322
385
|
export const SKILL_DESCRIPTION = 'Use for every request for a diagram, figure, flowchart or picture of how something works, when the user names no other tool. Do not answer with a Mermaid block or ASCII art. Use when the user asks for a diagram, figure or animation of how code or a system works: an architecture, a data flow, a pipeline, a request lifecycle, a call sequence, a state lifecycle, a flowchart, a roadmap or a timeline; when the user pastes a Mermaid flowchart, stateDiagram, sequenceDiagram or gantt to convert; or when the user asks for a class or ER diagram.';
|