@likec4/language-server 1.50.0 → 1.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -25
  3. package/bin/likec4-language-server.mjs +2 -3
  4. package/dist/_chunks/LikeC4FileSystem.mjs +2 -2
  5. package/dist/_chunks/{WithMCPServer.mjs → mcp.mjs} +5 -5
  6. package/dist/_chunks/module.d.mts +88 -26
  7. package/dist/_chunks/module.mjs +20 -19
  8. package/dist/_chunks/utils.mjs +1 -1
  9. package/dist/_chunks/workspace.mjs +1 -1
  10. package/dist/browser/index.d.mts +2 -2
  11. package/dist/browser/index.mjs +1 -1
  12. package/dist/browser/worker.mjs +1 -1
  13. package/dist/filesystem/index.d.mts +1 -1
  14. package/dist/filesystem/index.mjs +1 -1
  15. package/dist/index.d.mts +2 -2
  16. package/dist/index.mjs +1 -1
  17. package/dist/mcp/index.d.mts +1 -1
  18. package/dist/mcp/index.mjs +1 -1
  19. package/dist/module.d.mts +2 -2
  20. package/dist/module.mjs +1 -1
  21. package/package.json +19 -29
  22. package/bundled/package.json +0 -4
  23. package/dist/THIRD-PARTY-LICENSES.md +0 -178
  24. package/dist/_chunks/ConfigurableLayouter.mjs +0 -1
  25. package/dist/_chunks/libs/@msgpack/msgpack.mjs +0 -1
  26. package/dist/_chunks/libs/eventemitter3.mjs +0 -1
  27. package/dist/_chunks/libs/fast-equals.mjs +0 -1
  28. package/dist/_chunks/libs/p-queue.mjs +0 -1
  29. package/dist/_chunks/libs/parse-ms.mjs +0 -1
  30. package/dist/_chunks/libs/picomatch.mjs +0 -1
  31. package/dist/_chunks/libs/pretty-ms.mjs +0 -1
  32. package/dist/_chunks/libs/remeda.mjs +0 -2
  33. package/dist/_chunks/libs/strip-indent.mjs +0 -1
  34. package/dist/_chunks/libs/ufo.mjs +0 -1
  35. package/dist/_chunks/rolldown-runtime.mjs +0 -1
  36. package/dist/bundled.d.mts +0 -27
  37. package/dist/bundled.mjs +0 -1
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023-2026 Denis Davydkov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,31 +1,11 @@
1
1
  # `@likec4/language-server`
2
2
 
