@likec4/language-server 1.56.0 → 1.57.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.
@@ -1,3 +1,3 @@
1
- import{t as e}from"./icons.mjs";import{isLikeC4Builtin as t}from"../likec4lib.mjs";import{c as n,ci as r,l as i,n as a,o,oi as s,s as c}from"./utils.mjs";import{isLikeC4Config as l,loadConfig as u}from"@likec4/config/node";import{compareNaturalHierarchically as d,objectHash as f,onNextTick as p}from"@likec4/core/utils";import{fdir as m}from"fdir";import{SimpleCache as h,URI as g,UriUtils as _}from"langium";import{NodeFileSystemProvider as v}from"langium/node";import{mkdirSync as y,statSync as b}from"node:fs";import{unlink as x,writeFile as S}from"node:fs/promises";import{basename as C,dirname as w}from"node:path";import T from"chokidar";import E from"p-queue";import{exact as D}from"@likec4/core";import O from"json5";import k from"p-limit";import{indexBy as A,prop as j}from"remeda";import{Position as M,Range as N}from"vscode-languageserver-types";const P=s.getChild(`manual-layouts`),F=`.likec4.snap`,isManualLayoutFile=e=>e!==F&&e.endsWith(F);function fileName(e){return`${e}${F}`}function viewIdFromURI(e){let t=_.basename(e);return isManualLayoutFile(t)?t.slice(0,-12):null}function getManualLayoutsOutDir(e){return _.resolvePath(e.folderUri,e.config.manualLayouts?.outDir??`.likec4`)}const I={manualLayouts:e=>new DefaultLikeC4ManualLayouts(e)},L=`file://./`;var DefaultLikeC4ManualLayouts=class{cache;listeners=[];#e=k(1);constructor(e){this.services=e,this.cache=new h,p(()=>{e.workspace.ProjectsManager.onProjectsUpdate(()=>{this.clearCaches()})})}async handleFileSystemUpdate(e){let t=e.update??e.delete,n=viewIdFromURI(t)??void 0,r=this.services.workspace.ProjectsManager.ownerProjectId(t);if(this.cache.delete(r),`delete`in e){this.triggerUpdate(D({removed:t,projectId:r,viewId:n}));return}let i=this.services.workspace.ProjectsManager.getProject(r);if(!n){let e=await this.readSnapshot(t,i);e?n=e.id:(P.error(`Snapshot ${t.fsPath} does not exist or is invalid`),n=`index`)}this.triggerUpdate({updated:t,projectId:r,viewId:n})}onManualLayoutUpdate(e){return this.listeners.push(e),{dispose:()=>{let t=this.listeners.indexOf(e);t!==-1&&this.listeners.splice(t,1)}}}async readManualLayouts(e){let t=P.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=O.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.trace`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=A(i,j(`id`));return{hash:f(a),views:a}}async readSnapshot(e,t){let n=this.services.workspace.FileSystemProvider;try{let r=await n.readFile(e),i=O.parse(r);if(!t){let n=this.services.workspace.ProjectsManager.ownerProjectId(e);t=this.services.workspace.ProjectsManager.getProject(n)}return{...this.resolveIconPathsAfterRead(i,t.folderUri),_layout:`manual`}}catch(t){return P.warn(`Failed to read view snapshot ${e.fsPath}`,{err:t}),null}}async read(e){return await this.#e(async()=>{let t=this.cache.get(e.id);if(t!==void 0)return t;let n=await this.readManualLayouts(e);return this.cache.set(e.id,n),n})}async write(e,t){this.cache.delete(e.id);let n=P.getChild(e.id),r=getManualLayoutsOutDir(e),i=_.joinPath(r,fileName(t.id));if(`manualLayout`in t){let{manualLayout:e,...n}=t;t=n}let a=O.stringify(this.normalizeIconPathsForWrite(t,e.folderUri),{space:2,quote:`'`}),o={uri:i.toString(),range:N.create(M.create(0,0),M.create(a.split(`
1
+ import{t as e}from"./icons.mjs";import{isLikeC4Builtin as t}from"../likec4lib.mjs";import{c as n,l as r,n as i,o as a,oi as o,s,ui as c}from"./utils.mjs";import{compareNaturalHierarchically as l,onNextTick as u,stringHash as d}from"@likec4/core/utils";import{isLikeC4Config as f,loadConfig as p}from"@likec4/config/node";import{fdir as m}from"fdir";import{SimpleCache as h,URI as g,UriUtils as _}from"langium";import{NodeFileSystemProvider as v}from"langium/node";import{mkdirSync as y,statSync as b}from"node:fs";import{unlink as x,writeFile as S}from"node:fs/promises";import{basename as C,dirname as w}from"node:path";import T from"chokidar";import E from"p-queue";import{exact as D}from"@likec4/core";import O from"json5";import k from"p-limit";import{indexBy as A,prop as j}from"remeda";import{Position as M,Range as N}from"vscode-languageserver-types";const P=c.getChild(`manual-layouts`),F=`.likec4.snap`,isManualLayoutFile=e=>e!==F&&e.endsWith(F);function fileName(e){return`${e}${F}`}function viewIdFromURI(e){let t=_.basename(e);return isManualLayoutFile(t)?t.slice(0,-12):null}function getManualLayoutsOutDir(e){return _.resolvePath(e.folderUri,e.config.manualLayouts?.outDir??`.likec4`)}const I={manualLayouts:e=>new DefaultLikeC4ManualLayouts(e)},L=`file://./`;var DefaultLikeC4ManualLayouts=class{services;cache;listeners=[];#e=k(1);constructor(e){this.services=e,this.cache=new h,u(()=>{e.workspace.ProjectsManager.onProjectsUpdate(()=>{this.clearCaches()})})}async handleFileSystemUpdate(e){let t=e.update??e.delete,n=viewIdFromURI(t)??void 0,r=this.services.workspace.ProjectsManager.ownerProjectId(t);if(this.cache.delete(r),`delete`in e){this.triggerUpdate(D({removed:t,projectId:r,viewId:n}));return}let i=this.services.workspace.ProjectsManager.getProject(r);if(!n){let e=await this.readSnapshot(t,i);e?n=e.id:(P.error(`Snapshot ${t.fsPath} does not exist or is invalid`),n=`index`)}this.triggerUpdate({updated:t,projectId:r,viewId:n})}onManualLayoutUpdate(e){return this.listeners.push(e),{dispose:()=>{let t=this.listeners.indexOf(e);t!==-1&&this.listeners.splice(t,1)}}}async readManualLayouts(e){let t=P.getChild(e.id),n=this.services.workspace.FileSystemProvider,r=getManualLayoutsOutDir(e),i=[],a=`${r.toString()}`;try{let o=await n.scanDirectory(r,isManualLayoutFile);if(o.length===0)return null;o.sort((e,t)=>e.uri.path.localeCompare(t.uri.path));for(let r of o)try{let t=await n.readFile(r.uri),o=O.parse(t);a=d(a+r.uri.toString()+t);let s=this.resolveIconPathsAfterRead(o,e.folderUri);i.push({...s,_layout:`manual`})}catch(e){t.warn(`Failed to read view snapshot ${r.uri.fsPath}`,{err:e})}i.length&&t.trace`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 o=A(i,j(`id`));return{hash:a,views:o}}async readSnapshot(e,t){let n=this.services.workspace.FileSystemProvider;try{let r=await n.readFile(e),i=O.parse(r);if(!t){let n=this.services.workspace.ProjectsManager.ownerProjectId(e);t=this.services.workspace.ProjectsManager.getProject(n)}return{...this.resolveIconPathsAfterRead(i,t.folderUri),_layout:`manual`}}catch(t){return P.warn(`Failed to read view snapshot ${e.fsPath}`,{err:t}),null}}async read(e){return await this.#e(async()=>{let t=this.cache.get(e.id);if(t!==void 0)return P.trace`cache hit project ${e.id}`,t;let n=await this.readManualLayouts(e);return this.cache.set(e.id,n),n})}async write(e,t){this.cache.delete(e.id);let n=P.getChild(e.id),r=getManualLayoutsOutDir(e),i=_.joinPath(r,fileName(t.id));if(`manualLayout`in t){let{manualLayout:e,...n}=t;t=n}let a=O.stringify(this.normalizeIconPathsForWrite(t,e.folderUri),{space:2,quote:`'`}),o={uri:i.toString(),range:N.create(M.create(0,0),M.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
- `),this.triggerUpdate({updated:i,projectId:e.id,viewId:t.id})}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=P.getChild(e.id),r=getManualLayoutsOutDir(e),i=_.joinPath(r,fileName(t));n.debug`delete snapshot of ${t} in project ${e.id}. File: ${i.fsPath}`;let a={uri:i.toString(),range:N.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;this.triggerUpdate({removed:i,projectId:e.id,viewId:t})}catch(e){n.warn(`Failed to delete snapshot ${t} from ${i.fsPath}`,{err:e})}return a}clearCaches(){P.trace`clear caches`,this.cache.clear()}triggerUpdate(e){for(let t of this.listeners)a(()=>t(e))}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=g.parse(e.icon),r=_.relative(t,n);return r.startsWith(`..`)?e:{...e,icon:`${L}${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(L)){let n=e.icon.substring(9),r=_.joinPath(t,n);return{...e,icon:r.toString()}}return e});return{...e,nodes:n}}};const R=s.getChild(`chokidar`),z={fileSystemWatcher:e=>new ChokidarFileSystemWatcher(e)},isAnyLikeC4File=e=>{let t=C(e);return c(t)||l(t)||isManualLayoutFile(t)};var ChokidarFileSystemWatcher=class{watcher;queue=new E({concurrency:1,timeout:5e3});constructor(e){this.services=e}watch(e){if(this.watcher){R.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){R.debug`create watcher for folder: ${e}`;let t=T.watch(e,{ignored:[e=>n(e),(e,t)=>!!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){R.warn(`Failed on {fileop}`,{fileop:e,error:t})}}).catch(t=>{R.error(`Error on {fileop}`,{fileop:e,error:t})})}async onAddOrChange(e){let t=this.services.workspace,n=C(e),r=g.file(e);switch(!0){case l(n):R.debug`project config changed: ${e}`,t.ManualLayouts.clearCaches(),await t.ProjectsManager.registerConfigFile(r);break;case isManualLayoutFile(n):R.debug`manual layout file changed: ${e}`,await t.ManualLayouts.handleFileSystemUpdate({update:r});break;case c(n):R.debug`file changed: ${e}`,await t.DocumentBuilder.update([r],[]);break;default:R.warn`Unknown file change: ${e}`}}async onRemove(e){let t=this.services.workspace,n=C(e),r=g.file(e);switch(!0){case l(n):R.debug`project file removed: ${e}`,t.ManualLayouts.clearCaches(),await t.ProjectsManager.reloadProjects();break;case c(n):R.debug`file removed: ${e}`,await t.DocumentBuilder.update([],[r]);break;case isManualLayoutFile(n):R.debug`manual layout file removed: ${e}`,await t.ManualLayouts.handleFileSystemUpdate({delete:r});break;default:R.warn`Unknown file removal: ${e}`}}async onRemoveDir(e){R.debug`directory removed: ${e}`;let t=this.services.workspace;t.ProjectsManager.findOverlaped(e).length>0&&(t.ManualLayouts.clearCaches(),await t.ProjectsManager.reloadProjects())}};const B=s.getChild(`filesystem`);function isLikeC4ConfigFile(e,t=!1){return!t&&l(C(e))}function isLikeC4File(e,t=!1){return!t&&c(C(e))}const WithFileSystem=(e=!0)=>({fileSystemProvider:()=>new SymLinkTraversingFileSystemProvider,...e?z:r});var SymLinkTraversingFileSystemProvider=class extends v{async readFile(n){if(t(n))return Promise.resolve(e);try{return await super.readFile(n)}catch(e){return B.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 m().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:g.file(e)})}catch(t){B.warn(`Failed to read directory ${e.fsPath}`,{error:t})}return a.sort(o)}async scanProjectFiles(e){let t=await this.scanDirectory(e,isLikeC4ConfigFile);if(t.length<=1)return t;let n=d(`/`,!0);return t.sort((e,t)=>n(e.uri.path,t.uri.path))}async scanDirectory(e,t){let n=[];try{let r=await new m().withSymlinks({resolvePaths:!1}).exclude(i).withFullPaths().filter(t).crawl(e.fsPath).withPromise();for(let e of r)n.push({isFile:!0,isDirectory:!1,uri:g.file(e)})}catch(t){B.warn(`Failed to scan directory {path}`,{path:e.fsPath,error:t})}return n}async loadProjectConfig(e){return await u(e)}async writeFile(e,t){let n=w(e.fsPath),r=b(n,{throwIfNoEntry:!1});if(r?.isFile())throw Error(`Cannot create directory ${n} because a file with the same name exists.`);return r||(B.debug(`creating directory {path}`,{path:n}),y(n,{recursive:!0})),B.debug(`writing file {path}`,{path:e.fsPath}),await S(e.fsPath,t,{encoding:`utf-8`})}async deleteFile(e){try{let t=e.fsPath,n=b(t,{throwIfNoEntry:!1});return n?.isFile()||n?.isSymbolicLink()?(await x(t),B.debug(`deleted file {path}`,{path:t}),!0):(B.warn(`deleteFile failed: {path} does not exist, or is not a file`,{path:t}),!1)}catch(t){B.warn(`Failed to delete file ${e.fsPath}`,{error:t})}return!1}};export{z as n,I as r,WithFileSystem as t};
3
+ `),this.triggerUpdate({updated:i,projectId:e.id,viewId:t.id})}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=P.getChild(e.id),r=getManualLayoutsOutDir(e),i=_.joinPath(r,fileName(t));n.debug`delete snapshot of ${t} in project ${e.id}. File: ${i.fsPath}`;let a={uri:i.toString(),range:N.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;this.triggerUpdate({removed:i,projectId:e.id,viewId:t})}catch(e){n.warn(`Failed to delete snapshot ${t} from ${i.fsPath}`,{err:e})}return a}clearCaches(){P.trace`clear caches`,this.cache.clear()}triggerUpdate(e){for(let t of this.listeners)i(()=>t(e))}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=g.parse(e.icon),r=_.relative(t,n);return r.startsWith(`..`)?e:{...e,icon:`${L}${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(L)){let n=e.icon.substring(9),r=_.joinPath(t,n);return{...e,icon:r.toString()}}return e});return{...e,nodes:n}}};const R=c.getChild(`chokidar`),z={fileSystemWatcher:e=>new ChokidarFileSystemWatcher(e)},isAnyLikeC4File=e=>{let t=C(e);return s(t)||f(t)||isManualLayoutFile(t)};var ChokidarFileSystemWatcher=class{services;watcher;queue=new E({concurrency:1,timeout:5e3});constructor(e){this.services=e,R.debug`ChokidarFileSystemWatcher created`}watch(e){if(this.watcher){R.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){R.debug`create watcher for folder: ${e}`;let t=T.watch(e,{ignored:[e=>n(e),(e,t)=>!!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){R.warn(`Failed on {fileop}`,{fileop:e,error:t})}}).catch(t=>{R.error(`Error on {fileop}`,{fileop:e,error:t})})}async onAddOrChange(e){let t=this.services.workspace,n=C(e),r=g.file(e);switch(!0){case f(n):R.debug`project config changed: ${e}`,t.ManualLayouts.clearCaches(),await t.ProjectsManager.registerConfigFile(r);break;case isManualLayoutFile(n):R.debug`manual layout file changed: ${e}`,await t.ManualLayouts.handleFileSystemUpdate({update:r});break;case s(n):R.debug`file changed: ${e}`,await t.DocumentBuilder.update([r],[]);break;default:R.warn`Unknown file change: ${e}`}}async onRemove(e){let t=this.services.workspace,n=C(e),r=g.file(e);switch(!0){case f(n):R.debug`project file removed: ${e}`,t.ManualLayouts.clearCaches(),await t.ProjectsManager.reloadProjects();break;case s(n):R.debug`file removed: ${e}`,await t.DocumentBuilder.update([],[r]);break;case isManualLayoutFile(n):R.debug`manual layout file removed: ${e}`,await t.ManualLayouts.handleFileSystemUpdate({delete:r});break;default:R.warn`Unknown file removal: ${e}`}}async onRemoveDir(e){R.debug`directory removed: ${e}`;let t=this.services.workspace;t.ProjectsManager.findOverlaped(e).length>0&&(t.ManualLayouts.clearCaches(),await t.ProjectsManager.reloadProjects())}};const B=c.getChild(`filesystem`);function isLikeC4ConfigFile(e,t=!1){return!t&&f(C(e))}function isLikeC4File(e,t=!1){return!t&&s(C(e))}const WithFileSystem=(e=!1)=>({fileSystemProvider:()=>new SymLinkTraversingFileSystemProvider,...e?z:o});var SymLinkTraversingFileSystemProvider=class extends v{async readFile(n){if(t(n))return Promise.resolve(e);try{return await super.readFile(n)}catch(e){return B.warn(`Failed to read file ${n.fsPath}`,{error:e}),``}}async readDirectory(e,t){let n=t?.recursive??!0,i=t?.maxDepth??1/0,o=[];try{let t=new m().withSymlinks({resolvePaths:!1}).exclude(r).withFullPaths().filter(isLikeC4File);n?i!==1/0&&(t=t.withMaxDepth(i)):t=t.withMaxDepth(1);let a=await t.crawl(e.fsPath).withPromise();for(let e of a)o.push({isFile:!0,isDirectory:!1,uri:g.file(e)})}catch(t){B.warn(`Failed to read directory ${e.fsPath}`,{error:t})}return o.sort(a)}async scanProjectFiles(e){let t=await this.scanDirectory(e,isLikeC4ConfigFile);if(t.length<=1)return t;let n=l(`/`,!0);return t.sort((e,t)=>n(e.uri.path,t.uri.path))}async scanDirectory(e,t){let n=[];try{let i=await new m().withSymlinks({resolvePaths:!1}).exclude(r).withFullPaths().filter(t).crawl(e.fsPath).withPromise();for(let e of i)n.push({isFile:!0,isDirectory:!1,uri:g.file(e)})}catch(t){B.warn(`Failed to scan directory {path}`,{path:e.fsPath,error:t})}return n}async loadProjectConfig(e){return await p(e)}async writeFile(e,t){let n=w(e.fsPath),r=b(n,{throwIfNoEntry:!1});if(r?.isFile())throw Error(`Cannot create directory ${n} because a file with the same name exists.`);return r||(B.debug(`creating directory {path}`,{path:n}),y(n,{recursive:!0})),B.debug(`writing file {path}`,{path:e.fsPath}),await S(e.fsPath,t,{encoding:`utf-8`})}async deleteFile(e){try{let t=e.fsPath,n=b(t,{throwIfNoEntry:!1});return n?.isFile()||n?.isSymbolicLink()?(await x(t),B.debug(`deleted file {path}`,{path:t}),!0):(B.warn(`deleteFile failed: {path} does not exist, or is not a file`,{path:t}),!1)}catch(t){B.warn(`Failed to delete file ${e.fsPath}`,{error:t})}return!1}};export{z as n,I as r,WithFileSystem as t};
@@ -18,6 +18,7 @@ import { Fqn as Fqn$1, GuardedBy, LayoutedView as LayoutedView$1, ProjectId as P
18
18
  import { CancellationToken as CancellationToken$1 } from "vscode-jsonrpc";
19
19
  import * as type_fest0 from "type-fest";
20
20
  import { ConditionalPick, MergeExclusive, Simplify, Tagged, ValueOf, Writable } from "type-fest";
21
+ import { AILayoutHints } from "@likec4/layouts/ai";
21
22
 
22
23
  //#region src/documentation/documentation-provider.d.ts
23
24
  /**
@@ -383,7 +384,7 @@ type DeploymentElement = DeployedInstance | DeploymentNode;
383
384
  declare const DeploymentElement = "DeploymentElement";
384
385
  type DeploymentNodeOrElementKind = DeploymentNodeKind | ElementKind;
385
386
  declare const DeploymentNodeOrElementKind = "DeploymentNodeOrElementKind";
386
- type DeploymentViewRule = DeploymentViewRulePredicate | DeploymentViewRuleStyle | ViewRuleAutoLayout;
387
+ type DeploymentViewRule = DeploymentViewRulePredicate | DeploymentViewRuleStyle | ViewRuleAncestors | ViewRuleAutoLayout;
387
388
  declare const DeploymentViewRule = "DeploymentViewRule";
388
389
  type DynamicViewDisplayVariantValue = 'diagram' | 'sequence';
389
390
  type DynamicViewProperty = DynamicViewDisplayVariantProperty | ViewProperty;
@@ -515,7 +516,7 @@ declare const CustomElementProperties = "CustomElementProperties";
515
516
  interface CustomRelationProperties extends langium.AstNode {
516
517
  readonly $container: AbstractDynamicStep | RelationExprWith;
517
518
  readonly $type: 'CustomRelationProperties';
518
- props: Array<NotationProperty | NotesProperty | RelationNavigateToProperty | RelationStringProperty | RelationshipStyleProperty>;
519
+ props: Array<MultipleProperty | NotationProperty | NotesProperty | RelationNavigateToProperty | RelationStringProperty | RelationshipStyleProperty>;
519
520
  }
520
521
  declare const CustomRelationProperties = "CustomRelationProperties";
521
522
  interface DeployedInstance extends langium.AstNode {
@@ -994,7 +995,7 @@ interface MetadataAttribute extends langium.AstNode {
994
995
  readonly $container: MetadataBody;
995
996
  readonly $type: 'MetadataAttribute';
996
997
  boolValue: boolean;
997
- key: string;
998
+ key: Id;
998
999
  value?: MetadataValue;
999
1000
  }
1000
1001
  declare const MetadataAttribute = "MetadataAttribute";
@@ -1028,7 +1029,7 @@ interface ModelViews extends langium.AstNode {
1028
1029
  }
1029
1030
  declare const ModelViews = "ModelViews";
1030
1031
  interface MultipleProperty extends langium.AstNode {
1031
- readonly $container: CustomElementProperties | DeploymentViewRuleStyle | ElementStyleProperty | GlobalStyle | ViewRuleStyle;
1032
+ readonly $container: CustomElementProperties | CustomRelationProperties | DeploymentViewRuleStyle | ElementStyleProperty | GlobalStyle | SpecificationRelationshipKind | ViewRuleStyle;
1032
1033
  readonly $type: 'MultipleProperty';
1033
1034
  key: 'multiple';
1034
1035
  value: boolean;
@@ -1203,7 +1204,7 @@ interface SpecificationRelationshipKind extends langium.AstNode {
1203
1204
  readonly $container: SpecificationRule;
1204
1205
  readonly $type: 'SpecificationRelationshipKind';
1205
1206
  kind: RelationshipKind;
1206
- props: Array<RelationshipStyleProperty | SpecificationRelationshipStringProperty>;
1207
+ props: Array<MultipleProperty | RelationshipStyleProperty | SpecificationRelationshipStringProperty>;
1207
1208
  }
1208
1209
  declare const SpecificationRelationshipKind = "SpecificationRelationshipKind";
1209
1210
  interface SpecificationRelationshipStringProperty extends langium.AstNode {
@@ -1277,6 +1278,13 @@ interface ViewRef extends langium.AstNode {
1277
1278
  view: langium.Reference<LikeC4View>;
1278
1279
  }
1279
1280
  declare const ViewRef = "ViewRef";
1281
+ interface ViewRuleAncestors extends langium.AstNode {
1282
+ readonly $container: DeploymentViewBody;
1283
+ readonly $type: 'ViewRuleAncestors';
1284
+ key: 'includeAncestors';
1285
+ value: boolean;
1286
+ }
1287
+ declare const ViewRuleAncestors = "ViewRuleAncestors";
1280
1288
  interface ViewRuleAutoLayout extends langium.AstNode {
1281
1289
  readonly $container: DeploymentViewBody | DynamicViewBody | ElementViewBody;
1282
1290
  readonly $type: 'ViewRuleAutoLayout';
@@ -1594,6 +1602,7 @@ type LikeC4AstType = {
1594
1602
  ViewProperty: ViewProperty;
1595
1603
  ViewRef: ViewRef;
1596
1604
  ViewRule: ViewRule;
1605
+ ViewRuleAncestors: ViewRuleAncestors;
1597
1606
  ViewRuleAutoLayout: ViewRuleAutoLayout;
1598
1607
  ViewRuleGlobalPredicateRef: ViewRuleGlobalPredicateRef;
1599
1608
  ViewRuleGlobalStyle: ViewRuleGlobalStyle;
@@ -1703,6 +1712,7 @@ interface ParsedAstSpecification {
1703
1712
  line?: c4.RelationshipLineType;
1704
1713
  head?: c4.RelationshipArrowType;
1705
1714
  tail?: c4.RelationshipArrowType;
1715
+ multiple?: boolean;
1706
1716
  }>;
1707
1717
  colors: Record<c4.CustomColor, {
1708
1718
  color: c4.ColorLiteral;
@@ -2267,7 +2277,8 @@ type LayoutViewParams = {
2267
2277
  */
2268
2278
  layoutType?: LayoutType | undefined;
2269
2279
  projectId?: ProjectId | undefined;
2270
- cancelToken?: CancellationToken | undefined;
2280
+ cancelToken?: CancellationToken | undefined; /** Optional AI-generated layout hints */
2281
+ layoutHints?: AILayoutHints | undefined;
2271
2282
  };
2272
2283
  interface LikeC4Views {
2273
2284
  readonly layouter: GraphvizLayouter;
@@ -2285,10 +2296,12 @@ interface LikeC4Views {
2285
2296
  layoutAllViews(projectId?: ProjectId | undefined, cancelToken?: CancellationToken): Promise<GraphvizOut[]>;
2286
2297
  /**
2287
2298
  * Layouts a view.
2288
- * If layoutType is 'manual' - applies manual layout if any.
2289
- * If layoutType is 'auto' - returns latest version with drifts from manual layout if any
2299
+ * If `layoutType` is 'manual' - applies manual layout if any.
2300
+ * If `layoutType` is 'auto' - returns latest version with drifts from manual layout if any
2290
2301
  * If not specified - returns latest layout as is
2291
2302
  *
2303
+ * If `layoutHints` are provided, they will be used, ignoring any manual snapshots, and the resulting layout will not be cached (i.e. it will be computed on every call)
2304
+ *
2292
2305
  * If view not found in model, but there is a snapshot - it will be returned (with empty DOT)
2293
2306
  */
2294
2307
  layoutView(params: LayoutViewParams): Promise<GraphvizOut | null>;
@@ -3160,7 +3173,7 @@ declare class LikeC4ModelChanges {
3160
3173
  change
3161
3174
  }: {
3162
3175
  lookup: ViewLocateResult;
3163
- change: Exclude<ViewChange, ViewChange.SaveViewSnapshot | ViewChange.ResetManualLayout>;
3176
+ change: Exclude<ViewChange, ViewChange.SaveViewSnapshot | ViewChange.ResetManualLayout | ViewChange.ChangeProperty>;
3164
3177
  }): {
3165
3178
  modifiedRange: Range;
3166
3179
  edits: TextEdit[];
@@ -3319,7 +3332,7 @@ declare class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
3319
3332
  protected getSpecSymbol(astSpec: SpecificationRule): DocumentSymbol[];
3320
3333
  protected getModelSymbol(astModel: Model): DocumentSymbol[];
3321
3334
  protected getDeploymentModelSymbol(astModel: ModelDeployments): DocumentSymbol[];
3322
- protected getElementsSymbol(el: Element | Relation | ExtendElement): DocumentSymbol[];
3335
+ protected getElementsSymbol(el: Element | Relation | ExtendElement, parentFqn?: string): DocumentSymbol[];
3323
3336
  protected getExtendElementSymbol(astElement: ExtendElement): DocumentSymbol[];
3324
3337
  protected getElementSymbol(astElement: Element): DocumentSymbol[];
3325
3338
  protected getModelViewsSymbol(astViews: ModelViews): DocumentSymbol[];
@@ -3538,4 +3551,4 @@ declare function createLanguageServices<I1, I2, I3, I extends I1 & I2 & I3 & Lik
3538
3551
  */
3539
3552
  declare function createSharedServices(context?: Partial<LanguageServicesContext>): LikeC4SharedServices;
3540
3553
  //#endregion
3541
- export { NoFileSystem as A, ManualLayoutsSnapshot as B, LikeC4ModelBuilder as C, WithLikeC4ManualLayouts as D, LangiumDocuments as E, FileSystemProvider$1 as F, ProjectData as H, FileSystemWatcher as I, FileSystemWatcherModuleContext as L, NoLikeC4ManualLayouts as M, FileNode as N, WithChokidarWatcher as O, FileSystemModuleContext as P, LikeC4ManualLayouts as R, ViewLocateResult as S, LikeC4WorkspaceManager as T, ProjectsManager as U, Project as V, 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, NoFileSystemWatcher as j, WithFileSystem as k, createSharedServices as l, startLanguageServer$1 as m, LikeC4AddedServices as n, LikeC4SharedServices as o, LikeC4ModelParser as p, LikeC4Services as r, createLanguageServices as s, LanguageServicesContext as t, FormatOptions as u, WithGraphviz as v, FqnIndex as w, LikeC4ModelLocator as x, WithWasmGraphviz as y, LikeC4ManualLayoutsModuleContext as z };
3554
+ export { WithFileSystem as A, LikeC4ManualLayoutsModuleContext as B, ViewLocateResult as C, LangiumDocuments as D, LikeC4WorkspaceManager as E, FileSystemModuleContext as F, Project as H, FileSystemProvider$1 as I, FileSystemWatcher as L, NoFileSystemWatcher as M, NoLikeC4ManualLayouts as N, WithLikeC4ManualLayouts as O, FileNode as P, FileSystemWatcherModuleContext as R, LikeC4ModelLocator as S, FqnIndex as T, ProjectData as U, ManualLayoutsSnapshot as V, ProjectsManager as W, LikeC4ViewsModuleContext as _, LikeC4SharedModuleContext as a, LayoutViewParams as b, createLikeC4Module as c, LikeC4LanguageServices as d, DocumentParser as f, configureLanguageServerLogger as g, ConfigureLanguageServerLoggerOptions as h, LikeC4ServicesContext as i, NoFileSystem as j, WithChokidarWatcher as k, createSharedServices as l, startLanguageServer$1 as m, LikeC4AddedServices as n, LikeC4SharedServices as o, LikeC4ModelParser as p, LikeC4Services as r, createLanguageServices as s, LanguageServicesContext as t, FormatOptions as u, WithGraphviz as v, LikeC4ModelBuilder as w, LikeC4Views as x, WithWasmGraphviz as y, LikeC4ManualLayouts as z };