@likec4/language-server 1.33.0 → 1.34.1

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 (59) hide show
  1. package/README.md +27 -1
  2. package/dist/Rpc.d.ts +2 -0
  3. package/dist/Rpc.js +24 -6
  4. package/dist/bundled.mjs +2747 -2892
  5. package/dist/formatting/LikeC4Formatter.d.ts +1 -0
  6. package/dist/formatting/LikeC4Formatter.js +25 -1
  7. package/dist/generated/ast.d.ts +1 -1
  8. package/dist/generated/ast.js +5 -5
  9. package/dist/generated/grammar.js +1 -1
  10. package/dist/index.d.ts +0 -1
  11. package/dist/index.js +1 -2
  12. package/dist/mcp/{LikeC4MCPServerFactory.d.ts → NoopLikeC4MCPServer.d.ts} +1 -9
  13. package/dist/mcp/interfaces.d.ts +11 -0
  14. package/dist/mcp/interfaces.js +0 -0
  15. package/dist/mcp/sseserver/MCPServer.d.ts +1 -1
  16. package/dist/mcp/sseserver/MCPServer.js +5 -5
  17. package/dist/mcp/sseserver/MCPServerFactory.js +30 -58
  18. package/dist/mcp/sseserver/{with-mcp-server.d.ts → WithMCPServer.d.ts} +1 -1
  19. package/dist/mcp/tools/_common.d.ts +68 -0
  20. package/dist/mcp/tools/_common.js +14 -0
  21. package/dist/mcp/tools/list-projects.d.ts +6 -0
  22. package/dist/mcp/tools/list-projects.js +31 -0
  23. package/dist/mcp/tools/open-view.d.ts +10 -0
  24. package/dist/mcp/tools/open-view.js +29 -0
  25. package/dist/mcp/tools/read-element.d.ts +10 -0
  26. package/dist/mcp/tools/read-element.js +135 -0
  27. package/dist/mcp/tools/read-project-elements.d.ts +8 -0
  28. package/dist/mcp/tools/read-project-elements.js +93 -0
  29. package/dist/mcp/tools/read-project-summary.d.ts +8 -0
  30. package/dist/mcp/tools/read-project-summary.js +68 -0
  31. package/dist/mcp/tools/read-view.d.ts +10 -0
  32. package/dist/mcp/tools/read-view.js +164 -0
  33. package/dist/mcp/tools/search-element.d.ts +8 -0
  34. package/dist/mcp/tools/search-element.js +105 -0
  35. package/dist/mcp/utils.d.ts +17 -34
  36. package/dist/mcp/utils.js +41 -101
  37. package/dist/model/model-parser-where.d.ts +1 -0
  38. package/dist/model/model-parser-where.js +30 -24
  39. package/dist/model/model-parser.d.ts +14 -0
  40. package/dist/model/parser/DeploymentModelParser.d.ts +3 -1
  41. package/dist/model/parser/DeploymentViewParser.d.ts +3 -1
  42. package/dist/model/parser/FqnRefParser.d.ts +3 -1
  43. package/dist/model/parser/FqnRefParser.js +34 -10
  44. package/dist/model/parser/GlobalsParser.d.ts +3 -1
  45. package/dist/model/parser/ModelParser.d.ts +3 -1
  46. package/dist/model/parser/PredicatesParser.d.ts +3 -1
  47. package/dist/model/parser/ViewsParser.d.ts +3 -1
  48. package/dist/module.d.ts +1 -3
  49. package/dist/module.js +1 -6
  50. package/dist/protocol.d.ts +16 -0
  51. package/dist/protocol.js +4 -0
  52. package/dist/validation/property-checks.js +1 -1
  53. package/dist/views/likec4-views.d.ts +5 -0
  54. package/dist/views/likec4-views.js +6 -0
  55. package/package.json +7 -7
  56. package/dist/mcp/LikeC4MCPTools.d.ts +0 -96
  57. package/dist/mcp/LikeC4MCPTools.js +0 -293
  58. /package/dist/mcp/{LikeC4MCPServerFactory.js → NoopLikeC4MCPServer.js} +0 -0
  59. /package/dist/mcp/sseserver/{with-mcp-server.js → WithMCPServer.js} +0 -0
