likec4 1.50.0 → 1.52.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 (46) hide show
  1. package/__app__/src/ProjectsOverview.js +1 -1
  2. package/__app__/src/likec4.js +277 -164
  3. package/__app__/src/main.js +2 -56
  4. package/__app__/src/routes/index.js +85 -18
  5. package/__app__/src/routes/projects.js +1 -1
  6. package/__app__/src/routes/single.js +433 -53
  7. package/__app__/src/style.css +1 -1
  8. package/__app__/src/vendors.js +18646 -17381
  9. package/__app__/src/webcomponent.js +1 -1
  10. package/config/schema.json +1 -1
  11. package/dist/THIRD-PARTY-LICENSES.md +183 -285
  12. package/dist/_chunks/LikeC4.mjs +1 -1154
  13. package/dist/_chunks/filesystem.mjs +1229 -0
  14. package/dist/_chunks/index2.d.mts +49 -18
  15. package/dist/_chunks/libs/@hono/mcp.mjs +9 -9
  16. package/dist/_chunks/libs/@hono/node-server.mjs +1 -1
  17. package/dist/_chunks/libs/@logtape/logtape.mjs +1 -1
  18. package/dist/_chunks/libs/@modelcontextprotocol/sdk.d.mts +13 -13
  19. package/dist/_chunks/libs/ansi-align.mjs +2 -0
  20. package/dist/_chunks/libs/ansi-regex.mjs +1 -0
  21. package/dist/_chunks/libs/ansi-styles.mjs +1 -0
  22. package/dist/_chunks/libs/atomically.mjs +1 -1
  23. package/dist/_chunks/libs/boxen.d.mts +1 -0
  24. package/dist/_chunks/libs/boxen.mjs +22 -0
  25. package/dist/_chunks/libs/conf.mjs +1 -1
  26. package/dist/_chunks/libs/langium.d.mts +1 -1
  27. package/dist/_chunks/libs/langium.mjs +17 -17
  28. package/dist/_chunks/libs/remeda.mjs +2 -2
  29. package/dist/_chunks/libs/tinyrainbow.mjs +1 -1
  30. package/dist/_chunks/libs/vscode-languageserver.mjs +1 -0
  31. package/dist/_chunks/sequence.mjs +1 -1
  32. package/dist/_chunks/src.mjs +1 -1
  33. package/dist/_chunks/src2.mjs +64 -64
  34. package/dist/cli/index.mjs +84 -74
  35. package/dist/index.d.mts +836 -1
  36. package/dist/index.mjs +1 -1
  37. package/dist/vite-plugin/index.mjs +1 -1
  38. package/dist/vite-plugin/internal.mjs +1 -1
  39. package/package.json +23 -24
  40. package/react/index.d.mts +56 -2
  41. package/react/index.mjs +1575 -595
  42. package/dist/_chunks/binary.mjs +0 -72
  43. package/dist/_chunks/libs/@logtape/logtape.d.mts +0 -741
  44. package/dist/_chunks/libs/@msgpack/msgpack.mjs +0 -1
  45. package/dist/_chunks/libs/@smithy/is-array-buffer.mjs +0 -1
  46. package/dist/_chunks/libs/@smithy/util-base64.mjs +0 -1
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{s as e}from"../_chunks/rolldown-runtime.mjs";import"../_chunks/libs/birpc.mjs";import{C as t,E as n,G as r,J as i,Q as a,S as o,U as s,X as c,k as l,t as u}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 d,h as f,m as p,p as m,v as h,y as g}from"../_chunks/binary.mjs";import"../_chunks/libs/defu.mjs";import"../_chunks/libs/pathe.mjs";import{t as _}from"../_chunks/libs/tinyrainbow.mjs";import{t as v}from"../_chunks/libs/json5.mjs";import"../_chunks/libs/@hono/mcp.mjs";import"../_chunks/src.mjs";import{B as y,z as b}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/eventemitter3.mjs";import"../_chunks/libs/p-queue.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{t as x}from"../_chunks/libs/picomatch.mjs";import{c as S,l as ee,o as te,r as ne,s as re}from"../_chunks/libs/ufo.mjs";import"../_chunks/libs/parse-ms.mjs";import{t as ie}from"../_chunks/libs/pretty-ms.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 ae}from"../_chunks/libs/strip-indent.mjs";import"../_chunks/libs/isexe.mjs";import"../_chunks/libs/which.mjs";import{a as oe,c as se,d as ce,f as C,i as le,l as ue,n as de,o as fe,r as pe,s as me,t as he,u as ge}from"../_chunks/src2.mjs";import"../_chunks/libs/pako.mjs";import{LikeC4Model as _e}from"../model/index.mjs";import{t as ve}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 ye}from"../_chunks/LikeC4.mjs";import"../_chunks/libs/@modelcontextprotocol/sdk.mjs";import"../_chunks/libs/@hono/node-server.mjs";import"../_chunks/libs/find-up-simple.mjs";import{t as be}from"../_chunks/libs/package-up.mjs";import{n as xe,t as Se}from"../_chunks/libs/package-manager-detector.mjs";import{n as Ce,t as we}from"../_chunks/libs/conf.mjs";import"../_chunks/libs/atomically.mjs";import"../_chunks/libs/ajv.mjs";import{t as Te}from"../_chunks/libs/ky.mjs";import{n as E,t as Ee}from"../_chunks/libs/get-port.mjs";import De from"node:module";import{isDeploymentElementModel as Oe,isDeploymentRelationModel as ke,isElementModel as Ae,isLikeC4ViewModel as je,isRelationModel as Me}from"@likec4/core/model";import{invariant as Ne,nonexhaustive as Pe}from"@likec4/core";import{copyFile as Fe,mkdir as D,mkdtemp as O,readFile as Ie,readdir as Le,realpath as Re,rm as ze,stat as Be,writeFile as k}from"node:fs/promises";import{basename as Ve,dirname as A,extname as j,isAbsolute as He,join as M,relative as N,resolve as P,sep as Ue}from"node:path";import{copyFileSync as We,existsSync as F,readdirSync as Ge,rmSync as Ke,statSync as qe}from"node:fs";import{resolve as I}from"path";import Je from"nano-spawn";import{tmpdir as Ye}from"node:os";import{argv as Xe,cwd as L,exit as Ze,hrtime as Qe,stdout as $e}from"node:process";import{env as et,isDevelopment as tt,isMinimal as nt,nodeENV as rt}from"std-env";import it from"yargs";import{hideBin as at}from"yargs/helpers";import ot from"boxen";import{fileURLToPath as st}from"node:url";import ct from"@vitejs/plugin-react";import{viteSingleFile as lt}from"vite-plugin-singlefile";import{build as R,createServer as ut,preview as dt}from"vite";import{setTimeout as ft}from"node:timers/promises";var pt=`likec4`,z=`1.50.0`;const B=p.getChild(`cli`);function V(e){let t=p.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(`${_.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(`${_.red(r.name+` `+r.message)}`,{error:r});return}t.error(_.red(e),{error:r});return}if(typeof e==`string`){t.error(_.red(e));return}t.error`${e}`},clearScreen:function(e){},hasErrorLogged:function(e){return!1},hasWarned:!1}}function mt(e){let[t,n]=Qe(e),r=t*1e3+n/1e6;return{ms:r,pretty:ie(r)}}function H(e){let t=Qe();return{stopAndLog(n=`done in `){n=_.green(`${n}${mt(t).pretty}`),(e||B).info(n)}}}function U(e,t){console.log(ot(e,{padding:1,margin:1,dimBorder:!0,...t}))}const ht=V(`vite`),W=A(st(import.meta.url)),gt={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/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/fast-equals.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 be,t as xe}from"../_chunks/LikeC4.mjs";import"../_chunks/libs/ansi-regex.mjs";import{t as Se}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 Ce}from"../_chunks/libs/package-up.mjs";import{n as we,t as Te}from"../_chunks/libs/package-manager-detector.mjs";import{n as Ee,t as De}from"../_chunks/libs/conf.mjs";import"../_chunks/libs/atomically.mjs";import"../_chunks/libs/ajv.mjs";import{t as Oe}from"../_chunks/libs/ky.mjs";import{n as ke,t as Ae}from"../_chunks/libs/get-port.mjs";import{t as je}from"../_chunks/libs/vscode-languageserver.mjs";import Me from"node:module";import{isDeploymentElementModel as Ne,isDeploymentRelationModel as Pe,isElementModel as Fe,isLikeC4ViewModel as Ie,isRelationModel as Le}from"@likec4/core/model";import{invariant as Re,nonexhaustive as ze}from"@likec4/core";import Be from"nano-spawn";import{tmpdir as T}from"node:os";import{resolve as E}from"path";import{env as Ve,isProduction as He,nodeENV as Ue}from"std-env";import{copyFile as We,mkdir as D,mkdtemp as O,readFile as Ge,readdir as Ke,realpath as qe,rm as Je,stat as Ye,writeFile as k}from"node:fs/promises";import{basename as A,dirname as j,extname as M,isAbsolute as Xe,join as N,relative as P,resolve as F,sep as Ze}from"node:path";import{copyFileSync as Qe,existsSync as I,readdirSync as $e,rmSync as et,statSync as tt}from"node:fs";import{argv as nt,cwd as L,exit as rt,hrtime as it,stdout as at}from"node:process";import ot from"yargs";import{hideBin as st}from"yargs/helpers";import{fileURLToPath as R,pathToFileURL as ct}from"node:url";import lt from"@vitejs/plugin-react";import{viteSingleFile as ut}from"vite-plugin-singlefile";import{build as z,createServer as dt,preview as ft}from"vite";import{setTimeout as pt}from"node:timers/promises";var mt=`likec4`,B=`1.52.0`;const V=u.getChild(`cli`);function H(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 ht(e){let[t,n]=it(e),r=t*1e3+n/1e6;return{ms:r,pretty:ae(r)}}function U(e){let t=it();return{stopAndLog(n=`done in `){n=v.green(`${n}${ht(t).pretty}`),(e||V).info(n)}}}function W(e,t){console.log(Se(e,{padding:1,margin:1,dimBorder:!0,...t}))}const gt=H(`vite`),G=j(R(import.meta.url)),_t={banner:`/* prettier-ignore-start */
3
3
  /* eslint-disable */
