@likec4/language-server 1.36.1 → 1.38.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 (94) hide show
  1. package/dist/LikeC4LanguageServices.d.ts +43 -7
  2. package/dist/LikeC4LanguageServices.js +51 -11
  3. package/dist/Rpc.js +22 -6
  4. package/dist/browser.d.ts +1 -1
  5. package/dist/browser.js +1 -1
  6. package/dist/bundled.mjs +4258 -3083
  7. package/dist/config/schema.d.ts +1 -1
  8. package/dist/config/schema.js +1 -1
  9. package/dist/empty.d.ts +2 -0
  10. package/dist/empty.js +1 -0
  11. package/dist/filesystem/ChokidarWatcher.d.ts +14 -0
  12. package/dist/filesystem/ChokidarWatcher.js +64 -0
  13. package/dist/filesystem/FileSystemWatcher.d.ts +19 -0
  14. package/dist/filesystem/FileSystemWatcher.js +11 -0
  15. package/dist/filesystem/LikeC4FileSystem.d.ts +5 -0
  16. package/dist/filesystem/LikeC4FileSystem.js +56 -0
  17. package/dist/filesystem/index.d.ts +20 -0
  18. package/dist/filesystem/index.js +16 -0
  19. package/dist/index.d.ts +18 -4
  20. package/dist/index.js +23 -10
  21. package/dist/likec4lib.d.ts +1 -1
  22. package/dist/lsp/DocumentLinkProvider.js +3 -3
  23. package/dist/lsp/DocumentSymbolProvider.js +1 -1
  24. package/dist/mcp/{sseserver/MCPServerFactory.d.ts → MCPServerFactory.d.ts} +1 -1
  25. package/dist/mcp/MCPServerFactory.js +69 -0
  26. package/dist/mcp/NoopLikeC4MCPServer.d.ts +4 -10
  27. package/dist/mcp/NoopLikeC4MCPServer.js +5 -10
  28. package/dist/mcp/interfaces.d.ts +7 -5
  29. package/dist/mcp/interfaces.js +4 -0
  30. package/dist/mcp/server/StdioLikeC4MCPServer.d.ts +16 -0
  31. package/dist/mcp/server/StdioLikeC4MCPServer.js +43 -0
  32. package/dist/mcp/{sseserver/MCPServer.d.ts → server/StreamableLikeC4MCPServer.d.ts} +3 -2
  33. package/dist/mcp/server/StreamableLikeC4MCPServer.js +156 -0
  34. package/dist/mcp/server/WithMCPServer.d.ts +2 -0
  35. package/dist/mcp/server/WithMCPServer.js +57 -0
  36. package/dist/mcp/tools/_common.d.ts +24 -5
  37. package/dist/mcp/tools/_common.js +31 -3
  38. package/dist/mcp/tools/find-relationships.d.ts +13 -0
  39. package/dist/mcp/tools/find-relationships.js +151 -0
  40. package/dist/mcp/tools/list-projects.js +42 -14
  41. package/dist/mcp/tools/open-view.d.ts +4 -3
  42. package/dist/mcp/tools/open-view.js +37 -14
  43. package/dist/mcp/tools/{read-project-elements.d.ts → read-deployment.d.ts} +6 -3
  44. package/dist/mcp/tools/read-deployment.js +130 -0
  45. package/dist/mcp/tools/read-element.d.ts +4 -3
  46. package/dist/mcp/tools/read-element.js +114 -51
  47. package/dist/mcp/tools/read-project-summary.d.ts +3 -2
  48. package/dist/mcp/tools/read-project-summary.js +141 -34
  49. package/dist/mcp/tools/read-view.d.ts +4 -3
  50. package/dist/mcp/tools/read-view.js +146 -105
  51. package/dist/mcp/tools/search-element.js +81 -30
  52. package/dist/mcp/utils.js +7 -4
  53. package/dist/model/builder/buildModel.d.ts +1 -1
  54. package/dist/model/builder/buildModel.js +4 -6
  55. package/dist/model/model-parser.d.ts +9 -9
  56. package/dist/model/model-parser.js +3 -0
  57. package/dist/model/parser/Base.d.ts +1 -1
  58. package/dist/model/parser/Base.js +1 -1
  59. package/dist/model/parser/DeploymentModelParser.d.ts +1 -1
  60. package/dist/model/parser/DeploymentViewParser.d.ts +1 -1
  61. package/dist/model/parser/DeploymentViewParser.js +2 -2
  62. package/dist/model/parser/FqnRefParser.d.ts +1 -1
  63. package/dist/model/parser/FqnRefParser.js +8 -1
  64. package/dist/model/parser/GlobalsParser.d.ts +1 -1
  65. package/dist/model/parser/ImportsParser.d.ts +1 -1
  66. package/dist/model/parser/ModelParser.d.ts +1 -1
  67. package/dist/model/parser/PredicatesParser.d.ts +1 -1
  68. package/dist/model/parser/SpecificationParser.d.ts +1 -1
  69. package/dist/model/parser/ViewsParser.d.ts +1 -1
  70. package/dist/model/parser/ViewsParser.js +3 -3
  71. package/dist/module.d.ts +13 -9
  72. package/dist/module.js +28 -30
  73. package/dist/protocol.d.ts +18 -4
  74. package/dist/protocol.js +5 -1
  75. package/dist/test/testServices.d.ts +5 -2
  76. package/dist/test/testServices.js +7 -3
  77. package/dist/validation/DocumentValidator.d.ts +11 -0
  78. package/dist/validation/DocumentValidator.js +16 -0
  79. package/dist/validation/index.d.ts +1 -1
  80. package/dist/validation/index.js +1 -0
  81. package/dist/workspace/LangiumDocuments.d.ts +1 -0
  82. package/dist/workspace/LangiumDocuments.js +10 -1
  83. package/dist/workspace/ProjectsManager.d.ts +35 -17
  84. package/dist/workspace/ProjectsManager.js +168 -54
  85. package/dist/workspace/WorkspaceManager.d.ts +9 -2
  86. package/dist/workspace/WorkspaceManager.js +31 -40
  87. package/package.json +14 -10
  88. package/dist/LikeC4FileSystem.d.ts +0 -14
  89. package/dist/LikeC4FileSystem.js +0 -39
  90. package/dist/mcp/sseserver/MCPServer.js +0 -80
  91. package/dist/mcp/sseserver/MCPServerFactory.js +0 -50
  92. package/dist/mcp/sseserver/WithMCPServer.d.ts +0 -9
  93. package/dist/mcp/sseserver/WithMCPServer.js +0 -53
  94. package/dist/mcp/tools/read-project-elements.js +0 -93