@@ -1,293 +0,0 @@
1
- import { _type, RichText } from "@likec4/core";
2
- import { loggable } from "@likec4/log";
3
- import { flatMap } from "remeda";
4
- import stripIndent from "strip-indent";
5
- import { z } from "zod";
6
- import { logger as mainLogger } from "../logger.js";
7
- import { toSingleLine } from "../model/parser/Base.js";
8
- import { ProjectsManager } from "../workspace/ProjectsManager.js";
9
- import { elementResource, modelViewResource } from "./utils.js";
10
- const logger = mainLogger.getChild("LikeC4MCPServices");
11
- function singleLine(str) {
12
- if (str === null || str === void 0) {
13
- return "null";
14
- }
15
- const res = toSingleLine(RichText.from(str).text)?.replaceAll('"', "'");
16
- return res ? `"${res}"` : "null";
17
- }
18
- function outputEach(iterator, ifEmpty, output) {
19
- const items = [...iterator];
20
- if (items.length === 0) {
21
- return [ifEmpty];
22
- }
23
- return flatMap(items, output);
24
- }
25
- export var LikeC4MCPTools;
26
- ((LikeC4MCPTools2) => {
27
- LikeC4MCPTools2.instructions = `This server provides access to LikeC4 model.
28
-
29
- Key capabilities:
30
- - List all available LikeC4 projects in the workspace
31
- - Search for LikeC4 project and return its summary, that includes specifications, all elements and views
32
- - Search for LikeC4 element by title
33
- - Read details about LikeC4 element by id
34
- - Read details about LikeC4 view by id
35
-
36
- `;
37
- LikeC4MCPTools2.listProjects = {
38
- name: "list-projects",
39
- description: "Lists all available LikeC4 projects in the workspace"
40
- };
41
- LikeC4MCPTools2.readProjectSummary = {
42
- name: "read-project-summary",
43
- description: stripIndent(`
44
- Searches for LikeC4 project and returns its summary, specifications, elements and views
45
-
46
- Args:
47
- project: Project name
48
- `),
49
- paramsSchema: {
50
- project: z.string().optional()
51
- }
52
- };
53
- LikeC4MCPTools2.searchElement = {
54
- name: "search-element",
55
- description: stripIndent(`
56
- Search for LikeC4 elements that have the search string in their names
57
- Can be used to resolve projects for further requests (like read-element or read-project-summary)
58
-
59
- Args:
60
- search: non-empty string
61
- `),
62
- paramsSchema: {
63
- search: z.string()
64
- }
65
- };
66
- LikeC4MCPTools2.readElement = {
67
- name: "read-element",
68
- description: stripIndent(`
69
- Read details about a LikeC4 element
70
-
71
- Args:
72
- id: Element id (FQN)
73
- project: Project name (optional, will use default project if not specified)
74
- `),
75
- paramsSchema: {
76
- id: z.string().min(1),
77
- project: z.string().optional()
78
- }
79
- };
80
- LikeC4MCPTools2.readView = {
81
- name: "read-view",
82
- description: stripIndent(`
83
- Read details about a LikeC4 view
84
-
85
- Args:
86
- id: View id
87
- project: Project name (optional, will use default project if not specified)
88
- `),
89
- paramsSchema: {
90
- id: z.string().min(1),
91
- project: z.string().optional()
92
- }
93
- };
94
- })(LikeC4MCPTools || (LikeC4MCPTools = {}));
95
- export class DefaultLikeC4MCPTools {
96
- constructor(services) {
97
- this.services = services;
98
- this.languageServices = services.likec4.LanguageServices;
99
- }
100
- languageServices;
101
- async listProjects() {
102
- const projects = await this.languageServices.projects();
103
- const response = [];
104
- for (const project of projects) {
105
- if (!project.documents) {
106
- continue;
107
- }
108
- response.push(
109
- `<likec4project>`,
110
- `id: "${project.id}"`,
111
- `folder: ${project.folder.toString()}`,
112
- "sources:",
113
- ...project.documents.map((d) => `- ${d.toString()}`),
114
- ""
115
- );
116
- try {
117
- const model = await this.languageServices.computedModel(project.id);
118
- const elements = [...model.elements()];
119
- if (elements.length > 0) {
120
- response.push(
121
- "elements:",
122
- ...elements.flatMap((el) => [
123
- `- id: ${el.id}`,
124
- ` kind: ${el.kind}`,
125
- ` title: ${singleLine(el.title)}`,
126
- ""
127
- ]),
128
- ""
129
- );
130
- }
131
- const views = [...model.views()];
132
- if (views.length > 0) {
133
- response.push(
134
- "views:",
135
- ...views.flatMap((v) => [
136
- `- id: ${v.id}`,
137
- ` title: ${singleLine(v.title)}`,
138
- ""
139
- ]),
140
- ""
141
- );
142
- }
143
- } catch (error) {
144
- logger.error(loggable(error));
145
- }
146
- response.push(`</likec4project>`);
147
- }
148
- if (response.length === 0) {
149
- response.push(
150
- `<likec4project>`,
151
- `id: "default"`,
152
- `folder: ${this.languageServices.workspaceUri.toString()}`,
153
- `</likec4project>`
154
- );
155
- }
156
- return response.join("\n");
157
- }
158
- async readProjectSummary(_project) {
159
- const projectId = _project ?? ProjectsManager.DefaultProjectId;
160
- const project = this.languageServices.projects().find((p) => p.id === projectId);
161
- if (!project) {
162
- return "Project not found";
163
- }
164
- const model = await this.languageServices.computedModel(project.id);
165
- const response = [
166
- `project: "${project.id}"`,
167
- `folder: ${project.folder.toString()}`
168
- ];
169
- if (project.documents) {
170
- response.push(
171
- "sources:",
172
- ...project.documents.map((d) => `- ${d.toString()}`),
173
- ""
174
- );
175
- }
176
- response.push("<specifications>");
177
- const elementKinds = Object.keys(model.$model.specification.elements);
178
- if (elementKinds.length > 0) {
179
- response.push(
180
- "element kinds:",
181
- ...elementKinds.map((kind) => `- ${kind}`),
182
- ""
183
- );
184
- }
185
- const relationshipKinds = Object.keys(model.$model.specification.relationships);
186
- if (relationshipKinds.length > 0) {
187
- response.push(
188
- "relationship kinds:",
189
- ...relationshipKinds.map((kind) => `- ${kind}`),
190
- ""
191
- );
192
- }
193
- const deploymentKinds = Object.keys(model.$model.specification.deployments);
194
- if (deploymentKinds.length > 0) {
195
- response.push(
196
- "deployment node kinds:",
197
- ...deploymentKinds.map((kind) => `- ${kind}`),
198
- ""
199
- );
200
- }
201
- const tags = model.tags;
202
- if (tags.length > 0) {
203
- response.push(
204
- "tags:",
205
- ...tags.map((t) => `- ${t}`),
206
- ""
207
- );
208
- }
209
- response.push(
210
- "</specifications>",
211
- ""
212
- );
213
- response.push(
214
- "<elements>",
215
- ...outputEach(model.elements(), "No elements", (el) => [
216
- `- id: ${el.id}`,
217
- ...el.parent ? [
218
- ` parentId: ${el.parent.id}`
219
- ] : [],
220
- ` kind: ${el.kind}`,
221
- ` shape: ${el.shape}`,
222
- ` title: ${singleLine(el.title)}`,
223
- ` description: ${singleLine(el.description)}`,
224
- ` technology: ${singleLine(el.technology)}`,
225
- ` tags: ${JSON.stringify(el.tags)}`,
226
- ""
227
- ]),
228
- "</elements>",
229
- "<views>",
230
- ...outputEach(model.views(), "No views", (v) => [
231
- `- id: ${v.id}`,
232
- ` viewType: ${v[_type]}`,
233
- ` title: ${singleLine(v.title)}`,
234
- ""
235
- ]),
236
- "</views>"
237
- );
238
- return response.join("\n");
239
- }
240
- async searchElement(params) {
241
- const search = params.search.toLowerCase();
242
- const found = [];
243
- for (const project of this.languageServices.projects()) {
244
- try {
245
- const model = await this.languageServices.computedModel(project.id);
246
- const elements = [...model.elements()].filter((el) => el.title.toLowerCase().includes(search));
247
- if (elements.length > 0) {
248
- found.push(
249
- "<project>",
250
- `project: "${project.id}"`,
251
- "found:",
252
- ...elements.flatMap((el) => [
253
- `- id: ${el.id}`,
254
- ` kind: ${el.kind}`,
255
- ` title: ${singleLine(el.title)}`,
256
- ""
257
- ]),
258
- "</project>"
259
- );
260
- }
261
- } catch (error) {
262
- logger.error(loggable(error));
263
- }
264
- }
265
- return found.length > 0 ? found.join("\n") : "No elements with this name found";
266
- }
267
- async readElement(params) {
268
- const projectId = params.project ?? ProjectsManager.DefaultProjectId;
269
- const project = this.languageServices.projects().find((p) => p.id === projectId);
270
- if (!project) {
271
- return `Project "${projectId}" not found`;
272
- }
273
- const model = await this.languageServices.computedModel(project.id);
274
- const element = model.findElement(params.id);
275
- if (!element) {
276
- return `Element "${params.id}" not found in project "${projectId}"`;
277
- }
278
- return JSON.stringify(elementResource(this.languageServices, element, project.id));
279
- }
280
- async readView(params) {
281
- const projectId = params.project ?? ProjectsManager.DefaultProjectId;
282
- const project = this.languageServices.projects().find((p) => p.id === projectId);
283
- if (!project) {
284
- return `Project "${projectId}" not found`;
285
- }
286
- const model = await this.languageServices.computedModel(project.id);
287
- const view = model.findView(params.id);
288
- if (!view) {
289
- return `View "${params.id}" not found in project "${projectId}"`;
290
- }
291
- return JSON.stringify(modelViewResource(this.languageServices, view, project.id));
292
- }
293
- }