3
- [docs](https://likec4.dev/) | [playground](https://playground.likec4.dev/) | [demo](https://template.likec4.dev/view/index/)
3
+ LikeC4 Language Server Protocol (LSP) based on [langium](https://github.com/langium/langium) library.
4
4
 
5
- Language Server Protocol (LSP) based on [langium](https://github.com/langium/langium) library.
6
-
7
- ## Usage
8
-
9
- ```bash
10
- npm install -g @likec4/language-server
11
- likec4-language-server --stdio
12
- ```
13
-
14
- Valid arguments:
15
-
16
- - `--node-ipc`
17
- - `--stdio`
18
- - `--socket={number}`
19
-
20
- ### Usage in code
21
-
22
- ```js
23
- import { startLanguageServer } from '@likec4/language-server/bundled'
24
- startLanguageServer().catch((e) => {
25
- console.error(e)
26
- process.exit(1)
27
- })
28
- ```
5
+ > [!WARNING]
6
+ > **This package is intended for internal use within other LikeC4 packages.**
7
+ >
8
+ > Please use the main [`likec4`](https://www.npmjs.com/package/likec4) package instead.
29
9
 
30
10
  ## Getting help
31
11
 
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { startLanguageServer } from '../dist/bundled.mjs'
4
-
5
- startLanguageServer()
3
+ console.error('This package is not available as a standalone LSP server. Use `likec4 lsp` instead.')
4
+ process.exit(1)
@@ -1,3 +1,3 @@
1
- import{a as e,r as t}from"./likec4lib.mjs";import{n}from"./noop.mjs";import{Er as r,n as i,r as a,t as o}from"./utils.mjs";import{t as s}from"./libs/p-queue.mjs";import{D as c,o as l}from"./libs/remeda.mjs";import{isLikeC4Config as u,loadConfig as d}from"@likec4/config/node";import{fdir as f}from"fdir";import{SimpleCache as p,URI as m,UriUtils as h}from"langium";import{NodeFileSystemProvider as g}from"langium/node";import{mkdirSync as _,statSync as v}from"node:fs";import{unlink as y,writeFile as b}from"node:fs/promises";import{basename as x,dirname as S}from"node:path";import{objectHash as C,onNextTick as w}from"@likec4/core/utils";import T from"chokidar";import E from"json5";import{Position as D,Range as O}from"vscode-languageserver-types";const k=r.getChild(`manual-layouts`),isManualLayoutFile=e=>e.endsWith(`.likec4.snap`);function fileName(e){return`${e}.likec4.snap`}function getManualLayoutsOutDir(e){return h.resolvePath(e.folderUri,e.config.manualLayouts?.outDir??`.likec4`)}const A={manualLayouts:e=>new DefaultLikeC4ManualLayouts(e)},j=`file://./`;var DefaultLikeC4ManualLayouts=class{cache;constructor(e){this.services=e,this.cache=new p,w(()=>{e.workspace.ProjectsManager.onProjectsUpdate(()=>{this.clearCaches()})})}async read(e){return await this.cache.get(e.id,async()=>{let t=k.getChild(e.id),n=this.services.workspace.FileSystemProvider,r=getManualLayoutsOutDir(e),i=[];try{let a=await n.scanDirectory(r,isManualLayoutFile);if(a.length===0)return null;for(let r of a)try{let t=await n.readFile(r.uri),a=E.parse(t),o=this.resolveIconPathsAfterRead(a,e.folderUri);i.push({...o,_layout:`manual`})}catch(e){t.warn(`Failed to read view snapshot ${r.uri.fsPath}`,{err:e})}i.length&&t.debug`read manual layouts for ${e.id}, found ${i.length}`}catch(n){t.warn(`Failed to read manual layouts for ${e.folderUri.fsPath}`,{err:n})}if(i.length===0)return null;let a=c(i,l(`id`));return{hash:C(a),views:a}})}async write(e,t){let n=k.getChild(e.id),r=getManualLayoutsOutDir(e),i=h.joinPath(r,fileName(t.id));if(`manualLayout`in t){let{manualLayout:e,...n}=t;t=n}let a=E.stringify(this.normalizeIconPathsForWrite(t,e.folderUri),{space:2,quote:`'`}),o={uri:i.toString(),range:O.create(D.create(0,0),D.create(a.split(`
1
+ import{a as e,r as t}from"./likec4lib.mjs";import{n}from"./noop.mjs";import{Tr as r,n as i,r as a,t as o}from"./utils.mjs";import{isLikeC4Config as s,loadConfig as c}from"@likec4/config/node";import{fdir as l}from"fdir";import{SimpleCache as u,URI as d,UriUtils as f}from"langium";import{NodeFileSystemProvider as p}from"langium/node";import{mkdirSync as m,statSync as h}from"node:fs";import{unlink as g,writeFile as _}from"node:fs/promises";import{basename as v,dirname as y}from"node:path";import{objectHash as b,onNextTick as x}from"@likec4/core/utils";import S from"chokidar";import C from"p-queue";import w from"json5";import{indexBy as T,prop as E}from"remeda";import{Position as D,Range as O}from"vscode-languageserver-types";const k=r.getChild(`manual-layouts`),isManualLayoutFile=e=>e.endsWith(`.likec4.snap`);function fileName(e){return`${e}.likec4.snap`}function getManualLayoutsOutDir(e){return f.resolvePath(e.folderUri,e.config.manualLayouts?.outDir??`.likec4`)}const A={manualLayouts:e=>new DefaultLikeC4ManualLayouts(e)},j=`file://./`;var DefaultLikeC4ManualLayouts=class{cache;constructor(e){this.services=e,this.cache=new u,x(()=>{e.workspace.ProjectsManager.onProjectsUpdate(()=>{this.clearCaches()})})}async read(e){return await this.cache.get(e.id,async()=>{let t=k.getChild(e.id),n=this.services.workspace.FileSystemProvider,r=getManualLayoutsOutDir(e),i=[];try{let a=await n.scanDirectory(r,isManualLayoutFile);if(a.length===0)return null;for(let r of a)try{let t=await n.readFile(r.uri),a=w.parse(t),o=this.resolveIconPathsAfterRead(a,e.folderUri);i.push({...o,_layout:`manual`})}catch(e){t.warn(`Failed to read view snapshot ${r.uri.fsPath}`,{err:e})}i.length&&t.debug`read manual layouts for ${e.id}, found ${i.length}`}catch(n){t.warn(`Failed to read manual layouts for ${e.folderUri.fsPath}`,{err:n})}if(i.length===0)return null;let a=T(i,E(`id`));return{hash:b(a),views:a}})}async write(e,t){this.cache.delete(e.id);let n=k.getChild(e.id),r=getManualLayoutsOutDir(e),i=f.joinPath(r,fileName(t.id));if(`manualLayout`in t){let{manualLayout:e,...n}=t;t=n}let a=w.stringify(this.normalizeIconPathsForWrite(t,e.folderUri),{space:2,quote:`'`}),o={uri:i.toString(),range:O.create(D.create(0,0),D.create(a.split(`
2
2
  `).length-1,1))};n.debug`write snapshot of ${t.id} in project ${e.id} to ${i.fsPath}`;let s=this.services.workspace.FileSystemProvider;try{await s.writeFile(i,a+`
3
- `)}catch(e){n.warn(`Failed to write snapshot ${t.id} to ${i.fsPath}`,{err:e})}return this.cache.delete(e.id),o}async remove(e,t){let n=k.getChild(e.id),r=getManualLayoutsOutDir(e),i=h.joinPath(r,fileName(t));n.debug`delete snapshot of ${t} in project ${e.id}. File: ${i.fsPath}`;let a={uri:i.toString(),range:O.create(0,0,0,0)};this.cache.delete(e.id);try{if(!await this.services.workspace.FileSystemProvider.deleteFile(i))return n.warn`Snapshot ${t} did not exist at ${i.fsPath}`,null}catch(e){n.warn(`Failed to delete snapshot ${t} from ${i.fsPath}`,{err:e})}return a}clearCaches(){k.trace`clear caches`,this.cache.clear()}normalizeIconPathsForWrite(e,t){let n=e.nodes.map(e=>{if(!e.icon||typeof e.icon!=`string`)return e;if(e.icon.startsWith(`file://`)){let n=m.parse(e.icon),r=h.relative(t,n);return r.startsWith(`..`)?e:{...e,icon:`${j}${r}`}}return e});return{...e,nodes:n}}resolveIconPathsAfterRead(e,t){let n=e.nodes.map(e=>{if(!e.icon||typeof e.icon!=`string`)return e;if(e.icon.startsWith(j)){let n=e.icon.substring(9),r=h.joinPath(t,n);return{...e,icon:r.toString()}}return e});return{...e,nodes:n}}};const M=r.getChild(`chokidar`),N={fileSystemWatcher:e=>new ChokidarFileSystemWatcher(e)},isAnyLikeC4File=e=>{let t=x(e);return a(t)||u(t)||isManualLayoutFile(t)};var ChokidarFileSystemWatcher=class{watcher;queue=new s({concurrency:1,timeout:5e3});constructor(e){this.services=e}watch(e){if(this.watcher){M.debug`add watching folder: ${e}`,this.watcher.add(e);return}this.watcher=this.createWatcher(e)}async dispose(){if(this.watcher){let e=this.watcher;this.watcher=void 0,await e.close()}}createWatcher(e){M.debug`create watcher for folder: ${e}`;let t=T.watch(e,{ignored:[e=>e.includes(`node_modules`)||e.includes(`.git`),(e,t)=>!!t?.isFile()&&!isAnyLikeC4File(e)],followSymlinks:!0,ignoreInitial:!0}),onAddOrChange=(e,t)=>{t?.isDirectory()||this.enqueueFileOp(`addOrChange: `+e,async()=>{await this.onAddOrChange(e)})};return t.on(`add`,onAddOrChange).on(`change`,onAddOrChange).on(`unlink`,(e,t)=>{t?.isDirectory()||this.enqueueFileOp(`remove: `+e,async()=>{await this.onRemove(e)})}).on(`unlinkDir`,e=>{this.enqueueFileOp(`removeDir: `+e,async()=>{await this.onRemoveDir(e)})}),t}enqueueFileOp(e,t){this.queue.add(async()=>{try{await t()}catch(t){M.warn(`Failed on {fileop}`,{fileop:e,error:t})}}).catch(t=>{M.error(`Error on {fileop}`,{fileop:e,error:t})})}async onAddOrChange(e){let t=this.services.workspace,n=x(e),r=m.file(e);switch(!0){case u(n):M.debug`project file changed: ${e}`,t.ManualLayouts.clearCaches(),await t.ProjectsManager.registerConfigFile(r);break;case a(n):M.debug`file changed: ${e}`,await t.DocumentBuilder.update([r],[]);break;case isManualLayoutFile(n):{M.debug`manual layout file changed: ${e}`,t.ManualLayouts.clearCaches();let n=t.ProjectsManager.ownerProjectId(r);await t.ProjectsManager.rebuildProject(n);break}default:M.warn`Unknown file change: ${e}`}}async onRemove(e){let t=this.services.workspace,n=x(e),r=m.file(e);switch(!0){case u(n):M.debug`project file removed: ${e}`,t.ManualLayouts.clearCaches(),await t.ProjectsManager.reloadProjects();break;case a(n):M.debug`file removed: ${e}`,await t.DocumentBuilder.update([],[r]);break;case isManualLayoutFile(n):{M.debug`manual layout file removed: ${e}`;let n=t.ProjectsManager.ownerProjectId(r);t.ManualLayouts.clearCaches(),await t.ProjectsManager.rebuildProject(n);break}default:M.warn`Unknown file removal: ${e}`}}async onRemoveDir(e){M.debug`directory removed: ${e}`;let t=this.services.workspace;t.ProjectsManager.findOverlaped(e).length>0&&(t.ManualLayouts.clearCaches(),await t.ProjectsManager.reloadProjects())}};const P=r.getChild(`filesystem`);function isLikeC4ConfigFile(e,t=!1){return!t&&u(x(e))}function isLikeC4File(e,t=!1){return!t&&a(x(e))}const WithFileSystem=(e=!0)=>({fileSystemProvider:()=>new SymLinkTraversingFileSystemProvider,...e?N:n});var SymLinkTraversingFileSystemProvider=class extends g{async readFile(n){if(t(n))return Promise.resolve(e);try{return await super.readFile(n)}catch(e){return P.warn(`Failed to read file ${n.fsPath}`,{error:e}),``}}async readDirectory(e,t){let n=t?.recursive??!0,r=t?.maxDepth??1/0,a=[];try{let t=new f().withSymlinks({resolvePaths:!1}).exclude(i).withFullPaths().filter(isLikeC4File);n?r!==1/0&&(t=t.withMaxDepth(r)):t=t.withMaxDepth(1);let o=await t.crawl(e.fsPath).withPromise();for(let e of o)a.push({isFile:!0,isDirectory:!1,uri:m.file(e)})}catch(t){P.warn(`Failed to read directory ${e.fsPath}`,{error:t})}return a.sort(o)}async scanProjectFiles(e){return await this.scanDirectory(e,isLikeC4ConfigFile)}async scanDirectory(e,t){let n=[];try{let r=await new f().withSymlinks({resolvePaths:!1}).exclude(i).withFullPaths().filter(t).crawl(e.fsPath).withPromise();for(let e of r)n.push({isFile:!0,isDirectory:!1,uri:m.file(e)})}catch(t){P.warn(`Failed to scan directory {path}`,{path:e.fsPath,error:t})}return n}async loadProjectConfig(e){return await d(e)}async writeFile(e,t){let n=S(e.fsPath),r=v(n,{throwIfNoEntry:!1});if(r?.isFile())throw Error(`Cannot create directory ${n} because a file with the same name exists.`);return r||(P.debug(`creating directory {path}`,{path:n}),_(n,{recursive:!0})),P.debug(`writing file {path}`,{path:e.fsPath}),await b(e.fsPath,t,{encoding:`utf-8`})}async deleteFile(e){try{let t=e.fsPath,n=v(t,{throwIfNoEntry:!1});return n?.isFile()||n?.isSymbolicLink()?(await y(t),P.debug(`deleted file {path}`,{path:t}),!0):(P.warn(`deleteFile failed: {path} does not exist, or is not a file`,{path:t}),!1)}catch(t){P.warn(`Failed to delete file ${e.fsPath}`,{error:t})}return!1}};export{N as n,A as r,WithFileSystem as t};
3
+ `)}catch(e){n.warn(`Failed to write snapshot ${t.id} to ${i.fsPath}`,{err:e})}return o}async remove(e,t){this.cache.delete(e.id);let n=k.getChild(e.id),r=getManualLayoutsOutDir(e),i=f.joinPath(r,fileName(t));n.debug`delete snapshot of ${t} in project ${e.id}. File: ${i.fsPath}`;let a={uri:i.toString(),range:O.create(0,0,0,0)};try{if(!await this.services.workspace.FileSystemProvider.deleteFile(i))return n.warn`Snapshot ${t} did not exist at ${i.fsPath}`,null}catch(e){n.warn(`Failed to delete snapshot ${t} from ${i.fsPath}`,{err:e})}return a}clearCaches(){k.trace`clear caches`,this.cache.clear()}normalizeIconPathsForWrite(e,t){let n=e.nodes.map(e=>{if(!e.icon||typeof e.icon!=`string`)return e;if(e.icon.startsWith(`file://`)){let n=d.parse(e.icon),r=f.relative(t,n);return r.startsWith(`..`)?e:{...e,icon:`${j}${r}`}}return e});return{...e,nodes:n}}resolveIconPathsAfterRead(e,t){let n=e.nodes.map(e=>{if(!e.icon||typeof e.icon!=`string`)return e;if(e.icon.startsWith(j)){let n=e.icon.substring(9),r=f.joinPath(t,n);return{...e,icon:r.toString()}}return e});return{...e,nodes:n}}};const M=r.getChild(`chokidar`),N={fileSystemWatcher:e=>new ChokidarFileSystemWatcher(e)},isAnyLikeC4File=e=>{let t=v(e);return a(t)||s(t)||isManualLayoutFile(t)};var ChokidarFileSystemWatcher=class{watcher;queue=new C({concurrency:1,timeout:5e3});constructor(e){this.services=e}watch(e){if(this.watcher){M.debug`add watching folder: ${e}`,this.watcher.add(e);return}this.watcher=this.createWatcher(e)}async dispose(){if(this.watcher){let e=this.watcher;this.watcher=void 0,await e.close()}}createWatcher(e){M.debug`create watcher for folder: ${e}`;let t=S.watch(e,{ignored:[e=>e.includes(`node_modules`)||e.includes(`.git`),(e,t)=>!!t?.isFile()&&!isAnyLikeC4File(e)],followSymlinks:!0,ignoreInitial:!0}),onAddOrChange=(e,t)=>{t?.isDirectory()||this.enqueueFileOp(`addOrChange: `+e,async()=>{await this.onAddOrChange(e)})};return t.on(`add`,onAddOrChange).on(`change`,onAddOrChange).on(`unlink`,(e,t)=>{t?.isDirectory()||this.enqueueFileOp(`remove: `+e,async()=>{await this.onRemove(e)})}).on(`unlinkDir`,e=>{this.enqueueFileOp(`removeDir: `+e,async()=>{await this.onRemoveDir(e)})}),t}enqueueFileOp(e,t){this.queue.add(async()=>{try{await t()}catch(t){M.warn(`Failed on {fileop}`,{fileop:e,error:t})}}).catch(t=>{M.error(`Error on {fileop}`,{fileop:e,error:t})})}async onAddOrChange(e){let t=this.services.workspace,n=v(e),r=d.file(e);switch(!0){case s(n):M.debug`project file changed: ${e}`,t.ManualLayouts.clearCaches(),await t.ProjectsManager.registerConfigFile(r);break;case a(n):M.debug`file changed: ${e}`,await t.DocumentBuilder.update([r],[]);break;case isManualLayoutFile(n):{M.debug`manual layout file changed: ${e}`,t.ManualLayouts.clearCaches();let n=t.ProjectsManager.ownerProjectId(r);await t.ProjectsManager.rebuildProject(n);break}default:M.warn`Unknown file change: ${e}`}}async onRemove(e){let t=this.services.workspace,n=v(e),r=d.file(e);switch(!0){case s(n):M.debug`project file removed: ${e}`,t.ManualLayouts.clearCaches(),await t.ProjectsManager.reloadProjects();break;case a(n):M.debug`file removed: ${e}`,await t.DocumentBuilder.update([],[r]);break;case isManualLayoutFile(n):{M.debug`manual layout file removed: ${e}`;let n=t.ProjectsManager.ownerProjectId(r);t.ManualLayouts.clearCaches(),await t.ProjectsManager.rebuildProject(n);break}default:M.warn`Unknown file removal: ${e}`}}async onRemoveDir(e){M.debug`directory removed: ${e}`;let t=this.services.workspace;t.ProjectsManager.findOverlaped(e).length>0&&(t.ManualLayouts.clearCaches(),await t.ProjectsManager.reloadProjects())}};const P=r.getChild(`filesystem`);function isLikeC4ConfigFile(e,t=!1){return!t&&s(v(e))}function isLikeC4File(e,t=!1){return!t&&a(v(e))}const WithFileSystem=(e=!0)=>({fileSystemProvider:()=>new SymLinkTraversingFileSystemProvider,...e?N:n});var SymLinkTraversingFileSystemProvider=class extends p{async readFile(n){if(t(n))return Promise.resolve(e);try{return await super.readFile(n)}catch(e){return P.warn(`Failed to read file ${n.fsPath}`,{error:e}),``}}async readDirectory(e,t){let n=t?.recursive??!0,r=t?.maxDepth??1/0,a=[];try{let t=new l().withSymlinks({resolvePaths:!1}).exclude(i).withFullPaths().filter(isLikeC4File);n?r!==1/0&&(t=t.withMaxDepth(r)):t=t.withMaxDepth(1);let o=await t.crawl(e.fsPath).withPromise();for(let e of o)a.push({isFile:!0,isDirectory:!1,uri:d.file(e)})}catch(t){P.warn(`Failed to read directory ${e.fsPath}`,{error:t})}return a.sort(o)}async scanProjectFiles(e){return await this.scanDirectory(e,isLikeC4ConfigFile)}async scanDirectory(e,t){let n=[];try{let r=await new l().withSymlinks({resolvePaths:!1}).exclude(i).withFullPaths().filter(t).crawl(e.fsPath).withPromise();for(let e of r)n.push({isFile:!0,isDirectory:!1,uri:d.file(e)})}catch(t){P.warn(`Failed to scan directory {path}`,{path:e.fsPath,error:t})}return n}async loadProjectConfig(e){return await c(e)}async writeFile(e,t){let n=y(e.fsPath),r=h(n,{throwIfNoEntry:!1});if(r?.isFile())throw Error(`Cannot create directory ${n} because a file with the same name exists.`);return r||(P.debug(`creating directory {path}`,{path:n}),m(n,{recursive:!0})),P.debug(`writing file {path}`,{path:e.fsPath}),await _(e.fsPath,t,{encoding:`utf-8`})}async deleteFile(e){try{let t=e.fsPath,n=h(t,{throwIfNoEntry:!1});return n?.isFile()||n?.isSymbolicLink()?(await g(t),P.debug(`deleted file {path}`,{path:t}),!0):(P.warn(`deleteFile failed: {path} does not exist, or is not a file`,{path:t}),!1)}catch(t){P.warn(`Failed to delete file ${e.fsPath}`,{error:t})}return!1}};export{N as n,A as r,WithFileSystem as t};
@@ -1,4 +1,4 @@
1
- import{Er as e}from"./utils.mjs";import{h as t}from"./libs/remeda.mjs";import{n}from"./workspace.mjs";import{ifilter as r,invariant as i,isSameHierarchy as a}from"@likec4/core/utils";import{loggable as o}from"@likec4/log";import{invariant as s}from"@likec4/core";import{isDeploymentNodeModel as c,modelConnection as l}from"@likec4/core/model";import{URI as u}from"vscode-uri";import{McpServer as d}from"@modelcontextprotocol/sdk/server/mcp.js";import*as f from"zod/v3";import{StdioServerTransport as p}from"@modelcontextprotocol/sdk/server/stdio.js";import{MemoryEventStore as m,StreamableHTTPTransport as h}from"@hono/mcp";import{serve as g}from"@hono/node-server";import{Hono as _}from"hono";import{cors as v}from"hono/cors";const y=e.getChild(`mcp`);function likec4Tool(e,t){let{name:n,description:r,...i}=e;return e=>[n,{description:r?.trim()??``,...i},mkcallTool(n,e,t)]}function mkcallTool(e,t,n){let r=n.bind(null,t);return(async function(t,n){y.debug(`Calling tool {name}, args: {args}`,{name:e,args:t});try{let e=await r.call(null,t,n);return typeof e==`string`?{content:[{type:`text`,text:e}]}:{content:[{type:`text`,text:JSON.stringify(e)}],structuredContent:e}}catch(t){return y.error(`Tool ${e} failed`,{err:t}),{content:[{type:`text`,text:o(t)}],isError:!0}}})}var b=`1.50.0`;const x=f.object({name:f.string().describe(`Project identifier`),title:f.string().optional().describe(`Human-readable project title`),contactPerson:f.string().optional().describe(`Maintainer contact information`),metadata:f.record(f.string(),f.unknown()).optional().describe(`Custom project metadata as key-value pairs`),extends:f.union([f.string(),f.array(f.string())]).optional().describe(`Style inheritance paths`),exclude:f.array(f.string()).optional().describe(`File exclusion patterns`),include:f.object({paths:f.array(f.string()).describe(`Include paths`),maxDepth:f.number().describe(`Maximum directory depth`),fileThreshold:f.number().describe(`File threshold`)}).optional().describe(`Include configuration`),manualLayouts:f.object({outDir:f.string().describe(`Output directory for manual layouts`)}).optional().describe(`Manual layouts configuration`),styles:f.object({hasTheme:f.boolean().describe(`Whether theme customization is defined`),hasDefaults:f.boolean().describe(`Whether default style values are defined`),hasCustomCss:f.boolean().describe(`Whether custom CSS is defined`)}).optional().describe(`Simplified styles configuration (boolean flags)`)});function serializeConfig(e){let t={name:e.name};return e.title!=null&&(t.title=e.title),e.contactPerson!=null&&(t.contactPerson=e.contactPerson),e.metadata&&(t.metadata=e.metadata),e.extends&&(t.extends=e.extends),e.exclude&&(t.exclude=e.exclude),e.include&&(t.include={paths:e.include.paths||[],maxDepth:e.include.maxDepth??3,fileThreshold:e.include.fileThreshold??30}),e.manualLayouts&&(t.manualLayouts={outDir:e.manualLayouts.outDir??`.likec4`}),e.styles&&(t.styles={hasTheme:!!e.styles.theme,hasDefaults:!!e.styles.defaults,hasCustomCss:!!e.styles.customCss}),t}const S=f.object({id:f.string().describe(`Element id (FQN)`),name:f.string().describe(`Element name`),kind:f.string().describe(`Element kind`),title:f.string(),tags:f.array(f.string()),metadata:f.record(f.union([f.string(),f.array(f.string())])),includedInViews:f.array(f.object({id:f.string().describe(`View id`),title:f.string().describe(`View title`),type:f.enum([`element`,`deployment`,`dynamic`]).describe(`View type`)})).describe(`Views that include this element`)});function serializeElement(e){return{id:e.id,name:e.name,kind:e.kind,title:e.title,tags:[...e.tags],metadata:e.getMetadata(),includedInViews:includedInViews(e.views())}}function traverseGraph(e,t,n,r,i,a){s(e.findElement(t),`Element "${t}" not found`);let o=new Set,c={},l=0,u=!1,d=[{elementId:t,depth:0}];for(;d.length>0;){let{elementId:t,depth:s}=d.shift();if(s>i||o.has(t))continue;if(o.size>=a){u=!0;break}let f=e.findElement(t);if(!f)continue;o.add(t),l=Math.max(l,s);let p=(n===`incoming`?[...f.incoming(r)]:[...f.outgoing(r)]).map(e=>{let t={elementId:n===`incoming`?e.source.id:e.target.id};return e.title&&(t.relationshipLabel=e.title),e.technology&&(t.technology=e.technology),t});c[t]={...serializeElement(f),neighbors:p,depth:s};for(let e of p)o.has(e.elementId)||d.push({elementId:e.elementId,depth:s+1})}for(let e of Object.values(c))e.neighbors=e.neighbors.filter(e=>e.elementId in c);return{target:t,totalNodes:o.size,maxDepth:l,truncated:u,nodes:c}}const C=f.object({path:f.string().describe(`Path to the file`),range:f.object({start:f.object({line:f.number(),character:f.number()}),end:f.object({line:f.number(),character:f.number()})}).describe(`Range in the file`)}).nullable(),w=f.string().refine(e=>!0).optional().default(n.DefaultProjectId).describe(`Project id (optional, will use "default" if not specified)`),T=f.array(f.object({id:f.string().describe(`View id`),title:f.string().describe(`View title`),type:f.enum([`element`,`deployment`,`dynamic`]).describe(`View type`)})),includedInViews=e=>[...e].map(e=>({id:e.id,title:e.titleOrId,type:e.$view._type})),mkLocate=(e,t)=>n=>{try{let r=e.locate({projectId:t,...n});return r?{path:u.parse(r.uri).fsPath,range:r.range}:null}catch(e){return y.debug(`Failed to locate {params}`,{error:e,params:n}),null}},E=S.extend({description:f.string().nullable().describe(`Element description`),technology:f.string().nullable().describe(`Element technology`),shape:f.string().describe(`Rendered shape`),color:f.string().describe(`Rendered color`),children:f.array(f.string()).describe(`Direct child element ids`),incomingCount:f.number().describe(`Number of incoming relationships`),outgoingCount:f.number().describe(`Number of outgoing relationships`)}),D=likec4Tool({name:`batch-read-elements`,description:`
1
+ import{Tr as e}from"./utils.mjs";import{n as t}from"./workspace.mjs";import{ifilter as n,invariant as r,isSameHierarchy as i}from"@likec4/core/utils";import{loggable as a}from"@likec4/log";import{keys as o}from"remeda";import{invariant as s}from"@likec4/core";import{isDeploymentNodeModel as c,modelConnection as l}from"@likec4/core/model";import{URI as u}from"vscode-uri";import{McpServer as d}from"@modelcontextprotocol/sdk/server/mcp.js";import*as f from"zod/v3";import{StdioServerTransport as p}from"@modelcontextprotocol/sdk/server/stdio.js";import{MemoryEventStore as m,StreamableHTTPTransport as h}from"@hono/mcp";import{serve as g}from"@hono/node-server";import{Hono as _}from"hono";import{cors as v}from"hono/cors";const y=e.getChild(`mcp`);function likec4Tool(e,t){let{name:n,description:r,...i}=e;return e=>[n,{description:r?.trim()??``,...i},mkcallTool(n,e,t)]}function mkcallTool(e,t,n){let r=n.bind(null,t);return(async function(t,n){y.debug(`Calling tool {name}, args: {args}`,{name:e,args:t});try{let e=await r.call(null,t,n);return typeof e==`string`?{content:[{type:`text`,text:e}]}:{content:[{type:`text`,text:JSON.stringify(e)}],structuredContent:e}}catch(t){return y.error(`Tool ${e} failed`,{err:t}),{content:[{type:`text`,text:a(t)}],isError:!0}}})}var b=`1.51.0`;const x=f.object({name:f.string().describe(`Project identifier`),title:f.string().optional().describe(`Human-readable project title`),contactPerson:f.string().optional().describe(`Maintainer contact information`),metadata:f.record(f.string(),f.unknown()).optional().describe(`Custom project metadata as key-value pairs`),extends:f.union([f.string(),f.array(f.string())]).optional().describe(`Style inheritance paths`),exclude:f.array(f.string()).optional().describe(`File exclusion patterns`),include:f.object({paths:f.array(f.string()).describe(`Include paths`),maxDepth:f.number().describe(`Maximum directory depth`),fileThreshold:f.number().describe(`File threshold`)}).optional().describe(`Include configuration`),manualLayouts:f.object({outDir:f.string().describe(`Output directory for manual layouts`)}).optional().describe(`Manual layouts configuration`),styles:f.object({hasTheme:f.boolean().describe(`Whether theme customization is defined`),hasDefaults:f.boolean().describe(`Whether default style values are defined`),hasCustomCss:f.boolean().describe(`Whether custom CSS is defined`)}).optional().describe(`Simplified styles configuration (boolean flags)`)});function serializeConfig(e){let t={name:e.name};return e.title!=null&&(t.title=e.title),e.contactPerson!=null&&(t.contactPerson=e.contactPerson),e.metadata&&(t.metadata=e.metadata),e.extends&&(t.extends=e.extends),e.exclude&&(t.exclude=e.exclude),e.include&&(t.include={paths:e.include.paths||[],maxDepth:e.include.maxDepth??3,fileThreshold:e.include.fileThreshold??30}),e.manualLayouts&&(t.manualLayouts={outDir:e.manualLayouts.outDir??`.likec4`}),e.styles&&(t.styles={hasTheme:!!e.styles.theme,hasDefaults:!!e.styles.defaults,hasCustomCss:!!e.styles.customCss}),t}const S=f.object({id:f.string().describe(`Element id (FQN)`),name:f.string().describe(`Element name`),kind:f.string().describe(`Element kind`),title:f.string(),tags:f.array(f.string()),metadata:f.record(f.union([f.string(),f.array(f.string())])),includedInViews:f.array(f.object({id:f.string().describe(`View id`),title:f.string().describe(`View title`),type:f.enum([`element`,`deployment`,`dynamic`]).describe(`View type`)})).describe(`Views that include this element`)});function serializeElement(e){return{id:e.id,name:e.name,kind:e.kind,title:e.title,tags:[...e.tags],metadata:e.getMetadata(),includedInViews:includedInViews(e.views())}}function traverseGraph(e,t,n,r,i,a){s(e.findElement(t),`Element "${t}" not found`);let o=new Set,c={},l=0,u=!1,d=[{elementId:t,depth:0}];for(;d.length>0;){let{elementId:t,depth:s}=d.shift();if(s>i||o.has(t))continue;if(o.size>=a){u=!0;break}let f=e.findElement(t);if(!f)continue;o.add(t),l=Math.max(l,s);let p=(n===`incoming`?[...f.incoming(r)]:[...f.outgoing(r)]).map(e=>{let t={elementId:n===`incoming`?e.source.id:e.target.id};return e.title&&(t.relationshipLabel=e.title),e.technology&&(t.technology=e.technology),t});c[t]={...serializeElement(f),neighbors:p,depth:s};for(let e of p)o.has(e.elementId)||d.push({elementId:e.elementId,depth:s+1})}for(let e of Object.values(c))e.neighbors=e.neighbors.filter(e=>e.elementId in c);return{target:t,totalNodes:o.size,maxDepth:l,truncated:u,nodes:c}}const C=f.object({path:f.string().describe(`Path to the file`),range:f.object({start:f.object({line:f.number(),character:f.number()}),end:f.object({line:f.number(),character:f.number()})}).describe(`Range in the file`)}).nullable(),w=f.string().refine(e=>!0).optional().default(t.DefaultProjectId).describe(`Project id (optional, will use "default" if not specified)`),T=f.array(f.object({id:f.string().describe(`View id`),title:f.string().describe(`View title`),type:f.enum([`element`,`deployment`,`dynamic`]).describe(`View type`)})),includedInViews=e=>[...e].map(e=>({id:e.id,title:e.titleOrId,type:e.$view._type})),mkLocate=(e,t)=>n=>{try{let r=e.locate({projectId:t,...n});return r?{path:u.parse(r.uri).fsPath,range:r.range}:null}catch(e){return y.debug(`Failed to locate {params}`,{error:e,params:n}),null}},E=S.extend({description:f.string().nullable().describe(`Element description`),technology:f.string().nullable().describe(`Element technology`),shape:f.string().describe(`Rendered shape`),color:f.string().describe(`Rendered color`),children:f.array(f.string()).describe(`Direct child element ids`),incomingCount:f.number().describe(`Number of incoming relationships`),outgoingCount:f.number().describe(`Number of outgoing relationships`)}),D=likec4Tool({name:`batch-read-elements`,description:`
2
2
  Read details of multiple elements in a single call, reducing round-trips.
3
3
  Returns a compact summary for each element including metadata, description, technology, shape, children, and relationship counts.
4
4
 
@@ -280,7 +280,7 @@ Response:
280
280
  }
281
281
  ]
282
282
  }
283
- `,inputSchema:{element1:f.string().describe(`Element ID (FQN)`),element2:f.string().describe(`Element ID (FQN)`),project:w},outputSchema:{found:f.array(N)}},async(e,t)=>{let n=e.projectsManager.ensureProjectId(t.project);if(a(t.element1,t.element2))throw Error(`No relationships possible between parent-child`);let r=[],o=await e.computedModel(n),s=o.findElement(t.element1);i(s,`Element "${t.element1}" not found in project "${n}"`);let c=o.findElement(t.element2);i(c,`Element "${t.element2}" not found in project "${n}"`);let u=mkLocate(e,n),d=l.findConnection(s,c,`both`).flatMap(e=>[...e.relations]);for(let e of d){let t=e.source===s&&e.target===c||e.source===c&&e.target===s;r.push({type:t?`direct`:`indirect`,source:{id:e.source.id,title:e.source.title,kind:e.source.kind},target:{id:e.target.id,title:e.target.title,kind:e.target.kind},kind:e.kind,title:e.title,description:e.description.text,technology:e.technology,tags:[...e.tags],includedInViews:includedInViews(e.views()),sourceLocation:u({relation:e.id})})}return{found:r}}),F=likec4Tool({name:`list-projects`,description:`
283
+ `,inputSchema:{element1:f.string().describe(`Element ID (FQN)`),element2:f.string().describe(`Element ID (FQN)`),project:w},outputSchema:{found:f.array(N)}},async(e,t)=>{let n=e.projectsManager.ensureProjectId(t.project);if(i(t.element1,t.element2))throw Error(`No relationships possible between parent-child`);let a=[],o=await e.computedModel(n),s=o.findElement(t.element1);r(s,`Element "${t.element1}" not found in project "${n}"`);let c=o.findElement(t.element2);r(c,`Element "${t.element2}" not found in project "${n}"`);let u=mkLocate(e,n),d=l.findConnection(s,c,`both`).flatMap(e=>[...e.relations]);for(let e of d){let t=e.source===s&&e.target===c||e.source===c&&e.target===s;a.push({type:t?`direct`:`indirect`,source:{id:e.source.id,title:e.source.title,kind:e.source.kind},target:{id:e.target.id,title:e.target.title,kind:e.target.kind},kind:e.kind,title:e.title,description:e.description.text,technology:e.technology,tags:[...e.tags],includedInViews:includedInViews(e.views()),sourceLocation:u({relation:e.id})})}return{found:a}}),F=likec4Tool({name:`list-projects`,description:`
284
284
  List LikeC4 projects discoverable in the current workspace.
285
285
 
286
286
  Request:
@@ -948,7 +948,7 @@ Example response:
948
948
  }
949
949
  ]
950
950
  }
951
- `,inputSchema:{project:w},outputSchema:{title:f.string(),folder:f.string(),sources:f.array(f.string()),config:x.describe(`Project configuration`),specification:f.object({elementKinds:f.array(f.string()),relationshipKinds:f.array(f.string()),deploymentKinds:f.array(f.string()),tags:f.array(f.string()),metadataKeys:f.array(f.string())}),elements:f.array(f.object({id:f.string(),kind:f.string(),title:f.string(),tags:f.array(f.string())})).describe(`List of elements in the project`),deployments:f.array(f.discriminatedUnion(`type`,[f.object({type:f.literal(`deployment-node`),id:f.string().describe(`Node ID`),kind:f.string().describe(`Deployment node kind`),title:f.string().describe(`Node title`),tags:f.array(f.string())}),f.object({type:f.literal(`deployed-instance`),id:f.string().describe(`Node ID`),title:f.string().describe(`Node title`),tags:f.array(f.string()),referencedElementId:f.string().describe(`Element ID (FQN)`)})])).describe(`List of deployment nodes and deployed instances in the project`),views:f.array(f.object({id:f.string(),title:f.string(),type:f.enum([`element`,`deployment`,`dynamic`])}))}},async(e,n)=>{let r=e.projectsManager.ensureProjectId(n.project),i=e.project(r),a=await e.computedModel(r);return{title:i.title,folder:i.folder.fsPath,sources:i.documents?.map(e=>e.fsPath)??[],config:serializeConfig(i.config),specification:{elementKinds:t(a.specification.elements),relationshipKinds:t(a.specification.relationships),deploymentKinds:t(a.specification.deployments),tags:[...a.tags],metadataKeys:a.specification.metadataKeys??[]},elements:[...a.elements()].filter(e=>!e.imported).map(e=>({id:e.id,kind:e.kind,title:e.title,tags:[...e.tags]})),deployments:[...a.deployment.elements()].map(e=>e.isInstance()?{type:`deployed-instance`,id:e.id,title:e.title,tags:[...e.tags],referencedElementId:e.element.id}:{type:`deployment-node`,id:e.id,kind:e.kind,title:e.title,tags:[...e.tags]}),views:[...a.views()].map(e=>({id:e.id,title:e.titleOrId,type:e.$view._type}))}}),modelRef=e=>e.hasElement()?e.element.id:e.hasDeployment()?e.deployment.id:null,X=f.discriminatedUnion(`type`,[f.object({type:f.literal(`element`),id:f.string().describe(`Node ID`),elementId:f.string().describe(`Element ID (FQN)`),kind:f.string().describe(`Element kind`),title:f.string().describe(`Node title`),description:f.string().nullable(),technology:f.string().nullable(),children:f.array(f.string()).describe(`Children nodes, array of node IDs`),shape:f.string().describe(`Rendered shape`),color:f.string().describe(`Rendered color`),tags:f.array(f.string())}),f.object({type:f.literal(`deployment-node`),id:f.string().describe(`Node ID`),deploymentId:f.string().describe(`Deployment entity ID (FQN)`),kind:f.string().describe(`Deployment kind`),title:f.string().describe(`Node title`),description:f.string().nullable(),technology:f.string().nullable(),children:f.array(f.string()).describe(`Children nodes, array of node IDs`),shape:f.string().describe(`Rendered shape`),color:f.string().describe(`Rendered color`),tags:f.array(f.string())}),f.object({type:f.literal(`deployed-instance`),id:f.string().describe(`Node ID`),deploymentId:f.string().describe(`Deployment entity ID (FQN)`),title:f.string().describe(`Node title`),description:f.string().nullable(),technology:f.string().nullable(),referencedElement:f.object({id:f.string().describe(`Element ID (FQN)`),kind:f.string().describe(`Element kind`),title:f.string().describe(`Element title`)}),shape:f.string().describe(`Rendered shape`),color:f.string().describe(`Rendered color`),tags:f.array(f.string())})]),Z=likec4Tool({name:`read-view`,description:`
951
+ `,inputSchema:{project:w},outputSchema:{title:f.string(),folder:f.string(),sources:f.array(f.string()),config:x.describe(`Project configuration`),specification:f.object({elementKinds:f.array(f.string()),relationshipKinds:f.array(f.string()),deploymentKinds:f.array(f.string()),tags:f.array(f.string()),metadataKeys:f.array(f.string())}),elements:f.array(f.object({id:f.string(),kind:f.string(),title:f.string(),tags:f.array(f.string())})).describe(`List of elements in the project`),deployments:f.array(f.discriminatedUnion(`type`,[f.object({type:f.literal(`deployment-node`),id:f.string().describe(`Node ID`),kind:f.string().describe(`Deployment node kind`),title:f.string().describe(`Node title`),tags:f.array(f.string())}),f.object({type:f.literal(`deployed-instance`),id:f.string().describe(`Node ID`),title:f.string().describe(`Node title`),tags:f.array(f.string()),referencedElementId:f.string().describe(`Element ID (FQN)`)})])).describe(`List of deployment nodes and deployed instances in the project`),views:f.array(f.object({id:f.string(),title:f.string(),type:f.enum([`element`,`deployment`,`dynamic`])}))}},async(e,t)=>{let n=e.projectsManager.ensureProjectId(t.project),r=e.project(n),i=await e.computedModel(n);return{title:r.title,folder:r.folder.fsPath,sources:r.documents?.map(e=>e.fsPath)??[],config:serializeConfig(r.config),specification:{elementKinds:o(i.specification.elements),relationshipKinds:o(i.specification.relationships),deploymentKinds:o(i.specification.deployments),tags:[...i.tags],metadataKeys:i.specification.metadataKeys??[]},elements:[...i.elements()].filter(e=>!e.imported).map(e=>({id:e.id,kind:e.kind,title:e.title,tags:[...e.tags]})),deployments:[...i.deployment.elements()].map(e=>e.isInstance()?{type:`deployed-instance`,id:e.id,title:e.title,tags:[...e.tags],referencedElementId:e.element.id}:{type:`deployment-node`,id:e.id,kind:e.kind,title:e.title,tags:[...e.tags]}),views:[...i.views()].map(e=>({id:e.id,title:e.titleOrId,type:e.$view._type}))}}),modelRef=e=>e.hasElement()?e.element.id:e.hasDeployment()?e.deployment.id:null,X=f.discriminatedUnion(`type`,[f.object({type:f.literal(`element`),id:f.string().describe(`Node ID`),elementId:f.string().describe(`Element ID (FQN)`),kind:f.string().describe(`Element kind`),title:f.string().describe(`Node title`),description:f.string().nullable(),technology:f.string().nullable(),children:f.array(f.string()).describe(`Children nodes, array of node IDs`),shape:f.string().describe(`Rendered shape`),color:f.string().describe(`Rendered color`),tags:f.array(f.string())}),f.object({type:f.literal(`deployment-node`),id:f.string().describe(`Node ID`),deploymentId:f.string().describe(`Deployment entity ID (FQN)`),kind:f.string().describe(`Deployment kind`),title:f.string().describe(`Node title`),description:f.string().nullable(),technology:f.string().nullable(),children:f.array(f.string()).describe(`Children nodes, array of node IDs`),shape:f.string().describe(`Rendered shape`),color:f.string().describe(`Rendered color`),tags:f.array(f.string())}),f.object({type:f.literal(`deployed-instance`),id:f.string().describe(`Node ID`),deploymentId:f.string().describe(`Deployment entity ID (FQN)`),title:f.string().describe(`Node title`),description:f.string().nullable(),technology:f.string().nullable(),referencedElement:f.object({id:f.string().describe(`Element ID (FQN)`),kind:f.string().describe(`Element kind`),title:f.string().describe(`Element title`)}),shape:f.string().describe(`Rendered shape`),color:f.string().describe(`Rendered color`),tags:f.array(f.string())})]),Z=likec4Tool({name:`read-view`,description:`
952
952
  Read detailed information about a LikeC4 view.
953
953
 
954
954
  Request:
@@ -1051,7 +1051,7 @@ Example response:
1051
1051
  }
1052
1052
  ]
1053
1053
  }
1054
- `,inputSchema:{search:f.string().min(2,`Search must be at least 2 characters long`)},outputSchema:{total:f.number(),found:Q}},async(e,t)=>{let n=e.projects(),i=[],a=t.search.toLowerCase(),predicate;a.startsWith(`kind:`)?(a=a.slice(5),y.debug(`search by kind: {search}`,{search:a}),predicate=e=>e.kind.toLowerCase()===a):a.startsWith(`shape:`)?(a=a.slice(6),y.debug(`search by shape: {search}`,{search:a}),predicate=e=>e.shape.toLowerCase()===a):a.startsWith(`meta:`)?(a=a.slice(5),y.debug(`search by metadata: {search}`,{search:a}),predicate=e=>!!e.getMetadata(a)):a.startsWith(`#`)?(a=a.slice(1),y.debug(`search by tag: {search}`,{search:a}),predicate=e=>e.tags.some(e=>e.toLowerCase().includes(a))):(y.debug(`search by id/title: {search}`,{search:a}),predicate=e=>e.id.toLowerCase().includes(a)||e.title.toLowerCase().includes(a));for(let t of n)try{let n=await e.computedModel(t.id);for(let e of r(n.elements(),e=>!e.imported&&predicate(e)))i.push({type:`element`,project:t.id,id:e.id,name:e.name,kind:e.kind,title:e.title,technology:e.technology,shape:e.shape,tags:[...e.tags],metadata:e.getMetadata(),includedInViews:includedInViews(e.views())});for(let e of r(n.deployment.nodes(),predicate))i.push({type:`deployment-node`,project:t.id,id:e.id,name:e.name,kind:e.kind,title:e.title,technology:e.technology,shape:e.shape,tags:[...e.tags],metadata:e.getMetadata(),includedInViews:includedInViews(e.views())})}catch(e){y.error(`Error searching in project ${t.id}:`,{error:e})}return{total:i.length,found:i.slice(0,20)}}),ee=f.object({id:f.string().describe(`Element id (FQN)`),name:f.string().describe(`Element name`),kind:f.string().describe(`Element kind`),title:f.string().describe(`Human-readable title`),depth:f.number().describe(`Depth relative to the root element (1 = direct child)`),tags:f.array(f.string()).describe(`Assigned tags`),metadata:f.record(f.union([f.string(),f.array(f.string())])).describe(`Element metadata`),childCount:f.number().describe(`Number of direct children`),incomingCount:f.number().describe(`Number of incoming relationships`),outgoingCount:f.number().describe(`Number of outgoing relationships`)}),te=likec4Tool({name:`subgraph-summary`,description:`
1054
+ `,inputSchema:{search:f.string().min(2,`Search must be at least 2 characters long`)},outputSchema:{total:f.number(),found:Q}},async(e,t)=>{let r=e.projects(),i=[],a=t.search.toLowerCase(),predicate;a.startsWith(`kind:`)?(a=a.slice(5),y.debug(`search by kind: {search}`,{search:a}),predicate=e=>e.kind.toLowerCase()===a):a.startsWith(`shape:`)?(a=a.slice(6),y.debug(`search by shape: {search}`,{search:a}),predicate=e=>e.shape.toLowerCase()===a):a.startsWith(`meta:`)?(a=a.slice(5),y.debug(`search by metadata: {search}`,{search:a}),predicate=e=>!!e.getMetadata(a)):a.startsWith(`#`)?(a=a.slice(1),y.debug(`search by tag: {search}`,{search:a}),predicate=e=>e.tags.some(e=>e.toLowerCase().includes(a))):(y.debug(`search by id/title: {search}`,{search:a}),predicate=e=>e.id.toLowerCase().includes(a)||e.title.toLowerCase().includes(a));for(let t of r)try{let r=await e.computedModel(t.id);for(let e of n(r.elements(),e=>!e.imported&&predicate(e)))i.push({type:`element`,project:t.id,id:e.id,name:e.name,kind:e.kind,title:e.title,technology:e.technology,shape:e.shape,tags:[...e.tags],metadata:e.getMetadata(),includedInViews:includedInViews(e.views())});for(let e of n(r.deployment.nodes(),predicate))i.push({type:`deployment-node`,project:t.id,id:e.id,name:e.name,kind:e.kind,title:e.title,technology:e.technology,shape:e.shape,tags:[...e.tags],metadata:e.getMetadata(),includedInViews:includedInViews(e.views())})}catch(e){y.error(`Error searching in project ${t.id}:`,{error:e})}return{total:i.length,found:i.slice(0,20)}}),ee=f.object({id:f.string().describe(`Element id (FQN)`),name:f.string().describe(`Element name`),kind:f.string().describe(`Element kind`),title:f.string().describe(`Human-readable title`),depth:f.number().describe(`Depth relative to the root element (1 = direct child)`),tags:f.array(f.string()).describe(`Assigned tags`),metadata:f.record(f.union([f.string(),f.array(f.string())])).describe(`Element metadata`),childCount:f.number().describe(`Number of direct children`),incomingCount:f.number().describe(`Number of incoming relationships`),outgoingCount:f.number().describe(`Number of outgoing relationships`)}),te=likec4Tool({name:`subgraph-summary`,description:`
1055
1055
  Get a compact, table-friendly summary of all descendants of a parent element.
1056
1056
  Returns each descendant with its depth, metadata, tags, and relationship counts in a single call.
1057
1057
  Much more efficient than calling read-element for each descendant individually.
@@ -1151,4 +1151,4 @@ Instructions:
1151
1151
  - If response returns "sourceLocation", provide link to this location in the editor
1152
1152
 
1153
1153
  Full documentation: https://likec4.dev/llms-full.txt
1154
- `,enforceStrictCapabilities:!0,...t,capabilities:{tools:{},logging:{},...t?.capabilities}});return r.registerTool(...F(this.services.likec4.LanguageServices)),r.registerTool(...Y(this.services.likec4.LanguageServices)),r.registerTool(...J(this.services.likec4.LanguageServices)),r.registerTool(...q(this.services.likec4.LanguageServices)),r.registerTool(...Z(this.services.likec4.LanguageServices)),r.registerTool(...$(this.services.likec4.LanguageServices)),r.registerTool(...P(this.services.likec4.LanguageServices)),r.registerTool(...H(this.services.likec4.LanguageServices)),r.registerTool(...W(this.services.likec4.LanguageServices)),r.registerTool(...K(this.services.likec4.LanguageServices)),r.registerTool(...R(this.services.likec4.LanguageServices)),r.registerTool(...B(this.services.likec4.LanguageServices)),r.registerTool(...j(this.services.likec4.LanguageServices)),r.registerTool(...D(this.services.likec4.LanguageServices)),r.registerTool(...z(this.services.likec4.LanguageServices)),r.registerTool(...A(this.services.likec4.LanguageServices)),r.registerTool(...te(this.services.likec4.LanguageServices)),n&&r.registerTool(...I(this.services.likec4.LanguageServices)),r.server.onerror=t=>{e.error(o(t))},r}},StdioLikeC4MCPServer=class{transport=void 0;_mcp=void 0;constructor(e){this.services=e}get mcp(){if(!this._mcp)throw Error(`MCP server is not started`);return this._mcp}get isStarted(){return this.transport!==void 0}get port(){return NaN}async dispose(){await this.stop()}async start(){this.transport||(y.info(`Starting MCP stdio server`),this._mcp=this.services.mcp.ServerFactory.create(),this.transport=new p,await this._mcp.connect(this.transport),y.info(`LikeC4 MCP Server running on stdio`))}async stop(){if(this.transport)try{y.info(`Stopping MCP stdio server`),await this.transport.close(),this._mcp&&await this._mcp.close()}finally{this._mcp=void 0,this.transport=void 0}}};async function createHonoApp(e){let t=new _;t.use(`*`,v({origin:`*`,allowHeaders:[`Content-Type`,`mcp-session-id`,`Last-Event-ID`,`mcp-protocol-version`],exposeHeaders:[`mcp-session-id`,`mcp-protocol-version`]})),t.get(`/health`,e=>e.json({status:`ok`}));let n=e.create(),r=new h({eventStore:new m({})});return t.all(`/mcp`,async e=>(n.isConnected()||await n.connect(r),await r.handleRequest(e))),t.notFound(e=>(y.debug(`${e.req.method} ${e.req.url} not found`),e.json({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not found.`},id:null},{status:404}))),t.onError((e,t)=>(y.error(o(e)),t.json({jsonrpc:`2.0`,error:{code:-32603,message:`Internal server error`},id:null},{status:500}))),t}async function startServer(e){let{factory:t,port:n}=e,r=await createHonoApp(t);return new Promise((e,t)=>{let i=g({fetch:r.fetch,hostname:`0.0.0.0`,port:n}).prependOnceListener(`error`,t).prependOnceListener(`listening`,()=>{i.removeListener(`error`,t),e(i.unref())})})}var StreamableLikeC4MCPServer=class{server=void 0;constructor(e,t=33335){this.services=e,this._port=t}get mcp(){throw Error(`StreamableLikeC4MCPServer has access to McpServer only during the request`)}get isStarted(){return this.server?.listening===!0}get port(){return this._port}async dispose(){await this.stop()}async start(e=this._port){if(this.server){if(this.port===e)return;await this.stop()}y.info(`Starting MCP server on port {port}`,{port:e}),this._port=e,this.server=await startServer({factory:this.services.mcp.ServerFactory,port:e}),y.info(`MCP server ready at http://0.0.0.0:{port}/mcp`,{port:e})}stop(){let e=this.server;return e?(y.info(`Stopping MCP server`),this.server=void 0,new Promise(t=>{e.close(e=>{e?y.error(`Failed to stop MCP server`,{err:e}):y.info(`MCP server stopped`),t()})})):(y.info(`MCP server is not running, nothing to stop`),Promise.resolve())}};function streamableLikeC4MCPServer(e,t=33335){y.debug(`Creating StreamableLikeC4MCPServer`);let n=new StreamableLikeC4MCPServer(e,t),r=e.LanguageMetaData.languageId,i=e.shared.lsp.Connection;return e.shared.workspace.ConfigurationProvider.onConfigurationSectionUpdate(e=>{if(e.section!==r){y.warn(`Unexpected configuration update: {update}`,{update:e});return}let{enabled:a=!1,port:s=t}=e.configuration.mcp;if(!a){n.stop();return}Promise.resolve().then(()=>n.start(s)).then(()=>{i?.telemetry?.logEvent({eventName:`mcp-server-started`,mcpPort:s})}).catch(e=>{let t=o(e);i?.telemetry?.logEvent({eventName:`mcp-server-start-failed`,mcpPort:s,message:t}),y.warn(`Failed to start LikeC4 MCP Server: \n${t}`),i&&i.window.showErrorMessage(`LikeC4: Failed to start MCP Server\n\n${t}`)})}),n}function stdioLikeC4MCPServer(e){return new StdioLikeC4MCPServer(e)}function WithMCPServer(e=`sse`){return{mcpServer:t=>e===`stdio`?stdioLikeC4MCPServer(t):streamableLikeC4MCPServer(t,typeof e==`object`?e.port:33335),mcpServerFactory:e=>new MCPServerFactory(e)}}export{WithMCPServer as t};
1154
+ `,enforceStrictCapabilities:!0,...t,capabilities:{tools:{},logging:{},...t?.capabilities}});return r.registerTool(...F(this.services.likec4.LanguageServices)),r.registerTool(...Y(this.services.likec4.LanguageServices)),r.registerTool(...J(this.services.likec4.LanguageServices)),r.registerTool(...q(this.services.likec4.LanguageServices)),r.registerTool(...Z(this.services.likec4.LanguageServices)),r.registerTool(...$(this.services.likec4.LanguageServices)),r.registerTool(...P(this.services.likec4.LanguageServices)),r.registerTool(...H(this.services.likec4.LanguageServices)),r.registerTool(...W(this.services.likec4.LanguageServices)),r.registerTool(...K(this.services.likec4.LanguageServices)),r.registerTool(...R(this.services.likec4.LanguageServices)),r.registerTool(...B(this.services.likec4.LanguageServices)),r.registerTool(...j(this.services.likec4.LanguageServices)),r.registerTool(...D(this.services.likec4.LanguageServices)),r.registerTool(...z(this.services.likec4.LanguageServices)),r.registerTool(...A(this.services.likec4.LanguageServices)),r.registerTool(...te(this.services.likec4.LanguageServices)),n&&r.registerTool(...I(this.services.likec4.LanguageServices)),r.server.onerror=t=>{e.error(a(t))},r}},StdioLikeC4MCPServer=class{transport=void 0;_mcp=void 0;constructor(e){this.services=e}get mcp(){if(!this._mcp)throw Error(`MCP server is not started`);return this._mcp}get isStarted(){return this.transport!==void 0}get port(){return NaN}async dispose(){await this.stop()}async start(){this.transport||(y.info(`Starting MCP stdio server`),this._mcp=this.services.mcp.ServerFactory.create(),this.transport=new p,await this._mcp.connect(this.transport),y.info(`LikeC4 MCP Server running on stdio`))}async stop(){if(this.transport)try{y.info(`Stopping MCP stdio server`),await this.transport.close(),this._mcp&&await this._mcp.close()}finally{this._mcp=void 0,this.transport=void 0}}};async function createHonoApp(e){let t=new _;t.use(`*`,v({origin:`*`,allowHeaders:[`Content-Type`,`mcp-session-id`,`Last-Event-ID`,`mcp-protocol-version`],exposeHeaders:[`mcp-session-id`,`mcp-protocol-version`]})),t.get(`/health`,e=>e.json({status:`ok`}));let n=e.create(),r=new h({eventStore:new m({})});return t.all(`/mcp`,async e=>(n.isConnected()||await n.connect(r),await r.handleRequest(e))),t.notFound(e=>(y.debug(`${e.req.method} ${e.req.url} not found`),e.json({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not found.`},id:null},{status:404}))),t.onError((e,t)=>(y.error(a(e)),t.json({jsonrpc:`2.0`,error:{code:-32603,message:`Internal server error`},id:null},{status:500}))),t}async function startServer(e){let{factory:t,port:n}=e,r=await createHonoApp(t);return new Promise((e,t)=>{let i=g({fetch:r.fetch,hostname:`0.0.0.0`,port:n}).prependOnceListener(`error`,t).prependOnceListener(`listening`,()=>{i.removeListener(`error`,t),e(i.unref())})})}var StreamableLikeC4MCPServer=class{server=void 0;constructor(e,t=33335){this.services=e,this._port=t}get mcp(){throw Error(`StreamableLikeC4MCPServer has access to McpServer only during the request`)}get isStarted(){return this.server?.listening===!0}get port(){return this._port}async dispose(){await this.stop()}async start(e=this._port){if(this.server){if(this.port===e)return;await this.stop()}y.info(`Starting MCP server on port {port}`,{port:e}),this._port=e,this.server=await startServer({factory:this.services.mcp.ServerFactory,port:e}),y.info(`MCP server ready at http://0.0.0.0:{port}/mcp`,{port:e})}stop(){let e=this.server;return e?(y.info(`Stopping MCP server`),this.server=void 0,new Promise(t=>{e.close(e=>{e?y.error(`Failed to stop MCP server`,{err:e}):y.info(`MCP server stopped`),t()})})):(y.info(`MCP server is not running, nothing to stop`),Promise.resolve())}};function streamableLikeC4MCPServer(e,t=33335){y.debug(`Creating StreamableLikeC4MCPServer`);let n=new StreamableLikeC4MCPServer(e,t),r=e.LanguageMetaData.languageId,i=e.shared.lsp.Connection;return e.shared.workspace.ConfigurationProvider.onConfigurationSectionUpdate(e=>{if(e.section!==r){y.warn(`Unexpected configuration update: {update}`,{update:e});return}let{enabled:o=!1,port:s=t}=e.configuration.mcp;if(!o){n.stop();return}Promise.resolve().then(()=>n.start(s)).then(()=>{i?.telemetry?.logEvent({eventName:`mcp-server-started`,mcpPort:s})}).catch(e=>{let t=a(e);i?.telemetry?.logEvent({eventName:`mcp-server-start-failed`,mcpPort:s,message:t}),y.warn(`Failed to start LikeC4 MCP Server: \n${t}`),i&&i.window.showErrorMessage(`LikeC4: Failed to start MCP Server\n\n${t}`)})}),n}function stdioLikeC4MCPServer(e){return new StdioLikeC4MCPServer(e)}function WithMCPServer(e=`sse`){return{mcpServer:t=>e===`stdio`?stdioLikeC4MCPServer(t):streamableLikeC4MCPServer(t,typeof e==`object`?e.port:33335),mcpServerFactory:e=>new MCPServerFactory(e)}}export{WithMCPServer as t};
@@ -2,9 +2,9 @@ import { h as Locate, n as ChangeView, o as DidRequestOpenViewNotification } fro
2
2
  import * as langium from "langium";
