qgraphflow 0.0.6
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/.agents/plugins/marketplace.json +20 -0
- package/.claude-plugin/marketplace.json +17 -0
- package/.claude-plugin/plugin.json +13 -0
- package/.codex-plugin/plugin.json +26 -0
- package/.cursor-plugin/plugin.json +9 -0
- package/.qoder-plugin/plugin.json +9 -0
- package/LICENSE +21 -0
- package/README.md +262 -0
- package/THIRD_PARTY_NOTICES.md +190 -0
- package/bin/qgraphflow.mjs +17 -0
- package/docs/clients.de.md +83 -0
- package/docs/clients.es.md +83 -0
- package/docs/clients.ja.md +83 -0
- package/docs/clients.md +83 -0
- package/docs/clients.pt.md +83 -0
- package/docs/clients.ru.md +83 -0
- package/docs/clients.zh-CN.md +83 -0
- package/docs/readme/README.de.md +262 -0
- package/docs/readme/README.es.md +262 -0
- package/docs/readme/README.ja.md +262 -0
- package/docs/readme/README.pt.md +262 -0
- package/docs/readme/README.ru.md +262 -0
- package/docs/readme/README.zh-CN.md +264 -0
- package/examples/order-flow.graph.json +94 -0
- package/package.json +61 -0
- package/skills/q-flow/SKILL.md +69 -0
- package/skills/q-flow/agents/openai.yaml +5 -0
- package/skills/q-flow/assets/layout-dist/ELK-LICENSE.md +264 -0
- package/skills/q-flow/assets/layout-dist/worker.mjs +24 -0
- package/skills/q-flow/assets/viewer/package.json +22 -0
- package/skills/q-flow/assets/viewer/src/diagrams/architecture.js +43 -0
- package/skills/q-flow/assets/viewer/src/diagrams/card.js +21 -0
- package/skills/q-flow/assets/viewer/src/diagrams/class.js +52 -0
- package/skills/q-flow/assets/viewer/src/diagrams/dataflow.js +19 -0
- package/skills/q-flow/assets/viewer/src/diagrams/deployment.js +41 -0
- package/skills/q-flow/assets/viewer/src/diagrams/drawing.js +174 -0
- package/skills/q-flow/assets/viewer/src/diagrams/er.js +34 -0
- package/skills/q-flow/assets/viewer/src/diagrams/flowchart.js +37 -0
- package/skills/q-flow/assets/viewer/src/diagrams/registry.js +28 -0
- package/skills/q-flow/assets/viewer/src/diagrams/sequence.js +38 -0
- package/skills/q-flow/assets/viewer/src/diagrams/state.js +91 -0
- package/skills/q-flow/assets/viewer/src/diagrams/usecase.js +28 -0
- package/skills/q-flow/assets/viewer/src/edge-routing.js +596 -0
- package/skills/q-flow/assets/viewer/src/export-svg.js +90 -0
- package/skills/q-flow/assets/viewer/src/graph-validation.js +286 -0
- package/skills/q-flow/assets/viewer/src/i18n-messages.json +1314 -0
- package/skills/q-flow/assets/viewer/src/i18n.js +14 -0
- package/skills/q-flow/assets/viewer/src/layout-measure.js +55 -0
- package/skills/q-flow/assets/viewer/src/layout-quality.js +164 -0
- package/skills/q-flow/assets/viewer/src/layout-spacing.js +12 -0
- package/skills/q-flow/assets/viewer/src/node-svg.js +28 -0
- package/skills/q-flow/assets/viewer/src/radix-colors.js +47 -0
- package/skills/q-flow/assets/viewer/src/sequence-executions.js +140 -0
- package/skills/q-flow/assets/viewer/src/sequence-fragments.js +208 -0
- package/skills/q-flow/assets/viewer/src/session-graph.js +43 -0
- package/skills/q-flow/assets/viewer/src/text-layout.js +126 -0
- package/skills/q-flow/assets/viewer/src/visual-style.js +158 -0
- package/skills/q-flow/assets/viewer-dist/index.html +291 -0
- package/skills/q-flow/references/acceptance.md +11 -0
- package/skills/q-flow/references/evidence-sources.md +38 -0
- package/skills/q-flow/references/graph-common.md +54 -0
- package/skills/q-flow/references/graph-schema.md +214 -0
- package/skills/q-flow/references/guided-intake.md +100 -0
- package/skills/q-flow/references/types/architecture.md +41 -0
- package/skills/q-flow/references/types/class.md +40 -0
- package/skills/q-flow/references/types/dataflow.md +41 -0
- package/skills/q-flow/references/types/deployment.md +37 -0
- package/skills/q-flow/references/types/er.md +36 -0
- package/skills/q-flow/references/types/flowchart.md +47 -0
- package/skills/q-flow/references/types/sequence.md +74 -0
- package/skills/q-flow/references/types/state.md +44 -0
- package/skills/q-flow/references/types/usecase.md +39 -0
- package/skills/q-flow/references/viewer-development.md +258 -0
- package/skills/q-flow/references/visual-contract.md +54 -0
- package/skills/q-flow/scripts/compile-layout.mjs +565 -0
- package/skills/q-flow/scripts/compile-sequence.mjs +112 -0
- package/skills/q-flow/scripts/generate-viewer.mjs +126 -0
- package/skills/q-flow/scripts/validate-graph.mjs +278 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Browser acceptance on request
|
|
2
|
+
|
|
3
|
+
Run these checks only when the user asks to see or check the rendering, the delivery includes Viewer changes, or a receipt reports rendering diagnostics. Ordinary delivery stops at input validation, generation and output validation; its reply says `Browser acceptance: not performed`.
|
|
4
|
+
|
|
5
|
+
- Open the real generated page at 1440×900 with the browser tooling available in the current client; for a collection, inspect every requested diagram type: one screenshot per view for first-screen readability, containment and console errors. Repeat only after correcting an observed issue. Review spacing, type-specific composition and proportional edge motion: nodes, routes, arrows and stroke widths scale together.
|
|
6
|
+
- Every ordinary card carries its module wash; a plain card is a defect to fix in the graph. Two modules sharing a colour is expected once a collection has many modules; the module chip text tells them apart.
|
|
7
|
+
- For sequence delivery, check the rendered activation bars and nesting, matching call/return colors and IDs, evidenced fragment nesting, solid sync / open async / dashed return notation, and visible flow that preserves those line types; check static exports for the same bars, pairing and fragments. A valid graph without execution data does not satisfy an activation-bar request.
|
|
8
|
+
- SVG/PNG exports check current geometry and actual browser glyph bounds after fonts load. Invalid layout remains an editable JSON draft. PNG rejects blank encoding and dimensions above 32767px or 64 million pixels without reducing resolution; SVG is assessed independently. The generator's own SVGs (`diagram*.svg`) never had browser glyph measurement: open one of them in the browser too.
|
|
9
|
+
- An automation HTTP server must close in the same process's `finally`. If no browser tool is available, report generation and graph validation separately and mark browser acceptance incomplete; do not claim visual or interaction checks passed.
|
|
10
|
+
|
|
11
|
+
Report the outcome next to the validation result: what was opened, at which size, what was checked per view, and anything corrected and re-checked. When a check could not run, say so; never present generation and validation as visual acceptance.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Evidence sources and CodeGraph fallback
|
|
2
|
+
|
|
3
|
+
CodeGraph is the preferred call-graph accelerator, not a hard dependency.
|
|
4
|
+
|
|
5
|
+
## CodeGraph preflight
|
|
6
|
+
|
|
7
|
+
The intended implementation is [`colbymchenry/codegraph`](https://github.com/colbymchenry/codegraph), exposed through its local CLI or MCP server.
|
|
8
|
+
|
|
9
|
+
1. Check whether `codegraph` is on `PATH` and whether the target repository contains `.codegraph/`.
|
|
10
|
+
2. When both are present, run `codegraph status` and use one bounded `codegraph explore "<question or symbols>"` query before direct repository tracing.
|
|
11
|
+
3. An already configured CodeGraph MCP tool can serve the same bounded query. Use the tools actually available in this client; do not assume a client-specific tool name.
|
|
12
|
+
4. If the CLI, MCP tool or current index is unavailable, continue directly with the fallback below. Ordinary drawing does not require installing or initializing CodeGraph, resolving npm versions, or changing client configuration.
|
|
13
|
+
|
|
14
|
+
## Optional setup when requested
|
|
15
|
+
|
|
16
|
+
1. Only when the user requests or has authorized CodeGraph setup, resolve the exact stable package version with `npm view @colbymchenry/codegraph version` and check that version's official installation instructions and supported targets.
|
|
17
|
+
2. Before installation, identify the target client, command and writes: executable, client configuration/instructions, and `.codegraph/` index. Prefer project-local configuration when the installer supports it. Do not assume every client uses `--target=codex` or invent target values from client names.
|
|
18
|
+
3. Pin the resolved package version. Run initialization only within the authorized repository. If no installer integration exists for the client, use a supported standalone CLI setup or direct source tracing; an MCP integration is not required.
|
|
19
|
+
4. Verify `codegraph status` after setup and use the available CLI or MCP tool. Follow the target client's reload/restart procedure if needed. If version resolution or installation fails, report it and continue with direct tracing rather than trying another installer automatically.
|
|
20
|
+
|
|
21
|
+
## Fallback order
|
|
22
|
+
|
|
23
|
+
1. Use `rg --files`, then narrow `rg` searches to declarations, entry points, callers, implementations, configuration keys, and tests.
|
|
24
|
+
2. Read the complete relevant source path and preserve file, line, and symbol anchors.
|
|
25
|
+
3. Check build models, packaged artifacts, focused tests, and runtime configuration when they change the conclusion.
|
|
26
|
+
4. Use framework documentation only for behavior owned by the framework; label it `framework` rather than repository source.
|
|
27
|
+
5. Mark non-critical unresolved links as `inference`. Omit unresolved links on the claimed main path.
|
|
28
|
+
|
|
29
|
+
## Diagram-specific authority
|
|
30
|
+
|
|
31
|
+
| Diagram | Preferred evidence without CodeGraph |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
| Architecture, sequence, class, data flow | Entrypoints, callers, interfaces, implementations, build dependencies, RPC/MQ clients, and focused tests |
|
|
34
|
+
| Flowchart, state, use case | Accepted requirements and API documents, then controller/service behavior and tests; show documented and implemented behavior separately when they differ |
|
|
35
|
+
| ER | DDL and migrations first, then JPA entities, ORM/MyBatis mappings, constraints, and repository tests |
|
|
36
|
+
| Deployment | Dockerfile, Compose, Kubernetes, Helm, service configuration, network policy, and CI/CD manifests |
|
|
37
|
+
|
|
38
|
+
Direct tracing cannot guarantee complete coverage of reflection, dependency injection, generated proxies, runtime routing, RPC, or messaging. State this limit and distinguish `source`, `config`, `schema`, `test`, `document`, `framework`, and `inference` evidence.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Graph JSON: rules shared by every diagram type
|
|
2
|
+
|
|
3
|
+
Read this file plus `types/<diagramType>.md`. Together they are the complete authoring contract; do not read scripts, the bundled HTML, Viewer source or tests to learn rules. `graph-schema.md` is the maintainers' full reference.
|
|
4
|
+
|
|
5
|
+
## Shape
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"meta": { "title": "…", "subtitle": "…", "sourceRef": "<repo>@<rev> or a document name", "scope": "…", "diagramType": "architecture", "locale": "zh-CN" },
|
|
10
|
+
"groups": [{ "id": "g1", "label": "…", "kind": "<group kind>" }],
|
|
11
|
+
"nodes": [{ "id": "n1", "label": "…", "kind": "<node kind>", "subtitle": "…", "groupId": "g1", "module": "order", "tags": ["core"], "facts": ["…"], "source": { "kind": "source", "file": "src/a.js", "lineStart": 10, "lineEnd": 24, "symbol": "createOrder" } }],
|
|
12
|
+
"edges": [{ "id": "e1", "source": "n1", "target": "n2", "kind": "<edge kind>", "label": "…", "evidence": "source" }]
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
- Required: `meta.title`, `meta.sourceRef`, `meta.diagramType`, non-empty `nodes`, and `edges` (an array; it may be empty). `meta.locale` is the user's language: `zh-CN` (default), `en`, `ru`, `pt`, `ja`, `de`, `es`.
|
|
17
|
+
- `meta.locale` only translates the Viewer's interface. Write every readable text yourself in that language — title, subtitle, scope, `facts`, edge labels (relationship verbs, branch words), guards; the type pages' English sample text is a placeholder. Identifiers (class, table, field, method, route, config key, literal value) and standard notation (cardinalities, `«include»`, `alt` / `loop`) stay verbatim.
|
|
18
|
+
- Write facts only: **no `position`, `size` or `route`** — layout is computed. Optional hints (`layout.rank` / `layout.order` on nodes, `layout.primaryPath` / `layout.participantOrder` on the graph) express an order that already exists in the source.
|
|
19
|
+
- IDs are unique non-empty strings; every edge endpoint names a node. Keep ids short and stable (`order-service`, `m3`).
|
|
20
|
+
- One graph per file by default. Only when the user asks for several views, wrap them as `{ "diagrams": [graph, graph] }`, each with a distinct `diagramType`.
|
|
21
|
+
|
|
22
|
+
## Nodes
|
|
23
|
+
|
|
24
|
+
- `kind` must be one of the type's node kinds (see the type file). No invented kinds, no colour fields.
|
|
25
|
+
- `label` is the real name from the source (class, route, table, service). `subtitle` is one line of responsibility. `facts` are short atomic statements; put uncertainty into the wording.
|
|
26
|
+
- `module`: the subsystem whose work the node performs (order, inventory, payment …). Reuse the exact same non-empty string for that subsystem across nodes and views; it drives card identity colours (chip, frame, faint wash, outgoing lines). It is not containment (`groupId` is). A node without `module` renders on the plain surface, so give every ordinary node one — steps, decisions, choices, start / end, and an external hub or broker that belongs to an evidenced channel; only `initial` / `final` and true outsiders (a caller, a debugger, an ops role) stay plain. Eight colour slots are hashed from the name, so two modules can share a colour: that is expected, the module label stays authoritative, and a module is never renamed for colour.
|
|
27
|
+
- `groupId` declares real containment in a `groups` entry; groups nest with `parentId`. Group `kind` must be one of the type's group kinds.
|
|
28
|
+
- The business centre: use the `business` kind where the type has one (architecture), otherwise add `"core"` to `tags`. Never invent a `core` kind.
|
|
29
|
+
- `fields` (ER, optional elsewhere): `[{ "name", "type", "key": "PK|FK|UK", "nullable": true|false }]`. `attributes` / `methods` (class): arrays of strings.
|
|
30
|
+
|
|
31
|
+
## Edges
|
|
32
|
+
|
|
33
|
+
- `kind` from the type's edge kinds. `label` names the action, message or data, not the kind.
|
|
34
|
+
- `evidence` (required): `source` (code you read), `code`, `config`, `schema`, `test`, `document`, `framework` (behaviour supplied by a framework, not visible in project code), `inference` (your deduction — label it, do not hide it).
|
|
35
|
+
- Omit relationships you cannot support. Do not add intermediate nodes to make notation look conventional.
|
|
36
|
+
|
|
37
|
+
## Source anchors
|
|
38
|
+
|
|
39
|
+
- `source.file` is repository-relative (no `..`, no absolute paths); `lineStart` / `lineEnd` are 1-based and inclusive; `symbol` is optional. The generator checks that the file exists and the range fits when `--repo-root` is passed.
|
|
40
|
+
- `symbol` is the name exactly as written at the definition (`OrderService.createOrder`, `orders`), never a description. With `--repo-root`, its last segment must appear as a whole word inside the range, so a moved, renamed or deleted definition fails validation; `--fix` re-anchors a name found once in its file.
|
|
41
|
+
- Anchor the node to where it is **defined** (class, function, table, service block), not to a call site. Edges carry no anchor of their own; their endpoint nodes do.
|
|
42
|
+
- Omit `source` for external actors, third-party systems and framework-owned runtime components. Never reuse an anchor from an example.
|
|
43
|
+
- Prefer one node per real component. Split by responsibility only when the source does.
|
|
44
|
+
|
|
45
|
+
## Composition
|
|
46
|
+
|
|
47
|
+
- The diagram must answer the question asked from the first reading view: one clear path, real component names, action / message / data names on edges. Choose the smallest set of nodes that still tells the truth; a large system is several views, not one huge graph.
|
|
48
|
+
- Groups are for real boundaries only. `module` is not decoration either: it states which business subsystem a node's work belongs to, and the same subsystem keeps the same name in every view.
|
|
49
|
+
- Full labels, never abbreviated to fit: the layout expands for text and wraps long labels.
|
|
50
|
+
- For a collection, reuse node ids and `module` values across views so the same component is recognisable everywhere.
|
|
51
|
+
|
|
52
|
+
## Delivery
|
|
53
|
+
|
|
54
|
+
Validate with `node scripts/validate-graph.mjs <graph.json> --input-only --repo-root <repo>` before generating; `SKILL.md` says how to repair errors and what the composition warnings mean. Errors name the element (`edge m7.order duplicates 7`, `node api unknown kind …`): fix that field with an edit; do not rewrite the whole file, do not delete facts to pass, do not bypass with `--force`.
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# Graph JSON contract
|
|
2
|
+
|
|
3
|
+
> Authoring a graph? Read [graph-common.md](graph-common.md) and `types/<diagramType>.md` instead — they carry every rule the validator applies, with a minimal valid skeleton per type. This file is the complete reference for maintainers of the validator, layout and Viewer.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
`scripts/generate-viewer.mjs` accepts either one `Graph` or a graph collection. Older graphs without `meta.diagramType` remain valid and render as `architecture`.
|
|
7
|
+
`adaptive-v2`: generation defaults to `--layout auto` and accepts semantic inputs without positions or sizes. Declare real ownership with node `groupId` and group `parentId`; color `module` is not ownership. Optional node `layout.rank` / `layout.order`, graph `layout.primaryPath` / `layout.participantOrder` express existing order only. `--layout preserve` checks existing geometry without rearranging it. Ambiguous old containment requires an explicit author decision. `--input-only` checks semantics; source, geometry and browser rendering have separate statuses. `--force` only permits replacing outputs and never bypasses quality checks. A layered result whose width/height ratio leaves the accepted band 1/1.6–1.6 by more than 10% is folded (2–5 segments): a top-down layout that is too tall cuts its layer sequence into columns with aligned tops, a left-to-right layout that is too wide cuts it into rows with aligned starts, so every segment keeps its reading direction and continues at the start of the next one. Geometry and routes inside a segment are kept; cuts prefer boundary changes and avoid a decision's branches; an edge across a cut runs through the channel between its segments, or through the corridor before or after them when a neighbour or heading is in the way. A boundary spread over several segments is rebuilt around its members and must not cover foreign nodes. Among the folds that pass the quality gate within 10% of the band, the one with the fewest crossings wins, then the fewest segments, so a balanced fold is not passed over for a ragged one; a fold the gate rejects is skipped for the next one, and otherwise the nearest valid shape competes with the unfolded result. Candidates whose ratio is within 1.3× of the band rank equal on shape, so fewer point crossings come before compactness and a crossing is never traded for a slightly better ratio; only a strip beyond that outranks them. The type budget only breaks ties towards its preferred orientation. Declared `layout.rank` layouts and state charts with branches or loops never fold.
|
|
8
|
+
|
|
9
|
+
Flowchart main paths must run top-to-bottom, with left/right branches and outside feedback routes; a column fold continues the main path at the top of the next column, which is the only step that may run upwards. Auto, strict preservation and image exports apply the same rule. Optional `primaryPath` declares the main order; an unambiguous simple chain is checked even without it. Horizontal main paths are rejected regardless of node count; side branches and feedback edges may still run sideways or upwards.
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{
|
|
14
|
+
"meta": {
|
|
15
|
+
"title": "Required title",
|
|
16
|
+
"diagramType": "architecture",
|
|
17
|
+
"subtitle": "Optional supporting line",
|
|
18
|
+
"sourceRef": "Branch, commit, document version, or evidence scope",
|
|
19
|
+
"scope": "Verified evidence scope",
|
|
20
|
+
"generatedAt": "ISO-8601 timestamp"
|
|
21
|
+
},
|
|
22
|
+
"groups": [
|
|
23
|
+
{
|
|
24
|
+
"id": "runtime-boundary",
|
|
25
|
+
"label": "Consumer application JVM",
|
|
26
|
+
"kind": "runtime",
|
|
27
|
+
"position": { "x": 40, "y": 80 },
|
|
28
|
+
"size": { "width": 1440, "height": 620 }
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"nodes": [
|
|
32
|
+
{
|
|
33
|
+
"id": "jwt-decoder",
|
|
34
|
+
"label": "NimbusJwtDecoder",
|
|
35
|
+
"subtitle": "Verify and decode JWT",
|
|
36
|
+
"module": "Identity",
|
|
37
|
+
"kind": "security",
|
|
38
|
+
"position": { "x": 720, "y": 220 },
|
|
39
|
+
"size": { "width": 220, "height": 120 },
|
|
40
|
+
"source": {
|
|
41
|
+
"kind": "source",
|
|
42
|
+
"file": "module/src/main/java/example/Config.java",
|
|
43
|
+
"lineStart": 111,
|
|
44
|
+
"lineEnd": 130,
|
|
45
|
+
"symbol": "jwtDecoder"
|
|
46
|
+
},
|
|
47
|
+
"facts": ["Built from issuer-uri"],
|
|
48
|
+
"tags": ["JWT", "Spring Security"]
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"edges": [
|
|
52
|
+
{
|
|
53
|
+
"id": "decode-token",
|
|
54
|
+
"source": "bearer-filter",
|
|
55
|
+
"target": "jwt-decoder",
|
|
56
|
+
"label": "decode and verify",
|
|
57
|
+
"module": "Identity",
|
|
58
|
+
"kind": "call",
|
|
59
|
+
"evidence": "framework",
|
|
60
|
+
"route": {
|
|
61
|
+
"via": [{ "x": 640, "y": 180 }],
|
|
62
|
+
"labelAt": { "x": 640, "y": 156 }
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Use one graph by default; a standalone page has no diagram-type menu. For a requested multi-diagram viewer, wrap 1–9 graphs in `diagrams`. Each graph must use a unique `meta.diagramType`; the toolbar view menu follows the fixed order `architecture`, `flowchart`, `sequence`, `er`, `deployment`, `class`, `state`, `usecase`, `dataflow` regardless of input order. The view menu lists the requested types vertically.
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"diagrams": [
|
|
74
|
+
{ "meta": { "title": "System", "diagramType": "architecture", "sourceRef": "main" }, "nodes": [], "edges": [] },
|
|
75
|
+
{ "meta": { "title": "Request", "diagramType": "sequence", "sourceRef": "main" }, "nodes": [], "edges": [] }
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The abbreviated graphs above show only the wrapper; every graph still follows the complete contract and requires non-empty nodes.
|
|
81
|
+
|
|
82
|
+
## Common fields
|
|
83
|
+
|
|
84
|
+
- Required: `meta.title`, `meta.sourceRef`, non-empty `nodes`, and `edges`.
|
|
85
|
+
- `meta`, nodes, edges, groups and source anchors are objects; `nodes`, `edges`, and optional `groups` are arrays of objects. Invalid containers are rejected before layout or output generation.
|
|
86
|
+
- Optional `meta.subtitle`, `meta.scope`, node `subtitle`, `source.symbol`, and edge `label` are strings. Optional node and edge `module` values are non-empty strings: reuse the exact same value for the same business module across every graph in a collection; do not store literal colors. Node `facts`, `tags`, `attributes`, and `methods` are arrays of non-empty strings. These rules apply to every diagram type.
|
|
87
|
+
- Optional node `fields` is an array of objects with non-empty string `name` and `type`, optional `key` (`PK`, `FK`, `UK`) and boolean `nullable`; ER requires at least one field. Other types can expose these fields in search and details.
|
|
88
|
+
- `meta.diagramType`: `architecture`, `flowchart`, `sequence`, `er`, `deployment`, `class`, `state`, `usecase`, or `dataflow`.
|
|
89
|
+
- `meta.locale`: optional Viewer language: `en`, `zh-CN` (default), `ru`, `pt`, `ja`, `de`, or `es`; `ko` and `fr` remain supported for existing graphs. Interface strings are authored in English in the Viewer source (`i18n.js`, `i18n-messages.json` holds every other language including `zh-CN`); a graph without `meta.locale` still renders its interface in Chinese. This controls built-in interface and export labels; author titles, node labels, facts and relationship text in the desired language separately. Code identifiers and standard notation remain unchanged. In a collection, each diagram uses its own locale.
|
|
90
|
+
- IDs are unique non-empty strings. Every edge endpoint names a node.
|
|
91
|
+
- In compiled output or `--layout preserve`, every node and group requires finite non-negative `position` and positive `size`; semantic `auto` input may omit them.
|
|
92
|
+
- Class associations, aggregation and composition may declare `sourceMultiplicity` / `targetMultiplicity`: `*`, a non-negative integer, or an ascending range such as `0..1` or `1..*`. Inheritance, implementation and dependency reject these fields. `dataflow` preserves declared data flows between real components, including direct external-to-store, store-to-store and external-to-external flows. Gane–Sarson-inspired symbols distinguish external entities, processes and stores; this is not strict process-only DFD modeling. Do not invent intermediate processes or reclassify components to satisfy notation.
|
|
93
|
+
- Edge `evidence`: `source`, `code`, `config`, `schema`, `test`, `document`, `framework`, or `inference`.
|
|
94
|
+
- Edge `route` is optional. `via` contains graph-space waypoints and `labelAt` fixes the graph-space label center; omit both when automatic orthogonal routing is clear.
|
|
95
|
+
- Every `route.via` and `route.labelAt` coordinate must be a finite non-negative number. The router inserts orthogonal elbows between waypoints and keeps the first and last connection anchored to the current node positions.
|
|
96
|
+
- Optional node `source.kind` uses the same evidence values. `source.file` and `source.lineStart` identify the exact anchor.
|
|
97
|
+
- With `--repo-root <directory>`, validation and generation read every node's `source.file` as repository-relative UTF-8 text and check the inclusive line range. Absolute paths, parent traversal, directories, binary files and symlinks escaping the root are rejected. Repeated references share one file read. When `source.symbol` is present, its last segment (split on every character other than a letter, digit, `_` or `$`) must occur as a whole word within the range; write the name as it appears at the definition, not a description. A failure names the lines where the word does occur in the file, and the receipt counts symbol checks in `sourceEvidence.symbols`. `--fix --repo-root` moves `lineStart` to the only such line in the file and shifts `lineEnd` with it, clamped to the last line; anchors with several or no matches stay for the author. Without the root, receipts explicitly mark existing source anchors `skipped`; without anchors they report `not-applicable`. These checks cover the local working tree, not `sourceRef` revision identity, definition parsing or claim correctness: a mention of the name left inside the range still passes.
|
|
98
|
+
- To emphasize the business center, use the existing `business` kind where supported, or include `core` or `business` in `tags` (matched case-insensitively). Keep the diagram's legal node kind; `core` is not a new kind or schema field. In a state diagram the `core` state is the goal and a `failure` tag marks a failed state; both only feed the Viewer's derived state colors.
|
|
99
|
+
- Composition review (`reviewComposition()` in `graph-validation.js`, printed in full by `validate-graph.mjs --input-only` as `Composition warning (<type>) <rule>: …`, counted as `warnings: n` in every receipt) is advisory: warnings never fail validation or generation, and a collection with no `module` anywhere gets none. Rules: `module.missing` (an ordinary node without `module` once the collection uses modules; `initial` / `final` and the outsider kinds `external`, `actor`, `device` are exempt), `module.inconsistent` (the same node label carries a module in one view and none or another in a second view), `module.single-tone` (a flowchart or data flow of ≥ 6 washed nodes all in one module — a prompt to check, legitimate when the flow lives in one subsystem), `flowchart.process-branch` (a non-decision with more than one outgoing edge). The receipt carries `warnings: <count>` only when there are any.
|
|
100
|
+
- The cool-neutral visual system is a Viewer presentation rule. Color, typography, and core styling require no new graph fields. The order-fulfillment preview model is example content, not a default dataset or evidence source.
|
|
101
|
+
|
|
102
|
+
Legacy `playback` metadata is ignored. The Viewer has no automatic or stepped playback; directed-edge motion is a separate visual cue and does not imply execution order.
|
|
103
|
+
|
|
104
|
+
## Saving Viewer edits
|
|
105
|
+
|
|
106
|
+
Switching diagram types retains each graph's saved text and positions within the open page. Reset restores only the active graph's embedded original content. **Save changes** saves the entire collection (or the original single-graph shape), including edits in other views, metadata and source anchors. Chromium browsers let the user pick the page's folder once and then rewrite the open page, its sibling `graph.json` and the per-view SVGs in place, so reloading shows the edits; the SVGs are byte-identical to a `--layout preserve` regeneration, and when an edited view fails the layout gate the page and `graph.json` are saved as a draft while every SVG stays as it was. Other browsers save or download `graph.json`; regenerate with `--layout preserve --force` to update the page and SVGs. Cancelling or failing a save keeps all page edits.
|
|
107
|
+
|
|
108
|
+
A page saved in place reloads with its edits because its embedded data was rewritten; a page whose edits were only downloaded still starts from its old embedded data, so keep that JSON and regenerate into a new output directory to reopen the edited model. Saving does not bypass validation: manually edited labels or positions can still need layout corrections before regeneration. The browser does not reverify source anchors; rerun both CLI commands with `--repo-root` for source-backed delivery.
|
|
109
|
+
|
|
110
|
+
## Routing and spacing
|
|
111
|
+
|
|
112
|
+
- Initial canvas budgets are 2400×1600 graph units for architecture / er / deployment / class / usecase / dataflow, 1600×2400 for flowchart / state, and content-adaptive for sequence. These are starting budgets, not minimum borders, export resolutions or aspect-ratio requirements. Preserve full text and type semantics; expand for spacing and routes, keep small graphs compact, and never shrink text or add empty padding to match a ratio. Start with 64 units between peers and 80–96 between layers; expand only the affected label/port corridor. Keep 24 around labels and below measured group headings, with 32 at group sides. Wrap complete long labels instead of spreading every node; sequence messages constrain their own participant span and measured row height. Budgets alone do not rearrange existing geometry.
|
|
113
|
+
- Full-size text is required for generation and image export. Legacy compact geometry (cards shorter than 100px) remains loadable as a JSON draft, drawn with the regular card layout, and needs recompilation before export.
|
|
114
|
+
- Parallel, fan-out, and fan-in relationships receive automatic 24-pixel lanes and may share at most 12 pixels near an endpoint; the longer ER symbol clearance is not permission to merge routes.
|
|
115
|
+
- A node side must be long enough to hold its automatic lanes; enlarge the node or provide route hints when validation reports endpoint-side overflow.
|
|
116
|
+
- For non-self hinted routes, the first/last waypoint determines each endpoint side and its projected border position. Keep a 28-pixel outward straight section for ER cardinality symbols and a 12-pixel section for other diagrams. Waypoints must stay outside all node interiors, including the endpoints.
|
|
117
|
+
- Self-loops default to a 48-by-32-pixel route outside the node's right edge. Use `route.via` or `route.labelAt` only when that area is occupied.
|
|
118
|
+
- Keep full text at 20/16/14px. Minimum clearances: nodes 48px; labels to nodes/labels 24px; labels to unrelated edges 6px; below measured group heading 24px, other insets 32px; sibling groups 48px; parallel channels 24px; straight endpoint segments 12px, ER 28px. Readable point crossings, including nonplanar graphs, are allowed. Prefer fewer repeated crossings between the same pair and reject long collinear overlaps. Layout generation also removes crossings that a different order would avoid: while a candidate still crosses, a bounded search (`REFINE_*` in `compile-layout.mjs`) swaps the ports of the crossing relations within a node side, the side a decision branch or actor relation leaves on, sibling node order and fold lanes, and keeps a swap only when the candidate scores better, so only the crossings a topology forces remain (a full 3×3 mesh keeps 9). The search ends on its evaluation budget, never on the clock: a slow or busy machine lays out the same graph the same way, and only the generation timeout can end a run, as an error. Authors never need to reorder edges or add hints for this. Canvas ratios are informational; never remove relationships or shrink text to pass.
|
|
119
|
+
- Sequence participant centers must be at least `max(160, estimated message width + 32)` pixels apart.
|
|
120
|
+
|
|
121
|
+
## Diagram-specific notation
|
|
122
|
+
|
|
123
|
+
| `diagramType` | Node `kind` | Group `kind` | Edge `kind` |
|
|
124
|
+
| --- | --- | --- | --- |
|
|
125
|
+
| `architecture` | `external`, `config`, `framework`, `security`, `service`, `business`, `data`, `failure`, `system`, `component`, `database` | `runtime`, `security`, `ownership`, `external` | `request`, `call`, `data`, `success`, `failure`, `framework`, `optional`, `depends` |
|
|
126
|
+
| `flowchart` | `start`, `end`, `process`, `decision`, `input`, `output`, `subprocess` | none | `flow`, `yes`, `no`, `success`, `failure` |
|
|
127
|
+
| `sequence` | `actor`, `participant`, `external`, `service`, `database` | `alt`, `opt`, `loop`, `par` | `sync`, `async`, `return` |
|
|
128
|
+
| `er` | `entity` | none | `relationship` |
|
|
129
|
+
| `deployment` | `device`, `node`, `container`, `artifact`, `service`, `database`, `external` | `host`, `network`, `cluster`, `namespace` | `deploy`, `network`, `depends` |
|
|
130
|
+
| `class` | `class`, `interface`, `abstract` | none | `association`, `inheritance`, `implementation`, `composition`, `aggregation`, `dependency` |
|
|
131
|
+
| `state` | `initial`, `state`, `final`, `choice` | none | `transition` |
|
|
132
|
+
| `usecase` | `actor`, `usecase` | `system` | `association`, `include`, `extend` |
|
|
133
|
+
| `dataflow` | `external`, `process`, `dataStore` | `ownership`, `external` | `data` |
|
|
134
|
+
|
|
135
|
+
### Sequence
|
|
136
|
+
|
|
137
|
+
Sequence `order` retains semantic order; generated `route.messageY` supplies the actual vertical coordinate. Outside `--input-only`, every sequence message needs `route.messageY`; automatic layout writes it, so regenerate older graphs with `--layout auto`. A page whose messages lack it still opens in the Viewer: they are stacked by order below the headers and the layout notice names the missing coordinate. Without `layout.participantOrder` or node `layout.order`, participants stand left to right in the order the messages first reach them (the initiator leftmost), never by id. Automatic layout requires explicit fragment operands and never invents conditions. A fragment spans the lifelines of its own messages; a fragment without messages (guards and bodies only) stays under the nearest ancestor's message span, or the whole conversation at top level, so it always covers a lifeline. Frames reserve room for the operator tag beyond any activation bar, and guards, bodies and message labels inside a frame take that frame's surface in both themes. Participant subtitles, guards and bodies must be complete. Invalid geometry remains an editable/saveable JSON draft; SVG/PNG export checks the current snapshot and actual glyph bounds after fonts load. PNG rejects blank encoding or sizes above 32767px / 64 million pixels, without reducing resolution.
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{ "id": "request", "source": "browser", "target": "api", "label": "POST /orders", "kind": "sync", "order": 1, "evidence": "source" }
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
Sequence `alt` optionally accepts `operands`: `[{"guard":"SignalR","edgeIds":["m10"]},{"guard":"HTTP","edgeIds":["m11","m12"]}]`. If supplied, at least two branches are required, with nonempty guards and valid, unique message IDs in ordered, non-interleaving order ranges. No visually enclosed message may be omitted. Guards are escaped text, never code. Page/export share guard and separator geometry; insufficient space is an error, not an implicit frame expansion. Legacy alt without operands remains loadable/saveable and visibly reports unspecified branch conditions with a validation warning. Text/position edits preserve operands.
|
|
145
|
+
|
|
146
|
+
Sync has a filled arrow, async an open V, return an open V plus dashes; Sync stays solid; framework/inference evidence can still dash async messages, while returns remain dashed. Participant subtitles are drawn directly, in full; legacy drafts may retain ellipsis but cannot pass strict export. Actor heads are 130px with a subtitle, otherwise108px; ordinary heads stay72px. Authored lifeline ends and message order remain unchanged. Desktop defaults show overview; directory/search/keyboard locate and mobile (≤700px) defaults use local views at zoom≥.75. Explicit fit always shows the whole diagram.
|
|
147
|
+
|
|
148
|
+
### ER
|
|
149
|
+
|
|
150
|
+
Every entity requires a non-empty `fields` array. Field `key` may be `PK`, `FK`, or `UK`. A relationship requires both endpoint cardinalities: `1`, `0..1`, `*`, `1..*`, or `0..*`.
|
|
151
|
+
|
|
152
|
+
Size an entity for a 72px header, approximately 32px per field, and bottom padding. Grow its key/name/type columns for 16px field names and 14px types and key badges, especially with long identifiers. Leave 28px of straight route outside each entity for cardinality symbols; the cardinality values in the JSON remain unchanged.
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"id": "orders",
|
|
157
|
+
"label": "orders",
|
|
158
|
+
"kind": "entity",
|
|
159
|
+
"fields": [
|
|
160
|
+
{ "name": "id", "type": "bigint", "key": "PK", "nullable": false },
|
|
161
|
+
{ "name": "user_id", "type": "bigint", "key": "FK", "nullable": false }
|
|
162
|
+
],
|
|
163
|
+
"position": { "x": 80, "y": 120 },
|
|
164
|
+
"size": { "width": 260, "height": 170 }
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{ "id": "user-orders", "source": "users", "target": "orders", "kind": "relationship", "sourceCardinality": "1", "targetCardinality": "0..*", "evidence": "schema" }
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Class
|
|
173
|
+
|
|
174
|
+
Class nodes may contain string arrays `attributes` and `methods`. Interface and abstract names are rendered with their stereotype. Allow a 68px header, 28px member rows at 16px font size, and both compartments' padding; grow width and height to fit the name, stereotype, and all members without clipping or shrinking. Inheritance/implementation and composition/aggregation use their own triangle and diamond markers without changing the existing edge kinds.
|
|
175
|
+
|
|
176
|
+
### State
|
|
177
|
+
|
|
178
|
+
Transition edges may contain `guard` and `action`. The visible label is assembled as `label [guard] / action`; the trigger is drawn in ink, the `[guard]` in amber (Radix amber step 11) and the `/ action` in the muted tone. A self-transition (`source` equals `target`) is drawn as one arc beside the state, and the layout reserves 44 px for it (`elk.spacing.nodeSelfLoop`).
|
|
179
|
+
|
|
180
|
+
State nodes (`kind: "state"`) may contain `entry`, `do` and `exit`, each a non-empty string. They are listed below a divider as `entry / …`; the title keeps the compartment above. Other node kinds reject the keys. Initial and final pseudostates are ink; transitions end in an open arrow.
|
|
181
|
+
|
|
182
|
+
### Source anchors
|
|
183
|
+
|
|
184
|
+
Use `source` only when the node maps to a precise repository or supplied-document location. Omit it for external actors and framework-owned runtime components. Keep `facts` short and atomic, and put uncertainty in the wording as well as the evidence kind.
|
|
185
|
+
|
|
186
|
+
For an explicitly requested conceptual example, describe the relevant business model in `facts`, label inferred relationships as `inference`, and name that scope in metadata. Do not fabricate source paths or reuse preview-document anchors for another graph. Normal generation still writes `index.html`, `graph.json` and one SVG per view.
|
|
187
|
+
|
|
188
|
+
### Execution, pairing and nested fragments
|
|
189
|
+
|
|
190
|
+
See `examples/sequence-execution.graph.json` in the repository (not shipped in the package) for the complete conceptual example (five participants, six call/return pairs, six executions, `loop → alt` and `opt → par`). The Viewer keeps these fields optional, so legacy graphs still render; the CLI validator requires a bar on the callee of every `sync` call answered by a `return`, from the call's `receive` to the return's `send` (legacy graphs without `replyTo` are never asked). `--fix` adds the missing bars, each nested in the innermost bar of that participant around it. Two answered calls to one callee that interleave (the second opens inside the first and closes after it) are not asked for bars, since bars on one participant cannot cross. New source-grounded sequences must explicitly author known executions, nesting and call/return references; the renderer does not infer bars from paired messages. Include only fragment behavior established by the source. These fields require a Viewer built with sequence execution support.
|
|
191
|
+
|
|
192
|
+
A return declares `"replyTo": "call-id"`. It must reference an earlier sync/async call with reversed endpoints, in the same operand path, with at most one explicit return per call. Merge alternative outcomes before that return. Unpaired legacy messages stay legal. Paired labels display `C1` / `↩ C1` independently of editable text. Call and return share a color; nested calls form separate groups. Eight group colors are reused deterministically per theme; larger graphs retain unique pair IDs even when colors repeat. Node module colors are independent.
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
"executions": [{
|
|
196
|
+
"id": "risk-work",
|
|
197
|
+
"participantId": "risk",
|
|
198
|
+
"start": { "edgeId": "check", "at": "receive" },
|
|
199
|
+
"end": { "edgeId": "checked", "at": "send" }
|
|
200
|
+
}]
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Each execution uses message `send`/`receive` endpoints belonging to its participant, start before end. Optional `parentId` declares a same-participant enclosing execution. Siblings cannot overlap. Self-calls connect outer send to inner receive; self-returns end the inner bar at send, not receive. Bars are derived from routes and are not separately draggable.
|
|
204
|
+
|
|
205
|
+
Structured fragments use `operands: [{id, edgeIds, guard?, label?, body?}]`:
|
|
206
|
+
|
|
207
|
+
- `alt`: at least two guarded operands; optional `else` occurs once, last.
|
|
208
|
+
- `opt`: one guarded operand.
|
|
209
|
+
- `loop`: one guarded operand plus `loop: {min, max}`; non-negative integer min, max ≥ min or `"*"`. The condition is displayed, never evaluated.
|
|
210
|
+
- `par`: at least two labeled operands, separated visibly and joined at the frame end. Message order is local to each branch; vertical branch order is not runtime order.
|
|
211
|
+
|
|
212
|
+
A child group specifies `parentId` and `parentOperandId`. For example, a loop operand `{id:"attempt", guard:"attempt < 3", edgeIds:["call","reply"]}` owns an alt group via `{parentId:"retry", parentOperandId:"attempt"}`. An opt operand `{id:"reserved", guard:"reserved", edgeIds:[]}` can own a par group in the same way. List a message directly in only one operand; parents inherit child membership. An empty `edgeIds` array requires non-empty plain-text `body` or a child fragment. Guards and body text are escaped, not executable. Reserve authored frame space for titles, guards, text-only branches, message labels and nested frames; validation rejects cycles, crossing frames, incorrect ownership and collisions.
|
|
213
|
+
|
|
214
|
+
Legacy alt without operand IDs and old unstructured opt/loop remain readable and save without forced migration. Missing conditions are never invented. Sync messages use a solid baseline even for conceptual/inference evidence; evidence remains in metadata and details. Return messages keep dashed open arrows. JSON editing/download, SVG and PNG preserve the same execution bounds, pairing, fragments and group colors; exports remain static.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Guided intake
|
|
2
|
+
|
|
3
|
+
Used only when the invocation and the conversation together do not supply a ready request. A ready request names a **subject** and the **question** the diagram must answer. Everything else has a default and is never asked.
|
|
4
|
+
|
|
5
|
+
## Readiness
|
|
6
|
+
|
|
7
|
+
| Item | Ready when | Never asked |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| Subject | A repository, module, flow, entity set or document is named, at the level the question needs: behaviour questions need one flow (state: one component); structure questions accept a repository or module | — |
|
|
10
|
+
| Question | The user says what the diagram must answer, or names a type that implies it | — |
|
|
11
|
+
| Diagram type | — | Derived from the question by SKILL.md Author step 1; default `architecture` |
|
|
12
|
+
| Granularity | — | Derived from the subject by the altitude rule below; never ask "detailed or simple" |
|
|
13
|
+
| Output directory, language, graph count, CodeGraph setup | — | Existing defaults; the recap shows the directory so the user can override |
|
|
14
|
+
|
|
15
|
+
Only the missing item is asked. A behaviour question with a repository- or module-level subject is missing its flow: run the entry-point scan from the second round below on that subject and ask only for the flow. A request that arrived through the conversation (the skill was triggered by its description) is a ready request when it names both items.
|
|
16
|
+
|
|
17
|
+
## First-round inventory
|
|
18
|
+
|
|
19
|
+
Run before asking so that options name real modules. Budget: directory listing to depth 2 plus manifest presence; do not read source, do not scan entry points, do not run `codegraph explore`.
|
|
20
|
+
|
|
21
|
+
| Signal | Files or directories | Enables |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| Build | `package.json`, `pom.xml`, `build.gradle*`, `go.mod`, `Cargo.toml`, `pyproject.toml`, `*.csproj` | Module candidates; language and framework |
|
|
24
|
+
| Persistence | `migrations/`, `db/migration/`, `*.sql`, `entity/`, `model/`, ORM mapping files | `er` |
|
|
25
|
+
| Deployment | `Dockerfile`, `docker-compose*.yml`, `k8s/`, `helm/`, `charts/` | `deployment` |
|
|
26
|
+
| State | file names containing `State`, `Status`, `Phase`, `Lifecycle` | `state` |
|
|
27
|
+
| Documents | `docs/`, `requirements/`, `*.md` requirement files | `flowchart`, `usecase` |
|
|
28
|
+
| CodeGraph | `.codegraph/` present | Recap says "CodeGraph" instead of "direct tracing" |
|
|
29
|
+
|
|
30
|
+
More than 8 top-level directories: list only subdirectories that contain a build manifest. If the working directory is empty, is not a code repository, or is this plugin's own installation directory, ask for the target repository path or requirements document instead and list no module candidates.
|
|
31
|
+
|
|
32
|
+
## Intent options
|
|
33
|
+
|
|
34
|
+
Phrase options as the question the diagram answers. Each option carries the subject level it needs and a one-word cost tag. Offer at most four, only those the inventory supports, and mark exactly one as recommended (default: the whole repository's structural overview).
|
|
35
|
+
|
|
36
|
+
| Option text | `meta.diagramType` | Needs | Cost | Offer when |
|
|
37
|
+
| --- | --- | --- | --- | --- |
|
|
38
|
+
| What the system is made of and who depends on whom | `architecture` | repository or module | fast | always |
|
|
39
|
+
| Where it runs and how the pieces are deployed | `deployment` | repository | fast | deployment signal |
|
|
40
|
+
| What is stored and how it relates | `er` | repository or module | fast | persistence signal |
|
|
41
|
+
| Which types exist and how they relate | `class` | module | fast | build signal |
|
|
42
|
+
| Who can do what | `usecase` | repository or module | fast | documents signal or public entry points |
|
|
43
|
+
| Who calls whom, in what order | `sequence` | one flow | traces calls | always |
|
|
44
|
+
| What decisions a process makes | `flowchart` | one flow | traces calls | always |
|
|
45
|
+
| How data moves and changes | `dataflow` | one flow | traces calls | always |
|
|
46
|
+
| What states something goes through | `state` | one component | traces calls | state signal |
|
|
47
|
+
|
|
48
|
+
Structure intents (`architecture`, `deployment`, `er`, `class`, `usecase`) read manifests and declarations. Behaviour intents (`sequence`, `flowchart`, `dataflow`, `state`) trace execution paths and cost more; the tag states this, it does not change the recommendation.
|
|
49
|
+
|
|
50
|
+
## Altitude rule and view budget
|
|
51
|
+
|
|
52
|
+
Node unit is one level below the subject:
|
|
53
|
+
|
|
54
|
+
| Subject | Node unit |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| Whole repository | Module or service |
|
|
57
|
+
| Module | Component or class |
|
|
58
|
+
| One flow | Step or function |
|
|
59
|
+
| Entity set | Table |
|
|
60
|
+
|
|
61
|
+
No fixed node or edge cap applies. Keep all facts needed by the requested scope; use the type-specific canvas budget and strict readability checks. A separate detail view may supplement the original model, but must not silently remove its relationships.
|
|
62
|
+
|
|
63
|
+
## Asking
|
|
64
|
+
|
|
65
|
+
One message asks subject and intent together. Use the client's structured question tool when one exists; otherwise number the options in plain text. Do not assume a client-specific tool name. Ask in the user's language.
|
|
66
|
+
|
|
67
|
+
Plain-text shape:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
Which part? 1 order 2 payment 3 inventory 4 whole repository (recommended)
|
|
71
|
+
What should the diagram answer?
|
|
72
|
+
a what the system is made of and who depends on whom — repository or module · fast (recommended)
|
|
73
|
+
b who calls whom, in what order — one flow · traces calls
|
|
74
|
+
c what is stored and how it relates — repository or module · fast
|
|
75
|
+
d where it runs — repository · fast
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
After asking, **end the turn and wait for the reply**. Do not assume an answer. Do not write `index.html`, `graph.json` or any other output before the round completes.
|
|
79
|
+
|
|
80
|
+
## Second round
|
|
81
|
+
|
|
82
|
+
Structure intents finish in the first round. A second round happens only in these cases, and there is never a third:
|
|
83
|
+
|
|
84
|
+
- **No subject yet**: offer at most three modules from the inventory, one recommended.
|
|
85
|
+
- **Two intents**: take the primary one, note that the other can be a second diagram.
|
|
86
|
+
- **Behaviour intent with a repository- or module-level subject**: scan the chosen subject for entry points and offer at most four flows. Use `rg -l` on file names and annotations (`*Controller*`, `*Handler*`, `*Listener*`, `*Consumer*`, `main`, `@RestController`, `@KafkaListener`, route decorators); do not read function bodies. Prefer candidates matching words the user already used. If still too many, group by package and let the user pick a package; that pick is the second round.
|
|
87
|
+
|
|
88
|
+
"Whatever", "you decide" or an equivalent takes the recommended option; state the assumption in the recap.
|
|
89
|
+
|
|
90
|
+
## Recap, then start
|
|
91
|
+
|
|
92
|
+
One line, then start evidence without a second confirmation. The user can correct it with a new message at any time.
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
<type> · <subject> · answers <question> · <node unit>, nodes required by the evidence · <type-specific layout> · <output directory> · <CodeGraph | direct tracing>. Say so to drill into a node later.
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Example: `sequence · order module, OrderController.create flow · answers the call order of placing an order · step-level nodes, as required · participants across and time down · docs/qgraphflow/order-create-sequence/ · direct tracing. Say so to drill into a step later.`
|
|
99
|
+
|
|
100
|
+
If bounded layout fails, report the blocking nodes and relationships and propose separate views with explicit coverage of the original model; never silently reduce the requested detail.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# architecture
|
|
2
|
+
|
|
3
|
+
Components and their dependencies: who calls, reads or depends on whom, inside which runtime or ownership boundary. Read with `graph-common.md`.
|
|
4
|
+
|
|
5
|
+
| Node `kind` | Group `kind` | Edge `kind` |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| `external`, `config`, `framework`, `security`, `service`, `business`, `data`, `failure`, `system`, `component`, `database` | `runtime`, `security`, `ownership`, `external` | `request`, `call`, `data`, `success`, `failure`, `framework`, `optional`, `depends` |
|
|
8
|
+
|
|
9
|
+
## Rules
|
|
10
|
+
|
|
11
|
+
- `business` is the business centre (one or two per view); `service` for services and entry points, `component` for internal modules, `data` for repositories / caches / queues as code, `database` for the store itself, `external` for systems outside the repository (clients, gateways, third parties — no `source`), `security` for auth / filters, `config` for configuration, `framework` for framework-owned runtime pieces, `failure` for an explicit failure handler or dead-letter path, `system` for a whole subsystem shown as one box.
|
|
12
|
+
- Edges follow the direction of the call or data movement: `request` for HTTP / RPC into the system, `call` for in-process or service calls, `data` for reads / writes, `depends` for configuration or library dependency, `success` / `failure` for outcome branches, `framework` for wiring supplied by a framework, `optional` for conditional paths. Label with the operation (`createOrder`, `publish order.created`), not the kind.
|
|
13
|
+
- `groupId` puts a node inside a real boundary (`runtime` = one process / JVM / container, `ownership` = team or module, `security` = trust zone, `external` = outside world). Nodes outside every group are fine.
|
|
14
|
+
- Keep 6–12 nodes per view; a second view beats a crowded one. Every node needs a `source` anchor except externals and framework pieces.
|
|
15
|
+
|
|
16
|
+
## Minimal valid skeleton
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"meta": { "title": "Order service · components", "sourceRef": "repo@main", "diagramType": "architecture", "locale": "zh-CN" },
|
|
21
|
+
"groups": [{ "id": "process", "label": "order-service process", "kind": "runtime" }],
|
|
22
|
+
"nodes": [
|
|
23
|
+
{ "id": "client", "label": "Web client", "kind": "external", "subtitle": "calls POST /orders" },
|
|
24
|
+
{ "id": "api", "label": "OrderController", "kind": "service", "groupId": "process", "module": "order", "source": { "kind": "source", "file": "src/api/orders.js", "lineStart": 1, "lineEnd": 40, "symbol": "OrderController" } },
|
|
25
|
+
{ "id": "service", "label": "OrderService", "kind": "business", "groupId": "process", "module": "order", "subtitle": "createOrder · payOrder", "source": { "kind": "source", "file": "src/services/order-service.js", "lineStart": 6, "lineEnd": 49 } },
|
|
26
|
+
{ "id": "db", "label": "orders DB", "kind": "database", "groupId": "process", "module": "order", "source": { "kind": "schema", "file": "db/schema.sql", "lineStart": 1, "lineEnd": 31 } }
|
|
27
|
+
],
|
|
28
|
+
"edges": [
|
|
29
|
+
{ "id": "e1", "source": "client", "target": "api", "kind": "request", "label": "HTTP", "evidence": "source" },
|
|
30
|
+
{ "id": "e2", "source": "api", "target": "service", "kind": "call", "label": "createOrder", "evidence": "source" },
|
|
31
|
+
{ "id": "e3", "source": "service", "target": "db", "kind": "data", "label": "save order", "evidence": "source" }
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Frequent validation errors
|
|
37
|
+
|
|
38
|
+
- `node X.kind is unsupported for architecture` — you used a kind from another type (`actor`, `process`, `entity`); pick from the table.
|
|
39
|
+
- `node X.groupId does not name a group` — add the group to `groups` or remove `groupId`.
|
|
40
|
+
- `edge e.evidence is unsupported` — one of `source code config schema test document framework inference`.
|
|
41
|
+
- Layout diagnostics after generation (`group.member-inset`, `route.*`) mean the view is too dense: split into two views rather than removing facts.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# class
|
|
2
|
+
|
|
3
|
+
Types and their structural relationships: inheritance, implementation, composition, aggregation, association, dependency. Read with `graph-common.md`.
|
|
4
|
+
|
|
5
|
+
| Node `kind` | Group `kind` | Edge `kind` |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| `class`, `interface`, `abstract` | none | `association`, `inheritance`, `implementation`, `composition`, `aggregation`, `dependency` |
|
|
8
|
+
|
|
9
|
+
## Rules
|
|
10
|
+
|
|
11
|
+
- `attributes` and `methods` are arrays of strings in UML form (`+cents: number`, `+charge(orderId, amount): Promise<Result>`); list the real members, keep declared types. `interface` and `abstract` render with their stereotype.
|
|
12
|
+
- Edge direction: `inheritance` child → parent; `implementation` class → `interface` (the target must be an interface); `composition` / `aggregation` whole → part (diamond at the whole); `association` from the holder of the reference to the referenced type; `dependency` user → used (`new`, parameter, return type).
|
|
13
|
+
- `sourceMultiplicity` / `targetMultiplicity` (`1`, `*`, `0..1`, `1..*`, `2..4`) are allowed only on `association`, `aggregation` and `composition`.
|
|
14
|
+
- Optional `layout.rank` puts parents / interfaces above their children; when given, a child must not rank above its parent.
|
|
15
|
+
- Keep 5–10 classes per view; show the members that matter for the question, but never fabricate ones.
|
|
16
|
+
|
|
17
|
+
## Minimal valid skeleton
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"meta": { "title": "Order domain", "sourceRef": "repo@main", "diagramType": "class", "locale": "zh-CN" },
|
|
22
|
+
"nodes": [
|
|
23
|
+
{ "id": "provider", "label": "PaymentProvider", "kind": "abstract", "methods": ["+charge(orderId, amount): Promise<Result>"], "source": { "kind": "source", "file": "src/domain/payment-provider.js", "lineStart": 2, "lineEnd": 6 } },
|
|
24
|
+
{ "id": "gateway", "label": "GatewayPaymentProvider", "kind": "class", "attributes": ["+client: PaymentGatewayClient"], "methods": ["+charge(orderId, amount): Promise<Result>"], "source": { "kind": "source", "file": "src/domain/payment-provider.js", "lineStart": 8, "lineEnd": 17 } },
|
|
25
|
+
{ "id": "order", "label": "Order", "kind": "class", "attributes": ["+id: string", "+items: OrderItem[]"], "methods": ["+total(): Money"], "source": { "kind": "source", "file": "src/domain/order.js", "lineStart": 17, "lineEnd": 34 } },
|
|
26
|
+
{ "id": "item", "label": "OrderItem", "kind": "class", "attributes": ["+sku: string", "+quantity: number"], "source": { "kind": "source", "file": "src/domain/order.js", "lineStart": 5, "lineEnd": 15 } }
|
|
27
|
+
],
|
|
28
|
+
"edges": [
|
|
29
|
+
{ "id": "c1", "source": "gateway", "target": "provider", "kind": "inheritance", "evidence": "source" },
|
|
30
|
+
{ "id": "c2", "source": "order", "target": "item", "kind": "composition", "label": "items", "sourceMultiplicity": "1", "targetMultiplicity": "1..*", "evidence": "source" }
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Frequent validation errors
|
|
36
|
+
|
|
37
|
+
- `edge c implementation target must be an interface` — use `inheritance` for an abstract base class, `implementation` only towards `kind: "interface"`.
|
|
38
|
+
- `edge c.sourceMultiplicity is only supported on associations, aggregation and composition` — remove multiplicities from inheritance / implementation / dependency.
|
|
39
|
+
- `edge c layout.rank must place parent/interface above` — drop the conflicting `layout.rank` or reorder it.
|
|
40
|
+
- Layout `spacing.labels` on two associations from different holders into one target with the same end multiplicity (`0..1` twice) — the multiplicity labels land on one port; write the multiplicity into those two labels (`ledger 0..1(…)`) and drop the field on them only.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# dataflow
|
|
2
|
+
|
|
3
|
+
How data moves between external entities, processes and data stores (Gane–Sarson style). Read with `graph-common.md`.
|
|
4
|
+
|
|
5
|
+
| Node `kind` | Group `kind` | Edge `kind` |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| `external`, `process`, `dataStore` | `ownership`, `external` | `data` |
|
|
8
|
+
|
|
9
|
+
## Rules
|
|
10
|
+
|
|
11
|
+
- `external` is a source or sink outside the system (user, partner API — no `source`); `process` transforms data (a service method, a job); `dataStore` holds it (table group, file, cache, topic).
|
|
12
|
+
- Every edge is `data` and its `label` names the data that flows (`customerId, items`, `paid orders`), not the operation. Direction is the direction the data moves; a request and its response are two edges when both carry data.
|
|
13
|
+
- Flows directly between stores, or from an external entity to a store, are kept when the source shows them; do not insert a process to make the notation "pure".
|
|
14
|
+
- `groups` mark ownership (`ownership`) or the outside world (`external`) only when the boundary is real. Anchor processes to the function, stores to the schema / file writer.
|
|
15
|
+
- Keep 6–10 nodes per view; one pipeline or one request path per view. `module` follows the evidenced domain of each process and store (the service, the cache layer, the topic); an external that belongs to a channel carries it too.
|
|
16
|
+
|
|
17
|
+
## Minimal valid skeleton
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"meta": { "title": "Order data flow", "sourceRef": "repo@main", "diagramType": "dataflow", "locale": "zh-CN" },
|
|
22
|
+
"nodes": [
|
|
23
|
+
{ "id": "buyer", "label": "Buyer", "kind": "external" },
|
|
24
|
+
{ "id": "create", "label": "createOrder", "kind": "process", "tags": ["core"], "source": { "kind": "source", "file": "src/services/order-service.js", "lineStart": 15, "lineEnd": 37 } },
|
|
25
|
+
{ "id": "orders", "label": "orders / order_items", "kind": "dataStore", "source": { "kind": "source", "file": "src/repo/order-repository.js", "lineStart": 8, "lineEnd": 11 } },
|
|
26
|
+
{ "id": "export", "label": "settlement export", "kind": "process", "source": { "kind": "source", "file": "src/jobs/settlement-export.js", "lineStart": 6, "lineEnd": 21 } },
|
|
27
|
+
{ "id": "csv", "label": "settlement CSV", "kind": "dataStore" }
|
|
28
|
+
],
|
|
29
|
+
"edges": [
|
|
30
|
+
{ "id": "d1", "source": "buyer", "target": "create", "kind": "data", "label": "customerId, items", "evidence": "source" },
|
|
31
|
+
{ "id": "d2", "source": "create", "target": "orders", "kind": "data", "label": "order", "evidence": "source" },
|
|
32
|
+
{ "id": "d3", "source": "orders", "target": "export", "kind": "data", "label": "paid orders", "evidence": "source" },
|
|
33
|
+
{ "id": "d4", "source": "export", "target": "csv", "kind": "data", "label": "settlement rows", "evidence": "source" }
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Frequent validation errors
|
|
39
|
+
|
|
40
|
+
- `edge d.kind is unsupported for dataflow` — only `data`; the operation belongs in the label.
|
|
41
|
+
- `node X.kind is unsupported for dataflow` — `service` / `component` / `database` are architecture kinds; here they are `process` or `dataStore`.
|