likec4 1.52.0 → 1.53.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 (36) hide show
  1. package/__app__/src/likec4.js +34 -48
  2. package/__app__/src/routes/index.js +7 -0
  3. package/__app__/src/routes/single.js +30 -18
  4. package/__app__/src/style.css +1 -1
  5. package/__app__/src/vendors.js +2065 -2809
  6. package/config/schema.json +56 -0
  7. package/dist/THIRD-PARTY-LICENSES.md +10 -2
  8. package/dist/_chunks/filesystem.mjs +70 -68
  9. package/dist/_chunks/index.d.mts +10 -1
  10. package/dist/_chunks/index2.d.mts +76 -4
  11. package/dist/_chunks/libs/@hono/mcp.mjs +1 -1
  12. package/dist/_chunks/libs/@logtape/logtape.d.mts +1021 -0
  13. package/dist/_chunks/libs/@logtape/logtape.mjs +4 -6
  14. package/dist/_chunks/libs/@modelcontextprotocol/sdk.d.mts +1 -1
  15. package/dist/_chunks/libs/@nanostores/react.d.mts +5 -5
  16. package/dist/_chunks/libs/destr.mjs +1 -0
  17. package/dist/_chunks/libs/fast-equals.mjs +1 -1
  18. package/dist/_chunks/libs/langium.mjs +1 -1
  19. package/dist/_chunks/libs/remeda.mjs +2 -2
  20. package/dist/_chunks/libs/tinyrainbow.mjs +1 -1
  21. package/dist/_chunks/libs/unstorage.mjs +1 -0
  22. package/dist/_chunks/node.mjs +1 -0
  23. package/dist/_chunks/sequence.mjs +1 -1
  24. package/dist/_chunks/src.mjs +14 -12
  25. package/dist/_chunks/src2.mjs +46 -46
  26. package/dist/cli/index.mjs +164 -84
  27. package/dist/index.d.mts +16 -819
  28. package/dist/index.mjs +1 -1
  29. package/dist/vite-plugin/index.mjs +1 -1
  30. package/dist/vite-plugin/internal.mjs +1 -1
  31. package/package.json +34 -33
  32. package/react/index.d.mts +24 -20
  33. package/react/index.mjs +969 -1728
  34. package/vite-plugin-modules.d.ts +5 -0
  35. package/dist/_chunks/LikeC4.mjs +0 -1
  36. package/dist/_chunks/libs/boxen.d.mts +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{$ 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 */
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,m as c,t as l,w 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,b as f,g as p,n as m,u as h,v as g,x as _,y as v}from"../_chunks/filesystem.mjs";import"../_chunks/libs/defu.mjs";import"../_chunks/libs/pathe.mjs";import{t as y}from"../_chunks/libs/tinyrainbow.mjs";import"../_chunks/libs/json5.mjs";import"../_chunks/libs/@hono/mcp.mjs";import"../_chunks/src.mjs";import{H 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/parse-ms.mjs";import{t as S}from"../_chunks/libs/pretty-ms.mjs";import{t as ee}from"../_chunks/libs/picomatch.mjs";import{c as te,l as ne,o as re,r as ie,s as ae}from"../_chunks/libs/ufo.mjs";import"../_chunks/libs/@modelcontextprotocol/sdk.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"../_chunks/libs/destr.mjs";import"../_chunks/libs/unstorage.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 w}from"../model/index.mjs";import"../_chunks/libs/is-docker.mjs";import{t as T}from"../_chunks/libs/is-inside-container.mjs";import"../_chunks/libs/ansi-regex.mjs";import{t as ve}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 ye}from"../_chunks/libs/package-up.mjs";import{n as be,t as xe}from"../_chunks/libs/package-manager-detector.mjs";import{t as Se}from"../_chunks/libs/esm-env.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 Ee}from"../_chunks/node.mjs";import{n as De,t as Oe}from"../_chunks/libs/get-port.mjs";import{t as ke}from"../_chunks/libs/vscode-languageserver.mjs";import Ae from"node:module";import{isDeploymentElementModel as je,isDeploymentRelationModel as Me,isElementModel as Ne,isLikeC4ViewModel as Pe,isRelationModel as Fe}from"@likec4/core/model";import{invariant as Ie,nonexhaustive as Le}from"@likec4/core";import Re from"nano-spawn";import{tmpdir as ze}from"node:os";import{resolve as E}from"path";import{env as Be,isCI as Ve,isDevelopment as He,isProduction as Ue,isTest as We,nodeENV as Ge}from"std-env";import{copyFile as Ke,mkdir as D,mkdtemp as qe,readFile as O,readdir as Je,realpath as Ye,rm as Xe,stat as Ze,writeFile as k}from"node:fs/promises";import{basename as Qe,dirname as A,extname as j,isAbsolute as $e,join as M,relative as N,resolve as P,sep as et}from"node:path";import{copyFileSync as tt,existsSync as F,readFileSync as nt,readdirSync as rt,rmSync as it,statSync as at}from"node:fs";import{argv as ot,cwd as I,exit as st,hrtime as ct,stdout as lt}from"node:process";import ut from"yargs";import{hideBin as dt}from"yargs/helpers";import{fileURLToPath as L,pathToFileURL as ft}from"node:url";import pt from"@vitejs/plugin-react";import{viteSingleFile as mt}from"vite-plugin-singlefile";import{build as R,createServer as ht,preview as gt}from"vite";import{setTimeout as _t}from"node:timers/promises";import{setTimeout as vt}from"node:timers";var yt=`likec4`,bt=`1.53.0`;const z=d.getChild(`cli`);function B(e){let t=d.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(`${y.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(`${y.red(r.name+` `+r.message)}`,{error:r});return}t.error(y.red(e),{error:r});return}if(typeof e==`string`){t.error(y.red(e));return}t.error`${e}`},clearScreen:function(e){},hasErrorLogged:function(e){return!1},hasWarned:!1}}function xt(e){let[t,n]=ct(e),r=t*1e3+n/1e6;return{ms:r,pretty:S(r)}}function V(e){let t=ct();return{stopAndLog(n=`done in `){n=y.green(`${n}${xt(t).pretty}`),(e||z).info(n)}}}function H(e,t){console.log(ve(e,{padding:1,margin:1,dimBorder:!0,...t}))}const St=B(`vite`),Ct=A(L(import.meta.url)),wt={banner:`/* prettier-ignore-start */
3
3
  /* eslint-disable */
4
4
 
5
5
  /******************************************************************************
@@ -10,91 +10,162 @@ 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 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:`)}
13
+ `};function Tt(){let e=ye({cwd:Ct});if(!e)throw Error(`likec4 package folder not found`);return A(e)}function Et(){let e=[P(Tt(),`__app__`),P(Ct,`../__app__`),P(Ct,`../../__app__`),P(Ct,`../../dist/__app__`)],t=r(e,F);if(!t)throw d.error(`likec4 app root does not exist, tried:\n${e.join(`
14
+ `)}`),Error(`likec4 app root does not exist`);return t}async function Dt(){let e=await qe(M(ze(),`.likec4-public-`));return await k(M(e,`likec4-views.js`),`// generated by likec4
15
+ `),e}function Ot(e){return N(I(),e)}const kt=1e4;function At(){let e=Tt();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 jt=async({languageServices:e,likec4AssetsDir:t,...n})=>{let r=n.customLogger??St,i=Et();r.info(`${y.cyan(`likec4 app root`)} ${y.dim(Ot(i))}`);let a=n.outputDir??P(e.workspace,`dist`);r.info(y.cyan(`outDir`)+` `+y.dim(Ot(a)));let o=`/`;n.base&&(o=ne(n.base),!ie(o)&&o!==`./`&&(o=ae(o))),o!==`/`&&r.info(`${y.green(`app base url`)} ${y.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:{...At(),"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:kt,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:[pt(),ge({languageServices:e.languageServices}),l?mt():void 0]}};async function Mt({languageServices:e,outDir:t,base:n,webcomponentPrefix:r=`likec4`,filename:i=`likec4-views.js`}){let a=B([`vite`,`webcomponent`]),o=Et();return a.info(y.cyan(`outDir`)+` `+y.dim(t)),{root:o,clearScreen:!1,base:n,configFile:!1,publicDir:!1,mode:`production`,resolve:{conditions:[`production`],alias:At(),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:{...wt,tsconfigRaw:{compilerOptions:{target:`ESNext`,jsx:`react-jsx`}}},build:{outDir:t,emptyOutDir:!1,sourcemap:!1,minify:!0,assetsInlineLimit:1024*1024,chunkSizeWarningLimit:kt,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:[pt(),ge({languageServices:e.languageServices})]}}const Nt=[`favicon.ico`,`robots.txt`];async function Pt({buildWebcomponent:e=!0,webcomponentPrefix:t=`likec4`,title:n,languageServices:r,likec4AssetsDir:i,outputSingleFile:a,...o}){i??=await qe(M(ze(),`.likec4-assets-`));let s=await jt({...o,languageServices:r,likec4AssetsDir:i,webcomponentPrefix:t,title:n,outputSingleFile:a}),c=!F(s.build.outDir)||rt(s.build.outDir).length===0,l=await Dt();for(let e of Nt){let t=P(s.root,e);F(t)&&tt(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(`${y.dim(`workspace:`)} ${y.green(`✓ all views layouted`)}`):s.customLogger.warn(`${y.dim(`workspace:`)} ${y.yellow(`✗ layouted ${t.length} of ${e.length} views`)}`),t.forEach(e=>{(e.hasLayoutDrift||e.drifts&&e.drifts.length>0)&&s.customLogger.warn(y.dim(`view`)+` `+y.red(e.id)+` `+y.yellow(`is out of date, layout drift detected`))});let n=u[0].config.landingPage;if(n&&(`include`in n||`exclude`in n)){let e=`include`in n?n.include:n.exclude;t.some(t=>e.some(e=>e.startsWith(`#`)?t.tags?.some(t=>t===e.slice(1)):t.id===e))||s.customLogger.warn(y.dim(`landingPage:`)+` `+y.yellow(`no views match the configured filter`))}}else for(let e of u){let t=await r.viewsService.computedViews(e.id);t.length===0?s.customLogger.warn(`${y.dim(`project:`)} ${e.id} ${y.yellow(`✗ no views found`)}`):s.customLogger.info(`${y.dim(`project:`)} ${e.id} ${y.green(`${t.length} views`)}`);let n=await r.diagrams(e.id),i=e.config.landingPage;if(i&&(`include`in i||`exclude`in i)){let t=`include`in i?i.include:i.exclude;n.some(e=>t.some(t=>t.startsWith(`#`)?e.tags?.some(e=>e===t.slice(1)):e.id===t))||s.customLogger.warn(`${y.dim(`project:`)} ${e.id} ${y.yellow(`landingPage: no views match the configured filter`)}`)}}if(e&&!a&&await R(await Mt({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(y.yellow(`outDir was not empty, skipping cleanup`));return}for(let e of rt(P(s.build.outDir)).filter(e=>e!==`index.html`))it(P(s.build.outDir,e),{recursive:!0})}let d=P(s.build.outDir,`index.html`);F(d)&&tt(d,P(s.build.outDir,`404.html`))}function Ft(e){try{return!!Ae.createRequire(import.meta.url).resolve(e)}catch(e){return z.debug(_(e)),!1}}async function U(){if(Ft(`react`)&&Ft(`react-dom`)){z.debug(`react already installed`);return}z.warn(`react not installed`);let e=await xe();e||(z.error`Package manager not detected, please install dependencies manually: ${`react`} ${`react-dom`}`,process.exit(1));let t=be(e.agent,`add`,[`react`,`react-dom`]);t||(z.error`Please install dependencies manually: ${`react`} ${`react-dom`}`,process.exit(1));try{await Re(t.command,t.args,{stdio:`inherit`})}catch(e){z.debug(_(e)),z.error`Please install dependencies manually: ${`react`} ${`react-dom`}`,process.exit(1)}}async function It(){if(Ft(`playwright`)){z.debug(`playwright already installed`);return}z.warn(`playwright not installed`);let e=await xe();e||(z.error`Package manager not detected, please install dependencies manually: ${`playwright`}`,process.exit(1));let t=be(e.agent,`add`,[`playwright`]);t||(z.error`Please install dependencies manually: ${`playwright`}`,process.exit(1));try{await Re(t.command,t.args,{preferLocal:!0,stdio:`inherit`})}catch(e){z.debug(_(e)),z.error`Please install dependencies manually: ${`playwright`}`,process.exit(1)}}const W={type:`string`,desc:`<directory> with LikeC4 sources (default is current directory or 'LIKEC4_WORKSPACE' env)`,normalize:!0,default:Be.LIKEC4_WORKSPACE||`.`,coerce:P},G={alias:`use-dot-bin`,boolean:!0,type:`boolean`,desc:T()?`enabled in container, disable by --no-use-dot`:`use graphviz binaries ("dot" should be on PATH)`,default:T()},Lt={boolean:!0,type:`boolean`,desc:"use `@likec4/core` package in types",default:!1},Rt={boolean:!0,type:`boolean`,desc:`use hash history for navigation, e.g. "/#/view" instead of "/view"`},K={alias:[`o`,`output`],string:!0,desc:`output directory`,normalize:!0,nargs:1,coerce:P},zt={alias:`w`,string:!0,desc:`prefix for Webcomponents, e.g "c4" generates <c4-view ../>`,default:`likec4`,nargs:1},Bt={alias:`t`,string:!0,desc:`base title of the app pages (default is "LikeC4")`,default:`LikeC4`,nargs:1},Vt={alias:[`base-url`],string:!0,desc:`base url the app is being served from, e.g. "/" or "/pages/"`,nargs:1},Ht={boolean:!0,desc:`outputs a single self-contained HTML file with all required resources inlined`},Ut={alias:`l`,string:!0,...T()?{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},Wt={number:!0,desc:`port number for the dev server (default is 5173, or PORT environment variable)`,nargs:1},q={alias:`p`,string:!0,desc:`select LikeC4 project by name (e.g. "my-project") or by path`,nargs:1},Gt={hidden:!0,nargs:1,desc:`force log level`,choices:[`trace`,`debug`,`info`,`warning`,`error`],conflicts:[`verbose`]},Kt={boolean:!0,desc:`verbose logging`,conflicts:[`log-level`]},qt=Se?`trace`:`debug`,J={name:yt,version:bt},Jt=c(()=>new we({projectName:yt,clearInvalidConfig:!0})),Yt=1e3*60,Xt=Yt*60*24*7;function Y(){if(!Ve)try{let e=Jt(),t=e.get(`lastSupportUsMessage`);if(!t){e.set(`lastSupportUsMessage`,Date.now()-Xt+5*Yt);return}if(t+Xt>Date.now())return;e.set(`lastSupportUsMessage`,Date.now()),H([y.dim(`If you are working in a commercial environment`),y.dim(`consider supporting the project`),``,y.dim(`How to get more?`)+` `+y.underline(`https://likec4.dev/sponsor/`)].join(`
16
+ `))}catch{}}function X(){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 Zt=e=>e.command({command:`build [path]`,aliases:[`bundle`],describe:`Build a static website`,builder:e=>e.positional(`path`,W).option(`output`,{alias:`o`,type:`string`,desc:`output directory for production build`,normalize:!0,coerce:P}).option(`base`,Vt).option(`use-hash-history`,Rt).option(`use-dot`,G).option(`webcomponent-prefix`,zt).option(`title`,Bt).option(`output-single-file`,Ht).example(`${y.green(`$0 build -o ./build ./src`)}`,y.gray(`Search for likec4 files in 'src' and output static site to 'build'`)),handler:async e=>{try{var t=X();let n={useHashHistory:e[`use-hash-history`]??!1,useDotBin:e[`use-dot`],webcomponentPrefix:e[`webcomponent-prefix`],outputSingleFile:e[`output-single-file`]??!1};await U();let r=B(`c4:build`),i=t.a(await C(e.path,{graphviz:e[`use-dot`]?`binary`:`wasm`,watch:!1})),a=e.output??P(i.workspace,`dist`),o=P(a,`assets`);await Pt({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}),Y()}catch(e){t.e=e}finally{await t.d()}}});var Qt=e(Ce(),1);const $t=`check-update`;async function en(){if(Ue||Ge===$t)return;let e=Jt(),t=e.get(`lastUpdateCheck`);if(!t){await tn(!1);return}let n=e.get(`latestVersion`);if(s(n)||s(t)||t+864e5<Date.now())try{Re(`likec4`,[`check-update`],{stdio:`ignore`,timeout:5e3,preferLocal:!0,detached:!0,env:{NODE_ENV:$t}}).catch(()=>{})}catch{}n&&(0,Qt.gt)(n,J.version)&&H([`Update available: `,y.dim(J.version),y.reset(` → `),y.green(n)].join(``))}async function tn(e=!0){try{let t=Jt();t.set({lastUpdateCheck:Date.now()});let n=await nn();Ie(n,`No version found in latest npm`),t.set({lastUpdateCheck:Date.now(),latestVersion:n}),(0,Qt.gt)(n,J.version)?H([`Update available: `,y.dim(J.version),y.reset(` → `),y.green(n)].join(``)):e&&H(y.dim(`Up to date: `)+` `+y.green(J.version))}catch(e){z.warning(_(e))}}async function nn(){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, */*`},timeout:5e3,keepalive:!0}).json()).version}const rn=e=>e.command({command:`check-update`,describe:`Check for updates`,handler:async()=>{await tn()}});function an(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)&&at(n).isDirectory()){z.debug`Project path exists: ${n}`;let t=b.file(n.endsWith(et)?n:n+et),r=e.languageServices.projects().find(e=>e.folder.fsPath===t.fsPath);if(r)return z.debug`Found project ${r.id} at path: ${n}`,r.id;z.debug`No project registered at path: ${n}`}return e.languageServices.projectsManager.ensureProjectId(t)}function Z(e,t){let n=an(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=z.getChild(`generator`);async function on({name:e,path:t,useDotBin:n,project:r}){try{var i=X();let a=V(Q),o=i.a(await C(t,{graphviz:n?`binary`:`wasm`,watch:!1})),{projectId:s,config:c}=Z(o,r);r&&Q.info(`${y.dim(`project`)} ${y.green(s)}`);let l=c.generators?.[e];if(!l)throw Q.error(y.red(`generator ${e} does not exist in project config`)),Error(`generator ${e} does not exist in project config`);Q.info(`${y.dim(`generator`)} ${y.green(e)}`),await sn({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 sn({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(`${y.dim(`running for project:`)} ${y.green(o.id)}`),await Promise.resolve().then(()=>n({likec4model:t,ctx:{workspace:e.languageServices.workspaceUri,project:o,locate:e=>{let t=null;switch(!0){case Ne(e):t=i.locate({element:e.id,projectId:s});break;case Pe(e):t=i.locate({view:e.id,projectId:s});break;case je(e):t=i.locate({deployment:e.id,projectId:s});break;case Fe(e):case Me(e):t=i.locate({relation:e.id,projectId:s});break;default:Le(e)}if(!t)throw r.error(`Cannot locate ${e.id}`,{target:e}),Error(`Cannot locate ${e.id}`);let n=b.parse(t.uri);return{range:t.range,document:n,relativePath:x.relative(o.folder,n),folder:x.dirname(n).fsPath,filename:x.basename(n)}},write:async({path:e,content:t})=>{let n;n=Array.isArray(e)?P(o.folder.fsPath,...e):b.isUri(e)?e.fsPath:P(o.folder.fsPath,`${e}`);let i=A(n);a.has(i)||(F(i)||(r.debug(`${y.dim(`create directory`)} ${i}`),await D(i,{recursive:!0})),a.add(i)),r.debug(`${y.dim(`write`)} ${n}`),await k(n,t)},abort:e=>{throw r.error(e||`Generator aborted`),Error(e||`Generator aborted`)}}}))}async function cn(e,t,n){t??=P(e.workspace,`likec4.generated.ts`),j(t)!==`.ts`&&(t+=`.ts`),await D(A(t),{recursive:!0});let r=me([...await e.diagrams()]);await k(t,r),n.info(`${y.dim(`generated`)} ${N(process.cwd(),t)}`)}async function ln(e,t,n){await D(t,{recursive:!0}),n.info(`${y.dim(`format`)} ${y.green(`dot`)}`),n.info(`${y.dim(`outdir`)} ${t}`);let r=new Set,i=await e.computedModel(),a=l(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(`${y.dim(`generated`)} ${N(process.cwd(),l)}`),o++}catch(e){z.error(`error while generating ${s.id}`,{error:e})}o>0&&n.info(`${y.dim(`total`)} ${o} files`)}async function un(e,t,n,r){await D(n,{recursive:!0}),r.info(`${y.dim(`format`)} ${y.green(t)}`),r.info(`${y.dim(`outdir`)} ${n}`);let i,a;switch(t){case`d2`:i=`.d2`,a=le;break;case`mermaid`:i=`.mmd`,a=pe;break;case`plantuml`:i=`.puml`,a=ue;break;default:Le(t)}let o=new Set,s=await e.layoutedModel(),c=0;for(let e of s.views()){let t=e.$view;try{let s=`.`;t.sourcePath&&(s=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(`${y.dim(`generated`)} ${N(process.cwd(),l)}`),c++}catch(e){r.error(`error while generating ${t.id}`,{error:e})}}c>0&&r.info(`${y.dim(`total`)} ${c} files`)}async function dn({path:e,useDotBin:t,...n}){let r=B(`c4:codegen`),i=V(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 cn(a,n.outfile,r);break;case`dot`:await ln(a,n.outdir??e,r);break;case`d2`:case`mermaid`:case`plantuml`:await un(a,n.format,n.outdir??e,r);break;default:Le(n)}i.stopAndLog()}const fn=A(L(import.meta.url));function pn(){try{return JSON.parse(nt(M(fn,`..`,`package.json`),`utf8`)).version??`0.1.0`}catch{return JSON.parse(nt(M(fn,`..`,`..`,`package.json`),`utf8`)).version??`0.1.0`}}const mn=pn(),hn=`leanix`,gn=`depends on`,_n={factSheetTypes:{system:`Application`,container:`ITComponent`,component:`ITComponent`,actor:`Provider`},relationTypes:{default:gn},metadataToFields:{title:`name`,description:`description`,technology:`technology`}};function vn(e){let t={factSheetTypes:{..._n.factSheetTypes},relationTypes:{..._n.relationTypes},metadataToFields:{..._n.metadataToFields}};return e?{factSheetTypes:{...t.factSheetTypes,...e.factSheetTypes},relationTypes:{...t.relationTypes,...e.relationTypes},metadataToFields:{...t.metadataToFields,...e.metadataToFields}}:t}function yn(e,t){return t.factSheetTypes[e]??t.factSheetTypes.default??`Application`}function bn(e,t){let n=e??`default`;return t.relationTypes[n]??t.relationTypes.default??gn}const xn={manifestVersion:`1.0`,bridgeVersion:mn,mappingProfile:`default`};function Sn(e){let t={};for(let n of e.elements())t[n.id]={canonicalId:n.id,external:{}};return t}function Cn(e){let t={};for(let n of e.views())t[n.id]={viewId:n.id,external:{}};return t}function wn(e){let t=[];for(let n of e.relationships())t.push({relationId:n.id,sourceFqn:n.source.id,targetFqn:n.target.id,compositeKey:`${n.source.id}|${n.target.id}|${n.id}`,external:{}});return t}function Tn(e,t={}){let n={...xn,...t,generatedAt:t.generatedAt??new Date().toISOString()};return{manifestVersion:n.manifestVersion,generatedAt:n.generatedAt,bridgeVersion:n.bridgeVersion,mappingProfile:n.mappingProfile,projectId:e.projectId,entities:Sn(e),views:Cn(e),relations:wn(e)}}function En(e,t){let n=[];for(let r of e.elements()){let e=yn(r.kind,t),i=r.getMetadata(),a=typeof i.description==`string`?i.description:void 0,o=r.technology??(typeof i.technology==`string`?i.technology:void 0);n.push({type:e,likec4Id:r.id,name:r.title,...a!==void 0&&{description:a},...o!==void 0&&{technology:o},...r.tags.length>0&&{tags:[...r.tags]},...Object.keys(i).length>0&&{metadata:{...i}}})}return n.sort((e,t)=>e.likec4Id.localeCompare(t.likec4Id)),n}function Dn(e,t){let n=[];for(let r of e.relationships()){let e=r.title??r.kind;n.push({type:bn(r.kind,t),likec4RelationId:r.id,sourceLikec4Id:r.source.id,targetLikec4Id:r.target.id,...e!=null&&e!==``&&{title:String(e)}})}return n.sort((e,t)=>e.likec4RelationId.localeCompare(t.likec4RelationId)),n}function On(e,t={}){let n=vn(t.mapping),r=t.generatedAt??new Date().toISOString(),i=t.mappingProfile??(t.mapping?`custom`:`default`);return{generatedAt:r,projectId:e.projectId,mappingProfile:i,factSheets:En(e,n),relations:Dn(e,n)}}function kn(e,t){let n=[];return e.projectId!==t.projectId&&n.push(`projectId (manifest: ${e.projectId}, leanixDryRun: ${t.projectId})`),e.mappingProfile!==t.mappingProfile&&n.push(`mappingProfile (manifest: ${e.mappingProfile}, leanixDryRun: ${t.mappingProfile})`),`Manifest and LeanIX dry-run must belong to the same run. Mismatch: ${n.join(`; `)}`}function An(e,t){if(e.projectId!==t.projectId||e.mappingProfile!==t.mappingProfile)throw Error(kn(e,t));return{generatedAt:e.generatedAt,projectId:e.projectId,manifestVersion:e.manifestVersion,bridgeVersion:e.bridgeVersion,mappingProfile:e.mappingProfile,counts:{entities:Object.keys(e.entities).length,views:Object.keys(e.views).length,relations:e.relations.length,factSheets:t.factSheets.length,leanixRelations:t.relations.length},artifacts:{manifest:`manifest.json`,leanixDryRun:`leanix-dry-run.json`}}}var jn=class extends Error{constructor(e,t,n){super(e),this.statusCode=t,this.graphqlErrors=n,this.name=`LeanixApiError`}};function Mn(e){return new Promise(t=>setTimeout(t,e))}var Nn=class{baseUrl;apiToken;requestDelayMs;lastRequestTime=0;rateLimitLock=Promise.resolve();constructor(e){this.apiToken=e.apiToken,this.baseUrl=(e.baseUrl??`https://app.leanix.net`).replace(/\/$/,``),this.requestDelayMs=e.requestDelayMs??200}async graphql(e,t){let n=async()=>{let n=Date.now()-this.lastRequestTime;n<this.requestDelayMs&&await Mn(this.requestDelayMs-n),this.lastRequestTime=Date.now();let r=`${this.baseUrl}/services/pathfinder/v1/graphql`,i;try{i=await fetch(r,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${this.apiToken}`},body:JSON.stringify({query:e,variables:t})})}catch(e){throw new jn(`GraphQL request failed: ${r} POST - ${e instanceof Error?e.message:String(e)}`)}let a;try{a=await i.json()}catch(e){let t=e instanceof Error?e.message:String(e);throw new jn(`Invalid JSON response: ${r} ${i.status} ${i.statusText} - ${t}`,i.status)}if(!i.ok)throw new jn(a.errors?.[0]?.message??`HTTP ${i.status} ${i.statusText}`,i.status,a.errors);if(a.errors&&a.errors.length>0)throw new jn(a.errors.map(e=>e.message).join(`; `),i.status,a.errors);if(a.data===void 0)throw new jn(`GraphQL response had no data and no errors`);return a.data},r=this.rateLimitLock,i;this.rateLimitLock=new Promise(e=>{i=e}),await r;try{return await n()}finally{i()}}};async function Pn(e,t,n){let r=(await e.graphql(`
17
+ query FindFactSheet($name: String!, $type: String!) {
18
+ allFactSheets(filter: { name: $name, factSheetType: $type }) {
19
+ edges { node { id name type } }
20
+ }
21
+ }
22
+ `,{name:t,type:n})).allFactSheets?.edges??[];if(r.length>1)throw Error(`Multiple fact sheets found for name="${t}" type="${n}". Ensure unique name+type in LeanIX or use likec4Id attribute for lookup.`);return r[0]?.node?.id??null}async function Fn(e,t,n){let r={facetFilters:[{facetKey:t,operator:`OR`,keys:[n]}]},i=(await e.graphql(`
23
+ query FindFactSheetByAttribute($filter: FilterInput!) {
24
+ allFactSheets(filter: $filter) {
25
+ edges { node { id } }
26
+ }
27
+ }
28
+ `,{filter:r})).allFactSheets?.edges??[];if(i.length>1)throw Error(`Multiple fact sheets found for attribute ${t}=${n}. Ensure unique likec4Id in LeanIX.`);return i[0]?.node?.id??null}async function In(e,t,n,r){let i=[{op:`replace`,path:`/factSheetAttributes/${n}`,value:r}];if(!(await e.graphql(`
29
+ mutation UpdateFactSheet($id: ID!, $patches: [Patch]) {
30
+ updateFactSheet(id: $id, patches: $patches) {
31
+ factSheet { id }
32
+ }
33
+ }
34
+ `,{id:t,patches:i})).updateFactSheet?.factSheet?.id)throw Error(`updateFactSheet did not return fact sheet (id=${t}, attribute=${n})`)}async function Ln(e,t,n){let r=[];t.description&&r.push({op:`replace`,path:`/description`,value:t.description}),n&&t.likec4Id&&r.push({op:`replace`,path:`/factSheetAttributes/${n}`,value:t.likec4Id});let i={input:{name:t.name,type:t.type},patches:r},a=(await e.graphql(`
35
+ mutation CreateFactSheet($input: CreateFactSheetInput!, $patches: [Patch]) {
36
+ createFactSheet(input: $input, patches: $patches) {
37
+ factSheet { id name type rev }
38
+ }
39
+ }
40
+ `,i)).createFactSheet?.factSheet?.id;if(!a)throw Error(`createFactSheet did not return id for ${String(t.name)}`);return a}async function Rn(e,t,n,r,i){let a=await e.graphql(`
41
+ mutation CreateRelation($source: ID!, $target: ID!, $type: String!) {
42
+ createRelation(source: $source, target: $target, type: $type) {
43
+ relation { id }
44
+ }
45
+ }
46
+ `,{source:t,target:n,type:r}),o=a.createRelation?.relation?.id;if(!o){let e=JSON.stringify(a,null,2);throw Error(`createRelation did not return relation id (sourceFactSheetId=${t}, targetFactSheetId=${n}, relationType=${r}). Response: ${e}`)}return o}function zn(e,t){let n=t?`update`:`create`;return{likec4Id:e.likec4Id,name:e.name,type:e.type,action:n,...t?{existingFactSheetId:t}:{}}}function Bn(e,t){return{factSheetsToCreate:e.filter(e=>e.action===`create`).length,factSheetsToUpdate:e.filter(e=>e.action===`update`).length,relationsToCreate:t.length}}function Vn(e){if(e instanceof Error)return e.stack?`${e.message}\n${e.stack}`:e.message;if(typeof e==`object`&&e)try{return JSON.stringify(e,null,2)}catch{return Object.prototype.toString.call(e)}return String(e)}function Hn(e,t){let n={...e};for(let[r,i]of Object.entries(e)){let e=t.get(r);e&&(n[r]={...i,external:{...i.external,[hn]:{factSheetId:e,externalId:e}}})}return n}async function Un(e,t,n,r){if(!n)return null;if(r){let n=await Fn(e,r,t.likec4Id);if(n)return n;let i=await Pn(e,t.name,t.type);if(i&&t.likec4Id)try{await In(e,i,r,t.likec4Id)}catch(e){console.warn(`[leanix-bridge] Failed to backfill likec4Id on fact sheet ${i} (${t.name}/${t.type}): ${e instanceof Error?e.message:String(e)}. Reusing ID.`)}return i??null}return Pn(e,t.name,t.type)}async function Wn(e,t,n,r){let i=new Map,a=[],o=0,s=0;for(let c of t)try{let t=await Un(e,c,n,r);t&&s++,t||(t=await Ln(e,c,r),o++),t&&i.set(c.likec4Id,t)}catch(e){a.push(`Fact sheet ${c.likec4Id} (${String(c.name)}): ${Vn(e)}`)}return{likec4IdToFactSheetId:i,factSheetsCreated:o,factSheetsReused:s,errors:a}}async function Gn(e,t,n,r){let i=[],a=[],o=0;for(let s of t){let t=r.get(s.sourceFqn),c=r.get(s.targetFqn),l=s.external?.[hn];if(t&&c&&!l?.relationId){let r=n.find(e=>e.sourceLikec4Id===s.sourceFqn&&e.targetLikec4Id===s.targetFqn&&e.likec4RelationId===s.relationId);if(r)try{let n=await Rn(e,t,c,r.type,r.title);o++,i.push({...s,external:{...s.external,[hn]:{relationId:n,...s.external?.[hn]}}});continue}catch(e){a.push(`Relation ${s.compositeKey}: ${Vn(e)}`)}}i.push(s)}return{updatedRelations:i,relationsCreated:o,errors:a}}async function Kn(e,t,n={}){let r=n.idempotent??!0,i=n.likec4IdAttribute,a=n.generatedAt??new Date().toISOString(),o=[],s=[];for(let n of e.factSheets)try{let e=null;r&&(i?(e=await Fn(t,i,n.likec4Id),e||=await Pn(t,n.name,n.type)):e=await Pn(t,n.name,n.type)),s.push(zn(n,e))}catch(e){o.push(`Fact sheet ${n.likec4Id} (${String(n.name)}): ${Vn(e)}`),s.push(zn(n,null))}let c=e.relations.map(e=>({likec4RelationId:e.likec4RelationId,sourceLikec4Id:e.sourceLikec4Id,targetLikec4Id:e.targetLikec4Id,type:e.type,action:`create`}));return{generatedAt:a,projectId:e.projectId,mappingProfile:e.mappingProfile,summary:Bn(s,c),factSheetPlans:s,relationPlans:c,errors:o}}async function qn(e,t,n,r={}){let i=r.idempotent??!0,a=r.likec4IdAttribute,o=await Wn(n,t.factSheets,i,a),s=Hn(e.entities,o.likec4IdToFactSheetId),c=await Gn(n,e.relations,t.relations,o.likec4IdToFactSheetId);return{manifest:{...e,entities:s,relations:c.updatedRelations},factSheetsCreated:o.factSheetsCreated,factSheetsReused:o.factSheetsReused,relationsCreated:c.relationsCreated,errors:[...o.errors,...c.errors]}}async function Jn(e){let t;for(let n=0;n<3;n++)try{return await e()}catch(e){t=e,n<2&&await new Promise(e=>setTimeout(e,500*(n+1)))}throw t}async function Yn(e,t={}){let n=t.generatedAt??new Date().toISOString(),r=t.maxFactSheets??1e3;if(!Number.isInteger(r)||r<0)throw Error(`maxFactSheets must be a non-negative integer`);let i=t.likec4IdAttribute,a=await Zn(e,{...i==null?{}:{likec4IdAttribute:i},maxFactSheets:r});return{generatedAt:n,factSheets:a,relations:await Qn(e,a.map(e=>e.id))}}function Xn(e,t){if(!e?.id)return null;let n=t!=null&&Array.isArray(e.factSheetAttributes)?e.factSheetAttributes.find(e=>e.key===t)?.value:void 0;return{id:e.id,name:e.name??``,type:e.type??``,...n?{likec4Id:n}:{}}}async function Zn(e,t){let n=t.likec4IdAttribute,r=Math.min(100,t.maxFactSheets),i=[],a=null,o=!0,s=`
47
+ query AllFactSheets($first: Int!, $after: String, $filter: FilterInput) {
48
+ allFactSheets(first: $first, after: $after, filter: $filter) {
49
+ edges {
50
+ node {
51
+ id
52
+ name
53
+ type
54
+ ${n==null?``:`factSheetAttributes { key value }`}
55
+ }
56
+ cursor
57
+ }
58
+ pageInfo {
59
+ hasNextPage
60
+ endCursor
61
+ }
62
+ }
63
+ }
64
+ `,c=async t=>Jn(()=>e.graphql(s,{first:r,after:t,filter:{}}));for(;o&&i.length<t.maxFactSheets;){let e=await c(a),r=e.allFactSheets?.edges??[],s=e.allFactSheets?.pageInfo;for(let e of r){if(i.length>=t.maxFactSheets)break;let r=Xn(e.node,n);r&&i.push(r)}o=s?.hasNextPage===!0&&i.length<t.maxFactSheets,a=s?.endCursor??null}return i}async function Qn(e,t){if(t.length===0)return[];let n=[],r=new Set(t);async function i(t){let n=[],i=null,a=!0;for(;a;){let o=await Jn(()=>e.graphql(`
65
+ query FactSheetRelations($id: ID!, $first: Int, $after: String) {
66
+ factSheet(id: $id) {
67
+ id
68
+ relations(first: $first, after: $after) {
69
+ edges {
70
+ node {
71
+ id
72
+ type
73
+ targetFactSheet { id }
74
+ }
75
+ }
76
+ pageInfo { hasNextPage endCursor }
77
+ }
78
+ }
79
+ }
80
+ `,{id:t,first:100,after:i})),s=o?.factSheet?.relations?.edges??[],c=o?.factSheet?.relations?.pageInfo;for(let e of s){let i=e.node,a=i?.targetFactSheet?.id;!a||!r.has(a)||n.push({...i?.id?{id:i.id}:{},sourceFactSheetId:t,targetFactSheetId:a,type:i?.type??`RELATES_TO`})}a=c?.hasNextPage===!0,i=c?.endCursor??null}return n}for(let e=0;e<t.length;e+=10){let r=t.slice(e,e+10),a=await Promise.all(r.map(e=>i(e)));for(let e of a)n.push(...e)}return n}function $n(e,t,n,r){let i=e.external?.[hn],a=i?.factSheetId??i?.externalId;if(a==null)return null;let o=n.get(a);return!o||r.has(o.id)?null:(r.add(o.id),{canonicalId:t,factSheetId:o.id,name:o.name,type:o.type})}function er(e,t,n){let r=t.get(e);return!r||n.has(r.id)?null:(n.add(r.id),{canonicalId:e,factSheetId:r.id,name:r.name,type:r.type})}function tr(e,t,n,r,i,a,o,s){let c=`${t??e}${n??``}`,l=r.get(c)?.filter(e=>!i.has(e.id))??[];if(l.length===0)o.push({canonicalId:e,...t===void 0?{}:{name:t},...n===void 0?{}:{type:n}});else if(l.length===1){let t=l[0];a.push({canonicalId:e,factSheetId:t.id,name:t.name,type:t.type}),i.add(t.id)}else s.push({canonicalId:e,...t===void 0?{}:{name:t},...n===void 0?{}:{type:n},candidateFactSheetIds:l.map(e=>e.id)})}function nr(e,t,n={}){let r=n.generatedAt??new Date().toISOString(),i=n.dryRun,a=[],o=[],s=[],c=new Map(e.factSheets.map(e=>[e.id,e])),l=new Map,u=new Map;for(let t of e.factSheets){t.likec4Id&&l.set(t.likec4Id,t);let e=`${t.name}${t.type}`;u.has(e)||u.set(e,[]),u.get(e).push(t)}let d=i?new Map(i.factSheets.map(e=>[e.likec4Id,e])):null,f=new Set;for(let[e,n]of Object.entries(t.entities)){let t=$n(n,e,c,f);if(t){a.push(t);continue}let r=er(e,l,f);if(r){a.push(r);continue}let i=d?.get(e);tr(e,i?.name??void 0,i?.type??void 0,u,f,a,o,s)}let p=e.factSheets.filter(e=>!f.has(e.id)).map(e=>({factSheetId:e.id,name:e.name,type:e.type,...e.likec4Id?{likec4Id:e.likec4Id}:{}}));return{generatedAt:r,manifestProjectId:t.projectId,snapshotGeneratedAt:e.generatedAt,matched:a,unmatchedInLikec4:o,unmatchedInLeanix:p,ambiguous:s,summary:{matched:a.length,unmatchedInLikec4:o.length,unmatchedInLeanix:p.length,ambiguous:s.length}}}function $(e){return typeof e==`object`&&!!e}function rr(e){return $(e)?typeof e.canonicalId==`string`:!1}function ir(e){return $(e)?typeof e.viewId==`string`:!1}function ar(e){return $(e)?typeof e.relationId==`string`&&typeof e.sourceFqn==`string`&&typeof e.targetFqn==`string`&&typeof e.compositeKey==`string`:!1}function or(e){return $(e)?typeof e.id==`string`&&typeof e.name==`string`&&typeof e.type==`string`:!1}function sr(e){return $(e)?typeof e.sourceFactSheetId==`string`&&typeof e.targetFactSheetId==`string`&&typeof e.type==`string`:!1}function cr(e){if(!$(e)||typeof e.manifestVersion!=`string`||typeof e.generatedAt!=`string`||typeof e.bridgeVersion!=`string`||typeof e.mappingProfile!=`string`||typeof e.projectId!=`string`)return!1;let t=e.entities;if(typeof t!=`object`||!t||Array.isArray(t))return!1;for(let e of Object.values(t))if(!rr(e))return!1;let n=e.views;if(typeof n!=`object`||!n||Array.isArray(n))return!1;for(let e of Object.values(n))if(!ir(e))return!1;let r=e.relations;if(!Array.isArray(r))return!1;for(let e of r)if(!ar(e))return!1;return!0}function lr(e){if(!$(e)||typeof e.generatedAt!=`string`||e.workspaceId!==void 0&&typeof e.workspaceId!=`string`||!Array.isArray(e.factSheets))return!1;for(let t of e.factSheets)if(!or(t))return!1;if(!Array.isArray(e.relations))return!1;for(let t of e.relations)if(!sr(t))return!1;return!0}const ur=`No project or empty model`,dr=`LEANIX_API_TOKEN is required for likec4 sync leanix --apply`,fr=`default`,pr=`manifest.json`,mr=`leanix-dry-run.json`,hr=`report.json`;function gr(e){return{projectId:String(e.projectId),elements:()=>e.elements(),relationships:()=>e.relationships(),views:()=>e.views()}}function _r(e){let t=Tn(e,{mappingProfile:fr}),n=On(e,{mappingProfile:fr});return{manifest:t,dryRun:n,report:An(t,n)}}async function vr(e,t,n,r=process.cwd()){await D(e,{recursive:!0});let i=P(e,pr),a=P(e,mr),o=P(e,hr);await k(i,JSON.stringify(t.manifest,null,2)),await k(a,JSON.stringify(t.dryRun,null,2)),await k(o,JSON.stringify(t.report,null,2)),n.info(`${y.dim(`generated`)} ${N(r,i)}`),n.info(`${y.dim(`generated`)} ${N(r,a)}`),n.info(`${y.dim(`generated`)} ${N(r,o)}`)}const yr={manifest:pr,dryRun:mr,report:hr};async function br(e){let t=B(`c4:gen:leanix:dry-run`),n=V(t),{path:r,outdir:i,project:a,useDotBin:o}=e;try{try{var s=X();let e=s.a(await C(r,{graphviz:o?`binary`:`wasm`,watch:!1})),{projectId:n}=Z(e,a);a&&t.info(`${y.dim(`project`)} ${y.green(n)}`);let c=await e.layoutedModel(n);if(c===w.EMPTY)throw t.error(ur),Error(ur);await vr(i,_r(gr(c)),t)}catch(e){s.e=e}finally{await s.d()}}finally{n.stopAndLog()}}function xr(){let e=process.env.LEANIX_API_TOKEN?.trim();return e?new Nn({apiToken:e,baseUrl:process.env.LEANIX_BASE_URL?.trim()||`https://app.leanix.net`,requestDelayMs:200}):null}function Sr(){let e=xr();if(!e)throw Error(`LEANIX_API_TOKEN is required. Set it in the environment to call the LeanIX API.`);return e}async function Cr(e){let t=B(`c4:gen:leanix:inventory`),n=V(t),{outdir:r,likec4IdAttribute:i}=e;try{let e=Sr(),n={};typeof i==`string`&&i.trim()!==``&&(n.likec4IdAttribute=i.trim());let a=await Yn(e,n);await D(r,{recursive:!0});let o=P(r,`leanix-inventory-snapshot.json`);await k(o,JSON.stringify(a,null,2)),t.info(`${y.dim(`generated`)} ${N(process.cwd(),o)}`),t.info(`${y.dim(`snapshot`)} ${a.factSheets.length} fact sheets, ${a.relations.length} relations`)}finally{n.stopAndLog()}}const wr=`manifest.json`,Tr=`leanix-inventory-snapshot.json`;async function Er(e){let t=P(e,wr),n=P(e,Tr),[r,i]=await Promise.all([O(t,`utf-8`),O(n,`utf-8`)]),a=JSON.parse(r),o=JSON.parse(i);if(!cr(a))throw Error(`Invalid manifest format: missing manifestVersion, projectId, entities, relations, or views`);if(!lr(o))throw Error(`Invalid snapshot format: missing factSheets or relations arrays`);return{manifest:a,snapshot:o}}async function Dr(e,t,n){try{var r=X();let i=r.a(await C(e,{graphviz:n?`binary`:`wasm`,watch:!1})),{projectId:a}=Z(i,t),o=await i.layoutedModel(a);return o===w.EMPTY?void 0:_r(gr(o)).dryRun}catch(e){r.e=e}finally{await r.d()}}async function Or(e){let t=B(`c4:gen:leanix:reconcile`),n=V(t),{path:r,outdir:i,project:a,useDotBin:o}=e;try{let e,n;try{let t=await Er(i);e=t.manifest,n=t.snapshot}catch(e){let n=e instanceof Error?e.message:String(e);throw t.error(`Failed to read ${wr} or ${Tr} from ${i}: ${n}`),e}let s;try{s=await Dr(r,a,o)}catch(e){let n=e instanceof Error?e.message:String(e);if(a!=null&&a!==``)throw t.error(`Failed to load workspace for dryRun enrichment: ${n}`),e;t.warn(`Could not load workspace for dryRun enrichment; proceeding without it: ${n}`),s=void 0}let c=nr(n,e,{...s==null?{}:{dryRun:s}}),l=P(i,`reconciliation-report.json`);await k(l,JSON.stringify(c,null,2)),t.info(`${y.dim(`generated`)} ${N(process.cwd(),l)}`),t.info(`${y.dim(`reconcile`)} matched=${c.summary.matched} unmatchedLikec4=${c.summary.unmatchedInLikec4} unmatchedLeanix=${c.summary.unmatchedInLeanix} ambiguous=${c.summary.ambiguous}`)}finally{n.stopAndLog()}}async function kr({path:e,useDotBin:t,useCorePackage:n,outfile:r,project:i}){try{var a=X();let o=B(`c4:codegen`),s=V(o),c=a.a(await C(e,{graphviz:t?`binary`:`wasm`,watch:!1})),{projectId:l,projectFolder:u}=Z(c,i);i&&o.info(`${y.dim(`project`)} ${y.green(l)}`),o.info(`${y.dim(`format`)} ${y.green(`model`)}`);let d=await c.layoutedModel(l);for(let e of d.views())e.hasLayoutDrifts&&o.warn(y.yellow(`layout drift detected, view:`)+` `+y.red(e.id));let f=P(c.projectsManager.hasMultipleProjects()?u:c.workspace,`likec4-model.ts`);if(r&&(f=$e(r)?r:P(r),F(r)&&(await Ze(r)).isDirectory()))throw Error(`output file is a directory: ${r}`);let p=Qe(f);o.info(`${y.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(`${y.dim(`outdir`)} ${h}`),await D(h,{recursive:!0}),await k(f,se(d,{useCorePackage:n}),{encoding:`utf-8`}),s.stopAndLog(),H(oe(`
81
+ ${y.dim(`Source generated:`)}
82
+ ${N(I(),f)}
83
+
84
+ ${y.dim(`How to use:`)}
85
+ ${y.underline(`https://likec4.dev/tooling/code-generation/model/`)}
86
+ `).trim(),{padding:1,borderColor:`green`,borderStyle:`round`})}catch(e){a.e=e}finally{await a.d()}}async function Ar({languageServices:e,outDir:t,filename:n=`likec4-react.mjs`}){let r=B([`vite`,`react`]),i=Et();return r.info(`${y.cyan(`likec4 app root`)} ${y.dim(Ot(i))}`),r.info(y.cyan(`outDir`)+` `+y.dim(Ot(t))),{customLogger:r,root:i,configFile:!1,clearScreen:!1,publicDir:!1,mode:`production`,resolve:{conditions:[`production`],alias:At()},esbuild:{banner:`'use client'
87
+ `+wt.banner,footer:wt.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:kt,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:[pt({}),ge({languageServices:e.languageServices})]}}async function jr({path:e,useDotBin:t,useCorePackage:n,outfile:r,project:i}){try{var a=X();await U();let o=B(`c4:codegen`),s=V(o),c=a.a(await C(e,{graphviz:t?`binary`:`wasm`,watch:!1})),{projectId:l,projectFolder:u}=Z(c,i);i&&o.info(`${y.dim(`project`)} ${y.green(l)}`),o.info(`${y.dim(`format`)} ${y.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(y.yellow(`layout drift detected, view:`)+` `+y.red(e.id));return}if(e.hasLayoutDrift){o.warn(y.yellow(`drift detected, manual layout can not be applied, view:`)+` `+y.red(e.id));return}});let f=P(c.projectsManager.hasMultipleProjects()?u:c.workspace,`likec4-views.js`);if(r&&(f=$e(r)?r:P(r),F(r)&&(await Ze(r)).isDirectory()))throw Error(`output file is a directory: ${r}`);let p=A(f);o.info(`${y.dim(`outdir`)} ${p}`);let m=Qe(f);o.info(`${y.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 Ar({languageServices:c,outDir:p,filename:m}),logLevel:`warn`});let g=await c.layoutedModel(l),_=P(p,Qe(f,h)+(h===`.mjs`?`.d.mts`:`.d.ts`));await k(_,fe(g,{useCorePackage:n})),s.stopAndLog(),H(oe(`
88
+ ${y.dim(`Sources generated:`)}
89
+ ${N(I(),f)}
90
+ ${N(I(),_)}
91
+
92
+ ${y.dim(`How to use:`)}
93
+ ${y.underline(`https://likec4.dev/tooling/code-generation/react/`)}
94
+ `),{padding:1,borderColor:`green`,borderStyle:`round`})}catch(e){a.e=e}finally{await a.d()}}async function Mr({project:e,path:t,useDotBin:n,webcomponentPrefix:r=`likec4`,outfile:i}){try{var o=X();await U();let s=B(`c4:codegen`),c=V(s),l=o.a(await C(t,{graphviz:n?`binary`:`wasm`,watch:!1})),{projectId:u,projectFolder:d}=Z(l,e);e&&s.info(`${y.dim(`project`)} ${y.green(u)}`),s.info(`${y.dim(`format`)} ${y.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(y.yellow(`drift detected, manual layout can not be applied, view:`)+` `+y.red(e.id))});let p=P(l.projectsManager.hasMultipleProjects()?d:l.workspace,`likec4-views.js`);if(i&&(p=$e(i)?i:P(i),F(i)&&(await Ze(i)).isDirectory()))throw Error(`output file is a directory: ${i}`);s.debug(`${y.dim(`outfilepath`)} ${p}`);let m=Qe(p);s.debug(`${y.dim(`filename`)} ${m}`);let h=j(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 Dt();s.debug(`${y.dim(`created temp public`)} ${g}`);let _=await Mt({languageServices:l,outDir:g,filename:m,webcomponentPrefix:r,base:`/`});s.debug(`${y.dim(`vite build webcomponent`)}`),await R({..._,logLevel:`warn`});let v=P(g,m);if(!F(v))throw Error(`output file not found: ${v}`);await D(A(p),{recursive:!0}),await Ke(v,p),s.info(`${y.dim(`generated`)} ${p}`),s.debug(`${y.dim(`remove temp public`)}`),await Xe(g,{recursive:!0,force:!0}),c.stopAndLog(),H(oe(`
95
+ ${y.dim(`Webcomponents generated to:`)}
96
+ ${N(I(),p)}
97
+
98
+ ${y.dim(`Setup and usage instructions:`)}
99
+ ${y.blue(`https://likec4.dev/tooling/code-generation/webcomponent/`)}
100
+ `))}catch(e){o.e=e}finally{await o.d()}}const Nr=e=>e.command({command:`gen <command> [path]`,aliases:[`generate`,`codegen`],describe:`Generate various artifacts from LikeC4 sources`,builder:e=>e.positional(`path`,W).command(`react [path]`,`generate react component to render likec4 view`,e=>e.positional(`path`,W).option(`project`,q).option(`outfile`,{alias:[`o`,`output`],type:`string`,desc:`<file> path to output file (.jsx, .mjs or .js)`,normalize:!0,coerce:E}).option(`use-dot`,G).option(`use-core-package`,Lt),async e=>{await jr({project:e.project,useDotBin:e.useDotBin,path:e.path,outfile:e.outfile,useCorePackage:e.useCorePackage}),Y()}).command({command:`webcomponent [path]`,aliases:[`wc`,`webcomp`],describe:`generate js with webcomponents`,builder:e=>e.positional(`path`,W).option(`project`,q).option(`outfile`,{alias:[`o`,`output`],type:`string`,desc:`<file> path to output file (.mjs or .js)`,normalize:!0,coerce:E}).option(`webcomponent-prefix`,zt).option(`use-dot`,G),handler:async e=>{await Mr({project:e.project,useDotBin:e.useDotBin,path:e.path,outfile:e.outfile,webcomponentPrefix:e.webcomponentPrefix}),Y()}}).command({command:`model [path]`,aliases:[`ts`],describe:`generate LikeC4Model (.ts)`,builder:e=>e.positional(`path`,W).option(`project`,q).option(`outfile`,{alias:[`o`,`output`],type:`string`,desc:`<file> path to output file (.ts)`,normalize:!0,coerce:E}).option(`use-dot`,G).option(`use-core-package`,Lt),handler:async e=>{await kr({path:e.path,useDotBin:e.useDotBin,useCorePackage:e.useCorePackage,outfile:e.outfile,project:e.project}),Y()}}).command({command:`views-data [path]`,aliases:[`views`],describe:`{deprecated} use codegen model`,deprecated:!0,builder:e=>e.positional(`path`,W).option(`outfile`,{alias:[`o`,`output`],type:`string`,desc:`<file> output .ts file`,normalize:!0,coerce:E}).option(`use-dot`,G),handler:async e=>{await dn({format:`views`,path:e.path,useDotBin:e.useDotBin,outfile:e.outfile})}}).command({command:`leanix [path]`,describe:`LeanIX bridge: dry-run, inventory snapshot, reconcile`,builder:e=>e.positional(`path`,W).demandCommand(1,`Choose a subcommand: dry-run, inventory, reconcile`).command(`dry-run [path]`,`generate LeanIX bridge artifacts (manifest, dry-run inventory, report)`,e=>e.positional(`path`,W).option(`outdir`,{...K,desc:`<dir> output directory for manifest.json, leanix-dry-run.json, report.json`}).option(`project`,q).option(`use-dot`,G).example(`${y.green(`$0 gen leanix dry-run -o out/bridge`)}`,y.gray(`Write bridge artifacts to out/bridge`)),async e=>{await br({path:e.path,outdir:e.outdir??E(process.cwd(),`out`,`bridge`),project:e.project,useDotBin:e.useDotBin})}).command(`inventory`,`fetch LeanIX inventory (read-only) and write leanix-inventory-snapshot.json`,e=>e.option(`outdir`,{...K,default:E(process.cwd(),`out`,`bridge`),desc:`<dir> output directory for leanix-inventory-snapshot.json`}).option(`likec4-id-attribute`,{type:`string`,desc:`custom LeanIX attribute key for likec4Id (e.g. "likec4Id")`}).example(`${y.green(`$0 gen leanix inventory -o out/bridge`)}`,y.gray(`Requires LEANIX_API_TOKEN`)),async e=>{await Cr({outdir:e.outdir??E(process.cwd(),`out`,`bridge`),...e.likec4IdAttribute==null?{}:{likec4IdAttribute:e.likec4IdAttribute}})}).command(`reconcile [path]`,`reconcile manifest with leanix-inventory-snapshot; write reconciliation-report.json`,e=>e.positional(`path`,W).option(`outdir`,{...K,default:E(process.cwd(),`out`,`bridge`),desc:`<dir> directory with manifest.json and leanix-inventory-snapshot.json`}).option(`project`,q).option(`use-dot`,G).example(`${y.green(`$0 gen leanix reconcile -o out/bridge`)}`,y.gray(`Reads manifest + snapshot from outdir; optional workspace for name+type matching`)),async e=>{await Or({path:e.path,outdir:e.outdir??E(process.cwd(),`out`,`bridge`),project:e.project,useDotBin:e.useDotBin})}),handler:async()=>{}}).command({command:`dot [path]`,describe:`generate graphviz files (.dot)`,builder:e=>e.positional(`path`,W).option(`outdir`,K).option(`use-dot`,G),handler:async e=>{await dn({format:`dot`,path:e.path,useDotBin:e.useDotBin,outdir:e.outdir}),Y()}}).command({command:`d2 [path]`,describe:`generate D2 files (.d2)`,builder:e=>e.positional(`path`,W).option(`outdir`,K).option(`use-dot`,G),handler:async e=>{await dn({format:`d2`,path:e.path,useDotBin:e.useDotBin,outdir:e.outdir}),Y()}}).command({command:`mermaid [path]`,aliases:[`mmd`],describe:`generate Mermaid files (.mmd)`,builder:e=>e.positional(`path`,W).option(`outdir`,K).option(`use-dot`,G),handler:async e=>{await dn({format:`mermaid`,useDotBin:e.useDotBin,path:e.path,outdir:e.outdir}),Y()}}).command({command:`plantuml [path]`,aliases:[`puml`],describe:`generate PlantUML files (.puml)`,builder:e=>e.positional(`path`,W).option(`outdir`,K).option(`use-dot`,G),handler:async e=>{await dn({format:`plantuml`,useDotBin:e.useDotBin,path:e.path,outdir:e.outdir}),Y()}}).command({command:`<custom> [path]`,describe:`run custom generator from likec4 config`,builder:e=>e.positional(`path`,W).option(`project`,q).option(`use-dot`,G),handler:async e=>{await on({name:`custom`,path:e.path,project:e.project,useDotBin:e.useDotBin})}}).epilog(`${y.bold(`Examples:`)}
36
101
  likec4 gen react -o dist/likec4-views.mjs ./src/likec4
37
102
  likec4 gen model -o likec4-model.ts
103
+ likec4 gen leanix dry-run -o out/bridge
104
+ likec4 gen leanix inventory -o out/bridge
105
+ likec4 gen leanix reconcile -o out/bridge
38
106
  likec4 gen ts --outfile likec4-model.ts
39
107
  likec4 gen webcomponent -o likec4.js --webcomponent-prefix c4 --use-dot ./src
40
108
  likec4 gen mmd --outdir assets/
41
109
  likec4 gen plantuml --outdir assets/
42
110
  likec4 gen dot -o out .
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:`),`
111
+ `),handler:async e=>{await on({name:e.command,path:e.path,project:e.project,useDotBin:e.useDotBin})}}),Pr=new Set([`node_modules`,`.git`]);function Fr(e){return e.endsWith(`.c4`)||e.endsWith(`.likec4`)}function Ir(e,t=`
112
+
113
+ `){return e.filter(e=>e.trim()!==``).join(t)}const Lr=`No project or empty model`,Rr=`No views could be exported`;function zr(){return`${y.bold(`Examples:`)}
114
+ ${y.green(`$0 export drawio`)}
115
+ ${y.gray(`Export each view to a separate .drawio file`)}
116
+
117
+ ${y.green(`$0 export drawio --all-in-one -o ./diagrams src/`)}
118
+ ${y.gray(`Export all views as tabs in one .drawio file`)}
119
+
120
+ ${y.green(`$0 export drawio --roundtrip -o ./out`)}
121
+ ${y.gray(`Re-apply layout/waypoints from comment blocks (e.g. after import from DrawIO)`)}
122
+
123
+ ${y.green(`$0 export drawio --uncompressed -o ./out`)}
124
+ ${y.gray(`Export with raw XML (no compression) for draw.io desktop compatibility`)}
125
+
126
+ ${y.green(`$0 export drawio --profile leanix -o ./out`)}
127
+ ${y.gray(`Export with bridge-managed metadata (likec4Id, likec4ViewId, etc.) for LeanIX interoperability`)}`}function Br(e){return e instanceof Error?e:Error(_(e))}function Vr(e,t,n){let r=Br(n);throw e.error(t,{error:r}),r}async function Hr(e,t){let n=[],r=new Set;async function i(e,a){if(a>=50)return;let o=await Ye(e).catch(()=>null);if(o==null||r.has(o))return;r.add(o);let s=await Je(e,{withFileTypes:!0}).catch(n=>(t?.debug&&t.debug(`${y.dim(`Roundtrip:`)} readdir failed`,{dir:e,err:n}),[]));for(let r of s){let o=M(e,r.name);switch(!0){case r.isDirectory():Pr.has(r.name)||await i(o,a+1);break;case r.isSymbolicLink():if((await Ze(o).catch(()=>null))?.isFile()&&Fr(r.name)){let e=await O(o,`utf-8`).catch(e=>(t?.debug&&t.debug(`${y.dim(`Roundtrip:`)} readFile failed`,{file:o,err:e}),``));e&&n.push(e)}break;case r.isFile()&&Fr(r.name):{let e=await O(o,`utf-8`).catch(e=>(t?.debug&&t.debug(`${y.dim(`Roundtrip:`)} readFile failed`,{file:o,err:e}),``));e&&n.push(e);break}}}}return await i(e,0),Ir(n)}async function Ur(e,t,n){if(t)return Hr(P(e),n)}function Wr(e,t,n){let r=e?{compressed:!1}:{compressed:!0};return t===`leanix`&&(r.profile=`leanix`,r.projectId=n),r}function Gr(e,t,n,r,i){return he(e.map(e=>String(e.$view.id)),t,Wr(n,r,i))}async function Kr(e){let{viewmodels:t,outdir:n,workspacePath:r,roundtrip:i,uncompressed:a,profile:o,projectId:s,logger:c}=e,l=de(t,Gr(t,await Ur(r,i,c),a,o,s)),u=P(n,_e);await k(u,l),c.info(`${y.dim(`generated`)} ${N(process.cwd(),u)} (${t.length} tab(s))`)}async function qr(e,t,n,r){let i=String(e.$view.id);try{let a=ce(e,t[i]),o=P(n,i+`.drawio`);return await D(A(o),{recursive:!0}),await k(o,a),r.info(`${y.dim(`generated`)} ${N(process.cwd(),o)}`),!0}catch(e){return r.error(`Failed to export view ${i}`,{error:Br(e)}),!1}}async function Jr(e){let{viewmodels:t,outdir:n,workspacePath:r,roundtrip:i,uncompressed:a,profile:o,projectId:s,logger:c}=e,l=Gr(t,await Ur(r,i,c),a,o,s),u=0;for(let e of t)await qr(e,l,n,c)&&u++;return{succeeded:u}}async function Yr(e,t){try{var n=X();let r=V(t),i=n.a(await Ee(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===w.EMPTY)throw t.error(Lr),Error(Lr);let s=[...o.views()];if(s.length===0)throw t.error(`No views to export`),Error(Rr);await D(e.outdir,{recursive:!0});let c=String(o.projectId),l={viewmodels:s,outdir:e.outdir,workspacePath:e.path,roundtrip:e.roundtrip,uncompressed:e.uncompressed,profile:e.profile,projectId:c,logger:t};if(e.allInOne)try{await Kr(l)}catch(e){Vr(t,`Failed to export DrawIO`,e)}else{let{succeeded:e}=await Jr(l);if(e===0)throw t.error(Rr),Error(Rr);t.info(`${y.dim(`total`)} ${e} DrawIO file(s)`)}r.stopAndLog(`✓ export drawio in `)}catch(e){n.e=e}finally{await n.d()}}function Xr(e){return e.command({command:`drawio [path]`,describe:`export view(s) to DrawIO (.drawio) for editing in draw.io`,builder:e=>e.positional(`path`,W).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)`}).option(`profile`,{type:`string`,choices:[`default`,`leanix`],default:`default`,desc:`export profile: default (round-trip) or leanix (bridge-managed metadata for LeanIX interoperability)`}).options({project:q,"use-dot":G}).epilog(zr()),handler:async e=>{let t=B(`c4:export`);await Yr({path:e.path,outdir:e.outdir??e.path,allInOne:!!e.allInOne,roundtrip:!!e.roundtrip,uncompressed:!!e.uncompressed,profile:e.profile===`leanix`?`leanix`:`default`,project:e.project,useDot:!!e[`use-dot`]},t)}})}const Zr=`project not found`,Qr=`No projects found`;async function $r(e,t){try{var n=X();let r=V(t),i=n.a(await C(e.path,{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(`${Zr}: ${e.project}`),Error(`${Zr}: ${e.project}`)}else{if(!a(o,1))throw t.error(Qr),Error(Qr);t.info(`${y.dim(`workspace:`)} Found ${o.length} projects`)}let s=[];for(let n of o){let r;if(e.skipLayout?(t.info(`Generate model for project ${y.green(n)} ${y.dim(`(skip layout)`)}`),r=await i.computedModel(n)):(t.info(`Generating layouted model for project ${y.green(n)}`),r=await i.layoutedModel(n)),r===w.EMPTY){t.warn(y.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(`${y.dim(`generated`)} ${d}`),r.stopAndLog(`✓ export in `)}catch(e){n.e=e}finally{await n.d()}}function ei(e){return e.command({command:`json [path]`,describe:`export model(s) to JSON`,builder:e=>e.positional(`path`,W).option(`outfile`,{alias:`o`,type:`string`,desc:`<file> output .json file`,default:`likec4.json`,normalize:!0,coerce:P}).options({project:q,"use-dot":G,"skip-layout":{type:`boolean`,desc:`skip layouting (only compute model)`},pretty:{type:`boolean`,desc:`indented JSON output`}}).epilog(`${y.bold(`Examples:`)}
128
+ ${y.green(`$0 export json --skip-layout`)}
129
+ ${y.gray(`Search for likec4 files in current directory and output JSON to likec4.json (no layout)`)}
130
+
131
+ ${y.green(`$0 export json --pretty -o ./generated/likec4.json src/likec4 `)}
132
+ ${y.gray(`Search for likec4 files in src/likec4 and output JSON to generated/likec4.json`)}
133
+ `),handler:async e=>{let t=B(`c4:export`);await $r({path:e.path,outfile:e.outfile,project:e.project,skipLayout:!!e.skipLayout,pretty:!!e.pretty,useDot:!!e[`use-dot`]},t),Y()}})}var ti=e(ee(),1);function ni(e){if(e.resolvedUrls)return i(e.resolvedUrls.network)??i(e.resolvedUrls.local)}function ri(e){if(!e.resolvedUrls)throw Error(`Vite server is not ready, no resolvedUrls`);H([y.green(`LikeC4 served at:`),``,y.dim(`Local: `)+e.resolvedUrls.local.join(`
134
+ `+``.padEnd(9,` `)),e.resolvedUrls.network.length?y.dim(`Network: `)+e.resolvedUrls.network.join(`
135
+ `+``.padEnd(9,` `)):void 0].filter(e=>u(e)).join(`
136
+ `))}async function ii({buildWebcomponent:e=!0,hmr:t=!0,webcomponentPrefix:n=`likec4`,title:r,languageServices:i,likec4AssetsDir:a,openBrowser:o,listen:s,port:c,...l}){a??=await qe(M(ze(),`.likec4-assets-`));let{isDev:u,...d}=await jt({...l,languageServices:i,likec4AssetsDir:a,webcomponentPrefix:n,title:r}),f=d.customLogger;c??=Be.PORT?parseInt(Be.PORT,10):void 0,c||=await Oe({port:[5173,5174,...De(61e3,61010),...De(62002,62010)]});let p=24678,m=await Dt(),h=s??(T()?`0.0.0.0`:`localhost`);t?(p=await Oe({port:De(24678,24690)}),f.info(`Enabling HMR: localhost:${p}`),T()&&f.info(y.yellow(`ensure port ${p} is published from container`))):f.info(`Disabling HMR`);let g=await ht({...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&&!T())}});return e?(f.info(`Building webcomponent`),Mt({webcomponentPrefix:n,languageServices:i,outDir:m,base:d.base}).then(e=>R({...e,logLevel:`warn`})).catch(e=>{f.warn(_(e)),f.warn(`webcomponent build failed, ignoring error and continue`)})):f.info(`Skip webcomponent build`),await g.listen(),g}async function ai({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(y.cyan(g)+y.dim(` attempt ${h} of ${s} after ${e}ms`)),await _t(e)}else r.hasLayoutDrift&&a.warn(y.yellow(`Drift detected, manual layout can not be applied, view may be invalid: `)+y.red(r.id));let f=`.`;l===`relative`&&(f=r.sourcePath??`.`,f=f.includes(`/`)?f.slice(0,f.lastIndexOf(`/`)):`.`);let m=P(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(te(g,{padding:20,theme:u,dynamic:c})),a.info(y.cyan(g)+y.dim(` -> ${N(i,m)}`)),await d.waitForSelector(`.react-flow.initialized`),r.nodes.some(e=>n(e.icon)&&e.icon.toLowerCase().startsWith(`http`))&&await oi(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(y.red(`failed `+g+`
137
+ `+e)),h<s&&(f.push({view:r,attempt:h+1}),a.info(y.dim(`retry ${g}`))),d=void 0}}return p}async function oi(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 si({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(`${y.dim(`output`)} ${a}`),e.info(`${y.dim(`base url`)} ${t}\n`);let{chromium:u}=await import(`playwright`),d=u.executablePath();e.info(y.cyan(`Start chromium`)+` `+y.dim(d));let f=await u.launch({chromiumSandbox:c,headless:!0});e.info(y.cyan(`Color scheme: `)+n+`
138
+ `);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 ai({browserContext:p,views:i,output:a,outputType:o,logger:e,maxAttempts:s,dynamicVariant:l?`sequence`:`diagram`,timeout:r,theme:n})}finally{e.info(y.cyan(`close chromium`)),await p.close(),await f.close()}}async function ci(e,t){try{var n=X();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 C(r,{graphviz:i?`binary`:`wasm`,watch:!1})),v=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(y.cyan(`start preview server`)),b=await ii({languageServices:_,buildWebcomponent:!1,openBrowser:!1,hmr:!1}),x=ni(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(y.dim(`---------`)),t.info(`${y.dim(`project:`)} ${e.id}`),t.info(`${y.dim(`folder:`)} ${e.folder.fsPath}`));let n=await _.diagrams(e.id);if(m&&a(m,1)&&a(n,1)){let e=(0,ti.default)(m);t.info(`${y.cyan(`filter`)} ${y.dim(JSON.stringify(m))}`),n=n.filter(n=>e(n.id)?(t.info(`${y.green(`include`)} ${n.id} ✅`),!0):(t.info(`${y.gray(`skip`)} ${y.dim(n.id)}`),!1))}if(!a(n,1)){t.warn(`no views found`);continue}let r=S.length>1?ne(re(x,`project`,e.id)):x,i=S.length>1?re(v,e.id):v,c=ct(),u=await si({logger:t,serverUrl:r,theme:s,timeoutMs:f,views:n,output:i,outputType:l,maxAttempts:p,sequence:h,chromiumSandbox:g}),{pretty:b}=xt(c);if(u.length>0&&t.info(y.green(`exported ${u.length} views in ${b}`)+`
139
+ `),u.length!==n.length&&(d&&u.length>0?t.info(y.dim(`ignore`)+` `+y.red(`failed ${n.length-u.length} out of ${n.length} views`)):t.error(y.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(y.cyan(`stop server`)),await b.close().catch(e=>{t.error(e)}))}}catch(e){n.e=e}finally{await n.d()}}async function li(e){await ci(e,B(`c4:export`))}function ui(e){return e.command({command:`png [path]`,describe:`export views to PNG`,builder:e=>e.positional(`path`,W).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:q,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":G,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
140
+ 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(`${y.bold(`Examples:`)}
141
+ ${y.green(`$0 export png`)}
142
+ ${y.gray(`Search for likec4 files in current directory and output PNG next to sources`)}
143
+
144
+ ${y.green(`$0 export png --theme dark -o ./png src/likec4`)}
145
+ ${y.gray(`Search for likec4 files in src/likec4 and output PNG with dark theme to png folder`)}
146
+
147
+ ${y.green(`$0 export png -f "team1*" -f "team2*" --flat -o ./png src/likec4`)}
148
+ ${y.gray(`Export views matching team1* or team2* only`)}
149
+
150
+ ${y.green(`$0 export png -f "use-case*" --sequence src/likec4`)}
151
+ ${y.gray(`Export views matching use-case* using sequence layout`)}
152
+ `),handler:async e=>{Ie(e.timeout>=1,`timeout must be >= 1`),Ie(e[`max-attempts`]>=1,`max-attempts must be >= 1`),await U(),await It();let t=e.theme??(e.dark?`dark`:`light`);await li({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`]}),Y()}})}const di=e=>e.command({command:`export <format> [path]`,describe:`Export to images, JSON, or DrawIO`,builder:e=>o(e.usage(`${y.bold(`Usage:`)} $0 export <format> [path]`),ui,ei,Xr).updateStrings({"Commands:":y.bold(`Formats:`)}),handler:()=>void 0}),fi=e=>e.command({command:`format [path]`,aliases:[`fmt`],describe:`Format LikeC4 source files`,builder:e=>e.positional(`path`,W).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=>P(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=X();let n=B(`c4:format`),r=V(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=>ft(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(` ${L(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=N(l,e);return t.startsWith(`..`)?e:t};if(s){let e=s.filter(e=>!c.has(e));for(let t of e)n.warn(`${y.yellow(`skipped`)} ${u(L(t))} (not found in workspace)`)}let d=0,f=0,p=[];for(let[e,t]of c){let r=L(e),a=u(r),o;try{o=await O(r,`utf-8`)}catch(e){n.error(`Failed to read ${a}: ${e}`),f++;continue}if(o===t){n.debug(`${y.dim(`unchanged`)} ${a}`);continue}if(d++,p.push(a),i)n.info(`${y.yellow(`needs formatting`)} ${a}`);else try{await k(r,t,`utf-8`),n.info(`${y.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(`
153
+ `)}`),process.exitCode=1;return}n.info(y.green(`All ${c.size} file(s) are formatted`))}else d>0?n.info(`${y.green(String(d))} of ${c.size} file(s) formatted`):n.info(y.green(`All ${c.size} file(s) already formatted`));r.stopAndLog(`✓ format in `)}catch(e){t.e=e}finally{await t.d()}}});var pi=ke();function mi(e){return e.command({command:`lsp`,aliases:[],describe:`Start LSP server`,builder:e=>e.usage(`${y.bold(`Usage:`)} $0 lsp`).option(`log-level`,Gt).option(`verbose`,Kt).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`,G).showHidden().epilog(`${y.bold(`Examples:`)}
154
+
155
+ ${y.green(`$0 lsp --stdio `)}
156
+ ${y.gray(`Start LSP with stdio transport`)}
157
+
158
+ ${y.green(`$0 lsp --node-ipc --watch --no-manual-layouts --no-color `)}
159
+ ${y.gray(`Start LSP with node-ipc transport and watcher, disabled manual layouts and disabled color`)}
160
+
161
+ `),handler:e=>{let t;if(e.nodeIpc||e.stdio||e.socket||e.pipe)t=(0,pi.createConnection)(pi.ProposedFeatures.all);else throw Error(`No transport specified`);h({lspConnection:t,useStdErr:e.stdio===!0,colors:y.isColorSupported,enableTelemetry:e.telemetry,logLevel:e.verbose?qt:e.logLevel}),m({connection:t,enableManualLayouts:e.manualLayouts,enableWatcher:e.watch,graphviz:e.useDot?`binary`:`wasm`,configureLogger:!1})}})}const hi=e=>e.command({command:`mcp [path]`,aliases:[],describe:`Start MCP server`,builder:e=>e.usage(`${y.bold(`Usage:`)} $0 mcp [path]`).positional(`path`,W).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`,G).option(`log-level`,Gt).option(`verbose`,Kt).showHidden().epilog(`${y.bold(`Examples:`)}
162
+ ${y.green(`$0 mcp`)}
163
+ ${y.gray(`Start MCP with default stdio transport`)}
164
+ ${y.green(`$0 mcp --http ./src`)}
165
+ ${y.gray(`Start MCP with streamable http transport on port 33335 at ./src folder`)}
166
+ ${y.green(`$0 mcp -p 1234`)}
167
+ ${y.gray(`Start MCP with streamable http transport on port 1234`)}
168
+ `),handler:async e=>{e.http||e.port?(h({colors:y.isColorSupported,logLevel:e.verbose?qt:e.logLevel}),await gi(e.path,e.useDot,e.port)):(h({useStdErr:!0,logLevel:e.verbose?qt:e.logLevel}),await _i(e.path,e.useDot))}});async function gi(e,t,n=33335){await Ee(e,{mcp:{port:n},watch:!0,configureLogger:!1,graphviz:t?`binary`:`wasm`}),H([y.green(`LikeC4 MCP served at:`),`
98
169
  {
99
170
  "mcpServers": {
100
171
  "likec4": {
@@ -103,9 +174,18 @@ ${v.green(`$0 mcp -p 1234`)}
103
174
  }
104
175
  }
105
176
 
106
- ${v.dim(`Documentation:`)}
107
- ${v.underline(`https://likec4.dev/tooling/mcp/#using-extension`)}
177
+ ${y.dim(`Documentation:`)}
178
+ ${y.underline(`https://likec4.dev/tooling/mcp/#using-extension`)}
108
179
  `].join(`
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{};
180
+ `))}async function _i(e,t){await Ee(e,{mcp:`stdio`,watch:!0,configureLogger:!1,graphviz:t?`binary`:`wasm`})}async function vi(e){let t=await jt({...e,likec4AssetsDir:``,webcomponentPrefix:void 0}),n=await Oe({port:De(62001,62010)}),r=e?.open??!1;return await gt({...t,customLogger:t.customLogger,mode:`production`,preview:{host:e.listen??`127.0.0.1`,allowedHosts:!0,port:n,open:r}})}async function yi({path:e,output:t,base:n,listen:r}){ri(await vi({base:n,languageServices:await C(e,{watch:!1}),outputDir:t,open:!T(),listen:r}))}const bi=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
181
+ 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 yi(e)}});async function xi({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 ii({buildWebcomponent:a,hmr:o,base:s,webcomponentPrefix:n,title:r,languageServices:await C(e,{graphviz:t?`binary`:`wasm`,watch:o}),useHashHistory:i,likec4AssetsDir:await qe(M(ze(),`.likec4-assets-`)),listen:c,port:l});u.config.logger.clearScreen(`info`),ri(u),vt(Y,1e3).unref()}const Si=e=>e.command({command:`start [path]`,aliases:[`serve`,`dev`],describe:`Start local dev server to preview LikeC4 views`,builder:e=>e.positional(`path`,W).option(`base`,Vt).option(`webcomponent-prefix`,zt).option(`title`,Bt).option(`use-hash-history`,Rt).option(`use-dot`,G).option(`listen`,Ut).option(`port`,Wt).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 U(),await xi({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`]})}});async function Ci(e,t,n,r){let i=await Kn(t,n,{idempotent:!0}),a=P(e,`sync-plan.json`);if(await k(a,JSON.stringify(i,null,2)),r.info(`${y.dim(`generated`)} ${N(process.cwd(),a)}`),i.errors.length>0){let e=`${i.errors.length} plan error(s): ${i.errors.join(`; `)}`;throw r.error(e),Error(e)}}async function wi(e,t,n,r){let i=await qn(t.manifest,t.dryRun,n,{idempotent:!0}),a=P(e,yr.manifest);if(await k(a,JSON.stringify(i.manifest,null,2)),r.info(`${y.dim(`generated`)} ${N(process.cwd(),a)} (after sync)`),i.errors.length>0){let e=`${i.errors.length} sync error(s): ${i.errors.join(`; `)}`;throw r.error(e),Error(e)}}async function Ti(e){let t=B(`c4:sync:leanix`),n=V(t),{path:r,outdir:i,project:a,useDotBin:o,dryRun:s,apply:c}=e;try{try{var l=X();if(s&&c)throw Error(`Choose either dryRun or apply, not both`);let e=l.a(await C(r,{graphviz:o?`binary`:`wasm`,watch:!1})),{projectId:n}=Z(e,a);a&&t.info(`${y.dim(`project`)} ${y.green(n)}`);let u=await e.layoutedModel(n);if(u===w.EMPTY)throw t.error(ur),Error(ur);let d=_r(gr(u));await vr(i,d,t);let f=xr();if((s||!c)&&(f?await Ci(i,d.dryRun,f,t):t.info(`${y.dim(`skip`)} sync-plan (set LEANIX_API_TOKEN to include plan)`)),c){if(!f)throw t.error(dr),Error(dr);await wi(i,d,f,t)}}catch(e){l.e=e}finally{await l.d()}}finally{n.stopAndLog()}}const Ei=P(process.cwd(),`out`,`bridge`);function Di(e){return typeof e!=`object`||!e||!Object.hasOwn(e,`target`)?!1:typeof Reflect.get(e,`target`)==`string`}function Oi(e){return e.command({command:`sync <target> [path]`,describe:`Sync bridge artifacts (e.g. LeanIX)`,builder:e=>e.positional(`target`,{type:`string`,choices:[`leanix`],describe:`Target system (leanix)`}).positional(`path`,W).option(`outdir`,{...K,default:Ei,desc:`<dir> output directory for bridge artifacts (manifest, leanix-dry-run, report, sync-plan)`}).option(`dry-run`,{type:`boolean`,describe:`Only write artifacts and optional sync-plan; do not call LeanIX API for create/update`}).option(`apply`,{type:`boolean`,describe:`Run live sync to LeanIX (requires LEANIX_API_TOKEN)`}).conflicts(`dry-run`,`apply`).option(`project`,q).option(`use-dot`,G).example(`${y.green(`$0 sync leanix --dry-run -o out/bridge`)}`,y.gray(`Write bridge artifacts and optionally sync-plan when LEANIX_API_TOKEN is set`)).example(`${y.green(`$0 sync leanix --apply -o out/bridge`)}`,y.gray(`Write artifacts then run live sync; updates manifest with LeanIX IDs`)),handler:async e=>{if(!Di(e)||e.target!==`leanix`)return;let t=e.apply??!1,n=e.dryRun??!t;await Ti({path:e.path??`.`,outdir:e.outdir??Ei,project:e.project,useDotBin:e.useDotBin??!1,dryRun:n,apply:t})}})}const ki=e=>e.command({command:`validate [path]`,aliases:[],describe:`Validate syntax, semantics and layout drifts`,builder:e=>e.positional(`path`,W).options({project:q,file:{alias:`f`,array:!0,string:!0,description:`only report errors from these files (can be specified multiple times)`},layout:{boolean:!0,default:!0,defaultDescription:`enabled`,description:`force layout validation, or disable with --no-layout`},json:{boolean:!0,nargs:0,description:`output as JSON (structured)`}}).showHidden().epilog(`${y.bold(`Examples:`)}
182
+ ${y.green(`$0 validate `)}
183
+ ${y.gray(`Validate all in the current directory`)}
184
+
185
+ ${y.green(`$0 validate --no-layout --json -f ./src/model.c4 -f ./src/deployment.c4 `)}
186
+ ${y.gray([`Validate all`,`ignore layout drifts`,`report only errors from these files`,`output as JSON`].join(`, `))}
187
+
188
+ ${y.green(`$0 validate --project my-project /some/where`)}
189
+ ${y.gray(`Validate my-project in /some/where`)}
190
+ `),handler:async e=>{try{var t=X();let n=B(`c4:validate`),r=V(n),i=e.json===!0,a=e.layout===!0,o=e.file?.map(e=>P(e))??null,s=t.a(await C(e.path,{watch:!1,printErrors:!i,throwIfInvalid:!1,configureLogger:i?`stderr`:!1})),c=s.getErrors().map(e=>({message:e.message,file:e.sourceFsPath,line:e.line,range:e.range})),l=[];if(a){n.debug(`running layout validation...`);try{let t=await s.diagrams(e.project);for(let n of t)n.drifts&&n.drifts.length>0&&l.push({message:`Layout drift detected on view '${n.id}'`,file:n.sourcePath?P(e.path,n.sourcePath):``,line:0,range:null})}catch(e){l.push({message:`Layout validation failed: ${e instanceof Error?e.message:String(e)}`,file:``,line:0,range:null})}}let u=[...c,...l],d=s.documentCount(),f=u.length,p=o?u.filter(e=>o.some(t=>e.file===t||e.file.endsWith(`/`+t)||e.file.endsWith(`\\`+t))):u,m=new Set(p.map(e=>e.file)),h=p.length===0;process.exitCode=h?0:1;let g={valid:h,errors:p,stats:{totalFiles:d,totalErrors:f,filteredFiles:o?m.size:d,filteredErrors:p.length}};if(i){console.log(JSON.stringify(g,null,2));return}for(let e of l)n.error(y.red(e.message)+(e.file?` at `+e.file:``));if(h)n.info(y.green(`✓ Valid`)+y.dim(` (${d} files)`));else{let e=o?`, ${p.length} in filtered files`:``;n.error(y.red(`✗ Invalid`)+y.dim(` (${d} files, ${f} errors${e})`))}r.stopAndLog(`validate `)}catch(e){t.e=e}finally{await t.d()}}});function Ai(e){let t=e??(He?`trace`:`info`);p({reset:!0,sinks:{console:g({formatter:y.isColorSupported?v():f()})},loggers:[{category:`likec4`,sinks:[`console`],lowestLevel:t}]})}async function ji(){!We&&!Ve&&!T()&&await en(),await o(ut(dt(ot)),Si,Zt,Nr,di,fi,bi,Oi,ki,hi,mi,rn,e=>e.command({command:`completion`,describe:`Generate completion script`,handler:()=>{e.showCompletionScript()}})).scriptName(`likec4`).usage(`Usage: $0 <command>`).version(bt).alias(`v`,`version`).alias(`h`,`help`).help(`help`).option(`log-level`,Gt).option(`verbose`,Kt).option(`color`,{boolean:!0,describe:[`force color output, or disable with --no-color`,`respects 'FORCE_COLOR' and 'NO_COLOR' env variables`].join(`
191
+ `),skipValidation:!0,hidden:!0,global:!0}).group([`log-level`,`verbose`,`color`,`help`,`version`,`show-hidden`],`Globals:`).demandCommand(1,`Please run with valid command`).recommendCommands().showHelpOnFail(!0).showHidden().updateStrings({"Globals:":y.bold(`Globals:`),"Options:":y.bold(`Options:`),"Positionals:":y.bold(`Arguments:`),"Commands:":y.bold(`Commands:`),"Examples:":y.bold(`Examples:`)}).wrap(t(lt.columns-10,{min:60,max:180})).middleware(e=>{Ai(e.verbose?qt:e.logLevel)}).parseAsync()}function Mi(e,t){console.error(t==null?_(e):`${t} ${_(e)}`),st(1)}ji().catch(Mi),process.on(`unhandledRejection`,e=>{Mi(e,`Unhandled rejection:`)}),process.on(`uncaughtException`,e=>{console.error(e)});export{};