3
3
  import { AstNode, AstNodeDescription, AsyncDisposable, BuildOptions, Cancellation, CstNode, DefaultAstNodeDescriptionProvider, DefaultDocumentValidator, DefaultIndexManager, DefaultLangiumDocuments, DefaultNameProvider, DefaultScopeComputation, DefaultScopeProvider, DefaultValueConverter, DefaultWorkspaceManager, DiagnosticInfo, Disposable, FileSelector, FileSystemNode, FileSystemProvider, GrammarAST, JSDocDocumentationProvider, LangiumDocument, LangiumDocumentFactory, MaybePromise, Module, PrecomputedScopes, Reference, ReferenceDescription, ReferenceInfo, Scope, SimpleCache, Stream, URI, ValidationOptions, ValueType, WorkspaceCache } from "langium";
4
4
  import { DefaultWeakMap, MultiMap as MultiMap$1 } from "@likec4/core/utils";
5
- import { CompletionItemKind, Diagnostic, DocumentSymbol, FormattingOptions, Hover, Location, Range, SemanticTokens, SemanticTokensDelta, SymbolKind, TextEdit } from "vscode-languageserver-types";
5
+ import { CompletionItemKind, Diagnostic, DocumentSymbol, FormattingOptions, Hover, Location, Range, SymbolKind, TextEdit } from "vscode-languageserver-types";
6
6
  import { AbstractFormatter, AbstractSemanticTokenProvider, AstNodeHoverProvider, CodeActionProvider, CodeLensProvider, CompletionAcceptor, CompletionContext, DefaultCompletionProvider, DefaultDocumentHighlightProvider, DefaultSharedModuleContext, DefaultWorkspaceSymbolProvider, DocumentLinkProvider, DocumentSymbolProvider, FormattingRegion, LangiumServices, LangiumSharedServices, NextFeature, NodeKindProvider, PartialLangiumServices, SemanticTokenAcceptor } from "langium/lsp";
