dsh-model-everything 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.en-US.md +332 -0
- package/README.md +332 -3
- package/cordis.patch.yml +20 -0
- package/examples/README.md +48 -0
- package/examples/control-dispatcher.json +113 -0
- package/examples/control-dispatcher.overbudget.json +113 -0
- package/examples/ecommerce-data-model.json +185 -0
- package/examples/order-state-machine.after.json +116 -0
- package/examples/order-state-machine.before.json +101 -0
- package/examples/user-migration.after.json +29 -0
- package/examples/user-migration.before.json +29 -0
- package/gate/locale/en.json +6 -0
- package/gate/locale/zh.json +6 -0
- package/gate/package.json +5 -0
- package/lib/baseline.js +249 -0
- package/lib/compose-tool.js +80 -0
- package/lib/concurrency-tool.js +40 -0
- package/lib/concurrency.js +206 -0
- package/lib/data-engine.js +1141 -0
- package/lib/data-tool.js +87 -0
- package/lib/design-engine.js +1149 -0
- package/lib/design-tool.js +63 -0
- package/lib/engine.js +4343 -0
- package/lib/export-tool.js +78 -0
- package/lib/exporters.js +434 -0
- package/lib/gate.js +274 -0
- package/lib/granularity.js +237 -0
- package/lib/index.js +237 -0
- package/lib/json-value.js +18 -0
- package/lib/model-file.js +48 -0
- package/lib/option-shape.js +62 -0
- package/lib/report-diff-tool.js +63 -0
- package/lib/report-view.js +433 -0
- package/lib/structure-tool.js +91 -0
- package/lib/structure.js +711 -0
- package/lib/tool.js +94 -0
- package/lib/types/baseline.d.ts +65 -0
- package/lib/types/compose-tool.d.ts +7 -0
- package/lib/types/concurrency-tool.d.ts +8 -0
- package/lib/types/concurrency.d.ts +37 -0
- package/lib/types/data-engine.d.ts +211 -0
- package/lib/types/data-tool.d.ts +10 -0
- package/lib/types/design-engine.d.ts +215 -0
- package/lib/types/design-tool.d.ts +11 -0
- package/lib/types/engine.d.ts +494 -0
- package/lib/types/export-tool.d.ts +7 -0
- package/lib/types/exporters.d.ts +37 -0
- package/lib/types/gate.d.ts +91 -0
- package/lib/types/granularity.d.ts +106 -0
- package/lib/types/index.d.ts +45 -0
- package/lib/types/json-value.d.ts +21 -0
- package/lib/types/model-file.d.ts +7 -0
- package/lib/types/option-shape.d.ts +22 -0
- package/lib/types/report-diff-tool.d.ts +8 -0
- package/lib/types/report-view.d.ts +50 -0
- package/lib/types/structure-tool.d.ts +10 -0
- package/lib/types/structure.d.ts +152 -0
- package/lib/types/tool.d.ts +11 -0
- package/lib/types/uml-communication.d.ts +109 -0
- package/lib/types/uml-composite.d.ts +107 -0
- package/lib/types/uml-interaction-overview.d.ts +91 -0
- package/lib/types/uml-profile.d.ts +112 -0
- package/lib/types/uml-structure.d.ts +53 -0
- package/lib/types/uml-syntax.d.ts +296 -0
- package/lib/types/uml-timing.d.ts +152 -0
- package/lib/types/uml-tool.d.ts +12 -0
- package/lib/types/uml-usecase.d.ts +58 -0
- package/lib/types/uml.d.ts +303 -0
- package/lib/uml-communication.js +353 -0
- package/lib/uml-composite.js +442 -0
- package/lib/uml-interaction-overview.js +277 -0
- package/lib/uml-profile.js +373 -0
- package/lib/uml-structure.js +306 -0
- package/lib/uml-syntax.js +545 -0
- package/lib/uml-timing.js +974 -0
- package/lib/uml-tool.js +213 -0
- package/lib/uml-usecase.js +532 -0
- package/lib/uml.js +2110 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +128 -6
- package/skills/model-everything/SKILL.md +450 -0
- package/skills/model-everything/references/dsh-model-schema.md +437 -0
- package/skills/model-everything/references/gap-routing-guide.md +42 -0
- package/skills/model-everything/references/hash-spec.md +152 -0
- package/skills/model-everything/references/logic-verification-guide.md +422 -0
- package/skills/model-everything-datamodel/SKILL.md +130 -0
- package/skills/model-everything-datamodel/references/data-model-guide.md +84 -0
- package/skills/model-everything-datamodel/references/data-model-schema.md +128 -0
- package/skills/model-everything-design/SKILL.md +115 -0
- package/skills/model-everything-interleaving/SKILL.md +63 -0
- package/skills/model-everything-interleaving/SKILL.zh-CN.md +60 -0
- package/skills/model-everything-interleaving/references/concurrency-risk-guide.md +63 -0
- package/skills/model-everything-report-reading/SKILL.md +137 -0
- package/skills/model-everything-report-reading/references/reading-a-report.md +166 -0
- package/skills/model-everything-report-reading/references/reading-a-report.mmd +59 -0
- package/skills/model-everything-structure/SKILL.md +96 -0
- package/skills/model-everything-structure/references/structure-review-guide.md +201 -0
- package/skills/model-everything-uml/SKILL.md +60 -0
- package/skills/model-everything-uml/references/uml-modeling-guide.md +551 -0
- package/src/baseline.ts +288 -0
- package/src/compose-tool.ts +82 -0
- package/src/concurrency-tool.ts +44 -0
- package/src/concurrency.ts +254 -0
- package/src/data-engine.ts +1208 -0
- package/src/data-tool.ts +91 -0
- package/src/design-engine.ts +1263 -0
- package/src/design-tool.ts +68 -0
- package/src/engine.ts +4564 -0
- package/src/export-tool.ts +81 -0
- package/src/exporters.ts +399 -0
- package/src/gate.ts +330 -0
- package/src/granularity.ts +312 -0
- package/src/index.ts +289 -0
- package/src/json-value.ts +20 -0
- package/src/model-file.ts +49 -0
- package/src/option-shape.ts +64 -0
- package/src/report-diff-tool.ts +67 -0
- package/src/report-view.ts +483 -0
- package/src/structure-tool.ts +93 -0
- package/src/structure.ts +786 -0
- package/src/tool.ts +103 -0
- package/src/uml-communication.ts +428 -0
- package/src/uml-composite.ts +520 -0
- package/src/uml-interaction-overview.ts +321 -0
- package/src/uml-profile.ts +439 -0
- package/src/uml-structure.ts +317 -0
- package/src/uml-syntax.ts +764 -0
- package/src/uml-timing.ts +1106 -0
- package/src/uml-tool.ts +230 -0
- package/src/uml-usecase.ts +566 -0
- package/src/uml.ts +2139 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The timing diagram module.
|
|
3
|
+
*
|
|
4
|
+
* A timing diagram is an interaction seen against a clock: which participants exist,
|
|
5
|
+
* what state each one is in over time, and what they send each other. It is not a
|
|
6
|
+
* machine and not a trace, so it has its own model — lifelines, the time points they
|
|
7
|
+
* change state at, the messages between them, and the duration constraints — its own
|
|
8
|
+
* renderer, and its own review.
|
|
9
|
+
*
|
|
10
|
+
* PlantUML is the only notation that draws one. Mermaid has no timing diagram, and the
|
|
11
|
+
* engine's capability table says so with a reason instead of drawing something else
|
|
12
|
+
* under the name.
|
|
13
|
+
*
|
|
14
|
+
* @module model-everything-uml-timing
|
|
15
|
+
*/
|
|
16
|
+
import { type UmlNotation, type UmlFamilyModule, type UmlFamilyParse, type UmlFamilyRender, type UmlFamilyFinding } from './uml-syntax.js';
|
|
17
|
+
/**
|
|
18
|
+
* What this module carries out of the PlantUML timing syntax, and what it does not.
|
|
19
|
+
*
|
|
20
|
+
* Carried: the lifeline kinds with their `period`, state points and ranges, relative
|
|
21
|
+
* times, messages with their own time, and the `<->` duration constraints.
|
|
22
|
+
*
|
|
23
|
+
* Not carried, and reported as discarded constructs rather than dropped: participant
|
|
24
|
+
* blocks (`@WB` with per-lifeline times), anchor points (`@XX as :name`), states with
|
|
25
|
+
* comments or colours (`is Waiting : note`, `is Waiting #LightCyan`), `highlight`,
|
|
26
|
+
* `note top of`, scale and date axes, `mode compact`, and the `has` state-order
|
|
27
|
+
* declaration. Each is a real construct of the notation; none of them is a state or a
|
|
28
|
+
* message, and inventing a model for them would be the fabrication this plugin exists to
|
|
29
|
+
* refuse.
|
|
30
|
+
*
|
|
31
|
+
* The syntax reference is <https://plantuml.com/timing-diagram>.
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* How PlantUML draws a lifeline. The kind is part of the model, not decoration: a
|
|
35
|
+
* `binary` lifeline can only be in two states, and a `clock` one carries a period.
|
|
36
|
+
*/
|
|
37
|
+
export type TimingLifelineKind = 'robust' | 'concise' | 'binary' | 'clock' | 'analog' | 'rectangle';
|
|
38
|
+
export interface TimingLifeline {
|
|
39
|
+
id: string;
|
|
40
|
+
/** Human-readable name, when the diagram gave one that differs from the id. */
|
|
41
|
+
label?: string;
|
|
42
|
+
/** Drawing style. Absent means PlantUML's default. */
|
|
43
|
+
kind?: TimingLifelineKind;
|
|
44
|
+
/** `clock` only: the period PlantUML draws the clock with. */
|
|
45
|
+
period?: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* One state a lifeline is monitored in, over a half-open time interval `[from, to)`.
|
|
49
|
+
*
|
|
50
|
+
* `to` is optional in the input and always written on parse: a state runs until the
|
|
51
|
+
* next one on the same lifeline begins. Carrying it makes "how long was it in this
|
|
52
|
+
* state" a property of the model instead of a question about its neighbours.
|
|
53
|
+
*/
|
|
54
|
+
export interface TimingLifelineState {
|
|
55
|
+
id: string;
|
|
56
|
+
/** What the state means to a reader, when it is more than the id. */
|
|
57
|
+
label?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* One stretch of time a lifeline spends in a state, starting at `from`.
|
|
61
|
+
*
|
|
62
|
+
* There is no `to`. The PlantUML syntax has no way to say "this state ends here": a
|
|
63
|
+
* lifeline is a list of changes, so the next change on the same lifeline *is* this
|
|
64
|
+
* one's end. Carrying an explicit end would be a field the diagram cannot express, and
|
|
65
|
+
* the round trip would drop it — which is exactly what it did before this field was
|
|
66
|
+
* removed.
|
|
67
|
+
*/
|
|
68
|
+
export interface TimingSegment {
|
|
69
|
+
/** The lifeline being monitored. */
|
|
70
|
+
lifeline: string;
|
|
71
|
+
/** The state it is in from `from` up to the next state change on the same lifeline. */
|
|
72
|
+
state: string;
|
|
73
|
+
from: number;
|
|
74
|
+
/** PlantUML's `at <time> is <state>`, which marks the left edge as well. */
|
|
75
|
+
atStart?: boolean;
|
|
76
|
+
}
|
|
77
|
+
export interface TimingMessage {
|
|
78
|
+
from: string;
|
|
79
|
+
to: string;
|
|
80
|
+
time: number;
|
|
81
|
+
label?: string;
|
|
82
|
+
}
|
|
83
|
+
/** `@a <-> @b : {duration}` between two moments of the timeline. */
|
|
84
|
+
export interface TimingConstraint {
|
|
85
|
+
fromTime: number;
|
|
86
|
+
toTime: number;
|
|
87
|
+
/** The duration text as PlantUML draws it, braces included. */
|
|
88
|
+
label?: string;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* A timing diagram as a model.
|
|
92
|
+
*
|
|
93
|
+
* Times are numbers on one axis for the whole diagram. Their unit is a property of the
|
|
94
|
+
* diagram (`unit`), not of a point: `{ms}` on one arrow and `{s}` on the next would be
|
|
95
|
+
* a diagram that cannot be read.
|
|
96
|
+
*/
|
|
97
|
+
export interface TimingModelV1 {
|
|
98
|
+
schemaVersion: 1;
|
|
99
|
+
/** The time unit the axis is drawn in, when the diagram declares one. */
|
|
100
|
+
unit?: string;
|
|
101
|
+
lifelines: TimingLifeline[];
|
|
102
|
+
states: TimingLifelineState[];
|
|
103
|
+
segments: TimingSegment[];
|
|
104
|
+
messages: TimingMessage[];
|
|
105
|
+
constraints: TimingConstraint[];
|
|
106
|
+
/**
|
|
107
|
+
* Ids a message or a segment named that no declaration introduced. PlantUML accepts
|
|
108
|
+
* them and draws a bare timeline, which is exactly how a typo stays invisible.
|
|
109
|
+
*/
|
|
110
|
+
undeclared?: string[];
|
|
111
|
+
narrative?: {
|
|
112
|
+
lifelines?: Record<string, string>;
|
|
113
|
+
states?: Record<string, string>;
|
|
114
|
+
unit?: string;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Validate a candidate model and normalize it.
|
|
119
|
+
*
|
|
120
|
+
* The contract other families keep: an undeclared key or a wrong type is a refusal with
|
|
121
|
+
* `UML_INPUT`, never a silently dropped field. A model that renders into a diagram that
|
|
122
|
+
* is not the model is worse than no diagram.
|
|
123
|
+
*/
|
|
124
|
+
export declare function validateTimingModel(input: unknown): TimingModelV1;
|
|
125
|
+
/**
|
|
126
|
+
* Render a timing model as PlantUML.
|
|
127
|
+
*
|
|
128
|
+
* @param input - candidate `TimingModelV1`.
|
|
129
|
+
* @param notation - only `plantuml` draws a timing diagram; another notation is refused
|
|
130
|
+
* by the capability table before reaching here.
|
|
131
|
+
*/
|
|
132
|
+
export declare function renderTiming(input: unknown, notation: UmlNotation): UmlFamilyRender;
|
|
133
|
+
/**
|
|
134
|
+
* Read PlantUML timing text back into a model.
|
|
135
|
+
*
|
|
136
|
+
* Two sources are read together, and the diagram wins where they disagree: the diagram
|
|
137
|
+
* is what a reader sees. The directives carry only what the syntax cannot spell — the
|
|
138
|
+
* exact state ids, the explicit end of a segment, the unit — so a hand-written diagram
|
|
139
|
+
* with no directives still parses into a complete model.
|
|
140
|
+
*/
|
|
141
|
+
export declare function parseTiming(text: string, notation: UmlNotation): UmlFamilyParse<TimingModelV1>;
|
|
142
|
+
export type TimingFindingCode = 'UML042_TIMING_NO_LIFELINES' | 'UML043_TIMING_EMPTY_LIFELINE' | 'UML044_TIMING_TIME_ORDER' | 'UML045_TIMING_SIMULTANEOUS_STATES' | 'UML046_TIMING_UNDECLARED_REFERENCE' | 'UML047_TIMING_CONSTRAINT_RANGE' | 'UML048_TIMING_STATE_UNUSED' | 'UML049_TIMING_UNDOCUMENTED';
|
|
143
|
+
export declare const TIMING_FINDING_CODES: readonly TimingFindingCode[];
|
|
144
|
+
/**
|
|
145
|
+
* What a reader would get wrong about a timing diagram.
|
|
146
|
+
*
|
|
147
|
+
* The checks read the model alone: whether a duration is achievable is a question about
|
|
148
|
+
* the system, not about the diagram, and it is not answered here.
|
|
149
|
+
*/
|
|
150
|
+
export declare function reviewTimingModel(model: TimingModelV1, labels: Record<string, string>): UmlFamilyFinding[];
|
|
151
|
+
/** The timing family, as the engine's registry expects it. */
|
|
152
|
+
export declare const timingModule: UmlFamilyModule<TimingModelV1>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const UML_RENDER_TOOL_NAME = "uml_render";
|
|
2
|
+
export declare const UML_PARSE_TOOL_NAME = "uml_parse";
|
|
3
|
+
export declare const UML_REVIEW_TOOL_NAME = "uml_review";
|
|
4
|
+
export declare const UML_LABELS_TOOL_NAME = "uml_explain_labels";
|
|
5
|
+
/** Draw a model as diagram source. */
|
|
6
|
+
export declare const umlRenderTool: import("@deepseek-ai/dsh-tools").ToolDefinition;
|
|
7
|
+
/** Read diagram text into the model of the family it declares. */
|
|
8
|
+
export declare const umlParseTool: import("@deepseek-ai/dsh-tools").ToolDefinition;
|
|
9
|
+
/** Audit the modelling: the diagram, the model, or the two against each other. */
|
|
10
|
+
export declare const umlReviewTool: import("@deepseek-ai/dsh-tools").ToolDefinition;
|
|
11
|
+
/** Print the label and comment contract the parser accepts. */
|
|
12
|
+
export declare const umlExplainLabelsTool: import("@deepseek-ai/dsh-tools").ToolDefinition;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The use case diagram module.
|
|
3
|
+
*
|
|
4
|
+
* A use case diagram is not a machine: it says who uses the system and which services
|
|
5
|
+
* the system offers, not in what order anything happens. So it has its own model
|
|
6
|
+
* (actors, use cases, a subject, and the relations between them), its own renderer,
|
|
7
|
+
* and its own review. Handing this text to the state parser was the bug this module
|
|
8
|
+
* exists to fix: `:User: --> (Login)` used to come back as a state machine with no
|
|
9
|
+
* finding at all.
|
|
10
|
+
*
|
|
11
|
+
* PlantUML is the only notation that draws one. Mermaid has no use case diagram, and
|
|
12
|
+
* the engine's capability table says so with a reason instead of rendering something
|
|
13
|
+
* else under the name.
|
|
14
|
+
*
|
|
15
|
+
* @module model-everything-uml-usecase
|
|
16
|
+
*/
|
|
17
|
+
import { type UmlNotation, type UmlFamilyModule, type UmlFamilyParse, type UmlFamilyRender, type UmlFamilyFinding } from './uml-syntax.js';
|
|
18
|
+
export interface UseCaseElement {
|
|
19
|
+
id: string;
|
|
20
|
+
/** Human-readable name, when the diagram gave one that differs from the id. */
|
|
21
|
+
label?: string;
|
|
22
|
+
}
|
|
23
|
+
export type UseCaseRelationKind = 'association' | 'include' | 'extend' | 'generalization';
|
|
24
|
+
export interface UseCaseRelation {
|
|
25
|
+
/** The element the relation starts at. For a generalization this is the more specific one. */
|
|
26
|
+
from: string;
|
|
27
|
+
to: string;
|
|
28
|
+
kind: UseCaseRelationKind;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A use case diagram as a model.
|
|
32
|
+
*
|
|
33
|
+
* The narrative is optional and holds the same information a reader needs: what each
|
|
34
|
+
* actor and each use case means in the words of the system being described.
|
|
35
|
+
*/
|
|
36
|
+
export interface UseCaseModelV1 {
|
|
37
|
+
schemaVersion: 1;
|
|
38
|
+
/** The system under discussion, when the diagram draws its boundary. */
|
|
39
|
+
subject?: string;
|
|
40
|
+
actors: UseCaseElement[];
|
|
41
|
+
useCases: UseCaseElement[];
|
|
42
|
+
relations: UseCaseRelation[];
|
|
43
|
+
/** Ids a relation named that no declaration introduced; the review reports them. */
|
|
44
|
+
undeclared?: string[];
|
|
45
|
+
narrative?: {
|
|
46
|
+
subject?: string;
|
|
47
|
+
actors?: Record<string, string>;
|
|
48
|
+
useCases?: Record<string, string>;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export declare function validateUseCaseModel(input: unknown): UseCaseModelV1;
|
|
52
|
+
export declare function renderUseCase(input: unknown, notation: UmlNotation): UmlFamilyRender;
|
|
53
|
+
export declare function parseUseCase(text: string, notation: UmlNotation): UmlFamilyParse<UseCaseModelV1>;
|
|
54
|
+
export type UseCaseFindingCode = 'UML030_USE_CASE_NO_ACTORS' | 'UML031_USE_CASE_NO_USE_CASES' | 'UML032_ISOLATED_ACTOR' | 'UML033_USE_CASE_WITHOUT_ACTOR' | 'UML034_DANGLING_RELATION_ENDPOINT' | 'UML035_INCLUDE_EXTEND_CYCLE' | 'UML036_ACTOR_TO_ACTOR_ASSOCIATION' | 'UML037_ACTOR_INCLUDE_EXTEND' | 'UML038_SELF_RELATION' | 'UML039_USE_CASE_UNDOCUMENTED';
|
|
55
|
+
export declare const USE_CASE_FINDING_CODES: readonly UseCaseFindingCode[];
|
|
56
|
+
export declare function reviewUseCaseModel(model: UseCaseModelV1, labels: Record<string, string>): UmlFamilyFinding[];
|
|
57
|
+
/** The use case family, as the engine's registry expects it. */
|
|
58
|
+
export declare const useCaseModule: UmlFamilyModule<UseCaseModelV1>;
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UML front end for LogicModelV1 — model a code flow as a UML diagram, then
|
|
3
|
+
* review the modelling itself.
|
|
4
|
+
*
|
|
5
|
+
* Two halves, one data flow:
|
|
6
|
+
*
|
|
7
|
+
* 1. `renderUml` turns a validated LogicModelV1 into Mermaid or PlantUML text
|
|
8
|
+
* (state machine, activity/flow, or sequence trace). The diagram is a
|
|
9
|
+
* *view*: it never invents structure the model does not have, and anything
|
|
10
|
+
* the notation cannot express is reported as a warning instead of being
|
|
11
|
+
* dropped silently.
|
|
12
|
+
* 2. `parseUml` reads that text back into a LogicModelV1, and `reviewUml`
|
|
13
|
+
* compares the two. That comparison is the point of the feature: a UML
|
|
14
|
+
* diagram of a code flow is itself a model, and a model can be wrong —
|
|
15
|
+
* ambiguous branches, dead ends, flows nobody can enter, symbols the
|
|
16
|
+
* source never names. A diagram that does not round-trip to the model it
|
|
17
|
+
* was drawn from is mis-modelled, and the review says so.
|
|
18
|
+
*
|
|
19
|
+
* Why the round trip is the fidelity check: rendering and parsing are inverse
|
|
20
|
+
* only if every construct survives the notation. The generated text carries
|
|
21
|
+
* `dsh-model-everything:` directives (ignored by Mermaid/PlantUML renderers) that pin the
|
|
22
|
+
* initial state, the terminal states and any state id the notation cannot spell
|
|
23
|
+
* verbatim, so an exact comparison is possible rather than a fuzzy one.
|
|
24
|
+
*
|
|
25
|
+
* The review deliberately does NOT replace `model_verify`: it checks the
|
|
26
|
+
* modelling (structure the diagram claims, documentation coverage, notation
|
|
27
|
+
* fidelity), while S1-S8/A1-A14 check the machine's behaviour (guard
|
|
28
|
+
* exhaustiveness under real valuations, invariant paths, deadlock/liveness in
|
|
29
|
+
* the runtime state space). Findings name the engine check to run next.
|
|
30
|
+
*
|
|
31
|
+
* @module model-everything-uml
|
|
32
|
+
*/
|
|
33
|
+
import { type HashSpec, type NarrativeCoverage, type ReportSchema, type Verdict } from './engine.js';
|
|
34
|
+
import type { GuardNode, LogicModelV1, UpdateSpec } from './engine.js';
|
|
35
|
+
import { type UmlNotation, type UmlFamilyId } from './uml-syntax.js';
|
|
36
|
+
import { type UseCaseModelV1 } from './uml-usecase.js';
|
|
37
|
+
import { type StructureModelV1 } from './uml-structure.js';
|
|
38
|
+
import { type TimingModelV1 } from './uml-timing.js';
|
|
39
|
+
import { type ProfileModelV1 } from './uml-profile.js';
|
|
40
|
+
import { type CompositeModelV1 } from './uml-composite.js';
|
|
41
|
+
import { type CommunicationModelV1 } from './uml-communication.js';
|
|
42
|
+
import { type InteractionOverviewModelV1 } from './uml-interaction-overview.js';
|
|
43
|
+
export { UmlError, UML_NOTATIONS } from './uml-syntax.js';
|
|
44
|
+
export type { UmlNotation, UmlFamilyId } from './uml-syntax.js';
|
|
45
|
+
export { validateTimingModel, reviewTimingModel, TIMING_FINDING_CODES, parseTiming, renderTiming } from './uml-timing.js';
|
|
46
|
+
export type { TimingModelV1, TimingSegment, TimingLifeline, TimingFindingCode } from './uml-timing.js';
|
|
47
|
+
export { validateProfileModel, reviewProfileModel, PROFILE_FINDING_CODES, renderProfile, profileModule } from './uml-profile.js';
|
|
48
|
+
export type { ProfileModelV1, ProfileExtension, ProfileApplication, ProfileFindingCode } from './uml-profile.js';
|
|
49
|
+
export { validateCompositeModel, reviewCompositeModel, COMPOSITE_FINDING_CODES, renderComposite, parseComposite, compositeModule } from './uml-composite.js';
|
|
50
|
+
export type { CompositeModelV1, CompositePart, CompositePort, CompositeConnector, CompositeFindingCode } from './uml-composite.js';
|
|
51
|
+
export { validateCommunicationModel, reviewCommunicationModel, COMMUNICATION_FINDING_CODES, renderCommunication, parseCommunication, communicationModule, communicationSequenceOrder } from './uml-communication.js';
|
|
52
|
+
export type { CommunicationModelV1, CommunicationLifeline, CommunicationMessage, CommunicationFindingCode } from './uml-communication.js';
|
|
53
|
+
export { validateInteractionOverviewModel, reviewInteractionOverviewModel, INTERACTION_OVERVIEW_FINDING_CODES, renderInteractionOverview, parseInteractionOverview, interactionOverviewModule } from './uml-interaction-overview.js';
|
|
54
|
+
export type { InteractionOverviewModelV1, InteractionOverviewNode, InteractionOverviewEdge, InteractionOverviewFindingCode } from './uml-interaction-overview.js';
|
|
55
|
+
/**
|
|
56
|
+
* The diagram families this front end knows, in the engine's order. The name is kept
|
|
57
|
+
* for callers that already use it: it is now the whole UML 2.5 family list rather
|
|
58
|
+
* than the three machine views.
|
|
59
|
+
*/
|
|
60
|
+
export type UmlDiagram = UmlFamilyId;
|
|
61
|
+
export declare const UML_DIAGRAMS: readonly UmlDiagram[];
|
|
62
|
+
/**
|
|
63
|
+
* What the caller is going to do with the artifact, declared up front.
|
|
64
|
+
*
|
|
65
|
+
* The view follows the question, not the machine, so the tool cannot pick it. What it
|
|
66
|
+
* can do is refuse a pairing that cannot serve the question — before the work, not as
|
|
67
|
+
* a finding after it.
|
|
68
|
+
*/
|
|
69
|
+
export type UmlIntent = 'present' | 'verify' | 'fidelity';
|
|
70
|
+
export declare const UML_INTENTS: readonly UmlIntent[];
|
|
71
|
+
/** The tool actions, for the entry check. `labels` is `action=explain-labels`. */
|
|
72
|
+
export type UmlIntentAction = 'render' | 'parse' | 'review' | 'labels';
|
|
73
|
+
export interface UmlRenderResult {
|
|
74
|
+
notation: UmlNotation;
|
|
75
|
+
diagram: UmlDiagram;
|
|
76
|
+
/** The diagram source; hand this to the user or a renderer as-is. */
|
|
77
|
+
primary: string;
|
|
78
|
+
warnings: string[];
|
|
79
|
+
}
|
|
80
|
+
/** What a family's parse produces: a LogicModelV1 for the machine families, the family model otherwise. */
|
|
81
|
+
export type UmlFamilyModel = LogicModelV1 | UseCaseModelV1 | StructureModelV1 | TimingModelV1 | ProfileModelV1 | CompositeModelV1 | CommunicationModelV1 | InteractionOverviewModelV1;
|
|
82
|
+
export interface UmlParseResult {
|
|
83
|
+
notation: UmlNotation;
|
|
84
|
+
diagram: UmlDiagram;
|
|
85
|
+
/** Which family model `model` holds. */
|
|
86
|
+
family: UmlFamilyId;
|
|
87
|
+
model: UmlFamilyModel;
|
|
88
|
+
/**
|
|
89
|
+
* Display labels found in the diagram, keyed by state id. They are how a
|
|
90
|
+
* reader learns what a symbol means; a missing entry is an undocumented
|
|
91
|
+
* symbol, which the review reports.
|
|
92
|
+
*/
|
|
93
|
+
labels: Record<string, string>;
|
|
94
|
+
/**
|
|
95
|
+
* Declarations found in the text that LogicModelV1 cannot represent. A non-empty
|
|
96
|
+
* list means the parsed model is NOT this diagram: the text belongs to another
|
|
97
|
+
* diagram family (component, package, class, deployment, …), so whatever came
|
|
98
|
+
* out is a by-product of reading keywords the parser does not own.
|
|
99
|
+
*/
|
|
100
|
+
discardedConstructs: DiscardedConstruct[];
|
|
101
|
+
/**
|
|
102
|
+
* Arrows whose endpoints were declared by a discarded construct. They survive
|
|
103
|
+
* parsing as state transitions, which is exactly why they are counted out loud.
|
|
104
|
+
*/
|
|
105
|
+
discardedEdges: number;
|
|
106
|
+
warnings: string[];
|
|
107
|
+
}
|
|
108
|
+
/** One declaration the parser could not represent, with the source line that carried it. */
|
|
109
|
+
export interface DiscardedConstruct {
|
|
110
|
+
/** The construct keyword, lower-cased (`component`, `package`, `classDiagram`). */
|
|
111
|
+
construct: string;
|
|
112
|
+
/** 1-based line number in the diagram source. */
|
|
113
|
+
line: number;
|
|
114
|
+
/** The source line, trimmed. */
|
|
115
|
+
text: string;
|
|
116
|
+
}
|
|
117
|
+
export interface UmlFinding {
|
|
118
|
+
code: string;
|
|
119
|
+
severity: 'error' | 'warning' | 'info';
|
|
120
|
+
message: string;
|
|
121
|
+
states?: string[];
|
|
122
|
+
events?: string[];
|
|
123
|
+
transitions?: Array<{
|
|
124
|
+
from: string;
|
|
125
|
+
event: string;
|
|
126
|
+
to: string;
|
|
127
|
+
}>;
|
|
128
|
+
detail?: string;
|
|
129
|
+
/** Machine-readable context for the finding (ids, coverage, rule matches), same shape as the engine's findings. */
|
|
130
|
+
evidence?: Record<string, unknown>;
|
|
131
|
+
}
|
|
132
|
+
export interface UmlRoundTripReport {
|
|
133
|
+
notation: UmlNotation;
|
|
134
|
+
diagram: UmlDiagram;
|
|
135
|
+
ok: boolean;
|
|
136
|
+
/** Which published hash specification the two hashes follow (see references/hash-spec.md). */
|
|
137
|
+
hashSpec: HashSpec;
|
|
138
|
+
modelHash: string;
|
|
139
|
+
parsedHash: string;
|
|
140
|
+
diffs: string[];
|
|
141
|
+
warnings: string[];
|
|
142
|
+
}
|
|
143
|
+
export interface UmlReviewReport {
|
|
144
|
+
/** The review ran and produced this report. It does NOT mean the modelling passed — read `verdict`. */
|
|
145
|
+
ok: boolean;
|
|
146
|
+
ran: boolean;
|
|
147
|
+
verdict: Verdict;
|
|
148
|
+
verdictReason: string;
|
|
149
|
+
/** The versioned report contract this result follows. */
|
|
150
|
+
schema: ReportSchema;
|
|
151
|
+
source: 'model' | 'diagram' | 'model+diagram';
|
|
152
|
+
/** Which UML family this review covers. */
|
|
153
|
+
family?: UmlFamilyId;
|
|
154
|
+
/** Element counts for a family whose model is not a machine. */
|
|
155
|
+
familySummary?: {
|
|
156
|
+
actors?: number;
|
|
157
|
+
useCases?: number;
|
|
158
|
+
relations?: number;
|
|
159
|
+
nodes?: number;
|
|
160
|
+
edges?: number;
|
|
161
|
+
};
|
|
162
|
+
summary: {
|
|
163
|
+
errors: number;
|
|
164
|
+
warnings: number;
|
|
165
|
+
info: number;
|
|
166
|
+
states: number;
|
|
167
|
+
events: number;
|
|
168
|
+
transitions: number;
|
|
169
|
+
terminalStates: number;
|
|
170
|
+
reachableStates: number;
|
|
171
|
+
documentedStates: number;
|
|
172
|
+
};
|
|
173
|
+
findings: UmlFinding[];
|
|
174
|
+
roundTrip: UmlRoundTripReport | null;
|
|
175
|
+
/** Diagram display labels, when a diagram took part in the review. */
|
|
176
|
+
labels?: Record<string, string>;
|
|
177
|
+
/** Model parsed from the diagram, when a diagram was given (a machine feeds `model_verify`). */
|
|
178
|
+
model?: UmlFamilyModel;
|
|
179
|
+
/** Diagram rendered from the model, when only a model was given. */
|
|
180
|
+
primary?: string;
|
|
181
|
+
/** Paths of the `_`-prefixed metadata keys found in the supplied model, when it carried any. */
|
|
182
|
+
metadataKeys?: string[];
|
|
183
|
+
/** How much of the model the narrative documents; absent when there is no narrative. */
|
|
184
|
+
narrativeCoverage?: NarrativeCoverage;
|
|
185
|
+
/** Hashes of what was reviewed, in one place. */
|
|
186
|
+
hashes: {
|
|
187
|
+
hashSpec: HashSpec;
|
|
188
|
+
modelHash?: string;
|
|
189
|
+
parsedHash?: string;
|
|
190
|
+
};
|
|
191
|
+
/** Declarations the parser could not represent; a non-empty list fails the review. */
|
|
192
|
+
discardedConstructs?: DiscardedConstruct[];
|
|
193
|
+
/** Arrows whose endpoints came from a discarded construct. */
|
|
194
|
+
discardedEdges?: number;
|
|
195
|
+
warnings: string[];
|
|
196
|
+
nextSteps: string[];
|
|
197
|
+
}
|
|
198
|
+
/** Canonical guard text. Rendering wraps every composite node in parentheses, and the parser flattens same-operator chains, so render∘parse is the identity. */
|
|
199
|
+
export declare function guardText(node: GuardNode): string;
|
|
200
|
+
/**
|
|
201
|
+
* Refuse a view the requested notation cannot draw, before any work. The entry check
|
|
202
|
+
* every caller already used now asks the engine and the registry.
|
|
203
|
+
*/
|
|
204
|
+
export declare function assertUmlView(notation: UmlNotation, diagram: UmlDiagram): void;
|
|
205
|
+
/**
|
|
206
|
+
* Refuse, before any work, a request whose declared purpose the view cannot serve.
|
|
207
|
+
*
|
|
208
|
+
* Without an intent this changes nothing: the review still reports `UML019` when the
|
|
209
|
+
* fidelity check does not apply to the view it was given. With one, an impossible
|
|
210
|
+
* pairing is an error carrying a code, instead of a report about the wrong artifact —
|
|
211
|
+
* which is the failure this check exists to prevent.
|
|
212
|
+
*
|
|
213
|
+
* @param intent - the declared purpose, or `undefined` to leave the behaviour unchanged.
|
|
214
|
+
* @param action - which action is about to run.
|
|
215
|
+
* @param view - the requested `(notation, diagram)`, for the actions that have one.
|
|
216
|
+
*/
|
|
217
|
+
export declare function checkUmlIntent(intent: UmlIntent | undefined, action: UmlIntentAction, view?: {
|
|
218
|
+
notation: UmlNotation;
|
|
219
|
+
diagram: UmlDiagram;
|
|
220
|
+
}): void;
|
|
221
|
+
/**
|
|
222
|
+
* Render a LogicModelV1 as UML.
|
|
223
|
+
*
|
|
224
|
+
* Mermaid covers all three views; PlantUML covers state and sequence (see
|
|
225
|
+
* `assertUmlView` for why activity is refused).
|
|
226
|
+
*
|
|
227
|
+
* @param input - candidate LogicModelV1.
|
|
228
|
+
* @param notation - `mermaid` (default) or `plantuml`.
|
|
229
|
+
* @param diagram - `state` (default), `activity`, or `sequence`.
|
|
230
|
+
* @param maxSteps - cap on the sequence trace length.
|
|
231
|
+
* @param intent - what the diagram is for; a view that cannot serve it is refused first.
|
|
232
|
+
*/
|
|
233
|
+
export declare function renderUml(input: unknown, notation?: UmlNotation, diagram?: UmlDiagram, maxSteps?: number, intent?: UmlIntent): UmlRenderResult;
|
|
234
|
+
/** Parse a guard expression such as `(retry < 3 && armed == true)`. */
|
|
235
|
+
export declare function parseGuardText(text: string): GuardNode;
|
|
236
|
+
/** Parse a UML action clause such as `retry := retry + 1, armed := true`. */
|
|
237
|
+
export declare function parseUpdatesText(text: string, warnings: string[]): UpdateSpec[];
|
|
238
|
+
/**
|
|
239
|
+
* Findings a parse result carries on its own. A diagram from another family parses
|
|
240
|
+
* into something; without this finding that something is presented as a model of the
|
|
241
|
+
* file, which is a false guarantee of exactly the kind this plugin exists to prevent.
|
|
242
|
+
*/
|
|
243
|
+
export declare function parseFindings(parsed: UmlParseResult): UmlFinding[];
|
|
244
|
+
/** One accepted way of writing a state's meaning into a diagram label. */
|
|
245
|
+
export interface LabelForm {
|
|
246
|
+
form: string;
|
|
247
|
+
example: string;
|
|
248
|
+
note: string;
|
|
249
|
+
}
|
|
250
|
+
export interface LabelExplanation {
|
|
251
|
+
notation: UmlNotation;
|
|
252
|
+
/** The comment prefix a `dsh-model-everything:` directive uses in this notation. */
|
|
253
|
+
directivePrefix: string;
|
|
254
|
+
directiveLines: Array<{
|
|
255
|
+
example: string;
|
|
256
|
+
meaning: string;
|
|
257
|
+
}>;
|
|
258
|
+
/** Accepted label spellings, in the order `documentedMeaning` accepts them. */
|
|
259
|
+
acceptedLabelForms: LabelForm[];
|
|
260
|
+
/** What the renderer itself writes, so a hand-edited diagram can match it. */
|
|
261
|
+
renderedForm: string;
|
|
262
|
+
ignoredLines: Array<{
|
|
263
|
+
pattern: string;
|
|
264
|
+
behaviour: string;
|
|
265
|
+
}>;
|
|
266
|
+
rules: string[];
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* What the front end expects of labels and comments, so "why does my hand-drawn diagram
|
|
270
|
+
* report label drift or ignored lines?" has a printed answer instead of a guess.
|
|
271
|
+
* `tests/uml/run.mjs` feeds every claim here back through the parser, so this text cannot
|
|
272
|
+
* drift away from the behaviour it describes.
|
|
273
|
+
*/
|
|
274
|
+
export declare function explainLabels(notation?: UmlNotation): LabelExplanation;
|
|
275
|
+
/**
|
|
276
|
+
* Parse a Mermaid or PlantUML diagram back into a LogicModelV1.
|
|
277
|
+
*
|
|
278
|
+
* State and activity diagrams carry the whole machine, so they parse into a
|
|
279
|
+
* complete model. Sequence diagrams do not: a trace shows the paths that were
|
|
280
|
+
* walked, not the branches that were not, so parsing one would silently prune
|
|
281
|
+
* the machine. That case is refused rather than approximated.
|
|
282
|
+
*
|
|
283
|
+
* @param text - diagram source.
|
|
284
|
+
* @param notation - `auto` (default) detects Mermaid vs PlantUML from the text.
|
|
285
|
+
*/
|
|
286
|
+
export declare function parseUml(text: string, notation?: UmlNotation | 'auto'): UmlParseResult;
|
|
287
|
+
/** Compare two machines by structure — the fidelity measure behind the round-trip check. */
|
|
288
|
+
export declare function diffModels(left: LogicModelV1, right: LogicModelV1): string[];
|
|
289
|
+
export interface UmlReviewOptions {
|
|
290
|
+
/** LogicModelV1 to review. Provide it, `diagram`, or both. */
|
|
291
|
+
model?: unknown;
|
|
292
|
+
/** Diagram text: reviewed on its own, or compared against `model` when both are given. */
|
|
293
|
+
diagram?: string;
|
|
294
|
+
notation?: UmlNotation | 'auto';
|
|
295
|
+
diagramKind?: UmlDiagram;
|
|
296
|
+
/** Render-and-reparse fidelity check (default true; only meaningful with a model). */
|
|
297
|
+
roundTrip?: boolean;
|
|
298
|
+
/** Cap on the sequence trace used for the fidelity check. */
|
|
299
|
+
maxSteps?: number;
|
|
300
|
+
/** What the review is for; a view that cannot serve it is refused before any work. */
|
|
301
|
+
intent?: UmlIntent;
|
|
302
|
+
}
|
|
303
|
+
export declare function reviewUml(options: UmlReviewOptions): UmlReviewReport;
|