@cardenelabs/dragon 0.7.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 cardene777
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,173 @@
1
+ # @cardenelabs/dragon
2
+
3
+ Dragon は [@cardenelabs/cdl](https://www.npmjs.com/package/@cardenelabs/cdl) engine の上に乗る、 Mermaid 感覚の Text DSL。
4
+ 箇条書きで書ける宣言的 syntax から animated SVG diagram を生成する。
5
+
6
+ ## Why Dragon
7
+
8
+ Mermaid は静的、 cdl 直書きは TypeScript builder が必要。
9
+ Dragon は両者の中間 ... Mermaid に似た短文 syntax で書きつつ、 cdl の animation engine 上で動く。
10
+
11
+ - Mermaid 風 syntax (1 行 = 1 step、 `A -> B` 矢印、 box-drawing 不要)
12
+ - Mermaid にない animation (state tween / phase highlight / badge)
13
+ - 出力は cdl の `CdlDiagram`、 そのまま `CdlDiagramView` 等に渡せる
14
+ - engine 部 (layout / render / animation) は cdl に委譲、 dragon は parser + compiler に専念
15
+
16
+ ## Quickstart
17
+
18
+ ```bash
19
+ npm install @cardenelabs/dragon @cardenelabs/cdl
20
+ ```
21
+
22
+ ```ts
23
+ import { textDslToDiagram } from "@cardenelabs/dragon";
24
+ import { CdlDiagramView } from "@cardenelabs/cdl/react";
25
+
26
+ const diagram = textDslToDiagram(`
27
+ title: "送金フロー"
28
+ type: sequence
29
+
30
+ actors:
31
+ - Alice
32
+ - Vault: storage
33
+ - Bob
34
+
35
+ flow:
36
+ - Alice -> Vault: "deposit"
37
+ - Vault -> Bob: "send" (success)
38
+ `);
39
+
40
+ // React で render
41
+ <CdlDiagramView diagram={diagram} />
42
+ ```
43
+
44
+ ## API
45
+
46
+ **Text DSL (人向け YAML)**
47
+ - `textDslToDiagram(src: string): CdlDiagram` ... 一発変換 (v0.4 / v0.5 auto-detect、 recommended entry)
48
+ - `parseTextDslV05(src: string): V05ParseResult` ... v0.5 parser を直接呼出 (error 詳細取得)
49
+ - `compileToCdl(doc: DslDocument): CdlDiagram` ... AST → CdlDiagram
50
+
51
+ **JSON DSL (LLM 向け)**
52
+ - `jsonToDiagram(json: unknown): CdlDiagram` ... JSON DSL → CdlDiagram、 validation error は throw
53
+ - `validateDragonJson(json: unknown): { ok, data | errors }` ... compile なしで validation のみ
54
+ - `diagramJsonSchema` ... JSON Schema (Draft 7)、 LLM の tool schema にそのまま注入可能
55
+
56
+ **Deprecated (2026-12-31 削除予定)**
57
+ - `parseTextDsl(src: string): ParseResult` ... v0.4 parser、 `textDslToDiagram` に移行推奨
58
+
59
+ ## LLM 向け JSON DSL
60
+
61
+ LLM (Anthropic Claude / OpenAI GPT) が structured output で確実に diagram を生成できるよう、 YAML DSL と 1:1 対応する JSON 記法を提供する。
62
+
63
+ ### 最小 example
64
+
65
+ ```ts
66
+ import { jsonToDiagram } from "@cardenelabs/dragon";
67
+ import { CdlDiagramView } from "@cardenelabs/cdl/react";
68
+
69
+ const diagram = jsonToDiagram({
70
+ title: "ログインAPI",
71
+ type: "sequence",
72
+ actors: ["ユーザー", "API", "DB"],
73
+ flow: [
74
+ { from: "ユーザー", to: "API", label: "ログイン要求" },
75
+ { from: "API", to: "DB", label: "ユーザー検索" },
76
+ { from: "DB", to: "API", label: "結果", tone: "success" },
77
+ { from: "API", to: "ユーザー", label: "認証成功", tone: "success" },
78
+ ],
79
+ animation: [
80
+ { step: "call", duration: 1.4, focus: ["ユーザー", "API"] },
81
+ { step: "query", duration: 1.4, focus: ["API", "DB"] },
82
+ { step: "return", duration: 1.4, focus: ["DB", "API"] },
83
+ { step: "ok", duration: 1.4, focus: ["API", "ユーザー"] },
84
+ ],
85
+ });
86
+ // <CdlDiagramView diagram={diagram} />
87
+ ```
88
+
89
+ ### Anthropic Claude で LLM に書かせる example
90
+
91
+ ```ts
92
+ import Anthropic from "@anthropic-ai/sdk";
93
+ import { jsonToDiagram, diagramJsonSchema, validateDragonJson } from "@cardenelabs/dragon";
94
+
95
+ const client = new Anthropic();
96
+
97
+ async function generateDiagramFromLLM(userRequest: string, maxRetry = 3) {
98
+ const messages: Anthropic.MessageParam[] = [{ role: "user", content: userRequest }];
99
+ for (let attempt = 0; attempt < maxRetry; attempt++) {
100
+ const res = await client.messages.create({
101
+ model: "claude-sonnet-5",
102
+ max_tokens: 4096,
103
+ tools: [{
104
+ name: "create_diagram",
105
+ description: "Create an animated diagram from user's request using Dragon DSL.",
106
+ input_schema: diagramJsonSchema,
107
+ }],
108
+ tool_choice: { type: "tool", name: "create_diagram" },
109
+ messages,
110
+ });
111
+ const toolUse = res.content.find((c) => c.type === "tool_use");
112
+ if (!toolUse || toolUse.type !== "tool_use") throw new Error("no tool_use in LLM response");
113
+ const validation = validateDragonJson(toolUse.input);
114
+ if (validation.ok) {
115
+ return jsonToDiagram(validation.data);
116
+ }
117
+ // retry loop = error path を prompt に注入して LLM に修正させる
118
+ const errorSummary = validation.errors.map((e) => ` ${e.path}: ${e.message}`).join("\n");
119
+ messages.push({ role: "assistant", content: res.content });
120
+ messages.push({
121
+ role: "user",
122
+ content: `The diagram JSON has validation errors:\n${errorSummary}\nPlease fix and retry.`,
123
+ });
124
+ }
125
+ throw new Error(`LLM failed to generate valid diagram after ${maxRetry} attempts`);
126
+ }
127
+
128
+ // 使用例
129
+ const diagram = await generateDiagramFromLLM(
130
+ "ユーザーが API 経由で DB に検索をかけて結果を受け取るシーケンス図を作って"
131
+ );
132
+ ```
133
+
134
+ ### OpenAI GPT で structured output に使う場合
135
+
136
+ ```ts
137
+ import OpenAI from "openai";
138
+ import { jsonToDiagram, diagramJsonSchema } from "@cardenelabs/dragon";
139
+
140
+ const client = new OpenAI();
141
+ const res = await client.chat.completions.create({
142
+ model: "gpt-4o-2024-08-06",
143
+ messages: [{ role: "user", content: "..." }],
144
+ response_format: {
145
+ type: "json_schema",
146
+ json_schema: { name: "diagram", strict: true, schema: diagramJsonSchema },
147
+ },
148
+ });
149
+ const json = JSON.parse(res.choices[0].message.content!);
150
+ const diagram = jsonToDiagram(json);
151
+ ```
152
+
153
+ ### JSON Schema の場所
154
+
155
+ - SSOT = `packages/dragon/src/schemas/diagram.json`
156
+ - npm 経由取得 = `@cardenelabs/dragon/schemas/diagram.json` (package.json exports)
157
+ - TypeScript import = `import { diagramJsonSchema } from "@cardenelabs/dragon"`
158
+
159
+ ### YAML と JSON の 1:1 対応
160
+
161
+ 同じ図を両方の記法で書ける。 人 → YAML、 LLM → JSON が推奨だが、 混在可能。
162
+
163
+ | YAML | JSON |
164
+ |---|---|
165
+ | `title: "..."` | `{title: "..."}` |
166
+ | `actors: [A, B: kind]` | `{actors: [{name: "A"}, {name: "B", kind: "storage"}]}` |
167
+ | `- A -> B: "label"` | `{from: "A", to: "B", label: "label"}` |
168
+ | `step: "..." 1.4s` | `{step: "...", duration: 1.4}` |
169
+ | `focus: [A, B]` | `{focus: ["A", "B"]}` |
170
+
171
+ ## License
172
+
173
+ MIT