@@ -1,8 +1,7 @@
1
1
  import { type DiagramView, type NonEmptyArray, type ProjectId } from '@likec4/core';
2
2
  import { LikeC4Model } from '@likec4/core/model';
3
- import { URI } from 'langium';
3
+ import { type LangiumDocument, URI } from 'langium';
4
4
  import { type Range } from 'vscode-languageserver-types';
5
- import type { ProjectConfig } from './config';
6
5
  import type { LikeC4ModelBuilder } from './model';
7
6
  import type { LikeC4Services } from './module';
8
7
  import type { Locate } from './protocol';
@@ -13,13 +12,30 @@ export interface LikeC4LanguageServices {
13
12
  readonly builder: LikeC4ModelBuilder;
14
13
  readonly workspaceUri: URI;
15
14
  readonly projectsManager: ProjectsManager;
15
+ /**
16
+ * Returns all projects with relevant documents
17
+ */
16
18
  projects(): NonEmptyArray<{
17
19
  id: ProjectId;
18
20
  folder: URI;
19
- config: ProjectConfig;
20
- documents: NonEmptyArray<URI> | null;
21
+ title: string;
22
+ documents: ReadonlyArray<URI>;
21
23
  }>;
22
- diagrams(): Promise<DiagramView[]>;
24
+ /**
25
+ * Returns project by ID
26
+ * If no project ID is specified, returns default project
27
+ */
28
+ project(projectId?: ProjectId): {
29
+ id: ProjectId;
30
+ folder: URI;
31
+ title: string;
32
+ documents: ReadonlyArray<URI>;
33
+ };
34
+ /**
35
+ * Returns diagrams (i.e. views with layout computed) for the specified project
36
+ * If no project is specified, returns diagrams for default project
37
+ */
38
+ diagrams(project?: ProjectId | undefined): Promise<DiagramView[]>;
23
39
  computedModel(project?: ProjectId | undefined): Promise<LikeC4Model.Computed>;
24
40
  layoutedModel(project?: ProjectId | undefined): Promise<LikeC4Model.Layouted>;
25
41
  getErrors(): Array<{
@@ -28,11 +44,21 @@ export interface LikeC4LanguageServices {
28
44
  range: Range;
29
45
  sourceFsPath: string;
30
46
  }>;
47
+ /**
48
+ * Notifies the language server about changes in the workspace
49
+ */
31
50
  notifyUpdate(update: {
32
51
  changed?: string;
33
52
  removed?: string;
34
53
  }): Promise<boolean>;
54
+ /**
55
+ * Returns the location of the specified element, relation, view or deployment element
56
+ */
35
57
  locate(params: Locate.Params): Locate.Res;
58
+ /**
59
+ * Checks if the specified document should be excluded from processing.
60
+ */
61
+ isExcluded(doc: LangiumDocument): boolean;
36
62
  }
37
63
  /**
38
64
  * Public Language Services
@@ -47,9 +73,15 @@ export declare class DefaultLikeC4LanguageServices implements LikeC4LanguageServ
47
73
  projects(): NonEmptyArray<{
48
74
  id: ProjectId;
49
75
  folder: URI;
50
- config: ProjectConfig;
51
- documents: NonEmptyArray<URI> | null;
76
+ title: string;
77
+ documents: ReadonlyArray<URI>;
52
78
  }>;
79
+ project(projectId?: ProjectId): {
80
+ id: ProjectId;
81
+ folder: URI;
82
+ title: string;
83
+ documents: ReadonlyArray<URI>;
84
+ };
53
85
  /**
54
86
  * Diagram is a computed view, layouted using Graphviz
55
87
  * Used in React components
@@ -80,4 +112,8 @@ export declare class DefaultLikeC4LanguageServices implements LikeC4LanguageServ
80
112
  removed?: string;
81
113
  }): Promise<boolean>;
82
114
  locate(params: Locate.Params): Locate.Res;
115
+ /**
116
+ * Checks if the specified document should be excluded from processing.
117
+ */
118
+ isExcluded(doc: LangiumDocument): boolean;
83
119
  }