4
4
 
5
5
  /******************************************************************************
@@ -10,29 +10,29 @@ import{s as e}from"../_chunks/rolldown-runtime.mjs";import"../_chunks/libs/birpc
10
10
  `,footer:`
11
11
 
12
12
  /* prettier-ignore-end */
13
- `};function _t(){let e=be({cwd:W});if(!e)throw Error(`likec4 package folder not found`);return A(e)}function vt(){let e=[P(_t(),`__app__`),P(W,`../__app__`),P(W,`../../__app__`),P(W,`../../dist/__app__`)],t=r(e,F);if(!t)throw p.error(`likec4 app root does not exist, tried:\n${e.join(`
14
- `)}`),Error(`likec4 app root does not exist`);return t}async function yt(){let e=await O(M(Ye(),`.likec4-public-`));return await k(M(e,`likec4-views.js`),`// generated by likec4
15
- `),e}function G(e){return N(L(),e)}const bt=1e4;function xt(){let e=_t();return{"likec4/icons":`@likec4/icons`,"likec4/react":P(e,`react/index.mjs`),"likec4/model":P(e,`dist/model/index.mjs`),"likec4/vite-plugin/internal":P(e,`dist/vite-plugin/internal.mjs`)}}const St=async({languageServices:e,likec4AssetsDir:t,...n})=>{let r=n.customLogger??ht,i=vt();r.info(`${_.cyan(`likec4 app root`)} ${_.dim(G(i))}`);let a=n.outputDir??P(e.workspace,`dist`);r.info(_.cyan(`outDir`)+` `+_.dim(G(a)));let o=`/`;n.base&&(o=ee(n.base),!ne(o)&&o!==`./`&&(o=re(o))),o!==`/`&&r.info(`${_.green(`app base url`)} ${_.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:[P(i,`index.html`),P(i,`src`,`main.js`),P(i,`src`,`fonts.css`),P(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:[ct(),he({languageServices:e.languageServices}),l?lt():void 0]}};async function Ct({languageServices:e,outDir:t,base:n,webcomponentPrefix:r=`likec4`,filename:i=`likec4-views.js`}){let a=V([`vite`,`webcomponent`]),o=vt();return a.info(_.cyan(`outDir`)+` `+_.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:{...gt,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:[ct(),he({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 O(M(Ye(),`.likec4-assets-`));let s=await St({...o,languageServices:r,likec4AssetsDir:i,webcomponentPrefix:t,title:n,outputSingleFile:a}),c=!F(s.build.outDir)||Ge(s.build.outDir).length===0,l=await yt();for(let e of wt){let t=P(s.root,e);F(t)&&We(t,P(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(`${_.dim(`workspace:`)} ${_.green(`✓ all views layouted`)}`):s.customLogger.warn(`${_.dim(`workspace:`)} ${_.yellow(`✗ layouted ${t.length} of ${e.length} views`)}`),t.forEach(e=>{(e.hasLayoutDrift||e.drifts&&e.drifts.length>0)&&s.customLogger.warn(_.dim(`view`)+` `+_.red(e.id)+` `+_.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(`${_.dim(`project:`)} ${e.id} ${_.yellow(`✗ no views found`)}`):s.customLogger.info(`${_.dim(`project:`)} ${e.id} ${_.green(`${t.length} views`)}`)}if(e&&!a&&await R(await Ct({webcomponentPrefix:t,languageServices:r,outDir:l,base:s.base})),await R({...s,customLogger:s.customLogger,publicDir:l,mode:`production`}),a){if(!c){s.customLogger.warn(_.yellow(`outDir was not empty, skipping cleanup`));return}for(let e of Ge(P(s.build.outDir)).filter(e=>e!==`index.html`))Ke(P(s.build.outDir,e),{recursive:!0})}let d=P(s.build.outDir,`index.html`);F(d)&&We(d,P(s.build.outDir,`404.html`))}function Et(e){try{return!!De.createRequire(import.meta.url).resolve(e)}catch(e){return B.debug(g(e)),!1}}async function K(){if(Et(`react`)&&Et(`react-dom`)){B.debug(`react already installed`);return}B.debug(`react not installed`);let e=await Se();e||(B.error`Package manager not detected, please install dependencies manually: ${`react`} ${`react-dom`}`,process.exit(1));let t=xe(e.agent,`add`,[`react`,`react-dom`]);t||(B.error`Please install dependencies manually: ${`react`} ${`react-dom`}`,process.exit(1));try{await Je(t.command,t.args,{stdio:`inherit`})}catch(e){B.debug(g(e)),B.error`Please install dependencies manually: ${`react`} ${`react-dom`}`,process.exit(1)}}const q={type:`string`,desc:`<directory> with LikeC4 sources (default is current directory)`,normalize:!0,default:`.`,coerce:P},J={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()},Dt={boolean:!0,type:`boolean`,desc:"use `@likec4/core` package in types",default:!1},Ot={boolean:!0,type:`boolean`,desc:`use hash history for navigation, e.g. "/#/view" instead of "/view"`},Y={alias:`o`,type:`string`,desc:`output directory`,normalize:!0,nargs:1,coerce:P},kt={alias:`w`,type:`string`,desc:`prefix for Webcomponents, e.g "c4" generates <c4-view ../>`,default:`likec4`,nargs:1},At={alias:`t`,type:`string`,desc:`base title of the app pages (default is "LikeC4")`,default:`LikeC4`,nargs:1},jt={alias:[`base-url`],type:`string`,desc:`base url the app is being served from, e.g. "/" or "/pages/"`,nargs:1},Mt={boolean:!0,type:`boolean`,desc:`outputs a single self-contained HTML file with all required resources inlined`},Nt={alias:`l`,type:`string`,...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},Pt={type:`number`,desc:`port number for the dev server (default is 5173, or PORT environment variable)`,nargs:1},X={alias:`p`,type:`string`,desc:`select LikeC4 project by name (e.g. "my-project") or by path`,nargs:1};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 Ft=e=>e.command({command:`build [path]`,aliases:[`bundle`],describe:`Build a static website`,builder:e=>e.positional(`path`,q).option(`output`,{alias:`o`,type:`string`,desc:`output directory for production build`,normalize:!0,coerce:P}).option(`base`,jt).option(`use-hash-history`,Ot).option(`use-dot`,J).option(`webcomponent-prefix`,kt).option(`title`,At).option(`output-single-file`,Mt).example(`${_.green(`$0 build -o ./build ./src`)}`,_.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 K();let r=V(`c4:build`),i=t.a(await T(e.path,{graphviz:e[`use-dot`]?`binary`:`wasm`,watch:!1})),a=e.output??P(i.workspace,`dist`),o=P(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 It=e(Ce(),1);const Lt=new we({projectName:pt,serialize:e=>v.stringify(e,null,2),deserialize:e=>v.parse(e)}),Rt=`check-update`;function zt(){if(nt||rt===Rt)return;let e=Lt.get(`lastUpdateCheck`),t=Lt.get(`latestVersion`);if(l(t)||n(e)||e+864e5<Date.now())try{Je(`likec4`,[`check-update`],{stdio:`ignore`,preferLocal:!0,detached:!0,env:{NODE_ENV:Rt}}).catch(()=>{})}catch{}t&&(0,It.gt)(t,z)&&U([`Update available: `,_.dim(z),_.reset(` → `),_.green(t)].join(``))}async function Bt(){try{let e=await Vt();Ne(e,`No version found in latest npm`),Lt.set({lastUpdateCheck:Date.now(),latestVersion:e}),(0,It.gt)(e,z)?U([`Update available: `,_.dim(z),_.reset(` → `),_.green(e)].join(``)):U(_.dim(`Up to date: `)+` `+_.green(z))}catch(e){B.error(g(e))}}async function Vt(){return(await Te(`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 Ht=e=>e.command({command:`check-update`,describe:`Check for updates`,handler:async()=>{await Bt()}});function Ut(e,t){if(!t)return e.languageServices.projectsManager.ensureProjectId();let n=P(t);if(n===e.workspace)return e.languageServices.projectsManager.ensureProjectId();if(F(n)&&qe(n).isDirectory()){B.debug`Project path exists: ${n}`;let t=y.file(n.endsWith(Ue)?n:n+Ue),r=e.languageServices.projects().find(e=>e.folder.fsPath===t.fsPath);if(r)return B.debug`Found project ${r.id} at path: ${n}`,r.id;B.debug`No project registered at path: ${n}`}return e.languageServices.projectsManager.ensureProjectId(t)}function Wt(e,t){let n=Ut(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=B.getChild(`generator`);async function Gt({name:e,path:t,useDotBin:n,project:r}){try{var i=Z();let a=H(Q),o=i.a(await C(t,{graphviz:n?`binary`:`wasm`,watch:!1})),{projectId:s,config:c}=Wt(o,r);r&&Q.info(`${_.dim(`project`)} ${_.green(s)}`);let l=c.generators?.[e];if(!l)throw Q.error(_.red(`generator ${e} does not exist in project config`)),Error(`generator ${e} does not exist in project config`);Q.info(`${_.dim(`generator`)} ${_.green(e)}`),await Kt({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 Kt({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(`${_.dim(`runnig for project:`)} ${_.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 Ae(e):t=i.locate({element:e.id,projectId:s});break;case je(e):t=i.locate({view:e.id,projectId:s});break;case Oe(e):t=i.locate({deployment:e.id,projectId:s});break;case Me(e):case ke(e):t=i.locate({relation:e.id,projectId:s});break;default:Pe(e)}if(!t)throw r.error(`Cannot locate ${e.id}`,{target:e}),Error(`Cannot locate ${e.id}`);let n=y.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)?P(o.folder.fsPath,...e):y.isUri(e)?e.fsPath:P(o.folder.fsPath,`${e}`);let i=A(n);a.has(i)||(F(i)||(r.debug(`${_.dim(`create directory`)} ${i}`),await D(i,{recursive:!0})),a.add(i)),r.debug(`${_.dim(`write`)} ${n}`),await k(n,t)},abort:e=>{throw r.error(e||`Generator aborted`),Error(e||`Generator aborted`)}}}))}async function qt(e,t,n){t??=P(e.workspace,`likec4.generated.ts`),j(t)!==`.ts`&&(t+=`.ts`),await D(A(t),{recursive:!0});let r=pe([...await e.diagrams()]);await k(t,r),n.info(`${_.dim(`generated`)} ${N(process.cwd(),t)}`)}async function Jt(e,t,n){await D(t,{recursive:!0}),n.info(`${_.dim(`format`)} ${_.green(`dot`)}`),n.info(`${_.dim(`outdir`)} ${t}`);let r=new Set,i=await e.computedModel(),a=u(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=A(s.sourcePath)),c=P(t,c),r.has(c)||(await D(c,{recursive:!0}),r.add(c));let l=P(c,s.id+`.dot`);await k(l,a),n.info(`${_.dim(`generated`)} ${N(process.cwd(),l)}`),o++}catch(e){B.error(`error while generating ${s.id}`,{error:e})}o>0&&n.info(`${_.dim(`total`)} ${o} files`)}async function Yt(e,t,n,r){await D(n,{recursive:!0}),r.info(`${_.dim(`format`)} ${_.green(t)}`),r.info(`${_.dim(`outdir`)} ${n}`);let i,a;switch(t){case`d2`:i=`.d2`,a=ce;break;case`mermaid`:i=`.mmd`,a=fe;break;case`plantuml`:i=`.puml`,a=le;break;default:Pe(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=A(t.sourcePath)),s=P(n,s),o.has(s)||(await D(s,{recursive:!0}),o.add(s));let l=P(s,t.id+i);await k(l,a(e)),r.info(`${_.dim(`generated`)} ${N(process.cwd(),l)}`),c++}catch(e){r.error(`error while generating ${t.id}`,{error:e})}}c>0&&r.info(`${_.dim(`total`)} ${c} files`)}async function $({path:e,useDotBin:t,...n}){let r=V(`c4:codegen`),i=H(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 Jt(a,n.outdir??e,r);break;case`d2`:case`mermaid`:case`plantuml`:await Yt(a,n.format,n.outdir??e,r);break;default:Pe(n)}i.stopAndLog()}async function Xt({path:e,useDotBin:t,useCorePackage:n,outfile:r,project:i}){try{var a=Z();let o=V(`c4:codegen`),s=H(o),c=a.a(await C(e,{graphviz:t?`binary`:`wasm`,watch:!1})),{projectId:l,projectFolder:u}=Wt(c,i);i&&o.info(`${_.dim(`project`)} ${_.green(l)}`),o.info(`${_.dim(`format`)} ${_.green(`model`)}`);let d=await c.layoutedModel(l);for(let e of d.views())e.hasLayoutDrifts&&o.warn(_.yellow(`layout drift detected, view:`)+` `+_.red(e.id));let f=P(c.projectsManager.hasMultipleProjects()?u:c.workspace,`likec4-model.ts`);if(r&&(f=He(r)?r:P(r),F(r)&&(await Be(r)).isDirectory()))throw Error(`output file is a directory: ${r}`);let p=Ve(f);o.info(`${_.dim(`filename`)} ${p}`);let m=j(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=A(f);o.info(`${_.dim(`outdir`)} ${h}`),await D(h,{recursive:!0}),await k(f,oe(d,{useCorePackage:n}),{encoding:`utf-8`}),s.stopAndLog(),U(ae(`
16
- ${_.dim(`Source generated:`)}
17
- ${N(L(),f)}
18
-
19
- ${_.dim(`How to use:`)}
20
- ${_.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 Zt({languageServices:e,outDir:t,filename:n=`likec4-react.mjs`}){let r=V([`vite`,`react`]),i=vt();return r.info(`${_.cyan(`likec4 app root`)} ${_.dim(G(i))}`),r.info(_.cyan(`outDir`)+` `+_.dim(G(t))),{customLogger:r,root:i,configFile:!1,clearScreen:!1,publicDir:!1,mode:`production`,resolve:{conditions:[`production`],alias:xt()},esbuild:{banner:`'use client'
22
- `+gt.banner,footer:gt.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:[ct({}),he({languageServices:e.languageServices})]}}async function Qt({path:e,useDotBin:t,useCorePackage:n,outfile:r,project:i}){try{var a=Z();await K();let o=V(`c4:codegen`),s=H(o),c=a.a(await C(e,{graphviz:t?`binary`:`wasm`,watch:!1})),{projectId:l,projectFolder:u}=Wt(c,i);i&&o.info(`${_.dim(`project`)} ${_.green(l)}`),o.info(`${_.dim(`format`)} ${_.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(_.yellow(`layout drift detected, view:`)+` `+_.red(e.id));return}if(e.hasLayoutDrift){o.warn(_.yellow(`drift detected, manual layout can not be applied, view:`)+` `+_.red(e.id));return}});let f=P(c.projectsManager.hasMultipleProjects()?u:c.workspace,`likec4-views.js`);if(r&&(f=He(r)?r:P(r),F(r)&&(await Be(r)).isDirectory()))throw Error(`output file is a directory: ${r}`);let p=A(f);o.info(`${_.dim(`outdir`)} ${p}`);let m=Ve(f);o.info(`${_.dim(`filename`)} ${m}`);let h=j(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 R({...await Zt({languageServices:c,outDir:p,filename:m}),logLevel:`warn`});let g=await c.layoutedModel(l),v=P(p,Ve(f,h)+(h===`.mjs`?`.d.mts`:`.d.ts`));await k(v,de(g,{useCorePackage:n})),s.stopAndLog(),U(ae(`
23
- ${_.dim(`Sources generated:`)}
24
- ${N(L(),f)}
25
- ${N(L(),v)}
26
-
27
- ${_.dim(`How to use:`)}
28
- ${_.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 $t({project:e,path:t,useDotBin:n,webcomponentPrefix:r=`likec4`,outfile:a}){try{var o=Z();await K();let s=V(`c4:codegen`),c=H(s),l=o.a(await C(t,{graphviz:n?`binary`:`wasm`,watch:!1})),{projectId:u,projectFolder:d}=Wt(l,e);e&&s.info(`${_.dim(`project`)} ${_.green(u)}`),s.info(`${_.dim(`format`)} ${_.green(`webcomponent`)}`);let f=await l.diagrams(u);if(!i(f,1))throw s.warn(`no views found`),process.exitCode=1,Error(`no views found`);f.forEach(e=>{e.hasLayoutDrift&&s.warn(_.yellow(`drift detected, manual layout can not be applied, view:`)+` `+_.red(e.id))});let p=P(l.projectsManager.hasMultipleProjects()?d:l.workspace,`likec4-views.js`);if(a&&(p=He(a)?a:P(a),F(a)&&(await Be(a)).isDirectory()))throw Error(`output file is a directory: ${a}`);s.debug(`${_.dim(`outfilepath`)} ${p}`);let m=Ve(p);s.debug(`${_.dim(`filename`)} ${m}`);let h=j(m).toLocaleLowerCase();if(h!==`.js`&&h!==`.mjs`)throw s.warn(`output file ${a} has extension "${h}"`),Error(`output file ${a} must be a .js or .mjs`);let g=await yt();s.debug(`${_.dim(`created temp public`)} ${g}`);let v=await Ct({languageServices:l,outDir:g,filename:m,webcomponentPrefix:r,base:`/`});s.debug(`${_.dim(`vite build webcomponent`)}`),await R({...v,logLevel:`warn`});let y=P(g,m);if(!F(y))throw Error(`output file not found: ${y}`);await D(A(p),{recursive:!0}),await Fe(y,p),s.info(`${_.dim(`generated`)} ${p}`),s.debug(`${_.dim(`remove temp public`)}`),await ze(g,{recursive:!0,force:!0}),c.stopAndLog(),U(ae(`
30
- ${_.dim(`Webcomponents generated to:`)}
31
- ${N(L(),p)}
32
-
33
- ${_.dim(`Setup and usage instructions:`)}
34
- ${_.blue(`https://likec4.dev/tooling/code-generation/webcomponent/`)}
35
- `))}catch(e){o.e=e}finally{await o.d()}}const en=e=>e.command({command:`gen <command> [path]`,aliases:[`generate`,`codegen`],describe:`Generate various artifacts from LikeC4 sources`,builder:e=>e.positional(`path`,q).command(`react [path]`,`generate react component to render likec4 view`,e=>e.positional(`path`,q).option(`project`,X).option(`outfile`,{alias:`o`,type:`string`,desc:`<file> path to output file (.jsx, .mjs or .js)`,normalize:!0,coerce:I}).option(`use-dot`,J).option(`use-core-package`,Dt),async e=>{await Qt({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`,q).option(`project`,X).option(`outfile`,{alias:`o`,type:`string`,desc:`<file> path to output file (.mjs or .js)`,normalize:!0,coerce:I}).option(`webcomponent-prefix`,kt).option(`use-dot`,J),handler:async e=>{await $t({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`,q).option(`project`,X).option(`outfile`,{alias:`o`,type:`string`,desc:`<file> path to output file (.ts)`,normalize:!0,coerce:I}).option(`use-dot`,J).option(`use-core-package`,Dt),handler:async e=>{await Xt({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`,q).option(`outfile`,{alias:`o`,type:`string`,desc:`<file> output .ts file`,normalize:!0,coerce:I}).option(`use-dot`,J),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`,q).option(`outdir`,Y).option(`use-dot`,J),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`,q).option(`outdir`,Y).option(`use-dot`,J),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`,q).option(`outdir`,Y).option(`use-dot`,J),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`,q).option(`outdir`,Y).option(`use-dot`,J),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`,q).option(`project`,X).option(`use-dot`,J),handler:async e=>{await Gt({name:`custom`,path:e.path,project:e.project,useDotBin:e.useDotBin})}}).epilog(`${_.bold(`Examples:`)}
13
+ `};function vt(){let e=Ce({cwd:G});if(!e)throw Error(`likec4 package folder not found`);return j(e)}function yt(){let e=[F(vt(),`__app__`),F(G,`../__app__`),F(G,`../../__app__`),F(G,`../../dist/__app__`)],t=r(e,I);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 bt(){let e=await O(N(T(),`.likec4-public-`));return await k(N(e,`likec4-views.js`),`// generated by likec4
15
+ `),e}function K(e){return P(L(),e)}const xt=1e4;function St(){let e=vt();return{"likec4/icons":`@likec4/icons`,"likec4/react":F(e,`react/index.mjs`),"likec4/model":F(e,`dist/model/index.mjs`),"likec4/vite-plugin/internal":F(e,`dist/vite-plugin/internal.mjs`)}}const Ct=async({languageServices:e,likec4AssetsDir:t,...n})=>{let r=n.customLogger??gt,i=yt();r.info(`${v.cyan(`likec4 app root`)} ${v.dim(K(i))}`);let a=n.outputDir??F(e.workspace,`dist`);r.info(v.cyan(`outDir`)+` `+v.dim(K(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:{...St(),"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:xt,assetsInlineLimit:1e5,rollupOptions:{treeshake:{preset:`recommended`},...!l&&{input:[F(i,`index.html`),F(i,`src`,`main.js`),F(i,`src`,`fonts.css`),F(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:[lt(),ge({languageServices:e.languageServices}),l?ut():void 0]}};async function wt({languageServices:e,outDir:t,base:n,webcomponentPrefix:r=`likec4`,filename:i=`likec4-views.js`}){let a=H([`vite`,`webcomponent`]),o=yt();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:St(),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:{..._t,tsconfigRaw:{compilerOptions:{target:`ESNext`,jsx:`react-jsx`}}},build:{outDir:t,emptyOutDir:!1,sourcemap:!1,minify:!0,assetsInlineLimit:1024*1024,chunkSizeWarningLimit:xt,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:[lt(),ge({languageServices:e.languageServices})]}}const Tt=[`favicon.ico`,`robots.txt`];async function Et({buildWebcomponent:e=!0,webcomponentPrefix:t=`likec4`,title:n,languageServices:r,likec4AssetsDir:i,outputSingleFile:a,...o}){i??=await O(N(T(),`.likec4-assets-`));let s=await Ct({...o,languageServices:r,likec4AssetsDir:i,webcomponentPrefix:t,title:n,outputSingleFile:a}),c=!I(s.build.outDir)||$e(s.build.outDir).length===0,l=await bt();for(let e of Tt){let t=F(s.root,e);I(t)&&Qe(t,F(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 z(await wt({webcomponentPrefix:t,languageServices:r,outDir:l,base:s.base})),await z({...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 $e(F(s.build.outDir)).filter(e=>e!==`index.html`))et(F(s.build.outDir,e),{recursive:!0})}let d=F(s.build.outDir,`index.html`);I(d)&&Qe(d,F(s.build.outDir,`404.html`))}function Dt(e){try{return!!Me.createRequire(import.meta.url).resolve(e)}catch(e){return V.debug(g(e)),!1}}async function q(){if(Dt(`react`)&&Dt(`react-dom`)){V.debug(`react already installed`);return}V.warn(`react not installed`);let e=await Te();e||(V.error`Package manager not detected, please install dependencies manually: ${`react`} ${`react-dom`}`,process.exit(1));let t=we(e.agent,`add`,[`react`,`react-dom`]);t||(V.error`Please install dependencies manually: ${`react`} ${`react-dom`}`,process.exit(1));try{await Be(t.command,t.args,{stdio:`inherit`})}catch(e){V.debug(g(e)),V.error`Please install dependencies manually: ${`react`} ${`react-dom`}`,process.exit(1)}}async function Ot(){if(Dt(`playwright`)){V.debug(`playwright already installed`);return}V.warn(`playwright not installed`);let e=await Te();e||(V.error`Package manager not detected, please install dependencies manually: ${`playwright`}`,process.exit(1));let t=we(e.agent,`add`,[`playwright`]);t||(V.error`Please install dependencies manually: ${`playwright`}`,process.exit(1));try{await Be(t.command,t.args,{preferLocal:!0,stdio:`inherit`})}catch(e){V.debug(g(e)),V.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:Ve.LIKEC4_WORKSPACE||`.`,coerce:F},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()},kt={boolean:!0,type:`boolean`,desc:"use `@likec4/core` package in types",default:!1},At={boolean:!0,type:`boolean`,desc:`use hash history for navigation, e.g. "/#/view" instead of "/view"`},jt={alias:[`o`,`output`],string:!0,desc:`output directory`,normalize:!0,nargs:1,coerce:F},Mt={alias:`w`,string:!0,desc:`prefix for Webcomponents, e.g "c4" generates <c4-view ../>`,default:`likec4`,nargs:1},Nt={alias:`t`,string:!0,desc:`base title of the app pages (default is "LikeC4")`,default:`LikeC4`,nargs:1},Pt={alias:[`base-url`],string:!0,desc:`base url the app is being served from, e.g. "/" or "/pages/"`,nargs:1},Ft={boolean:!0,desc:`outputs a single self-contained HTML file with all required resources inlined`},It={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},Lt={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},Rt={hidden:!0,nargs:1,choices:[`trace`,`debug`,`info`,`warning`,`error`],conflicts:[`verbose`]},zt={boolean:!0,desc:`verbose logging`,conflicts:[`log-level`]},Bt=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 Vt=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:F}).option(`base`,Pt).option(`use-hash-history`,At).option(`use-dot`,Y).option(`webcomponent-prefix`,Mt).option(`title`,Nt).option(`output-single-file`,Ft).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=H(`c4:build`),i=t.a(await be(e.path,{graphviz:e[`use-dot`]?`binary`:`wasm`,watch:!1})),a=e.output??F(i.workspace,`dist`),o=F(a,`assets`);await Et({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 Ht=e(Ee(),1);const Ut=new De({projectName:mt,serialize:e=>y.stringify(e,null,2),deserialize:e=>y.parse(e)}),Wt=`check-update`;async function Gt(){if(He||Ue===Wt)return;let e=Ut.get(`lastUpdateCheck`);if(!e){await Kt(!1);return}let t=Ut.get(`latestVersion`);if(s(t)||s(e)||e+864e5<Date.now())try{Be(`likec4`,[`check-update`],{stdio:`ignore`,timeout:5e3,preferLocal:!0,detached:!0,env:{NODE_ENV:Wt}}).catch(()=>{})}catch{}t&&(0,Ht.gt)(t,B)&&W([`Update available: `,v.dim(B),v.reset(` → `),v.green(t)].join(``))}async function Kt(e=!0){try{Ut.set({lastUpdateCheck:Date.now()});let t=await qt();Re(t,`No version found in latest npm`),Ut.set({lastUpdateCheck:Date.now(),latestVersion:t}),(0,Ht.gt)(t,B)?W([`Update available: `,v.dim(B),v.reset(` → `),v.green(t)].join(``)):e&&W(v.dim(`Up to date: `)+` `+v.green(B))}catch(e){V.warning(g(e))}}async function qt(){return(await Oe(`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 Jt=e=>e.command({command:`check-update`,describe:`Check for updates`,handler:async()=>{await Kt()}});function Yt(e,t){if(!t)return e.languageServices.projectsManager.ensureProjectId();let n=F(t);if(n===e.workspace)return e.languageServices.projectsManager.ensureProjectId();if(I(n)&&tt(n).isDirectory()){V.debug`Project path exists: ${n}`;let t=x.file(n.endsWith(Ze)?n:n+Ze),r=e.languageServices.projects().find(e=>e.folder.fsPath===t.fsPath);if(r)return V.debug`Found project ${r.id} at path: ${n}`,r.id;V.debug`No project registered at path: ${n}`}return e.languageServices.projectsManager.ensureProjectId(t)}function Xt(e,t){let n=Yt(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=V.getChild(`generator`);async function Zt({name:e,path:t,useDotBin:n,project:r}){try{var i=Z();let a=U(Q),o=i.a(await C(t,{graphviz:n?`binary`:`wasm`,watch:!1})),{projectId:s,config:c}=Xt(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 Qt({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 Qt({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 Fe(e):t=i.locate({element:e.id,projectId:s});break;case Ie(e):t=i.locate({view:e.id,projectId:s});break;case Ne(e):t=i.locate({deployment:e.id,projectId:s});break;case Le(e):case Pe(e):t=i.locate({relation:e.id,projectId:s});break;default:ze(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)?F(o.folder.fsPath,...e):x.isUri(e)?e.fsPath:F(o.folder.fsPath,`${e}`);let i=j(n);a.has(i)||(I(i)||(r.debug(`${v.dim(`create directory`)} ${i}`),await D(i,{recursive:!0})),a.add(i)),r.debug(`${v.dim(`write`)} ${n}`),await k(n,t)},abort:e=>{throw r.error(e||`Generator aborted`),Error(e||`Generator aborted`)}}}))}async function $t(e,t,n){t??=F(e.workspace,`likec4.generated.ts`),M(t)!==`.ts`&&(t+=`.ts`),await D(j(t),{recursive:!0});let r=me([...await e.diagrams()]);await k(t,r),n.info(`${v.dim(`generated`)} ${P(process.cwd(),t)}`)}async function en(e,t,n){await D(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=j(s.sourcePath)),c=F(t,c),r.has(c)||(await D(c,{recursive:!0}),r.add(c));let l=F(c,s.id+`.dot`);await k(l,a),n.info(`${v.dim(`generated`)} ${P(process.cwd(),l)}`),o++}catch(e){V.error(`error while generating ${s.id}`,{error:e})}o>0&&n.info(`${v.dim(`total`)} ${o} files`)}async function tn(e,t,n,r){await D(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:ze(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=j(t.sourcePath)),s=F(n,s),o.has(s)||(await D(s,{recursive:!0}),o.add(s));let l=F(s,t.id+i);await k(l,a(e)),r.info(`${v.dim(`generated`)} ${P(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=H(`c4:codegen`),i=U(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 $t(a,n.outfile,r);break;case`dot`:await en(a,n.outdir??e,r);break;case`d2`:case`mermaid`:case`plantuml`:await tn(a,n.format,n.outdir??e,r);break;default:ze(n)}i.stopAndLog()}async function nn({path:e,useDotBin:t,useCorePackage:n,outfile:r,project:i}){try{var a=Z();let o=H(`c4:codegen`),s=U(o),c=a.a(await C(e,{graphviz:t?`binary`:`wasm`,watch:!1})),{projectId:l,projectFolder:u}=Xt(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=F(c.projectsManager.hasMultipleProjects()?u:c.workspace,`likec4-model.ts`);if(r&&(f=Xe(r)?r:F(r),I(r)&&(await Ye(r)).isDirectory()))throw Error(`output file is a directory: ${r}`);let p=A(f);o.info(`${v.dim(`filename`)} ${p}`);let m=M(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=j(f);o.info(`${v.dim(`outdir`)} ${h}`),await D(h,{recursive:!0}),await k(f,se(d,{useCorePackage:n}),{encoding:`utf-8`}),s.stopAndLog(),W(oe(`
16
+ ${v.dim(`Source generated:`)}
17
+ ${P(L(),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 rn({languageServices:e,outDir:t,filename:n=`likec4-react.mjs`}){let r=H([`vite`,`react`]),i=yt();return r.info(`${v.cyan(`likec4 app root`)} ${v.dim(K(i))}`),r.info(v.cyan(`outDir`)+` `+v.dim(K(t))),{customLogger:r,root:i,configFile:!1,clearScreen:!1,publicDir:!1,mode:`production`,resolve:{conditions:[`production`],alias:St()},esbuild:{banner:`'use client'
22
+ `+_t.banner,footer:_t.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:xt,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:[lt({}),ge({languageServices:e.languageServices})]}}async function an({path:e,useDotBin:t,useCorePackage:n,outfile:r,project:i}){try{var a=Z();await q();let o=H(`c4:codegen`),s=U(o),c=a.a(await C(e,{graphviz:t?`binary`:`wasm`,watch:!1})),{projectId:l,projectFolder:u}=Xt(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=F(c.projectsManager.hasMultipleProjects()?u:c.workspace,`likec4-views.js`);if(r&&(f=Xe(r)?r:F(r),I(r)&&(await Ye(r)).isDirectory()))throw Error(`output file is a directory: ${r}`);let p=j(f);o.info(`${v.dim(`outdir`)} ${p}`);let m=A(f);o.info(`${v.dim(`filename`)} ${m}`);let h=M(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 z({...await rn({languageServices:c,outDir:p,filename:m}),logLevel:`warn`});let g=await c.layoutedModel(l),_=F(p,A(f,h)+(h===`.mjs`?`.d.mts`:`.d.ts`));await k(_,fe(g,{useCorePackage:n})),s.stopAndLog(),W(oe(`
23
+ ${v.dim(`Sources generated:`)}
24
+ ${P(L(),f)}
25
+ ${P(L(),_)}
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 on({project:e,path:t,useDotBin:n,webcomponentPrefix:r=`likec4`,outfile:i}){try{var o=Z();await q();let s=H(`c4:codegen`),c=U(s),l=o.a(await C(t,{graphviz:n?`binary`:`wasm`,watch:!1})),{projectId:u,projectFolder:d}=Xt(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=F(l.projectsManager.hasMultipleProjects()?d:l.workspace,`likec4-views.js`);if(i&&(p=Xe(i)?i:F(i),I(i)&&(await Ye(i)).isDirectory()))throw Error(`output file is a directory: ${i}`);s.debug(`${v.dim(`outfilepath`)} ${p}`);let m=A(p);s.debug(`${v.dim(`filename`)} ${m}`);let h=M(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 bt();s.debug(`${v.dim(`created temp public`)} ${g}`);let _=await wt({languageServices:l,outDir:g,filename:m,webcomponentPrefix:r,base:`/`});s.debug(`${v.dim(`vite build webcomponent`)}`),await z({..._,logLevel:`warn`});let y=F(g,m);if(!I(y))throw Error(`output file not found: ${y}`);await D(j(p),{recursive:!0}),await We(y,p),s.info(`${v.dim(`generated`)} ${p}`),s.debug(`${v.dim(`remove temp public`)}`),await Je(g,{recursive:!0,force:!0}),c.stopAndLog(),W(oe(`
30
+ ${v.dim(`Webcomponents generated to:`)}
31
+ ${P(L(),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 sn=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`,`output`],type:`string`,desc:`<file> path to output file (.jsx, .mjs or .js)`,normalize:!0,coerce:E}).option(`use-dot`,Y).option(`use-core-package`,kt),async e=>{await an({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`,`output`],type:`string`,desc:`<file> path to output file (.mjs or .js)`,normalize:!0,coerce:E}).option(`webcomponent-prefix`,Mt).option(`use-dot`,Y),handler:async e=>{await on({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`,`output`],type:`string`,desc:`<file> path to output file (.ts)`,normalize:!0,coerce:E}).option(`use-dot`,Y).option(`use-core-package`,kt),handler:async e=>{await nn({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`,`output`],type:`string`,desc:`<file> output .ts file`,normalize:!0,coerce:E}).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`,jt).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`,jt).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`,jt).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`,jt).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 Zt({name:`custom`,path:e.path,project:e.project,useDotBin:e.useDotBin})}}).epilog(`${v.bold(`Examples:`)}
36
36
  likec4 gen react -o dist/likec4-views.mjs ./src/likec4
37
37
  likec4 gen model -o likec4-model.ts
38
38
  likec4 gen ts --outfile likec4-model.ts
@@ -40,52 +40,61 @@ import{s as e}from"../_chunks/rolldown-runtime.mjs";import"../_chunks/libs/birpc
40
40
  likec4 gen mmd --outdir assets/
41
41
  likec4 gen plantuml --outdir assets/
42
42
  likec4 gen dot -o out .
43
- `),handler:async e=>{await Gt({name:e.command,path:e.path,project:e.project,useDotBin:e.useDotBin})}}),tn=new Set([`node_modules`,`.git`]);function nn(e){return e.endsWith(`.c4`)||e.endsWith(`.likec4`)}function rn(e,t=`
44
-
45
- `){return e.filter(e=>e.trim()!==``).join(t)}const an=`No project or empty model`,on=`No views could be exported`;function sn(){return`${_.bold(`Examples:`)}
46
- ${_.green(`$0 export drawio`)}
47
- ${_.gray(`Export each view to a separate .drawio file`)}
48
-
49
- ${_.green(`$0 export drawio --all-in-one -o ./diagrams src/`)}
50
- ${_.gray(`Export all views as tabs in one .drawio file`)}
51
-
52
- ${_.green(`$0 export drawio --roundtrip -o ./out`)}
53
- ${_.gray(`Re-apply layout/waypoints from comment blocks (e.g. after import from DrawIO)`)}
54
-
55
- ${_.green(`$0 export drawio --uncompressed -o ./out`)}
56
- ${_.gray(`Export with raw XML (no compression) for draw.io desktop compatibility`)}`}function cn(e){return e instanceof Error?e:Error(g(e))}function ln(e,t,n){let r=cn(n);throw e.error(t,{error:r}),r}async function un(e,t){let n=[],r=new Set;async function i(e,a){if(a>=50)return;let o=await Re(e).catch(()=>null);if(o==null||r.has(o))return;r.add(o);let s=await Le(e,{withFileTypes:!0}).catch(n=>(t?.debug&&t.debug(`${_.dim(`Roundtrip:`)} readdir failed`,{dir:e,err:n}),[]));for(let r of s){let o=M(e,r.name);switch(!0){case r.isDirectory():tn.has(r.name)||await i(o,a+1);break;case r.isSymbolicLink():if((await Be(o).catch(()=>null))?.isFile()&&nn(r.name)){let e=await Ie(o,`utf-8`).catch(e=>(t?.debug&&t.debug(`${_.dim(`Roundtrip:`)} readFile failed`,{file:o,err:e}),``));e&&n.push(e)}break;case r.isFile()&&nn(r.name):{let e=await Ie(o,`utf-8`).catch(e=>(t?.debug&&t.debug(`${_.dim(`Roundtrip:`)} readFile failed`,{file:o,err:e}),``));e&&n.push(e);break}}}}return await i(e,0),rn(n)}async function dn(e,t,n){if(t)return un(P(e),n)}function fn(e,t,n){return me(e.map(e=>String(e.$view.id)),t,n?{compressed:!1}:void 0)}async function pn(e){let{viewmodels:t,outdir:n,workspacePath:r,roundtrip:i,uncompressed:a,logger:o}=e,s=ue(t,fn(t,await dn(r,i,o),a)),c=P(n,ge);await k(c,s),o.info(`${_.dim(`generated`)} ${N(process.cwd(),c)} (${t.length} tab(s))`)}async function mn(e,t,n,r){let i=String(e.$view.id);try{let a=se(e,t[i]),o=P(n,i+`.drawio`);return await D(A(o),{recursive:!0}),await k(o,a),r.info(`${_.dim(`generated`)} ${N(process.cwd(),o)}`),!0}catch(e){return r.error(`Failed to export view ${i}`,{error:cn(e)}),!1}}async function hn(e){let{viewmodels:t,outdir:n,workspacePath:r,roundtrip:i,uncompressed:a,logger:o}=e,s=fn(t,await dn(r,i,o),a),c=0;for(let e of t)await mn(e,s,n,o)&&c++;return{succeeded:c}}async function gn(e,t){try{var n=Z();let r=H(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===_e.EMPTY)throw t.error(an),Error(an);let s=[...o.views()];if(s.length===0)throw t.error(`No views to export`),Error(on);await D(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 pn(c)}catch(e){ln(t,`Failed to export DrawIO`,e)}else{let{succeeded:e}=await hn(c);if(e===0)throw t.error(on),Error(on);t.info(`${_.dim(`total`)} ${e} DrawIO file(s)`)}r.stopAndLog(`✓ export drawio in `)}catch(e){n.e=e}finally{await n.d()}}function _n(e){return e.command({command:`drawio [path]`,describe:`export view(s) to DrawIO (.drawio) for editing in draw.io`,builder:e=>e.positional(`path`,q).option(`outdir`,{alias:`o`,type:`string`,desc:`<dir> output directory for .drawio files`,normalize:!0,coerce:P}).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":J}).epilog(sn()),handler:async e=>{let t=V(`c4:export`);await gn({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 vn=`project not found`,yn=`No projects found`;async function bn(e,t){try{var n=Z();let r=H(t),a=n.a(await ye.fromWorkspace(e.path,{logger:t,graphviz:e.useDot?`binary`:`wasm`,watch:!1})),o=[...a.projectsManager.all];if(e.project){if(o=o.filter(t=>t===e.project),!i(o,1))throw t.error(`${vn}: ${e.project}`),Error(`${vn}: ${e.project}`)}else{if(!i(o,1))throw t.error(yn),Error(yn);t.info(`${_.dim(`workspace:`)} Found ${o.length} projects`)}let s=[];for(let n of o){let r;if(e.skipLayout?(t.info(`Generate model for project ${_.green(n)} ${_.dim(`(skip layout)`)}`),r=await a.computedModel(n)):(t.info(`Generating layouted model for project ${_.green(n)}`),r=await a.layoutedModel(n)),r===_e.EMPTY){t.warn(_.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;j(c).toLowerCase()!==`.json`&&(c+=`.json`),await D(A(c),{recursive:!0});let l=s.length===1?s[0]:s,u=e.pretty?JSON.stringify(l,void 0,2):JSON.stringify(l);await k(c,u);let d=c.startsWith(e.path)?N(e.path,c):c;t.info(`${_.dim(`generated`)} ${d}`),r.stopAndLog(`✓ export in `)}catch(e){n.e=e}finally{await n.d()}}function xn(e){return e.command({command:`json [path]`,describe:`export model(s) to JSON`,builder:e=>e.positional(`path`,q).option(`outfile`,{alias:`o`,type:`string`,desc:`<file> output .json file`,default:`likec4.json`,normalize:!0,coerce:P}).options({project:X,"use-dot":J,"skip-layout":{type:`boolean`,desc:`skip layouting (only compute model)`},pretty:{type:`boolean`,desc:`indented JSON output`}}).epilog(`${_.bold(`Examples:`)}
57
- ${_.green(`$0 export json --skip-layout`)}
58
- ${_.gray(`Search for likec4 files in current directory and output JSON to likec4.json (no layout)`)}
59
-
60
- ${_.green(`$0 export json --pretty -o ./generated/likec4.json src/likec4 `)}
61
- ${_.gray(`Search for likec4 files in src/likec4 and output JSON to generated/likec4.json`)}
62
- `),handler:async e=>{let t=V(`c4:export`);await bn({path:e.path,outfile:e.outfile,project:e.project,skipLayout:!!e.skipLayout,pretty:!!e.pretty,useDot:!!e[`use-dot`]},t)}})}var Sn=e(x(),1);function Cn(e){if(e.resolvedUrls)return s(e.resolvedUrls.network)??s(e.resolvedUrls.local)}function wn(e){if(!e.resolvedUrls)throw Error(`Vite server is not ready, no resolvedUrls`);U([_.green(`LikeC4 served at:`),``,_.dim(`Local: `)+e.resolvedUrls.local.join(`
63
- `+``.padEnd(9,` `)),e.resolvedUrls.network.length?_.dim(`Network: `)+e.resolvedUrls.network.join(`
64
- `+``.padEnd(9,` `)):void 0].filter(e=>t(e)).join(`
65
- `))}async function Tn({buildWebcomponent:e=!0,hmr:t=!0,webcomponentPrefix:n=`likec4`,title:r,languageServices:i,likec4AssetsDir:a,openBrowser:o,listen:s,port:c,...l}){a??=await O(M(Ye(),`.likec4-assets-`));let{isDev:u,...d}=await St({...l,languageServices:i,likec4AssetsDir:a,webcomponentPrefix:n,title:r}),f=d.customLogger;c??=et.PORT?parseInt(et.PORT,10):void 0,c||=await Ee({port:[5173,5174,...E(61e3,61010),...E(62002,62010)]});let p=24678,m=await yt(),h=s??(w()?`0.0.0.0`:`localhost`);t?(p=await Ee({port:E(24678,24690)}),f.info(`Enabling HMR: localhost:${p}`),w()&&f.info(_.yellow(`ensure port ${p} is published from container`))):f.info(`Disabling HMR`);let v=await ut({...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=>R({...e,logLevel:`warn`})).catch(e=>{f.warn(g(e)),f.warn(`webcomponent build failed, ignoring error and continue`)})):f.info(`Skip webcomponent build`),await v.listen(),v}async function En({browserContext:e,views:t,output:n,logger:r,timeout:i,maxAttempts:s,dynamicVariant:c,outputType:l,theme:u}){let d,f=t.map(e=>({view:e,attempt:1})),p=[],m;for(;m=f.shift();){let{view:t,attempt:h}=m,g=`export/${encodeURIComponent(t.id)}/`;try{if(h>1){d&&=(d.close({runBeforeUnload:!0}).catch(e=>r.error(`failed to close page: ${e}`)),void 0);let e=a(h*200,{min:200,max:1e3});r.info(_.cyan(g)+_.dim(` attempt ${h} of ${s} after ${e}ms`)),await ft(e)}else t.hasLayoutDrift&&r.warn(_.yellow(`Drift detected, manual layout can not be applied, view may be invalid: `)+_.red(t.id));let f=`.`;l===`relative`&&(f=t.sourcePath??`.`,f=f.includes(`/`)?f.slice(0,f.lastIndexOf(`/`)):`.`);let m=P(n,f,`${t.id}.png`);d??=await e.newPage();let v=t.bounds;c===`sequence`&&t._type===`dynamic`&&(v=t.sequenceLayout.bounds),await d.setViewportSize({width:v.width+40+20,height:v.height+40+20}),await d.goto(S(g,{padding:20,theme:u,dynamic:c})),r.info(_.cyan(g)+_.dim(` -> ${N(n,m)}`)),await d.waitForSelector(`.react-flow.initialized`),t.nodes.some(e=>o(e.icon)&&e.icon.toLowerCase().startsWith(`http`))&&await Dn(d,i),await d.getByTestId(`export-page`).screenshot({animations:`disabled`,path:m,omitBackground:!0}),p.push({view:t,path:m})}catch(e){d?.close({runBeforeUnload:!0}).catch(e=>r.error(`failed to close page: ${e}`)),r.error(_.red(`failed `+g+`
66
- `+e)),h<s&&(f.push({view:t,attempt:h+1}),r.info(_.dim(`retry ${g}`))),d=void 0}}return p}async function Dn(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 On({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(`${_.dim(`output`)} ${a}`),e.info(`${_.dim(`base url`)} ${t}\n`);let{chromium:u}=await import(`playwright`),d=u.executablePath();e.info(_.cyan(`Start chromium`)+` `+_.dim(d));let f=await u.launch({chromiumSandbox:c,headless:!0});e.info(_.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 En({browserContext:p,views:i,output:a,outputType:o,logger:e,maxAttempts:s,dynamicVariant:l?`sequence`:`diagram`,timeout:r,theme:n})}finally{e.info(_.cyan(`close chromium`)),await p.close(),await f.close()}}async function kn(e,t){try{var n=Z();let{path:r,useDotBin:a,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,v=n.a(await ye.fromWorkspace(r,{logger:`vite`,graphviz:a?`binary`:`wasm`,watch:!1})),y=c??v.workspace,b,x=u,S=[...v.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(_.cyan(`start preview server`)),b=await Tn({languageServices:v,buildWebcomponent:!1,openBrowser:!1,hmr:!1}),x=Cn(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(_.dim(`---------`)),t.info(`${_.dim(`project:`)} ${e.id}`),t.info(`${_.dim(`folder:`)} ${e.folder.fsPath}`));let n=await v.diagrams(e.id);if(m&&i(m,1)&&i(n,1)){let e=(0,Sn.default)(m);t.info(`${_.cyan(`filter`)} ${_.dim(JSON.stringify(m))}`),n=n.filter(n=>e(n.id)?(t.info(`${_.green(`include`)} ${n.id} ✅`),!0):(t.info(`${_.gray(`skip`)} ${_.dim(n.id)}`),!1))}if(!i(n,1)){t.warn(`no views found`);continue}let r=S.length>1?ee(te(x,`project`,e.id)):x,a=S.length>1?te(y,e.id):y,c=Qe(),u=await On({logger:t,serverUrl:r,theme:s,timeoutMs:f,views:n,output:a,outputType:l,maxAttempts:p,sequence:h,chromiumSandbox:g}),{pretty:b}=mt(c);if(u.length>0&&t.info(_.green(`exported ${u.length} views in ${b}`)+`
68
- `),u.length!==n.length&&(d&&u.length>0?t.info(_.dim(`ignore`)+` `+_.red(`failed ${n.length-u.length} out of ${n.length} views`)):t.error(_.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(_.cyan(`stop server`)),await b.close().catch(e=>{t.error(e)}))}}catch(e){n.e=e}finally{await n.d()}}async function An(e){await kn(e,V(`c4:export`))}function jn(e){return e.command({command:`png [path]`,describe:`export views to PNG`,builder:e=>e.positional(`path`,q).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:P},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":J,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(`${_.bold(`Examples:`)}
70
- ${_.green(`$0 export png`)}
71
- ${_.gray(`Search for likec4 files in current directory and output PNG next to sources`)}
72
-
73
- ${_.green(`$0 export png --theme dark -o ./png src/likec4`)}
74
- ${_.gray(`Search for likec4 files in src/likec4 and output PNG with dark theme to png folder`)}
75
-
76
- ${_.green(`$0 export png -f "team1*" -f "team2*" --flat -o ./png src/likec4`)}
77
- ${_.gray(`Export views matching team1* or team2* only`)}
78
-
79
- ${_.green(`$0 export png -f "use-case*" --sequence src/likec4`)}
80
- ${_.gray(`Export views matching use-case* using sequence layout`)}
81
- `),handler:async e=>{Ne(e.timeout>=1,`timeout must be >= 1`),Ne(e[`max-attempts`]>=1,`max-attempts must be >= 1`),await K();let t=e.theme??(e.dark?`dark`:`light`);await An({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 Mn=e=>e.command({command:`export <format> [path]`,describe:`Export to images, JSON, or DrawIO`,builder:e=>c(e.usage(`${_.bold(`Usage:`)} $0 export <format> [path]`),jn,xn,_n).updateStrings({"Commands:":_.bold(`Formats:`)}),handler:()=>void 0}),Nn=e=>e.command({command:`mcp [path]`,aliases:[],describe:`Start MCP server`,builder:e=>e.usage(`${_.bold(`Usage:`)} $0 mcp [path]`).positional(`path`,q).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`,J).epilog(`${_.bold(`Examples:`)}
82
- ${_.green(`$0 mcp`)}
83
- ${_.gray(`Start MCP with default stdio transport`)}
84
- ${_.green(`$0 mcp --http ./src`)}
85
- ${_.gray(`Start MCP with streamable http transport on port 33335 at ./src folder`)}
86
- ${_.green(`$0 mcp -p 1234`)}
87
- ${_.gray(`Start MCP with streamable http transport on port 1234`)}
88
- `),handler:async e=>{e.http||e.port?await Pn(e.path,e.useDot,e.port):await Fn(e.path,e.useDot)}});async function Pn(e,t,n=33335){await T(e,{mcp:{port:n},watch:!0,graphviz:t?`binary`:`wasm`}),U([_.green(`LikeC4 MCP served at:`),`
43
+ `),handler:async e=>{await Zt({name:e.command,path:e.path,project:e.project,useDotBin:e.useDotBin})}}),cn=new Set([`node_modules`,`.git`]);function ln(e){return e.endsWith(`.c4`)||e.endsWith(`.likec4`)}function un(e,t=`
44
+
45
+ `){return e.filter(e=>e.trim()!==``).join(t)}const dn=`No project or empty model`,fn=`No views could be exported`;function pn(){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 mn(e){return e instanceof Error?e:Error(g(e))}function hn(e,t,n){let r=mn(n);throw e.error(t,{error:r}),r}async function gn(e,t){let n=[],r=new Set;async function i(e,a){if(a>=50)return;let o=await qe(e).catch(()=>null);if(o==null||r.has(o))return;r.add(o);let s=await Ke(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=N(e,r.name);switch(!0){case r.isDirectory():cn.has(r.name)||await i(o,a+1);break;case r.isSymbolicLink():if((await Ye(o).catch(()=>null))?.isFile()&&ln(r.name)){let e=await Ge(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()&&ln(r.name):{let e=await Ge(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),un(n)}async function _n(e,t,n){if(t)return gn(F(e),n)}function vn(e,t,n){return he(e.map(e=>String(e.$view.id)),t,n?{compressed:!1}:void 0)}async function yn(e){let{viewmodels:t,outdir:n,workspacePath:r,roundtrip:i,uncompressed:a,logger:o}=e,s=de(t,vn(t,await _n(r,i,o),a)),c=F(n,_e);await k(c,s),o.info(`${v.dim(`generated`)} ${P(process.cwd(),c)} (${t.length} tab(s))`)}async function bn(e,t,n,r){let i=String(e.$view.id);try{let a=ce(e,t[i]),o=F(n,i+`.drawio`);return await D(j(o),{recursive:!0}),await k(o,a),r.info(`${v.dim(`generated`)} ${P(process.cwd(),o)}`),!0}catch(e){return r.error(`Failed to export view ${i}`,{error:mn(e)}),!1}}async function xn(e){let{viewmodels:t,outdir:n,workspacePath:r,roundtrip:i,uncompressed:a,logger:o}=e,s=vn(t,await _n(r,i,o),a),c=0;for(let e of t)await bn(e,s,n,o)&&c++;return{succeeded:c}}async function Sn(e,t){try{var n=Z();let r=U(t),i=n.a(await be(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(dn),Error(dn);let s=[...o.views()];if(s.length===0)throw t.error(`No views to export`),Error(fn);await D(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 yn(c)}catch(e){hn(t,`Failed to export DrawIO`,e)}else{let{succeeded:e}=await xn(c);if(e===0)throw t.error(fn),Error(fn);t.info(`${v.dim(`total`)} ${e} DrawIO file(s)`)}r.stopAndLog(`✓ export drawio in `)}catch(e){n.e=e}finally{await n.d()}}function Cn(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:F}).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(pn()),handler:async e=>{let t=H(`c4:export`);await Sn({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 wn=`project not found`,Tn=`No projects found`;async function En(e,t){try{var n=Z();let r=U(t),i=n.a(await xe.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(`${wn}: ${e.project}`),Error(`${wn}: ${e.project}`)}else{if(!a(o,1))throw t.error(Tn),Error(Tn);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;M(c).toLowerCase()!==`.json`&&(c+=`.json`),await D(j(c),{recursive:!0});let l=s.length===1?s[0]:s,u=e.pretty?JSON.stringify(l,void 0,2):JSON.stringify(l);await k(c,u);let d=c.startsWith(e.path)?P(e.path,c):c;t.info(`${v.dim(`generated`)} ${d}`),r.stopAndLog(`✓ export in `)}catch(e){n.e=e}finally{await n.d()}}function Dn(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:F}).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=H(`c4:export`);await En({path:e.path,outfile:e.outfile,project:e.project,skipLayout:!!e.skipLayout,pretty:!!e.pretty,useDot:!!e[`use-dot`]},t)}})}var On=e(S(),1);function kn(e){if(e.resolvedUrls)return i(e.resolvedUrls.network)??i(e.resolvedUrls.local)}function An(e){if(!e.resolvedUrls)throw Error(`Vite server is not ready, no resolvedUrls`);W([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 jn({buildWebcomponent:e=!0,hmr:t=!0,webcomponentPrefix:n=`likec4`,title:r,languageServices:i,likec4AssetsDir:a,openBrowser:o,listen:s,port:c,...l}){a??=await O(N(T(),`.likec4-assets-`));let{isDev:u,...d}=await Ct({...l,languageServices:i,likec4AssetsDir:a,webcomponentPrefix:n,title:r}),f=d.customLogger;c??=Ve.PORT?parseInt(Ve.PORT,10):void 0,c||=await Ae({port:[5173,5174,...ke(61e3,61010),...ke(62002,62010)]});let p=24678,m=await bt(),h=s??(w()?`0.0.0.0`:`localhost`);t?(p=await Ae({port:ke(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 dt({...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`),wt({webcomponentPrefix:n,languageServices:i,outDir:m,base:d.base}).then(e=>z({...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 Mn({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 pt(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=F(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(` -> ${P(i,m)}`)),await d.waitForSelector(`.react-flow.initialized`),r.nodes.some(e=>n(e.icon)&&e.icon.toLowerCase().startsWith(`http`))&&await Nn(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 Nn(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 Pn({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 Mn({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 Fn(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 xe.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 jn({languageServices:_,buildWebcomponent:!1,openBrowser:!1,hmr:!1}),x=kn(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,On.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=it(),u=await Pn({logger:t,serverUrl:r,theme:s,timeoutMs:f,views:n,output:i,outputType:l,maxAttempts:p,sequence:h,chromiumSandbox:g}),{pretty:b}=ht(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 In(e){await Fn(e,H(`c4:export`))}function Ln(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:F},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=>{Re(e.timeout>=1,`timeout must be >= 1`),Re(e[`max-attempts`]>=1,`max-attempts must be >= 1`),await q(),await Ot();let t=e.theme??(e.dark?`dark`:`light`);await In({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 Rn=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]`),Ln,Dn,Cn).updateStrings({"Commands:":v.bold(`Formats:`)}),handler:()=>void 0}),zn=e=>e.command({command:`format [path]`,aliases:[`fmt`],describe:`Format LikeC4 source files`,builder:e=>e.positional(`path`,J).options({project:{alias:`p`,type:`string`,array:!0,desc:`select project(s) to format (repeatable)`},files:{type:`string`,array:!0,normalize:!0,coerce:e=>e.map(e=>F(e)),desc:`specific file(s) to format (repeatable)`},check:{type:`boolean`,desc:`Check if files are formatted (exit with 1 if not)`,default:!1}}),handler:async e=>{try{var t=Z();let n=H(`c4:format`),r=U(n),i=e.check,a;try{a=await C(e.path,{watch:!1})}catch(e){n.error(e instanceof Error?e.message:String(e)),process.exitCode=1;return}t.a(a);let o=e.project?.filter(Boolean),s=e.files?.filter(Boolean).map(e=>ct(e).toString());if(n.debug(`workspace: ${e.path}`),o?.length){n.debug(`projects:`);for(let e of o)n.debug(` ${e}`)}if(s?.length){n.debug(`files:`);for(let e of s)n.debug(` ${R(e)}`)}let c;try{c=await a.format({...o?.length&&{projects:o},...s?.length&&{documentUris:s}})}catch(e){n.error(e instanceof Error?e.message:String(e)),process.exitCode=1;return}n.debug(`${c.size} document(s) to process`);let l=process.cwd(),u=e=>{let t=P(l,e);return t.startsWith(`..`)?e:t};if(s){let e=s.filter(e=>!c.has(e));for(let t of e)n.warn(`${v.yellow(`skipped`)} ${u(R(t))} (not found in workspace)`)}let d=0,f=0,p=[];for(let[e,t]of c){let r=R(e),a=u(r),o;try{o=await Ge(r,`utf-8`)}catch(e){n.error(`Failed to read ${a}: ${e}`),f++;continue}if(o===t){n.debug(`${v.dim(`unchanged`)} ${a}`);continue}if(d++,p.push(a),i)n.info(`${v.yellow(`needs formatting`)} ${a}`);else try{await k(r,t,`utf-8`),n.info(`${v.green(`formatted`)} ${a}`)}catch(e){n.error(`Failed to write ${a}: ${e}`),f++}}if(f>0){n.error(`${f} file(s) failed to process`),process.exitCode=1;return}if(i){if(d>0){n.error(`${d} of ${c.size} file(s) need formatting:\n${p.map(e=>` ${e}`).join(`
82
+ `)}`),process.exitCode=1;return}n.info(v.green(`All ${c.size} file(s) are formatted`))}else d>0?n.info(`${v.green(String(d))} of ${c.size} file(s) formatted`):n.info(v.green(`All ${c.size} file(s) already formatted`));r.stopAndLog(`✓ format in `)}catch(e){t.e=e}finally{await t.d()}}});var Bn=je();function Vn(e){return e.command({command:`lsp`,aliases:[],describe:`Start LSP server`,builder:e=>e.usage(`${v.bold(`Usage:`)} $0 lsp`).option(`log-level`,Rt).option(`verbose`,zt).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:`)}
83
+
84
+ ${v.green(`$0 lsp --stdio `)}
85
+ ${v.gray(`Start LSP with stdio transport`)}
86
+
87
+ ${v.green(`$0 lsp --node-ipc --watch --no-manual-layouts --no-color `)}
88
+ ${v.gray(`Start LSP with node-ipc transport and watcher, disabled manual layouts and disabled color`)}
89
+
90
+ `),handler:e=>{let t;if(e.nodeIpc||e.stdio||e.socket||e.pipe)t=(0,Bn.createConnection)(Bn.ProposedFeatures.all);else throw Error(`No transport specified`);m({lspConnection:t,useStdErr:e.stdio===!0,colors:v.isColorSupported,enableTelemetry:e.telemetry,logLevel:e.verbose?Bt:e.logLevel}),p({connection:t,enableManualLayouts:e.manualLayouts,enableWatcher:e.watch,graphviz:e.useDot?`binary`:`wasm`,configureLogger:!1})}})}const Hn=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`,Rt).option(`verbose`,zt).showHidden().epilog(`${v.bold(`Examples:`)}
91
+ ${v.green(`$0 mcp`)}
92
+ ${v.gray(`Start MCP with default stdio transport`)}
93
+ ${v.green(`$0 mcp --http ./src`)}
94
+ ${v.gray(`Start MCP with streamable http transport on port 33335 at ./src folder`)}
95
+ ${v.green(`$0 mcp -p 1234`)}
96
+ ${v.gray(`Start MCP with streamable http transport on port 1234`)}
97
+ `),handler:async e=>{e.http||e.port?(m({colors:v.isColorSupported,logLevel:e.verbose?Bt:e.logLevel}),await Un(e.path,e.useDot,e.port)):(m({useStdErr:!0,logLevel:e.verbose?Bt:e.logLevel}),await Wn(e.path,e.useDot))}});async function Un(e,t,n=33335){await be(e,{mcp:{port:n},watch:!0,configureLogger:!1,graphviz:t?`binary`:`wasm`}),W([v.green(`LikeC4 MCP served at:`),`
89
98
  {
90
99
  "mcpServers": {
91
100
  "likec4": {
@@ -94,8 +103,9 @@ ${_.green(`$0 mcp -p 1234`)}
94
103
  }
95
104
  }
96
105
 
97
- ${_.dim(`Documentation:`)}
98
- ${_.underline(`https://likec4.dev/tooling/mcp/#using-extension`)}
106
+ ${v.dim(`Documentation:`)}
107
+ ${v.underline(`https://likec4.dev/tooling/mcp/#using-extension`)}
99
108
  `].join(`
100
- `))}async function Fn(e,t){await T(e,{mcp:`stdio`,watch:!0,graphviz:t?`binary`:`wasm`})}async function In(e){let t=await St({...e,likec4AssetsDir:``,webcomponentPrefix:void 0}),n=await Ee({port:E(62001,62010)}),r=e?.open??!1;return await dt({...t,customLogger:t.customLogger,mode:`production`,preview:{host:e.listen??`127.0.0.1`,allowedHosts:!0,port:n,open:r}})}async function Ln({path:e,output:t,base:n,listen:r}){wn(await In({base:n,languageServices:await C(e,{watch:!1}),outputDir:t,open:!w(),listen:r}))}const Rn=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
101
- 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`],I).default(`path`,I(`.`),`.`).default(`listen`,`127.0.0.1`,`localhost`),handler:async e=>{await Ln(e)}});async function zn({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 Tn({buildWebcomponent:a,hmr:o,base:s,webcomponentPrefix:n,title:r,languageServices:await C(e,{graphviz:t?`binary`:`wasm`,watch:o}),useHashHistory:i,likec4AssetsDir:await O(M(Ye(),`.likec4-assets-`)),listen:c,port:l});u.config.logger.clearScreen(`info`),wn(u)}const Bn=e=>e.command({command:`start [path]`,aliases:[`serve`,`dev`],describe:`Start local dev server to preview LikeC4 views`,builder:e=>e.positional(`path`,q).option(`base`,jt).option(`webcomponent-prefix`,kt).option(`title`,At).option(`use-hash-history`,Ot).option(`use-dot`,J).option(`listen`,Nt).option(`port`,Pt).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 K(),await zn({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 Vn(e){return e.getErrors().length===0}async function Hn(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(_.red(`Layout drift detected on view '${t.id}' at ${P(e,t.sourcePath??`.`)}`)));return!i}const Un=e=>e.command({command:`validate [path]`,aliases:[],describe:`Validate model syntax and manual layout`,builder:e=>e.positional(`path`,q).option(`ignore-layout`,{alias:[`skip-layout`],boolean:!0,default:!1,description:`do not validate layout of views`}),handler:async e=>{let t=V(`c4:validate`),n=e[`ignore-layout`],r=await C(e.path,{watch:!1}),i=Vn(r);i&&=n||await Hn(e.path,r,t)}});function Wn(e=tt){m({sinks:{console:f({formatter:_.isColorSupported?d():h()})},loggers:[{category:`likec4`,sinks:[`console`],lowestLevel:e?`debug`:`info`}]})}async function Gn(){!ve&&!w()&&zt(),await c(it(at(Xe)),Bn,Ft,en,Mn,Rn,Un,Nn,Ht,e=>e.command({command:`completion`,describe:`Generate completion script`,handler:()=>{e.showCompletionScript()}})).scriptName(`likec4`).usage(`Usage: $0 <command>`).version(z).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:":_.bold(`Options:`),"Positionals:":_.bold(`Arguments:`),"Commands:":_.bold(`Commands:`),"Examples:":_.bold(`Examples:`)}).wrap(a($e.columns-10,{min:80,max:150})).middleware(e=>{Wn(e.verbose||tt)}).parseAsync()}function Kn(e,t){console.error(t==null?g(e):`${t} ${g(e)}`),Ze(1)}Gn().catch(Kn),process.on(`unhandledRejection`,e=>{Kn(e,`Unhandled rejection:`)});export{};
109
+ `))}async function Wn(e,t){await be(e,{mcp:`stdio`,watch:!0,configureLogger:!1,graphviz:t?`binary`:`wasm`})}async function Gn(e){let t=await Ct({...e,likec4AssetsDir:``,webcomponentPrefix:void 0}),n=await Ae({port:ke(62001,62010)}),r=e?.open??!1;return await ft({...t,customLogger:t.customLogger,mode:`production`,preview:{host:e.listen??`127.0.0.1`,allowedHosts:!0,port:n,open:r}})}async function Kn({path:e,output:t,base:n,listen:r}){An(await Gn({base:n,languageServices:await C(e,{watch:!1}),outputDir:t,open:!w(),listen:r}))}const qn=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
110
+ 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`],E).default(`path`,E(`.`),`.`).default(`listen`,`127.0.0.1`,`localhost`),handler:async e=>{await Kn(e)}});async function Jn({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 jn({buildWebcomponent:a,hmr:o,base:s,webcomponentPrefix:n,title:r,languageServices:await C(e,{graphviz:t?`binary`:`wasm`,watch:o}),useHashHistory:i,likec4AssetsDir:await O(N(T(),`.likec4-assets-`)),listen:c,port:l});u.config.logger.clearScreen(`info`),An(u)}const Yn=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`,Pt).option(`webcomponent-prefix`,Mt).option(`title`,Nt).option(`use-hash-history`,At).option(`use-dot`,Y).option(`listen`,It).option(`port`,Lt).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 Jn({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 Xn(e){return e.getErrors().length===0}async function Zn(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 ${F(e,t.sourcePath??`.`)}`)));return!i}const Qn=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=H(`c4:validate`),n=e[`ignore-layout`],r=await C(e.path,{watch:!1}),i=Xn(r);i&&=n||await Zn(e.path,r,t)}});function $n(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 er(){!ye&&!w()&&await Gt(),await o(ot(st(nt)),Yn,Vt,sn,Rn,zn,qn,Qn,Hn,Vn,Jt,e=>e.command({command:`completion`,describe:`Generate completion script`,handler:()=>{e.showCompletionScript()}})).scriptName(`likec4`).usage(`Usage: $0 <command>`).version(B).alias(`v`,`version`).alias(`h`,`help`).help(`help`).option(`log-level`,{...Rt,global:!1}).option(`verbose`,{...zt,global:!1}).option(`color`,{boolean:!0,describe:[`force color output, or disable with --no-color`,`respects 'FORCE_COLOR' and 'NO_COLOR' env variables`].join(`
111
+ `),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(at.columns-10,{min:60,max:180})).middleware(e=>{$n(e.verbose?Bt:e.logLevel)}).parseAsync()}function tr(e,t){console.error(t==null?g(e):`${t} ${g(e)}`),rt(1)}er().catch(tr),process.on(`unhandledRejection`,e=>{tr(e,`Unhandled rejection:`)}),process.on(`uncaughtException`,e=>{console.error(e)});export{};