@likec4/language-server 1.50.0 → 1.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +5 -25
- package/bin/likec4-language-server.mjs +2 -3
- package/dist/_chunks/LikeC4FileSystem.mjs +2 -2
- package/dist/_chunks/{WithMCPServer.mjs → mcp.mjs} +5 -5
- package/dist/_chunks/module.d.mts +124 -30
- package/dist/_chunks/module.mjs +19 -19
- package/dist/_chunks/utils.mjs +1 -1
- package/dist/_chunks/workspace.mjs +1 -1
- package/dist/browser/index.d.mts +2 -2
- package/dist/browser/index.mjs +1 -1
- package/dist/browser/worker.mjs +1 -1
- package/dist/filesystem/index.d.mts +1 -1
- package/dist/filesystem/index.mjs +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +1 -1
- package/dist/mcp/index.d.mts +1 -1
- package/dist/mcp/index.mjs +1 -1
- package/dist/module.d.mts +2 -2
- package/dist/module.mjs +1 -1
- package/package.json +23 -35
- package/bundled/package.json +0 -4
- package/dist/THIRD-PARTY-LICENSES.md +0 -178
- package/dist/_chunks/ConfigurableLayouter.mjs +0 -1
- package/dist/_chunks/libs/@msgpack/msgpack.mjs +0 -1
- package/dist/_chunks/libs/eventemitter3.mjs +0 -1
- package/dist/_chunks/libs/fast-equals.mjs +0 -1
- package/dist/_chunks/libs/p-queue.mjs +0 -1
- package/dist/_chunks/libs/parse-ms.mjs +0 -1
- package/dist/_chunks/libs/picomatch.mjs +0 -1
- package/dist/_chunks/libs/pretty-ms.mjs +0 -1
- package/dist/_chunks/libs/remeda.mjs +0 -2
- package/dist/_chunks/libs/strip-indent.mjs +0 -1
- package/dist/_chunks/libs/ufo.mjs +0 -1
- package/dist/_chunks/rolldown-runtime.mjs +0 -1
- package/dist/bundled.d.mts +0 -27
- 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
|
-
|
|
3
|
+
LikeC4 Language Server Protocol (LSP) based on [langium](https://github.com/langium/langium) library.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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,3 +1,3 @@
|
|
|
1
|
-
import{a as e,r as t}from"./likec4lib.mjs";import{n}from"./noop.mjs";import{
|
|
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
|
|
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{
|
|
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.52.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(
|
|
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,
|
|
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
|
|
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(
|
|
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,
|
|
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 {
|
|
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$
|
|
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
|
-
*
|
|
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;
|
|
@@ -1699,7 +1700,6 @@ interface ParsedAstElementView {
|
|
|
1699
1700
|
tags: c4.NonEmptyArray<c4.Tag> | null;
|
|
1700
1701
|
links: c4.NonEmptyArray<c4.Link> | null;
|
|
1701
1702
|
rules: c4.ElementViewRule[];
|
|
1702
|
-
manualLayout?: c4.ViewManualLayout;
|
|
1703
1703
|
}
|
|
1704
1704
|
interface ParsedAstDynamicView {
|
|
1705
1705
|
id: c4.ViewId;
|
|
@@ -1711,7 +1711,6 @@ interface ParsedAstDynamicView {
|
|
|
1711
1711
|
steps: c4.DynamicViewStep[];
|
|
1712
1712
|
rules: Array<c4.DynamicViewRule>;
|
|
1713
1713
|
variant: c4.DynamicViewDisplayVariant | undefined;
|
|
1714
|
-
manualLayout?: c4.ViewManualLayout;
|
|
1715
1714
|
}
|
|
1716
1715
|
interface ParsedAstDeploymentView {
|
|
1717
1716
|
id: c4.ViewId;
|
|
@@ -1721,7 +1720,6 @@ interface ParsedAstDeploymentView {
|
|
|
1721
1720
|
tags: c4.NonEmptyArray<c4.Tag> | null;
|
|
1722
1721
|
links: c4.NonEmptyArray<c4.Link> | null;
|
|
1723
1722
|
rules: Array<c4.DeploymentViewRule>;
|
|
1724
|
-
manualLayout?: c4.ViewManualLayout;
|
|
1725
1723
|
}
|
|
1726
1724
|
type ParsedAstView = ParsedAstElementView | ParsedAstDynamicView | ParsedAstDeploymentView;
|
|
1727
1725
|
interface AstNodeDescriptionWithFqn extends AstNodeDescription {
|
|
@@ -2075,9 +2073,9 @@ declare class LastSeenArtifacts {
|
|
|
2075
2073
|
//#region src/model/model-builder.d.ts
|
|
2076
2074
|
type ModelParsedListener = (docs: URI[]) => void;
|
|
2077
2075
|
interface LikeC4ModelBuilder extends Disposable {
|
|
2078
|
-
parseModel(projectId?: ProjectId | undefined, cancelToken?: CancellationToken$
|
|
2076
|
+
parseModel(projectId?: ProjectId | undefined, cancelToken?: CancellationToken$1): Promise<LikeC4Model<UnknownParsed> | null>;
|
|
2079
2077
|
unsafeSyncComputeModel(projectId: ProjectId): LikeC4Model<UnknownComputed>;
|
|
2080
|
-
computeModel(projectId?: ProjectId | undefined, cancelToken?: CancellationToken$
|
|
2078
|
+
computeModel(projectId?: ProjectId | undefined, cancelToken?: CancellationToken$1): Promise<LikeC4Model<UnknownComputed>>;
|
|
2081
2079
|
onModelParsed(callback: ModelParsedListener): Disposable;
|
|
2082
2080
|
clearCache(): void;
|
|
2083
2081
|
}
|
|
@@ -2231,8 +2229,56 @@ interface LikeC4Views {
|
|
|
2231
2229
|
adhocView(predicates: AdhocViewPredicate[], projectId?: ProjectId | undefined): Promise<LayoutedView>;
|
|
2232
2230
|
}
|
|
2233
2231
|
//#endregion
|
|
2232
|
+
//#region src/views/index.d.ts
|
|
2233
|
+
interface LikeC4ViewsModuleContext {
|
|
2234
|
+
graphviz: (services: LikeC4Services) => GraphvizPort;
|
|
2235
|
+
}
|
|
2236
|
+
declare const WithWasmGraphviz: LikeC4ViewsModuleContext;
|
|
2237
|
+
declare function WithGraphviz(graphviz: GraphvizPort): LikeC4ViewsModuleContext;
|
|
2238
|
+
//#endregion
|
|
2239
|
+
//#region src/configureLogger.d.ts
|
|
2240
|
+
type ConfigureLanguageServerLoggerOptions = {
|
|
2241
|
+
/**
|
|
2242
|
+
* The LSP connection if available
|
|
2243
|
+
* (used by Telemetry)
|
|
2244
|
+
*/
|
|
2245
|
+
lspConnection?: Connection | undefined;
|
|
2246
|
+
/**
|
|
2247
|
+
* Whether to use stderr for logging instead of stdout.
|
|
2248
|
+
* @default false
|
|
2249
|
+
*/
|
|
2250
|
+
useStdErr?: boolean;
|
|
2251
|
+
/**
|
|
2252
|
+
* The log level to use.
|
|
2253
|
+
* @default 'warning'
|
|
2254
|
+
*/
|
|
2255
|
+
logLevel?: 'trace' | 'debug' | 'info' | 'warning' | 'error' | undefined;
|
|
2256
|
+
/**
|
|
2257
|
+
* @default true
|
|
2258
|
+
*/
|
|
2259
|
+
enableTelemetry?: boolean;
|
|
2260
|
+
/**
|
|
2261
|
+
* Enable non-blocking logging (async).
|
|
2262
|
+
* @default false
|
|
2263
|
+
*/
|
|
2264
|
+
nonBlocking?: boolean;
|
|
2265
|
+
/**
|
|
2266
|
+
* Whether to use colors in logging.
|
|
2267
|
+
* @default false
|
|
2268
|
+
*/
|
|
2269
|
+
colors?: boolean;
|
|
2270
|
+
};
|
|
2271
|
+
declare function configureLanguageServerLogger({
|
|
2272
|
+
lspConnection: connection,
|
|
2273
|
+
enableTelemetry,
|
|
2274
|
+
useStdErr,
|
|
2275
|
+
logLevel: lowestLevel,
|
|
2276
|
+
nonBlocking,
|
|
2277
|
+
colors
|
|
2278
|
+
}?: ConfigureLanguageServerLoggerOptions): void;
|
|
2279
|
+
//#endregion
|
|
2234
2280
|
//#region src/index.d.ts
|
|
2235
|
-
|
|
2281
|
+
interface StartLanguageServerOptions {
|
|
2236
2282
|
/**
|
|
2237
2283
|
* The Language Server Protocol connection to use.
|
|
2238
2284
|
*/
|
|
@@ -2242,10 +2288,6 @@ type StartLanguageServerOptions = {
|
|
|
2242
2288
|
* @default true
|
|
2243
2289
|
*/
|
|
2244
2290
|
enableWatcher?: boolean;
|
|
2245
|
-
/**
|
|
2246
|
-
* @default true
|
|
2247
|
-
*/
|
|
2248
|
-
enableTelemetry?: boolean;
|
|
2249
2291
|
/**
|
|
2250
2292
|
* Whether to enable the MCP server.
|
|
2251
2293
|
* @default 'sse'
|
|
@@ -2258,7 +2300,25 @@ type StartLanguageServerOptions = {
|
|
|
2258
2300
|
* @default true
|
|
2259
2301
|
*/
|
|
2260
2302
|
enableManualLayouts?: boolean;
|
|
2261
|
-
|
|
2303
|
+
/**
|
|
2304
|
+
* Whether to use the `dot` binary for layouting or the WebAssembly version.
|
|
2305
|
+
* If {@link connection} is set, {@link ConfigurableLayouter} is started
|
|
2306
|
+
* and this option controls the default layouter implementation used by it.
|
|
2307
|
+
*
|
|
2308
|
+
* @default 'wasm'
|
|
2309
|
+
*/
|
|
2310
|
+
graphviz?: 'wasm' | 'binary';
|
|
2311
|
+
/**
|
|
2312
|
+
* Whether to configure the logger.
|
|
2313
|
+
*
|
|
2314
|
+
* - `false` - don't configure the logger
|
|
2315
|
+
* - `'console'` - configure the logger with console sink
|
|
2316
|
+
* - `'stderr'` - configure the logger with stderr sink
|
|
2317
|
+
*
|
|
2318
|
+
* @default false
|
|
2319
|
+
*/
|
|
2320
|
+
configureLogger?: false | 'console' | 'stderr';
|
|
2321
|
+
}
|
|
2262
2322
|
declare function startLanguageServer$1(options?: StartLanguageServerOptions): {
|
|
2263
2323
|
shared: LikeC4SharedServices;
|
|
2264
2324
|
likec4: LikeC4Services;
|
|
@@ -3035,28 +3095,28 @@ interface LikeC4LanguageServices {
|
|
|
3035
3095
|
* Computes and layouts projects overview - a special diagram
|
|
3036
3096
|
* that shows all projects and their relationships
|
|
3037
3097
|
*/
|
|
3038
|
-
projectsOverview(cancelToken?: CancellationToken$
|
|
3098
|
+
projectsOverview(cancelToken?: CancellationToken$1): Promise<LayoutedProjectsView$1>;
|
|
3039
3099
|
/**
|
|
3040
3100
|
* Returns {@link LikeC4Model} of the specified project, with computed views {@link ComputedView}
|
|
3041
3101
|
* Not ready for rendering, but enough to traverse model. Much faster than {@link layoutedModel}
|
|
3042
3102
|
*
|
|
3043
3103
|
* If no {@link project} is specified, returns for default project
|
|
3044
3104
|
*/
|
|
3045
|
-
computedModel(project?: ProjectId | undefined, cancelToken?: CancellationToken$
|
|
3105
|
+
computedModel(project?: ProjectId | undefined, cancelToken?: CancellationToken$1): Promise<LikeC4Model<UnknownComputed>>;
|
|
3046
3106
|
/**
|
|
3047
3107
|
* Returns {@link LikeC4Model} of the specified project, with layouted views {@link LayoutedView}
|
|
3048
3108
|
* Ready for rendering. Applies manual layouts if available.
|
|
3049
3109
|
*
|
|
3050
3110
|
* If no {@link project} is specified, returns for default project
|
|
3051
3111
|
*/
|
|
3052
|
-
layoutedModel(project?: ProjectId | undefined, cancelToken?: CancellationToken$
|
|
3112
|
+
layoutedModel(project?: ProjectId | undefined, cancelToken?: CancellationToken$1): Promise<LikeC4Model<UnknownLayouted>>;
|
|
3053
3113
|
/**
|
|
3054
3114
|
* Returns diagrams (i.e. layouted views {@link LayoutedView}) for the specified project
|
|
3055
3115
|
* Applies manual layouts if available.
|
|
3056
3116
|
*
|
|
3057
3117
|
* If no {@link project} is specified, returns diagrams for default project
|
|
3058
3118
|
*/
|
|
3059
|
-
diagrams(project?: ProjectId | undefined, cancelToken?: CancellationToken$
|
|
3119
|
+
diagrams(project?: ProjectId | undefined, cancelToken?: CancellationToken$1): Promise<LayoutedView[]>;
|
|
3060
3120
|
getErrors(): Array<{
|
|
3061
3121
|
message: string;
|
|
3062
3122
|
line: number;
|
|
@@ -3067,8 +3127,43 @@ interface LikeC4LanguageServices {
|
|
|
3067
3127
|
* Returns the location of the specified element, relation, view or deployment element
|
|
3068
3128
|
*/
|
|
3069
3129
|
locate(params: Locate.Params): Locate.Res;
|
|
3130
|
+
/**
|
|
3131
|
+
* Formats documents and returns a map of document URI → formatted source text.
|
|
3132
|
+
*
|
|
3133
|
+
* Target selection uses union semantics:
|
|
3134
|
+
* - No options: formats all documents across all projects
|
|
3135
|
+
* - `projectIds`: includes all documents from those projects
|
|
3136
|
+
* - `documentUris`: includes specific documents
|
|
3137
|
+
* - Both: formats the union (deduplicated)
|
|
3138
|
+
*/
|
|
3139
|
+
format(options?: FormatOptions): Promise<Map<string, string>>;
|
|
3070
3140
|
dispose(): Promise<void>;
|
|
3071
3141
|
}
|
|
3142
|
+
/**
|
|
3143
|
+
* Options for {@link LikeC4LanguageServices.format}.
|
|
3144
|
+
*
|
|
3145
|
+
* Target selection uses union semantics:
|
|
3146
|
+
* - Omit both `projectIds` and `documentUris` to format **all** documents.
|
|
3147
|
+
* - Provide `projectIds` to include all documents from those projects.
|
|
3148
|
+
* - Provide `documentUris` to include specific documents.
|
|
3149
|
+
* - Provide both to format the **union** of project documents and specified documents.
|
|
3150
|
+
*/
|
|
3151
|
+
interface FormatOptions {
|
|
3152
|
+
/** Include all documents from these projects. */
|
|
3153
|
+
projectIds?: ReadonlyArray<ProjectId>;
|
|
3154
|
+
/** Include these specific documents (by URI string). */
|
|
3155
|
+
documentUris?: ReadonlyArray<string>;
|
|
3156
|
+
/** Size of a tab in spaces (default: 2). */
|
|
3157
|
+
tabSize?: number;
|
|
3158
|
+
/** Prefer spaces over tabs (default: true). */
|
|
3159
|
+
insertSpaces?: boolean;
|
|
3160
|
+
/** Trim trailing whitespace on a line. */
|
|
3161
|
+
trimTrailingWhitespace?: boolean;
|
|
3162
|
+
/** Insert a newline character at the end of the file if one does not exist. */
|
|
3163
|
+
insertFinalNewline?: boolean;
|
|
3164
|
+
/** Trim all newlines after the final newline at the end of the file. */
|
|
3165
|
+
trimFinalNewlines?: boolean;
|
|
3166
|
+
}
|
|
3072
3167
|
//#endregion
|
|
3073
3168
|
//#region src/lsp/CodeLensProvider.d.ts
|
|
3074
3169
|
declare class LikeC4CodeLensProvider implements CodeLensProvider {
|
|
@@ -3181,7 +3276,7 @@ declare class LikeC4CodeActionProvider implements CodeActionProvider {
|
|
|
3181
3276
|
* @throws `OperationCancelled` if cancellation is detected during execution
|
|
3182
3277
|
* @throws `ResponseError` if an error is detected that should be sent as response to the client
|
|
3183
3278
|
*/
|
|
3184
|
-
getCodeActions(
|
|
3279
|
+
getCodeActions(_document: LangiumDocument, _params: CodeActionParams): CommandOrCodeAction[] | undefined;
|
|
3185
3280
|
}
|
|
3186
3281
|
//#endregion
|
|
3187
3282
|
//#region src/lsp/SemanticTokenProvider.d.ts
|
|
@@ -3190,10 +3285,6 @@ declare class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider
|
|
|
3190
3285
|
private rules;
|
|
3191
3286
|
constructor(services: LikeC4Services);
|
|
3192
3287
|
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
3288
|
protected highlightElement(node: AstNode, acceptor: SemanticTokenAcceptor): void | undefined | 'prune';
|
|
3198
3289
|
private highlightNameAndKind;
|
|
3199
3290
|
private highlightView;
|
|
@@ -3226,7 +3317,6 @@ declare class NodeKindProvider$1 implements NodeKindProvider {
|
|
|
3226
3317
|
declare class WorkspaceSymbolProvider extends DefaultWorkspaceSymbolProvider {}
|
|
3227
3318
|
//#endregion
|
|
3228
3319
|
//#region src/module.d.ts
|
|
3229
|
-
type LanguageServicesContext = Omit<DefaultSharedModuleContext, 'fileSystemProvider'> & FileSystemModuleContext & LikeC4MCPServerModuleContext & LikeC4ManualLayoutsModuleContext;
|
|
3230
3320
|
interface LikeC4AddedSharedServices {
|
|
3231
3321
|
lsp: {
|
|
3232
3322
|
NodeKindProvider: NodeKindProvider$1;
|
|
@@ -3244,6 +3334,7 @@ interface LikeC4AddedSharedServices {
|
|
|
3244
3334
|
};
|
|
3245
3335
|
}
|
|
3246
3336
|
type LikeC4SharedServices = LangiumSharedServices & LikeC4AddedSharedServices;
|
|
3337
|
+
type LikeC4SharedModuleContext = Omit<DefaultSharedModuleContext, 'fileSystemProvider'> & FileSystemModuleContext & LikeC4ManualLayoutsModuleContext;
|
|
3247
3338
|
/**
|
|
3248
3339
|
* Declaration of custom services - add your own service classes here.
|
|
3249
3340
|
*/
|
|
@@ -3262,6 +3353,7 @@ interface LikeC4AddedServices {
|
|
|
3262
3353
|
likec4: {
|
|
3263
3354
|
LanguageServices: LikeC4LanguageServices;
|
|
3264
3355
|
Views: LikeC4Views;
|
|
3356
|
+
Graphviz: GraphvizPort;
|
|
3265
3357
|
Layouter: QueueGraphvizLayoter;
|
|
3266
3358
|
DeploymentsIndex: DeploymentsIndex;
|
|
3267
3359
|
FqnIndex: FqnIndex;
|
|
@@ -3293,12 +3385,14 @@ interface LikeC4AddedServices {
|
|
|
3293
3385
|
};
|
|
3294
3386
|
}
|
|
3295
3387
|
type LikeC4Services = LangiumServices & LikeC4AddedServices;
|
|
3388
|
+
type LikeC4ServicesContext = LikeC4MCPServerModuleContext & LikeC4ViewsModuleContext;
|
|
3296
3389
|
/**
|
|
3297
3390
|
* Most probably you don't need to use this function directly.
|
|
3298
3391
|
* Use {@link createLanguageServices} instead.
|
|
3299
3392
|
* @internal
|
|
3300
3393
|
*/
|
|
3301
|
-
declare function createLikeC4Module(context:
|
|
3394
|
+
declare function createLikeC4Module(context: LikeC4ServicesContext): Module<LikeC4Services, PartialLangiumServices & LikeC4AddedServices>;
|
|
3395
|
+
type LanguageServicesContext = LikeC4SharedModuleContext & LikeC4ServicesContext;
|
|
3302
3396
|
/**
|
|
3303
3397
|
* Create and initialize likec4 language services with the given context
|
|
3304
3398
|
* @example
|
|
@@ -3344,4 +3438,4 @@ declare function createLanguageServices<I1, I2, I3, I extends I1 & I2 & I3 & Lik
|
|
|
3344
3438
|
*/
|
|
3345
3439
|
declare function createSharedServices(context?: Partial<LanguageServicesContext>): LikeC4SharedServices;
|
|
3346
3440
|
//#endregion
|
|
3347
|
-
export {
|
|
3441
|
+
export { LikeC4MCPServerFactory as A, FileSystemProvider$1 as B, LikeC4ModelLocator as C, LikeC4WorkspaceManager as D, FqnIndex as E, NoFileSystem as F, ManualLayoutsSnapshot as G, FileSystemWatcherModuleContext as H, NoFileSystemWatcher as I, ProjectsManager as J, Project as K, NoLikeC4ManualLayouts as L, WithLikeC4ManualLayouts as M, WithChokidarWatcher as N, LangiumDocuments as O, WithFileSystem as P, FileNode as R, NoMCPServer as S, LikeC4ModelBuilder as T, LikeC4ManualLayouts as U, FileSystemWatcher as V, LikeC4ManualLayoutsModuleContext as W, LikeC4ViewsModuleContext as _, LikeC4SharedModuleContext as a, LikeC4Views as b, createLikeC4Module as c, LikeC4LanguageServices as d, DocumentParser as f, configureLanguageServerLogger as g, ConfigureLanguageServerLoggerOptions as h, LikeC4ServicesContext as i, LikeC4MCPServerModuleContext as j, LikeC4MCPServer as k, createSharedServices as l, startLanguageServer$1 as m, LikeC4AddedServices as n, LikeC4SharedServices as o, LikeC4ModelParser as p, ProjectData as q, LikeC4Services as r, createLanguageServices as s, LanguageServicesContext as t, FormatOptions as u, WithGraphviz as v, ViewLocateResult as w, WithMCPServer as x, WithWasmGraphviz as y, FileSystemModuleContext as z };
|