@@ -1,10 +1,13 @@
1
- import { nonexhaustive } from "@likec4/core";
1
+ import {
2
+ nonexhaustive
3
+ } from "@likec4/core";
2
4
  import { LikeC4Model } from "@likec4/core/model";
3
5
  import { loggable } from "@likec4/log";
4
6
  import { URI } from "langium";
5
7
  import { entries, hasAtLeast, indexBy, map, pipe, prop } from "remeda";
6
8
  import { DiagnosticSeverity } from "vscode-languageserver-types";
7
- import { logger as mainLogger } from "./logger.js";
9
+ import { isLikeC4LangiumDocument } from "./ast.js";
10
+ import { logger as mainLogger, logWarnError } from "./logger.js";
8
11
  import { ProjectsManager } from "./workspace/index.js";
9
12
  const logger = mainLogger.getChild("LikeC4LanguageServices");
10
13
  export class DefaultLikeC4LanguageServices {
@@ -27,11 +30,11 @@ export class DefaultLikeC4LanguageServices {
27
30
  entries(),
28
31
  map(([projectId, docs]) => {
29
32
  const id = projectId;
30
- const { folder: folder2, config: config2 } = projectsManager.getProject(id);
33
+ const { folderUri: folderUri2, config: config2 } = projectsManager.getProject(id);
31
34
  return {
32
35
  id,
33
- folder: folder2,
34
- config: config2,
36
+ folder: folderUri2,
37
+ title: config2.title ?? config2.name,
35
38
  documents: map(docs, prop("uri"))
36
39
  };
37
40
  })
@@ -39,14 +42,33 @@ export class DefaultLikeC4LanguageServices {
39
42
  if (hasAtLeast(projectsWithDocs, 1)) {
40
43
  return projectsWithDocs;
41
44
  }
42
- const { folder, config } = projectsManager.getProject(ProjectsManager.DefaultProjectId);
45
+ const { folderUri, config } = projectsManager.getProject(ProjectsManager.DefaultProjectId);
46
+ const documents = map(
47
+ this.services.shared.workspace.LangiumDocuments.projectDocuments(ProjectsManager.DefaultProjectId).toArray(),
48
+ prop("uri")
49
+ );
43
50
  return [{
44
51
  id: ProjectsManager.DefaultProjectId,
45
- folder,
46
- config,
47
- documents: null
52
+ folder: folderUri,
53
+ title: config.title ?? config.name,
54
+ documents
48
55
  }];
49
56
  }
57
+ project(projectId) {
58
+ projectId = this.projectsManager.ensureProjectId(projectId);
59
+ const projectsManager = this.services.shared.workspace.ProjectsManager;
60
+ const { folderUri, config } = projectsManager.getProject(projectId);
61
+ const documents = map(
62
+ this.services.shared.workspace.LangiumDocuments.projectDocuments(projectId).toArray(),
63
+ prop("uri")
64
+ );
65
+ return {
66
+ id: projectId,
67
+ folder: folderUri,
68
+ title: config.title ?? config.name,
69
+ documents
70
+ };
71
+ }
50
72
  /**
51
73
  * Diagram is a computed view, layouted using Graphviz
52
74
  * Used in React components
@@ -98,13 +120,20 @@ export class DefaultLikeC4LanguageServices {
98
120
  if (!changed && !removed) {
99
121
  return false;
100
122
  }
123
+ const _changed = changed ? URI.file(changed) : void 0;
124
+ const _removed = removed ? URI.file(removed) : void 0;
125
+ const pm = this.services.shared.workspace.ProjectsManager;
126
+ if (_changed && pm.isConfigFile(_changed) || _removed && pm.isConfigFile(_removed)) {
127
+ await pm.reloadProjects();
128
+ return true;
129
+ }
101
130
  const mutex = this.services.shared.workspace.WorkspaceLock;
102
131
  try {
103
132
  let completed = false;
104
133
  await mutex.write(async (token) => {
105
134
  await this.services.shared.workspace.DocumentBuilder.update(
106
- changed ? [URI.file(changed)] : [],
107
- removed ? [URI.file(removed)] : [],
135
+ _changed ? [_changed] : [],
136
+ _removed ? [_removed] : [],
108
137
  token
109
138
  );
110
139
  completed = !token.isCancellationRequested;
@@ -132,4 +161,15 @@ export class DefaultLikeC4LanguageServices {
132
161
  nonexhaustive(params);
133
162
  }
134
163
  }
164
+ /**
165
+ * Checks if the specified document should be excluded from processing.
166
+ */
167
+ isExcluded(doc) {
168
+ try {
169
+ return !isLikeC4LangiumDocument(doc) || this.services.shared.workspace.ProjectsManager.checkIfExcluded(doc);
170
+ } catch (e) {
171
+ logWarnError(e);
172
+ return false;
173
+ }
174
+ }
135
175
  }
package/dist/Rpc.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  } from "@likec4/core";
6
6
  import { LikeC4Model } from "@likec4/core/model";