7
- import { GraphvizLayouter, QueueGraphvizLayoter } from "@likec4/layouts";
7
+ import { GraphvizLayouter, GraphvizPort, QueueGraphvizLayoter } from "@likec4/layouts";
8
8
  import * as c4 from "@likec4/core";
9
9
  import { ComputedView, DiagramView, LayoutType, LayoutedView, NonEmptyArray, NonEmptyReadonlyArray, ProjectId, Tag, UnknownComputed, UnknownLayouted, UnknownParsed, ViewChange, ViewId } from "@likec4/core";
10
10
  import { AdhocViewPredicate, LayoutedProjectsView as LayoutedProjectsView$1 } from "@likec4/core/compute-view";
@@ -13,9 +13,9 @@ import { IncludeConfig, LikeC4ProjectConfig, LikeC4ProjectConfigInput } from "@l
13
13
  import { URI as URI$2 } from "vscode-uri";
14
14
  import { LikeC4Styles } from "@likec4/core/styles";
15
15
  import { CancellationToken, CodeLens, CodeLensParams, Connection, DocumentHighlight, DocumentLink, DocumentLinkParams, DocumentSymbolParams, WorkspaceFolder } from "vscode-languageserver";
16
- import { CancellationToken as CancellationToken$1, CodeAction, CodeActionParams, Command, SemanticTokensDeltaParams, SemanticTokensParams, SemanticTokensRangeParams } from "vscode-languageserver-protocol";
16
+ import { CodeAction, CodeActionParams, Command } from "vscode-languageserver-protocol";
17
17
  import { Fqn as Fqn$1, GuardedBy, LayoutedView as LayoutedView$1, ProjectId as ProjectId$1, ViewId as ViewId$1 } from "@likec4/core/types";
