@mcuste/pi-diagram 0.0.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.md +240 -0
- package/dist/artifacts.d.ts +59 -0
- package/dist/artifacts.d.ts.map +1 -0
- package/dist/artifacts.js +274 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/cache.d.ts +43 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +0 -0
- package/dist/cache.js.map +1 -0
- package/dist/d2/diagnostics.d.ts +25 -0
- package/dist/d2/diagnostics.d.ts.map +1 -0
- package/dist/d2/diagnostics.js +77 -0
- package/dist/d2/diagnostics.js.map +1 -0
- package/dist/d2/fonts.d.ts +23 -0
- package/dist/d2/fonts.d.ts.map +1 -0
- package/dist/d2/fonts.js +255 -0
- package/dist/d2/fonts.js.map +1 -0
- package/dist/d2/preflight.d.ts +20 -0
- package/dist/d2/preflight.d.ts.map +1 -0
- package/dist/d2/preflight.js +217 -0
- package/dist/d2/preflight.js.map +1 -0
- package/dist/d2/profiles.d.ts +34 -0
- package/dist/d2/profiles.d.ts.map +1 -0
- package/dist/d2/profiles.js +118 -0
- package/dist/d2/profiles.js.map +1 -0
- package/dist/d2/runner.d.ts +95 -0
- package/dist/d2/runner.d.ts.map +1 -0
- package/dist/d2/runner.js +350 -0
- package/dist/d2/runner.js.map +1 -0
- package/dist/display.d.ts +48 -0
- package/dist/display.d.ts.map +1 -0
- package/dist/display.js +120 -0
- package/dist/display.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/normalize.d.ts +23 -0
- package/dist/normalize.d.ts.map +1 -0
- package/dist/normalize.js +83 -0
- package/dist/normalize.js.map +1 -0
- package/dist/process.d.ts +38 -0
- package/dist/process.d.ts.map +1 -0
- package/dist/process.js +87 -0
- package/dist/process.js.map +1 -0
- package/dist/raster.d.ts +40 -0
- package/dist/raster.d.ts.map +1 -0
- package/dist/raster.js +193 -0
- package/dist/raster.js.map +1 -0
- package/dist/render.d.ts +55 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +229 -0
- package/dist/render.js.map +1 -0
- package/dist/tools.d.ts +58 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +284 -0
- package/dist/tools.js.map +1 -0
- package/package.json +101 -0
- package/src/artifacts.ts +418 -0
- package/src/cache.ts +0 -0
- package/src/d2/diagnostics.ts +114 -0
- package/src/d2/fonts.ts +289 -0
- package/src/d2/preflight.ts +270 -0
- package/src/d2/profiles.ts +157 -0
- package/src/d2/runner.ts +513 -0
- package/src/display.ts +201 -0
- package/src/index.ts +5 -0
- package/src/normalize.ts +119 -0
- package/src/process.ts +134 -0
- package/src/raster.ts +258 -0
- package/src/render.ts +338 -0
- package/src/tools.ts +455 -0
package/dist/render.js
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { parseArtifactNames, parseArtifactTarget, writeArtifacts, } from "./artifacts.js";
|
|
2
|
+
import { DiagramSourceError } from "./d2/diagnostics.js";
|
|
3
|
+
import { parseSafeSource } from "./d2/preflight.js";
|
|
4
|
+
import { parseProfile } from "./d2/profiles.js";
|
|
5
|
+
import { TextRenderUnavailableError, } from "./d2/runner.js";
|
|
6
|
+
import { normalizeSource, parseTitle } from "./normalize.js";
|
|
7
|
+
import { ImageRenderUnavailableError, ResvgRasterizer, } from "./raster.js";
|
|
8
|
+
/** Bounds for one transcript diagram. */
|
|
9
|
+
const MAX_LINES = 300;
|
|
10
|
+
const MAX_COLUMNS = 400;
|
|
11
|
+
const MAX_BYTES = 32 * 1024;
|
|
12
|
+
/**
|
|
13
|
+
* `image` and `auto` choose the text that goes with the image. Whether a terminal can show one is
|
|
14
|
+
* only decided when the result is displayed, so both are always prepared.
|
|
15
|
+
*/
|
|
16
|
+
export function parseRepresentation(requested) {
|
|
17
|
+
switch (requested) {
|
|
18
|
+
case undefined:
|
|
19
|
+
case "auto":
|
|
20
|
+
case "image":
|
|
21
|
+
case "unicode":
|
|
22
|
+
return "unicode";
|
|
23
|
+
case "ascii":
|
|
24
|
+
return "ascii";
|
|
25
|
+
case "source":
|
|
26
|
+
return "source";
|
|
27
|
+
default:
|
|
28
|
+
throw new DiagramSourceError("Unsupported render mode.", [
|
|
29
|
+
{
|
|
30
|
+
code: "D2_SOURCE",
|
|
31
|
+
message: `${JSON.stringify(requested)} is not a render mode.`,
|
|
32
|
+
hint: "Use auto, image, unicode, ascii, or source.",
|
|
33
|
+
},
|
|
34
|
+
]);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** Asking for a text representation suppresses the image, rather than producing both. */
|
|
38
|
+
function wantsImage(request) {
|
|
39
|
+
if (request.images !== true) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return request.render === undefined || request.render === "auto" || request.render === "image";
|
|
43
|
+
}
|
|
44
|
+
export async function renderDiagram(request, renderer, rasterizer = new ResvgRasterizer()) {
|
|
45
|
+
const normalized = normalizeSource(request.source);
|
|
46
|
+
const source = parseSafeSource(normalized.text);
|
|
47
|
+
const representation = parseRepresentation(request.render);
|
|
48
|
+
const profile = parseProfile(request.profile);
|
|
49
|
+
const title = parseTitle(request.title);
|
|
50
|
+
// Everything the request asks for is parsed before D2 starts, so a bad save path costs nothing.
|
|
51
|
+
const wantsFiles = request.save !== undefined || request.formats !== undefined;
|
|
52
|
+
const names = wantsFiles
|
|
53
|
+
? parseArtifactNames({ formats: request.formats, save: request.save }, { title, hash: normalized.hash })
|
|
54
|
+
: undefined;
|
|
55
|
+
const target = names === undefined ? undefined : await parseArtifactTarget(request.cwd, names);
|
|
56
|
+
const notes = [];
|
|
57
|
+
const showsImage = wantsImage(request);
|
|
58
|
+
const savesPng = names?.formats.includes("png") === true;
|
|
59
|
+
const wantsText = representation !== "source" || names?.formats.includes("txt") === true;
|
|
60
|
+
let mode = representation === "ascii" ? "standard" : "extended";
|
|
61
|
+
let drawn = wantsText ? await tryRender(renderer, source, mode, request.signal) : undefined;
|
|
62
|
+
if (drawn instanceof TextRenderUnavailableError && mode === "extended") {
|
|
63
|
+
// Exactly one fallback attempt, so a beta renderer cannot be retried indefinitely.
|
|
64
|
+
const retry = await tryRender(renderer, source, "standard", request.signal);
|
|
65
|
+
if (!(retry instanceof TextRenderUnavailableError)) {
|
|
66
|
+
notes.push("Unicode output failed, so this diagram is drawn in plain ASCII.");
|
|
67
|
+
mode = "standard";
|
|
68
|
+
drawn = retry;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const textFailure = drawn instanceof TextRenderUnavailableError ? drawn : undefined;
|
|
72
|
+
const text = drawn instanceof TextRenderUnavailableError ? undefined : drawn?.text;
|
|
73
|
+
const svg = names?.formats.includes("svg") === true || showsImage || savesPng
|
|
74
|
+
? await renderer.renderSvg({ source, profile, signal: request.signal })
|
|
75
|
+
: undefined;
|
|
76
|
+
let raster;
|
|
77
|
+
if (svg !== undefined && (showsImage || savesPng)) {
|
|
78
|
+
raster = await tryRasterize(rasterizer, svg.svg, request.signal, notes);
|
|
79
|
+
}
|
|
80
|
+
let saved = [];
|
|
81
|
+
if (target !== undefined && names !== undefined) {
|
|
82
|
+
// Every text artifact ends with a newline, the way any other checked-in text file does.
|
|
83
|
+
const contents = new Map([
|
|
84
|
+
["source", await sourceToSave(renderer, source, request.signal)],
|
|
85
|
+
]);
|
|
86
|
+
if (svg !== undefined) {
|
|
87
|
+
contents.set("svg", `${svg.svg}\n`);
|
|
88
|
+
}
|
|
89
|
+
if (raster !== undefined) {
|
|
90
|
+
contents.set("png", raster.png);
|
|
91
|
+
}
|
|
92
|
+
else if (savesPng) {
|
|
93
|
+
notes.push("No .png was written, because the diagram could not be drawn as an image.");
|
|
94
|
+
}
|
|
95
|
+
if (text !== undefined) {
|
|
96
|
+
contents.set("txt", `${text}\n`);
|
|
97
|
+
}
|
|
98
|
+
else if (names.formats.includes("txt")) {
|
|
99
|
+
notes.push("No .txt was written, because D2 could not draw this diagram as text.");
|
|
100
|
+
}
|
|
101
|
+
saved = await writeArtifacts(target, contents);
|
|
102
|
+
}
|
|
103
|
+
const image = raster === undefined || !showsImage
|
|
104
|
+
? undefined
|
|
105
|
+
: await keepImage(raster, title, normalized.hash, notes);
|
|
106
|
+
// Work that came out fine is not discarded because the text renderer choked.
|
|
107
|
+
if (textFailure !== undefined && representation !== "source") {
|
|
108
|
+
if (saved.length === 0 && image === undefined) {
|
|
109
|
+
throw explain(textFailure);
|
|
110
|
+
}
|
|
111
|
+
notes.push("The diagram is shown as source, because D2 could not draw it as text.");
|
|
112
|
+
return {
|
|
113
|
+
title,
|
|
114
|
+
profile: profile.name,
|
|
115
|
+
sourceHash: normalized.hash,
|
|
116
|
+
...measure(source, MAX_COLUMNS),
|
|
117
|
+
renderedAs: "source",
|
|
118
|
+
text: source,
|
|
119
|
+
source,
|
|
120
|
+
diagnostics: textFailure.diagnostics,
|
|
121
|
+
image,
|
|
122
|
+
d2Version: svg?.version,
|
|
123
|
+
saved,
|
|
124
|
+
notes,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
// Text may have been drawn only to write a .txt sidecar, which must not override the
|
|
128
|
+
// representation the caller asked for.
|
|
129
|
+
const showSource = representation === "source" || text === undefined;
|
|
130
|
+
return {
|
|
131
|
+
title,
|
|
132
|
+
profile: profile.name,
|
|
133
|
+
sourceHash: normalized.hash,
|
|
134
|
+
...measure(showSource ? source : text, MAX_COLUMNS),
|
|
135
|
+
renderedAs: showSource ? "source" : mode === "standard" ? "ascii" : "unicode",
|
|
136
|
+
text: showSource ? source : text,
|
|
137
|
+
source,
|
|
138
|
+
diagnostics: [],
|
|
139
|
+
image,
|
|
140
|
+
d2Version: drawn instanceof TextRenderUnavailableError ? svg?.version : (drawn?.version ?? svg?.version),
|
|
141
|
+
saved,
|
|
142
|
+
notes,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/** A checked-in `.d2` is read and edited by people later, so it is saved formatted. */
|
|
146
|
+
async function sourceToSave(renderer, source, signal) {
|
|
147
|
+
try {
|
|
148
|
+
const formatted = await renderer.formatSource({ source, signal });
|
|
149
|
+
// Parsed again, because nothing reaches the workspace without passing the safe subset.
|
|
150
|
+
return `${parseSafeSource(normalizeSource(formatted).text)}\n`;
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// Formatting is cosmetic, so what the model wrote is saved as it is.
|
|
154
|
+
return `${source}\n`;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/** An image that cannot be drawn is a display fallback, not a failure the model should correct. */
|
|
158
|
+
async function tryRasterize(rasterizer, svg, signal, notes) {
|
|
159
|
+
try {
|
|
160
|
+
const raster = await rasterizer.rasterize({ svg, signal });
|
|
161
|
+
if (raster.systemFonts) {
|
|
162
|
+
notes.push("Some labels use characters the diagram's own font does not carry, so the image was " +
|
|
163
|
+
"drawn with the fonts installed on this machine.");
|
|
164
|
+
}
|
|
165
|
+
return raster;
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
if (!(error instanceof ImageRenderUnavailableError)) {
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
notes.push(`${error.message} The diagram is shown as text instead.`);
|
|
172
|
+
return undefined;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/** The temp store keeps the bytes out of the model's context and out of the repository. */
|
|
176
|
+
async function keepImage(raster, title, hash, notes) {
|
|
177
|
+
try {
|
|
178
|
+
const names = parseArtifactNames({ formats: ["png"] }, { title, hash });
|
|
179
|
+
const target = await parseArtifactTarget(undefined, names);
|
|
180
|
+
const [written] = await writeArtifacts(target, new Map([["png", raster.png]]));
|
|
181
|
+
if (written === undefined) {
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
return { path: written.path, widthPx: raster.widthPx, heightPx: raster.heightPx };
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
notes.push(`The image could not be stored: ${error.message}`);
|
|
188
|
+
return undefined;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Returns a text-renderer failure as a value so the caller can decide whether to retry.
|
|
193
|
+
* Everything else, including source errors and cancellation, still throws.
|
|
194
|
+
*/
|
|
195
|
+
async function tryRender(renderer, source, asciiMode, signal) {
|
|
196
|
+
try {
|
|
197
|
+
return await renderer.renderText({ source, asciiMode, signal });
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
if (error instanceof TextRenderUnavailableError) {
|
|
201
|
+
return error;
|
|
202
|
+
}
|
|
203
|
+
throw error;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function explain(failure) {
|
|
207
|
+
return new TextRenderUnavailableError(`${failure.message} D2's text renderer is beta and cannot draw every diagram. ` +
|
|
208
|
+
'Try a simpler diagram, or ask for `render: "source"` to see the D2 source instead.', failure.diagnostics);
|
|
209
|
+
}
|
|
210
|
+
/** Throws if the drawing is too big to belong in a transcript. */
|
|
211
|
+
function measure(text, maxColumns) {
|
|
212
|
+
const lines = text.split("\n");
|
|
213
|
+
let widthCells = 0;
|
|
214
|
+
for (const line of lines) {
|
|
215
|
+
widthCells = Math.max(widthCells, Array.from(line).length);
|
|
216
|
+
}
|
|
217
|
+
const bytes = Buffer.byteLength(text, "utf8");
|
|
218
|
+
if (lines.length > MAX_LINES || widthCells > maxColumns || bytes > MAX_BYTES) {
|
|
219
|
+
throw new DiagramSourceError("The rendered diagram is too big for the transcript.", [
|
|
220
|
+
{
|
|
221
|
+
code: "D2_TOO_LARGE",
|
|
222
|
+
message: `It is ${lines.length} lines by ${widthCells} columns (${bytes} bytes); the limit is ${MAX_LINES} by ${maxColumns} (${MAX_BYTES} bytes).`,
|
|
223
|
+
hint: "Show fewer nodes, shorten labels, or split it into several diagrams.",
|
|
224
|
+
},
|
|
225
|
+
]);
|
|
226
|
+
}
|
|
227
|
+
return { lineCount: lines.length, widthCells };
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
|
package/dist/tools.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { type Static, type TSchema } from "typebox";
|
|
2
|
+
import { type D2Renderer } from "./d2/runner.js";
|
|
3
|
+
import { type Component, type DisplayContext, type DisplayTheme } from "./display.js";
|
|
4
|
+
import { type SvgRasterizer } from "./raster.js";
|
|
5
|
+
interface TextContent {
|
|
6
|
+
readonly type: "text";
|
|
7
|
+
readonly text: string;
|
|
8
|
+
}
|
|
9
|
+
interface ToolResult<TDetails> {
|
|
10
|
+
readonly content: readonly TextContent[];
|
|
11
|
+
readonly details: TDetails;
|
|
12
|
+
}
|
|
13
|
+
interface ToolContext {
|
|
14
|
+
readonly cwd: string;
|
|
15
|
+
/** Only a terminal UI can display an image; print and RPC modes never can. */
|
|
16
|
+
readonly mode?: "tui" | "rpc" | "json" | "print";
|
|
17
|
+
readonly ui?: {
|
|
18
|
+
confirm(title: string, message: string): Promise<boolean>;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
type ToolTier = "read" | "write" | "exec";
|
|
22
|
+
type ToolApprovalDecision = ToolTier | {
|
|
23
|
+
readonly tier: ToolTier;
|
|
24
|
+
readonly reason?: string;
|
|
25
|
+
readonly policy?: "allow" | "deny" | "prompt";
|
|
26
|
+
};
|
|
27
|
+
interface ToolDefinition<TParameters extends TSchema, TDetails> {
|
|
28
|
+
readonly name: string;
|
|
29
|
+
readonly label: string;
|
|
30
|
+
readonly description: string;
|
|
31
|
+
readonly parameters: TParameters;
|
|
32
|
+
readonly approval: ToolApprovalDecision | ((args: unknown) => ToolApprovalDecision);
|
|
33
|
+
readonly loadMode: "essential" | "discoverable";
|
|
34
|
+
readonly concurrency?: "shared" | "exclusive" | ((args: Partial<Static<TParameters>>) => "shared" | "exclusive");
|
|
35
|
+
readonly executionMode?: "sequential" | "parallel";
|
|
36
|
+
readonly formatApprovalDetails?: (args: unknown) => string | readonly string[] | undefined;
|
|
37
|
+
/** Arguments can still be arriving, so every field is read defensively. */
|
|
38
|
+
readonly renderCall?: (args: Partial<Static<TParameters>>, theme: DisplayTheme) => Component;
|
|
39
|
+
/** Throwing here is the host's signal to render the result its own way. */
|
|
40
|
+
readonly renderResult?: (result: {
|
|
41
|
+
readonly content: readonly TextContent[];
|
|
42
|
+
readonly details: TDetails;
|
|
43
|
+
}, options: {
|
|
44
|
+
readonly expanded: boolean;
|
|
45
|
+
readonly isPartial: boolean;
|
|
46
|
+
}, theme: DisplayTheme, context: DisplayContext) => Component;
|
|
47
|
+
execute(toolCallId: string, parameters: Static<TParameters>, signal: AbortSignal | undefined, onUpdate: unknown, context: ToolContext): Promise<ToolResult<TDetails>>;
|
|
48
|
+
}
|
|
49
|
+
export interface DiagramExtensionApi {
|
|
50
|
+
registerTool<TParameters extends TSchema, TDetails>(definition: ToolDefinition<TParameters, TDetails>): void;
|
|
51
|
+
}
|
|
52
|
+
export interface DiagramExtensionDependencies {
|
|
53
|
+
readonly renderer?: D2Renderer;
|
|
54
|
+
readonly rasterizer?: SvgRasterizer;
|
|
55
|
+
}
|
|
56
|
+
export declare function registerDiagramTools(pi: DiagramExtensionApi, dependencies?: DiagramExtensionDependencies): void;
|
|
57
|
+
export {};
|
|
58
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
|
package/dist/tools.js
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
import { parseArtifactNames, workspacePaths } from "./artifacts.js";
|
|
3
|
+
import { formatDiagnostic } from "./d2/diagnostics.js";
|
|
4
|
+
import { DEFAULT_PROFILE } from "./d2/profiles.js";
|
|
5
|
+
import { D2Cli } from "./d2/runner.js";
|
|
6
|
+
import { displayLoaded, imagesSupported, primeDisplay, renderDiagramCall, renderDiagramResult, } from "./display.js";
|
|
7
|
+
import { ResvgRasterizer } from "./raster.js";
|
|
8
|
+
import { renderDiagram } from "./render.js";
|
|
9
|
+
/**
|
|
10
|
+
* Capped well below what D2 can parse: a diagram that reads clearly in a terminal is a few dozen
|
|
11
|
+
* lines, and a larger one usually means the model is dumping a whole codebase.
|
|
12
|
+
*/
|
|
13
|
+
const MAX_SOURCE_LENGTH = 20_000;
|
|
14
|
+
const MAX_TITLE_LENGTH = 120;
|
|
15
|
+
const MAX_PATH_LENGTH = 255;
|
|
16
|
+
const DiagramSource = Type.String({
|
|
17
|
+
minLength: 1,
|
|
18
|
+
maxLength: MAX_SOURCE_LENGTH,
|
|
19
|
+
description: "Diagram source in D2. Imports, local images, and remote icons are rejected.",
|
|
20
|
+
});
|
|
21
|
+
const DiagramTitle = Type.String({
|
|
22
|
+
minLength: 1,
|
|
23
|
+
maxLength: MAX_TITLE_LENGTH,
|
|
24
|
+
description: "Short label shown with the diagram and used to name saved artifacts.",
|
|
25
|
+
});
|
|
26
|
+
/** One literal per profile, because a mapped union loses the names from the static type. */
|
|
27
|
+
const DiagramProfile = Type.Union([
|
|
28
|
+
Type.Literal("explain"),
|
|
29
|
+
Type.Literal("architecture"),
|
|
30
|
+
Type.Literal("data"),
|
|
31
|
+
Type.Literal("docs"),
|
|
32
|
+
Type.Literal("tree"),
|
|
33
|
+
Type.Literal("c4"),
|
|
34
|
+
Type.Literal("dependency"),
|
|
35
|
+
], {
|
|
36
|
+
description: "What the diagram is for. The harness maps this to theme and spacing; the model does not choose them.",
|
|
37
|
+
});
|
|
38
|
+
const DiagramRender = Type.Union([
|
|
39
|
+
Type.Literal("auto"),
|
|
40
|
+
Type.Literal("image"),
|
|
41
|
+
Type.Literal("unicode"),
|
|
42
|
+
Type.Literal("ascii"),
|
|
43
|
+
Type.Literal("source"),
|
|
44
|
+
], {
|
|
45
|
+
description: "Preferred representation in the transcript. `auto` shows an image where the terminal supports it and Unicode text otherwise.",
|
|
46
|
+
});
|
|
47
|
+
const DiagramFormat = Type.Union([
|
|
48
|
+
Type.Literal("source"),
|
|
49
|
+
Type.Literal("svg"),
|
|
50
|
+
Type.Literal("png"),
|
|
51
|
+
Type.Literal("txt"),
|
|
52
|
+
]);
|
|
53
|
+
const DiagramFormats = Type.Array(DiagramFormat, {
|
|
54
|
+
minItems: 1,
|
|
55
|
+
uniqueItems: true,
|
|
56
|
+
description: "Files to produce. They are written outside the repository and their paths are returned. Defaults to editable source and an SVG.",
|
|
57
|
+
});
|
|
58
|
+
const DiagramSave = Type.Object({
|
|
59
|
+
dir: Type.String({
|
|
60
|
+
minLength: 1,
|
|
61
|
+
maxLength: MAX_PATH_LENGTH,
|
|
62
|
+
description: "Directory inside the workspace to copy the files into. There is no default: name where diagrams belong in this repository.",
|
|
63
|
+
}),
|
|
64
|
+
basename: Type.Optional(Type.String({
|
|
65
|
+
minLength: 1,
|
|
66
|
+
maxLength: MAX_TITLE_LENGTH,
|
|
67
|
+
description: "Stable file name stem, without an extension. Defaults to the title.",
|
|
68
|
+
})),
|
|
69
|
+
}, {
|
|
70
|
+
additionalProperties: false,
|
|
71
|
+
description: "Copy the files into the repository. Use it only when the user asked to keep the diagram.",
|
|
72
|
+
});
|
|
73
|
+
const DiagramParameters = Type.Object({
|
|
74
|
+
source: DiagramSource,
|
|
75
|
+
title: Type.Optional(DiagramTitle),
|
|
76
|
+
profile: Type.Optional(DiagramProfile),
|
|
77
|
+
render: Type.Optional(DiagramRender),
|
|
78
|
+
formats: Type.Optional(DiagramFormats),
|
|
79
|
+
save: Type.Optional(DiagramSave),
|
|
80
|
+
}, { additionalProperties: false });
|
|
81
|
+
const DIAGRAM_DESCRIPTION = [
|
|
82
|
+
"Draw a diagram from D2 source and show it in the terminal. Use it when architecture,",
|
|
83
|
+
"relationships, sequence, data flow, state transitions, schemas, or process flow are easier to",
|
|
84
|
+
"see than to read, and keep the diagram to what answers the question.",
|
|
85
|
+
"",
|
|
86
|
+
"D2 in brief:",
|
|
87
|
+
" edges client -> gateway: request",
|
|
88
|
+
" containers core: Core Services { api; worker }, then core.api -> core.worker",
|
|
89
|
+
" sequence flow: { shape: sequence_diagram; user -> api: submit }",
|
|
90
|
+
" tables users: { shape: sql_table; id: int {constraint: primary_key}; email: varchar }",
|
|
91
|
+
"",
|
|
92
|
+
"Not allowed: `@` imports, `icon`, `link`, `shape: image`, and `|...|` block labels.",
|
|
93
|
+
"Do not set colours, themes, or fonts. This tool owns how diagrams look.",
|
|
94
|
+
"Aim for 5 to 15 nodes, or up to about 25 with `profile: dependency`. Split anything larger.",
|
|
95
|
+
"",
|
|
96
|
+
"`profile` says what the diagram is for, and sets the layout, theme, and spacing:",
|
|
97
|
+
" explain an answer in this conversation, drawn by hand. The default",
|
|
98
|
+
" architecture systems and components, with room between the parts",
|
|
99
|
+
" data schemas, tables, class relationships",
|
|
100
|
+
" docs a diagram that will be checked into the repository",
|
|
101
|
+
" tree a hierarchy: an org chart, a call tree, a file layout",
|
|
102
|
+
" c4 the C4 convention, with the palette its readers expect",
|
|
103
|
+
" dependency a graph with more nodes than usual, drawn dense",
|
|
104
|
+
"",
|
|
105
|
+
"Files: `formats` produces .d2, .svg, .png, or .txt outside the repository and returns the",
|
|
106
|
+
"paths. `save: { dir }` also copies them into the repository, so Markdown can reference the",
|
|
107
|
+
"SVG. Only pass `save` when the user asked to keep the diagram; explaining something needs",
|
|
108
|
+
"neither. A terminal that can show images shows one without being asked.",
|
|
109
|
+
].join("\n");
|
|
110
|
+
/** Only `save` reaches the repository. The temp store changes nothing worth approving. */
|
|
111
|
+
function approvalFor(args) {
|
|
112
|
+
return readSave(args) === undefined ? "read" : "write";
|
|
113
|
+
}
|
|
114
|
+
/** Names the repository files at stake, so approving is a decision about specific paths. */
|
|
115
|
+
function approvalDetails(args) {
|
|
116
|
+
const save = readSave(args);
|
|
117
|
+
if (save === undefined) {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
const read = (key) => typeof args === "object" && args !== null ? Reflect.get(args, key) : undefined;
|
|
121
|
+
try {
|
|
122
|
+
const title = read("title");
|
|
123
|
+
const names = parseArtifactNames({ formats: read("formats"), save }, { title: typeof title === "string" ? title : undefined, hash: "" });
|
|
124
|
+
return workspacePaths(names).map((path) => `Writes ${path}`);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// The call itself will refuse with the reason; the prompt only needs the intent.
|
|
128
|
+
return typeof save.dir === "string"
|
|
129
|
+
? [`Writes diagram artifacts into ${save.dir}`]
|
|
130
|
+
: ["Writes diagram artifacts into the repository"];
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function readSave(args) {
|
|
134
|
+
if (typeof args !== "object" || args === null) {
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
const save = Reflect.get(args, "save");
|
|
138
|
+
return typeof save === "object" && save !== null && !Array.isArray(save)
|
|
139
|
+
? save
|
|
140
|
+
: undefined;
|
|
141
|
+
}
|
|
142
|
+
/** The waiting row names the diagram and the policy, never the source. */
|
|
143
|
+
function callView(args) {
|
|
144
|
+
const title = typeof args.title === "string" ? args.title.trim() : "";
|
|
145
|
+
const source = typeof args.source === "string" ? args.source : "";
|
|
146
|
+
const lines = source.split("\n").filter((line) => line.trim().length > 0).length;
|
|
147
|
+
const directory = readSave(args)?.dir;
|
|
148
|
+
const saving = typeof directory === "string" ? `, saving into ${directory}` : "";
|
|
149
|
+
const profile = typeof args.profile === "string" ? args.profile : DEFAULT_PROFILE.name;
|
|
150
|
+
return {
|
|
151
|
+
subject: title === "" ? `${lines} line${lines === 1 ? "" : "s"}` : `"${title}"`,
|
|
152
|
+
note: `(${profile}${saving})`,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
/** How each representation is named to the reader. */
|
|
156
|
+
const DRAWN = {
|
|
157
|
+
image: "an image",
|
|
158
|
+
unicode: "box drawing",
|
|
159
|
+
ascii: "plain ASCII",
|
|
160
|
+
source: "D2 source",
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* What the model reads. The diagram is left out when this package draws the row, and the summary
|
|
164
|
+
* says so, because an empty-looking result invites the model to render again.
|
|
165
|
+
*/
|
|
166
|
+
function contentFor(rendering, drawnHere) {
|
|
167
|
+
const paths = rendering.saved.map((artifact) => artifact.path).join(", ");
|
|
168
|
+
const saved = rendering.saved.length === 0
|
|
169
|
+
? undefined
|
|
170
|
+
: rendering.saved[0]?.location === "workspace"
|
|
171
|
+
? `saved in the repository: ${paths}`
|
|
172
|
+
: `saved outside the repository: ${paths}`;
|
|
173
|
+
const blocks = drawnHere ? [summaryFor(rendering)] : [rendering.title, rendering.text];
|
|
174
|
+
return [...blocks, saved, ...rendering.notes.map((note) => `note: ${note}`)]
|
|
175
|
+
.filter((block) => Boolean(block))
|
|
176
|
+
.join("\n\n");
|
|
177
|
+
}
|
|
178
|
+
function summaryFor(rendering) {
|
|
179
|
+
const named = rendering.title === undefined ? "the diagram" : `"${rendering.title}"`;
|
|
180
|
+
const as = DRAWN[rendering.image === undefined ? rendering.renderedAs : "image"];
|
|
181
|
+
return `Drew ${named} as ${as}. It is on the user's screen, so it is not repeated here.`;
|
|
182
|
+
}
|
|
183
|
+
function outputsFor(rendering) {
|
|
184
|
+
if (rendering.saved.length === 0) {
|
|
185
|
+
return undefined;
|
|
186
|
+
}
|
|
187
|
+
const keys = {
|
|
188
|
+
source: "sourcePath",
|
|
189
|
+
svg: "svgPath",
|
|
190
|
+
png: "pngPath",
|
|
191
|
+
txt: "textPath",
|
|
192
|
+
};
|
|
193
|
+
return {
|
|
194
|
+
location: rendering.saved[0]?.location ?? "temp",
|
|
195
|
+
...Object.fromEntries(rendering.saved.map((artifact) => [keys[artifact.format], artifact.path])),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
function detailsFor(parameters, rendering) {
|
|
199
|
+
const outputs = outputsFor(rendering);
|
|
200
|
+
return {
|
|
201
|
+
language: "d2",
|
|
202
|
+
...(rendering.title === undefined ? {} : { title: rendering.title }),
|
|
203
|
+
profile: rendering.profile,
|
|
204
|
+
requested: parameters.render ?? "auto",
|
|
205
|
+
renderedAs: rendering.image === undefined ? rendering.renderedAs : "image",
|
|
206
|
+
...(rendering.image === undefined ? {} : { image: rendering.image }),
|
|
207
|
+
textPreview: rendering.text,
|
|
208
|
+
source: rendering.source,
|
|
209
|
+
...(rendering.diagnostics.length === 0 ? {} : { diagnostics: rendering.diagnostics }),
|
|
210
|
+
sourceHash: rendering.sourceHash,
|
|
211
|
+
lineCount: rendering.lineCount,
|
|
212
|
+
widthCells: rendering.widthCells,
|
|
213
|
+
...(rendering.d2Version === undefined ? {} : { d2Version: rendering.d2Version }),
|
|
214
|
+
...(outputs === undefined ? {} : { outputs }),
|
|
215
|
+
...(rendering.notes.length === 0 ? {} : { notes: rendering.notes }),
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/** Saved and temporary file paths, for the expanded view. */
|
|
219
|
+
function pathsFor(details) {
|
|
220
|
+
return Object.entries(details.outputs ?? {})
|
|
221
|
+
.filter(([key]) => key !== "location")
|
|
222
|
+
.map(([, path]) => path);
|
|
223
|
+
}
|
|
224
|
+
/** The expanded row: how it was drawn, where the files are, what went wrong, and the source. */
|
|
225
|
+
function expandedLines(details) {
|
|
226
|
+
const version = details.d2Version === undefined ? "" : `, D2 ${details.d2Version}`;
|
|
227
|
+
const lines = [
|
|
228
|
+
`Drawn as ${DRAWN[details.renderedAs]}, profile ${details.profile}${version}`,
|
|
229
|
+
...pathsFor(details),
|
|
230
|
+
...(details.diagnostics ?? []).map(formatDiagnostic),
|
|
231
|
+
];
|
|
232
|
+
// The collapsed row already shows the source when that is what was drawn.
|
|
233
|
+
return details.renderedAs === "source" ? lines : [...lines, "", details.source];
|
|
234
|
+
}
|
|
235
|
+
export function registerDiagramTools(pi, dependencies = {}) {
|
|
236
|
+
const renderer = dependencies.renderer ?? new D2Cli();
|
|
237
|
+
const rasterizer = dependencies.rasterizer ?? new ResvgRasterizer();
|
|
238
|
+
void primeDisplay();
|
|
239
|
+
pi.registerTool({
|
|
240
|
+
name: "diagram",
|
|
241
|
+
label: "Diagram",
|
|
242
|
+
description: DIAGRAM_DESCRIPTION,
|
|
243
|
+
parameters: DiagramParameters,
|
|
244
|
+
approval: approvalFor,
|
|
245
|
+
formatApprovalDetails: approvalDetails,
|
|
246
|
+
renderCall(args, theme) {
|
|
247
|
+
return renderDiagramCall(callView(args), theme);
|
|
248
|
+
},
|
|
249
|
+
loadMode: "discoverable",
|
|
250
|
+
concurrency: "shared",
|
|
251
|
+
executionMode: "parallel",
|
|
252
|
+
async execute(_toolCallId, parameters, signal, _onUpdate, context) {
|
|
253
|
+
// Anywhere else the host prints `content`, so the diagram has to travel in it.
|
|
254
|
+
const drawnHere = context.mode === "tui" && displayLoaded();
|
|
255
|
+
const rendering = await renderDiagram({
|
|
256
|
+
source: parameters.source,
|
|
257
|
+
title: parameters.title,
|
|
258
|
+
profile: parameters.profile,
|
|
259
|
+
render: parameters.render,
|
|
260
|
+
formats: parameters.formats,
|
|
261
|
+
save: parameters.save,
|
|
262
|
+
cwd: context.cwd,
|
|
263
|
+
// Drawing an image nothing can show would cost an SVG render for nothing.
|
|
264
|
+
images: drawnHere && imagesSupported() !== false,
|
|
265
|
+
signal,
|
|
266
|
+
}, renderer, rasterizer);
|
|
267
|
+
return {
|
|
268
|
+
content: [{ type: "text", text: contentFor(rendering, drawnHere) }],
|
|
269
|
+
details: detailsFor(parameters, rendering),
|
|
270
|
+
};
|
|
271
|
+
},
|
|
272
|
+
renderResult(result, options, theme, context) {
|
|
273
|
+
const details = result.details;
|
|
274
|
+
return renderDiagramResult({
|
|
275
|
+
image: details.image,
|
|
276
|
+
title: details.title,
|
|
277
|
+
text: details.textPreview,
|
|
278
|
+
notes: details.notes ?? [],
|
|
279
|
+
details: expandedLines(details),
|
|
280
|
+
}, theme, { showImages: context.showImages, expanded: options.expanded, state: context.state });
|
|
281
|
+
},
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
|