likec4 1.49.0 → 1.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/__app__/src/likec4.js +33 -62
  2. package/__app__/src/main.js +2 -56
  3. package/__app__/src/routes/index.js +81 -16
  4. package/__app__/src/routes/single.js +43 -23
  5. package/__app__/src/style.css +1 -1
  6. package/__app__/src/vendors.js +17891 -17752
  7. package/config/schema.json +16 -0
  8. package/dist/THIRD-PARTY-LICENSES.md +192 -62
  9. package/dist/_chunks/LikeC4.mjs +1 -0
  10. package/dist/_chunks/filesystem.mjs +1230 -0
  11. package/dist/_chunks/index.d.mts +11 -12
  12. package/dist/_chunks/index2.d.mts +173 -84
  13. package/dist/_chunks/libs/@chevrotain/cst-dts-gen.mjs +30 -0
  14. package/dist/_chunks/libs/@chevrotain/regexp-to-ast.mjs +8 -8
  15. package/dist/_chunks/libs/@chevrotain/types.d.mts +1 -0
  16. package/dist/_chunks/libs/@chevrotain/utils.mjs +1 -1
  17. package/dist/_chunks/libs/@hono/mcp.mjs +8 -8
  18. package/dist/_chunks/libs/@hono/node-server.mjs +1 -1
  19. package/dist/_chunks/libs/@logtape/logtape.mjs +3 -3
  20. package/dist/_chunks/libs/@lume/kiwi.mjs +1 -1
  21. package/dist/_chunks/libs/@modelcontextprotocol/sdk.d.mts +114 -14
  22. package/dist/_chunks/libs/@modelcontextprotocol/sdk.mjs +7 -7
  23. package/dist/_chunks/libs/@msgpack/msgpack.mjs +1 -1
  24. package/dist/_chunks/libs/@nanostores/react.d.mts +61 -1
  25. package/dist/_chunks/libs/@nanostores/react.mjs +1 -1
  26. package/dist/_chunks/libs/@smithy/is-array-buffer.mjs +1 -0
  27. package/dist/_chunks/libs/@smithy/util-base64.mjs +1 -1
  28. package/dist/_chunks/libs/ajv.mjs +1 -1
  29. package/dist/_chunks/libs/ansi-align.mjs +2 -0
  30. package/dist/_chunks/libs/ansi-regex.mjs +1 -0
  31. package/dist/_chunks/libs/ansi-styles.mjs +1 -0
  32. package/dist/_chunks/libs/atomically.mjs +1 -1
  33. package/dist/_chunks/libs/birpc.mjs +1 -1
  34. package/dist/_chunks/libs/boxen.d.mts +1 -0
  35. package/dist/_chunks/libs/boxen.mjs +22 -0
  36. package/dist/_chunks/libs/chevrotain-allstar.mjs +2 -2
  37. package/dist/_chunks/libs/chevrotain.mjs +35 -35
  38. package/dist/_chunks/libs/conf.mjs +1 -1
  39. package/dist/_chunks/libs/defu.mjs +1 -1
  40. package/dist/_chunks/libs/esm-env.mjs +1 -1
  41. package/dist/_chunks/libs/eventemitter3.mjs +1 -1
  42. package/dist/_chunks/libs/fast-equals.mjs +1 -1
  43. package/dist/_chunks/libs/find-up-simple.mjs +1 -1
  44. package/dist/_chunks/libs/get-port.mjs +1 -1
  45. package/dist/_chunks/libs/is-docker.mjs +1 -1
  46. package/dist/_chunks/libs/is-error-instance.mjs +1 -1
  47. package/dist/_chunks/libs/is-inside-container.mjs +1 -1
  48. package/dist/_chunks/libs/is-plain-obj.mjs +1 -1
  49. package/dist/_chunks/libs/isexe.mjs +1 -1
  50. package/dist/_chunks/libs/json5.mjs +10 -10
  51. package/dist/_chunks/libs/khroma.mjs +1 -1
  52. package/dist/_chunks/libs/ky.mjs +2 -2
  53. package/dist/_chunks/libs/langium.d.mts +5 -4
  54. package/dist/_chunks/libs/langium.mjs +20 -19
  55. package/dist/_chunks/libs/merge-error-cause.mjs +2 -2
  56. package/dist/_chunks/libs/p-limit.mjs +1 -1
  57. package/dist/_chunks/libs/p-queue.mjs +1 -1
  58. package/dist/_chunks/libs/package-manager-detector.mjs +1 -1
  59. package/dist/_chunks/libs/package-up.mjs +1 -1
  60. package/dist/_chunks/libs/pako.mjs +1 -0
  61. package/dist/_chunks/libs/parse-ms.mjs +1 -1
  62. package/dist/_chunks/libs/pathe.mjs +1 -1
  63. package/dist/_chunks/libs/picomatch.mjs +1 -1
  64. package/dist/_chunks/libs/pretty-ms.mjs +1 -1
  65. package/dist/_chunks/libs/remeda.mjs +2 -1
  66. package/dist/_chunks/libs/safe-stringify.mjs +1 -1
  67. package/dist/_chunks/libs/strip-indent.mjs +1 -1
  68. package/dist/_chunks/libs/tinyrainbow.mjs +1 -1
  69. package/dist/_chunks/libs/ts-graphviz.mjs +3 -3
  70. package/dist/_chunks/libs/ufo.mjs +1 -1
  71. package/dist/_chunks/libs/vscode-languageserver.mjs +1 -0
  72. package/dist/_chunks/libs/which.mjs +1 -1
  73. package/dist/_chunks/libs/word-wrap.mjs +2 -2
  74. package/dist/_chunks/rolldown-runtime.mjs +1 -1
  75. package/dist/_chunks/sequence.mjs +1 -0
  76. package/dist/_chunks/src.mjs +15 -0
  77. package/dist/_chunks/src2.mjs +499 -0
  78. package/dist/cli/index.mjs +84 -231
  79. package/dist/config/index.mjs +1 -1
  80. package/dist/index.d.mts +810 -4
  81. package/dist/index.mjs +1 -1
  82. package/dist/model/index.mjs +1 -1
  83. package/dist/vite-plugin/index.d.mts +3 -0
  84. package/dist/vite-plugin/index.mjs +1 -1
  85. package/dist/vite-plugin/internal.d.mts +1 -2
  86. package/dist/vite-plugin/internal.mjs +1 -1
  87. package/package.json +28 -29
  88. package/react/index.d.mts +2 -2
  89. package/react/index.mjs +52 -76
  90. package/vite-plugin-modules.d.ts +5 -0
  91. package/dist/_chunks/GraphvizBinaryAdapter.mjs +0 -72
  92. package/dist/_chunks/filenames.mjs +0 -14
  93. package/dist/_chunks/libs/@chevrotain/gast.mjs +0 -1
  94. package/dist/_chunks/libs/@logtape/logtape.d.mts +0 -741
  95. package/dist/_chunks/libs/nanostores.d.mts +0 -63
  96. package/dist/_chunks/libs/nanostores.mjs +0 -1
  97. package/dist/_chunks/node.mjs +0 -481
  98. package/dist/_chunks/plugin.mjs +0 -322
  99. package/dist/_chunks/sequence-view.mjs +0 -1