18
- import { CancellationToken as CancellationToken$2 } from "vscode-jsonrpc";
18
+ import { CancellationToken as CancellationToken$1 } from "vscode-jsonrpc";
19
19
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
20
20
  import * as type_fest0 from "type-fest";
21
21
  import { ConditionalPick, MergeExclusive, Simplify, Tagged, ValueOf, Writable } from "type-fest";
@@ -45,8 +45,8 @@ declare class LikeC4DocumentationProvider extends JSDocDocumentationProvider {
45
45
  //#region src/workspace/ProjectsManager.d.ts
46
46
  type DocOrUri = LangiumDocument | string | URI;
47
47
  /**
48
- * A tagged string that represents a project folder URI
49
- * Always has trailing slash.
48
+ * A tagged string that represents a project folder URI (with trailing slash).
49
+ * Used in `startsWith` checks to determine if a document belongs to a project.
50
50
  */
51
51
  type ProjectFolder = Tagged<string, 'ProjectFolder'>;
52
52
  declare function ProjectFolder(folder: URI | string): ProjectFolder;
@@ -167,6 +167,7 @@ declare class ProjectsManager {
167
167
  private getWorkspaceFolder;
168
168
  private notifyListeners;
169
169
  private updateIncludesExcludes;
170
+ private warnIfConfigOverride;
170
171
  }
171
172
  //#endregion
172
173
  //#region src/filesystem/types.d.ts
@@ -324,7 +325,7 @@ interface LikeC4MCPServerModuleContext {
324
325
  }
325
326
  //#endregion
326
327
  //#region src/generated/ast.d.ts
327
- type AnyProperty = DynamicViewProperty | ElementProperty | RelationProperty | StringProperty | ViewProperty;
328
+ type AnyProperty = DynamicViewProperty | ElementProperty | NavigateToProperty | NotationProperty | NotesProperty | RelationProperty | RelationshipStyleProperty | StringProperty | StyleProperty | ViewProperty;
328
329
  declare const AnyProperty = "AnyProperty";
329
330
  type ArrowType = 'crow' | 'diamond' | 'dot' | 'none' | 'normal' | 'odiamond' | 'odot' | 'onormal' | 'open' | 'vee';
330
331
  type BorderStyleValue = 'none' | LineOptions;
@@ -2075,9 +2076,9 @@ declare class LastSeenArtifacts {
2075
2076
  //#region src/model/model-builder.d.ts
2076
2077
  type ModelParsedListener = (docs: URI[]) => void;
2077
2078
  interface LikeC4ModelBuilder extends Disposable {
2078
- parseModel(projectId?: ProjectId | undefined, cancelToken?: CancellationToken$2): Promise<LikeC4Model<UnknownParsed> | null>;
2079
+ parseModel(projectId?: ProjectId | undefined, cancelToken?: CancellationToken$1): Promise<LikeC4Model<UnknownParsed> | null>;
2079
2080
  unsafeSyncComputeModel(projectId: ProjectId): LikeC4Model<UnknownComputed>;
2080
- computeModel(projectId?: ProjectId | undefined, cancelToken?: CancellationToken$2): Promise<LikeC4Model<UnknownComputed>>;
2081
+ computeModel(projectId?: ProjectId | undefined, cancelToken?: CancellationToken$1): Promise<LikeC4Model<UnknownComputed>>;
2081
2082
  onModelParsed(callback: ModelParsedListener): Disposable;
2082
2083
  clearCache(): void;
2083
2084
  }
@@ -2231,8 +2232,56 @@ interface LikeC4Views {
2231
2232
  adhocView(predicates: AdhocViewPredicate[], projectId?: ProjectId | undefined): Promise<LayoutedView>;
2232
2233
  }
2233
2234
  //#endregion
2235
+ //#region src/views/index.d.ts
2236
+ interface LikeC4ViewsModuleContext {
2237
+ graphviz: (services: LikeC4Services) => GraphvizPort;
2238
+ }
2239
+ declare const WithWasmGraphviz: LikeC4ViewsModuleContext;
2240
+ declare function WithGraphviz(graphviz: GraphvizPort): LikeC4ViewsModuleContext;
2241
+ //#endregion
2242
+ //#region src/configureLogger.d.ts
2243
+ type ConfigureLanguageServerLoggerOptions = {
2244
+ /**
2245
+ * The LSP connection if available
2246
+ * (used by Telemetry)
2247
+ */
2248
+ lspConnection?: Connection | undefined;
2249
+ /**
2250
+ * Whether to use stderr for logging instead of stdout.
2251
+ * @default false
2252
+ */
2253
+ useStdErr?: boolean;
2254
+ /**
2255
+ * The log level to use.
2256
+ * @default 'warning'
2257
+ */
2258
+ logLevel?: 'trace' | 'debug' | 'info' | 'warning' | 'error' | undefined;
2259
+ /**
2260
+ * @default true
2261
+ */
2262
+ enableTelemetry?: boolean;
2263
+ /**
2264
+ * Enable non-blocking logging (async).
2265
+ * @default false
2266
+ */
2267
+ nonBlocking?: boolean;
2268
+ /**
2269
+ * Whether to use colors in logging.
2270
+ * @default false
2271
+ */
2272
+ colors?: boolean;
2273
+ };
2274
+ declare function configureLanguageServerLogger({
2275
+ lspConnection: connection,
2276
+ enableTelemetry,
2277
+ useStdErr,
2278
+ logLevel: lowestLevel,
2279
+ nonBlocking,
2280
+ colors
2281
+ }?: ConfigureLanguageServerLoggerOptions): void;
2282
+ //#endregion
2234
2283
  //#region src/index.d.ts
2235
- type StartLanguageServerOptions = {
2284
+ interface StartLanguageServerOptions {
2236
2285
  /**
2237
2286
  * The Language Server Protocol connection to use.
2238
2287
  */
@@ -2242,10 +2291,6 @@ type StartLanguageServerOptions = {
2242
2291
  * @default true
2243
2292
  */
2244
2293
  enableWatcher?: boolean;
2245
- /**
2246
- * @default true
2247
- */
2248
- enableTelemetry?: boolean;
2249
2294
  /**
2250
2295
  * Whether to enable the MCP server.
2251
2296
  * @default 'sse'
@@ -2258,7 +2303,25 @@ type StartLanguageServerOptions = {
2258
2303
  * @default true
2259
2304
  */
2260
2305
  enableManualLayouts?: boolean;
2261
- };
2306
+ /**
2307
+ * Whether to use the `dot` binary for layouting or the WebAssembly version.
2308
+ * If {@link connection} is set, {@link ConfigurableLayouter} is started
2309
+ * and this option controls the default layouter implementation used by it.
2310
+ *
2311
+ * @default 'wasm'
2312
+ */
2313
+ graphviz?: 'wasm' | 'binary';
2314
+ /**
2315
+ * Whether to configure the logger.
2316
+ *
2317
+ * - `false` - don't configure the logger
2318
+ * - `'console'` - configure the logger with console sink
2319
+ * - `'stderr'` - configure the logger with stderr sink
2320
+ *
2321
+ * @default false
2322
+ */
2323
+ configureLogger?: false | 'console' | 'stderr';
2324
+ }
2262
2325
  declare function startLanguageServer$1(options?: StartLanguageServerOptions): {
2263
2326
  shared: LikeC4SharedServices;
2264
2327
  likec4: LikeC4Services;
@@ -3035,28 +3098,28 @@ interface LikeC4LanguageServices {
3035
3098
  * Computes and layouts projects overview - a special diagram
3036
3099
  * that shows all projects and their relationships
3037
3100
  */
3038
- projectsOverview(cancelToken?: CancellationToken$2): Promise<LayoutedProjectsView$1>;
3101
+ projectsOverview(cancelToken?: CancellationToken$1): Promise<LayoutedProjectsView$1>;
3039
3102
  /**
3040
3103
  * Returns {@link LikeC4Model} of the specified project, with computed views {@link ComputedView}
3041
3104
  * Not ready for rendering, but enough to traverse model. Much faster than {@link layoutedModel}
3042
3105
  *
3043
3106
  * If no {@link project} is specified, returns for default project
3044
3107
  */
3045
- computedModel(project?: ProjectId | undefined, cancelToken?: CancellationToken$2): Promise<LikeC4Model<UnknownComputed>>;
3108
+ computedModel(project?: ProjectId | undefined, cancelToken?: CancellationToken$1): Promise<LikeC4Model<UnknownComputed>>;
3046
3109
  /**
3047
3110
  * Returns {@link LikeC4Model} of the specified project, with layouted views {@link LayoutedView}
3048
3111
  * Ready for rendering. Applies manual layouts if available.
3049
3112
  *
3050
3113
  * If no {@link project} is specified, returns for default project
3051
3114
  */
3052
- layoutedModel(project?: ProjectId | undefined, cancelToken?: CancellationToken$2): Promise<LikeC4Model<UnknownLayouted>>;
3115
+ layoutedModel(project?: ProjectId | undefined, cancelToken?: CancellationToken$1): Promise<LikeC4Model<UnknownLayouted>>;
3053
3116
  /**
3054
3117
  * Returns diagrams (i.e. layouted views {@link LayoutedView}) for the specified project
3055
3118
  * Applies manual layouts if available.
3056
3119
  *
3057
3120
  * If no {@link project} is specified, returns diagrams for default project
3058
3121
  */
3059
- diagrams(project?: ProjectId | undefined, cancelToken?: CancellationToken$2): Promise<LayoutedView[]>;
3122
+ diagrams(project?: ProjectId | undefined, cancelToken?: CancellationToken$1): Promise<LayoutedView[]>;
3060
3123
  getErrors(): Array<{
3061
3124
  message: string;
3062
3125
  line: number;
@@ -3190,10 +3253,6 @@ declare class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider
3190
3253
  private rules;
3191
3254
  constructor(services: LikeC4Services);
3192
3255
  protected initRules(): void;
3193
- semanticHighlight(document: LangiumDocument, params: SemanticTokensParams, cancelToken?: CancellationToken$1): Promise<SemanticTokens>;
3194
- semanticHighlightRange(document: LangiumDocument, params: SemanticTokensRangeParams, cancelToken?: CancellationToken$1): Promise<SemanticTokens>;
3195
- semanticHighlightDelta(document: LangiumDocument, params: SemanticTokensDeltaParams, cancelToken?: CancellationToken$1): Promise<SemanticTokens | SemanticTokensDelta>;
3196
- protected ensureState(document: LangiumDocument, cancelToken: CancellationToken$1): Promise<void>;
3197
3256
  protected highlightElement(node: AstNode, acceptor: SemanticTokenAcceptor): void | undefined | 'prune';
3198
3257
  private highlightNameAndKind;
3199
3258
  private highlightView;
@@ -3226,7 +3285,6 @@ declare class NodeKindProvider$1 implements NodeKindProvider {
3226
3285
  declare class WorkspaceSymbolProvider extends DefaultWorkspaceSymbolProvider {}
3227
3286
  //#endregion
3228
3287
  //#region src/module.d.ts
3229
- type LanguageServicesContext = Omit<DefaultSharedModuleContext, 'fileSystemProvider'> & FileSystemModuleContext & LikeC4MCPServerModuleContext & LikeC4ManualLayoutsModuleContext;
3230
3288
  interface LikeC4AddedSharedServices {
3231
3289
  lsp: {
3232
3290
  NodeKindProvider: NodeKindProvider$1;
@@ -3244,6 +3302,7 @@ interface LikeC4AddedSharedServices {
3244
3302
  };
3245
3303
  }
3246
3304
  type LikeC4SharedServices = LangiumSharedServices & LikeC4AddedSharedServices;
3305
+ type LikeC4SharedModuleContext = Omit<DefaultSharedModuleContext, 'fileSystemProvider'> & FileSystemModuleContext & LikeC4ManualLayoutsModuleContext;
3247
3306
  /**
3248
3307
  * Declaration of custom services - add your own service classes here.
3249
3308
  */
@@ -3262,6 +3321,7 @@ interface LikeC4AddedServices {
3262
3321
  likec4: {
3263
3322
  LanguageServices: LikeC4LanguageServices;
3264
3323
  Views: LikeC4Views;
3324
+ Graphviz: GraphvizPort;
3265
3325
  Layouter: QueueGraphvizLayoter;
3266
3326
  DeploymentsIndex: DeploymentsIndex;
3267
3327
  FqnIndex: FqnIndex;
@@ -3293,12 +3353,14 @@ interface LikeC4AddedServices {
3293
3353
  };
3294
3354
  }
3295
3355
  type LikeC4Services = LangiumServices & LikeC4AddedServices;
3356
+ type LikeC4ServicesContext = LikeC4MCPServerModuleContext & LikeC4ViewsModuleContext;
3296
3357
  /**
3297
3358
  * Most probably you don't need to use this function directly.
3298
3359
  * Use {@link createLanguageServices} instead.
3299
3360
  * @internal
3300
3361
  */
3301
- declare function createLikeC4Module(context: LikeC4MCPServerModuleContext): Module<LikeC4Services, PartialLangiumServices & LikeC4AddedServices>;
3362
+ declare function createLikeC4Module(context: LikeC4ServicesContext): Module<LikeC4Services, PartialLangiumServices & LikeC4AddedServices>;
3363
+ type LanguageServicesContext = LikeC4SharedModuleContext & LikeC4ServicesContext;
3302
3364
  /**
3303
3365
  * Create and initialize likec4 language services with the given context
3304
3366
  * @example
@@ -3344,4 +3406,4 @@ declare function createLanguageServices<I1, I2, I3, I extends I1 & I2 & I3 & Lik
3344
3406
  */
3345
3407
  declare function createSharedServices(context?: Partial<LanguageServicesContext>): LikeC4SharedServices;
3346
3408
  //#endregion
3347
- export { FileNode as A, ProjectsManager as B, LikeC4MCPServerModuleContext as C, NoFileSystem as D, WithFileSystem as E, LikeC4ManualLayouts as F, LikeC4ManualLayoutsModuleContext as I, ManualLayoutsSnapshot as L, FileSystemProvider$1 as M, FileSystemWatcher as N, NoFileSystemWatcher as O, FileSystemWatcherModuleContext as P, Project as R, LikeC4MCPServerFactory as S, WithChokidarWatcher as T, LikeC4ModelBuilder as _, createLanguageServices as a, LangiumDocuments as b, LikeC4LanguageServices as c, startLanguageServer$1 as d, LikeC4Views as f, ViewLocateResult as g, LikeC4ModelLocator as h, LikeC4SharedServices as i, FileSystemModuleContext as j, NoLikeC4ManualLayouts as k, DocumentParser as l, NoMCPServer as m, LikeC4AddedServices as n, createLikeC4Module as o, WithMCPServer as p, LikeC4Services as r, createSharedServices as s, LanguageServicesContext as t, LikeC4ModelParser as u, FqnIndex as v, WithLikeC4ManualLayouts as w, LikeC4MCPServer as x, LikeC4WorkspaceManager as y, ProjectData as z };
3409
+ export { LikeC4MCPServerModuleContext as A, FileSystemWatcher as B, ViewLocateResult as C, LangiumDocuments as D, LikeC4WorkspaceManager as E, NoFileSystemWatcher as F, Project as G, LikeC4ManualLayouts as H, NoLikeC4ManualLayouts as I, ProjectData as K, FileNode as L, WithChokidarWatcher as M, WithFileSystem as N, LikeC4MCPServer as O, NoFileSystem as P, FileSystemModuleContext as R, LikeC4ModelLocator as S, FqnIndex as T, LikeC4ManualLayoutsModuleContext as U, FileSystemWatcherModuleContext as V, ManualLayoutsSnapshot as W, WithGraphviz as _, LikeC4SharedModuleContext as a, WithMCPServer as b, createLikeC4Module as c, DocumentParser as d, LikeC4ModelParser as f, LikeC4ViewsModuleContext as g, configureLanguageServerLogger as h, LikeC4ServicesContext as i, WithLikeC4ManualLayouts as j, LikeC4MCPServerFactory as k, createSharedServices as l, ConfigureLanguageServerLoggerOptions as m, LikeC4AddedServices as n, LikeC4SharedServices as o, startLanguageServer$1 as p, ProjectsManager as q, LikeC4Services as r, createLanguageServices as s, LanguageServicesContext as t, LikeC4LanguageServices as u, WithWasmGraphviz as v, LikeC4ModelBuilder as w, NoMCPServer as x, LikeC4Views as y, FileSystemProvider$1 as z };