7
7
  import { Disposable, interruptAndCheck, URI, UriUtils } from "langium";
8
- import { DiagnosticSeverity } from "vscode-languageserver";
8
+ import { DiagnosticSeverity } from "vscode-languageserver-protocol";
9
9
  import {
10
10
  BuildDocuments,
11
11
  ChangeView,
@@ -20,6 +20,7 @@ import {
20
20
  GetDocumentTags,
21
21
  LayoutView,
22
22
  Locate,
23
+ ReloadProjects,
23
24
  ValidateLayout
24
25
  } from "./protocol.js";
25
26
  import { ADisposable } from "./utils/index.js";
@@ -46,14 +47,14 @@ export class Rpc extends ADisposable {
46
47
  const notifyModelParsed = funnel(
47
48
  () => {
48
49
  logger.debug`sendNotification ${"onDidChangeModel"}`;
49
- connection.sendNotification(DidChangeModelNotification.type, "").catch((e) => {
50
- logger.warn(`[ServerRpc] error sending onDidChangeModel: ${e}`);
51
- return Promise.resolve();
50
+ connection.sendNotification(DidChangeModelNotification.type, "").catch((error) => {
51
+ logger.warn(`[ServerRpc] error sending onDidChangeModel:`, { error });
52
+ return;
52
53
  });
53
54
  },
54
55
  {
55
56
  triggerAt: "end",
56
- minQuietPeriodMs: 100,
57
+ minQuietPeriodMs: 150,
57
58
  maxBurstDurationMs: 500,
58
59
  minGapMs: 300
59
60
  }
@@ -106,9 +107,24 @@ export class Rpc extends ADisposable {
106
107
  logger.debug`received request ${"FetchProjects"}`;
107
108
  const docsByProject = LangiumDocuments.groupedByProject();
108
109
  return {
109
- projects: mapValues(docsByProject, (docs) => map(docs, (d) => d.uri.toString()))
110
+ projects: mapValues(docsByProject, (docs, projectId) => {
111
+ const {
112
+ folderUri,
113
+ config
114
+ } = projects.getProject(projectId);
115
+ return {
116
+ folder: folderUri.toString(),
117
+ config,
118
+ docs: map(docs, (d) => d.uri.toString())
119
+ };
120
+ })
110
121
  };
111
122
  }),
123
+ connection.onRequest(ReloadProjects.req, async (cancelToken) => {
124
+ logger.debug`received request ${"ReloadProjects"}`;
125
+ await projects.reloadProjects(cancelToken);
126
+ return;
127
+ }),
112
128
  connection.onRequest(FetchViewsFromAllProjects.req, async (cancelToken) => {
113
129
  logger.debug`received request ${"FetchViewsFromAllProjects"}`;
114
130
  const promises = projects.all.map(async (projectId) => {
package/dist/browser.d.ts CHANGED
@@ -2,7 +2,7 @@ import { type LikeC4Services, type LikeC4SharedServices } from './module';
2
2
  export { logger as lspLogger } from './logger';
3
3
  export type { DocumentParser, LikeC4ModelBuilder, LikeC4ModelLocator, LikeC4ModelParser } from './model';
4
4
  export type { LikeC4LanguageServices } from './LikeC4LanguageServices';
5
- export { createCustomLanguageServices, createLanguageServices, LikeC4Module } from './module';
5
+ export { createLanguageServices } from './module';
6
6
  export type { LikeC4Services, LikeC4SharedServices } from './module';
7
7
  export type { LikeC4Views } from './views';
8
8
  export declare function startLanguageServer(port: MessagePort | DedicatedWorkerGlobalScope): {
package/dist/browser.js CHANGED
@@ -3,7 +3,7 @@ import { startLanguageServer as startLanguim } from "langium/lsp";
3
3
  import { BrowserMessageReader, BrowserMessageWriter, createConnection } from "vscode-languageserver/browser";
4
4
  import { createLanguageServices } from "./module.js";
5
5
  export { logger as lspLogger } from "./logger.js";
6
- export { createCustomLanguageServices, createLanguageServices, LikeC4Module } from "./module.js";
6
+ export { createLanguageServices } from "./module.js";
7
7
  export function startLanguageServer(port) {
8
8
  const messageReader = new BrowserMessageReader(port);
9
9
  const messageWriter = new BrowserMessageWriter(port);