@kekonic/diagrams-cli 1.0.0-rc.5 → 1.0.0-rc.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @kekonic/diagrams-cli
2
2
 
3
- Command-line tools for KDiagram diagrams.
3
+ Command-line tools for Kekonic Diagrams.
4
4
 
5
5
  ## Install
6
6
 
@@ -10,7 +10,8 @@ pnpm kdiagrams --help
10
10
  ```
11
11
 
12
12
  Keep the CLI local to the project so developers and CI use the same version. For a one-off
13
- evaluation, run `pnpm dlx @kekonic/diagrams-cli --help`.
13
+ evaluation, run `pnpm dlx @kekonic/diagrams-cli --help` or `npx @kekonic/diagrams-cli --help`.
14
+ The package publishes one `kdiagrams` executable so npx and pnpm dlx can resolve it.
14
15
 
15
16
  ## Commands
16
17
 
@@ -27,8 +28,8 @@ kdiagrams check - --json # diagram source on stdin
27
28
  git ls-files "*.kdiagram" | kdiagrams check --files-from -
28
29
 
29
30
  # Dump AST or GraphModel as JSON
30
- kdiagrams ast diagram.kdiagrams --pretty
31
- kdiagrams graph diagram.kdiagrams --pretty
31
+ kdiagrams ast diagram.kdiagram --pretty
32
+ kdiagrams graph diagram.kdiagram --pretty
32
33
 
33
34
  # Discover the supported surface and inspect rendered quality
34
35
  kdiagrams capabilities --pretty
@@ -79,7 +80,7 @@ project-specific delivery policy.
79
80
  ## Portable exports and project config
80
81
 
81
82
  CLI SVG is a self-contained theme snapshot by default. Use `--live-theme` only when the SVG will be
82
- inlined into a host that provides KDiagram CSS variables. `--background theme`, `--embed-fonts`, and
83
+ inlined into a host that provides Kekonic Diagrams CSS variables. `--background theme`, `--embed-fonts`, and
83
84
  `--print-safe` make destination requirements explicit.
84
85
 
85
86
  The CLI discovers `kekonic-diagrams.config.json` upward from the current directory. It can define named
@@ -113,7 +114,7 @@ After stable releases begin, macOS users can install the same published CLI thro
113
114
  ```bash
114
115
  kdiagrams studio architecture.kdiagram
115
116
  kdiagrams studio diagrams/ --no-open
116
- kdiagrams studio architecture.kdiagrams --allow-write
117
+ kdiagrams studio architecture.kdiagram --allow-write
117
118
  ```
118
119
 
119
120
  Studio starts an offline browser authoring host with Monaco editing, live preview and diagnostics,
package/dist/cli.d.mts CHANGED
@@ -1 +1 @@
1
- export { };
1
+ export {}
package/dist/cli.mjs CHANGED
@@ -4,7 +4,7 @@ import { createRequire } from "node:module";
4
4
  import { createReadStream, existsSync, mkdirSync, readFileSync, statSync, watch, writeFileSync } from "node:fs";
5
5
  import { basename, dirname, extname, isAbsolute, join, parse, relative, resolve, sep } from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
- import { analyzeDiagramQuality, compileSource, getCapabilities, parseSource, registerTheme, renderPipeline } from "@kekonic/diagrams";
7
+ import { analyzeDiagramQuality, compileSource, getCapabilities, listCompileTargets, parseSource, registerTheme, renderPipeline } from "@kekonic/diagrams";
8
8
  import { KDiagramLanguageService } from "@kekonic/diagrams-language-service";
9
9
  import { globSync, isDynamicPattern } from "tinyglobby";
10
10
  import { spawn } from "node:child_process";
@@ -47,7 +47,9 @@ const VALUE_OPTIONS = /* @__PURE__ */ new Map([
47
47
  ["--profile", "profile"],
48
48
  ["--theme-file", "themeFile"],
49
49
  ["--background", "background"],
50
- ["--port", "port"]
50
+ ["--port", "port"],
51
+ ["--view", "view"],
52
+ ["--diagram-index", "diagramIndex"]
51
53
  ]);
52
54
  const BOOLEAN_OPTIONS = /* @__PURE__ */ new Map([
53
55
  ["--snapshot", "snapshot"],
@@ -92,17 +94,23 @@ const ALLOWED_OPTIONS = {
92
94
  "background",
93
95
  "embedFonts",
94
96
  "printSafe",
97
+ "view",
98
+ "diagramIndex",
95
99
  ...DISCOVERY,
96
100
  ...PRESENTATION
97
101
  ]),
98
102
  check: /* @__PURE__ */ new Set([
99
103
  "json",
104
+ "view",
105
+ "diagramIndex",
100
106
  ...DISCOVERY,
101
107
  ...PRESENTATION
102
108
  ]),
103
109
  analyze: /* @__PURE__ */ new Set([
104
110
  "json",
105
111
  "pretty",
112
+ "view",
113
+ "diagramIndex",
106
114
  ...DISCOVERY,
107
115
  ...PRESENTATION
108
116
  ]),
@@ -116,6 +124,8 @@ const ALLOWED_OPTIONS = {
116
124
  graph: /* @__PURE__ */ new Set([
117
125
  "pretty",
118
126
  "json",
127
+ "view",
128
+ "diagramIndex",
119
129
  ...DISCOVERY,
120
130
  ...PRESENTATION
121
131
  ]),
@@ -272,7 +282,7 @@ function validateOptions(command, options) {
272
282
  //#endregion
273
283
  //#region src/completions.ts
274
284
  const COMMANDS = "render check analyze capabilities format studio lsp ast graph doctor completions";
275
- const OPTIONS = "--help --version --color --quiet --verbose --debug --exclude --ignore-file --stdin-filename --files-from --output --out-dir --output-template --theme --theme-file --config --profile --live-theme --snapshot --background --embed-fonts --print-safe --json --pretty --check --write --open --no-open --allow-write --port --stdio";
285
+ const OPTIONS = "--help --version --color --quiet --verbose --debug --exclude --ignore-file --stdin-filename --files-from --output --out-dir --output-template --theme --theme-file --config --profile --live-theme --snapshot --background --embed-fonts --print-safe --json --pretty --check --write --open --no-open --allow-write --port --stdio --view --diagram-index";
276
286
  function shellCompletions(shell) {
277
287
  switch (shell) {
278
288
  case "bash": return `# Kekonic Diagrams completion\n_kdiagrams() {\n local cur="\${COMP_WORDS[COMP_CWORD]}"\n COMPREPLY=( $(compgen -W "${COMMANDS} ${OPTIONS}" -- "$cur") )\n}\ncomplete -F _kdiagrams kdiagrams\n`;
@@ -661,7 +671,8 @@ function finalizePortableSvg(svg, settings) {
661
671
  return output;
662
672
  }
663
673
  function embedInter(svg) {
664
- const css = `@font-face{font-family:"Inter";src:url(data:font/woff;base64,${readFileSync(require$1.resolve("@fontsource/inter/files/inter-latin-500-normal.woff")).toString("base64")}) format("woff");font-style:normal;font-weight:100 900;font-display:block;}`;
674
+ const fontPath = require$1.resolve("@fontsource/inter/files/inter-latin-500-normal.woff");
675
+ const css = `@font-face{font-family:"Inter";src:url(data:font/woff;base64,${readFileSync(fontPath).toString("base64")}) format("woff");font-style:normal;font-weight:100 900;font-display:block;}`;
665
676
  const styleIndex = svg.indexOf("<style>");
666
677
  if (styleIndex >= 0) return svg.slice(0, styleIndex + 7) + css + svg.slice(styleIndex + 7);
667
678
  return svg.replace(/(<svg\b[^>]*>)/, `$1\n<style>${css}</style>`);
@@ -688,6 +699,7 @@ async function startStudioServer(options) {
688
699
  });
689
700
  }
690
701
  let activeDocumentId = documents.keys().next().value;