@@ -1,162 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{s as __toESM}from"../_chunks/rolldown-runtime.mjs";import{C as e$3,E as e,G as r,J as t$4,O as e$1,Q as t$5,S as e$4,U as n,X as t$1,k as e$2,t,x as t$3,y as t$2}from"../_chunks/libs/remeda.mjs";import{_ as getAnsiColorFormatter,h as getConsoleSink,m as logger$2,p as configureLogger,v as getConsoleFormatter,y as loggable}from"../_chunks/GraphvizBinaryAdapter.mjs";import"../_chunks/libs/defu.mjs";import{t as u}from"../_chunks/libs/tinyrainbow.mjs";import{t as lib}from"../_chunks/libs/json5.mjs";import"../_chunks/libs/@hono/mcp.mjs";import{B as URI,a as expandToNode,i as toString,n as CompositeGeneratorNode,r as NL,t as joinToNode,z as UriUtils}from"../_chunks/libs/langium.mjs";import"../_chunks/libs/@chevrotain/regexp-to-ast.mjs";import"../_chunks/libs/chevrotain.mjs";import"../_chunks/libs/chevrotain-allstar.mjs";import"../_chunks/libs/eventemitter3.mjs";import"../_chunks/libs/@lume/kiwi.mjs";import"../_chunks/libs/ts-graphviz.mjs";import"../_chunks/libs/word-wrap.mjs";import{t as require_picomatch}from"../_chunks/libs/picomatch.mjs";import{c as withQuery,l as withTrailingSlash,o as joinURL,r as hasProtocol,s as withLeadingSlash}from"../_chunks/libs/ufo.mjs";import{t as prettyMilliseconds}from"../_chunks/libs/pretty-ms.mjs";import{n as stripIndent}from"../_chunks/libs/strip-indent.mjs";import"../_chunks/libs/isexe.mjs";import"../_chunks/libs/which.mjs";import{a as fromWorkspace,i as generateD2,n as generatePuml,r as generateMermaid,t as LikeC4VitePlugin}from"../_chunks/plugin.mjs";import{LikeC4Model as LikeC4Model$1}from"../model/index.mjs";import{t as false_default}from"../_chunks/libs/esm-env.mjs";import"../_chunks/libs/is-docker.mjs";import{t as isInsideContainer}from"../_chunks/libs/is-inside-container.mjs";import{n as fromWorkspace$1}from"../_chunks/node.mjs";import"../_chunks/libs/@modelcontextprotocol/sdk.mjs";import"../_chunks/libs/@hono/node-server.mjs";import"../_chunks/libs/find-up-simple.mjs";import{t as packageUpSync}from"../_chunks/libs/package-up.mjs";import{n as resolveCommand,t as detect}from"../_chunks/libs/package-manager-detector.mjs";import{n as require_semver,t as Conf}from"../_chunks/libs/conf.mjs";import"../_chunks/libs/atomically.mjs";import"../_chunks/libs/ajv.mjs";import{t as ky}from"../_chunks/libs/ky.mjs";import{n as portNumbers,t as getPorts}from"../_chunks/libs/get-port.mjs";import module from"node:module";import{isDeploymentElementModel,isDeploymentRelationModel,isElementModel,isLikeC4ViewModel,isRelationModel}from"@likec4/core/model";import{invariant,nonexhaustive}from"@likec4/core";import{flattenMarkdownOrString}from"@likec4/core/types";import{copyFile,mkdir,mkdtemp,readFile,rm,stat,writeFile}from"node:fs/promises";import{basename,dirname,extname,isAbsolute,join,relative,resolve,sep}from"node:path";import{copyFileSync,existsSync,readdirSync,rmSync,statSync}from"node:fs";import{compareNatural,invariant as invariant$1,sortNaturalByFqn}from"@likec4/core/utils";import{resolve as resolve$1}from"path";import spawn from"nano-spawn";import{tmpdir}from"node:os";import{argv,cwd,exit,hrtime,stdout}from"node:process";import{env,isDevelopment,isMinimal,nodeENV}from"std-env";import yargs from"yargs";import{hideBin}from"yargs/helpers";import _boxen from"boxen";import{fileURLToPath}from"node:url";import react from"@vitejs/plugin-react";import{viteSingleFile}from"vite-plugin-singlefile";import{build,createServer,preview}from"vite";import{setTimeout}from"node:timers/promises";const DEFAULT_ELEMENT_COLORS={primary:{fill:`#3b82f6`,stroke:`#2563eb`},gray:{fill:`#6b7280`,stroke:`#4b5563`},green:{fill:`#22c55e`,stroke:`#16a34a`},red:{fill:`#ef4444`,stroke:`#dc2626`},blue:{fill:`#3b82f6`,stroke:`#2563eb`},indigo:{fill:`#6366f1`,stroke:`#4f46e5`},muted:{fill:`#9ca3af`,stroke:`#6b7280`}};function escapeXml(i){return i.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&apos;`)}function drawioShape(i){switch(i){case`person`:return`shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;`;case`rectangle`:return`shape=rectangle;`;case`browser`:return`shape=rectangle;rounded=1;`;case`mobile`:return`shape=rectangle;rounded=1;`;case`cylinder`:return`shape=cylinder3;whiteSpace=wrap;boundedLbl=1;backgroundOutline=1;size=15;`;case`queue`:return`shape=cylinder3;whiteSpace=wrap;boundedLbl=1;backgroundOutline=1;size=15;`;case`storage`:return`shape=cylinder3;whiteSpace=wrap;boundedLbl=1;backgroundOutline=1;size=15;`;case`bucket`:return`shape=rectangle;rounded=1;`;case`document`:return`shape=document;whiteSpace=wrap;html=1;boundedLbl=1;`;case`component`:return`shape=component;`;default:return`shape=rectangle;`}}function getElementColors(i,a){let o=`$styles`in i&&i.$styles?i.$styles:null;if(o)try{let i=o.colors(a);return{fill:i.elements.fill,stroke:i.elements.stroke}}catch{}return DEFAULT_ELEMENT_COLORS[a]??DEFAULT_ELEMENT_COLORS.primary}function getEdgeStrokeColor(i,a){let o=`$styles`in i&&i.$styles?i.$styles:null;if(o)try{return o.colors(a).relationships.line}catch{}return`#6b7280`}function generateDrawio(i){let a=i.$view,{nodes:s,edges:c}=a,d=new Map,f=2,p=i=>{let a=d.get(i);return a||(a=String(f++),d.set(i,a)),a},m=[],h=[],g=[...s].sort((i,a)=>e(i.parent)&&e(a.parent)?0:e(i.parent)?-1:e(a.parent)?1:i.parent===a.parent?0:i.id.startsWith(a.id+`.`)?1:a.id.startsWith(i.id+`.`)?-1:0),_=i=>{let a=i;return{x:typeof a.x==`number`?a.x:Array.isArray(a.position)?a.position[0]:0,y:typeof a.y==`number`?a.y:Array.isArray(a.position)?a.position[1]:0,width:typeof a.width==`number`?a.width:a.size?.width??120,height:typeof a.height==`number`?a.height:a.size?.height??60}};for(let a of g){let o=p(a.id),s=a.parent?p(a.parent):`1`,c=escapeXml(a.title),d=drawioShape(a.shape),{x:f,y:h,width:g,height:v}=_(a),y=getElementColors(i,a.color),b=y==null?``:`fillColor=${y.fill};strokeColor=${y.stroke};fontColor=${y.stroke};`,x=a.description&&flattenMarkdownOrString(a.description),S=e$1(x)?``:escapeXml(x),C=a.technology&&flattenMarkdownOrString(a.technology),w=e$1(C)?``:escapeXml(C),T=S!==``||w!==``?`<mxUserObject><data key="likec4Description">${S}</data><data key="likec4Technology">${w}</data></mxUserObject>\n `:``;m.push(`<mxCell id="${o}" value="${c}" style="${d}${b}verticalAlign=middle;align=center;overflow=fill;spacingLeft=2;spacingRight=2;spacingTop=2;spacingBottom=2;" vertex="1" parent="${s}">
3
- ${T}<mxGeometry x="${Math.round(f)}" y="${Math.round(h)}" width="${Math.round(g)}" height="${Math.round(v)}" as="geometry" />
4
- </mxCell>`)}for(let a of c){let o=String(f++),s=p(a.source),c=p(a.target),l=a.label?escapeXml(a.label):``,d=getEdgeStrokeColor(i,a.color),m=a.line===`dashed`?`dashed=1;`:a.line===`dotted`?`dashed=1;dashPattern=1 1;`:``;h.push(`<mxCell id="${o}" value="${l}" style="endArrow=block;html=1;rounded=0;exitX=1;exitY=0.5;entryX=0;entryY=0.5;strokeColor=${d};${m}" edge="1" parent="1" source="${s}" target="${c}">
5
- <mxGeometry relative="1" as="geometry" />
6
- </mxCell>`)}let v={x:0,y:0,width:800,height:600};try{let a=i.bounds;a!=null&&typeof a.x==`number`&&(v=a)}catch{}let y=[`<mxCell id="1" vertex="1" parent="0">
7
- <mxGeometry x="${v.x}" y="${v.y}" width="${v.width}" height="${v.height}" as="geometry" />
8
- </mxCell>`,...m,...h].join(`
9
- `);return`<?xml version="1.0" encoding="UTF-8"?>
10
- <mxfile host="LikeC4" modified="${new Date().toISOString()}" agent="LikeC4" version="1.0" etag="" type="device">
11
- <diagram name="${escapeXml(a.id)}" id="likec4-${escapeXml(a.id)}">
12
- <mxGraphModel dx="800" dy="800" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale=1 pageWidth="827" pageHeight="1169" math="0" shadow="0">
13
- <root>
14
- <mxCell id="0" />
15
- ${y}
16
- </root>
17
- </mxGraphModel>
18
- </diagram>
19
- </mxfile>
20
- `}function getAttr(i,a){let o=RegExp(`${a}="([^"]*)"`,`i`),s=i.match(o);return s?s[1]:void 0}function parseNum(i){if(i===void 0||i===``)return;let a=Number.parseFloat(i);return Number.isNaN(a)?void 0:a}function parseStyle(i){let a=new Map;if(!i)return a;for(let o of i.split(`;`)){let i=o.indexOf(`=`);if(i>0){let s=o.slice(0,i).trim(),c=o.slice(i+1).trim();s&&c&&a.set(s.toLowerCase(),c)}}return a}function parseUserData(i){let a={},o=i.match(/<data\s+key="likec4Description"[^>]*>([\s\S]*?)<\/data>/i);o?.[1]&&(a.description=decodeXmlEntities(o[1].trim()));let s=i.match(/<data\s+key="likec4Technology"[^>]*>([\s\S]*?)<\/data>/i);return s?.[1]&&(a.technology=decodeXmlEntities(s[1].trim())),a}function parseDrawioXml(i){let a=[],o=/<mxCell\s+([^>]+?)(?:\s*\/>|>([\s\S]*?)<\/mxCell>)/gi,s=(i,a)=>getAttr(i,a),c;for(;(c=o.exec(i))!==null;){let i=c[1]??``,o=c[2]??``,l=getAttr(i,`id`);if(!l)continue;let d=getAttr(i,`value`),f=getAttr(i,`parent`),p=getAttr(i,`source`),m=getAttr(i,`target`),h=getAttr(i,`vertex`)===`1`,g=getAttr(i,`edge`)===`1`,_=getAttr(i,`style`),v=c[0].match(/<mxGeometry[^>]*>/i),y=v?v[0]:``,b=parseStyle(_??void 0),x=parseUserData(o),S=parseNum(s(y,`x`)),C=parseNum(s(y,`y`)),w=parseNum(s(y,`width`)),T=parseNum(s(y,`height`)),E=b.get(`fillcolor`)??b.get(`fillColor`),D=b.get(`strokecolor`)??b.get(`strokeColor`),O={id:l,...d!=null&&d!==``?{value:decodeXmlEntities(d)}:{},...f!=null&&f!==``?{parent:f}:{},...p!=null&&p!==``?{source:p}:{},...m!=null&&m!==``?{target:m}:{},vertex:h,edge:g,..._!=null&&_!==``?{style:_}:{},...S===void 0?{}:{x:S},...C===void 0?{}:{y:C},...w===void 0?{}:{width:w},...T===void 0?{}:{height:T},...E===void 0?{}:{fillColor:E},...D===void 0?{}:{strokeColor:D},...x.description==null?{}:{description:x.description},...x.technology==null?{}:{technology:x.technology}};a.push(O)}return a}function decodeXmlEntities(i){return i.replace(/&lt;/g,`<`).replace(/&gt;/g,`>`).replace(/&quot;/g,`"`).replace(/&apos;/g,`'`).replace(/&amp;/g,`&`)}function inferKind(i){if(!i)return`container`;let a=i.toLowerCase();return a.includes(`umlactor`)||a.includes(`shape=person`)?`actor`:a.includes(`swimlane`)||a.includes(`shape=rectangle`)&&a.includes(`rounded`)?`system`:`container`}function toId(i){return i.trim().replace(/\s+/g,`_`).replace(/[^a-zA-Z0-9_.-]/g,``).replace(/^[0-9]/,`_$&`)||`element`}function parseDrawioToLikeC4(i){let a=parseDrawioXml(i),o=new Map;for(let i of a)o.set(i.id,i);let s=a.filter(i=>i.vertex&&i.id!==`1`),c=a.filter(i=>i.edge&&i.source&&i.target),l=new Map,d=new Map;for(let i of s)d.set(i.id,i);let f=new Set;function p(i){let a=toId(i||`element`),o=a,s=0;for(;f.has(o);)o=`${a}_${++s}`;return f.add(o),o}for(let i of s)if(i.parent===`1`||!i.parent){let a=p(i.value??i.id);l.set(i.id,a)}let m=!0;for(;m;){m=!1;for(let i of s){if(l.has(i.id))continue;let a=i.parent?l.get(i.parent):null;if(a!=null){let o=p(i.value??i.id);l.set(i.id,`${a}.${o}`),m=!0}}}for(let i of s)l.has(i.id)||l.set(i.id,p(i.value??i.id));let h=new Map,g=0;for(let i of s){let a=i.fillColor?.trim();a&&/^#[0-9A-Fa-f]{3,8}$/.test(a)&&(h.has(a)||h.set(a,`drawio_color_${++g}`))}let _=[];if(h.size>0){_.push(`specification {`);for(let[i,a]of h)_.push(` color ${a} ${i}`);_.push(`}`),_.push(``)}_.push(`model {`),_.push(``);let v=new Map,y=[];for(let[i,a]of l){let o=d.get(i);if(o)if(o.parent===`1`||!o.parent)y.push({cellId:i,fqn:a});else{let s=l.get(o.parent);if(s!=null){let o=v.get(s)??[];o.push({cellId:i,fqn:a}),v.set(s,o)}else y.push({cellId:i,fqn:a})}}function b(i,a,o){let s=d.get(i);if(!s)return;let c=inferKind(s.style),l=s.value&&s.value.trim()||a.split(`.`).pop()||`Element`,f=a.split(`.`).pop(),p=` `.repeat(o),m=s.description?.trim(),g=s.technology?.trim(),y=s.fillColor&&/^#[0-9A-Fa-f]{3,8}$/.test(s.fillColor.trim())?h.get(s.fillColor.trim()):void 0;c===`actor`?_.push(`${p}${f} = actor '${l.replace(/'/g,`''`)}'`):c===`system`?_.push(`${p}${f} = system '${l.replace(/'/g,`''`)}'`):_.push(`${p}${f} = container '${l.replace(/'/g,`''`)}'`);let x=v.get(a);if(x&&x.length>0||m||g||y){if(_.push(`${p}{`),y&&_.push(`${p} style { color ${y} }`),m&&_.push(`${p} description '${m.replace(/'/g,`''`)}'`),g&&_.push(`${p} technology '${g.replace(/'/g,`''`)}'`),x&&x.length>0)for(let i of x)b(i.cellId,i.fqn,o+1);_.push(`${p}}`)}else _.push(`${p}{`),_.push(`${p}}`);_.push(``)}for(let{cellId:i,fqn:a}of y)b(i,a,1);for(let i of c){let a=l.get(i.source),o=l.get(i.target);if(!a||!o)continue;let s=i.value&&i.value.trim()?` '${i.value.replace(/'/g,`''`)}'`:``;_.push(` ${a} -> ${o}${s}`)}return _.push(`}`),_.push(``),_.push(`views {`),_.push(` view index {`),_.push(` include *`),_.push(` }`),_.push(`}`),_.push(``),_.join(`
21
- `)}function toUnion(i){return i.length===0?`never`:i.sort(compareNatural).map(i=>` | ${JSON.stringify(i)}`).join(`
22
- `).trimStart()}function elementIdToUnion(i){let a=t(i);return a.length===0?`never`:t$1(a,sortNaturalByFqn,t$2(i=>` | ${JSON.stringify(i.id)}`)).join(`
23
- `).trimStart()}function generateAux(i,a={}){let{useCorePackage:o=!1}=a;return`
24
- import type { Aux, SpecAux } from '${o?`@likec4/core/types`:`likec4/model`}';
25
-
26
- export type $Specs = SpecAux<
27
- // Element kinds
28
- ${toUnion(t$3(i.specification.elements))},
29
- // Deployment kinds
30
- ${toUnion(t$3(i.specification.deployments??{}))},
31
- // Relationship kinds
32
- ${toUnion(t$3(i.specification.relationships??{}))},
33
- // Tags
34
- ${toUnion(t$3(i.specification.tags??{}))},
35
- // Metadata keys
36
- ${toUnion(i.specification.metadataKeys??[])}
37
- >
38
-
39
- export type $Aux = Aux<
40
- ${JSON.stringify(i.stage)},
41
- // Elements
42
- ${elementIdToUnion(i.$data.elements)},
43
- // Deployments
44
- ${elementIdToUnion(i.$data.deployments.elements)},
45
- // Views
46
- ${toUnion(t$3(i.$data.views))},
47
- // Project ID
48
- ${JSON.stringify(i.projectId)},
49
- $Specs
50
- >
51
-
52
- export type $ElementId = $Aux['ElementId']
53
- export type $DeploymentId = $Aux['DeploymentId']
54
- export type $ViewId = $Aux['ViewId']
55
-
56
- export type $ElementKind = $Aux['ElementKind']
57
- export type $RelationKind = $Aux['RelationKind']
58
- export type $DeploymentKind = $Aux['DeploymentKind']
59
- export type $Tag = $Aux['Tag']
60
- export type $Tags = readonly $Aux['Tag'][]
61
- export type $MetadataKey = $Aux['MetadataKey']
62
- `.trimStart()}function generateLikeC4Model(i,a={}){let o=generateAux(i,a),{useCorePackage:s=!1}=a;return`
63
- /* prettier-ignore-start */
64
- /* eslint-disable */
65
-
66
- /******************************************************************************
67
- * This file was generated
68
- * DO NOT EDIT MANUALLY!
69
- ******************************************************************************/
70
-
71
- import { LikeC4Model } from '${s?`@likec4/core`:`likec4`}/model'
72
- ${o}
73
-
74
- export const likec4model: LikeC4Model<$Aux> = new LikeC4Model(${lib.stringify(i.$data,{space:2,quote:`'`})} as any) as any
75
-
76
- /* prettier-ignore-end */
77
- `.trimStart()}function generateViewId(i){return joinToNode(i,i=>expandToNode`${lib.stringify(i.id)}`,{separator:` | `})}function generateViewsDataTs(i){let a=Array.from(i),o=new CompositeGeneratorNode;return o.appendTemplate`
78
- /******************************************************************************
79
- * This file was generated
80
- * DO NOT EDIT MANUALLY!
81
- ******************************************************************************/
82
- /* prettier-ignore-start */
83
- /* eslint-disable */
84
-
85
- // @ts-nocheck
86
-
87
- import type { DiagramView } from 'likec4'
88
- `.append(NL,NL),a.length===0?(o.append(`export {}`,NL),toString(o)):(o.appendTemplate`
89
- export type LikeC4ViewId = ${generateViewId(a)};
90
- export const LikeC4Views = {
91
- `.indent({indentation:2,indentedChildren(i){i.appendNewLineIf(a.length>1).append(joinToNode(a,i=>expandToNode`${lib.stringify(i.id)}: (${lib.stringify(i)} as unknown) as DiagramView`,{separator:`,`,appendNewLineIfNotEmpty:!0}))}}).append(`} as const satisfies Record<LikeC4ViewId, DiagramView>`,NL,NL).appendTemplate`
92
- export type LikeC4Views = typeof LikeC4Views
93
-
94
- export function isLikeC4ViewId(value: unknown): value is LikeC4ViewId {
95
- return (
96
- value != null &&
97
- typeof value === 'string' &&
98
- !!LikeC4Views[value]
99
- )
100
- }
101
-
102
- /* prettier-ignore-end */
103
- `.append(NL),toString(o))}function generateReactTypes(i,a={}){let{useCorePackage:o=!1}=a;invariant$1(!i.isParsed(),`can not generate react types for parsed model`);let s=generateAux(i,a);return`
104
- /* prettier-ignore-start */
105
- /* eslint-disable */
106
-
107
- /******************************************************************************
108
- * This file was generated
109
- * DO NOT EDIT MANUALLY!
110
- ******************************************************************************/
111
-
112
- import type { PropsWithChildren } from 'react'
113
- import type { JSX } from 'react/jsx-runtime'
114
- import type { LikeC4Model } from '${o?`@likec4/core`:`likec4`}/model'
115
- import type { LayoutedView } from '${o?`@likec4/core/types`:`likec4/model`}'
116
- import type {
117
- LikeC4ViewProps as GenericLikeC4ViewProps,
118
- ReactLikeC4Props as GenericReactLikeC4Props
119
- } from 'likec4/react'
120
-
121
- ${s}
122
-
123
- declare function isLikeC4ViewId(value: unknown): value is $ViewId;
124
-
125
- declare const likec4model: LikeC4Model<$Aux>;
126
- declare function useLikeC4Model(): LikeC4Model<$Aux>;
127
- declare function useLikeC4View(viewId: $ViewId): LayoutedView<$Aux>;
128
-
129
- declare function LikeC4ModelProvider(props: PropsWithChildren): JSX.Element;
130
-
131
- type IconRendererProps = {
132
- node: {
133
- id: string
134
- title: string
135
- icon?: string | undefined
136
- }
137
- }
138
- declare function RenderIcon(props: IconRendererProps): JSX.Element;
139
-
140
- type LikeC4ViewProps = GenericLikeC4ViewProps<$Aux>;
141
- declare function LikeC4View({viewId, ...props}: LikeC4ViewProps): JSX.Element;
142
-
143
- type ReactLikeC4Props = GenericReactLikeC4Props<$Aux>
144
- declare function ReactLikeC4({viewId, ...props}: ReactLikeC4Props): JSX.Element;
145
-
146
- export {
147
- type LikeC4ViewProps,
148
- type ReactLikeC4Props,
149
- isLikeC4ViewId,
150
- useLikeC4Model,
151
- useLikeC4View,
152
- likec4model,
153
- LikeC4ModelProvider,
154
- LikeC4View,
155
- RenderIcon,
156
- ReactLikeC4
157
- }
158
- /* prettier-ignore-end */
159
- `.trimStart()}var name=`likec4`,version=`1.49.0`;const logger$1=logger$2.getChild(`cli`);function createLikeC4Logger(i){let a=logger$2.getChild(i);return{info(i){a.info(i)},warn(i){if(i instanceof Error){a.warn(`${u.red(i.name+` `+i.message)}`,{msg:i});return}if(typeof i==`string`){a.warn(i);return}a.warn`${i}`},warnOnce(i){a.warn(i)},error(i,o){let s=o?.error??i;if(s instanceof Error){if(i===s){a.error(`${u.red(s.name+` `+s.message)}`,{error:s});return}a.error(u.red(i),{error:s});return}if(typeof i==`string`){a.error(u.red(i));return}a.error`${i}`},clearScreen:function(i){},hasErrorLogged:function(i){throw Error(`Function not implemented.`)},hasWarned:!1}}function inMillis(i){let[a,o]=hrtime(i),s=a*1e3+o/1e6;return{ms:s,pretty:prettyMilliseconds(s)}}function startTimer(i){let a=hrtime();return{stopAndLog(o=`done in `){o=u.green(`${o}${inMillis(a).pretty}`),(i||logger$1).info(o)}}}function boxen(i,a){console.log(_boxen(i,{padding:1,margin:1,dimBorder:!0,...a}))}const viteLogger=createLikeC4Logger(`vite`),_dirname=dirname(fileURLToPath(import.meta.url)),JsBanners={banner:`/* prettier-ignore-start */
2
+ import{s as e}from"../_chunks/rolldown-runtime.mjs";import"../_chunks/libs/birpc.mjs";import{$ as t,C as n,K as r,W as i,Y as a,Z as o,k as s,t as c,w as l}from"../_chunks/libs/remeda.mjs";import"../_chunks/libs/@logtape/logtape.mjs";import"../_chunks/libs/merge-error-cause.mjs";import"../_chunks/libs/is-error-instance.mjs";import"../_chunks/libs/is-plain-obj.mjs";import"../_chunks/libs/safe-stringify.mjs";import{_ as u,b as d,g as f,n as p,u as m,v as h,x as g,y as _}from"../_chunks/filesystem.mjs";import"../_chunks/libs/defu.mjs";import"../_chunks/libs/pathe.mjs";import{t as v}from"../_chunks/libs/tinyrainbow.mjs";import{t as y}from"../_chunks/libs/json5.mjs";import"../_chunks/libs/@hono/mcp.mjs";import"../_chunks/src.mjs";import{B as b,V as x}from"../_chunks/libs/langium.mjs";import"../_chunks/libs/@chevrotain/regexp-to-ast.mjs";import"../_chunks/libs/chevrotain.mjs";import"../_chunks/libs/@chevrotain/cst-dts-gen.mjs";import"../_chunks/libs/@chevrotain/utils.mjs";import"../_chunks/libs/chevrotain-allstar.mjs";import"../_chunks/libs/fast-equals.mjs";import"../_chunks/sequence.mjs";import"../_chunks/libs/@lume/kiwi.mjs";import"../_chunks/libs/ts-graphviz.mjs";import"../_chunks/libs/word-wrap.mjs";import"../_chunks/libs/khroma.mjs";import"../_chunks/libs/p-limit.mjs";import"../_chunks/libs/eventemitter3.mjs";import"../_chunks/libs/p-queue.mjs";import"../_chunks/libs/isexe.mjs";import"../_chunks/libs/which.mjs";import"../_chunks/libs/@modelcontextprotocol/sdk.mjs";import{t as S}from"../_chunks/libs/picomatch.mjs";import{c as ee,l as te,o as ne,r as re,s as ie}from"../_chunks/libs/ufo.mjs";import"../_chunks/libs/parse-ms.mjs";import{t as ae}from"../_chunks/libs/pretty-ms.mjs";import"../_chunks/libs/@hono/node-server.mjs";import"../_chunks/libs/@msgpack/msgpack.mjs";import"../_chunks/libs/@smithy/is-array-buffer.mjs";import"../_chunks/libs/@smithy/util-base64.mjs";import{n as oe}from"../_chunks/libs/strip-indent.mjs";import{a as se,c as ce,d as le,f as C,i as ue,l as de,n as fe,o as pe,r as me,s as he,t as ge,u as _e}from"../_chunks/src2.mjs";import"../_chunks/libs/pako.mjs";import{LikeC4Model as ve}from"../model/index.mjs";import{t as ye}from"../_chunks/libs/esm-env.mjs";import"../_chunks/libs/is-docker.mjs";import{t as w}from"../_chunks/libs/is-inside-container.mjs";import{n as T,t as be}from"../_chunks/LikeC4.mjs";import"../_chunks/libs/ansi-regex.mjs";import{t as xe}from"../_chunks/libs/boxen.mjs";import"../_chunks/libs/ansi-align.mjs";import"../_chunks/libs/ansi-styles.mjs";import"../_chunks/libs/find-up-simple.mjs";import{t as Se}from"../_chunks/libs/package-up.mjs";import{n as Ce,t as we}from"../_chunks/libs/package-manager-detector.mjs";import{n as Te,t as Ee}from"../_chunks/libs/conf.mjs";import"../_chunks/libs/atomically.mjs";import"../_chunks/libs/ajv.mjs";import{t as De}from"../_chunks/libs/ky.mjs";import{n as E,t as Oe}from"../_chunks/libs/get-port.mjs";import{t as ke}from"../_chunks/libs/vscode-languageserver.mjs";import Ae from"node:module";import{isDeploymentElementModel as je,isDeploymentRelationModel as Me,isElementModel as Ne,isLikeC4ViewModel as Pe,isRelationModel as Fe}from"@likec4/core/model";import{invariant as Ie,nonexhaustive as Le}from"@likec4/core";import Re from"nano-spawn";import{tmpdir as D}from"node:os";import{resolve as O}from"path";import{env as ze,isProduction as Be,nodeENV as Ve}from"std-env";import{copyFile as He,mkdir as k,mkdtemp as A,readFile as Ue,readdir as We,realpath as Ge,rm as Ke,stat as j,writeFile as M}from"node:fs/promises";import{basename as N,dirname as P,extname as F,isAbsolute as qe,join as I,relative as L,resolve as R,sep as Je}from"node:path";import{copyFileSync as Ye,existsSync as z,readdirSync as Xe,rmSync as Ze,statSync as Qe}from"node:fs";import{argv as $e,cwd as B,exit as et,hrtime as tt,stdout as nt}from"node:process";import rt from"yargs";import{hideBin as it}from"yargs/helpers";import{fileURLToPath as at}from"node:url";import ot from"@vitejs/plugin-react";import{viteSingleFile as st}from"vite-plugin-singlefile";import{build as V,createServer as ct,preview as lt}from"vite";import{setTimeout as ut}from"node:timers/promises";var dt=`likec4`,H=`1.51.0`;const U=u.getChild(`cli`);function W(e){let t=u.getChild(e);return{info(e){t.info(e)},debug(e,...n){n.length===0?t.debug(e):t.debug(e,{args:n})},warn(e){if(e instanceof Error){t.warn(`${v.red(e.name+` `+e.message)}`,{msg:e});return}if(typeof e==`string`){t.warn(e);return}t.warn`${e}`},warnOnce(e){t.warn(e)},error(e,n){let r=n?.error??e;if(r instanceof Error){if(e===r){t.error(`${v.red(r.name+` `+r.message)}`,{error:r});return}t.error(v.red(e),{error:r});return}if(typeof e==`string`){t.error(v.red(e));return}t.error`${e}`},clearScreen:function(e){},hasErrorLogged:function(e){return!1},hasWarned:!1}}function ft(e){let[t,n]=tt(e),r=t*1e3+n/1e6;return{ms:r,pretty:ae(r)}}function G(e){let t=tt();return{stopAndLog(n=`done in `){n=v.green(`${n}${ft(t).pretty}`),(e||U).info(n)}}}function K(e,t){console.log(xe(e,{padding:1,margin:1,dimBorder:!0,...t}))}const pt=W(`vite`),mt=P(at(import.meta.url)),ht={banner:`/* prettier-ignore-start */
160
3
  /* eslint-disable */
161
4
 
162
5
  /******************************************************************************
@@ -167,29 +10,29 @@ export {
167
10
  `,footer:`
168
11
 
169
12
  /* prettier-ignore-end */
170
- `};function findPkgRoot(){let i=packageUpSync({cwd:_dirname});if(!i)throw Error(`likec4 package folder not found`);return dirname(i)}function viteAppRoot(){let i=[resolve(findPkgRoot(),`__app__`),resolve(_dirname,`../__app__`),resolve(_dirname,`../../__app__`),resolve(_dirname,`../../dist/__app__`)],a=r(i,existsSync);if(!a)throw logger$2.error(`likec4 app root does not exist, tried:\n${i.join(`
171
- `)}`),Error(`likec4 app root does not exist`);return a}async function mkTempPublicDir(){let i=await mkdtemp(join(tmpdir(),`.likec4-public-`));return await writeFile(join(i,`likec4-views.js`),`// generated by likec4
172
- `),i}function relativeToCwd(i){return relative(cwd(),i)}const chunkSizeWarningLimit=1e4;function viteAliases(){let i=findPkgRoot();return{"likec4/icons":`@likec4/icons`,"likec4/react":resolve(i,`react/index.mjs`),"likec4/model":resolve(i,`dist/model/index.mjs`),"likec4/vite-plugin/internal":resolve(i,`dist/vite-plugin/internal.mjs`)}}const viteConfig=async({languageServices:i,likec4AssetsDir:a,...o})=>{let s=o.customLogger??viteLogger,c=viteAppRoot();s.info(`${u.cyan(`likec4 app root`)} ${u.dim(relativeToCwd(c))}`);let l=o.outputDir??resolve(i.workspace,`dist`);s.info(u.cyan(`outDir`)+` `+u.dim(relativeToCwd(l)));let d=`/`;o.base&&(d=withTrailingSlash(o.base),!hasProtocol(d)&&d!==`./`&&(d=withLeadingSlash(d))),d!==`/`&&s.info(`${u.green(`app base url`)} ${u.dim(d)}`);let f=o.webcomponentPrefix??`likec4`,p=o.title??`LikeC4`,m=o.outputSingleFile??!1;return{isDev:!1,likec4AssetsDir:a,webcomponentPrefix:f,title:p,root:c,languageServices:i,clearScreen:!1,base:d,resolve:{conditions:[`production`],dedupe:[`react`,`react-dom`,`react/jsx-runtime`,`react/jsx-dev-runtime`,`react-dom/client`],alias:{...viteAliases(),"likec4/previews":a}},configFile:!1,mode:`production`,optimizeDeps:{include:[`react`,`react-dom`,`react/jsx-runtime`,`react/jsx-dev-runtime`,`react-dom/client`,`@likec4/core/types`,`@likec4/core/model`,`@likec4/core/styles`,`@likec4/core/utils`,`@likec4/core`,`likec4/vite-plugin/internal`],noDiscovery:!0},esbuild:{tsconfigRaw:{compilerOptions:{target:`ESNext`,jsx:`react-jsx`}}},define:{WEBCOMPONENT_PREFIX:JSON.stringify(f),PAGE_TITLE:JSON.stringify(p),__USE_HASH_HISTORY__:o?.useHashHistory===!0?`true`:`false`,"process.env.NODE_ENV":`"production"`},build:{outDir:l,emptyOutDir:!1,sourcemap:!1,cssMinify:!1,minify:!0,copyPublicDir:!0,chunkSizeWarningLimit,assetsInlineLimit:1e5,rollupOptions:{treeshake:{preset:`recommended`},...!m&&{input:[resolve(c,`index.html`),resolve(c,`src`,`main.js`),resolve(c,`src`,`fonts.css`),resolve(c,`src`,`style.css`)],output:{manualChunks:i=>{if(!(i.endsWith(`.css`)||i.endsWith(`.html`)||i.includes(`likec4/icons`)||i.includes(`const.js`))){if(i.includes(`__app__`)){let a=i.match(/__app__\/src\/([\w]+)\.js/)?.[1];return a?a[1]:void 0}if(i.includes(`likec4`))return`likec4`;if(i.includes(`node_modules`))return`vendors`}}}}}},customLogger:s,plugins:[react(),LikeC4VitePlugin({languageServices:i.languageServices}),m?viteSingleFile():void 0]}};async function viteWebcomponentConfig({languageServices:i,outDir:a,base:o,webcomponentPrefix:s=`likec4`,filename:c=`likec4-views.js`}){let l=createLikeC4Logger([`vite`,`webcomponent`]),d=viteAppRoot();return l.info(u.cyan(`outDir`)+` `+u.dim(a)),{root:d,clearScreen:!1,base:o,configFile:!1,publicDir:!1,mode:`production`,resolve:{conditions:[`production`],alias:viteAliases(),dedupe:[`react`,`react-dom`,`react/jsx-runtime`,`react/jsx-dev-runtime`,`react-dom/client`]},define:{WEBCOMPONENT_PREFIX:JSON.stringify(s),"process.env.NODE_ENV":`"production"`},esbuild:{...JsBanners,tsconfigRaw:{compilerOptions:{target:`ESNext`,jsx:`react-jsx`}}},build:{outDir:a,emptyOutDir:!1,sourcemap:!1,minify:!0,assetsInlineLimit:1024*1024,chunkSizeWarningLimit,lib:{entry:`src/webcomponent.js`,fileName(i,a){return c},formats:[`iife`],name:`LikeC4Views`},rollupOptions:{treeshake:{preset:`recommended`},output:{format:`iife`,hoistTransitiveImports:!1,compact:!0}}},customLogger:l,plugins:[react(),LikeC4VitePlugin({languageServices:i.languageServices})]}}const Assets=[`favicon.ico`,`robots.txt`];async function viteBuild({buildWebcomponent:i=!0,webcomponentPrefix:a=`likec4`,title:o,languageServices:s,likec4AssetsDir:c,outputSingleFile:l,...d}){c??=await mkdtemp(join(tmpdir(),`.likec4-assets-`));let f=await viteConfig({...d,languageServices:s,likec4AssetsDir:c,webcomponentPrefix:a,title:o,outputSingleFile:l}),p=!existsSync(f.build.outDir)||readdirSync(f.build.outDir).length===0,m=await mkTempPublicDir();for(let i of Assets){let a=resolve(f.root,i);existsSync(a)&&copyFileSync(a,resolve(m,i))}let h=s.languageServices.projects();if(h.length===1){let i=await s.viewsService.computedViews(),a=await s.diagrams();if(a.length===0)throw process.exitCode=1,Error(`no views found`);a.length===i.length?f.customLogger.info(`${u.dim(`workspace:`)} ${u.green(`✓ all views layouted`)}`):f.customLogger.warn(`${u.dim(`workspace:`)} ${u.yellow(`✗ layouted ${a.length} of ${i.length} views`)}`),a.forEach(i=>{(i.hasLayoutDrift||i.drifts&&i.drifts.length>0)&&f.customLogger.warn(u.dim(`view`)+` `+u.red(i.id)+` `+u.yellow(`is out of date, layout drift detected`))})}else for(let i of h){let a=await s.viewsService.computedViews(i.id);a.length===0?f.customLogger.warn(`${u.dim(`project:`)} ${i.id} ${u.yellow(`✗ no views found`)}`):f.customLogger.info(`${u.dim(`project:`)} ${i.id} ${u.green(`${a.length} views`)}`)}if(i&&!l&&await build(await viteWebcomponentConfig({webcomponentPrefix:a,languageServices:s,outDir:m,base:f.base})),await build({...f,publicDir:m,mode:`production`}),l){if(!p){f.customLogger.warn(u.yellow(`outDir was not empty, skipping cleanup`));return}for(let i of readdirSync(resolve(f.build.outDir)).filter(i=>i!==`index.html`))rmSync(resolve(f.build.outDir,i),{recursive:!0})}let g=resolve(f.build.outDir,`index.html`);existsSync(g)&&copyFileSync(g,resolve(f.build.outDir,`404.html`))}function isInstalled(i){try{return!!module.createRequire(import.meta.url).resolve(i)}catch(i){return logger$1.debug(loggable(i)),!1}}async function ensureReact(){if(isInstalled(`react`)&&isInstalled(`react-dom`)){logger$1.debug(`react already installed`);return}logger$1.debug(`react not installed`);let i=await detect();i||(logger$1.error`Package manager not detected, please install dependencies manually: ${`react`} ${`react-dom`}`,process.exit(1));let a=resolveCommand(i.agent,`add`,[`react`,`react-dom`]);a||(logger$1.error`Please install dependencies manually: ${`react`} ${`react-dom`}`,process.exit(1));try{await spawn(a.command,a.args,{stdio:`inherit`})}catch(i){logger$1.debug(loggable(i)),logger$1.error`Please install dependencies manually: ${`react`} ${`react-dom`}`,process.exit(1)}}const path$1={type:`string`,desc:`<directory> with LikeC4 sources (default is current directory)`,normalize:!0,default:`.`,coerce:resolve},useDotBin={alias:`use-dot-bin`,boolean:!0,type:`boolean`,desc:isInsideContainer()?`enabled in container, disable by --no-use-dot`:`use graphviz binaries ("dot" should be on PATH)`,default:isInsideContainer()},useCorePackage={boolean:!0,type:`boolean`,desc:"use `@likec4/core` package in types",default:!1},useHashHistory={boolean:!0,type:`boolean`,desc:`use hash history for navigation, e.g. "/#/view" instead of "/view"`},outdir={alias:`o`,type:`string`,desc:`output directory`,normalize:!0,nargs:1,coerce:resolve},webcomponentPrefix={alias:`w`,type:`string`,desc:`prefix for Webcomponents, e.g "c4" generates <c4-view ../>`,default:`likec4`,nargs:1},title={alias:`t`,type:`string`,desc:`base title of the app pages (default is "LikeC4")`,default:`LikeC4`,nargs:1},base={alias:[`base-url`],type:`string`,desc:`base url the app is being served from, e.g. "/" or "/pages/"`,nargs:1},outputSingleFile={boolean:!0,type:`boolean`,desc:`outputs a single self-contained HTML file with all required resources inlined`},listen={alias:`l`,type:`string`,...isInsideContainer()?{desc:`listen 0.0.0.0 by default in container`,default:`0.0.0.0`}:{desc:`ip address of the network interface to listen on`},nargs:1},port={type:`number`,desc:`port number for the dev server (default is 5173, or PORT environment variable)`,nargs:1},project={alias:`p`,type:`string`,desc:`select LikeC4 project by name (e.g. "my-project") or by path`,nargs:1};function _usingCtx(){var i=typeof SuppressedError==`function`?SuppressedError:function(i,a){var o=Error();return o.name=`SuppressedError`,o.error=i,o.suppressed=a,o},a={},o=[];function s(i,a){if(a!=null){if(Object(a)!==a)throw TypeError(`using declarations can only be used with objects, functions, null, or undefined.`);if(i)var s=a[Symbol.asyncDispose||Symbol.for(`Symbol.asyncDispose`)];if(s===void 0&&(s=a[Symbol.dispose||Symbol.for(`Symbol.dispose`)],i))var c=s;if(typeof s!=`function`)throw TypeError(`Object is not disposable.`);c&&(s=function i(){try{c.call(a)}catch(i){return Promise.reject(i)}}),o.push({v:a,d:s,a:i})}else i&&o.push({d:a,a:i});return a}return{e:a,u:s.bind(null,!1),a:s.bind(null,!0),d:function s(){var c,l=this.e,d=0;function f(){for(;c=o.pop();)try{if(!c.a&&d===1)return d=0,o.push(c),Promise.resolve().then(f);if(c.d){var i=c.d.call(c.v);if(c.a)return d|=2,Promise.resolve(i).then(f,p)}else d|=1}catch(i){return p(i)}if(d===1)return l===a?Promise.resolve():Promise.reject(l);if(l!==a)throw l}function p(o){return l=l===a?o:new i(o,l),f()}return f()}}}const buildCmd=i=>i.command({command:`build [path]`,aliases:[`bundle`],describe:`Build a static website`,builder:i=>i.positional(`path`,path$1).option(`output`,{alias:`o`,type:`string`,desc:`output directory for production build`,normalize:!0,coerce:resolve}).option(`base`,base).option(`use-hash-history`,useHashHistory).option(`use-dot`,useDotBin).option(`webcomponent-prefix`,webcomponentPrefix).option(`title`,title).option(`output-single-file`,outputSingleFile).example(`${u.green(`$0 build -o ./build ./src`)}`,u.gray(`Search for likec4 files in 'src' and output static site to 'build'`)),handler:async i=>{try{var a=_usingCtx();let o={useHashHistory:i[`use-hash-history`]??!1,useDotBin:i[`use-dot`],webcomponentPrefix:i[`webcomponent-prefix`],outputSingleFile:i[`output-single-file`]??!1};await ensureReact();let s=createLikeC4Logger(`c4:build`),c=a.a(await fromWorkspace$1(i.path,{graphviz:i[`use-dot`]?`binary`:`wasm`,watch:!1})),l=i.output??resolve(c.workspace,`dist`),d=resolve(l,`assets`);await viteBuild({base:i.base,useHashHistory:o.outputSingleFile||o.useHashHistory,customLogger:s,webcomponentPrefix:o.webcomponentPrefix,title:i.title,languageServices:c,likec4AssetsDir:d,outputDir:l,outputSingleFile:o.outputSingleFile})}catch(i){a.e=i}finally{await a.d()}}});var import_semver=__toESM(require_semver(),1);const conf=new Conf({projectName:name,serialize:i=>lib.stringify(i,null,2),deserialize:i=>lib.parse(i)}),ENV_CHECK_UPDATE=`check-update`;function notifyAvailableUpdate(){if(isMinimal||nodeENV===ENV_CHECK_UPDATE)return;let i=conf.get(`lastUpdateCheck`),a=conf.get(`latestVersion`);if(e$2(a)||e(i)||i+864e5<Date.now())try{spawn(`likec4`,[`check-update`],{stdio:`ignore`,preferLocal:!0,detached:!0,env:{NODE_ENV:ENV_CHECK_UPDATE}}).catch(()=>{})}catch{}a&&(0,import_semver.gt)(a,version)&&boxen([`Update available: `,u.dim(version),u.reset(` → `),u.green(a)].join(``))}async function checkAvailableUpdate(){try{let i=await fetchLatestVersion();invariant(i,`No version found in latest npm`),conf.set({lastUpdateCheck:Date.now(),latestVersion:i}),(0,import_semver.gt)(i,version)?boxen([`Update available: `,u.dim(version),u.reset(` → `),u.green(i)].join(``)):boxen(u.dim(`Up to date: `)+` `+u.green(version))}catch(i){logger$1.error(loggable(i))}}async function fetchLatestVersion(){return(await ky(`https://registry.npmjs.org/likec4/latest`,{headers:{accept:`application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*`},keepalive:!0}).json()).version}const checkUpdateCmd=i=>i.command({command:`check-update`,describe:`Check for updates`,handler:async()=>{await checkAvailableUpdate()}});function ensureProjectId(i,a){if(!a)return i.languageServices.projectsManager.ensureProjectId();let o=resolve(a);if(o===i.workspace)return i.languageServices.projectsManager.ensureProjectId();if(existsSync(o)&&statSync(o).isDirectory()){logger$1.debug`Project path exists: ${o}`;let a=URI.file(o.endsWith(sep)?o:o+sep),s=i.languageServices.projects().find(i=>i.folder.fsPath===a.fsPath);if(s)return logger$1.debug`Found project ${s.id} at path: ${o}`,s.id;logger$1.debug`No project registered at path: ${o}`}return i.languageServices.projectsManager.ensureProjectId(a)}function ensureProject(i,a){let o=ensureProjectId(i,a),s=i.languageServices.projectsManager.getProject(o);return i.languageServices.projectsManager.defaultProjectId=o,{projectId:o,projectFolder:s.folderUri.fsPath,config:s.config}}const logger=logger$1.getChild(`generator`);async function customHandler({name:i,path:a,useDotBin:o,project:s}){try{var c=_usingCtx();let l=startTimer(logger),d=c.a(await fromWorkspace(a,{graphviz:o?`binary`:`wasm`,watch:!1})),{projectId:f,config:p}=ensureProject(d,s);s&&logger.info(`${u.dim(`project`)} ${u.green(f)}`);let m=p.generators?.[i];if(!m)throw logger.error(u.red(`generator ${i} does not exist in project config`)),Error(`generator ${i} does not exist in project config`);logger.info(`${u.dim(`generator`)} ${u.green(i)}`),await runCustomGenerator({likec4:d,model:await d.layoutedModel(f),generator:m,logger:logger.getChild(i)}),l.stopAndLog()}catch(i){c.e=i}finally{await c.d()}}async function runCustomGenerator({likec4:i,model:a,generator:o,logger:s}){let c=i.languageServices,l=new Set,d=c.project(a.project.id),f=a.project.id;s.debug(`${u.dim(`runnig for project:`)} ${u.green(d.id)}`),await Promise.resolve().then(()=>o({likec4model:a,ctx:{workspace:i.languageServices.workspaceUri,project:d,locate:i=>{let a=null;switch(!0){case isElementModel(i):a=c.locate({element:i.id,projectId:f});break;case isLikeC4ViewModel(i):a=c.locate({view:i.id,projectId:f});break;case isDeploymentElementModel(i):a=c.locate({deployment:i.id,projectId:f});break;case isRelationModel(i):case isDeploymentRelationModel(i):a=c.locate({relation:i.id,projectId:f});break;default:nonexhaustive(i)}if(!a)throw s.error(`Cannot locate ${i.id}`,{target:i}),Error(`Cannot locate ${i.id}`);let o=URI.parse(a.uri);return{range:a.range,document:o,relativePath:UriUtils.relative(d.folder,o),folder:UriUtils.dirname(o).fsPath,filename:UriUtils.basename(o)}},write:async({path:i,content:a})=>{let o;o=Array.isArray(i)?resolve(d.folder.fsPath,...i):URI.isUri(i)?i.fsPath:resolve(d.folder.fsPath,`${i}`);let c=dirname(o);l.has(c)||(existsSync(c)||(s.debug(`${u.dim(`create directory`)} ${c}`),await mkdir(c,{recursive:!0})),l.add(c)),s.debug(`${u.dim(`write`)} ${o}`),await writeFile(o,a)},abort:i=>{throw s.error(i||`Generator aborted`),Error(i||`Generator aborted`)}}}))}async function singleFileCodegenAction(i,a,o){a??=resolve(i.workspace,`likec4.generated.ts`),extname(a)!==`.ts`&&(a+=`.ts`),await mkdir(dirname(a),{recursive:!0});let s=generateViewsDataTs([...await i.diagrams()]);await writeFile(a,s),o.info(`${u.dim(`generated`)} ${relative(process.cwd(),a)}`)}async function dotCodegenAction(i,a,o){await mkdir(a,{recursive:!0}),o.info(`${u.dim(`format`)} ${u.green(`dot`)}`),o.info(`${u.dim(`outdir`)} ${a}`);let s=new Set,c=await i.computedModel(),l=t(c.$data.views),d=0;for(let f of l)try{let l=await i.viewsService.layouter.dot({view:f,styles:c.$styles}),p=`.`;f.sourcePath&&(p=dirname(f.sourcePath)),p=resolve(a,p),s.has(p)||(await mkdir(p,{recursive:!0}),s.add(p));let m=resolve(p,f.id+`.dot`);await writeFile(m,l),o.info(`${u.dim(`generated`)} ${relative(process.cwd(),m)}`),d++}catch(i){logger$1.error(`error while generating ${f.id}`,{error:i})}d>0&&o.info(`${u.dim(`total`)} ${d} files`)}async function multipleFilesCodegenAction(i,a,o,s){await mkdir(o,{recursive:!0}),s.info(`${u.dim(`format`)} ${u.green(a)}`),s.info(`${u.dim(`outdir`)} ${o}`);let c,l;switch(a){case`d2`:c=`.d2`,l=generateD2;break;case`mermaid`:c=`.mmd`,l=generateMermaid;break;case`plantuml`:c=`.puml`,l=generatePuml;break;default:nonexhaustive(a)}let d=new Set,f=await i.layoutedModel(),p=0;for(let i of f.views()){let a=i.$view;try{let f=`.`;a.sourcePath&&(f=dirname(a.sourcePath)),f=resolve(o,f),d.has(f)||(await mkdir(f,{recursive:!0}),d.add(f));let m=resolve(f,a.id+c);await writeFile(m,l(i)),s.info(`${u.dim(`generated`)} ${relative(process.cwd(),m)}`),p++}catch(i){s.error(`error while generating ${a.id}`,{error:i})}}p>0&&s.info(`${u.dim(`total`)} ${p} files`)}async function legacyHandler({path:i,useDotBin:a,...o}){let s=createLikeC4Logger(`c4:codegen`),c=startTimer(s),l=await fromWorkspace(i,{graphviz:a?`binary`:`wasm`,watch:!1});if(l.ensureSingleProject(),(await l.viewsService.computedViews()).length===0)throw s.warn(`no views found`),process.exitCode=1,Error(`no views found`);switch(o.format){case`views`:await singleFileCodegenAction(l,o.outfile,s);break;case`dot`:await dotCodegenAction(l,o.outdir??i,s);break;case`d2`:case`mermaid`:case`plantuml`:await multipleFilesCodegenAction(l,o.format,o.outdir??i,s);break;default:nonexhaustive(o)}c.stopAndLog()}async function modelHandler({path:i,useDotBin:a,useCorePackage:o,outfile:s,project:c}){try{var l=_usingCtx();let d=createLikeC4Logger(`c4:codegen`),f=startTimer(d),p=l.a(await fromWorkspace(i,{graphviz:a?`binary`:`wasm`,watch:!1})),{projectId:m,projectFolder:h}=ensureProject(p,c);c&&d.info(`${u.dim(`project`)} ${u.green(m)}`),d.info(`${u.dim(`format`)} ${u.green(`model`)}`);let g=await p.layoutedModel(m);for(let i of g.views())i.hasLayoutDrifts&&d.warn(u.yellow(`layout drift detected, view:`)+` `+u.red(i.id));let _=resolve(p.projectsManager.hasMultipleProjects()?h:p.workspace,`likec4-model.ts`);if(s&&(_=isAbsolute(s)?s:resolve(s),existsSync(s)&&(await stat(s)).isDirectory()))throw Error(`output file is a directory: ${s}`);let v=basename(_);d.info(`${u.dim(`filename`)} ${v}`);let y=extname(v).toLocaleLowerCase();if(![`.ts`,`.mts`,`.cts`].includes(y))throw d.error(`output file ${s} has extension "${y}"`),Error(`output file ${s} must be a .ts, .mts or .cts file`);let b=dirname(_);d.info(`${u.dim(`outdir`)} ${b}`),await mkdir(b,{recursive:!0}),await writeFile(_,generateLikeC4Model(g,{useCorePackage:o}),{encoding:`utf-8`}),f.stopAndLog(),boxen(stripIndent(`
173
- ${u.dim(`Source generated:`)}
174
- ${relative(cwd(),_)}
175
-
176
- ${u.dim(`How to use:`)}
177
- ${u.underline(`https://likec4.dev/tooling/code-generation/model/`)}
178
- `).trim(),{padding:1,borderColor:`green`,borderStyle:`round`})}catch(i){l.e=i}finally{await l.d()}}async function viteReactConfig({languageServices:i,outDir:a,filename:o=`likec4-react.mjs`}){let s=createLikeC4Logger([`vite`,`react`]),c=viteAppRoot();return s.info(`${u.cyan(`likec4 app root`)} ${u.dim(relativeToCwd(c))}`),s.info(u.cyan(`outDir`)+` `+u.dim(relativeToCwd(a))),{customLogger:s,root:c,configFile:!1,clearScreen:!1,publicDir:!1,mode:`production`,resolve:{conditions:[`production`],alias:viteAliases()},esbuild:{banner:`'use client'
179
- `+JsBanners.banner,footer:JsBanners.footer,jsx:`transform`,jsxDev:!1,jsxSideEffects:!1,minifyIdentifiers:!1,minifySyntax:!1,minifyWhitespace:!1,tsconfigRaw:{compilerOptions:{target:`ES2022`,useDefineForClassFields:!0,verbatimModuleSyntax:!0,jsx:`react-jsx`}}},build:{outDir:a,emptyOutDir:!1,sourcemap:!1,minify:!1,copyPublicDir:!1,chunkSizeWarningLimit,assetsInlineLimit:5e5,lib:{entry:`react/likec4.tsx`,fileName(i,a){return o},formats:[`es`]},rollupOptions:{output:{compact:!1,exports:`named`},external:[`likec4/react`,`likec4/model`,`react`,`react-dom`,`react/jsx-runtime`,`react/jsx-dev-runtime`,`react-dom/client`,/@likec4\/core.*/],onwarn(i,a){i.code!==`SOURCEMAP_ERROR`&&a(i)}}},plugins:[react({}),LikeC4VitePlugin({languageServices:i.languageServices})]}}async function reactHandler({path:i,useDotBin:a,useCorePackage:o,outfile:s,project:c}){try{var l=_usingCtx();await ensureReact();let d=createLikeC4Logger(`c4:codegen`),f=startTimer(d),p=l.a(await fromWorkspace(i,{graphviz:a?`binary`:`wasm`,watch:!1})),{projectId:m,projectFolder:h}=ensureProject(p,c);c&&d.info(`${u.dim(`project`)} ${u.green(m)}`),d.info(`${u.dim(`format`)} ${u.green(`react`)}`);let g=await p.diagrams(m);if(g.length===0)throw process.exitCode=1,Error(`no views found`);g.forEach(i=>{if(i.drifts&&i.drifts.length>0){d.info(u.yellow(`layout drift detected, view:`)+` `+u.red(i.id));return}if(i.hasLayoutDrift){d.warn(u.yellow(`drift detected, manual layout can not be applied, view:`)+` `+u.red(i.id));return}});let _=resolve(p.projectsManager.hasMultipleProjects()?h:p.workspace,`likec4-views.js`);if(s&&(_=isAbsolute(s)?s:resolve(s),existsSync(s)&&(await stat(s)).isDirectory()))throw Error(`output file is a directory: ${s}`);let v=dirname(_);d.info(`${u.dim(`outdir`)} ${v}`);let y=basename(_);d.info(`${u.dim(`filename`)} ${y}`);let b=extname(y).toLocaleLowerCase();if(![`.js`,`.mjs`,`.jsx`].includes(b))throw d.error(`output file ${s} has extension "${b}"`),Error(`output file ${s} must be a .js, .jsx or .mjs`);await build({...await viteReactConfig({languageServices:p,outDir:v,filename:y}),logLevel:`warn`});let x=await p.layoutedModel(m),S=resolve(v,basename(_,b)+(b===`.mjs`?`.d.mts`:`.d.ts`));await writeFile(S,generateReactTypes(x,{useCorePackage:o})),f.stopAndLog(),boxen(stripIndent(`
180
- ${u.dim(`Sources generated:`)}
181
- ${relative(cwd(),_)}
182
- ${relative(cwd(),S)}
183
-
184
- ${u.dim(`How to use:`)}
185
- ${u.underline(`https://likec4.dev/tooling/code-generation/react/`)}
186
- `),{padding:1,borderColor:`green`,borderStyle:`round`})}catch(i){l.e=i}finally{await l.d()}}async function webcomponentHandler({project:i,path:a,useDotBin:o,webcomponentPrefix:s=`likec4`,outfile:l}){try{var d=_usingCtx();await ensureReact();let f=createLikeC4Logger(`c4:codegen`),p=startTimer(f),m=d.a(await fromWorkspace(a,{graphviz:o?`binary`:`wasm`,watch:!1})),{projectId:h,projectFolder:g}=ensureProject(m,i);i&&f.info(`${u.dim(`project`)} ${u.green(h)}`),f.info(`${u.dim(`format`)} ${u.green(`webcomponent`)}`);let _=await m.diagrams(h);if(!t$4(_,1))throw f.warn(`no views found`),process.exitCode=1,Error(`no views found`);_.forEach(i=>{i.hasLayoutDrift&&f.warn(u.yellow(`drift detected, manual layout can not be applied, view:`)+` `+u.red(i.id))});let v=resolve(m.projectsManager.hasMultipleProjects()?g:m.workspace,`likec4-views.js`);if(l&&(v=isAbsolute(l)?l:resolve(l),existsSync(l)&&(await stat(l)).isDirectory()))throw Error(`output file is a directory: ${l}`);logger$2.debug(`${u.dim(`outfilepath`)} ${v}`);let y=basename(v);logger$2.debug(`${u.dim(`filename`)} ${y}`);let b=extname(y).toLocaleLowerCase();if(b!==`.js`&&b!==`.mjs`)throw logger$2.warn(`output file ${l} has extension "${b}"`),Error(`output file ${l} must be a .js or .mjs`);let S=await mkTempPublicDir();logger$2.debug(`${u.dim(`created temp public`)} ${S}`);let C=await viteWebcomponentConfig({languageServices:m,outDir:S,filename:y,webcomponentPrefix:s,base:`/`});logger$2.debug(`${u.dim(`vite build webcomponent`)}`),await build({...C,logLevel:`warn`});let w=resolve(S,y);if(!existsSync(w))throw Error(`output file not found: ${w}`);await mkdir(dirname(v),{recursive:!0}),await copyFile(w,v),f.info(`${u.dim(`generated`)} ${v}`),logger$2.debug(`${u.dim(`remove temp public`)}`),await rm(S,{recursive:!0,force:!0}),p.stopAndLog(),boxen(stripIndent(`
187
- ${u.dim(`Webcomponents generated to:`)}
188
- ${relative(cwd(),v)}
189
-
190
- ${u.dim(`Setup and usage instructions:`)}
191
- ${u.blue(`https://likec4.dev/tooling/code-generation/webcomponent/`)}
192
- `))}catch(i){d.e=i}finally{await d.d()}}const codegenCmd=i=>i.command({command:`gen <command> [path]`,aliases:[`generate`,`codegen`],describe:`Generate various artifacts from LikeC4 sources`,builder:i=>i.positional(`path`,path$1).command(`react [path]`,`generate react component to render likec4 view`,i=>i.positional(`path`,path$1).option(`project`,project).option(`outfile`,{alias:`o`,type:`string`,desc:`<file> path to output file (.jsx, .mjs or .js)`,normalize:!0,coerce:resolve$1}).option(`use-dot`,useDotBin).option(`use-core-package`,useCorePackage),async i=>{await reactHandler({project:i.project,useDotBin:i.useDotBin,path:i.path,outfile:i.outfile,useCorePackage:i.useCorePackage})}).command({command:`webcomponent [path]`,aliases:[`wc`,`webcomp`],describe:`generate js with webcomponents`,builder:i=>i.positional(`path`,path$1).option(`project`,project).option(`outfile`,{alias:`o`,type:`string`,desc:`<file> path to output file (.mjs or .js)`,normalize:!0,coerce:resolve$1}).option(`webcomponent-prefix`,webcomponentPrefix).option(`use-dot`,useDotBin),handler:async i=>{await webcomponentHandler({project:i.project,useDotBin:i.useDotBin,path:i.path,outfile:i.outfile,webcomponentPrefix:i.webcomponentPrefix})}}).command({command:`model [path]`,aliases:[`ts`],describe:`generate LikeC4Model (.ts)`,builder:i=>i.positional(`path`,path$1).option(`project`,project).option(`outfile`,{alias:`o`,type:`string`,desc:`<file> path to output file (.ts)`,normalize:!0,coerce:resolve$1}).option(`use-dot`,useDotBin).option(`use-core-package`,useCorePackage),handler:async i=>{await modelHandler({path:i.path,useDotBin:i.useDotBin,useCorePackage:i.useCorePackage,outfile:i.outfile,project:i.project})}}).command({command:`views-data [path]`,aliases:[`views`],describe:`{deprecated} use codegen model`,deprecated:!0,builder:i=>i.positional(`path`,path$1).option(`outfile`,{alias:`o`,type:`string`,desc:`<file> output .ts file`,normalize:!0,coerce:resolve$1}).option(`use-dot`,useDotBin),handler:async i=>{await legacyHandler({format:`views`,path:i.path,useDotBin:i.useDotBin,outfile:i.outfile})}}).command({command:`dot [path]`,describe:`generate graphviz files (.dot)`,builder:i=>i.positional(`path`,path$1).option(`outdir`,outdir).option(`use-dot`,useDotBin),handler:async i=>{await legacyHandler({format:`dot`,path:i.path,useDotBin:i.useDotBin,outdir:i.outdir})}}).command({command:`d2 [path]`,describe:`generate D2 files (.d2)`,builder:i=>i.positional(`path`,path$1).option(`outdir`,outdir).option(`use-dot`,useDotBin),handler:async i=>{await legacyHandler({format:`d2`,path:i.path,useDotBin:i.useDotBin,outdir:i.outdir})}}).command({command:`mermaid [path]`,aliases:[`mmd`],describe:`generate Mermaid files (.mmd)`,builder:i=>i.positional(`path`,path$1).option(`outdir`,outdir).option(`use-dot`,useDotBin),handler:async i=>{await legacyHandler({format:`mermaid`,useDotBin:i.useDotBin,path:i.path,outdir:i.outdir})}}).command({command:`plantuml [path]`,aliases:[`puml`],describe:`generate PlantUML files (.puml)`,builder:i=>i.positional(`path`,path$1).option(`outdir`,outdir).option(`use-dot`,useDotBin),handler:async i=>{await legacyHandler({format:`plantuml`,useDotBin:i.useDotBin,path:i.path,outdir:i.outdir})}}).command({command:`<custom> [path]`,describe:`run custom generator from likec4 config`,builder:i=>i.positional(`path`,path$1).option(`project`,project).option(`use-dot`,useDotBin),handler:async i=>{await customHandler({name:`custom`,path:i.path,project:i.project,useDotBin:i.useDotBin})}}).epilog(`${u.bold(`Examples:`)}
13
+ `};function gt(){let e=Se({cwd:mt});if(!e)throw Error(`likec4 package folder not found`);return P(e)}function _t(){let e=[R(gt(),`__app__`),R(mt,`../__app__`),R(mt,`../../__app__`),R(mt,`../../dist/__app__`)],t=r(e,z);if(!t)throw u.error(`likec4 app root does not exist, tried:\n${e.join(`
14
+ `)}`),Error(`likec4 app root does not exist`);return t}async function vt(){let e=await A(I(D(),`.likec4-public-`));return await M(I(e,`likec4-views.js`),`// generated by likec4
15
+ `),e}function yt(e){return L(B(),e)}const bt=1e4;function xt(){let e=gt();return{"likec4/icons":`@likec4/icons`,"likec4/react":R(e,`react/index.mjs`),"likec4/model":R(e,`dist/model/index.mjs`),"likec4/vite-plugin/internal":R(e,`dist/vite-plugin/internal.mjs`)}}const St=async({languageServices:e,likec4AssetsDir:t,...n})=>{let r=n.customLogger??pt,i=_t();r.info(`${v.cyan(`likec4 app root`)} ${v.dim(yt(i))}`);let a=n.outputDir??R(e.workspace,`dist`);r.info(v.cyan(`outDir`)+` `+v.dim(yt(a)));let o=`/`;n.base&&(o=te(n.base),!re(o)&&o!==`./`&&(o=ie(o))),o!==`/`&&r.info(`${v.green(`app base url`)} ${v.dim(o)}`);let s=n.webcomponentPrefix??`likec4`,c=n.title??`LikeC4`,l=n.outputSingleFile??!1;return{isDev:!1,likec4AssetsDir:t,webcomponentPrefix:s,title:c,root:i,languageServices:e,clearScreen:!1,base:o,resolve:{conditions:[`production`],dedupe:[`react`,`react-dom`,`react/jsx-runtime`,`react/jsx-dev-runtime`,`react-dom/client`],alias:{...xt(),"likec4/previews":t}},configFile:!1,mode:`production`,optimizeDeps:{include:[`react`,`react-dom`,`react/jsx-runtime`,`react/jsx-dev-runtime`,`react-dom/client`,`@likec4/core/types`,`@likec4/core/model`,`@likec4/core/styles`,`@likec4/core/utils`,`@likec4/core`,`likec4/vite-plugin/internal`],noDiscovery:!0},esbuild:{tsconfigRaw:{compilerOptions:{target:`ESNext`,jsx:`react-jsx`}}},define:{WEBCOMPONENT_PREFIX:JSON.stringify(s),PAGE_TITLE:JSON.stringify(c),__USE_HASH_HISTORY__:n?.useHashHistory===!0?`true`:`false`,"process.env.NODE_ENV":`"production"`},build:{outDir:a,emptyOutDir:!1,sourcemap:!1,cssMinify:!1,minify:!0,copyPublicDir:!0,chunkSizeWarningLimit:bt,assetsInlineLimit:1e5,rollupOptions:{treeshake:{preset:`recommended`},...!l&&{input:[R(i,`index.html`),R(i,`src`,`main.js`),R(i,`src`,`fonts.css`),R(i,`src`,`style.css`)],output:{manualChunks:e=>{if(!(e.endsWith(`.css`)||e.endsWith(`.html`)||e.includes(`likec4/icons`)||e.includes(`const.js`))){if(e.includes(`__app__`)){let t=e.match(/__app__\/src\/([\w]+)\.js/)?.[1];return t?t[1]:void 0}if(e.includes(`likec4`))return`likec4`;if(e.includes(`node_modules`))return`vendors`}}}}}},customLogger:r,plugins:[ot(),ge({languageServices:e.languageServices}),l?st():void 0]}};async function Ct({languageServices:e,outDir:t,base:n,webcomponentPrefix:r=`likec4`,filename:i=`likec4-views.js`}){let a=W([`vite`,`webcomponent`]),o=_t();return a.info(v.cyan(`outDir`)+` `+v.dim(t)),{root:o,clearScreen:!1,base:n,configFile:!1,publicDir:!1,mode:`production`,resolve:{conditions:[`production`],alias:xt(),dedupe:[`react`,`react-dom`,`react/jsx-runtime`,`react/jsx-dev-runtime`,`react-dom/client`]},define:{WEBCOMPONENT_PREFIX:JSON.stringify(r),"process.env.NODE_ENV":`"production"`},esbuild:{...ht,tsconfigRaw:{compilerOptions:{target:`ESNext`,jsx:`react-jsx`}}},build:{outDir:t,emptyOutDir:!1,sourcemap:!1,minify:!0,assetsInlineLimit:1024*1024,chunkSizeWarningLimit:bt,lib:{entry:`src/webcomponent.js`,fileName(e,t){return i},formats:[`iife`],name:`LikeC4Views`},rollupOptions:{treeshake:{preset:`recommended`},output:{format:`iife`,hoistTransitiveImports:!1,compact:!0}}},customLogger:a,plugins:[ot(),ge({languageServices:e.languageServices})]}}const wt=[`favicon.ico`,`robots.txt`];async function Tt({buildWebcomponent:e=!0,webcomponentPrefix:t=`likec4`,title:n,languageServices:r,likec4AssetsDir:i,outputSingleFile:a,...o}){i??=await A(I(D(),`.likec4-assets-`));let s=await St({...o,languageServices:r,likec4AssetsDir:i,webcomponentPrefix:t,title:n,outputSingleFile:a}),c=!z(s.build.outDir)||Xe(s.build.outDir).length===0,l=await vt();for(let e of wt){let t=R(s.root,e);z(t)&&Ye(t,R(l,e))}let u=r.languageServices.projects();if(u.length===1){let e=await r.viewsService.computedViews(),t=await r.diagrams();if(t.length===0)throw process.exitCode=1,Error(`no views found`);t.length===e.length?s.customLogger.info(`${v.dim(`workspace:`)} ${v.green(`✓ all views layouted`)}`):s.customLogger.warn(`${v.dim(`workspace:`)} ${v.yellow(`✗ layouted ${t.length} of ${e.length} views`)}`),t.forEach(e=>{(e.hasLayoutDrift||e.drifts&&e.drifts.length>0)&&s.customLogger.warn(v.dim(`view`)+` `+v.red(e.id)+` `+v.yellow(`is out of date, layout drift detected`))})}else for(let e of u){let t=await r.viewsService.computedViews(e.id);t.length===0?s.customLogger.warn(`${v.dim(`project:`)} ${e.id} ${v.yellow(`✗ no views found`)}`):s.customLogger.info(`${v.dim(`project:`)} ${e.id} ${v.green(`${t.length} views`)}`)}if(e&&!a&&await V(await Ct({webcomponentPrefix:t,languageServices:r,outDir:l,base:s.base})),await V({...s,customLogger:s.customLogger,publicDir:l,mode:`production`}),a){if(!c){s.customLogger.warn(v.yellow(`outDir was not empty, skipping cleanup`));return}for(let e of Xe(R(s.build.outDir)).filter(e=>e!==`index.html`))Ze(R(s.build.outDir,e),{recursive:!0})}let d=R(s.build.outDir,`index.html`);z(d)&&Ye(d,R(s.build.outDir,`404.html`))}function Et(e){try{return!!Ae.createRequire(import.meta.url).resolve(e)}catch(e){return U.debug(g(e)),!1}}async function q(){if(Et(`react`)&&Et(`react-dom`)){U.debug(`react already installed`);return}U.warn(`react not installed`);let e=await we();e||(U.error`Package manager not detected, please install dependencies manually: ${`react`} ${`react-dom`}`,process.exit(1));let t=Ce(e.agent,`add`,[`react`,`react-dom`]);t||(U.error`Please install dependencies manually: ${`react`} ${`react-dom`}`,process.exit(1));try{await Re(t.command,t.args,{stdio:`inherit`})}catch(e){U.debug(g(e)),U.error`Please install dependencies manually: ${`react`} ${`react-dom`}`,process.exit(1)}}async function Dt(){if(Et(`playwright`)){U.debug(`playwright already installed`);return}U.warn(`playwright not installed`);let e=await we();e||(U.error`Package manager not detected, please install dependencies manually: ${`playwright`}`,process.exit(1));let t=Ce(e.agent,`add`,[`playwright`]);t||(U.error`Please install dependencies manually: ${`playwright`}`,process.exit(1));try{await Re(t.command,t.args,{preferLocal:!0,stdio:`inherit`})}catch(e){U.debug(g(e)),U.error`Please install dependencies manually: ${`playwright`}`,process.exit(1)}}const J={type:`string`,desc:`<directory> with LikeC4 sources (default is current directory or 'LIKEC4_WORKSPACE' env)`,normalize:!0,default:ze.LIKEC4_WORKSPACE||`.`,coerce:R},Y={alias:`use-dot-bin`,boolean:!0,type:`boolean`,desc:w()?`enabled in container, disable by --no-use-dot`:`use graphviz binaries ("dot" should be on PATH)`,default:w()},Ot={boolean:!0,type:`boolean`,desc:"use `@likec4/core` package in types",default:!1},kt={boolean:!0,type:`boolean`,desc:`use hash history for navigation, e.g. "/#/view" instead of "/view"`},At={alias:`o`,string:!0,desc:`output directory`,normalize:!0,nargs:1,coerce:R},jt={alias:`w`,string:!0,desc:`prefix for Webcomponents, e.g "c4" generates <c4-view ../>`,default:`likec4`,nargs:1},Mt={alias:`t`,string:!0,desc:`base title of the app pages (default is "LikeC4")`,default:`LikeC4`,nargs:1},Nt={alias:[`base-url`],string:!0,desc:`base url the app is being served from, e.g. "/" or "/pages/"`,nargs:1},Pt={boolean:!0,desc:`outputs a single self-contained HTML file with all required resources inlined`},Ft={alias:`l`,string:!0,...w()?{desc:`listen 0.0.0.0 by default in container`,default:`0.0.0.0`}:{desc:`ip address of the network interface to listen on`},nargs:1},It={number:!0,desc:`port number for the dev server (default is 5173, or PORT environment variable)`,nargs:1},X={alias:`p`,string:!0,desc:`select LikeC4 project by name (e.g. "my-project") or by path`,nargs:1},Lt={hidden:!0,nargs:1,choices:[`trace`,`debug`,`info`,`warning`,`error`],conflicts:[`verbose`]},Rt={boolean:!0,desc:`verbose logging`,conflicts:[`log-level`]},zt=ye?`trace`:`debug`;function Z(){var e=typeof SuppressedError==`function`?SuppressedError:function(e,t){var n=Error();return n.name=`SuppressedError`,n.error=e,n.suppressed=t,n},t={},n=[];function r(e,t){if(t!=null){if(Object(t)!==t)throw TypeError(`using declarations can only be used with objects, functions, null, or undefined.`);if(e)var r=t[Symbol.asyncDispose||Symbol.for(`Symbol.asyncDispose`)];if(r===void 0&&(r=t[Symbol.dispose||Symbol.for(`Symbol.dispose`)],e))var i=r;if(typeof r!=`function`)throw TypeError(`Object is not disposable.`);i&&(r=function e(){try{i.call(t)}catch(e){return Promise.reject(e)}}),n.push({v:t,d:r,a:e})}else e&&n.push({d:t,a:e});return t}return{e:t,u:r.bind(null,!1),a:r.bind(null,!0),d:function r(){var i,a=this.e,o=0;function s(){for(;i=n.pop();)try{if(!i.a&&o===1)return o=0,n.push(i),Promise.resolve().then(s);if(i.d){var e=i.d.call(i.v);if(i.a)return o|=2,Promise.resolve(e).then(s,c)}else o|=1}catch(e){return c(e)}if(o===1)return a===t?Promise.resolve():Promise.reject(a);if(a!==t)throw a}function c(n){return a=a===t?n:new e(n,a),s()}return s()}}}const Bt=e=>e.command({command:`build [path]`,aliases:[`bundle`],describe:`Build a static website`,builder:e=>e.positional(`path`,J).option(`output`,{alias:`o`,type:`string`,desc:`output directory for production build`,normalize:!0,coerce:R}).option(`base`,Nt).option(`use-hash-history`,kt).option(`use-dot`,Y).option(`webcomponent-prefix`,jt).option(`title`,Mt).option(`output-single-file`,Pt).example(`${v.green(`$0 build -o ./build ./src`)}`,v.gray(`Search for likec4 files in 'src' and output static site to 'build'`)),handler:async e=>{try{var t=Z();let n={useHashHistory:e[`use-hash-history`]??!1,useDotBin:e[`use-dot`],webcomponentPrefix:e[`webcomponent-prefix`],outputSingleFile:e[`output-single-file`]??!1};await q();let r=W(`c4:build`),i=t.a(await T(e.path,{graphviz:e[`use-dot`]?`binary`:`wasm`,watch:!1})),a=e.output??R(i.workspace,`dist`),o=R(a,`assets`);await Tt({base:e.base,useHashHistory:n.outputSingleFile||n.useHashHistory,customLogger:r,webcomponentPrefix:n.webcomponentPrefix,title:e.title,languageServices:i,likec4AssetsDir:o,outputDir:a,outputSingleFile:n.outputSingleFile})}catch(e){t.e=e}finally{await t.d()}}});var Vt=e(Te(),1);const Ht=new Ee({projectName:dt,serialize:e=>y.stringify(e,null,2),deserialize:e=>y.parse(e)}),Ut=`check-update`;async function Wt(){if(Be||Ve===Ut)return;let e=Ht.get(`lastUpdateCheck`);if(!e){await Gt(!1);return}let t=Ht.get(`latestVersion`);if(s(t)||s(e)||e+864e5<Date.now())try{Re(`likec4`,[`check-update`],{stdio:`ignore`,timeout:5e3,preferLocal:!0,detached:!0,env:{NODE_ENV:Ut}}).catch(()=>{})}catch{}t&&(0,Vt.gt)(t,H)&&K([`Update available: `,v.dim(H),v.reset(` → `),v.green(t)].join(``))}async function Gt(e=!0){try{Ht.set({lastUpdateCheck:Date.now()});let t=await Kt();Ie(t,`No version found in latest npm`),Ht.set({lastUpdateCheck:Date.now(),latestVersion:t}),(0,Vt.gt)(t,H)?K([`Update available: `,v.dim(H),v.reset(` → `),v.green(t)].join(``)):e&&K(v.dim(`Up to date: `)+` `+v.green(H))}catch(e){U.warning(g(e))}}async function Kt(){return(await De(`https://registry.npmjs.org/likec4/latest`,{headers:{accept:`application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*`},timeout:5e3,keepalive:!0}).json()).version}const qt=e=>e.command({command:`check-update`,describe:`Check for updates`,handler:async()=>{await Gt()}});function Jt(e,t){if(!t)return e.languageServices.projectsManager.ensureProjectId();let n=R(t);if(n===e.workspace)return e.languageServices.projectsManager.ensureProjectId();if(z(n)&&Qe(n).isDirectory()){U.debug`Project path exists: ${n}`;let t=x.file(n.endsWith(Je)?n:n+Je),r=e.languageServices.projects().find(e=>e.folder.fsPath===t.fsPath);if(r)return U.debug`Found project ${r.id} at path: ${n}`,r.id;U.debug`No project registered at path: ${n}`}return e.languageServices.projectsManager.ensureProjectId(t)}function Yt(e,t){let n=Jt(e,t),r=e.languageServices.projectsManager.getProject(n);return e.languageServices.projectsManager.defaultProjectId=n,{projectId:n,projectFolder:r.folderUri.fsPath,config:r.config}}const Q=U.getChild(`generator`);async function Xt({name:e,path:t,useDotBin:n,project:r}){try{var i=Z();let a=G(Q),o=i.a(await C(t,{graphviz:n?`binary`:`wasm`,watch:!1})),{projectId:s,config:c}=Yt(o,r);r&&Q.info(`${v.dim(`project`)} ${v.green(s)}`);let l=c.generators?.[e];if(!l)throw Q.error(v.red(`generator ${e} does not exist in project config`)),Error(`generator ${e} does not exist in project config`);Q.info(`${v.dim(`generator`)} ${v.green(e)}`),await Zt({likec4:o,model:await o.layoutedModel(s),generator:l,logger:Q.getChild(e)}),a.stopAndLog()}catch(e){i.e=e}finally{await i.d()}}async function Zt({likec4:e,model:t,generator:n,logger:r}){let i=e.languageServices,a=new Set,o=i.project(t.project.id),s=t.project.id;r.debug(`${v.dim(`running for project:`)} ${v.green(o.id)}`),await Promise.resolve().then(()=>n({likec4model:t,ctx:{workspace:e.languageServices.workspaceUri,project:o,locate:e=>{let t=null;switch(!0){case Ne(e):t=i.locate({element:e.id,projectId:s});break;case Pe(e):t=i.locate({view:e.id,projectId:s});break;case je(e):t=i.locate({deployment:e.id,projectId:s});break;case Fe(e):case Me(e):t=i.locate({relation:e.id,projectId:s});break;default:Le(e)}if(!t)throw r.error(`Cannot locate ${e.id}`,{target:e}),Error(`Cannot locate ${e.id}`);let n=x.parse(t.uri);return{range:t.range,document:n,relativePath:b.relative(o.folder,n),folder:b.dirname(n).fsPath,filename:b.basename(n)}},write:async({path:e,content:t})=>{let n;n=Array.isArray(e)?R(o.folder.fsPath,...e):x.isUri(e)?e.fsPath:R(o.folder.fsPath,`${e}`);let i=P(n);a.has(i)||(z(i)||(r.debug(`${v.dim(`create directory`)} ${i}`),await k(i,{recursive:!0})),a.add(i)),r.debug(`${v.dim(`write`)} ${n}`),await M(n,t)},abort:e=>{throw r.error(e||`Generator aborted`),Error(e||`Generator aborted`)}}}))}async function Qt(e,t,n){t??=R(e.workspace,`likec4.generated.ts`),F(t)!==`.ts`&&(t+=`.ts`),await k(P(t),{recursive:!0});let r=me([...await e.diagrams()]);await M(t,r),n.info(`${v.dim(`generated`)} ${L(process.cwd(),t)}`)}async function $t(e,t,n){await k(t,{recursive:!0}),n.info(`${v.dim(`format`)} ${v.green(`dot`)}`),n.info(`${v.dim(`outdir`)} ${t}`);let r=new Set,i=await e.computedModel(),a=c(i.$data.views),o=0;for(let s of a)try{let a=await e.viewsService.layouter.dot({view:s,styles:i.$styles}),c=`.`;s.sourcePath&&(c=P(s.sourcePath)),c=R(t,c),r.has(c)||(await k(c,{recursive:!0}),r.add(c));let l=R(c,s.id+`.dot`);await M(l,a),n.info(`${v.dim(`generated`)} ${L(process.cwd(),l)}`),o++}catch(e){U.error(`error while generating ${s.id}`,{error:e})}o>0&&n.info(`${v.dim(`total`)} ${o} files`)}async function en(e,t,n,r){await k(n,{recursive:!0}),r.info(`${v.dim(`format`)} ${v.green(t)}`),r.info(`${v.dim(`outdir`)} ${n}`);let i,a;switch(t){case`d2`:i=`.d2`,a=le;break;case`mermaid`:i=`.mmd`,a=pe;break;case`plantuml`:i=`.puml`,a=ue;break;default:Le(t)}let o=new Set,s=await e.layoutedModel(),c=0;for(let e of s.views()){let t=e.$view;try{let s=`.`;t.sourcePath&&(s=P(t.sourcePath)),s=R(n,s),o.has(s)||(await k(s,{recursive:!0}),o.add(s));let l=R(s,t.id+i);await M(l,a(e)),r.info(`${v.dim(`generated`)} ${L(process.cwd(),l)}`),c++}catch(e){r.error(`error while generating ${t.id}`,{error:e})}}c>0&&r.info(`${v.dim(`total`)} ${c} files`)}async function $({path:e,useDotBin:t,...n}){let r=W(`c4:codegen`),i=G(r),a=await C(e,{graphviz:t?`binary`:`wasm`,watch:!1});if(a.ensureSingleProject(),(await a.viewsService.computedViews()).length===0)throw r.warn(`no views found`),process.exitCode=1,Error(`no views found`);switch(n.format){case`views`:await Qt(a,n.outfile,r);break;case`dot`:await $t(a,n.outdir??e,r);break;case`d2`:case`mermaid`:case`plantuml`:await en(a,n.format,n.outdir??e,r);break;default:Le(n)}i.stopAndLog()}async function tn({path:e,useDotBin:t,useCorePackage:n,outfile:r,project:i}){try{var a=Z();let o=W(`c4:codegen`),s=G(o),c=a.a(await C(e,{graphviz:t?`binary`:`wasm`,watch:!1})),{projectId:l,projectFolder:u}=Yt(c,i);i&&o.info(`${v.dim(`project`)} ${v.green(l)}`),o.info(`${v.dim(`format`)} ${v.green(`model`)}`);let d=await c.layoutedModel(l);for(let e of d.views())e.hasLayoutDrifts&&o.warn(v.yellow(`layout drift detected, view:`)+` `+v.red(e.id));let f=R(c.projectsManager.hasMultipleProjects()?u:c.workspace,`likec4-model.ts`);if(r&&(f=qe(r)?r:R(r),z(r)&&(await j(r)).isDirectory()))throw Error(`output file is a directory: ${r}`);let p=N(f);o.info(`${v.dim(`filename`)} ${p}`);let m=F(p).toLocaleLowerCase();if(![`.ts`,`.mts`,`.cts`].includes(m))throw o.error(`output file ${r} has extension "${m}"`),Error(`output file ${r} must be a .ts, .mts or .cts file`);let h=P(f);o.info(`${v.dim(`outdir`)} ${h}`),await k(h,{recursive:!0}),await M(f,se(d,{useCorePackage:n}),{encoding:`utf-8`}),s.stopAndLog(),K(oe(`
16
+ ${v.dim(`Source generated:`)}
17
+ ${L(B(),f)}
18
+
19
+ ${v.dim(`How to use:`)}
20
+ ${v.underline(`https://likec4.dev/tooling/code-generation/model/`)}
21
+ `).trim(),{padding:1,borderColor:`green`,borderStyle:`round`})}catch(e){a.e=e}finally{await a.d()}}async function nn({languageServices:e,outDir:t,filename:n=`likec4-react.mjs`}){let r=W([`vite`,`react`]),i=_t();return r.info(`${v.cyan(`likec4 app root`)} ${v.dim(yt(i))}`),r.info(v.cyan(`outDir`)+` `+v.dim(yt(t))),{customLogger:r,root:i,configFile:!1,clearScreen:!1,publicDir:!1,mode:`production`,resolve:{conditions:[`production`],alias:xt()},esbuild:{banner:`'use client'
22
+ `+ht.banner,footer:ht.footer,jsx:`transform`,jsxDev:!1,jsxSideEffects:!1,minifyIdentifiers:!1,minifySyntax:!1,minifyWhitespace:!1,tsconfigRaw:{compilerOptions:{target:`ES2022`,useDefineForClassFields:!0,verbatimModuleSyntax:!0,jsx:`react-jsx`}}},build:{outDir:t,emptyOutDir:!1,sourcemap:!1,minify:!1,copyPublicDir:!1,chunkSizeWarningLimit:bt,assetsInlineLimit:5e5,lib:{entry:`react/likec4.tsx`,fileName(e,t){return n},formats:[`es`]},rollupOptions:{output:{compact:!1,exports:`named`},external:[`likec4/react`,`likec4/model`,`react`,`react-dom`,`react/jsx-runtime`,`react/jsx-dev-runtime`,`react-dom/client`,/@likec4\/core.*/],onwarn(e,t){e.code!==`SOURCEMAP_ERROR`&&t(e)}}},plugins:[ot({}),ge({languageServices:e.languageServices})]}}async function rn({path:e,useDotBin:t,useCorePackage:n,outfile:r,project:i}){try{var a=Z();await q();let o=W(`c4:codegen`),s=G(o),c=a.a(await C(e,{graphviz:t?`binary`:`wasm`,watch:!1})),{projectId:l,projectFolder:u}=Yt(c,i);i&&o.info(`${v.dim(`project`)} ${v.green(l)}`),o.info(`${v.dim(`format`)} ${v.green(`react`)}`);let d=await c.diagrams(l);if(d.length===0)throw process.exitCode=1,Error(`no views found`);d.forEach(e=>{if(e.drifts&&e.drifts.length>0){o.info(v.yellow(`layout drift detected, view:`)+` `+v.red(e.id));return}if(e.hasLayoutDrift){o.warn(v.yellow(`drift detected, manual layout can not be applied, view:`)+` `+v.red(e.id));return}});let f=R(c.projectsManager.hasMultipleProjects()?u:c.workspace,`likec4-views.js`);if(r&&(f=qe(r)?r:R(r),z(r)&&(await j(r)).isDirectory()))throw Error(`output file is a directory: ${r}`);let p=P(f);o.info(`${v.dim(`outdir`)} ${p}`);let m=N(f);o.info(`${v.dim(`filename`)} ${m}`);let h=F(m).toLocaleLowerCase();if(![`.js`,`.mjs`,`.jsx`].includes(h))throw o.error(`output file ${r} has extension "${h}"`),Error(`output file ${r} must be a .js, .jsx or .mjs`);await V({...await nn({languageServices:c,outDir:p,filename:m}),logLevel:`warn`});let g=await c.layoutedModel(l),_=R(p,N(f,h)+(h===`.mjs`?`.d.mts`:`.d.ts`));await M(_,fe(g,{useCorePackage:n})),s.stopAndLog(),K(oe(`
23
+ ${v.dim(`Sources generated:`)}
24
+ ${L(B(),f)}
25
+ ${L(B(),_)}
26
+
27
+ ${v.dim(`How to use:`)}
28
+ ${v.underline(`https://likec4.dev/tooling/code-generation/react/`)}
29
+ `),{padding:1,borderColor:`green`,borderStyle:`round`})}catch(e){a.e=e}finally{await a.d()}}async function an({project:e,path:t,useDotBin:n,webcomponentPrefix:r=`likec4`,outfile:i}){try{var o=Z();await q();let s=W(`c4:codegen`),c=G(s),l=o.a(await C(t,{graphviz:n?`binary`:`wasm`,watch:!1})),{projectId:u,projectFolder:d}=Yt(l,e);e&&s.info(`${v.dim(`project`)} ${v.green(u)}`),s.info(`${v.dim(`format`)} ${v.green(`webcomponent`)}`);let f=await l.diagrams(u);if(!a(f,1))throw s.warn(`no views found`),process.exitCode=1,Error(`no views found`);f.forEach(e=>{e.hasLayoutDrift&&s.warn(v.yellow(`drift detected, manual layout can not be applied, view:`)+` `+v.red(e.id))});let p=R(l.projectsManager.hasMultipleProjects()?d:l.workspace,`likec4-views.js`);if(i&&(p=qe(i)?i:R(i),z(i)&&(await j(i)).isDirectory()))throw Error(`output file is a directory: ${i}`);s.debug(`${v.dim(`outfilepath`)} ${p}`);let m=N(p);s.debug(`${v.dim(`filename`)} ${m}`);let h=F(m).toLocaleLowerCase();if(h!==`.js`&&h!==`.mjs`)throw s.warn(`output file ${i} has extension "${h}"`),Error(`output file ${i} must be a .js or .mjs`);let g=await vt();s.debug(`${v.dim(`created temp public`)} ${g}`);let _=await Ct({languageServices:l,outDir:g,filename:m,webcomponentPrefix:r,base:`/`});s.debug(`${v.dim(`vite build webcomponent`)}`),await V({..._,logLevel:`warn`});let y=R(g,m);if(!z(y))throw Error(`output file not found: ${y}`);await k(P(p),{recursive:!0}),await He(y,p),s.info(`${v.dim(`generated`)} ${p}`),s.debug(`${v.dim(`remove temp public`)}`),await Ke(g,{recursive:!0,force:!0}),c.stopAndLog(),K(oe(`
30
+ ${v.dim(`Webcomponents generated to:`)}
31
+ ${L(B(),p)}
32
+
33
+ ${v.dim(`Setup and usage instructions:`)}
34
+ ${v.blue(`https://likec4.dev/tooling/code-generation/webcomponent/`)}
35
+ `))}catch(e){o.e=e}finally{await o.d()}}const on=e=>e.command({command:`gen <command> [path]`,aliases:[`generate`,`codegen`],describe:`Generate various artifacts from LikeC4 sources`,builder:e=>e.positional(`path`,J).command(`react [path]`,`generate react component to render likec4 view`,e=>e.positional(`path`,J).option(`project`,X).option(`outfile`,{alias:`o`,type:`string`,desc:`<file> path to output file (.jsx, .mjs or .js)`,normalize:!0,coerce:O}).option(`use-dot`,Y).option(`use-core-package`,Ot),async e=>{await rn({project:e.project,useDotBin:e.useDotBin,path:e.path,outfile:e.outfile,useCorePackage:e.useCorePackage})}).command({command:`webcomponent [path]`,aliases:[`wc`,`webcomp`],describe:`generate js with webcomponents`,builder:e=>e.positional(`path`,J).option(`project`,X).option(`outfile`,{alias:`o`,type:`string`,desc:`<file> path to output file (.mjs or .js)`,normalize:!0,coerce:O}).option(`webcomponent-prefix`,jt).option(`use-dot`,Y),handler:async e=>{await an({project:e.project,useDotBin:e.useDotBin,path:e.path,outfile:e.outfile,webcomponentPrefix:e.webcomponentPrefix})}}).command({command:`model [path]`,aliases:[`ts`],describe:`generate LikeC4Model (.ts)`,builder:e=>e.positional(`path`,J).option(`project`,X).option(`outfile`,{alias:`o`,type:`string`,desc:`<file> path to output file (.ts)`,normalize:!0,coerce:O}).option(`use-dot`,Y).option(`use-core-package`,Ot),handler:async e=>{await tn({path:e.path,useDotBin:e.useDotBin,useCorePackage:e.useCorePackage,outfile:e.outfile,project:e.project})}}).command({command:`views-data [path]`,aliases:[`views`],describe:`{deprecated} use codegen model`,deprecated:!0,builder:e=>e.positional(`path`,J).option(`outfile`,{alias:`o`,type:`string`,desc:`<file> output .ts file`,normalize:!0,coerce:O}).option(`use-dot`,Y),handler:async e=>{await $({format:`views`,path:e.path,useDotBin:e.useDotBin,outfile:e.outfile})}}).command({command:`dot [path]`,describe:`generate graphviz files (.dot)`,builder:e=>e.positional(`path`,J).option(`outdir`,At).option(`use-dot`,Y),handler:async e=>{await $({format:`dot`,path:e.path,useDotBin:e.useDotBin,outdir:e.outdir})}}).command({command:`d2 [path]`,describe:`generate D2 files (.d2)`,builder:e=>e.positional(`path`,J).option(`outdir`,At).option(`use-dot`,Y),handler:async e=>{await $({format:`d2`,path:e.path,useDotBin:e.useDotBin,outdir:e.outdir})}}).command({command:`mermaid [path]`,aliases:[`mmd`],describe:`generate Mermaid files (.mmd)`,builder:e=>e.positional(`path`,J).option(`outdir`,At).option(`use-dot`,Y),handler:async e=>{await $({format:`mermaid`,useDotBin:e.useDotBin,path:e.path,outdir:e.outdir})}}).command({command:`plantuml [path]`,aliases:[`puml`],describe:`generate PlantUML files (.puml)`,builder:e=>e.positional(`path`,J).option(`outdir`,At).option(`use-dot`,Y),handler:async e=>{await $({format:`plantuml`,useDotBin:e.useDotBin,path:e.path,outdir:e.outdir})}}).command({command:`<custom> [path]`,describe:`run custom generator from likec4 config`,builder:e=>e.positional(`path`,J).option(`project`,X).option(`use-dot`,Y),handler:async e=>{await Xt({name:`custom`,path:e.path,project:e.project,useDotBin:e.useDotBin})}}).epilog(`${v.bold(`Examples:`)}
193
36
  likec4 gen react -o dist/likec4-views.mjs ./src/likec4
194
37
  likec4 gen model -o likec4-model.ts
195
38
  likec4 gen ts --outfile likec4-model.ts
@@ -197,61 +40,71 @@ export {
197
40
  likec4 gen mmd --outdir assets/
198
41
  likec4 gen plantuml --outdir assets/
199
42
  likec4 gen dot -o out .
200
- `),handler:async i=>{await customHandler({name:i.command,path:i.path,project:i.project,useDotBin:i.useDotBin})}});function drawioCmd$1(i){return i.command({command:`drawio [path]`,describe:`export view(s) to DrawIO (.drawio) for editing in draw.io`,builder:i=>i.positional(`path`,path$1).option(`outdir`,{alias:`o`,type:`string`,desc:`<dir> output directory for .drawio files`,normalize:!0,coerce:resolve}).options({project,"use-dot":useDotBin}).epilog(`${u.bold(`Examples:`)}
201
- ${u.green(`$0 export drawio`)}
202
- ${u.gray(`Export all views to DrawIO in current directory`)}
203
-
204
- ${u.green(`$0 export drawio -o ./diagrams src/`)}
205
- ${u.gray(`Export views to ./diagrams/`)}
206
- `),handler:async i=>{let a=i.outdir??i.path,o=i.project,s=createLikeC4Logger(`c4:export`),c=startTimer(s),l=await fromWorkspace(i.path,{graphviz:useDotBin?`binary`:`wasm`,watch:!1});l.ensureSingleProject();let d=o==null?void 0:l.languageServices.projectsManager.ensureProjectId(o),f=await l.layoutedModel(d);if(f===LikeC4Model$1.EMPTY)throw s.error(`No project or empty model`),Error(`No project or empty model`);await mkdir(a,{recursive:!0});let p=0;for(let i of f.views()){let o=i.$view;try{let c=generateDrawio(i),l=resolve(a,o.id+`.drawio`);await writeFile(l,c),s.info(`${u.dim(`generated`)} ${relative(process.cwd(),l)}`),p++}catch(i){s.error(`Failed to export view ${o.id}`,{error:i instanceof Error?i:Error(String(i))})}}p>0&&s.info(`${u.dim(`total`)} ${p} DrawIO file(s)`),c.stopAndLog(`✓ export drawio in `)}})}function jsonCmd(i){return i.command({command:`json [path]`,describe:`export model(s) to JSON`,builder:i=>i.positional(`path`,path$1).option(`outfile`,{alias:`o`,type:`string`,desc:`<file> output .json file`,default:`likec4.json`,normalize:!0,coerce:resolve}).options({project,"use-dot":useDotBin,"skip-layout":{type:`boolean`,desc:`skip layouting (only compute model)`},pretty:{type:`boolean`,desc:`indented JSON output`}}).epilog(`${u.bold(`Examples:`)}
207
- ${u.green(`$0 export json --skip-layout`)}
208
- ${u.gray(`Search for likec4 files in current directory and output JSON to likec4.json (no layout)`)}
209
-
210
- ${u.green(`$0 export json --pretty -o ./generated/likec4.json src/likec4 `)}
211
- ${u.gray(`Search for likec4 files in src/likec4 and output JSON to generated/likec4.json`)}
212
- `),handler:async i=>{let a=i.outfile,o=i.project,s=createLikeC4Logger(`c4:export`),l=startTimer(s),d=await fromWorkspace(i.path,{graphviz:useDotBin?`binary`:`wasm`,watch:!1}),f=[...d.projectsManager.all];if(o){if(f=f.filter(i=>i===o),!t$4(f,1))throw s.error(`project not found: ${o}`),Error(`project not found: ${o}`)}else{if(!t$4(f,1))throw s.error(`No projects found`),Error(`No projects found`);s.info(`${u.dim(`workspace:`)} Found ${f.length} projects`)}let p=[];for(let a of f){let o;if(i.skipLayout?(s.info(`Generate model for project ${u.green(a)} ${u.dim(`(skip layout)`)}`),o=await d.computedModel(a)):(s.info(`Generating layouted model for project ${u.green(a)}`),o=await d.layoutedModel(a)),o===LikeC4Model$1.EMPTY){s.warn(u.yellow(`Project ${a} is empty, skipping`));continue}p.push(o.$data)}extname(a)!==`.json`&&(a+=`.json`),await mkdir(dirname(a),{recursive:!0});let m=p.length===1?p[0]:p,h=i.pretty?JSON.stringify(m,void 0,2):JSON.stringify(m);await writeFile(a,h);let g=a.startsWith(i.path)?relative(i.path,a):a;s.info(`${u.dim(`generated`)} ${g}`),l.stopAndLog(`✓ export in `)}})}var import_picomatch=__toESM(require_picomatch(),1);function resolveServerUrl(i){if(i.resolvedUrls)return n(i.resolvedUrls.network)??n(i.resolvedUrls.local)}function printServerUrls(i){if(!i.resolvedUrls)throw Error(`Vite server is not ready, no resolvedUrls`);boxen([u.green(`LikeC4 served at:`),``,u.dim(`Local: `)+i.resolvedUrls.local.join(`
213
- `+``.padEnd(9,` `)),i.resolvedUrls.network.length?u.dim(`Network: `)+i.resolvedUrls.network.join(`
214
- `+``.padEnd(9,` `)):void 0].filter(i=>e$3(i)).join(`
215
- `))}async function viteDev({buildWebcomponent:i=!0,hmr:a=!0,webcomponentPrefix:o=`likec4`,title:s,languageServices:c,likec4AssetsDir:l,openBrowser:d,listen:f,port:p,...m}){l??=await mkdtemp(join(tmpdir(),`.likec4-assets-`));let{isDev:h,...g}=await viteConfig({...m,languageServices:c,likec4AssetsDir:l,webcomponentPrefix:o,title:s}),_=g.customLogger;p??=env.PORT?parseInt(env.PORT,10):void 0,p||=await getPorts({port:[5173,5174,...portNumbers(61e3,61010),...portNumbers(62002,62010)]});let v=24678,y=await mkTempPublicDir(),b=f??(isInsideContainer()?`0.0.0.0`:`localhost`);a?(v=await getPorts({port:portNumbers(24678,24690)}),_.info(`Enabling HMR: localhost:${v}`),isInsideContainer()&&_.info(u.yellow(`ensure port ${v} is published from container`))):_.info(`Disabling HMR`);let x=await createServer({...g,define:a?{...g.define,"process.env.NODE_ENV":`"development"`}:g.define,mode:a?`development`:g.mode,publicDir:y,server:{host:b,allowedHosts:!0,port:p,hmr:a&&{overlay:!0,port:v},fs:{strict:!1},open:d??(!h&&!isInsideContainer())}});return i?(_.info(`Building webcomponent`),viteWebcomponentConfig({webcomponentPrefix:o,languageServices:c,outDir:y,base:g.base}).then(i=>build({...i,logLevel:`warn`})).catch(i=>{_.warn(loggable(i)),_.warn(`webcomponent build failed, ignoring error and continue`)})):_.info(`Skip webcomponent build`),await x.listen(),x}async function takeScreenshot({browserContext:i,views:a,output:o,logger:s,timeout:c,maxAttempts:l,dynamicVariant:p,outputType:m,theme:h}){let g,_=a.map(i=>({view:i,attempt:1})),v=[],y;for(;y=_.shift();){let{view:a,attempt:b}=y,x=`export/${encodeURIComponent(a.id)}/`;try{if(b>1){g&&=(g.close({runBeforeUnload:!0}).catch(i=>s.error(`failed to close page: ${i}`)),void 0);let i=t$5(b*200,{min:200,max:1e3});s.info(u.cyan(x)+u.dim(` attempt ${b} of ${l} after ${i}ms`)),await setTimeout(i)}else a.hasLayoutDrift&&s.warn(u.yellow(`Drift detected, manual layout can not be applied, view may be invalid: `)+u.red(a.id));let _=`.`;m===`relative`&&(_=a.sourcePath??`.`,_=_.includes(`/`)?_.slice(0,_.lastIndexOf(`/`)):`.`);let y=resolve(o,_,`${a.id}.png`);g??=await i.newPage();let S=a.bounds;p===`sequence`&&a._type===`dynamic`&&(S=a.sequenceLayout.bounds),await g.setViewportSize({width:S.width+40+20,height:S.height+40+20}),await g.goto(withQuery(x,{padding:20,theme:h,dynamic:p})),s.info(u.cyan(x)+u.dim(` -> ${relative(o,y)}`)),await g.waitForSelector(`.react-flow.initialized`),a.nodes.some(i=>e$4(i.icon)&&i.icon.toLowerCase().startsWith(`http`))&&await waitAllImages(g,c),await g.getByTestId(`export-page`).screenshot({animations:`disabled`,path:y,omitBackground:!0}),v.push({view:a,path:y})}catch(i){g?.close({runBeforeUnload:!0}).catch(i=>s.error(`failed to close page: ${i}`)),s.error(u.red(`failed `+x+`
216
- `+i)),b<l&&(_.push({view:a,attempt:b+1}),s.info(u.dim(`retry ${x}`))),g=void 0}}return v}async function waitAllImages(i,a){let o=await i.locator(`//img`).all();if(!o.length)return;let s=o.map(i=>i.evaluate(i=>i.complete||new Promise(a=>{i.onload=a,i.onerror=a}),{timeout:Math.max(15e3,a)}));await Promise.allSettled(s)}async function exportViewsToPNG({logger:i,serverUrl:a,theme:o=`light`,timeoutMs:s=15e3,views:c,output:l,outputType:d=`relative`,maxAttempts:f=3,chromiumSandbox:p=!1,sequence:m=!1}){i.info(`${u.dim(`output`)} ${l}`),i.info(`${u.dim(`base url`)} ${a}\n`);let{chromium:h}=await import(`playwright`),g=h.executablePath();i.info(u.cyan(`Start chromium`)+` `+u.dim(g));let _=await h.launch({chromiumSandbox:p,headless:!0});i.info(u.cyan(`Color scheme: `)+o+`
217
- `);let v=await _.newContext({deviceScaleFactor:2,colorScheme:o,baseURL:a,bypassCSP:!0,ignoreHTTPSErrors:!0,isMobile:!1});v.setDefaultNavigationTimeout(s),v.setDefaultTimeout(s);try{return await takeScreenshot({browserContext:v,views:c,output:l,outputType:d,logger:i,maxAttempts:f,dynamicVariant:m?`sequence`:`diagram`,timeout:s,theme:o})}finally{i.info(u.cyan(`close chromium`)),await v.close(),await _.close()}}async function pngHandler({path:i,useDotBin:a,project:o,theme:s=`light`,output:l,outputType:d,serverUrl:f,ignore:p=!1,timeoutMs:m=1e4,maxAttempts:h=3,filter:g,sequence:_=!1,chromiumSandbox:v=!1}){try{var y=_usingCtx();let b=createLikeC4Logger(`export`),x=hrtime(),S=y.a(await fromWorkspace(i,{graphviz:a?`binary`:`wasm`,watch:!1}));l??=S.workspace;let C,w=[...S.languageServices.projects()];if(o&&!w.some(i=>i.id===o))throw b.error(`project not found: ${o}`),Error(`project not found: ${o}`);if(!f&&(b.info(u.cyan(`start preview server`)),C=await viteDev({languageServices:S,buildWebcomponent:!1,openBrowser:!1,hmr:!1}),f=resolveServerUrl(C),!f))throw b.error(`Vite server is not ready, no resolvedUrls`),Error(`Vite server is not ready, no resolvedUrls`);for(let i of w){if(o&&i.id!==o)continue;w.length>1&&(b.info(u.dim(`---------`)),b.info(`${u.dim(`project:`)} ${i.id}`),b.info(`${u.dim(`folder:`)} ${i.folder.fsPath}`));let a=await S.diagrams(i.id);if(g&&t$4(g,1)&&t$4(a,1)){let i=(0,import_picomatch.default)(g);b.info(`${u.cyan(`filter`)} ${u.dim(JSON.stringify(g))}`),a=a.filter(a=>i(a.id)?(b.info(`${u.green(`include`)} ${a.id} ✅`),!0):(b.info(`${u.gray(`skip`)} ${u.dim(a.id)}`),!1))}if(!t$4(a,1)){b.warn(`no views found`);continue}let y=w.length>1?withTrailingSlash(joinURL(f,`project`,i.id)):f,C=w.length>1?joinURL(l,i.id):l,E=await exportViewsToPNG({logger:b,serverUrl:y,theme:s,timeoutMs:m,views:a,output:C,outputType:d,maxAttempts:h,sequence:_,chromiumSandbox:v}),{pretty:D}=inMillis(x);if(E.length>0&&b.info(u.green(`exported ${E.length} views in ${D}`)+`
218
- `),E.length!==a.length&&(p&&E.length>0?b.info(u.dim(`ignore`)+` `+u.red(`failed ${a.length-E.length} out of ${a.length} views`)):b.error(u.red(`failed ${a.length-E.length} out of ${a.length} views`))),E.length!==a.length&&(E.length===0||!p))throw Error(`Failed ${a.length-E.length} out of ${a.length} views`)}C&&(b.info(u.cyan(`stop server`)),await C.close().catch(i=>{b.error(i)}))}catch(i){y.e=i}finally{await y.d()}}function pngCmd(i){return i.command({command:`png [path]`,describe:`export views to PNG`,builder:i=>i.positional(`path`,path$1).options({output:{alias:[`o`,`outdir`],type:`string`,desc:`output directory, if not specified, images are saved next to sources`,normalize:!0,nargs:1,coerce:resolve},project,theme:{choices:[`light`,`dark`],desc:`color-scheme to use, defaults to light`,conflicts:[`dark`,`light`],nargs:1},dark:{type:`boolean`,desc:`use dark theme, shortcut for --theme=dark`,conflicts:[`theme`,`light`]},light:{type:`boolean`,desc:`use light theme, shortcut for --theme=light`,conflicts:[`theme`,`dark`]},"use-dot":useDotBin,seq:{boolean:!0,alias:[`sequence`],type:`boolean`,desc:`use sequence layout for dynamic views`},flat:{alias:[`flatten`],boolean:!0,type:`boolean`,desc:`flatten all images in output directory ignoring sources structure`},filter:{alias:`f`,array:!0,string:!0,desc:`include views with ids matching given patterns
219
- multiple patterns are combined with OR`},ignore:{boolean:!0,alias:`i`,desc:`continue if export fails for some views`},timeout:{type:`number`,alias:`t`,desc:`timeout for playwright (in seconds)`,default:15,nargs:1},"max-attempts":{type:`number`,desc:`max attempts to export failing view, 1 means no retry`,default:3,nargs:1},"server-url":{type:`string`,desc:`use this url instead of starting new likec4 server`,nargs:1},"chromium-sandbox":{boolean:!0,desc:`enable chromium sandbox (see Playwright docs)`,default:!1}}).epilog(`${u.bold(`Examples:`)}
220
- ${u.green(`$0 export png`)}
221
- ${u.gray(`Search for likec4 files in current directory and output PNG next to sources`)}
222
-
223
- ${u.green(`$0 export png --theme dark -o ./png src/likec4`)}
224
- ${u.gray(`Search for likec4 files in src/likec4 and output PNG with dark theme to png folder`)}
225
-
226
- ${u.green(`$0 export png -f "team1*" -f "team2*" --flat -o ./png src/likec4`)}
227
- ${u.gray(`Export views matching team1* or team2* only`)}
228
-
229
- ${u.green(`$0 export png -f "use-case*" --sequence src/likec4`)}
230
- ${u.gray(`Export views matching use-case* using sequence layout`)}
231
- `),handler:async i=>{invariant(i.timeout>=1,`timeout must be >= 1`),invariant(i[`max-attempts`]>=1,`max-attempts must be >= 1`),await ensureReact();let a=i.theme??(i.dark?`dark`:`light`);await pngHandler({path:i.path,useDotBin:i[`use-dot`],output:i.output,project:i.project,timeoutMs:i.timeout*1e3,maxAttempts:i.maxAttempts,ignore:i.ignore===!0,outputType:i.flat?`flat`:`relative`,serverUrl:i.serverUrl,theme:a,filter:i.filter,sequence:i.seq,chromiumSandbox:i[`chromium-sandbox`]})}})}const exportCmd=i=>i.command({command:`export <format> [path]`,describe:`Export to images, JSON, or DrawIO`,builder:i=>t$1(i.usage(`${u.bold(`Usage:`)} $0 export <format> [path]`),pngCmd,jsonCmd,drawioCmd$1).updateStrings({"Commands:":u.bold(`Formats:`)}),handler:()=>void 0});function drawioCmd(i){return i.command({command:`drawio <input>`,describe:`convert DrawIO (.drawio) to LikeC4 source (.c4)`,builder:i=>i.positional(`input`,{type:`string`,describe:`path to .drawio or .drawio.xml file`,normalize:!0,coerce:resolve}).option(`outfile`,{alias:`o`,type:`string`,desc:`<file> output .c4 file (default: same name as input with .c4)`,normalize:!0,coerce:resolve}).epilog(`${u.bold(`Examples:`)}
232
- ${u.green(`$0 import drawio diagram.drawio`)}
233
- ${u.gray(`Convert diagram.drawio to diagram.c4`)}
234
-
235
- ${u.green(`$0 import drawio diagram.drawio -o src/model.c4`)}
236
- ${u.gray(`Convert and write to src/model.c4`)}
237
- `),handler:async i=>{let a=createLikeC4Logger(`c4:import`),o=startTimer(a),s=i.input;if(!s)throw Error(`Missing required argument: input`);let c=parseDrawioToLikeC4(await readFile(s,`utf-8`)),l=i.outfile;l?extname(l)!==`.c4`&&(l+=`.c4`):l=s.replace(/\.drawio(\.xml)?$/i,``)+`.c4`,await writeFile(l,c),a.info(`${u.dim(`generated`)} ${relative(process.cwd(),l)}`),o.stopAndLog(`✓ import drawio in `)}})}const importCmd=i=>i.command({command:`import <format> <input>`,describe:`Convert external diagram formats to LikeC4`,builder:i=>t$1(i.usage(`${u.bold(`Usage:`)} $0 import <format> <input> [options]`),drawioCmd).updateStrings({"Commands:":u.bold(`Formats:`)}),handler:()=>void 0}),mcpCmd=i=>i.command({command:`mcp [path]`,aliases:[],describe:`Start MCP server`,builder:i=>i.usage(`${u.bold(`Usage:`)} $0 mcp [path]`).positional(`path`,path$1).option(`stdio`,{boolean:!0,description:`use stdio transport`,conflicts:[`http`,`port`]}).option(`http`,{boolean:!0,description:`use streamable http transport (use 33335 port by default)`,conflicts:`stdio`}).option(`port`,{alias:`p`,number:!0,description:`enables http transport and sets the port`,conflicts:`stdio`}).option(`use-dot`,useDotBin).epilog(`${u.bold(`Examples:`)}
238
- ${u.green(`$0 mcp`)}
239
- ${u.gray(`Start MCP with default stdio transport`)}
240
- ${u.green(`$0 mcp --http ./src`)}
241
- ${u.gray(`Start MCP with streamable http transport on port 33335 at ./src folder`)}
242
- ${u.green(`$0 mcp -p 1234`)}
243
- ${u.gray(`Start MCP with streamable http transport on port 1234`)}
244
- `),handler:async i=>{i.http||i.port?await startHttpMcp(i.path,i.useDot,i.port):await startStdioMcp(i.path,i.useDot)}});async function startHttpMcp(i,a,o=33335){await fromWorkspace$1(i,{mcp:{port:o},watch:!0,graphviz:a?`binary`:`wasm`}),boxen([u.green(`LikeC4 MCP served at:`),`
43
+ `),handler:async e=>{await Xt({name:e.command,path:e.path,project:e.project,useDotBin:e.useDotBin})}}),sn=new Set([`node_modules`,`.git`]);function cn(e){return e.endsWith(`.c4`)||e.endsWith(`.likec4`)}function ln(e,t=`
44
+
45
+ `){return e.filter(e=>e.trim()!==``).join(t)}const un=`No project or empty model`,dn=`No views could be exported`;function fn(){return`${v.bold(`Examples:`)}
46
+ ${v.green(`$0 export drawio`)}
47
+ ${v.gray(`Export each view to a separate .drawio file`)}
48
+
49
+ ${v.green(`$0 export drawio --all-in-one -o ./diagrams src/`)}
50
+ ${v.gray(`Export all views as tabs in one .drawio file`)}
51
+
52
+ ${v.green(`$0 export drawio --roundtrip -o ./out`)}
53
+ ${v.gray(`Re-apply layout/waypoints from comment blocks (e.g. after import from DrawIO)`)}
54
+
55
+ ${v.green(`$0 export drawio --uncompressed -o ./out`)}
56
+ ${v.gray(`Export with raw XML (no compression) for draw.io desktop compatibility`)}`}function pn(e){return e instanceof Error?e:Error(g(e))}function mn(e,t,n){let r=pn(n);throw e.error(t,{error:r}),r}async function hn(e,t){let n=[],r=new Set;async function i(e,a){if(a>=50)return;let o=await Ge(e).catch(()=>null);if(o==null||r.has(o))return;r.add(o);let s=await We(e,{withFileTypes:!0}).catch(n=>(t?.debug&&t.debug(`${v.dim(`Roundtrip:`)} readdir failed`,{dir:e,err:n}),[]));for(let r of s){let o=I(e,r.name);switch(!0){case r.isDirectory():sn.has(r.name)||await i(o,a+1);break;case r.isSymbolicLink():if((await j(o).catch(()=>null))?.isFile()&&cn(r.name)){let e=await Ue(o,`utf-8`).catch(e=>(t?.debug&&t.debug(`${v.dim(`Roundtrip:`)} readFile failed`,{file:o,err:e}),``));e&&n.push(e)}break;case r.isFile()&&cn(r.name):{let e=await Ue(o,`utf-8`).catch(e=>(t?.debug&&t.debug(`${v.dim(`Roundtrip:`)} readFile failed`,{file:o,err:e}),``));e&&n.push(e);break}}}}return await i(e,0),ln(n)}async function gn(e,t,n){if(t)return hn(R(e),n)}function _n(e,t,n){return he(e.map(e=>String(e.$view.id)),t,n?{compressed:!1}:void 0)}async function vn(e){let{viewmodels:t,outdir:n,workspacePath:r,roundtrip:i,uncompressed:a,logger:o}=e,s=de(t,_n(t,await gn(r,i,o),a)),c=R(n,_e);await M(c,s),o.info(`${v.dim(`generated`)} ${L(process.cwd(),c)} (${t.length} tab(s))`)}async function yn(e,t,n,r){let i=String(e.$view.id);try{let a=ce(e,t[i]),o=R(n,i+`.drawio`);return await k(P(o),{recursive:!0}),await M(o,a),r.info(`${v.dim(`generated`)} ${L(process.cwd(),o)}`),!0}catch(e){return r.error(`Failed to export view ${i}`,{error:pn(e)}),!1}}async function bn(e){let{viewmodels:t,outdir:n,workspacePath:r,roundtrip:i,uncompressed:a,logger:o}=e,s=_n(t,await gn(r,i,o),a),c=0;for(let e of t)await yn(e,s,n,o)&&c++;return{succeeded:c}}async function xn(e,t){try{var n=Z();let r=G(t),i=n.a(await T(e.path,{graphviz:e.useDot?`binary`:`wasm`,watch:!1}));e.project||i.ensureSingleProject();let a=e.project==null?void 0:i.languageServices.projectsManager.ensureProjectId(e.project),o=await i.layoutedModel(a);if(o===ve.EMPTY)throw t.error(un),Error(un);let s=[...o.views()];if(s.length===0)throw t.error(`No views to export`),Error(dn);await k(e.outdir,{recursive:!0});let c={viewmodels:s,outdir:e.outdir,workspacePath:e.path,roundtrip:e.roundtrip,uncompressed:e.uncompressed,logger:t};if(e.allInOne)try{await vn(c)}catch(e){mn(t,`Failed to export DrawIO`,e)}else{let{succeeded:e}=await bn(c);if(e===0)throw t.error(dn),Error(dn);t.info(`${v.dim(`total`)} ${e} DrawIO file(s)`)}r.stopAndLog(`✓ export drawio in `)}catch(e){n.e=e}finally{await n.d()}}function Sn(e){return e.command({command:`drawio [path]`,describe:`export view(s) to DrawIO (.drawio) for editing in draw.io`,builder:e=>e.positional(`path`,J).option(`outdir`,{alias:`o`,type:`string`,desc:`<dir> output directory for .drawio files`,normalize:!0,coerce:R}).option(`all-in-one`,{type:`boolean`,default:!1,desc:`write one .drawio file with all views as tabs (diagrams)`}).option(`roundtrip`,{type:`boolean`,default:!1,desc:`apply layout/stroke/waypoints from DrawIO round-trip comment blocks in .c4 source`}).option(`uncompressed`,{type:`boolean`,default:!1,desc:`write diagram XML uncompressed inside .drawio (larger file; use if draw.io desktop fails to open compressed export)`}).options({project:X,"use-dot":Y}).epilog(fn()),handler:async e=>{let t=W(`c4:export`);await xn({path:e.path,outdir:e.outdir??e.path,allInOne:!!e.allInOne,roundtrip:!!e.roundtrip,uncompressed:!!e.uncompressed,project:e.project,useDot:!!e[`use-dot`]},t)}})}const Cn=`project not found`,wn=`No projects found`;async function Tn(e,t){try{var n=Z();let r=G(t),i=n.a(await be.fromWorkspace(e.path,{logger:t,graphviz:e.useDot?`binary`:`wasm`,watch:!1})),o=[...i.projectsManager.all];if(e.project){if(o=o.filter(t=>t===e.project),!a(o,1))throw t.error(`${Cn}: ${e.project}`),Error(`${Cn}: ${e.project}`)}else{if(!a(o,1))throw t.error(wn),Error(wn);t.info(`${v.dim(`workspace:`)} Found ${o.length} projects`)}let s=[];for(let n of o){let r;if(e.skipLayout?(t.info(`Generate model for project ${v.green(n)} ${v.dim(`(skip layout)`)}`),r=await i.computedModel(n)):(t.info(`Generating layouted model for project ${v.green(n)}`),r=await i.layoutedModel(n)),r===ve.EMPTY){t.warn(v.yellow(`Project ${n} is empty, skipping`));continue}s.push(r.$data)}if(s.length===0)throw t.warn(`No models generated, aborting export`),Error(`No models generated; all projects are empty or were skipped`);let c=e.outfile;F(c).toLowerCase()!==`.json`&&(c+=`.json`),await k(P(c),{recursive:!0});let l=s.length===1?s[0]:s,u=e.pretty?JSON.stringify(l,void 0,2):JSON.stringify(l);await M(c,u);let d=c.startsWith(e.path)?L(e.path,c):c;t.info(`${v.dim(`generated`)} ${d}`),r.stopAndLog(`✓ export in `)}catch(e){n.e=e}finally{await n.d()}}function En(e){return e.command({command:`json [path]`,describe:`export model(s) to JSON`,builder:e=>e.positional(`path`,J).option(`outfile`,{alias:`o`,type:`string`,desc:`<file> output .json file`,default:`likec4.json`,normalize:!0,coerce:R}).options({project:X,"use-dot":Y,"skip-layout":{type:`boolean`,desc:`skip layouting (only compute model)`},pretty:{type:`boolean`,desc:`indented JSON output`}}).epilog(`${v.bold(`Examples:`)}
57
+ ${v.green(`$0 export json --skip-layout`)}
58
+ ${v.gray(`Search for likec4 files in current directory and output JSON to likec4.json (no layout)`)}
59
+
60
+ ${v.green(`$0 export json --pretty -o ./generated/likec4.json src/likec4 `)}
61
+ ${v.gray(`Search for likec4 files in src/likec4 and output JSON to generated/likec4.json`)}
62
+ `),handler:async e=>{let t=W(`c4:export`);await Tn({path:e.path,outfile:e.outfile,project:e.project,skipLayout:!!e.skipLayout,pretty:!!e.pretty,useDot:!!e[`use-dot`]},t)}})}var Dn=e(S(),1);function On(e){if(e.resolvedUrls)return i(e.resolvedUrls.network)??i(e.resolvedUrls.local)}function kn(e){if(!e.resolvedUrls)throw Error(`Vite server is not ready, no resolvedUrls`);K([v.green(`LikeC4 served at:`),``,v.dim(`Local: `)+e.resolvedUrls.local.join(`
63
+ `+``.padEnd(9,` `)),e.resolvedUrls.network.length?v.dim(`Network: `)+e.resolvedUrls.network.join(`
64
+ `+``.padEnd(9,` `)):void 0].filter(e=>l(e)).join(`
65
+ `))}async function An({buildWebcomponent:e=!0,hmr:t=!0,webcomponentPrefix:n=`likec4`,title:r,languageServices:i,likec4AssetsDir:a,openBrowser:o,listen:s,port:c,...l}){a??=await A(I(D(),`.likec4-assets-`));let{isDev:u,...d}=await St({...l,languageServices:i,likec4AssetsDir:a,webcomponentPrefix:n,title:r}),f=d.customLogger;c??=ze.PORT?parseInt(ze.PORT,10):void 0,c||=await Oe({port:[5173,5174,...E(61e3,61010),...E(62002,62010)]});let p=24678,m=await vt(),h=s??(w()?`0.0.0.0`:`localhost`);t?(p=await Oe({port:E(24678,24690)}),f.info(`Enabling HMR: localhost:${p}`),w()&&f.info(v.yellow(`ensure port ${p} is published from container`))):f.info(`Disabling HMR`);let _=await ct({...d,define:t?{...d.define,"process.env.NODE_ENV":`"development"`}:d.define,mode:t?`development`:d.mode,publicDir:m,server:{host:h,allowedHosts:!0,port:c,hmr:t&&{overlay:!0,port:p},fs:{strict:!1},open:o??(!u&&!w())}});return e?(f.info(`Building webcomponent`),Ct({webcomponentPrefix:n,languageServices:i,outDir:m,base:d.base}).then(e=>V({...e,logLevel:`warn`})).catch(e=>{f.warn(g(e)),f.warn(`webcomponent build failed, ignoring error and continue`)})):f.info(`Skip webcomponent build`),await _.listen(),_}async function jn({browserContext:e,views:r,output:i,logger:a,timeout:o,maxAttempts:s,dynamicVariant:c,outputType:l,theme:u}){let d,f=r.map(e=>({view:e,attempt:1})),p=[],m;for(;m=f.shift();){let{view:r,attempt:h}=m,g=`export/${encodeURIComponent(r.id)}/`;try{if(h>1){d&&=(d.close({runBeforeUnload:!0}).catch(e=>a.error(`failed to close page: ${e}`)),void 0);let e=t(h*200,{min:200,max:1e3});a.info(v.cyan(g)+v.dim(` attempt ${h} of ${s} after ${e}ms`)),await ut(e)}else r.hasLayoutDrift&&a.warn(v.yellow(`Drift detected, manual layout can not be applied, view may be invalid: `)+v.red(r.id));let f=`.`;l===`relative`&&(f=r.sourcePath??`.`,f=f.includes(`/`)?f.slice(0,f.lastIndexOf(`/`)):`.`);let m=R(i,f,`${r.id}.png`);d??=await e.newPage();let _=r.bounds;c===`sequence`&&r._type===`dynamic`&&(_=r.sequenceLayout.bounds),await d.setViewportSize({width:_.width+40+20,height:_.height+40+20}),await d.goto(ee(g,{padding:20,theme:u,dynamic:c})),a.info(v.cyan(g)+v.dim(` -> ${L(i,m)}`)),await d.waitForSelector(`.react-flow.initialized`),r.nodes.some(e=>n(e.icon)&&e.icon.toLowerCase().startsWith(`http`))&&await Mn(d,o),await d.getByTestId(`export-page`).screenshot({animations:`disabled`,path:m,omitBackground:!0}),p.push({view:r,path:m})}catch(e){d?.close({runBeforeUnload:!0}).catch(e=>a.error(`failed to close page: ${e}`)),a.error(v.red(`failed `+g+`
66
+ `+e)),h<s&&(f.push({view:r,attempt:h+1}),a.info(v.dim(`retry ${g}`))),d=void 0}}return p}async function Mn(e,t){let n=await e.locator(`//img`).all();if(!n.length)return;let r=n.map(e=>e.evaluate(e=>e.complete||new Promise(t=>{e.onload=t,e.onerror=t}),{timeout:Math.max(15e3,t)}));await Promise.allSettled(r)}async function Nn({logger:e,serverUrl:t,theme:n=`light`,timeoutMs:r=15e3,views:i,output:a,outputType:o=`relative`,maxAttempts:s=3,chromiumSandbox:c=!1,sequence:l=!1}){e.info(`${v.dim(`output`)} ${a}`),e.info(`${v.dim(`base url`)} ${t}\n`);let{chromium:u}=await import(`playwright`),d=u.executablePath();e.info(v.cyan(`Start chromium`)+` `+v.dim(d));let f=await u.launch({chromiumSandbox:c,headless:!0});e.info(v.cyan(`Color scheme: `)+n+`
67
+ `);let p=await f.newContext({deviceScaleFactor:2,colorScheme:n,baseURL:t,bypassCSP:!0,ignoreHTTPSErrors:!0,isMobile:!1});p.setDefaultNavigationTimeout(r),p.setDefaultTimeout(r);try{return await jn({browserContext:p,views:i,output:a,outputType:o,logger:e,maxAttempts:s,dynamicVariant:l?`sequence`:`diagram`,timeout:r,theme:n})}finally{e.info(v.cyan(`close chromium`)),await p.close(),await f.close()}}async function Pn(e,t){try{var n=Z();let{path:r,useDotBin:i,project:o,theme:s=`light`,output:c,outputType:l,serverUrl:u,ignore:d=!1,timeoutMs:f=15e3,maxAttempts:p=3,filter:m,sequence:h=!1,chromiumSandbox:g=!1}=e,_=n.a(await be.fromWorkspace(r,{logger:`vite`,graphviz:i?`binary`:`wasm`,watch:!1})),y=c??_.workspace,b,x=u,S=[..._.languageServices.projects()];if(o&&!S.some(e=>e.id===o))throw t.error(`project not found: ${o}`),Error(`project not found: ${o}`);try{if(!x&&(t.info(v.cyan(`start preview server`)),b=await An({languageServices:_,buildWebcomponent:!1,openBrowser:!1,hmr:!1}),x=On(b),!x))throw t.error(`Vite server is not ready, no resolvedUrls`),Error(`Vite server is not ready, no resolvedUrls`);for(let e of S){if(o&&e.id!==o)continue;S.length>1&&(t.info(v.dim(`---------`)),t.info(`${v.dim(`project:`)} ${e.id}`),t.info(`${v.dim(`folder:`)} ${e.folder.fsPath}`));let n=await _.diagrams(e.id);if(m&&a(m,1)&&a(n,1)){let e=(0,Dn.default)(m);t.info(`${v.cyan(`filter`)} ${v.dim(JSON.stringify(m))}`),n=n.filter(n=>e(n.id)?(t.info(`${v.green(`include`)} ${n.id} ✅`),!0):(t.info(`${v.gray(`skip`)} ${v.dim(n.id)}`),!1))}if(!a(n,1)){t.warn(`no views found`);continue}let r=S.length>1?te(ne(x,`project`,e.id)):x,i=S.length>1?ne(y,e.id):y,c=tt(),u=await Nn({logger:t,serverUrl:r,theme:s,timeoutMs:f,views:n,output:i,outputType:l,maxAttempts:p,sequence:h,chromiumSandbox:g}),{pretty:b}=ft(c);if(u.length>0&&t.info(v.green(`exported ${u.length} views in ${b}`)+`
68
+ `),u.length!==n.length&&(d&&u.length>0?t.info(v.dim(`ignore`)+` `+v.red(`failed ${n.length-u.length} out of ${n.length} views`)):t.error(v.red(`failed ${n.length-u.length} out of ${n.length} views`))),u.length!==n.length&&(u.length===0||!d))throw Error(`Failed ${n.length-u.length} out of ${n.length} views`)}}finally{b&&(t.info(v.cyan(`stop server`)),await b.close().catch(e=>{t.error(e)}))}}catch(e){n.e=e}finally{await n.d()}}async function Fn(e){await Pn(e,W(`c4:export`))}function In(e){return e.command({command:`png [path]`,describe:`export views to PNG`,builder:e=>e.positional(`path`,J).options({outdir:{alias:[`o`,`output`],type:`string`,desc:`output directory for PNG files; if not specified, images are saved next to sources`,normalize:!0,nargs:1,coerce:R},project:X,theme:{choices:[`light`,`dark`],desc:`color-scheme to use, defaults to light`,conflicts:[`dark`,`light`],nargs:1},dark:{type:`boolean`,desc:`use dark theme, shortcut for --theme=dark`,conflicts:[`theme`,`light`]},light:{type:`boolean`,desc:`use light theme, shortcut for --theme=light`,conflicts:[`theme`,`dark`]},"use-dot":Y,seq:{alias:[`sequence`],type:`boolean`,desc:`use sequence layout for dynamic views`},flat:{alias:[`flatten`],type:`boolean`,desc:`flatten all images in outdir ignoring sources structure`},filter:{alias:`f`,array:!0,string:!0,desc:`include views with ids matching given patterns
69
+ multiple patterns are combined with OR`},ignore:{boolean:!0,alias:`i`,desc:`continue if export fails for some views`},timeout:{type:`number`,alias:`t`,desc:`timeout for playwright (in seconds)`,default:15,nargs:1},"max-attempts":{type:`number`,desc:`max attempts to export failing view, 1 means no retry`,default:3,nargs:1},"server-url":{type:`string`,desc:`use this url instead of starting new likec4 server`,nargs:1},"chromium-sandbox":{boolean:!0,desc:`enable chromium sandbox (see Playwright docs)`,default:!1}}).epilog(`${v.bold(`Examples:`)}
70
+ ${v.green(`$0 export png`)}
71
+ ${v.gray(`Search for likec4 files in current directory and output PNG next to sources`)}
72
+
73
+ ${v.green(`$0 export png --theme dark -o ./png src/likec4`)}
74
+ ${v.gray(`Search for likec4 files in src/likec4 and output PNG with dark theme to png folder`)}
75
+
76
+ ${v.green(`$0 export png -f "team1*" -f "team2*" --flat -o ./png src/likec4`)}
77
+ ${v.gray(`Export views matching team1* or team2* only`)}
78
+
79
+ ${v.green(`$0 export png -f "use-case*" --sequence src/likec4`)}
80
+ ${v.gray(`Export views matching use-case* using sequence layout`)}
81
+ `),handler:async e=>{Ie(e.timeout>=1,`timeout must be >= 1`),Ie(e[`max-attempts`]>=1,`max-attempts must be >= 1`),await q(),await Dt();let t=e.theme??(e.dark?`dark`:`light`);await Fn({path:e.path,useDotBin:e[`use-dot`],output:e.outdir,project:e.project,timeoutMs:e.timeout*1e3,maxAttempts:e[`max-attempts`],ignore:e.ignore===!0,outputType:e.flat?`flat`:`relative`,serverUrl:e[`server-url`],theme:t,filter:e.filter,sequence:e.seq,chromiumSandbox:e[`chromium-sandbox`]})}})}const Ln=e=>e.command({command:`export <format> [path]`,describe:`Export to images, JSON, or DrawIO`,builder:e=>o(e.usage(`${v.bold(`Usage:`)} $0 export <format> [path]`),In,En,Sn).updateStrings({"Commands:":v.bold(`Formats:`)}),handler:()=>void 0});var Rn=ke();function zn(e){return e.command({command:`lsp`,aliases:[],describe:`Start LSP server`,builder:e=>e.usage(`${v.bold(`Usage:`)} $0 lsp`).option(`log-level`,Lt).option(`verbose`,Rt).options({"node-ipc":{boolean:!0,description:`use node-ipc transport`,conflicts:[`stdio`,`socket`,`pipe`]},stdio:{boolean:!0,description:`use stdio transport`,conflicts:[`node-ipc`,`socket`,`pipe`]},socket:{number:!0,description:`use socket transport on specified port`,conflicts:[`node-ipc`,`stdio`,`pipe`],nargs:1},pipe:{string:!0,description:`use pipe transport with specified pipe name`,conflicts:[`node-ipc`,`stdio`,`socket`],nargs:1},"manual-layouts":{boolean:!0,description:`enable/disable manual layouts`,default:!0,defaultDescription:`enabled`},watch:{alias:`w`,boolean:!0,description:`enable built-in watcher`,default:!1,defaultDescription:`disabled`},telemetry:{boolean:!0,default:!0,defaultDescription:`IDE setting`,description:`enable/disable telemetry`,hidden:!0}}).option(`use-dot`,Y).showHidden().epilog(`${v.bold(`Examples:`)}
82
+
83
+ ${v.green(`$0 lsp --stdio `)}
84
+ ${v.gray(`Start LSP with stdio transport`)}
85
+
86
+ ${v.green(`$0 lsp --node-ipc --watch --no-manual-layouts --no-color `)}
87
+ ${v.gray(`Start LSP with node-ipc transport and watcher, disabled manual layouts and disabled color`)}
88
+
89
+ `),handler:e=>{let t;if(e.nodeIpc||e.stdio||e.socket||e.pipe)t=(0,Rn.createConnection)(Rn.ProposedFeatures.all);else throw Error(`No transport specified`);m({lspConnection:t,useStdErr:e.stdio===!0,colors:v.isColorSupported,enableTelemetry:e.telemetry,logLevel:e.verbose?zt:e.logLevel}),p({connection:t,enableManualLayouts:e.manualLayouts,enableWatcher:e.watch,graphviz:e.useDot?`binary`:`wasm`,configureLogger:!1})}})}const Bn=e=>e.command({command:`mcp [path]`,aliases:[],describe:`Start MCP server`,builder:e=>e.usage(`${v.bold(`Usage:`)} $0 mcp [path]`).positional(`path`,J).default(`path`,`.`,`current directory`).option(`stdio`,{boolean:!0,description:`use stdio transport`,conflicts:[`http`,`port`]}).option(`http`,{boolean:!0,description:`use streamable http transport (use 33335 port by default)`,conflicts:`stdio`}).option(`port`,{alias:`p`,number:!0,description:`enables http transport and sets the port`,conflicts:`stdio`}).option(`use-dot`,Y).option(`log-level`,Lt).option(`verbose`,Rt).showHidden().epilog(`${v.bold(`Examples:`)}
90
+ ${v.green(`$0 mcp`)}
91
+ ${v.gray(`Start MCP with default stdio transport`)}
92
+ ${v.green(`$0 mcp --http ./src`)}
93
+ ${v.gray(`Start MCP with streamable http transport on port 33335 at ./src folder`)}
94
+ ${v.green(`$0 mcp -p 1234`)}
95
+ ${v.gray(`Start MCP with streamable http transport on port 1234`)}
96
+ `),handler:async e=>{e.http||e.port?(m({colors:v.isColorSupported,logLevel:e.verbose?zt:e.logLevel}),await Vn(e.path,e.useDot,e.port)):(m({useStdErr:!0,logLevel:e.verbose?zt:e.logLevel}),await Hn(e.path,e.useDot))}});async function Vn(e,t,n=33335){await T(e,{mcp:{port:n},watch:!0,configureLogger:!1,graphviz:t?`binary`:`wasm`}),K([v.green(`LikeC4 MCP served at:`),`
245
97
  {
246
98
  "mcpServers": {
247
99
  "likec4": {
248
- "url": "http://localhost:${o}/mcp"
100
+ "url": "http://localhost:${n}/mcp"
249
101
  }
250
102
  }
251
103
  }
252
104
 
253
- ${u.dim(`Documentation:`)}
254
- ${u.underline(`https://likec4.dev/tooling/mcp/#using-extension`)}
105
+ ${v.dim(`Documentation:`)}
106
+ ${v.underline(`https://likec4.dev/tooling/mcp/#using-extension`)}
255
107
  `].join(`
256
- `))}async function startStdioMcp(i,a){await fromWorkspace$1(i,{mcp:`stdio`,watch:!0,graphviz:a?`binary`:`wasm`})}async function vitePreview(i){let a=await viteConfig({...i,likec4AssetsDir:``,webcomponentPrefix:void 0}),o=await getPorts({port:portNumbers(62001,62010)}),s=i?.open??!1;return await preview({...a,mode:`production`,preview:{host:i.listen??`127.0.0.1`,allowedHosts:!0,port:o,open:s}})}async function handler$1({path:i,output:a,base:o,listen:s}){printServerUrls(await vitePreview({base:o,languageServices:await fromWorkspace(i,{watch:!1}),outputDir:a,open:!isInsideContainer(),listen:s}))}const previewCmd=i=>i.command({command:`preview [path]`,describe:`Start local server to preview production build`,builder:i=>i.positional(`path`,{type:`string`,desc:`Directory with LikeC4 source files
257
- if not specified search in current directory`,normalize:!0}).options({output:{alias:`o`,type:`string`,desc:`output directory from production build`,normalize:!0},base:{type:`string`,desc:`base url the app is being served from`},listen:{alias:`l`,type:`string`,desc:`ip address of the network interface to listen on`}}).coerce([`path`,`output`],resolve$1).default(`path`,resolve$1(`.`),`.`).default(`listen`,`127.0.0.1`,`localhost`),handler:async i=>{await handler$1(i)}});async function handler({path:i,useDotBin:a,webcomponentPrefix:o,title:s,useHashHistory:c,enableWebcomponent:l=!0,enableHMR:d=!0,base:f,listen:p,port:m}){d&&(process.env.NODE_ENV=`development`);let h=await viteDev({buildWebcomponent:l,hmr:d,base:f,webcomponentPrefix:o,title:s,languageServices:await fromWorkspace(i,{graphviz:a?`binary`:`wasm`,watch:d}),useHashHistory:c,likec4AssetsDir:await mkdtemp(join(tmpdir(),`.likec4-assets-`)),listen:p,port:m});h.config.logger.clearScreen(`info`),printServerUrls(h)}const serveCmd=i=>i.command({command:`start [path]`,aliases:[`serve`,`dev`],describe:`Start local dev server to preview LikeC4 views`,builder:i=>i.positional(`path`,path$1).option(`base`,base).option(`webcomponent-prefix`,webcomponentPrefix).option(`title`,title).option(`use-hash-history`,useHashHistory).option(`use-dot`,useDotBin).option(`listen`,listen).option(`port`,port).options({"react-hmr":{type:`boolean`,default:!0,describe:`Enable/Disable React HMR`},"build-webcomponent":{type:`boolean`,default:!0,describe:`Enable/Disable Webcomponent build`}}),handler:async i=>{await ensureReact(),await handler({path:i.path,useDotBin:i[`use-dot`],base:i.base,webcomponentPrefix:i[`webcomponent-prefix`],title:i.title,useHashHistory:i[`use-hash-history`],listen:i.listen,port:i.port,enableHMR:i[`react-hmr`],enableWebcomponent:i[`build-webcomponent`]})}});function validateModel(i){return i.getErrors().length===0}async function validateLayout(i,a,o){let s=await a.diagrams(),c=!1;for(let a of s)a.drifts&&a.drifts.length>0&&(c=!0,o.error(u.red(`Layout drift detected on view '${a.id}' at ${resolve(i,a.sourcePath??`.`)}`)));return!c}const validateCmd=i=>i.command({command:`validate [path]`,aliases:[],describe:`Validate model syntax and manual layout`,builder:i=>i.positional(`path`,path$1).option(`ignore-layout`,{alias:[`skip-layout`],boolean:!0,default:!1,description:`do not validate layout of views`}),handler:async i=>{let a=createLikeC4Logger(`c4:validate`),o=i[`ignore-layout`],s=await fromWorkspace(i.path,{watch:!1}),c=validateModel(s);c&&=o||await validateLayout(i.path,s,a)}});function configurelogger(i=isDevelopment){configureLogger({sinks:{console:getConsoleSink({formatter:u.isColorSupported?getAnsiColorFormatter():getConsoleFormatter()})},loggers:[{category:`likec4`,sinks:[`console`],lowestLevel:i?`debug`:`info`}]})}async function main(){!false_default&&!isInsideContainer()&&notifyAvailableUpdate(),await t$1(yargs(hideBin(argv)),serveCmd,buildCmd,codegenCmd,exportCmd,importCmd,previewCmd,validateCmd,mcpCmd,checkUpdateCmd,i=>i.command({command:`completion`,describe:`Generate completion script`,handler:()=>{i.showCompletionScript()}})).scriptName(`likec4`).usage(`Usage: $0 <command>`).version(version).alias(`v`,`version`).alias(`h`,`help`).help(`help`).option(`verbose`,{type:`boolean`,describe:`verbose logging`,global:!0}).demandCommand(1,`Please run with valid command`).recommendCommands().showHelpOnFail(!0).updateStrings({"Options:":u.bold(`Options:`),"Positionals:":u.bold(`Arguments:`),"Commands:":u.bold(`Commands:`),"Examples:":u.bold(`Examples:`)}).wrap(t$5(stdout.columns-10,{min:80,max:150})).middleware(i=>{configurelogger(i.verbose||isDevelopment)}).parseAsync()}main().catch(()=>{exit(1)}),process.on(`unhandledRejection`,i=>{console.error(`Unhandled rejection`,i)});export{};
108
+ `))}async function Hn(e,t){await T(e,{mcp:`stdio`,watch:!0,configureLogger:!1,graphviz:t?`binary`:`wasm`})}async function Un(e){let t=await St({...e,likec4AssetsDir:``,webcomponentPrefix:void 0}),n=await Oe({port:E(62001,62010)}),r=e?.open??!1;return await lt({...t,customLogger:t.customLogger,mode:`production`,preview:{host:e.listen??`127.0.0.1`,allowedHosts:!0,port:n,open:r}})}async function Wn({path:e,output:t,base:n,listen:r}){kn(await Un({base:n,languageServices:await C(e,{watch:!1}),outputDir:t,open:!w(),listen:r}))}const Gn=e=>e.command({command:`preview [path]`,describe:`Start local server to preview production build`,builder:e=>e.positional(`path`,{type:`string`,desc:`Directory with LikeC4 source files
109
+ if not specified search in current directory`,normalize:!0}).options({output:{alias:`o`,type:`string`,desc:`output directory from production build`,normalize:!0},base:{type:`string`,desc:`base url the app is being served from`},listen:{alias:`l`,type:`string`,desc:`ip address of the network interface to listen on`}}).coerce([`path`,`output`],O).default(`path`,O(`.`),`.`).default(`listen`,`127.0.0.1`,`localhost`),handler:async e=>{await Wn(e)}});async function Kn({path:e,useDotBin:t,webcomponentPrefix:n,title:r,useHashHistory:i,enableWebcomponent:a=!0,enableHMR:o=!0,base:s,listen:c,port:l}){o&&(process.env.NODE_ENV=`development`);let u=await An({buildWebcomponent:a,hmr:o,base:s,webcomponentPrefix:n,title:r,languageServices:await C(e,{graphviz:t?`binary`:`wasm`,watch:o}),useHashHistory:i,likec4AssetsDir:await A(I(D(),`.likec4-assets-`)),listen:c,port:l});u.config.logger.clearScreen(`info`),kn(u)}const qn=e=>e.command({command:`start [path]`,aliases:[`serve`,`dev`],describe:`Start local dev server to preview LikeC4 views`,builder:e=>e.positional(`path`,J).option(`base`,Nt).option(`webcomponent-prefix`,jt).option(`title`,Mt).option(`use-hash-history`,kt).option(`use-dot`,Y).option(`listen`,Ft).option(`port`,It).options({"react-hmr":{type:`boolean`,default:!0,describe:`Enable/Disable React HMR`},"build-webcomponent":{type:`boolean`,default:!0,describe:`Enable/Disable Webcomponent build`}}),handler:async e=>{await q(),await Kn({path:e.path,useDotBin:e[`use-dot`],base:e.base,webcomponentPrefix:e[`webcomponent-prefix`],title:e.title,useHashHistory:e[`use-hash-history`],listen:e.listen,port:e.port,enableHMR:e[`react-hmr`],enableWebcomponent:e[`build-webcomponent`]})}});function Jn(e){return e.getErrors().length===0}async function Yn(e,t,n){let r=await t.diagrams(),i=!1;for(let t of r)t.drifts&&t.drifts.length>0&&(i=!0,n.error(v.red(`Layout drift detected on view '${t.id}' at ${R(e,t.sourcePath??`.`)}`)));return!i}const Xn=e=>e.command({command:`validate [path]`,aliases:[],describe:`Validate model syntax and manual layout`,builder:e=>e.positional(`path`,J).option(`ignore-layout`,{alias:[`skip-layout`],boolean:!0,default:!1,description:`do not validate layout of views`}),handler:async e=>{let t=W(`c4:validate`),n=e[`ignore-layout`],r=await C(e.path,{watch:!1}),i=Jn(r);i&&=n||await Yn(e.path,r,t)}});function Zn(e){let t=e??(ye?`trace`:`info`);f({reset:!0,sinks:{console:h({formatter:v.isColorSupported?_():d()})},loggers:[{category:`likec4`,sinks:[`console`],lowestLevel:t}]})}async function Qn(){!ye&&!w()&&await Wt(),await o(rt(it($e)),qn,Bt,on,Ln,Gn,Xn,Bn,zn,qt,e=>e.command({command:`completion`,describe:`Generate completion script`,handler:()=>{e.showCompletionScript()}})).scriptName(`likec4`).usage(`Usage: $0 <command>`).version(H).alias(`v`,`version`).alias(`h`,`help`).help(`help`).option(`log-level`,{...Lt,global:!1}).option(`verbose`,{...Rt,global:!1}).option(`color`,{boolean:!0,describe:[`force color output, or disable with --no-color`,`respects 'FORCE_COLOR' and 'NO_COLOR' env variables`].join(`
110
+ `),skipValidation:!0,global:!0}).demandCommand(1,`Please run with valid command`).recommendCommands().showHelpOnFail(!0).updateStrings({"Options:":v.bold(`Options:`),"Positionals:":v.bold(`Arguments:`),"Commands:":v.bold(`Commands:`),"Examples:":v.bold(`Examples:`)}).wrap(t(nt.columns-10,{min:60,max:180})).middleware(e=>{Zn(e.verbose?zt:e.logLevel)}).parseAsync()}function $n(e,t){console.error(t==null?g(e):`${t} ${g(e)}`),et(1)}Qn().catch($n),process.on(`unhandledRejection`,e=>{$n(e,`Unhandled rejection:`)}),process.on(`uncaughtException`,e=>{console.error(e)});export{};