702
+ const activeViews = /* @__PURE__ */ new Map();
691
703
  let presentation = {
692
704
  theme: "dark",
693
705
  options: { theme: "dark" }
@@ -697,6 +709,17 @@ async function startStudioServer(options) {
697
709
  const browserRoot = resolve(options.browserRoot ?? dirname(require.resolve("@kekonic/diagrams-studio/browser")));
698
710
  const clients = /* @__PURE__ */ new Set();
699
711
  const renders = /* @__PURE__ */ new Map();
712
+ const enrichDocument = (document) => {
713
+ const compileTargets = compileTargetsFor(document);
714
+ let activeView = activeViews.get(document.id);
715
+ if (compileTargets.length > 0 && (!activeView || !compileTargets.some((target) => target.viewName === activeView))) activeView = compileTargets.find((target) => target.viewName === "default")?.viewName ?? compileTargets.find((target) => target.viewName === "main")?.viewName ?? compileTargets[0]?.viewName;
716
+ if (activeView) activeViews.set(document.id, activeView);
717
+ return {
718
+ ...document,
719
+ compileTargets,
720
+ activeView
721
+ };
722
+ };
700
723
  const coordinator = createStudioPreviewCoordinator((source, renderOptions) => renderPipeline(source, {
701
724
  ...renderOptions,
702
725
  snapshotTheme: true,
@@ -707,7 +730,11 @@ async function startStudioServer(options) {
707
730
  for (const client of clients) client.write(line);
708
731
  };
709
732
  const renderDocument = async (document) => {
710
- const result = await coordinator.render(document.id, document.revision, document.source, presentation.options);
733
+ const enriched = enrichDocument(document);
734
+ const result = await coordinator.render(document.id, document.revision, document.source, {
735
+ ...presentation.options,
736
+ view: enriched.activeView
737
+ });
711
738
  if (result) {
712
739
  renders.set(document.id, result);
713
740
  broadcast({
@@ -734,7 +761,7 @@ async function startStudioServer(options) {
734
761
  version: 1,
735
762
  type: "ready",
736
763
  sessionId,
737
- documents: [...documents.values()],
764
+ documents: [...documents.values()].map(enrichDocument),
738
765
  activeDocumentId,
739
766
  capabilities: {
740
767
  write: options.allowWrite === true,
@@ -757,7 +784,17 @@ async function startStudioServer(options) {
757
784
  version: 1,
758
785
  type: "document",
759
786
  reason: "open",
760
- ...document
787
+ ...enrichDocument(document)
788
+ });
789
+ renderDocument(document);
790
+ break;
791
+ case "selectView":
792
+ activeViews.set(message.documentId, message.view);
793
+ broadcast({
794
+ version: 1,
795
+ type: "document",
796
+ reason: "open",
797
+ ...enrichDocument(document)
761
798
  });
762
799
  renderDocument(document);
763
800
  break;
@@ -808,7 +845,6 @@ async function startStudioServer(options) {
808
845
  presentation
809
846
  });
810
847
  renderDocument(documents.get(activeDocumentId));
811
- break;
812
848
  }
813
849
  return respond(response, 204, "");
814
850
  }
@@ -842,7 +878,7 @@ async function startStudioServer(options) {
842
878
  version: 1,
843
879
  type: "document",
844
880
  reason: "external",
845
- ...document
881
+ ...enrichDocument(document)
846
882
  });
847
883
  renderDocument(document);
848
884
  }));
@@ -962,12 +998,34 @@ function contentType(path) {
962
998
  default: return "application/octet-stream";
963
999
  }
964
1000
  }
1001
+ function compileTargetsFor(document) {
1002
+ const { ast } = parseSource(document.source);
1003
+ return listCompileTargets(ast).filter((target) => target.kind === "model-view" && target.viewName).map((target) => ({
1004
+ kind: "model-view",
1005
+ viewName: target.viewName,
1006
+ title: target.title ?? target.viewName
1007
+ }));
1008
+ }
965
1009
  //#endregion
966
1010
  //#region src/cli.ts
967
1011
  const argv = process.argv.slice(2);
968
1012
  const languageService = new KDiagramLanguageService();
969
1013
  let activeCommand;
970
1014
  installPipeErrorHandlers();
1015
+ function compileTargetFromCommand(command) {
1016
+ const diagramIndex = command.options.diagramIndex != null ? Number(command.options.diagramIndex) : void 0;
1017
+ if (command.options.view) return {
1018
+ diagramIndex: diagramIndex ?? 0,
1019
+ view: command.options.view
1020
+ };
1021
+ if (diagramIndex != null) return diagramIndex;
1022
+ return 0;
1023
+ }
1024
+ function pipelineCompileOptions(command) {
1025
+ const target = compileTargetFromCommand(command);
1026
+ if (typeof target === "number") return target === 0 ? {} : { diagramIndex: target };
1027
+ return target;
1028
+ }
971
1029
  function usage(stream = process.stdout) {
972
1030
  stream.write(`kdiagrams — deterministic text-to-diagram tooling
973
1031
 
@@ -976,6 +1034,8 @@ Common jobs:
976
1034
  kdiagrams format diagrams/ --check
977
1035
  kdiagrams render diagrams/ --out-dir public/diagrams
978
1036
  kdiagrams render architecture.kdiagram -o architecture.svg --print-safe
1037
+ kdiagrams render storefront-model.kdiagram --view context -o context.svg
1038
+ kdiagrams analyze architecture.kdiagram --pretty
979
1039
 
980
1040
  Commands:
981
1041
  render [inputs...] Render portable SVG
@@ -990,6 +1050,10 @@ Commands:
990
1050
  doctor Inspect runtime, font, config, and renderer health
991
1051
  completions <shell> Print Bash, Zsh, or Fish completion source
992
1052
 
1053
+ Model views (kdiagram 2 draft):
1054
+ --view name Select a named \`view\` inside a \`model\` block
1055
+ --diagram-index n Select which top-level diagram/model (default: 0)
1056
+
993
1057
  Studio:
994
1058
  --no-open Start without opening the browser (opens by default)
995
1059
  --allow-write Authorize saving resolved input files
@@ -1049,7 +1113,8 @@ async function cmdRender(command, inputs, context) {
1049
1113
  theme: settings.theme,
1050
1114
  snapshotTheme: settings.snapshotTheme,
1051
1115
  presentation: settings.presentation,
1052
- shadows: false
1116
+ shadows: false,
1117
+ ...pipelineCompileOptions(command)
1053
1118
  });
1054
1119
  printDiagnostics(context, result.diagnostics, source, input.displayPath);
1055
1120
  if (!result.ok || !result.svg) {
@@ -1073,7 +1138,12 @@ async function cmdAnalyze(command, inputs) {
1073
1138
  let errorCount = 0;
1074
1139
  let warningCount = 0;
1075
1140
  for (const input of inputs) {
1076
- const result = await renderPipeline(readResolvedInput(input), { shadows: false });
1141
+ const source = readResolvedInput(input);
1142
+ const compileOptions = pipelineCompileOptions(command);
1143
+ const result = await renderPipeline(source, {
1144
+ shadows: false,
1145
+ ...compileOptions
1146
+ });
1077
1147
  const diagnostics = result.diagnostics;
1078
1148
  errorCount += diagnostics.filter((item) => item.severity === "error").length;
1079
1149
  warningCount += diagnostics.filter((item) => item.severity === "warning").length;
@@ -1135,16 +1205,35 @@ function cmdInspect(command, inputs, context) {
1135
1205
  writeInspectionEnvelope(command, input, result.ast, result.diagnostics);
1136
1206
  return result.diagnostics.some((diagnostic) => diagnostic.severity === "error") ? 1 : 0;
1137
1207
  }
1138
- const result = compileSource(source);
1208
+ const parsed = parseSource(source);
1209
+ printDiagnostics(context, parsed.diagnostics, source, input.displayPath);
1210
+ if (parsed.diagnostics.some((diagnostic) => diagnostic.severity === "error")) {
1211
+ writeInspectionEnvelope(command, input, resultEmptyGraph(), parsed.diagnostics);
1212
+ return 1;
1213
+ }
1214
+ const result = compileSource(source, compileTargetFromCommand(command));
1139
1215
  printDiagnostics(context, result.diagnostics, source, input.displayPath);
1140
- writeInspectionEnvelope(command, input, result.graph, result.diagnostics);
1141
- return result.diagnostics.some((diagnostic) => diagnostic.severity === "error") ? 1 : 0;
1216
+ const diagnostics = [...parsed.diagnostics, ...result.diagnostics];
1217
+ writeInspectionEnvelope(command, input, result.graph, diagnostics, { targets: listCompileTargets(parsed.ast) });
1218
+ return diagnostics.some((diagnostic) => diagnostic.severity === "error") ? 1 : 0;
1219
+ }
1220
+ function resultEmptyGraph() {
1221
+ return {
1222
+ id: "empty",
1223
+ nodes: [],
1224
+ edges: [],
1225
+ groups: [],
1226
+ styles: [],
1227
+ animations: [],
1228
+ diagnostics: []
1229
+ };
1142
1230
  }
1143
- function writeInspectionEnvelope(command, input, data, diagnostics) {
1231
+ function writeInspectionEnvelope(command, input, data, diagnostics, extra) {
1144
1232
  process.stdout.write(`${JSON.stringify(machineEnvelope(command.name, {
1145
1233
  path: input.displayPath,
1146
1234
  data,
1147
- diagnostics
1235
+ diagnostics,
1236
+ ...extra
1148
1237
  }), null, command.options.pretty ? 2 : void 0)}\n`);
1149
1238
  }
1150
1239
  function cmdFormat(command, inputs, context) {
package/dist/cli.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.mjs","names":["COMMANDS","require","require"],"sources":["../src/command-model.ts","../src/completions.ts","../src/project-config.ts","../src/doctor.ts","../src/input-resolver.ts","../src/output.ts","../src/output-paths.ts","../src/portable-svg.ts","../src/studio-server.ts","../src/cli.ts"],"sourcesContent":["export type CommandName =\n | \"render\"\n | \"check\"\n | \"analyze\"\n | \"capabilities\"\n | \"ast\"\n | \"graph\"\n | \"format\"\n | \"studio\"\n | \"lsp\"\n | \"doctor\"\n | \"completions\";\n\nexport type ColorMode = \"auto\" | \"always\" | \"never\";\n\nexport type CommandOptions = {\n output?: string;\n outDir?: string;\n outputTemplate?: string;\n theme?: string;\n snapshot: boolean;\n liveTheme: boolean;\n config?: string;\n profile?: string;\n themeFile?: string;\n background?: \"transparent\" | \"theme\";\n embedFonts: boolean;\n printSafe: boolean;\n open: boolean;\n noOpen: boolean;\n allowWrite: boolean;\n stdio: boolean;\n port?: string;\n color: ColorMode;\n quiet: boolean;\n verbose: boolean;\n debug: boolean;\n json: boolean;\n pretty: boolean;\n write: boolean;\n check: boolean;\n excludes: string[];\n ignoreFile?: string;\n stdinFilename?: string;\n filesFrom?: string;\n};\n\nexport type ParsedCommand = {\n name: CommandName;\n inputs: string[];\n options: CommandOptions;\n};\n\nexport class CliUsageError extends Error {\n readonly exitCode = 2;\n}\n\nconst COMMANDS = new Set<CommandName>([\n \"render\",\n \"check\",\n \"analyze\",\n \"capabilities\",\n \"ast\",\n \"graph\",\n \"format\",\n \"studio\",\n \"lsp\",\n \"doctor\",\n \"completions\",\n]);\n\nconst VALUE_OPTIONS = new Map<\n string,\n | \"output\"\n | \"outDir\"\n | \"outputTemplate\"\n | \"theme\"\n | \"exclude\"\n | \"ignoreFile\"\n | \"stdinFilename\"\n | \"filesFrom\"\n | \"color\"\n | \"config\"\n | \"profile\"\n | \"themeFile\"\n | \"background\"\n | \"port\"\n>([\n [\"-o\", \"output\"],\n [\"--output\", \"output\"],\n [\"--out-dir\", \"outDir\"],\n [\"--output-template\", \"outputTemplate\"],\n [\"--theme\", \"theme\"],\n [\"--exclude\", \"exclude\"],\n [\"--ignore-file\", \"ignoreFile\"],\n [\"--stdin-filename\", \"stdinFilename\"],\n [\"--files-from\", \"filesFrom\"],\n [\"--color\", \"color\"],\n [\"--config\", \"config\"],\n [\"--profile\", \"profile\"],\n [\"--theme-file\", \"themeFile\"],\n [\"--background\", \"background\"],\n [\"--port\", \"port\"],\n] as const);\n\nconst BOOLEAN_OPTIONS = new Map<\n string,\n | \"snapshot\"\n | \"liveTheme\"\n | \"json\"\n | \"pretty\"\n | \"write\"\n | \"check\"\n | \"quiet\"\n | \"verbose\"\n | \"debug\"\n | \"embedFonts\"\n | \"printSafe\"\n | \"open\"\n | \"noOpen\"\n | \"allowWrite\"\n | \"stdio\"\n>([\n [\"--snapshot\", \"snapshot\"],\n [\"--live-theme\", \"liveTheme\"],\n [\"--json\", \"json\"],\n [\"--pretty\", \"pretty\"],\n [\"--write\", \"write\"],\n [\"--check\", \"check\"],\n [\"--quiet\", \"quiet\"],\n [\"--verbose\", \"verbose\"],\n [\"--debug\", \"debug\"],\n [\"--embed-fonts\", \"embedFonts\"],\n [\"--print-safe\", \"printSafe\"],\n [\"--open\", \"open\"],\n [\"--no-open\", \"noOpen\"],\n [\"--allow-write\", \"allowWrite\"],\n [\"--stdio\", \"stdio\"],\n] as const);\n\nconst DISCOVERY = [\"exclude\", \"ignoreFile\", \"stdinFilename\", \"filesFrom\"];\nconst PRESENTATION = [\"color\", \"quiet\", \"verbose\", \"debug\"];\n\nconst ALLOWED_OPTIONS: Record<CommandName, ReadonlySet<string>> = {\n render: new Set([\n \"output\",\n \"outDir\",\n \"outputTemplate\",\n \"theme\",\n \"snapshot\",\n \"liveTheme\",\n \"config\",\n \"profile\",\n \"themeFile\",\n \"background\",\n \"embedFonts\",\n \"printSafe\",\n ...DISCOVERY,\n ...PRESENTATION,\n ]),\n check: new Set([\"json\", ...DISCOVERY, ...PRESENTATION]),\n analyze: new Set([\"json\", \"pretty\", ...DISCOVERY, ...PRESENTATION]),\n capabilities: new Set([\"pretty\"]),\n ast: new Set([\"pretty\", \"json\", ...DISCOVERY, ...PRESENTATION]),\n graph: new Set([\"pretty\", \"json\", ...DISCOVERY, ...PRESENTATION]),\n format: new Set([\"output\", \"write\", \"check\", ...DISCOVERY, ...PRESENTATION]),\n studio: new Set([\"open\", \"noOpen\", \"allowWrite\", \"port\", ...DISCOVERY, ...PRESENTATION]),\n lsp: new Set([\"stdio\"]),\n doctor: new Set([\"json\", ...PRESENTATION]),\n completions: new Set([]),\n};\n\nfunction defaults(): CommandOptions {\n return {\n snapshot: false,\n liveTheme: false,\n color: \"auto\",\n quiet: false,\n verbose: false,\n debug: false,\n embedFonts: false,\n printSafe: false,\n open: false,\n noOpen: false,\n allowWrite: false,\n stdio: false,\n json: false,\n pretty: false,\n write: false,\n check: false,\n excludes: [],\n };\n}\n\nfunction optionParts(raw: string): { flag: string; inlineValue?: string } {\n if (!raw.startsWith(\"--\")) return { flag: raw };\n const equals = raw.indexOf(\"=\");\n return equals < 0\n ? { flag: raw }\n : { flag: raw.slice(0, equals), inlineValue: raw.slice(equals + 1) };\n}\n\nexport function parseCommand(argv: readonly string[]): ParsedCommand {\n const name = argv[0];\n if (!COMMANDS.has(name as CommandName)) {\n const suggestion = name ? nearest(name, [...COMMANDS]) : undefined;\n throw new CliUsageError(\n name\n ? `Unknown command: ${name}${suggestion ? `. Did you mean ${suggestion}?` : \"\"}`\n : \"Missing command\",\n );\n }\n\n const command = name as CommandName;\n const inputs: string[] = [];\n const options = defaults();\n let positionalOnly = false;\n\n for (let index = 1; index < argv.length; index++) {\n const raw = argv[index]!;\n if (raw === \"--\" && !positionalOnly) {\n positionalOnly = true;\n continue;\n }\n if (raw === \"-\" || positionalOnly || !raw.startsWith(\"-\")) {\n inputs.push(raw);\n continue;\n }\n\n const { flag, inlineValue } = optionParts(raw);\n const valueKey = VALUE_OPTIONS.get(flag);\n const booleanKey = BOOLEAN_OPTIONS.get(flag);\n const allowed = ALLOWED_OPTIONS[command];\n\n if (valueKey) {\n if (!allowed.has(valueKey)) throw new CliUsageError(`Unknown option for ${command}: ${flag}`);\n const value = inlineValue ?? argv[++index];\n if (!value || (inlineValue == null && value.startsWith(\"-\") && value !== \"-\")) {\n throw new CliUsageError(`Missing value for ${flag}`);\n }\n if (valueKey === \"exclude\") options.excludes.push(value);\n else if (valueKey === \"color\") {\n if (value !== \"auto\" && value !== \"always\" && value !== \"never\") {\n throw new CliUsageError(\n `Invalid --color value: ${value} (expected auto, always, or never)`,\n );\n }\n options.color = value;\n } else if (valueKey === \"background\") {\n if (value !== \"transparent\" && value !== \"theme\") {\n throw new CliUsageError(\n `Invalid --background value: ${value} (expected transparent or theme)`,\n );\n }\n options.background = value;\n } else if (valueKey === \"theme\") {\n options.theme = value;\n } else {\n options[valueKey] = value;\n }\n continue;\n }\n\n if (booleanKey) {\n if (inlineValue != null) throw new CliUsageError(`${flag} does not accept a value`);\n if (!allowed.has(booleanKey)) {\n throw new CliUsageError(`Unknown option for ${command}: ${flag}`);\n }\n options[booleanKey] = true;\n continue;\n }\n\n const candidates = [...VALUE_OPTIONS.keys(), ...BOOLEAN_OPTIONS.keys(), \"--help\", \"--version\"];\n const suggestion = nearest(flag, candidates);\n throw new CliUsageError(\n `Unknown option: ${flag}${suggestion ? `. Did you mean ${suggestion}?` : \"\"}`,\n );\n }\n\n validateOptions(command, options);\n return { name: command, inputs, options };\n}\n\nfunction nearest(value: string, candidates: readonly string[]): string | undefined {\n let best: { value: string; distance: number } | undefined;\n for (const candidate of candidates) {\n const distance = editDistance(value, candidate);\n if (!best || distance < best.distance) best = { value: candidate, distance };\n }\n return best && best.distance <= Math.max(2, Math.floor(value.length / 3))\n ? best.value\n : undefined;\n}\n\nfunction editDistance(left: string, right: string): number {\n const previous = Array.from({ length: right.length + 1 }, (_, index) => index);\n for (let i = 1; i <= left.length; i++) {\n const current = [i];\n for (let j = 1; j <= right.length; j++) {\n current[j] = Math.min(\n current[j - 1]! + 1,\n previous[j]! + 1,\n previous[j - 1]! + (left[i - 1] === right[j - 1] ? 0 : 1),\n );\n }\n previous.splice(0, previous.length, ...current);\n }\n return previous[right.length]!;\n}\n\nfunction validateOptions(command: CommandName, options: CommandOptions): void {\n if (command === \"render\") {\n const destinations = [options.output, options.outDir, options.outputTemplate].filter(Boolean);\n if (options.output && destinations.length > 1) {\n throw new CliUsageError(\"--output cannot be combined with --out-dir or --output-template\");\n }\n if (options.snapshot && options.liveTheme) {\n throw new CliUsageError(\"--snapshot and --live-theme cannot be combined\");\n }\n }\n if (command === \"format\") {\n if (options.write && options.check) {\n throw new CliUsageError(\"--write and --check cannot be combined\");\n }\n if (options.output && (options.write || options.check)) {\n throw new CliUsageError(\"--output cannot be combined with --write or --check\");\n }\n }\n if (command === \"studio\") {\n if (options.open && options.noOpen) {\n throw new CliUsageError(\"--open and --no-open cannot be combined\");\n }\n if (options.port != null && (!/^\\d+$/.test(options.port) || Number(options.port) > 65535)) {\n throw new CliUsageError(\"--port must be an integer from 0 to 65535\");\n }\n }\n if (command === \"lsp\" && !options.stdio) {\n throw new CliUsageError(\"lsp requires --stdio\");\n }\n if (options.quiet && options.verbose) {\n throw new CliUsageError(\"--quiet and --verbose cannot be combined\");\n }\n if (command === \"completions\" && options.excludes.length > 0) {\n throw new CliUsageError(\"completions does not accept discovery options\");\n }\n}\n","import { CliUsageError } from \"./command-model.ts\";\n\nconst COMMANDS = \"render check analyze capabilities format studio lsp ast graph doctor completions\";\nconst OPTIONS =\n \"--help --version --color --quiet --verbose --debug --exclude --ignore-file --stdin-filename --files-from --output --out-dir --output-template --theme --theme-file --config --profile --live-theme --snapshot --background --embed-fonts --print-safe --json --pretty --check --write --open --no-open --allow-write --port --stdio\";\n\nexport function shellCompletions(shell: string | undefined): string {\n switch (shell) {\n case \"bash\":\n return `# Kekonic Diagrams completion\\n_kdiagrams() {\\n local cur=\"\\${COMP_WORDS[COMP_CWORD]}\"\\n COMPREPLY=( $(compgen -W \"${COMMANDS} ${OPTIONS}\" -- \"$cur\") )\\n}\\ncomplete -F _kdiagrams kdiagrams\\n`;\n case \"zsh\":\n return `#compdef kdiagrams\\n_arguments '1:command:(${COMMANDS})' '*:option:(${OPTIONS})'\\n`;\n case \"fish\":\n return `${COMMANDS.split(\" \")\n .map((command) => `complete -c kdiagrams -f -n '__fish_use_subcommand' -a '${command}'`)\n .join(\"\\n\")}\\n`;\n default:\n throw new CliUsageError(\"completions requires one shell: bash, zsh, or fish\");\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, parse, resolve } from \"node:path\";\nimport { registerTheme, type PresentationOptions } from \"@kekonic/diagrams\";\nimport { CliUsageError, type ParsedCommand } from \"./command-model.ts\";\n\nconst DEFAULT_CONFIG = \"kekonic-diagrams.config.json\";\n\nexport type ExportProfile = {\n theme?: string;\n snapshotTheme?: boolean;\n background?: \"transparent\" | \"theme\";\n embedFonts?: boolean;\n printSafe?: boolean;\n presentation?: PresentationOptions;\n format?: \"svg\" | \"png\" | \"pdf\";\n};\n\nexport type ProjectConfig = {\n version: 1;\n defaultProfile?: string;\n themes?: Record<string, Record<string, string>>;\n profiles?: Record<string, ExportProfile>;\n};\n\nexport type ResolvedRenderSettings = Required<\n Pick<ExportProfile, \"theme\" | \"snapshotTheme\" | \"background\" | \"embedFonts\" | \"printSafe\">\n> & {\n presentation?: PresentationOptions;\n configPath?: string;\n profileName?: string;\n warnings: string[];\n};\n\nexport function resolveRenderSettings(\n command: ParsedCommand,\n cwd = process.cwd(),\n): ResolvedRenderSettings {\n const loaded = loadProjectConfig(command.options.config, cwd);\n const config = loaded?.config;\n const configDir = loaded ? dirname(loaded.path) : cwd;\n\n for (const [name, tokens] of Object.entries(config?.themes ?? {})) {\n validateTokens(tokens, `themes.${name}`);\n registerTheme(name, tokens);\n }\n if (command.options.themeFile) {\n const themePath = resolve(configDir, command.options.themeFile);\n const parsed = readJson(themePath);\n const name = command.options.theme ?? \"custom\";\n const tokens = isRecord(parsed) && isRecord(parsed.tokens) ? parsed.tokens : parsed;\n validateTokens(tokens, themePath);\n registerTheme(name, tokens);\n }\n\n const profileName = command.options.profile ?? config?.defaultProfile;\n const profile = profileName ? config?.profiles?.[profileName] : undefined;\n if (profileName && !profile) {\n throw new CliUsageError(`Unknown export profile: ${profileName}`);\n }\n if (profile?.format && profile.format !== \"svg\") {\n throw new CliUsageError(\n `Export profile ${profileName} requests ${profile.format}; this CLI build supports SVG output`,\n );\n }\n\n const printSafe = command.options.printSafe || profile?.printSafe === true;\n const snapshotTheme = command.options.liveTheme\n ? false\n : command.options.snapshot || profile?.snapshotTheme !== false;\n const settings: ResolvedRenderSettings = {\n theme: command.options.theme ?? profile?.theme ?? (printSafe ? \"light\" : \"dark\"),\n snapshotTheme,\n background:\n command.options.background ?? profile?.background ?? (printSafe ? \"theme\" : \"transparent\"),\n embedFonts: command.options.embedFonts || profile?.embedFonts === true,\n printSafe,\n presentation: profile?.presentation,\n configPath: loaded?.path,\n profileName,\n warnings: [],\n };\n if (!snapshotTheme) {\n settings.warnings.push(\n \"live-theme SVG retains unresolved CSS custom properties and requires KDiagram theme tokens from its host\",\n );\n }\n return settings;\n}\n\nexport function findProjectConfig(cwd: string): string | undefined {\n let current = resolve(cwd);\n const root = parse(current).root;\n while (true) {\n const candidate = join(current, DEFAULT_CONFIG);\n if (existsSync(candidate)) return candidate;\n if (current === root) return undefined;\n current = dirname(current);\n }\n}\n\nfunction loadProjectConfig(\n explicitPath: string | undefined,\n cwd: string,\n): { path: string; config: ProjectConfig } | undefined {\n const path = explicitPath\n ? isAbsolute(explicitPath)\n ? explicitPath\n : resolve(cwd, explicitPath)\n : findProjectConfig(cwd);\n if (!path) return undefined;\n if (!existsSync(path)) throw new CliUsageError(`Config file does not exist: ${path}`);\n const parsed = readJson(path);\n if (!isRecord(parsed) || parsed.version !== 1) {\n throw new CliUsageError(`${path}: expected { \"version\": 1, ... }`);\n }\n validateConfigKeys(parsed, path);\n return { path, config: parsed as ProjectConfig };\n}\n\nfunction validateConfigKeys(value: Record<string, unknown>, path: string): void {\n const allowed = new Set([\"version\", \"defaultProfile\", \"themes\", \"profiles\", \"$schema\"]);\n for (const key of Object.keys(value)) {\n if (!allowed.has(key)) throw new CliUsageError(`${path}: unknown config property ${key}`);\n }\n if (value.profiles != null && !isRecord(value.profiles)) {\n throw new CliUsageError(`${path}: profiles must be an object`);\n }\n for (const [name, profile] of Object.entries((value.profiles as object | undefined) ?? {})) {\n if (!isRecord(profile)) throw new CliUsageError(`${path}: profile ${name} must be an object`);\n const profileKeys = new Set([\n \"theme\",\n \"snapshotTheme\",\n \"background\",\n \"embedFonts\",\n \"printSafe\",\n \"presentation\",\n \"format\",\n ]);\n for (const key of Object.keys(profile)) {\n if (!profileKeys.has(key)) {\n throw new CliUsageError(`${path}: unknown profiles.${name}.${key}`);\n }\n }\n }\n}\n\nfunction readJson(path: string): unknown {\n try {\n return JSON.parse(readFileSync(path, \"utf8\"));\n } catch (error) {\n throw new CliUsageError(\n `${path}: ${error instanceof Error ? error.message : \"could not read JSON\"}`,\n );\n }\n}\n\nfunction validateTokens(value: unknown, label: string): asserts value is Record<string, string> {\n if (!isRecord(value)) throw new CliUsageError(`${label}: theme tokens must be an object`);\n for (const [key, token] of Object.entries(value)) {\n if (!/^--[a-zA-Z0-9_-]+$/.test(key) || typeof token !== \"string\") {\n throw new CliUsageError(`${label}: theme tokens must map --custom-properties to strings`);\n }\n if (/[;{}<>@]/.test(token) || /url\\s*\\(/i.test(token)) {\n throw new CliUsageError(`${label}.${key}: theme token contains unsupported CSS syntax`);\n }\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n","import { existsSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { findProjectConfig } from \"./project-config.ts\";\n\nconst require = createRequire(import.meta.url);\n\nexport type DoctorCheck = {\n name: string;\n status: \"pass\" | \"warn\" | \"fail\";\n detail: string;\n};\n\nexport function runDoctor(cwd = process.cwd()): DoctorCheck[] {\n const nodeMajor = Number(process.versions.node.split(\".\")[0]);\n const config = findProjectConfig(cwd);\n let font = \"unavailable\";\n try {\n const path = require.resolve(\"@fontsource/inter/files/inter-latin-500-normal.woff\");\n if (existsSync(path)) font = path;\n } catch {\n // Reported as a structured failure below.\n }\n return [\n {\n name: \"runtime\",\n status: nodeMajor >= 22 ? \"pass\" : \"fail\",\n detail: `Node ${process.versions.node} (requires >=22.18.0)`,\n },\n {\n name: \"font\",\n status: font === \"unavailable\" ? \"fail\" : \"pass\",\n detail:\n font === \"unavailable\"\n ? \"Bundled Inter measurement font not found\"\n : \"Bundled Inter font available\",\n },\n {\n name: \"config\",\n status: config ? \"pass\" : \"warn\",\n detail:\n config ?? \"No kekonic-diagrams.config.json discovered; built-in export defaults apply\",\n },\n {\n name: \"renderer\",\n status: \"pass\",\n detail: \"SVG renderer available; portable snapshot export is the default\",\n },\n ];\n}\n","import { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { basename, dirname, extname, isAbsolute, relative, resolve, sep } from \"node:path\";\nimport type { Ignore } from \"ignore\";\nimport { globSync, isDynamicPattern } from \"tinyglobby\";\nimport { CliUsageError, type ParsedCommand } from \"./command-model.ts\";\n\nconst SOURCE_EXTENSION = \".kdiagram\";\nconst DEFAULT_IGNORE_FILE = \".kdiagramignore\";\nconst CRAWL_IGNORES = [\"**/.git/**\", \"**/node_modules/**\"];\nconst require = createRequire(import.meta.url);\n// `ignore` v5 is CommonJS; createRequire preserves its callable runtime export under NodeNext.\nconst createIgnore = require(\"ignore\") as () => Ignore;\n\nexport type ResolvedInput = {\n kind: \"file\" | \"stdin\";\n absolutePath?: string;\n displayPath: string;\n relativePath: string;\n source?: string;\n};\n\nexport type ResolveInputOptions = {\n cwd?: string;\n stdinIsTTY?: boolean;\n readStdin?: () => string;\n};\n\ntype Candidate = { absolutePath: string; relativePath: string };\n\nexport function resolveCommandInputs(\n command: ParsedCommand,\n options: ResolveInputOptions = {},\n): ResolvedInput[] {\n const cwd = resolve(options.cwd ?? process.cwd());\n const readStdin = options.readStdin ?? (() => readFileSync(0, \"utf-8\"));\n const requested = [...command.inputs];\n\n if (command.options.filesFrom) {\n const listSource = command.options.filesFrom;\n let pathList: string;\n if (listSource === \"-\") {\n if (requested.includes(\"-\")) {\n throw new CliUsageError(\"stdin cannot contain both diagram source and --files-from paths\");\n }\n pathList = readStdin();\n } else {\n pathList = readFileSync(resolve(cwd, listSource), \"utf-8\");\n }\n requested.push(...parsePathList(pathList));\n }\n\n if (requested.length === 0) {\n if (command.options.filesFrom) {\n throw new CliUsageError(\"--files-from did not provide any input paths\");\n }\n if (options.stdinIsTTY ?? process.stdin.isTTY) {\n throw new CliUsageError(\"Missing input (pass a path, '-' or pipe diagram source on stdin)\");\n }\n requested.push(\"-\");\n }\n\n const files: Candidate[] = [];\n let stdinInput: ResolvedInput | undefined;\n for (const input of requested) {\n if (input === \"-\") {\n if (stdinInput) throw new CliUsageError(\"stdin source may be supplied only once\");\n const filename = command.options.stdinFilename;\n const absolutePath = filename ? resolve(cwd, filename) : undefined;\n stdinInput = {\n kind: \"stdin\",\n absolutePath,\n displayPath: filename ?? \"<stdin>\",\n relativePath: filename ? portableRelativePath(cwd, absolutePath!) : \"stdin.kdiagram\",\n source: readStdin(),\n };\n continue;\n }\n files.push(...expandInput(input, cwd));\n }\n\n const filtered = filterIgnoredFiles(\n files,\n cwd,\n command.options.ignoreFile,\n command.options.excludes,\n );\n const unique = new Map<string, Candidate>();\n for (const candidate of filtered) unique.set(resolve(candidate.absolutePath), candidate);\n const resolvedFiles = [...unique.values()]\n .sort((left, right) => comparePaths(left.absolutePath, right.absolutePath))\n .map<ResolvedInput>(({ absolutePath, relativePath }) => ({\n kind: \"file\",\n absolutePath,\n displayPath: absolutePath,\n relativePath,\n }));\n const result = stdinInput ? [...resolvedFiles, stdinInput] : resolvedFiles;\n if (result.length === 0) throw new CliUsageError(\"No .kdiagram input files matched\");\n return result;\n}\n\nexport function readResolvedInput(input: ResolvedInput): string {\n if (input.kind === \"stdin\") return input.source ?? \"\";\n return readFileSync(input.absolutePath!, \"utf-8\");\n}\n\nfunction expandInput(input: string, cwd: string): Candidate[] {\n const absolute = resolve(cwd, input);\n if (existsSync(absolute)) {\n const stats = statSync(absolute);\n if (stats.isDirectory()) {\n const matches = globSync(\"**/*.kdiagram\", {\n cwd: absolute,\n absolute: true,\n dot: true,\n followSymbolicLinks: false,\n ignore: CRAWL_IGNORES,\n });\n const insideCwd = isWithin(cwd, absolute);\n return matches.map((file) => ({\n absolutePath: file,\n relativePath: insideCwd\n ? portableRelativePath(cwd, file)\n : toPosix(relative(absolute, file)),\n }));\n }\n if (!stats.isFile()) throw new CliUsageError(`Input is not a file or directory: ${input}`);\n if (extname(absolute).toLowerCase() !== SOURCE_EXTENSION) {\n throw new CliUsageError(`Input file must end in ${SOURCE_EXTENSION}: ${input}`);\n }\n return [{ absolutePath: absolute, relativePath: portableRelativePath(cwd, absolute) }];\n }\n\n if (!isDynamicPattern(input)) throw new CliUsageError(`Input path does not exist: ${input}`);\n return globSync(input, {\n cwd,\n absolute: true,\n dot: true,\n followSymbolicLinks: false,\n onlyFiles: true,\n ignore: CRAWL_IGNORES,\n })\n .filter((file) => extname(file).toLowerCase() === SOURCE_EXTENSION)\n .map((file) => ({\n absolutePath: file,\n relativePath: portableRelativePath(cwd, file),\n }));\n}\n\nfunction filterIgnoredFiles(\n files: readonly Candidate[],\n cwd: string,\n ignoreFileOption: string | undefined,\n excludes: readonly string[],\n): Candidate[] {\n const ignoreFile = resolve(cwd, ignoreFileOption ?? DEFAULT_IGNORE_FILE);\n const ignoreRoot = dirname(ignoreFile);\n const ignoreMatcher = existsSync(ignoreFile)\n ? createIgnore().add(readFileSync(ignoreFile, \"utf-8\"))\n : undefined;\n const excludeMatcher = excludes.length > 0 ? createIgnore().add(excludes) : undefined;\n if (!ignoreMatcher && !excludeMatcher) return [...files];\n\n return files.filter((candidate) => {\n if (ignoreMatcher && isWithin(ignoreRoot, candidate.absolutePath)) {\n const ignoredPath = toPosix(relative(ignoreRoot, candidate.absolutePath));\n if (ignoreMatcher.ignores(ignoredPath)) return false;\n }\n return !excludeMatcher?.ignores(candidate.relativePath);\n });\n}\n\nfunction isWithin(parent: string, child: string): boolean {\n const rel = relative(parent, child);\n return !rel.startsWith(`..${sep}`) && !isAbsolute(rel);\n}\n\nfunction parsePathList(contents: string): string[] {\n return contents\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0 && !line.startsWith(\"#\"));\n}\n\nfunction portableRelativePath(cwd: string, absolutePath: string): string {\n const rel = relative(cwd, absolutePath);\n if (!rel || rel.startsWith(`..${sep}`) || isAbsolute(rel)) return basename(absolutePath);\n return toPosix(rel);\n}\n\nfunction toPosix(path: string): string {\n return path.split(sep).join(\"/\");\n}\n\nfunction comparePaths(left: string, right: string): number {\n const a = toPosix(left);\n const b = toPosix(right);\n return a < b ? -1 : a > b ? 1 : 0;\n}\n","import type { Diagnostic } from \"@kekonic/diagrams\";\nimport type { ColorMode, CommandOptions } from \"./command-model.ts\";\n\nexport const EXIT_SUCCESS = 0;\nexport const EXIT_DIAGNOSTICS = 1;\nexport const EXIT_USAGE = 2;\nexport const EXIT_OPERATIONAL = 3;\nexport const MACHINE_OUTPUT_VERSION = 1;\n\ntype Writable = Pick<NodeJS.WritableStream, \"write\"> & { isTTY?: boolean };\n\nexport type OutputContext = {\n color: boolean;\n quiet: boolean;\n verbose: boolean;\n debug: boolean;\n stderr: Writable;\n};\n\nexport function createOutputContext(\n options: Pick<CommandOptions, \"color\" | \"quiet\" | \"verbose\" | \"debug\">,\n stderr: Writable = process.stderr,\n env: NodeJS.ProcessEnv = process.env,\n): OutputContext {\n return {\n color: shouldUseColor(options.color, stderr.isTTY === true, env),\n quiet: options.quiet,\n verbose: options.verbose,\n debug: options.debug,\n stderr,\n };\n}\n\nexport function shouldUseColor(mode: ColorMode, isTTY: boolean, env: NodeJS.ProcessEnv): boolean {\n if (mode === \"always\") return true;\n if (mode === \"never\") return false;\n if (env.NO_COLOR != null || env.FORCE_COLOR === \"0\") return false;\n if (env.FORCE_COLOR != null) return true;\n return isTTY;\n}\n\nexport function printDiagnostic(\n context: OutputContext,\n diagnostic: Diagnostic,\n source: string,\n path: string,\n): void {\n const { start, end } = diagnostic.range;\n const severity = colorizeSeverity(context, diagnostic.severity);\n context.stderr.write(\n `${bold(context, `${path}:${start.line}:${start.column}`)} ${severity}[${diagnostic.code}] ${diagnostic.message}\\n`,\n );\n\n const lines = source.split(/\\r?\\n/);\n const line = lines[start.line - 1] ?? \"\";\n const lineNumber = String(start.line);\n const gutter = \" \".repeat(lineNumber.length);\n const startColumn = Math.max(1, start.column);\n const endColumn =\n end.line === start.line ? Math.max(startColumn + 1, end.column) : line.length + 1;\n const markerLength = Math.max(\n 1,\n Math.min(endColumn - startColumn, line.length - startColumn + 2),\n );\n context.stderr.write(`${dim(context, `${gutter} |`)}\\n`);\n context.stderr.write(`${dim(context, `${lineNumber} |`)} ${line}\\n`);\n context.stderr.write(\n `${dim(context, `${gutter} |`)} ${\" \".repeat(startColumn - 1)}${severityColor(context, diagnostic.severity, \"^\".repeat(markerLength))}\\n`,\n );\n if (diagnostic.hint) {\n context.stderr.write(\n `${dim(context, `${gutter} =`)} ${cyan(context, \"hint:\")} ${diagnostic.hint}\\n`,\n );\n }\n}\n\nexport function printSummary(context: OutputContext, message: string): void {\n if (!context.quiet) context.stderr.write(`${message}\\n`);\n}\n\nexport function printProgress(context: OutputContext, message: string): void {\n if (!context.quiet && context.verbose) context.stderr.write(`${dim(context, message)}\\n`);\n}\n\nexport function machineEnvelope<T>(\n command: string,\n payload: T,\n): {\n version: 1;\n command: string;\n payload: T;\n} {\n return { version: MACHINE_OUTPUT_VERSION, command, payload };\n}\n\nexport function installPipeErrorHandlers(): void {\n for (const stream of [process.stdout, process.stderr]) {\n stream.on(\"error\", (error: NodeJS.ErrnoException) => {\n if (error.code === \"EPIPE\") {\n process.exit(EXIT_SUCCESS);\n }\n throw error;\n });\n }\n}\n\nfunction printCode(code: number): string {\n return `\\u001b[${code}m`;\n}\n\nfunction styled(context: OutputContext, code: number, text: string): string {\n return context.color ? `${printCode(code)}${text}${printCode(0)}` : text;\n}\n\nfunction bold(context: OutputContext, text: string): string {\n return styled(context, 1, text);\n}\n\nfunction dim(context: OutputContext, text: string): string {\n return styled(context, 2, text);\n}\n\nfunction cyan(context: OutputContext, text: string): string {\n return styled(context, 36, text);\n}\n\nfunction severityColor(\n context: OutputContext,\n severity: Diagnostic[\"severity\"],\n text: string,\n): string {\n return styled(context, severity === \"error\" ? 31 : severity === \"warning\" ? 33 : 36, text);\n}\n\nfunction colorizeSeverity(context: OutputContext, severity: Diagnostic[\"severity\"]): string {\n return severityColor(context, severity, severity);\n}\n","import { basename, dirname, extname, resolve } from \"node:path\";\nimport { CliUsageError, type ParsedCommand } from \"./command-model.ts\";\nimport type { ResolvedInput } from \"./input-resolver.ts\";\n\nexport function renderOutputPaths(\n command: ParsedCommand,\n inputs: readonly ResolvedInput[],\n cwd = process.cwd(),\n): Array<string | undefined> {\n const { output, outDir, outputTemplate } = command.options;\n if (inputs.length > 1 && output) {\n throw new CliUsageError(\"--output accepts only one resolved input\");\n }\n if (inputs.length > 1 && !outDir && !outputTemplate) {\n throw new CliUsageError(\n \"Multiple render inputs require --out-dir or --output-template; SVG documents are never concatenated\",\n );\n }\n\n const paths = inputs.map((input) => {\n if (output) return resolve(cwd, output);\n if (!outDir && !outputTemplate) return undefined;\n const rendered = applyTemplate(outputTemplate ?? \"{path}.svg\", input.relativePath);\n return outDir ? resolve(cwd, outDir, rendered) : resolve(cwd, rendered);\n });\n rejectCollisions(paths);\n return paths;\n}\n\nfunction applyTemplate(template: string, relativeInput: string): string {\n const extension = extname(relativeInput);\n const pathWithoutExtension = extension\n ? relativeInput.slice(0, relativeInput.length - extension.length)\n : relativeInput;\n const directory = dirname(pathWithoutExtension) === \".\" ? \"\" : dirname(pathWithoutExtension);\n const name = basename(pathWithoutExtension);\n const rendered = template\n .replaceAll(\"{path}\", pathWithoutExtension)\n .replaceAll(\"{dir}\", directory)\n .replaceAll(\"{name}\", name)\n .replaceAll(\"{ext}\", \"svg\");\n if (!rendered || rendered.endsWith(\"/\")) {\n throw new CliUsageError(`Invalid --output-template result for ${relativeInput}: ${rendered}`);\n }\n return rendered;\n}\n\nfunction rejectCollisions(paths: readonly (string | undefined)[]): void {\n const seen = new Set<string>();\n for (const path of paths) {\n if (!path) continue;\n if (seen.has(path))\n throw new CliUsageError(`Multiple inputs resolve to the same output: ${path}`);\n seen.add(path);\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport type { ResolvedRenderSettings } from \"./project-config.ts\";\n\nconst require = createRequire(import.meta.url);\n\nexport function finalizePortableSvg(svg: string, settings: ResolvedRenderSettings): string {\n let output = svg;\n if (settings.embedFonts) output = embedInter(output);\n if (settings.background === \"theme\") {\n const background = `<rect class=\"kdiagram-export-background\" width=\"100%\" height=\"100%\" fill=\"var(--kd-bg)\"/>`;\n output = output.replace(/(<desc\\b[^>]*>[^<]*<\\/desc>)/, `$1\\n${background}`);\n }\n return output;\n}\n\nfunction embedInter(svg: string): string {\n const fontPath = require.resolve(\"@fontsource/inter/files/inter-latin-500-normal.woff\");\n const font = readFileSync(fontPath).toString(\"base64\");\n const css = `@font-face{font-family:\"Inter\";src:url(data:font/woff;base64,${font}) format(\"woff\");font-style:normal;font-weight:100 900;font-display:block;}`;\n const styleIndex = svg.indexOf(\"<style>\");\n if (styleIndex >= 0) return svg.slice(0, styleIndex + 7) + css + svg.slice(styleIndex + 7);\n return svg.replace(/(<svg\\b[^>]*>)/, `$1\\n<style>${css}</style>`);\n}\n","import { spawn } from \"node:child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport {\n createReadStream,\n existsSync,\n readFileSync,\n statSync,\n watch,\n writeFileSync,\n} from \"node:fs\";\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { basename, dirname, extname, relative, resolve, sep } from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport { renderPipeline } from \"@kekonic/diagrams\";\nimport { loadIconSubset } from \"@kekonic/diagrams-icons\";\nimport {\n STUDIO_PROTOCOL_VERSION,\n createStudioPreviewCoordinator,\n parseStudioClientMessage,\n studioMessageJson,\n type StudioDocument,\n type StudioPresentation,\n type StudioRender,\n type StudioServerMessage,\n} from \"@kekonic/diagrams-studio\";\n\nconst require = createRequire(import.meta.url);\nconst ICON_NAME = /^[a-z0-9][a-z0-9-]*$/;\nconst MAX_ICONS_PER_REQUEST = 64;\n\nexport type StudioServer = {\n url: string;\n port: number;\n token: string;\n closed: Promise<void>;\n close(): Promise<void>;\n};\n\nexport type StartStudioServerOptions = {\n files: string[];\n allowWrite?: boolean;\n port?: number;\n browserRoot?: string;\n};\n\nexport async function startStudioServer(options: StartStudioServerOptions): Promise<StudioServer> {\n const files = [...new Set(options.files.map((file) => resolve(file)))].sort();\n if (files.length === 0) throw new Error(\"Studio requires at least one .kdiagram file\");\n for (const file of files) {\n if (!existsSync(file) || !statSync(file).isFile())\n throw new Error(`Studio input is not a file: ${file}`);\n }\n const roots = minimalRoots(files.map(dirname));\n const documents = new Map<string, StudioDocument>();\n for (const file of files) {\n const id = relative(commonRoot(files), file).split(sep).join(\"/\") || basename(file);\n documents.set(id, {\n id,\n path: file,\n label: id,\n revision: 0,\n source: readFileSync(file, \"utf8\"),\n });\n }\n let activeDocumentId = documents.keys().next().value as string;\n let presentation: StudioPresentation = { theme: \"dark\", options: { theme: \"dark\" } };\n const token = randomBytes(32).toString(\"base64url\");\n const sessionId = randomBytes(16).toString(\"hex\");\n const browserRoot = resolve(\n options.browserRoot ?? dirname(require.resolve(\"@kekonic/diagrams-studio/browser\")),\n );\n const clients = new Set<ServerResponse>();\n const renders = new Map<string, StudioRender>();\n const coordinator = createStudioPreviewCoordinator((source, renderOptions) =>\n renderPipeline(source, { ...renderOptions, snapshotTheme: true, shadows: false }),\n );\n\n const broadcast = (message: StudioServerMessage): void => {\n const line = `data: ${studioMessageJson(message)}\\n\\n`;\n for (const client of clients) client.write(line);\n };\n const renderDocument = async (document: StudioDocument): Promise<void> => {\n const result = await coordinator.render(\n document.id,\n document.revision,\n document.source,\n presentation.options,\n );\n if (result) {\n renders.set(document.id, result);\n broadcast({ version: STUDIO_PROTOCOL_VERSION, type: \"render\", ...result });\n }\n };\n\n const server = createServer(async (request, response) => {\n try {\n const url = new URL(request.url ?? \"/\", \"http://127.0.0.1\");\n const cookieToken = request.headers.cookie\n ?.split(\";\")\n .map((item) => item.trim())\n .find((item) => item.startsWith(\"kdiagram_studio=\"))\n ?.slice(\"kdiagram_studio=\".length);\n if (url.searchParams.get(\"token\") !== token && cookieToken !== token) {\n return respond(response, 403, \"Forbidden\");\n }\n if (request.method === \"GET\" && url.pathname === \"/events\") {\n response.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n \"X-Content-Type-Options\": \"nosniff\",\n });\n clients.add(response);\n response.write(\n `data: ${studioMessageJson({\n version: 1,\n type: \"ready\",\n sessionId,\n documents: [...documents.values()],\n activeDocumentId,\n capabilities: { write: options.allowWrite === true, export: true },\n presentation,\n })}\\n\\n`,\n );\n request.on(\"close\", () => clients.delete(response));\n void renderDocument(documents.get(activeDocumentId)!);\n return;\n }\n if (request.method === \"POST\" && url.pathname === \"/message\") {\n const message = parseStudioClientMessage(JSON.parse(await readBody(request)));\n const document = \"documentId\" in message ? documents.get(message.documentId) : undefined;\n if (\"documentId\" in message && !document) return respond(response, 404, \"Unknown document\");\n switch (message.type) {\n case \"open\":\n activeDocumentId = message.documentId;\n broadcast({ version: 1, type: \"document\", reason: \"open\", ...document! });\n void renderDocument(document!);\n break;\n case \"source\":\n if (message.revision <= document!.revision)\n return respond(response, 409, \"Stale revision\");\n document!.revision = message.revision;\n document!.source = message.source;\n void renderDocument(document!);\n break;\n case \"save\":\n if (!options.allowWrite)\n return respond(response, 403, \"Studio writes are not authorized\");\n assertWithinRoots(document!.path, roots);\n if (message.revision < document!.revision)\n return respond(response, 409, \"Stale revision\");\n writeFileSync(\n document!.path,\n message.source.endsWith(\"\\n\") ? message.source : `${message.source}\\n`,\n \"utf8\",\n );\n document!.source = readFileSync(document!.path, \"utf8\");\n document!.revision = message.revision;\n broadcast({\n version: 1,\n type: \"saved\",\n documentId: document!.id,\n revision: document!.revision,\n });\n break;\n case \"selection\":\n if (message.selection.graphElement && !message.selection.range) {\n const graph = renders.get(message.selection.documentId)?.graph;\n const collection =\n message.selection.graphElement.type === \"node\" ? graph?.nodes : graph?.edges;\n const element = collection?.find(\n (item) => item.id === message.selection.graphElement?.id,\n );\n if (element?.sourceRange) message.selection.range = element.sourceRange;\n }\n broadcast({ version: 1, type: \"selection\", selection: message.selection });\n break;\n case \"viewport\":\n broadcast({ version: 1, type: \"viewport\", viewport: message.viewport });\n break;\n case \"presentation\":\n presentation = message.presentation;\n broadcast({ version: 1, type: \"presentation\", presentation });\n void renderDocument(documents.get(activeDocumentId)!);\n break;\n }\n return respond(response, 204, \"\");\n }\n if (request.method === \"GET\" && url.pathname.startsWith(\"/__kdiagram/icons/\")) {\n return serveIconSubset(url, response);\n }\n if (request.method !== \"GET\") return respond(response, 405, \"Method not allowed\");\n const requestedPath =\n url.pathname === \"/\" ? \"index.html\" : decodeURIComponent(url.pathname.slice(1));\n const assetPath = resolve(browserRoot, requestedPath);\n assertWithinRoots(assetPath, [browserRoot]);\n if (!existsSync(assetPath) || !statSync(assetPath).isFile())\n return respond(response, 404, \"Not found\");\n response.writeHead(200, {\n \"Content-Type\": contentType(assetPath),\n \"Cache-Control\":\n requestedPath === \"index.html\" ? \"no-store\" : \"public, max-age=31536000, immutable\",\n \"Content-Security-Policy\":\n \"default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; font-src 'self'; img-src 'self' data:; connect-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'\",\n \"X-Content-Type-Options\": \"nosniff\",\n \"Referrer-Policy\": \"no-referrer\",\n ...(requestedPath === \"index.html\"\n ? { \"Set-Cookie\": `kdiagram_studio=${token}; HttpOnly; SameSite=Strict; Path=/` }\n : {}),\n });\n createReadStream(assetPath).pipe(response);\n } catch (error) {\n respond(response, 400, error instanceof Error ? error.message : String(error));\n }\n });\n\n const watchers = files.map((file) =>\n watch(file, { persistent: false }, () => {\n const document = [...documents.values()].find((item) => item.path === file);\n if (!document) return;\n const source = readFileSync(file, \"utf8\");\n if (source === document.source) return;\n document.source = source;\n document.revision += 1;\n broadcast({ version: 1, type: \"document\", reason: \"external\", ...document });\n void renderDocument(document);\n }),\n );\n const heartbeat = setInterval(() => {\n for (const client of clients) client.write(\": heartbeat\\n\\n\");\n }, 15_000);\n heartbeat.unref();\n\n await new Promise<void>((resolveListen, reject) => {\n server.once(\"error\", reject);\n server.listen(options.port ?? 0, \"127.0.0.1\", resolveListen);\n });\n const address = server.address();\n if (!address || typeof address === \"string\")\n throw new Error(\"Studio server did not bind a TCP port\");\n let resolveClosed!: () => void;\n const closed = new Promise<void>((resolvePromise) => (resolveClosed = resolvePromise));\n server.once(\"close\", resolveClosed);\n const close = async (): Promise<void> => {\n clearInterval(heartbeat);\n for (const watcher of watchers) watcher.close();\n for (const client of clients) client.end();\n await new Promise<void>((resolveClose, reject) =>\n server.close((error) => (error ? reject(error) : resolveClose())),\n );\n };\n return {\n url: `http://127.0.0.1:${address.port}/?token=${encodeURIComponent(token)}`,\n port: address.port,\n token,\n closed,\n close,\n };\n}\n\nexport async function openStudioBrowser(url: string): Promise<void> {\n const command =\n process.platform === \"darwin\"\n ? { executable: \"open\", args: [url] }\n : process.platform === \"win32\"\n ? { executable: \"cmd\", args: [\"/c\", \"start\", \"\", url] }\n : { executable: \"xdg-open\", args: [url] };\n const child = spawn(command.executable, command.args, { detached: true, stdio: \"ignore\" });\n child.unref();\n await new Promise<void>((resolveSpawn, reject) => {\n child.once(\"spawn\", resolveSpawn);\n child.once(\"error\", reject);\n });\n}\n\nfunction respond(response: ServerResponse, status: number, body: string): void {\n response.writeHead(status, {\n \"Content-Type\": \"text/plain; charset=utf-8\",\n \"X-Content-Type-Options\": \"nosniff\",\n });\n response.end(body);\n}\n\nasync function serveIconSubset(url: URL, response: ServerResponse): Promise<void> {\n const match = /^\\/__kdiagram\\/icons\\/([a-z0-9-]+)\\.json$/.exec(url.pathname);\n const names = parseIconNames(url.searchParams.get(\"icons\"));\n if (!match || !names) return respondJson(response, 400, { error: \"Invalid icon request\" });\n const subset = await loadIconSubset(match[1]!, names);\n if (!subset) return respondJson(response, 404, { error: \"Unknown icon collection\" });\n return respondJson(response, 200, subset);\n}\n\nfunction parseIconNames(value: string | null): string[] | null {\n if (!value) return null;\n const names = [...new Set(value.split(\",\"))];\n if (\n names.length === 0 ||\n names.length > MAX_ICONS_PER_REQUEST ||\n names.some((name) => !ICON_NAME.test(name))\n ) {\n return null;\n }\n return names;\n}\n\nfunction respondJson(response: ServerResponse, status: number, body: unknown): void {\n response.writeHead(status, {\n \"Content-Type\": \"application/json; charset=utf-8\",\n \"Cache-Control\": \"public, max-age=86400\",\n \"X-Content-Type-Options\": \"nosniff\",\n });\n response.end(JSON.stringify(body));\n}\n\nasync function readBody(request: IncomingMessage): Promise<string> {\n const chunks: Buffer[] = [];\n let bytes = 0;\n for await (const chunk of request) {\n const buffer = Buffer.from(chunk);\n bytes += buffer.byteLength;\n if (bytes > 2_000_000) throw new Error(\"Studio message exceeds 2 MB\");\n chunks.push(buffer);\n }\n return Buffer.concat(chunks).toString(\"utf8\");\n}\n\nfunction assertWithinRoots(path: string, roots: string[]): void {\n const absolute = resolve(path);\n if (!roots.some((root) => absolute === root || absolute.startsWith(`${resolve(root)}${sep}`))) {\n throw new Error(\"Path is outside the studio session roots\");\n }\n}\n\nfunction minimalRoots(directories: string[]): string[] {\n const sorted = [...new Set(directories.map((directory) => resolve(directory)))].sort();\n return sorted.filter(\n (directory, index) =>\n !sorted.some(\n (other, otherIndex) => otherIndex !== index && directory.startsWith(`${other}${sep}`),\n ),\n );\n}\n\nfunction commonRoot(files: string[]): string {\n let root = dirname(files[0]!);\n while (!files.every((file) => file === root || file.startsWith(`${root}${sep}`)))\n root = dirname(root);\n return root;\n}\n\nfunction contentType(path: string): string {\n switch (extname(path)) {\n case \".html\":\n return \"text/html; charset=utf-8\";\n case \".js\":\n return \"text/javascript; charset=utf-8\";\n case \".css\":\n return \"text/css; charset=utf-8\";\n case \".ttf\":\n return \"font/ttf\";\n case \".map\":\n return \"application/json\";\n default:\n return \"application/octet-stream\";\n }\n}\n","#!/usr/bin/env node\nimport { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n analyzeDiagramQuality,\n compileSource,\n getCapabilities,\n parseSource,\n renderPipeline,\n type Diagnostic,\n} from \"@kekonic/diagrams\";\nimport { KDiagramLanguageService } from \"@kekonic/diagrams-language-service\";\nimport { CliUsageError, parseCommand, type ParsedCommand } from \"./command-model.ts\";\nimport { shellCompletions } from \"./completions.ts\";\nimport { runDoctor } from \"./doctor.ts\";\nimport { readResolvedInput, resolveCommandInputs, type ResolvedInput } from \"./input-resolver.ts\";\nimport {\n createOutputContext,\n EXIT_DIAGNOSTICS,\n EXIT_OPERATIONAL,\n EXIT_SUCCESS,\n EXIT_USAGE,\n installPipeErrorHandlers,\n machineEnvelope,\n printDiagnostic,\n printProgress,\n printSummary,\n type OutputContext,\n} from \"./output.ts\";\nimport { renderOutputPaths } from \"./output-paths.ts\";\nimport { finalizePortableSvg } from \"./portable-svg.ts\";\nimport { resolveRenderSettings } from \"./project-config.ts\";\nimport { openStudioBrowser, startStudioServer } from \"./studio-server.ts\";\nimport { runLanguageServer } from \"./lsp-server.ts\";\n\nconst argv = process.argv.slice(2);\nconst languageService = new KDiagramLanguageService();\nlet activeCommand: ParsedCommand | undefined;\ninstallPipeErrorHandlers();\n\nfunction usage(stream: NodeJS.WritableStream = process.stdout): void {\n stream.write(`kdiagrams — deterministic text-to-diagram tooling\n\nCommon jobs:\n kdiagrams check .\n kdiagrams format diagrams/ --check\n kdiagrams render diagrams/ --out-dir public/diagrams\n kdiagrams render architecture.kdiagram -o architecture.svg --print-safe\n\nCommands:\n render [inputs...] Render portable SVG\n check [inputs...] Validate source and semantics\n analyze [inputs...] Analyze rendered layout quality as JSON\n capabilities Describe the active language and renderer as JSON\n format [inputs...] Format or check source\n studio [inputs...] Launch the local browser authoring studio\n lsp --stdio Run the Language Server Protocol over stdio\n ast [input] Emit a versioned AST envelope\n graph [input] Emit a versioned semantic-model envelope\n doctor Inspect runtime, font, config, and renderer health\n completions <shell> Print Bash, Zsh, or Fish completion source\n\nStudio:\n --no-open Start without opening the browser (opens by default)\n --allow-write Authorize saving resolved input files\n --port number Loopback port (default: random available port)\n\nInput discovery:\n --exclude pattern Git-ignore-style exclusion (repeatable)\n --ignore-file file Rules file (default: .kdiagramignore)\n --stdin-filename file Logical filename for piped diagram source\n --files-from file|- Read additional input paths, one per line\n\nPortable render output:\n -o, --output file Single output file\n --out-dir dir Batch output directory; preserves relative paths\n --output-template text Template using {path}, {dir}, {name}, and {ext}\n --theme name Built-in or configured theme\n --config file Project config (default: discovered kekonic-diagrams.config.json)\n --profile name Named export profile from config\n --theme-file file JSON custom-property token map\n --live-theme Retain host-resolved CSS variables (snapshot is default)\n --background mode transparent or theme\n --embed-fonts Embed bundled Inter in SVG\n --print-safe Light snapshot with explicit theme background\n\nHuman and machine output:\n --json Versioned JSON envelope (check/doctor)\n --pretty Pretty versioned JSON (ast/graph)\n --color mode auto, always, or never\n --quiet Suppress summaries and progress\n --verbose Include progress details\n --debug Include stack traces for operational failures\n -v, --version Print installed version\n -h, --help Show help\n\nExit status: 0 success, 1 source/check failure, 2 usage error, 3 operational failure.\n`);\n}\n\nfunction version(): string {\n const manifestPath = fileURLToPath(new URL(\"../package.json\", import.meta.url));\n const manifest = JSON.parse(readFileSync(manifestPath, \"utf-8\")) as { version?: string };\n return manifest.version ?? \"unknown\";\n}\n\nfunction printDiagnostics(\n context: OutputContext,\n diagnostics: readonly Diagnostic[],\n source: string,\n path: string,\n): void {\n for (const diagnostic of diagnostics) printDiagnostic(context, diagnostic, source, path);\n}\n\nasync function cmdRender(\n command: ParsedCommand,\n inputs: ResolvedInput[],\n context: OutputContext,\n): Promise<number> {\n const outputPaths = renderOutputPaths(command, inputs);\n const settings = resolveRenderSettings(command);\n for (const warning of settings.warnings) {\n if (!context.quiet) context.stderr.write(`warning[FMCLI101] ${warning}\\n`);\n }\n if (settings.configPath) printProgress(context, `Using config ${settings.configPath}`);\n if (settings.profileName) printProgress(context, `Using export profile ${settings.profileName}`);\n\n let failed = false;\n for (let index = 0; index < inputs.length; index++) {\n const input = inputs[index]!;\n const source = readResolvedInput(input);\n printProgress(context, `Rendering ${input.displayPath}`);\n const result = await renderPipeline(source, {\n theme: settings.theme,\n snapshotTheme: settings.snapshotTheme,\n presentation: settings.presentation,\n shadows: false,\n });\n printDiagnostics(context, result.diagnostics, source, input.displayPath);\n if (!result.ok || !result.svg) {\n failed = true;\n continue;\n }\n\n const svg = finalizePortableSvg(result.svg, settings);\n const outputPath = outputPaths[index];\n if (!outputPath) {\n process.stdout.write(svg);\n continue;\n }\n mkdirSync(dirname(outputPath), { recursive: true });\n writeFileSync(outputPath, svg, \"utf-8\");\n printSummary(context, `Wrote ${outputPath}`);\n }\n return failed ? EXIT_DIAGNOSTICS : EXIT_SUCCESS;\n}\n\nasync function cmdAnalyze(command: ParsedCommand, inputs: ResolvedInput[]): Promise<number> {\n const files = [];\n let errorCount = 0;\n let warningCount = 0;\n for (const input of inputs) {\n const source = readResolvedInput(input);\n const result = await renderPipeline(source, { shadows: false });\n const diagnostics = result.diagnostics;\n errorCount += diagnostics.filter((item) => item.severity === \"error\").length;\n warningCount += diagnostics.filter((item) => item.severity === \"warning\").length;\n files.push({\n path: input.displayPath,\n diagnostics,\n artifact:\n result.layout && result.graph && result.routing\n ? {\n ...analyzeDiagramQuality(result.graph, result.layout, result.routing.edges).metrics,\n nodes: result.stats.nodeCount,\n edges: result.stats.edgeCount,\n layoutAlgorithm: result.stats.layoutAlgorithm,\n routerAlgorithm: result.stats.routerAlgorithm,\n }\n : undefined,\n });\n }\n process.stdout.write(\n `${JSON.stringify(\n machineEnvelope(\"analyze\", {\n files,\n summary: { files: inputs.length, errors: errorCount, warnings: warningCount },\n }),\n null,\n command.options.pretty ? 2 : undefined,\n )}\\n`,\n );\n return errorCount > 0 ? EXIT_DIAGNOSTICS : EXIT_SUCCESS;\n}\n\nfunction cmdCheck(command: ParsedCommand, inputs: ResolvedInput[], context: OutputContext): number {\n const files: Array<{ path: string; diagnostics: Diagnostic[] }> = [];\n let errorCount = 0;\n let warningCount = 0;\n for (const input of inputs) {\n const source = readResolvedInput(input);\n const diagnostics = languageService.updateDocument(inputUri(input), source, 1).diagnostics;\n files.push({ path: input.displayPath, diagnostics });\n errorCount += diagnostics.filter((diagnostic) => diagnostic.severity === \"error\").length;\n warningCount += diagnostics.filter((diagnostic) => diagnostic.severity === \"warning\").length;\n if (!command.options.json) {\n printDiagnostics(context, diagnostics, source, input.displayPath);\n }\n }\n\n if (command.options.json) {\n process.stdout.write(\n `${JSON.stringify(\n machineEnvelope(\"check\", {\n files,\n summary: { files: inputs.length, errors: errorCount, warnings: warningCount },\n }),\n )}\\n`,\n );\n } else {\n printSummary(\n context,\n `${inputs.length} file(s): ${errorCount} error(s), ${warningCount} warning(s)`,\n );\n }\n return errorCount > 0 ? EXIT_DIAGNOSTICS : EXIT_SUCCESS;\n}\n\nfunction cmdInspect(\n command: ParsedCommand,\n inputs: ResolvedInput[],\n context: OutputContext,\n): number {\n requireSingleInput(command.name, inputs);\n const input = inputs[0]!;\n const source = readResolvedInput(input);\n if (command.name === \"ast\") {\n const result = parseSource(source);\n printDiagnostics(context, result.diagnostics, source, input.displayPath);\n writeInspectionEnvelope(command, input, result.ast, result.diagnostics);\n return result.diagnostics.some((diagnostic) => diagnostic.severity === \"error\")\n ? EXIT_DIAGNOSTICS\n : EXIT_SUCCESS;\n }\n const result = compileSource(source);\n printDiagnostics(context, result.diagnostics, source, input.displayPath);\n writeInspectionEnvelope(command, input, result.graph, result.diagnostics);\n return result.diagnostics.some((diagnostic) => diagnostic.severity === \"error\")\n ? EXIT_DIAGNOSTICS\n : EXIT_SUCCESS;\n}\n\nfunction writeInspectionEnvelope(\n command: ParsedCommand,\n input: ResolvedInput,\n data: unknown,\n diagnostics: readonly Diagnostic[],\n): void {\n process.stdout.write(\n `${JSON.stringify(\n machineEnvelope(command.name, {\n path: input.displayPath,\n data,\n diagnostics,\n }),\n null,\n command.options.pretty ? 2 : undefined,\n )}\\n`,\n );\n}\n\nfunction cmdFormat(\n command: ParsedCommand,\n inputs: ResolvedInput[],\n context: OutputContext,\n): number {\n if (command.options.output) requireSingleInput(command.name, inputs);\n if (!command.options.write && !command.options.check && !command.options.output) {\n requireSingleInput(command.name, inputs);\n }\n if (command.options.write && inputs.some((input) => input.kind === \"stdin\")) {\n throw new CliUsageError(\"--write cannot be used with stdin\");\n }\n\n let changed = false;\n for (const input of inputs) {\n const source = readResolvedInput(input);\n const uri = inputUri(input);\n languageService.updateDocument(uri, source, 1);\n const formatted = languageService.format(uri)[0]?.newText ?? source;\n if (command.options.check) {\n if (source !== formatted) {\n changed = true;\n context.stderr.write(`${input.displayPath}: not formatted\\n`);\n }\n continue;\n }\n\n const target = command.options.output\n ? resolve(command.options.output)\n : command.options.write\n ? input.absolutePath\n : undefined;\n if (target) {\n mkdirSync(dirname(target), { recursive: true });\n writeFileSync(target, formatted, \"utf-8\");\n printSummary(context, `Wrote ${target}`);\n } else {\n process.stdout.write(formatted);\n }\n }\n return changed ? EXIT_DIAGNOSTICS : EXIT_SUCCESS;\n}\n\nfunction cmdDoctor(command: ParsedCommand, context: OutputContext): number {\n const checks = runDoctor();\n if (command.options.json) {\n process.stdout.write(`${JSON.stringify(machineEnvelope(\"doctor\", { checks }))}\\n`);\n } else {\n for (const check of checks) {\n context.stderr.write(\n `${check.status.toUpperCase().padEnd(4)} ${check.name}: ${check.detail}\\n`,\n );\n }\n }\n return checks.some((check) => check.status === \"fail\") ? EXIT_OPERATIONAL : EXIT_SUCCESS;\n}\n\nfunction requireSingleInput(command: string, inputs: readonly ResolvedInput[]): void {\n if (inputs.length !== 1) {\n throw new CliUsageError(\n `${command} requires exactly one resolved input; received ${inputs.length}`,\n );\n }\n}\n\nasync function main(): Promise<number> {\n if (argv.includes(\"-v\") || argv.includes(\"--version\")) {\n process.stdout.write(`${version()}\\n`);\n return EXIT_SUCCESS;\n }\n if (argv.includes(\"-h\") || argv.includes(\"--help\")) {\n usage();\n return EXIT_SUCCESS;\n }\n if (argv.length === 0) {\n usage(process.stderr);\n return EXIT_USAGE;\n }\n\n const command = parseCommand(argv);\n activeCommand = command;\n const context = createOutputContext(command.options);\n if (command.name === \"completions\") {\n if (command.inputs.length !== 1) throw new CliUsageError(\"completions requires one shell\");\n process.stdout.write(shellCompletions(command.inputs[0]));\n return EXIT_SUCCESS;\n }\n if (command.name === \"doctor\") {\n if (command.inputs.length > 0) throw new CliUsageError(\"doctor does not accept inputs\");\n return cmdDoctor(command, context);\n }\n if (command.name === \"capabilities\") {\n if (command.inputs.length > 0) throw new CliUsageError(\"capabilities does not accept inputs\");\n process.stdout.write(\n `${JSON.stringify(machineEnvelope(\"capabilities\", getCapabilities()), null, command.options.pretty ? 2 : undefined)}\\n`,\n );\n return EXIT_SUCCESS;\n }\n if (command.name === \"lsp\") {\n if (command.inputs.length !== 0) throw new CliUsageError(\"lsp does not accept inputs\");\n return runLanguageServer();\n }\n\n if (command.name === \"studio\") {\n const studioCommand = command.inputs.length === 0 ? { ...command, inputs: [\".\"] } : command;\n const studioInputs = resolveCommandInputs(studioCommand);\n if (studioInputs.some((input) => input.kind === \"stdin\" || !input.absolutePath)) {\n throw new CliUsageError(\"studio accepts files, directories, and globs, not stdin\");\n }\n const server = await startStudioServer({\n files: studioInputs.map((input) => input.absolutePath!),\n allowWrite: command.options.allowWrite,\n port: Number(command.options.port ?? 0),\n });\n context.stderr.write(`Kekonic Diagrams Studio: ${server.url}\\n`);\n if (!command.options.noOpen) await openStudioBrowser(server.url);\n await server.closed;\n return EXIT_SUCCESS;\n }\n\n const inputs = resolveCommandInputs(command);\n switch (command.name) {\n case \"render\":\n return cmdRender(command, inputs, context);\n case \"check\":\n return cmdCheck(command, inputs, context);\n case \"analyze\":\n return cmdAnalyze(command, inputs);\n case \"ast\":\n case \"graph\":\n return cmdInspect(command, inputs, context);\n case \"format\":\n return cmdFormat(command, inputs, context);\n }\n}\n\nmain()\n .then((exitCode) => {\n process.exitCode = exitCode;\n })\n .catch((error: unknown) => {\n if (error instanceof CliUsageError) {\n process.stderr.write(`${error.message}\\n`);\n process.exitCode = EXIT_USAGE;\n return;\n }\n const message = operationalMessage(error);\n process.stderr.write(`Operational error: ${message}\\n`);\n if (activeCommand?.options.debug && error instanceof Error && error.stack) {\n process.stderr.write(`${error.stack}\\n`);\n }\n process.exitCode = EXIT_OPERATIONAL;\n });\n\nfunction operationalMessage(error: unknown): string {\n if (error instanceof Error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\")\n return `File not found: ${(error as NodeJS.ErrnoException).path ?? error.message}`;\n if (code === \"EACCES\")\n return `Permission denied: ${(error as NodeJS.ErrnoException).path ?? error.message}`;\n return error.message;\n }\n return String(error);\n}\n\nfunction inputUri(input: ResolvedInput): string {\n return input.absolutePath ? `file://${input.absolutePath}` : `stdin://${input.displayPath}`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.mjs","names":["COMMANDS","require","require"],"sources":["../src/command-model.ts","../src/completions.ts","../src/project-config.ts","../src/doctor.ts","../src/input-resolver.ts","../src/output.ts","../src/output-paths.ts","../src/portable-svg.ts","../src/studio-server.ts","../src/cli.ts"],"sourcesContent":["export type CommandName =\n | \"render\"\n | \"check\"\n | \"analyze\"\n | \"capabilities\"\n | \"ast\"\n | \"graph\"\n | \"format\"\n | \"studio\"\n | \"lsp\"\n | \"doctor\"\n | \"completions\";\n\nexport type ColorMode = \"auto\" | \"always\" | \"never\";\n\nexport type CommandOptions = {\n output?: string;\n outDir?: string;\n outputTemplate?: string;\n theme?: string;\n snapshot: boolean;\n liveTheme: boolean;\n config?: string;\n profile?: string;\n themeFile?: string;\n background?: \"transparent\" | \"theme\";\n embedFonts: boolean;\n printSafe: boolean;\n open: boolean;\n noOpen: boolean;\n allowWrite: boolean;\n stdio: boolean;\n port?: string;\n color: ColorMode;\n quiet: boolean;\n verbose: boolean;\n debug: boolean;\n json: boolean;\n pretty: boolean;\n write: boolean;\n check: boolean;\n excludes: string[];\n ignoreFile?: string;\n stdinFilename?: string;\n filesFrom?: string;\n view?: string;\n diagramIndex?: string;\n};\n\nexport type ParsedCommand = {\n name: CommandName;\n inputs: string[];\n options: CommandOptions;\n};\n\nexport class CliUsageError extends Error {\n readonly exitCode = 2;\n}\n\nconst COMMANDS = new Set<CommandName>([\n \"render\",\n \"check\",\n \"analyze\",\n \"capabilities\",\n \"ast\",\n \"graph\",\n \"format\",\n \"studio\",\n \"lsp\",\n \"doctor\",\n \"completions\",\n]);\n\nconst VALUE_OPTIONS = new Map<\n string,\n | \"output\"\n | \"outDir\"\n | \"outputTemplate\"\n | \"theme\"\n | \"exclude\"\n | \"ignoreFile\"\n | \"stdinFilename\"\n | \"filesFrom\"\n | \"color\"\n | \"config\"\n | \"profile\"\n | \"themeFile\"\n | \"background\"\n | \"port\"\n | \"view\"\n | \"diagramIndex\"\n>([\n [\"-o\", \"output\"],\n [\"--output\", \"output\"],\n [\"--out-dir\", \"outDir\"],\n [\"--output-template\", \"outputTemplate\"],\n [\"--theme\", \"theme\"],\n [\"--exclude\", \"exclude\"],\n [\"--ignore-file\", \"ignoreFile\"],\n [\"--stdin-filename\", \"stdinFilename\"],\n [\"--files-from\", \"filesFrom\"],\n [\"--color\", \"color\"],\n [\"--config\", \"config\"],\n [\"--profile\", \"profile\"],\n [\"--theme-file\", \"themeFile\"],\n [\"--background\", \"background\"],\n [\"--port\", \"port\"],\n [\"--view\", \"view\"],\n [\"--diagram-index\", \"diagramIndex\"],\n] as const);\n\nconst BOOLEAN_OPTIONS = new Map<\n string,\n | \"snapshot\"\n | \"liveTheme\"\n | \"json\"\n | \"pretty\"\n | \"write\"\n | \"check\"\n | \"quiet\"\n | \"verbose\"\n | \"debug\"\n | \"embedFonts\"\n | \"printSafe\"\n | \"open\"\n | \"noOpen\"\n | \"allowWrite\"\n | \"stdio\"\n>([\n [\"--snapshot\", \"snapshot\"],\n [\"--live-theme\", \"liveTheme\"],\n [\"--json\", \"json\"],\n [\"--pretty\", \"pretty\"],\n [\"--write\", \"write\"],\n [\"--check\", \"check\"],\n [\"--quiet\", \"quiet\"],\n [\"--verbose\", \"verbose\"],\n [\"--debug\", \"debug\"],\n [\"--embed-fonts\", \"embedFonts\"],\n [\"--print-safe\", \"printSafe\"],\n [\"--open\", \"open\"],\n [\"--no-open\", \"noOpen\"],\n [\"--allow-write\", \"allowWrite\"],\n [\"--stdio\", \"stdio\"],\n] as const);\n\nconst DISCOVERY = [\"exclude\", \"ignoreFile\", \"stdinFilename\", \"filesFrom\"];\nconst PRESENTATION = [\"color\", \"quiet\", \"verbose\", \"debug\"];\n\nconst ALLOWED_OPTIONS: Record<CommandName, ReadonlySet<string>> = {\n render: new Set([\n \"output\",\n \"outDir\",\n \"outputTemplate\",\n \"theme\",\n \"snapshot\",\n \"liveTheme\",\n \"config\",\n \"profile\",\n \"themeFile\",\n \"background\",\n \"embedFonts\",\n \"printSafe\",\n \"view\",\n \"diagramIndex\",\n ...DISCOVERY,\n ...PRESENTATION,\n ]),\n check: new Set([\"json\", \"view\", \"diagramIndex\", ...DISCOVERY, ...PRESENTATION]),\n analyze: new Set([\"json\", \"pretty\", \"view\", \"diagramIndex\", ...DISCOVERY, ...PRESENTATION]),\n capabilities: new Set([\"pretty\"]),\n ast: new Set([\"pretty\", \"json\", ...DISCOVERY, ...PRESENTATION]),\n graph: new Set([\"pretty\", \"json\", \"view\", \"diagramIndex\", ...DISCOVERY, ...PRESENTATION]),\n format: new Set([\"output\", \"write\", \"check\", ...DISCOVERY, ...PRESENTATION]),\n studio: new Set([\"open\", \"noOpen\", \"allowWrite\", \"port\", ...DISCOVERY, ...PRESENTATION]),\n lsp: new Set([\"stdio\"]),\n doctor: new Set([\"json\", ...PRESENTATION]),\n completions: new Set([]),\n};\n\nfunction defaults(): CommandOptions {\n return {\n snapshot: false,\n liveTheme: false,\n color: \"auto\",\n quiet: false,\n verbose: false,\n debug: false,\n embedFonts: false,\n printSafe: false,\n open: false,\n noOpen: false,\n allowWrite: false,\n stdio: false,\n json: false,\n pretty: false,\n write: false,\n check: false,\n excludes: [],\n };\n}\n\nfunction optionParts(raw: string): { flag: string; inlineValue?: string } {\n if (!raw.startsWith(\"--\")) return { flag: raw };\n const equals = raw.indexOf(\"=\");\n return equals < 0\n ? { flag: raw }\n : { flag: raw.slice(0, equals), inlineValue: raw.slice(equals + 1) };\n}\n\nexport function parseCommand(argv: readonly string[]): ParsedCommand {\n const name = argv[0];\n if (!COMMANDS.has(name as CommandName)) {\n const suggestion = name ? nearest(name, [...COMMANDS]) : undefined;\n throw new CliUsageError(\n name\n ? `Unknown command: ${name}${suggestion ? `. Did you mean ${suggestion}?` : \"\"}`\n : \"Missing command\",\n );\n }\n\n const command = name as CommandName;\n const inputs: string[] = [];\n const options = defaults();\n let positionalOnly = false;\n\n for (let index = 1; index < argv.length; index++) {\n const raw = argv[index]!;\n if (raw === \"--\" && !positionalOnly) {\n positionalOnly = true;\n continue;\n }\n if (raw === \"-\" || positionalOnly || !raw.startsWith(\"-\")) {\n inputs.push(raw);\n continue;\n }\n\n const { flag, inlineValue } = optionParts(raw);\n const valueKey = VALUE_OPTIONS.get(flag);\n const booleanKey = BOOLEAN_OPTIONS.get(flag);\n const allowed = ALLOWED_OPTIONS[command];\n\n if (valueKey) {\n if (!allowed.has(valueKey)) throw new CliUsageError(`Unknown option for ${command}: ${flag}`);\n const value = inlineValue ?? argv[++index];\n if (!value || (inlineValue == null && value.startsWith(\"-\") && value !== \"-\")) {\n throw new CliUsageError(`Missing value for ${flag}`);\n }\n if (valueKey === \"exclude\") options.excludes.push(value);\n else if (valueKey === \"color\") {\n if (value !== \"auto\" && value !== \"always\" && value !== \"never\") {\n throw new CliUsageError(\n `Invalid --color value: ${value} (expected auto, always, or never)`,\n );\n }\n options.color = value;\n } else if (valueKey === \"background\") {\n if (value !== \"transparent\" && value !== \"theme\") {\n throw new CliUsageError(\n `Invalid --background value: ${value} (expected transparent or theme)`,\n );\n }\n options.background = value;\n } else if (valueKey === \"theme\") {\n options.theme = value;\n } else {\n options[valueKey] = value;\n }\n continue;\n }\n\n if (booleanKey) {\n if (inlineValue != null) throw new CliUsageError(`${flag} does not accept a value`);\n if (!allowed.has(booleanKey)) {\n throw new CliUsageError(`Unknown option for ${command}: ${flag}`);\n }\n options[booleanKey] = true;\n continue;\n }\n\n const candidates = [...VALUE_OPTIONS.keys(), ...BOOLEAN_OPTIONS.keys(), \"--help\", \"--version\"];\n const suggestion = nearest(flag, candidates);\n throw new CliUsageError(\n `Unknown option: ${flag}${suggestion ? `. Did you mean ${suggestion}?` : \"\"}`,\n );\n }\n\n validateOptions(command, options);\n return { name: command, inputs, options };\n}\n\nfunction nearest(value: string, candidates: readonly string[]): string | undefined {\n let best: { value: string; distance: number } | undefined;\n for (const candidate of candidates) {\n const distance = editDistance(value, candidate);\n if (!best || distance < best.distance) best = { value: candidate, distance };\n }\n return best && best.distance <= Math.max(2, Math.floor(value.length / 3))\n ? best.value\n : undefined;\n}\n\nfunction editDistance(left: string, right: string): number {\n const previous = Array.from({ length: right.length + 1 }, (_, index) => index);\n for (let i = 1; i <= left.length; i++) {\n const current = [i];\n for (let j = 1; j <= right.length; j++) {\n current[j] = Math.min(\n current[j - 1]! + 1,\n previous[j]! + 1,\n previous[j - 1]! + (left[i - 1] === right[j - 1] ? 0 : 1),\n );\n }\n previous.splice(0, previous.length, ...current);\n }\n return previous[right.length]!;\n}\n\nfunction validateOptions(command: CommandName, options: CommandOptions): void {\n if (command === \"render\") {\n const destinations = [options.output, options.outDir, options.outputTemplate].filter(Boolean);\n if (options.output && destinations.length > 1) {\n throw new CliUsageError(\"--output cannot be combined with --out-dir or --output-template\");\n }\n if (options.snapshot && options.liveTheme) {\n throw new CliUsageError(\"--snapshot and --live-theme cannot be combined\");\n }\n }\n if (command === \"format\") {\n if (options.write && options.check) {\n throw new CliUsageError(\"--write and --check cannot be combined\");\n }\n if (options.output && (options.write || options.check)) {\n throw new CliUsageError(\"--output cannot be combined with --write or --check\");\n }\n }\n if (command === \"studio\") {\n if (options.open && options.noOpen) {\n throw new CliUsageError(\"--open and --no-open cannot be combined\");\n }\n if (options.port != null && (!/^\\d+$/.test(options.port) || Number(options.port) > 65535)) {\n throw new CliUsageError(\"--port must be an integer from 0 to 65535\");\n }\n }\n if (command === \"lsp\" && !options.stdio) {\n throw new CliUsageError(\"lsp requires --stdio\");\n }\n if (options.quiet && options.verbose) {\n throw new CliUsageError(\"--quiet and --verbose cannot be combined\");\n }\n if (command === \"completions\" && options.excludes.length > 0) {\n throw new CliUsageError(\"completions does not accept discovery options\");\n }\n}\n","import { CliUsageError } from \"./command-model.ts\";\n\nconst COMMANDS = \"render check analyze capabilities format studio lsp ast graph doctor completions\";\nconst OPTIONS =\n \"--help --version --color --quiet --verbose --debug --exclude --ignore-file --stdin-filename --files-from --output --out-dir --output-template --theme --theme-file --config --profile --live-theme --snapshot --background --embed-fonts --print-safe --json --pretty --check --write --open --no-open --allow-write --port --stdio --view --diagram-index\";\n\nexport function shellCompletions(shell: string | undefined): string {\n switch (shell) {\n case \"bash\":\n return `# Kekonic Diagrams completion\\n_kdiagrams() {\\n local cur=\"\\${COMP_WORDS[COMP_CWORD]}\"\\n COMPREPLY=( $(compgen -W \"${COMMANDS} ${OPTIONS}\" -- \"$cur\") )\\n}\\ncomplete -F _kdiagrams kdiagrams\\n`;\n case \"zsh\":\n return `#compdef kdiagrams\\n_arguments '1:command:(${COMMANDS})' '*:option:(${OPTIONS})'\\n`;\n case \"fish\":\n return `${COMMANDS.split(\" \")\n .map((command) => `complete -c kdiagrams -f -n '__fish_use_subcommand' -a '${command}'`)\n .join(\"\\n\")}\\n`;\n default:\n throw new CliUsageError(\"completions requires one shell: bash, zsh, or fish\");\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, parse, resolve } from \"node:path\";\nimport { registerTheme, type PresentationOptions } from \"@kekonic/diagrams\";\nimport { CliUsageError, type ParsedCommand } from \"./command-model.ts\";\n\nconst DEFAULT_CONFIG = \"kekonic-diagrams.config.json\";\n\nexport type ExportProfile = {\n theme?: string;\n snapshotTheme?: boolean;\n background?: \"transparent\" | \"theme\";\n embedFonts?: boolean;\n printSafe?: boolean;\n presentation?: PresentationOptions;\n format?: \"svg\" | \"png\" | \"pdf\";\n};\n\nexport type ProjectConfig = {\n version: 1;\n defaultProfile?: string;\n themes?: Record<string, Record<string, string>>;\n profiles?: Record<string, ExportProfile>;\n};\n\nexport type ResolvedRenderSettings = Required<\n Pick<ExportProfile, \"theme\" | \"snapshotTheme\" | \"background\" | \"embedFonts\" | \"printSafe\">\n> & {\n presentation?: PresentationOptions;\n configPath?: string;\n profileName?: string;\n warnings: string[];\n};\n\nexport function resolveRenderSettings(\n command: ParsedCommand,\n cwd = process.cwd(),\n): ResolvedRenderSettings {\n const loaded = loadProjectConfig(command.options.config, cwd);\n const config = loaded?.config;\n const configDir = loaded ? dirname(loaded.path) : cwd;\n\n for (const [name, tokens] of Object.entries(config?.themes ?? {})) {\n validateTokens(tokens, `themes.${name}`);\n registerTheme(name, tokens);\n }\n if (command.options.themeFile) {\n const themePath = resolve(configDir, command.options.themeFile);\n const parsed = readJson(themePath);\n const name = command.options.theme ?? \"custom\";\n const tokens = isRecord(parsed) && isRecord(parsed.tokens) ? parsed.tokens : parsed;\n validateTokens(tokens, themePath);\n registerTheme(name, tokens);\n }\n\n const profileName = command.options.profile ?? config?.defaultProfile;\n const profile = profileName ? config?.profiles?.[profileName] : undefined;\n if (profileName && !profile) {\n throw new CliUsageError(`Unknown export profile: ${profileName}`);\n }\n if (profile?.format && profile.format !== \"svg\") {\n throw new CliUsageError(\n `Export profile ${profileName} requests ${profile.format}; this CLI build supports SVG output`,\n );\n }\n\n const printSafe = command.options.printSafe || profile?.printSafe === true;\n const snapshotTheme = command.options.liveTheme\n ? false\n : command.options.snapshot || profile?.snapshotTheme !== false;\n const settings: ResolvedRenderSettings = {\n theme: command.options.theme ?? profile?.theme ?? (printSafe ? \"light\" : \"dark\"),\n snapshotTheme,\n background:\n command.options.background ?? profile?.background ?? (printSafe ? \"theme\" : \"transparent\"),\n embedFonts: command.options.embedFonts || profile?.embedFonts === true,\n printSafe,\n presentation: profile?.presentation,\n configPath: loaded?.path,\n profileName,\n warnings: [],\n };\n if (!snapshotTheme) {\n settings.warnings.push(\n \"live-theme SVG retains unresolved CSS custom properties and requires KDiagram theme tokens from its host\",\n );\n }\n return settings;\n}\n\nexport function findProjectConfig(cwd: string): string | undefined {\n let current = resolve(cwd);\n const root = parse(current).root;\n while (true) {\n const candidate = join(current, DEFAULT_CONFIG);\n if (existsSync(candidate)) return candidate;\n if (current === root) return undefined;\n current = dirname(current);\n }\n}\n\nfunction loadProjectConfig(\n explicitPath: string | undefined,\n cwd: string,\n): { path: string; config: ProjectConfig } | undefined {\n const path = explicitPath\n ? isAbsolute(explicitPath)\n ? explicitPath\n : resolve(cwd, explicitPath)\n : findProjectConfig(cwd);\n if (!path) return undefined;\n if (!existsSync(path)) throw new CliUsageError(`Config file does not exist: ${path}`);\n const parsed = readJson(path);\n if (!isRecord(parsed) || parsed.version !== 1) {\n throw new CliUsageError(`${path}: expected { \"version\": 1, ... }`);\n }\n validateConfigKeys(parsed, path);\n return { path, config: parsed as ProjectConfig };\n}\n\nfunction validateConfigKeys(value: Record<string, unknown>, path: string): void {\n const allowed = new Set([\"version\", \"defaultProfile\", \"themes\", \"profiles\", \"$schema\"]);\n for (const key of Object.keys(value)) {\n if (!allowed.has(key)) throw new CliUsageError(`${path}: unknown config property ${key}`);\n }\n if (value.profiles != null && !isRecord(value.profiles)) {\n throw new CliUsageError(`${path}: profiles must be an object`);\n }\n for (const [name, profile] of Object.entries((value.profiles as object | undefined) ?? {})) {\n if (!isRecord(profile)) throw new CliUsageError(`${path}: profile ${name} must be an object`);\n const profileKeys = new Set([\n \"theme\",\n \"snapshotTheme\",\n \"background\",\n \"embedFonts\",\n \"printSafe\",\n \"presentation\",\n \"format\",\n ]);\n for (const key of Object.keys(profile)) {\n if (!profileKeys.has(key)) {\n throw new CliUsageError(`${path}: unknown profiles.${name}.${key}`);\n }\n }\n }\n}\n\nfunction readJson(path: string): unknown {\n try {\n return JSON.parse(readFileSync(path, \"utf8\"));\n } catch (error) {\n throw new CliUsageError(\n `${path}: ${error instanceof Error ? error.message : \"could not read JSON\"}`,\n );\n }\n}\n\nfunction validateTokens(value: unknown, label: string): asserts value is Record<string, string> {\n if (!isRecord(value)) throw new CliUsageError(`${label}: theme tokens must be an object`);\n for (const [key, token] of Object.entries(value)) {\n if (!/^--[a-zA-Z0-9_-]+$/.test(key) || typeof token !== \"string\") {\n throw new CliUsageError(`${label}: theme tokens must map --custom-properties to strings`);\n }\n if (/[;{}<>@]/.test(token) || /url\\s*\\(/i.test(token)) {\n throw new CliUsageError(`${label}.${key}: theme token contains unsupported CSS syntax`);\n }\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n","import { existsSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { findProjectConfig } from \"./project-config.ts\";\n\nconst require = createRequire(import.meta.url);\n\nexport type DoctorCheck = {\n name: string;\n status: \"pass\" | \"warn\" | \"fail\";\n detail: string;\n};\n\nexport function runDoctor(cwd = process.cwd()): DoctorCheck[] {\n const nodeMajor = Number(process.versions.node.split(\".\")[0]);\n const config = findProjectConfig(cwd);\n let font = \"unavailable\";\n try {\n const path = require.resolve(\"@fontsource/inter/files/inter-latin-500-normal.woff\");\n if (existsSync(path)) font = path;\n } catch {\n // Reported as a structured failure below.\n }\n return [\n {\n name: \"runtime\",\n status: nodeMajor >= 22 ? \"pass\" : \"fail\",\n detail: `Node ${process.versions.node} (requires >=22.18.0)`,\n },\n {\n name: \"font\",\n status: font === \"unavailable\" ? \"fail\" : \"pass\",\n detail:\n font === \"unavailable\"\n ? \"Bundled Inter measurement font not found\"\n : \"Bundled Inter font available\",\n },\n {\n name: \"config\",\n status: config ? \"pass\" : \"warn\",\n detail:\n config ?? \"No kekonic-diagrams.config.json discovered; built-in export defaults apply\",\n },\n {\n name: \"renderer\",\n status: \"pass\",\n detail: \"SVG renderer available; portable snapshot export is the default\",\n },\n ];\n}\n","import { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { basename, dirname, extname, isAbsolute, relative, resolve, sep } from \"node:path\";\nimport type { Ignore } from \"ignore\";\nimport { globSync, isDynamicPattern } from \"tinyglobby\";\nimport { CliUsageError, type ParsedCommand } from \"./command-model.ts\";\n\nconst SOURCE_EXTENSION = \".kdiagram\";\nconst DEFAULT_IGNORE_FILE = \".kdiagramignore\";\nconst CRAWL_IGNORES = [\"**/.git/**\", \"**/node_modules/**\"];\nconst require = createRequire(import.meta.url);\n// `ignore` v5 is CommonJS; createRequire preserves its callable runtime export under NodeNext.\nconst createIgnore = require(\"ignore\") as () => Ignore;\n\nexport type ResolvedInput = {\n kind: \"file\" | \"stdin\";\n absolutePath?: string;\n displayPath: string;\n relativePath: string;\n source?: string;\n};\n\nexport type ResolveInputOptions = {\n cwd?: string;\n stdinIsTTY?: boolean;\n readStdin?: () => string;\n};\n\ntype Candidate = { absolutePath: string; relativePath: string };\n\nexport function resolveCommandInputs(\n command: ParsedCommand,\n options: ResolveInputOptions = {},\n): ResolvedInput[] {\n const cwd = resolve(options.cwd ?? process.cwd());\n const readStdin = options.readStdin ?? (() => readFileSync(0, \"utf-8\"));\n const requested = [...command.inputs];\n\n if (command.options.filesFrom) {\n const listSource = command.options.filesFrom;\n let pathList: string;\n if (listSource === \"-\") {\n if (requested.includes(\"-\")) {\n throw new CliUsageError(\"stdin cannot contain both diagram source and --files-from paths\");\n }\n pathList = readStdin();\n } else {\n pathList = readFileSync(resolve(cwd, listSource), \"utf-8\");\n }\n requested.push(...parsePathList(pathList));\n }\n\n if (requested.length === 0) {\n if (command.options.filesFrom) {\n throw new CliUsageError(\"--files-from did not provide any input paths\");\n }\n if (options.stdinIsTTY ?? process.stdin.isTTY) {\n throw new CliUsageError(\"Missing input (pass a path, '-' or pipe diagram source on stdin)\");\n }\n requested.push(\"-\");\n }\n\n const files: Candidate[] = [];\n let stdinInput: ResolvedInput | undefined;\n for (const input of requested) {\n if (input === \"-\") {\n if (stdinInput) throw new CliUsageError(\"stdin source may be supplied only once\");\n const filename = command.options.stdinFilename;\n const absolutePath = filename ? resolve(cwd, filename) : undefined;\n stdinInput = {\n kind: \"stdin\",\n absolutePath,\n displayPath: filename ?? \"<stdin>\",\n relativePath: filename ? portableRelativePath(cwd, absolutePath!) : \"stdin.kdiagram\",\n source: readStdin(),\n };\n continue;\n }\n files.push(...expandInput(input, cwd));\n }\n\n const filtered = filterIgnoredFiles(\n files,\n cwd,\n command.options.ignoreFile,\n command.options.excludes,\n );\n const unique = new Map<string, Candidate>();\n for (const candidate of filtered) unique.set(resolve(candidate.absolutePath), candidate);\n const resolvedFiles = [...unique.values()]\n .sort((left, right) => comparePaths(left.absolutePath, right.absolutePath))\n .map<ResolvedInput>(({ absolutePath, relativePath }) => ({\n kind: \"file\",\n absolutePath,\n displayPath: absolutePath,\n relativePath,\n }));\n const result = stdinInput ? [...resolvedFiles, stdinInput] : resolvedFiles;\n if (result.length === 0) throw new CliUsageError(\"No .kdiagram input files matched\");\n return result;\n}\n\nexport function readResolvedInput(input: ResolvedInput): string {\n if (input.kind === \"stdin\") return input.source ?? \"\";\n return readFileSync(input.absolutePath!, \"utf-8\");\n}\n\nfunction expandInput(input: string, cwd: string): Candidate[] {\n const absolute = resolve(cwd, input);\n if (existsSync(absolute)) {\n const stats = statSync(absolute);\n if (stats.isDirectory()) {\n const matches = globSync(\"**/*.kdiagram\", {\n cwd: absolute,\n absolute: true,\n dot: true,\n followSymbolicLinks: false,\n ignore: CRAWL_IGNORES,\n });\n const insideCwd = isWithin(cwd, absolute);\n return matches.map((file) => ({\n absolutePath: file,\n relativePath: insideCwd\n ? portableRelativePath(cwd, file)\n : toPosix(relative(absolute, file)),\n }));\n }\n if (!stats.isFile()) throw new CliUsageError(`Input is not a file or directory: ${input}`);\n if (extname(absolute).toLowerCase() !== SOURCE_EXTENSION) {\n throw new CliUsageError(`Input file must end in ${SOURCE_EXTENSION}: ${input}`);\n }\n return [{ absolutePath: absolute, relativePath: portableRelativePath(cwd, absolute) }];\n }\n\n if (!isDynamicPattern(input)) throw new CliUsageError(`Input path does not exist: ${input}`);\n return globSync(input, {\n cwd,\n absolute: true,\n dot: true,\n followSymbolicLinks: false,\n onlyFiles: true,\n ignore: CRAWL_IGNORES,\n })\n .filter((file) => extname(file).toLowerCase() === SOURCE_EXTENSION)\n .map((file) => ({\n absolutePath: file,\n relativePath: portableRelativePath(cwd, file),\n }));\n}\n\nfunction filterIgnoredFiles(\n files: readonly Candidate[],\n cwd: string,\n ignoreFileOption: string | undefined,\n excludes: readonly string[],\n): Candidate[] {\n const ignoreFile = resolve(cwd, ignoreFileOption ?? DEFAULT_IGNORE_FILE);\n const ignoreRoot = dirname(ignoreFile);\n const ignoreMatcher = existsSync(ignoreFile)\n ? createIgnore().add(readFileSync(ignoreFile, \"utf-8\"))\n : undefined;\n const excludeMatcher = excludes.length > 0 ? createIgnore().add(excludes) : undefined;\n if (!ignoreMatcher && !excludeMatcher) return [...files];\n\n return files.filter((candidate) => {\n if (ignoreMatcher && isWithin(ignoreRoot, candidate.absolutePath)) {\n const ignoredPath = toPosix(relative(ignoreRoot, candidate.absolutePath));\n if (ignoreMatcher.ignores(ignoredPath)) return false;\n }\n return !excludeMatcher?.ignores(candidate.relativePath);\n });\n}\n\nfunction isWithin(parent: string, child: string): boolean {\n const rel = relative(parent, child);\n return !rel.startsWith(`..${sep}`) && !isAbsolute(rel);\n}\n\nfunction parsePathList(contents: string): string[] {\n return contents\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0 && !line.startsWith(\"#\"));\n}\n\nfunction portableRelativePath(cwd: string, absolutePath: string): string {\n const rel = relative(cwd, absolutePath);\n if (!rel || rel.startsWith(`..${sep}`) || isAbsolute(rel)) return basename(absolutePath);\n return toPosix(rel);\n}\n\nfunction toPosix(path: string): string {\n return path.split(sep).join(\"/\");\n}\n\nfunction comparePaths(left: string, right: string): number {\n const a = toPosix(left);\n const b = toPosix(right);\n return a < b ? -1 : a > b ? 1 : 0;\n}\n","import type { Diagnostic } from \"@kekonic/diagrams\";\nimport type { ColorMode, CommandOptions } from \"./command-model.ts\";\n\nexport const EXIT_SUCCESS = 0;\nexport const EXIT_DIAGNOSTICS = 1;\nexport const EXIT_USAGE = 2;\nexport const EXIT_OPERATIONAL = 3;\nexport const MACHINE_OUTPUT_VERSION = 1;\n\ntype Writable = Pick<NodeJS.WritableStream, \"write\"> & { isTTY?: boolean };\n\nexport type OutputContext = {\n color: boolean;\n quiet: boolean;\n verbose: boolean;\n debug: boolean;\n stderr: Writable;\n};\n\nexport function createOutputContext(\n options: Pick<CommandOptions, \"color\" | \"quiet\" | \"verbose\" | \"debug\">,\n stderr: Writable = process.stderr,\n env: NodeJS.ProcessEnv = process.env,\n): OutputContext {\n return {\n color: shouldUseColor(options.color, stderr.isTTY === true, env),\n quiet: options.quiet,\n verbose: options.verbose,\n debug: options.debug,\n stderr,\n };\n}\n\nexport function shouldUseColor(mode: ColorMode, isTTY: boolean, env: NodeJS.ProcessEnv): boolean {\n if (mode === \"always\") return true;\n if (mode === \"never\") return false;\n if (env.NO_COLOR != null || env.FORCE_COLOR === \"0\") return false;\n if (env.FORCE_COLOR != null) return true;\n return isTTY;\n}\n\nexport function printDiagnostic(\n context: OutputContext,\n diagnostic: Diagnostic,\n source: string,\n path: string,\n): void {\n const { start, end } = diagnostic.range;\n const severity = colorizeSeverity(context, diagnostic.severity);\n context.stderr.write(\n `${bold(context, `${path}:${start.line}:${start.column}`)} ${severity}[${diagnostic.code}] ${diagnostic.message}\\n`,\n );\n\n const lines = source.split(/\\r?\\n/);\n const line = lines[start.line - 1] ?? \"\";\n const lineNumber = String(start.line);\n const gutter = \" \".repeat(lineNumber.length);\n const startColumn = Math.max(1, start.column);\n const endColumn =\n end.line === start.line ? Math.max(startColumn + 1, end.column) : line.length + 1;\n const markerLength = Math.max(\n 1,\n Math.min(endColumn - startColumn, line.length - startColumn + 2),\n );\n context.stderr.write(`${dim(context, `${gutter} |`)}\\n`);\n context.stderr.write(`${dim(context, `${lineNumber} |`)} ${line}\\n`);\n context.stderr.write(\n `${dim(context, `${gutter} |`)} ${\" \".repeat(startColumn - 1)}${severityColor(context, diagnostic.severity, \"^\".repeat(markerLength))}\\n`,\n );\n if (diagnostic.hint) {\n context.stderr.write(\n `${dim(context, `${gutter} =`)} ${cyan(context, \"hint:\")} ${diagnostic.hint}\\n`,\n );\n }\n}\n\nexport function printSummary(context: OutputContext, message: string): void {\n if (!context.quiet) context.stderr.write(`${message}\\n`);\n}\n\nexport function printProgress(context: OutputContext, message: string): void {\n if (!context.quiet && context.verbose) context.stderr.write(`${dim(context, message)}\\n`);\n}\n\nexport function machineEnvelope<T>(\n command: string,\n payload: T,\n): {\n version: 1;\n command: string;\n payload: T;\n} {\n return { version: MACHINE_OUTPUT_VERSION, command, payload };\n}\n\nexport function installPipeErrorHandlers(): void {\n for (const stream of [process.stdout, process.stderr]) {\n stream.on(\"error\", (error: NodeJS.ErrnoException) => {\n if (error.code === \"EPIPE\") {\n process.exit(EXIT_SUCCESS);\n }\n throw error;\n });\n }\n}\n\nfunction printCode(code: number): string {\n return `\\u001b[${code}m`;\n}\n\nfunction styled(context: OutputContext, code: number, text: string): string {\n return context.color ? `${printCode(code)}${text}${printCode(0)}` : text;\n}\n\nfunction bold(context: OutputContext, text: string): string {\n return styled(context, 1, text);\n}\n\nfunction dim(context: OutputContext, text: string): string {\n return styled(context, 2, text);\n}\n\nfunction cyan(context: OutputContext, text: string): string {\n return styled(context, 36, text);\n}\n\nfunction severityColor(\n context: OutputContext,\n severity: Diagnostic[\"severity\"],\n text: string,\n): string {\n return styled(context, severity === \"error\" ? 31 : severity === \"warning\" ? 33 : 36, text);\n}\n\nfunction colorizeSeverity(context: OutputContext, severity: Diagnostic[\"severity\"]): string {\n return severityColor(context, severity, severity);\n}\n","import { basename, dirname, extname, resolve } from \"node:path\";\nimport { CliUsageError, type ParsedCommand } from \"./command-model.ts\";\nimport type { ResolvedInput } from \"./input-resolver.ts\";\n\nexport function renderOutputPaths(\n command: ParsedCommand,\n inputs: readonly ResolvedInput[],\n cwd = process.cwd(),\n): Array<string | undefined> {\n const { output, outDir, outputTemplate } = command.options;\n if (inputs.length > 1 && output) {\n throw new CliUsageError(\"--output accepts only one resolved input\");\n }\n if (inputs.length > 1 && !outDir && !outputTemplate) {\n throw new CliUsageError(\n \"Multiple render inputs require --out-dir or --output-template; SVG documents are never concatenated\",\n );\n }\n\n const paths = inputs.map((input) => {\n if (output) return resolve(cwd, output);\n if (!outDir && !outputTemplate) return undefined;\n const rendered = applyTemplate(outputTemplate ?? \"{path}.svg\", input.relativePath);\n return outDir ? resolve(cwd, outDir, rendered) : resolve(cwd, rendered);\n });\n rejectCollisions(paths);\n return paths;\n}\n\nfunction applyTemplate(template: string, relativeInput: string): string {\n const extension = extname(relativeInput);\n const pathWithoutExtension = extension\n ? relativeInput.slice(0, relativeInput.length - extension.length)\n : relativeInput;\n const directory = dirname(pathWithoutExtension) === \".\" ? \"\" : dirname(pathWithoutExtension);\n const name = basename(pathWithoutExtension);\n const rendered = template\n .replaceAll(\"{path}\", pathWithoutExtension)\n .replaceAll(\"{dir}\", directory)\n .replaceAll(\"{name}\", name)\n .replaceAll(\"{ext}\", \"svg\");\n if (!rendered || rendered.endsWith(\"/\")) {\n throw new CliUsageError(`Invalid --output-template result for ${relativeInput}: ${rendered}`);\n }\n return rendered;\n}\n\nfunction rejectCollisions(paths: readonly (string | undefined)[]): void {\n const seen = new Set<string>();\n for (const path of paths) {\n if (!path) continue;\n if (seen.has(path))\n throw new CliUsageError(`Multiple inputs resolve to the same output: ${path}`);\n seen.add(path);\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport type { ResolvedRenderSettings } from \"./project-config.ts\";\n\nconst require = createRequire(import.meta.url);\n\nexport function finalizePortableSvg(svg: string, settings: ResolvedRenderSettings): string {\n let output = svg;\n if (settings.embedFonts) output = embedInter(output);\n if (settings.background === \"theme\") {\n const background = `<rect class=\"kdiagram-export-background\" width=\"100%\" height=\"100%\" fill=\"var(--kd-bg)\"/>`;\n output = output.replace(/(<desc\\b[^>]*>[^<]*<\\/desc>)/, `$1\\n${background}`);\n }\n return output;\n}\n\nfunction embedInter(svg: string): string {\n const fontPath = require.resolve(\"@fontsource/inter/files/inter-latin-500-normal.woff\");\n const font = readFileSync(fontPath).toString(\"base64\");\n const css = `@font-face{font-family:\"Inter\";src:url(data:font/woff;base64,${font}) format(\"woff\");font-style:normal;font-weight:100 900;font-display:block;}`;\n const styleIndex = svg.indexOf(\"<style>\");\n if (styleIndex >= 0) return svg.slice(0, styleIndex + 7) + css + svg.slice(styleIndex + 7);\n return svg.replace(/(<svg\\b[^>]*>)/, `$1\\n<style>${css}</style>`);\n}\n","import { spawn } from \"node:child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport {\n createReadStream,\n existsSync,\n readFileSync,\n statSync,\n watch,\n writeFileSync,\n} from \"node:fs\";\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { basename, dirname, extname, relative, resolve, sep } from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport { renderPipeline, parseSource, listCompileTargets } from \"@kekonic/diagrams\";\nimport { loadIconSubset } from \"@kekonic/diagrams-icons\";\nimport {\n STUDIO_PROTOCOL_VERSION,\n createStudioPreviewCoordinator,\n parseStudioClientMessage,\n studioMessageJson,\n type StudioCompileTarget,\n type StudioDocument,\n type StudioPresentation,\n type StudioRender,\n type StudioServerMessage,\n} from \"@kekonic/diagrams-studio\";\n\nconst require = createRequire(import.meta.url);\nconst ICON_NAME = /^[a-z0-9][a-z0-9-]*$/;\nconst MAX_ICONS_PER_REQUEST = 64;\n\nexport type StudioServer = {\n url: string;\n port: number;\n token: string;\n closed: Promise<void>;\n close(): Promise<void>;\n};\n\nexport type StartStudioServerOptions = {\n files: string[];\n allowWrite?: boolean;\n port?: number;\n browserRoot?: string;\n};\n\nexport async function startStudioServer(options: StartStudioServerOptions): Promise<StudioServer> {\n const files = [...new Set(options.files.map((file) => resolve(file)))].sort();\n if (files.length === 0) throw new Error(\"Studio requires at least one .kdiagram file\");\n for (const file of files) {\n if (!existsSync(file) || !statSync(file).isFile())\n throw new Error(`Studio input is not a file: ${file}`);\n }\n const roots = minimalRoots(files.map(dirname));\n const documents = new Map<string, StudioDocument>();\n for (const file of files) {\n const id = relative(commonRoot(files), file).split(sep).join(\"/\") || basename(file);\n documents.set(id, {\n id,\n path: file,\n label: id,\n revision: 0,\n source: readFileSync(file, \"utf8\"),\n });\n }\n let activeDocumentId = documents.keys().next().value as string;\n const activeViews = new Map<string, string | undefined>();\n let presentation: StudioPresentation = { theme: \"dark\", options: { theme: \"dark\" } };\n const token = randomBytes(32).toString(\"base64url\");\n const sessionId = randomBytes(16).toString(\"hex\");\n const browserRoot = resolve(\n options.browserRoot ?? dirname(require.resolve(\"@kekonic/diagrams-studio/browser\")),\n );\n const clients = new Set<ServerResponse>();\n const renders = new Map<string, StudioRender>();\n\n const enrichDocument = (document: StudioDocument): StudioDocument => {\n const compileTargets = compileTargetsFor(document);\n let activeView = activeViews.get(document.id);\n if (\n compileTargets.length > 0 &&\n (!activeView || !compileTargets.some((target) => target.viewName === activeView))\n ) {\n activeView =\n compileTargets.find((target) => target.viewName === \"default\")?.viewName ??\n compileTargets.find((target) => target.viewName === \"main\")?.viewName ??\n compileTargets[0]?.viewName;\n }\n if (activeView) activeViews.set(document.id, activeView);\n return { ...document, compileTargets, activeView };\n };\n\n const coordinator = createStudioPreviewCoordinator((source, renderOptions) =>\n renderPipeline(source, {\n ...renderOptions,\n snapshotTheme: true,\n shadows: false,\n }),\n );\n\n const broadcast = (message: StudioServerMessage): void => {\n const line = `data: ${studioMessageJson(message)}\\n\\n`;\n for (const client of clients) client.write(line);\n };\n const renderDocument = async (document: StudioDocument): Promise<void> => {\n const enriched = enrichDocument(document);\n const result = await coordinator.render(document.id, document.revision, document.source, {\n ...presentation.options,\n view: enriched.activeView,\n });\n if (result) {\n renders.set(document.id, result);\n broadcast({ version: STUDIO_PROTOCOL_VERSION, type: \"render\", ...result });\n }\n };\n\n const server = createServer(async (request, response) => {\n try {\n const url = new URL(request.url ?? \"/\", \"http://127.0.0.1\");\n const cookieToken = request.headers.cookie\n ?.split(\";\")\n .map((item) => item.trim())\n .find((item) => item.startsWith(\"kdiagram_studio=\"))\n ?.slice(\"kdiagram_studio=\".length);\n if (url.searchParams.get(\"token\") !== token && cookieToken !== token) {\n return respond(response, 403, \"Forbidden\");\n }\n if (request.method === \"GET\" && url.pathname === \"/events\") {\n response.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n \"X-Content-Type-Options\": \"nosniff\",\n });\n clients.add(response);\n response.write(\n `data: ${studioMessageJson({\n version: 1,\n type: \"ready\",\n sessionId,\n documents: [...documents.values()].map(enrichDocument),\n activeDocumentId,\n capabilities: { write: options.allowWrite === true, export: true },\n presentation,\n })}\\n\\n`,\n );\n request.on(\"close\", () => clients.delete(response));\n void renderDocument(documents.get(activeDocumentId)!);\n return;\n }\n if (request.method === \"POST\" && url.pathname === \"/message\") {\n const message = parseStudioClientMessage(JSON.parse(await readBody(request)));\n const document = \"documentId\" in message ? documents.get(message.documentId) : undefined;\n if (\"documentId\" in message && !document) return respond(response, 404, \"Unknown document\");\n switch (message.type) {\n case \"open\":\n activeDocumentId = message.documentId;\n broadcast({\n version: 1,\n type: \"document\",\n reason: \"open\",\n ...enrichDocument(document!),\n });\n void renderDocument(document!);\n break;\n case \"selectView\":\n activeViews.set(message.documentId, message.view);\n broadcast({\n version: 1,\n type: \"document\",\n reason: \"open\",\n ...enrichDocument(document!),\n });\n void renderDocument(document!);\n break;\n case \"source\":\n if (message.revision <= document!.revision)\n return respond(response, 409, \"Stale revision\");\n document!.revision = message.revision;\n document!.source = message.source;\n void renderDocument(document!);\n break;\n case \"save\":\n if (!options.allowWrite)\n return respond(response, 403, \"Studio writes are not authorized\");\n assertWithinRoots(document!.path, roots);\n if (message.revision < document!.revision)\n return respond(response, 409, \"Stale revision\");\n writeFileSync(\n document!.path,\n message.source.endsWith(\"\\n\") ? message.source : `${message.source}\\n`,\n \"utf8\",\n );\n document!.source = readFileSync(document!.path, \"utf8\");\n document!.revision = message.revision;\n broadcast({\n version: 1,\n type: \"saved\",\n documentId: document!.id,\n revision: document!.revision,\n });\n break;\n case \"selection\":\n if (message.selection.graphElement && !message.selection.range) {\n const graph = renders.get(message.selection.documentId)?.graph;\n const collection =\n message.selection.graphElement.type === \"node\" ? graph?.nodes : graph?.edges;\n const element = collection?.find(\n (item) => item.id === message.selection.graphElement?.id,\n );\n if (element?.sourceRange) message.selection.range = element.sourceRange;\n }\n broadcast({ version: 1, type: \"selection\", selection: message.selection });\n break;\n case \"viewport\":\n broadcast({ version: 1, type: \"viewport\", viewport: message.viewport });\n break;\n case \"presentation\":\n presentation = message.presentation;\n broadcast({ version: 1, type: \"presentation\", presentation });\n void renderDocument(documents.get(activeDocumentId)!);\n break;\n }\n return respond(response, 204, \"\");\n }\n if (request.method === \"GET\" && url.pathname.startsWith(\"/__kdiagram/icons/\")) {\n return serveIconSubset(url, response);\n }\n if (request.method !== \"GET\") return respond(response, 405, \"Method not allowed\");\n const requestedPath =\n url.pathname === \"/\" ? \"index.html\" : decodeURIComponent(url.pathname.slice(1));\n const assetPath = resolve(browserRoot, requestedPath);\n assertWithinRoots(assetPath, [browserRoot]);\n if (!existsSync(assetPath) || !statSync(assetPath).isFile())\n return respond(response, 404, \"Not found\");\n response.writeHead(200, {\n \"Content-Type\": contentType(assetPath),\n \"Cache-Control\":\n requestedPath === \"index.html\" ? \"no-store\" : \"public, max-age=31536000, immutable\",\n \"Content-Security-Policy\":\n \"default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; font-src 'self'; img-src 'self' data:; connect-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'\",\n \"X-Content-Type-Options\": \"nosniff\",\n \"Referrer-Policy\": \"no-referrer\",\n ...(requestedPath === \"index.html\"\n ? { \"Set-Cookie\": `kdiagram_studio=${token}; HttpOnly; SameSite=Strict; Path=/` }\n : {}),\n });\n createReadStream(assetPath).pipe(response);\n } catch (error) {\n respond(response, 400, error instanceof Error ? error.message : String(error));\n }\n });\n\n const watchers = files.map((file) =>\n watch(file, { persistent: false }, () => {\n const document = [...documents.values()].find((item) => item.path === file);\n if (!document) return;\n const source = readFileSync(file, \"utf8\");\n if (source === document.source) return;\n document.source = source;\n document.revision += 1;\n broadcast({\n version: 1,\n type: \"document\",\n reason: \"external\",\n ...enrichDocument(document),\n });\n void renderDocument(document);\n }),\n );\n const heartbeat = setInterval(() => {\n for (const client of clients) client.write(\": heartbeat\\n\\n\");\n }, 15_000);\n heartbeat.unref();\n\n await new Promise<void>((resolveListen, reject) => {\n server.once(\"error\", reject);\n server.listen(options.port ?? 0, \"127.0.0.1\", resolveListen);\n });\n const address = server.address();\n if (!address || typeof address === \"string\")\n throw new Error(\"Studio server did not bind a TCP port\");\n let resolveClosed!: () => void;\n const closed = new Promise<void>((resolvePromise) => (resolveClosed = resolvePromise));\n server.once(\"close\", resolveClosed);\n const close = async (): Promise<void> => {\n clearInterval(heartbeat);\n for (const watcher of watchers) watcher.close();\n for (const client of clients) client.end();\n await new Promise<void>((resolveClose, reject) =>\n server.close((error) => (error ? reject(error) : resolveClose())),\n );\n };\n return {\n url: `http://127.0.0.1:${address.port}/?token=${encodeURIComponent(token)}`,\n port: address.port,\n token,\n closed,\n close,\n };\n}\n\nexport async function openStudioBrowser(url: string): Promise<void> {\n const command =\n process.platform === \"darwin\"\n ? { executable: \"open\", args: [url] }\n : process.platform === \"win32\"\n ? { executable: \"cmd\", args: [\"/c\", \"start\", \"\", url] }\n : { executable: \"xdg-open\", args: [url] };\n const child = spawn(command.executable, command.args, { detached: true, stdio: \"ignore\" });\n child.unref();\n await new Promise<void>((resolveSpawn, reject) => {\n child.once(\"spawn\", resolveSpawn);\n child.once(\"error\", reject);\n });\n}\n\nfunction respond(response: ServerResponse, status: number, body: string): void {\n response.writeHead(status, {\n \"Content-Type\": \"text/plain; charset=utf-8\",\n \"X-Content-Type-Options\": \"nosniff\",\n });\n response.end(body);\n}\n\nasync function serveIconSubset(url: URL, response: ServerResponse): Promise<void> {\n const match = /^\\/__kdiagram\\/icons\\/([a-z0-9-]+)\\.json$/.exec(url.pathname);\n const names = parseIconNames(url.searchParams.get(\"icons\"));\n if (!match || !names) return respondJson(response, 400, { error: \"Invalid icon request\" });\n const subset = await loadIconSubset(match[1]!, names);\n if (!subset) return respondJson(response, 404, { error: \"Unknown icon collection\" });\n return respondJson(response, 200, subset);\n}\n\nfunction parseIconNames(value: string | null): string[] | null {\n if (!value) return null;\n const names = [...new Set(value.split(\",\"))];\n if (\n names.length === 0 ||\n names.length > MAX_ICONS_PER_REQUEST ||\n names.some((name) => !ICON_NAME.test(name))\n ) {\n return null;\n }\n return names;\n}\n\nfunction respondJson(response: ServerResponse, status: number, body: unknown): void {\n response.writeHead(status, {\n \"Content-Type\": \"application/json; charset=utf-8\",\n \"Cache-Control\": \"public, max-age=86400\",\n \"X-Content-Type-Options\": \"nosniff\",\n });\n response.end(JSON.stringify(body));\n}\n\nasync function readBody(request: IncomingMessage): Promise<string> {\n const chunks: Buffer[] = [];\n let bytes = 0;\n for await (const chunk of request) {\n const buffer = Buffer.from(chunk);\n bytes += buffer.byteLength;\n if (bytes > 2_000_000) throw new Error(\"Studio message exceeds 2 MB\");\n chunks.push(buffer);\n }\n return Buffer.concat(chunks).toString(\"utf8\");\n}\n\nfunction assertWithinRoots(path: string, roots: string[]): void {\n const absolute = resolve(path);\n if (!roots.some((root) => absolute === root || absolute.startsWith(`${resolve(root)}${sep}`))) {\n throw new Error(\"Path is outside the studio session roots\");\n }\n}\n\nfunction minimalRoots(directories: string[]): string[] {\n const sorted = [...new Set(directories.map((directory) => resolve(directory)))].sort();\n return sorted.filter(\n (directory, index) =>\n !sorted.some(\n (other, otherIndex) => otherIndex !== index && directory.startsWith(`${other}${sep}`),\n ),\n );\n}\n\nfunction commonRoot(files: string[]): string {\n let root = dirname(files[0]!);\n while (!files.every((file) => file === root || file.startsWith(`${root}${sep}`)))\n root = dirname(root);\n return root;\n}\n\nfunction contentType(path: string): string {\n switch (extname(path)) {\n case \".html\":\n return \"text/html; charset=utf-8\";\n case \".js\":\n return \"text/javascript; charset=utf-8\";\n case \".css\":\n return \"text/css; charset=utf-8\";\n case \".ttf\":\n return \"font/ttf\";\n case \".map\":\n return \"application/json\";\n default:\n return \"application/octet-stream\";\n }\n}\n\nfunction compileTargetsFor(document: StudioDocument): StudioCompileTarget[] {\n const { ast } = parseSource(document.source);\n return listCompileTargets(ast)\n .filter((target) => target.kind === \"model-view\" && target.viewName)\n .map((target) => ({\n kind: \"model-view\" as const,\n viewName: target.viewName!,\n title: target.title ?? target.viewName!,\n }));\n}\n","#!/usr/bin/env node\nimport { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n analyzeDiagramQuality,\n compileSource,\n getCapabilities,\n listCompileTargets,\n parseSource,\n renderPipeline,\n type Diagnostic,\n} from \"@kekonic/diagrams\";\nimport { KDiagramLanguageService } from \"@kekonic/diagrams-language-service\";\nimport { CliUsageError, parseCommand, type ParsedCommand } from \"./command-model.ts\";\nimport { shellCompletions } from \"./completions.ts\";\nimport { runDoctor } from \"./doctor.ts\";\nimport { readResolvedInput, resolveCommandInputs, type ResolvedInput } from \"./input-resolver.ts\";\nimport {\n createOutputContext,\n EXIT_DIAGNOSTICS,\n EXIT_OPERATIONAL,\n EXIT_SUCCESS,\n EXIT_USAGE,\n installPipeErrorHandlers,\n machineEnvelope,\n printDiagnostic,\n printProgress,\n printSummary,\n type OutputContext,\n} from \"./output.ts\";\nimport { renderOutputPaths } from \"./output-paths.ts\";\nimport { finalizePortableSvg } from \"./portable-svg.ts\";\nimport { resolveRenderSettings } from \"./project-config.ts\";\nimport { openStudioBrowser, startStudioServer } from \"./studio-server.ts\";\nimport { runLanguageServer } from \"./lsp-server.ts\";\n\nconst argv = process.argv.slice(2);\nconst languageService = new KDiagramLanguageService();\nlet activeCommand: ParsedCommand | undefined;\ninstallPipeErrorHandlers();\n\nfunction compileTargetFromCommand(command: ParsedCommand) {\n const diagramIndex =\n command.options.diagramIndex != null ? Number(command.options.diagramIndex) : undefined;\n if (command.options.view) {\n return { diagramIndex: diagramIndex ?? 0, view: command.options.view };\n }\n if (diagramIndex != null) return diagramIndex;\n return 0;\n}\n\nfunction pipelineCompileOptions(command: ParsedCommand) {\n const target = compileTargetFromCommand(command);\n if (typeof target === \"number\") {\n return target === 0 ? {} : { diagramIndex: target };\n }\n return target;\n}\n\nfunction usage(stream: NodeJS.WritableStream = process.stdout): void {\n stream.write(`kdiagrams — deterministic text-to-diagram tooling\n\nCommon jobs:\n kdiagrams check .\n kdiagrams format diagrams/ --check\n kdiagrams render diagrams/ --out-dir public/diagrams\n kdiagrams render architecture.kdiagram -o architecture.svg --print-safe\n kdiagrams render storefront-model.kdiagram --view context -o context.svg\n kdiagrams analyze architecture.kdiagram --pretty\n\nCommands:\n render [inputs...] Render portable SVG\n check [inputs...] Validate source and semantics\n analyze [inputs...] Analyze rendered layout quality as JSON\n capabilities Describe the active language and renderer as JSON\n format [inputs...] Format or check source\n studio [inputs...] Launch the local browser authoring studio\n lsp --stdio Run the Language Server Protocol over stdio\n ast [input] Emit a versioned AST envelope\n graph [input] Emit a versioned semantic-model envelope\n doctor Inspect runtime, font, config, and renderer health\n completions <shell> Print Bash, Zsh, or Fish completion source\n\nModel views (kdiagram 2 draft):\n --view name Select a named \\`view\\` inside a \\`model\\` block\n --diagram-index n Select which top-level diagram/model (default: 0)\n\nStudio:\n --no-open Start without opening the browser (opens by default)\n --allow-write Authorize saving resolved input files\n --port number Loopback port (default: random available port)\n\nInput discovery:\n --exclude pattern Git-ignore-style exclusion (repeatable)\n --ignore-file file Rules file (default: .kdiagramignore)\n --stdin-filename file Logical filename for piped diagram source\n --files-from file|- Read additional input paths, one per line\n\nPortable render output:\n -o, --output file Single output file\n --out-dir dir Batch output directory; preserves relative paths\n --output-template text Template using {path}, {dir}, {name}, and {ext}\n --theme name Built-in or configured theme\n --config file Project config (default: discovered kekonic-diagrams.config.json)\n --profile name Named export profile from config\n --theme-file file JSON custom-property token map\n --live-theme Retain host-resolved CSS variables (snapshot is default)\n --background mode transparent or theme\n --embed-fonts Embed bundled Inter in SVG\n --print-safe Light snapshot with explicit theme background\n\nHuman and machine output:\n --json Versioned JSON envelope (check/doctor)\n --pretty Pretty versioned JSON (ast/graph)\n --color mode auto, always, or never\n --quiet Suppress summaries and progress\n --verbose Include progress details\n --debug Include stack traces for operational failures\n -v, --version Print installed version\n -h, --help Show help\n\nExit status: 0 success, 1 source/check failure, 2 usage error, 3 operational failure.\n`);\n}\n\nfunction version(): string {\n const manifestPath = fileURLToPath(new URL(\"../package.json\", import.meta.url));\n const manifest = JSON.parse(readFileSync(manifestPath, \"utf-8\")) as { version?: string };\n return manifest.version ?? \"unknown\";\n}\n\nfunction printDiagnostics(\n context: OutputContext,\n diagnostics: readonly Diagnostic[],\n source: string,\n path: string,\n): void {\n for (const diagnostic of diagnostics) printDiagnostic(context, diagnostic, source, path);\n}\n\nasync function cmdRender(\n command: ParsedCommand,\n inputs: ResolvedInput[],\n context: OutputContext,\n): Promise<number> {\n const outputPaths = renderOutputPaths(command, inputs);\n const settings = resolveRenderSettings(command);\n for (const warning of settings.warnings) {\n if (!context.quiet) context.stderr.write(`warning[FMCLI101] ${warning}\\n`);\n }\n if (settings.configPath) printProgress(context, `Using config ${settings.configPath}`);\n if (settings.profileName) printProgress(context, `Using export profile ${settings.profileName}`);\n\n let failed = false;\n for (let index = 0; index < inputs.length; index++) {\n const input = inputs[index]!;\n const source = readResolvedInput(input);\n printProgress(context, `Rendering ${input.displayPath}`);\n const result = await renderPipeline(source, {\n theme: settings.theme,\n snapshotTheme: settings.snapshotTheme,\n presentation: settings.presentation,\n shadows: false,\n ...pipelineCompileOptions(command),\n });\n printDiagnostics(context, result.diagnostics, source, input.displayPath);\n if (!result.ok || !result.svg) {\n failed = true;\n continue;\n }\n\n const svg = finalizePortableSvg(result.svg, settings);\n const outputPath = outputPaths[index];\n if (!outputPath) {\n process.stdout.write(svg);\n continue;\n }\n mkdirSync(dirname(outputPath), { recursive: true });\n writeFileSync(outputPath, svg, \"utf-8\");\n printSummary(context, `Wrote ${outputPath}`);\n }\n return failed ? EXIT_DIAGNOSTICS : EXIT_SUCCESS;\n}\n\nasync function cmdAnalyze(command: ParsedCommand, inputs: ResolvedInput[]): Promise<number> {\n const files = [];\n let errorCount = 0;\n let warningCount = 0;\n for (const input of inputs) {\n const source = readResolvedInput(input);\n const compileOptions = pipelineCompileOptions(command);\n\n const result = await renderPipeline(source, {\n shadows: false,\n ...compileOptions,\n });\n const diagnostics = result.diagnostics;\n errorCount += diagnostics.filter((item) => item.severity === \"error\").length;\n warningCount += diagnostics.filter((item) => item.severity === \"warning\").length;\n files.push({\n path: input.displayPath,\n diagnostics,\n artifact:\n result.layout && result.graph && result.routing\n ? {\n ...analyzeDiagramQuality(result.graph, result.layout, result.routing.edges).metrics,\n nodes: result.stats.nodeCount,\n edges: result.stats.edgeCount,\n layoutAlgorithm: result.stats.layoutAlgorithm,\n routerAlgorithm: result.stats.routerAlgorithm,\n }\n : undefined,\n });\n }\n process.stdout.write(\n `${JSON.stringify(\n machineEnvelope(\"analyze\", {\n files,\n summary: { files: inputs.length, errors: errorCount, warnings: warningCount },\n }),\n null,\n command.options.pretty ? 2 : undefined,\n )}\\n`,\n );\n return errorCount > 0 ? EXIT_DIAGNOSTICS : EXIT_SUCCESS;\n}\n\nfunction cmdCheck(command: ParsedCommand, inputs: ResolvedInput[], context: OutputContext): number {\n const files: Array<{ path: string; diagnostics: Diagnostic[] }> = [];\n let errorCount = 0;\n let warningCount = 0;\n for (const input of inputs) {\n const source = readResolvedInput(input);\n const diagnostics = languageService.updateDocument(inputUri(input), source, 1).diagnostics;\n files.push({ path: input.displayPath, diagnostics });\n errorCount += diagnostics.filter((diagnostic) => diagnostic.severity === \"error\").length;\n warningCount += diagnostics.filter((diagnostic) => diagnostic.severity === \"warning\").length;\n if (!command.options.json) {\n printDiagnostics(context, diagnostics, source, input.displayPath);\n }\n }\n\n if (command.options.json) {\n process.stdout.write(\n `${JSON.stringify(\n machineEnvelope(\"check\", {\n files,\n summary: { files: inputs.length, errors: errorCount, warnings: warningCount },\n }),\n )}\\n`,\n );\n } else {\n printSummary(\n context,\n `${inputs.length} file(s): ${errorCount} error(s), ${warningCount} warning(s)`,\n );\n }\n return errorCount > 0 ? EXIT_DIAGNOSTICS : EXIT_SUCCESS;\n}\n\nfunction cmdInspect(\n command: ParsedCommand,\n inputs: ResolvedInput[],\n context: OutputContext,\n): number {\n requireSingleInput(command.name, inputs);\n const input = inputs[0]!;\n const source = readResolvedInput(input);\n if (command.name === \"ast\") {\n const result = parseSource(source);\n printDiagnostics(context, result.diagnostics, source, input.displayPath);\n writeInspectionEnvelope(command, input, result.ast, result.diagnostics);\n return result.diagnostics.some((diagnostic) => diagnostic.severity === \"error\")\n ? EXIT_DIAGNOSTICS\n : EXIT_SUCCESS;\n }\n const parsed = parseSource(source);\n printDiagnostics(context, parsed.diagnostics, source, input.displayPath);\n if (parsed.diagnostics.some((diagnostic) => diagnostic.severity === \"error\")) {\n writeInspectionEnvelope(command, input, resultEmptyGraph(), parsed.diagnostics);\n return EXIT_DIAGNOSTICS;\n }\n const result = compileSource(source, compileTargetFromCommand(command));\n printDiagnostics(context, result.diagnostics, source, input.displayPath);\n const diagnostics = [...parsed.diagnostics, ...result.diagnostics];\n writeInspectionEnvelope(command, input, result.graph, diagnostics, {\n targets: listCompileTargets(parsed.ast),\n });\n return diagnostics.some((diagnostic) => diagnostic.severity === \"error\")\n ? EXIT_DIAGNOSTICS\n : EXIT_SUCCESS;\n}\n\nfunction resultEmptyGraph() {\n return {\n id: \"empty\",\n nodes: [],\n edges: [],\n groups: [],\n styles: [],\n animations: [],\n diagnostics: [],\n };\n}\n\nfunction writeInspectionEnvelope(\n command: ParsedCommand,\n input: ResolvedInput,\n data: unknown,\n diagnostics: readonly Diagnostic[],\n extra?: Record<string, unknown>,\n): void {\n process.stdout.write(\n `${JSON.stringify(\n machineEnvelope(command.name, {\n path: input.displayPath,\n data,\n diagnostics,\n ...extra,\n }),\n null,\n command.options.pretty ? 2 : undefined,\n )}\\n`,\n );\n}\n\nfunction cmdFormat(\n command: ParsedCommand,\n inputs: ResolvedInput[],\n context: OutputContext,\n): number {\n if (command.options.output) requireSingleInput(command.name, inputs);\n if (!command.options.write && !command.options.check && !command.options.output) {\n requireSingleInput(command.name, inputs);\n }\n if (command.options.write && inputs.some((input) => input.kind === \"stdin\")) {\n throw new CliUsageError(\"--write cannot be used with stdin\");\n }\n\n let changed = false;\n for (const input of inputs) {\n const source = readResolvedInput(input);\n const uri = inputUri(input);\n languageService.updateDocument(uri, source, 1);\n const formatted = languageService.format(uri)[0]?.newText ?? source;\n if (command.options.check) {\n if (source !== formatted) {\n changed = true;\n context.stderr.write(`${input.displayPath}: not formatted\\n`);\n }\n continue;\n }\n\n const target = command.options.output\n ? resolve(command.options.output)\n : command.options.write\n ? input.absolutePath\n : undefined;\n if (target) {\n mkdirSync(dirname(target), { recursive: true });\n writeFileSync(target, formatted, \"utf-8\");\n printSummary(context, `Wrote ${target}`);\n } else {\n process.stdout.write(formatted);\n }\n }\n return changed ? EXIT_DIAGNOSTICS : EXIT_SUCCESS;\n}\n\nfunction cmdDoctor(command: ParsedCommand, context: OutputContext): number {\n const checks = runDoctor();\n if (command.options.json) {\n process.stdout.write(`${JSON.stringify(machineEnvelope(\"doctor\", { checks }))}\\n`);\n } else {\n for (const check of checks) {\n context.stderr.write(\n `${check.status.toUpperCase().padEnd(4)} ${check.name}: ${check.detail}\\n`,\n );\n }\n }\n return checks.some((check) => check.status === \"fail\") ? EXIT_OPERATIONAL : EXIT_SUCCESS;\n}\n\nfunction requireSingleInput(command: string, inputs: readonly ResolvedInput[]): void {\n if (inputs.length !== 1) {\n throw new CliUsageError(\n `${command} requires exactly one resolved input; received ${inputs.length}`,\n );\n }\n}\n\nasync function main(): Promise<number> {\n if (argv.includes(\"-v\") || argv.includes(\"--version\")) {\n process.stdout.write(`${version()}\\n`);\n return EXIT_SUCCESS;\n }\n if (argv.includes(\"-h\") || argv.includes(\"--help\")) {\n usage();\n return EXIT_SUCCESS;\n }\n if (argv.length === 0) {\n usage(process.stderr);\n return EXIT_USAGE;\n }\n\n const command = parseCommand(argv);\n activeCommand = command;\n const context = createOutputContext(command.options);\n if (command.name === \"completions\") {\n if (command.inputs.length !== 1) throw new CliUsageError(\"completions requires one shell\");\n process.stdout.write(shellCompletions(command.inputs[0]));\n return EXIT_SUCCESS;\n }\n if (command.name === \"doctor\") {\n if (command.inputs.length > 0) throw new CliUsageError(\"doctor does not accept inputs\");\n return cmdDoctor(command, context);\n }\n if (command.name === \"capabilities\") {\n if (command.inputs.length > 0) throw new CliUsageError(\"capabilities does not accept inputs\");\n process.stdout.write(\n `${JSON.stringify(machineEnvelope(\"capabilities\", getCapabilities()), null, command.options.pretty ? 2 : undefined)}\\n`,\n );\n return EXIT_SUCCESS;\n }\n if (command.name === \"lsp\") {\n if (command.inputs.length !== 0) throw new CliUsageError(\"lsp does not accept inputs\");\n return runLanguageServer();\n }\n\n if (command.name === \"studio\") {\n const studioCommand = command.inputs.length === 0 ? { ...command, inputs: [\".\"] } : command;\n const studioInputs = resolveCommandInputs(studioCommand);\n if (studioInputs.some((input) => input.kind === \"stdin\" || !input.absolutePath)) {\n throw new CliUsageError(\"studio accepts files, directories, and globs, not stdin\");\n }\n const server = await startStudioServer({\n files: studioInputs.map((input) => input.absolutePath!),\n allowWrite: command.options.allowWrite,\n port: Number(command.options.port ?? 0),\n });\n context.stderr.write(`Kekonic Diagrams Studio: ${server.url}\\n`);\n if (!command.options.noOpen) await openStudioBrowser(server.url);\n await server.closed;\n return EXIT_SUCCESS;\n }\n\n const inputs = resolveCommandInputs(command);\n switch (command.name) {\n case \"render\":\n return cmdRender(command, inputs, context);\n case \"check\":\n return cmdCheck(command, inputs, context);\n case \"analyze\":\n return cmdAnalyze(command, inputs);\n case \"ast\":\n case \"graph\":\n return cmdInspect(command, inputs, context);\n case \"format\":\n return cmdFormat(command, inputs, context);\n }\n}\n\nmain()\n .then((exitCode) => {\n process.exitCode = exitCode;\n })\n .catch((error: unknown) => {\n if (error instanceof CliUsageError) {\n process.stderr.write(`${error.message}\\n`);\n process.exitCode = EXIT_USAGE;\n return;\n }\n const message = operationalMessage(error);\n process.stderr.write(`Operational error: ${message}\\n`);\n if (activeCommand?.options.debug && error instanceof Error && error.stack) {\n process.stderr.write(`${error.stack}\\n`);\n }\n process.exitCode = EXIT_OPERATIONAL;\n });\n\nfunction operationalMessage(error: unknown): string {\n if (error instanceof Error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\")\n return `File not found: ${(error as NodeJS.ErrnoException).path ?? error.message}`;\n if (code === \"EACCES\")\n return `Permission denied: ${(error as NodeJS.ErrnoException).path ?? error.message}`;\n return error.message;\n }\n return String(error);\n}\n\nfunction inputUri(input: ResolvedInput): string {\n return input.absolutePath ? `file://${input.absolutePath}` : `stdin://${input.displayPath}`;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- export { };
1
+ export {}
package/dist/lsp-bin.mjs CHANGED
File without changes
@@ -1,5 +1,4 @@
1
1
  import { Readable, Writable } from "node:stream";
2
-
3
2
  //#region src/lsp-server.d.ts
4
3
  declare function runLanguageServer(input?: Readable, output?: Writable): Promise<number>;
5
4
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kekonic/diagrams-cli",
3
- "version": "1.0.0-rc.5",
3
+ "version": "1.0.0-rc.7",
4
4
  "description": "CLI for rendering, validating, inspecting, and formatting KDiagram diagrams.",
5
5
  "keywords": [
6
6
  "architecture",
@@ -20,8 +20,7 @@
20
20
  "directory": "packages/diagrams-cli"
21
21
  },
22
22
  "bin": {
23
- "kdiagrams": "./dist/cli.mjs",
24
- "kdiagrams-lsp": "./dist/lsp-bin.mjs"
23
+ "kdiagrams": "./dist/cli.mjs"
25
24
  },
26
25
  "files": [
27
26
  "dist",
@@ -39,16 +38,16 @@
39
38
  },
40
39
  "dependencies": {
41
40
  "@fontsource/inter": "^5.2.5",
42
- "ignore": "^5.3.2",
41
+ "ignore": "^7.0.6",
43
42
  "tinyglobby": "^0.2.17",
44
- "@kekonic/diagrams-language-service": "1.0.0-rc.5",
45
- "@kekonic/diagrams": "1.0.0-rc.5",
46
- "@kekonic/diagrams-icons": "1.0.0-rc.5",
47
- "@kekonic/diagrams-studio": "1.0.0-rc.5"
43
+ "@kekonic/diagrams-language-service": "1.0.0-rc.7",
44
+ "@kekonic/diagrams": "1.0.0-rc.7",
45
+ "@kekonic/diagrams-studio": "1.0.0-rc.7",
46
+ "@kekonic/diagrams-icons": "1.0.0-rc.7"
48
47
  },
49
48
  "devDependencies": {
50
49
  "@types/node": "^26",
51
- "typescript": "^5",
50
+ "typescript": "^7",
52
51
  "vitest": "^4"
53
52
  },
54
53
  "engines": {