@likec4/language-server 1.32.2 → 1.34.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/README.md +27 -1
- package/dist/Rpc.d.ts +2 -0
- package/dist/Rpc.js +24 -6
- package/dist/ast.d.ts +6 -5
- package/dist/ast.js +3 -0
- package/dist/bundled.mjs +3194 -2547
- package/dist/formatting/LikeC4Formatter.d.ts +1 -0
- package/dist/formatting/LikeC4Formatter.js +25 -1
- package/dist/generated/ast.d.ts +21 -12
- package/dist/generated/ast.js +21 -9
- package/dist/generated/grammar.js +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +1 -2
- package/dist/lsp/SemanticTokenProvider.js +1 -1
- package/dist/mcp/{LikeC4MCPServerFactory.d.ts → NoopLikeC4MCPServer.d.ts} +1 -9
- package/dist/mcp/interfaces.d.ts +11 -0
- package/dist/mcp/interfaces.js +0 -0
- package/dist/mcp/sseserver/MCPServer.d.ts +1 -1
- package/dist/mcp/sseserver/MCPServer.js +5 -5
- package/dist/mcp/sseserver/MCPServerFactory.js +30 -58
- package/dist/mcp/sseserver/{with-mcp-server.d.ts → WithMCPServer.d.ts} +1 -1
- package/dist/mcp/tools/_common.d.ts +68 -0
- package/dist/mcp/tools/_common.js +14 -0
- package/dist/mcp/tools/list-projects.d.ts +6 -0
- package/dist/mcp/tools/list-projects.js +31 -0
- package/dist/mcp/tools/open-view.d.ts +10 -0
- package/dist/mcp/tools/open-view.js +29 -0
- package/dist/mcp/tools/read-element.d.ts +10 -0
- package/dist/mcp/tools/read-element.js +135 -0
- package/dist/mcp/tools/read-project-elements.d.ts +8 -0
- package/dist/mcp/tools/read-project-elements.js +93 -0
- package/dist/mcp/tools/read-project-summary.d.ts +8 -0
- package/dist/mcp/tools/read-project-summary.js +68 -0
- package/dist/mcp/tools/read-view.d.ts +10 -0
- package/dist/mcp/tools/read-view.js +164 -0
- package/dist/mcp/tools/search-element.d.ts +8 -0
- package/dist/mcp/tools/search-element.js +105 -0
- package/dist/mcp/utils.d.ts +17 -34
- package/dist/mcp/utils.js +41 -101
- package/dist/model/builder/MergedSpecification.js +8 -4
- package/dist/model/index.d.ts +1 -0
- package/dist/model/index.js +1 -0
- package/dist/model/model-parser-where.d.ts +1 -0
- package/dist/model/model-parser-where.js +30 -24
- package/dist/model/model-parser.d.ts +140 -0
- package/dist/model/parser/Base.d.ts +30 -2
- package/dist/model/parser/Base.js +54 -3
- package/dist/model/parser/DeploymentModelParser.d.ts +17 -1
- package/dist/model/parser/DeploymentModelParser.js +24 -21
- package/dist/model/parser/DeploymentViewParser.d.ts +17 -1
- package/dist/model/parser/DeploymentViewParser.js +15 -6
- package/dist/model/parser/FqnRefParser.d.ts +17 -1
- package/dist/model/parser/FqnRefParser.js +42 -16
- package/dist/model/parser/GlobalsParser.d.ts +17 -1
- package/dist/model/parser/ImportsParser.d.ts +14 -0
- package/dist/model/parser/ModelParser.d.ts +17 -1
- package/dist/model/parser/ModelParser.js +22 -14
- package/dist/model/parser/PredicatesParser.d.ts +17 -1
- package/dist/model/parser/SpecificationParser.d.ts +14 -0
- package/dist/model/parser/SpecificationParser.js +16 -11
- package/dist/model/parser/ValueConverter.d.ts +4 -0
- package/dist/model/parser/ValueConverter.js +12 -0
- package/dist/model/parser/ViewsParser.d.ts +17 -1
- package/dist/model/parser/ViewsParser.js +21 -7
- package/dist/module.d.ts +5 -4
- package/dist/module.js +6 -7
- package/dist/protocol.d.ts +16 -0
- package/dist/protocol.js +4 -0
- package/dist/validation/property-checks.js +1 -1
- package/dist/views/configurable-layouter.js +22 -28
- package/dist/views/likec4-views.d.ts +5 -0
- package/dist/views/likec4-views.js +6 -1
- package/package.json +20 -19
- package/dist/mcp/LikeC4MCPTools.d.ts +0 -96
- package/dist/mcp/LikeC4MCPTools.js +0 -290
- /package/dist/mcp/{LikeC4MCPServerFactory.js → NoopLikeC4MCPServer.js} +0 -0
- /package/dist/mcp/sseserver/{with-mcp-server.js → WithMCPServer.js} +0 -0
package/dist/module.js
CHANGED
|
@@ -25,17 +25,14 @@ import {
|
|
|
25
25
|
LikeC4HoverProvider,
|
|
26
26
|
LikeC4SemanticTokenProvider
|
|
27
27
|
} from "./lsp/index.js";
|
|
28
|
-
import {
|
|
29
|
-
NoopLikeC4MCPServer,
|
|
30
|
-
NoopLikeC4MCPServerFactory
|
|
31
|
-
} from "./mcp/LikeC4MCPServerFactory.js";
|
|
32
|
-
import { DefaultLikeC4MCPTools } from "./mcp/LikeC4MCPTools.js";
|
|
28
|
+
import { NoopLikeC4MCPServer, NoopLikeC4MCPServerFactory } from "./mcp/NoopLikeC4MCPServer.js";
|
|
33
29
|
import {
|
|
34
30
|
DefaultLikeC4ModelBuilder,
|
|
35
31
|
DeploymentsIndex,
|
|
36
32
|
FqnIndex,
|
|
37
33
|
LikeC4ModelLocator,
|
|
38
|
-
LikeC4ModelParser
|
|
34
|
+
LikeC4ModelParser,
|
|
35
|
+
LikeC4ValueConverter
|
|
39
36
|
} from "./model/index.js";
|
|
40
37
|
import { LikeC4ModelChanges } from "./model-change/ModelChanges.js";
|
|
41
38
|
import {
|
|
@@ -79,7 +76,6 @@ export const LikeC4Module = {
|
|
|
79
76
|
ValidatedWorkspaceCache: (services) => new WorkspaceCache(services.shared, DocumentState.Validated),
|
|
80
77
|
Rpc: bind(Rpc),
|
|
81
78
|
mcp: {
|
|
82
|
-
Tools: bind(DefaultLikeC4MCPTools),
|
|
83
79
|
Server: bind(NoopLikeC4MCPServer),
|
|
84
80
|
ServerFactory: bind(NoopLikeC4MCPServerFactory)
|
|
85
81
|
},
|
|
@@ -116,6 +112,9 @@ export const LikeC4Module = {
|
|
|
116
112
|
NameProvider: bind(LikeC4NameProvider),
|
|
117
113
|
ScopeComputation: bind(LikeC4ScopeComputation),
|
|
118
114
|
ScopeProvider: bind(LikeC4ScopeProvider)
|
|
115
|
+
},
|
|
116
|
+
parser: {
|
|
117
|
+
ValueConverter: bind(LikeC4ValueConverter)
|
|
119
118
|
}
|
|
120
119
|
};
|
|
121
120
|
export function createCustomLanguageServices(context, module, module2, module3) {
|
package/dist/protocol.d.ts
CHANGED
|
@@ -5,6 +5,19 @@ export declare namespace DidChangeModelNotification {
|
|
|
5
5
|
const type: NotificationType<string>;
|
|
6
6
|
type Type = typeof type;
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* When server requests to open a likec4 preview panel
|
|
10
|
+
* (available only in the editor).
|
|
11
|
+
* (not the best place, but seems to be working)
|
|
12
|
+
*/
|
|
13
|
+
export declare namespace DidRequestOpenViewNotification {
|
|
14
|
+
type Params = {
|
|
15
|
+
viewId: ViewId;
|
|
16
|
+
projectId: ProjectId;
|
|
17
|
+
};
|
|
18
|
+
const type: NotificationType<Params>;
|
|
19
|
+
type Type = typeof type;
|
|
20
|
+
}
|
|
8
21
|
/**
|
|
9
22
|
* Request to fetch the computed model data
|
|
10
23
|
* If LSP has multiple projects, the projectId is required.
|
|
@@ -175,9 +188,12 @@ export declare namespace FetchTelemetryMetrics {
|
|
|
175
188
|
type Res = {
|
|
176
189
|
metrics: null | {
|
|
177
190
|
elementKinds: number;
|
|
191
|
+
deploymentKinds: number;
|
|
178
192
|
relationshipKinds: number;
|
|
179
193
|
tags: number;
|
|
194
|
+
customColors: number;
|
|
180
195
|
elements: number;
|
|
196
|
+
deploymentNodes: number;
|
|
181
197
|
relationships: number;
|
|
182
198
|
views: number;
|
|
183
199
|
projects: number;
|
package/dist/protocol.js
CHANGED
|
@@ -3,6 +3,10 @@ export var DidChangeModelNotification;
|
|
|
3
3
|
((DidChangeModelNotification2) => {
|
|
4
4
|
DidChangeModelNotification2.type = new NotificationType("likec4/onDidChangeModel");
|
|
5
5
|
})(DidChangeModelNotification || (DidChangeModelNotification = {}));
|
|
6
|
+
export var DidRequestOpenViewNotification;
|
|
7
|
+
((DidRequestOpenViewNotification2) => {
|
|
8
|
+
DidRequestOpenViewNotification2.type = new NotificationType("likec4/onRequestOpenView");
|
|
9
|
+
})(DidRequestOpenViewNotification || (DidRequestOpenViewNotification = {}));
|
|
6
10
|
export var FetchComputedModel;
|
|
7
11
|
((FetchComputedModel2) => {
|
|
8
12
|
FetchComputedModel2.req = new RequestType("likec4/fetchComputedModel");
|
|
@@ -48,7 +48,7 @@ export const notesPropertyRuleChecks = (_) => {
|
|
|
48
48
|
export const colorLiteralRuleChecks = (_) => {
|
|
49
49
|
return (node, accept) => {
|
|
50
50
|
if (node.$type === "HexColor") {
|
|
51
|
-
if (node.hex === void 0) {
|
|
51
|
+
if (node.hex === void 0 || isString(node.hex) && !node.hex.match(/^[a-fA-F0-9]+$/)) {
|
|
52
52
|
accept("error", `Invalid HEX`, {
|
|
53
53
|
node,
|
|
54
54
|
property: "hex"
|
|
@@ -15,41 +15,35 @@ export const ConfigurableLayouter = {
|
|
|
15
15
|
likec4: {
|
|
16
16
|
Layouter(services) {
|
|
17
17
|
logger.debug("Creating ConfigurableLayouter");
|
|
18
|
-
const
|
|
19
|
-
const layouter = new QueueGraphvizLayoter({
|
|
20
|
-
graphviz: wasmAdapter
|
|
21
|
-
});
|
|
22
|
-
const langId = services.LanguageMetaData.languageId;
|
|
18
|
+
const layouter = new QueueGraphvizLayoter();
|
|
23
19
|
services.shared.workspace.ConfigurationProvider.onConfigurationSectionUpdate((update) => {
|
|
24
20
|
logger.debug("Configuration update: {update}", { update });
|
|
25
|
-
if (update.section
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
21
|
+
if (update.section !== services.LanguageMetaData.languageId) {
|
|
22
|
+
logger.debug(`Ignoring configuration update as it is not for ${services.LanguageMetaData.languageId}`);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const { mode, path } = update.configuration.graphviz ?? {
|
|
27
|
+
mode: "wasm",
|
|
28
|
+
path: ""
|
|
29
|
+
};
|
|
30
|
+
if (mode !== "wasm") {
|
|
36
31
|
let binaryPath = isEmpty(path) ? graphvizBinPath() : path;
|
|
37
|
-
if (binaryPath
|
|
38
|
-
layouter.changePort(
|
|
39
|
-
logger.
|
|
40
|
-
services.shared.lsp.Connection?.window.showWarningMessage(
|
|
41
|
-
"No Graphviz binaries found on PATH, set path to binaries in settings."
|
|
42
|
-
);
|
|
32
|
+
if (!isEmpty(binaryPath)) {
|
|
33
|
+
layouter.changePort(new GraphvizBinaryAdapter(binaryPath));
|
|
34
|
+
logger.info`use graphviz binary: ${binaryPath}`;
|
|
43
35
|
return;
|
|
44
36
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
37
|
+
logger.warn(`No Graphviz binaries found on PATH, use graphviz wasm`);
|
|
38
|
+
services.shared.lsp.Connection?.window.showWarningMessage(
|
|
39
|
+
"No Graphviz binaries found on PATH, set path to binaries in settings."
|
|
40
|
+
);
|
|
49
41
|
}
|
|
50
|
-
|
|
42
|
+
layouter.changePort(new GraphvizWasmAdapter());
|
|
43
|
+
logger.info("use graphviz wasm");
|
|
44
|
+
} catch (error) {
|
|
45
|
+
logger.error("Failed to update configuration", { error });
|
|
51
46
|
}
|
|
52
|
-
logger.warn("Unexpected configuration update: {update}", { update });
|
|
53
47
|
});
|
|
54
48
|
return layouter;
|
|
55
49
|
}
|
|
@@ -18,6 +18,7 @@ export interface LikeC4Views {
|
|
|
18
18
|
layoutView(viewId: ViewId, projectId?: ProjectId | undefined, cancelToken?: CancellationToken): Promise<GraphvizOut | null>;
|
|
19
19
|
diagrams(projectId?: ProjectId | undefined, cancelToken?: CancellationToken): Promise<Array<DiagramView>>;
|
|
20
20
|
viewsAsGraphvizOut(projectId?: ProjectId | undefined, cancelToken?: CancellationToken): Promise<Array<GraphvizSvgOut>>;
|
|
21
|
+
openView(viewId: ViewId, projectId?: ProjectId | undefined): Promise<void>;
|
|
21
22
|
}
|
|
22
23
|
export declare class DefaultLikeC4Views implements LikeC4Views {
|
|
23
24
|
private services;
|
|
@@ -31,5 +32,9 @@ export declare class DefaultLikeC4Views implements LikeC4Views {
|
|
|
31
32
|
layoutView(viewId: ViewId, projectId?: ProjectId | undefined, cancelToken?: CancellationToken): Promise<GraphvizOut | null>;
|
|
32
33
|
diagrams(projectId?: ProjectId | undefined, cancelToken?: CancellationToken): Promise<Array<DiagramView>>;
|
|
33
34
|
viewsAsGraphvizOut(projectId?: ProjectId | undefined, cancelToken?: CancellationToken): Promise<Array<GraphvizSvgOut>>;
|
|
35
|
+
/**
|
|
36
|
+
* Open a view in the preview panel.
|
|
37
|
+
*/
|
|
38
|
+
openView(viewId: ViewId, projectId: ProjectId): Promise<void>;
|
|
34
39
|
}
|
|
35
40
|
export {};
|
|
@@ -53,7 +53,6 @@ export class DefaultLikeC4Views {
|
|
|
53
53
|
},
|
|
54
54
|
onError: (task, error) => {
|
|
55
55
|
logger.warn(`Fail layout view ${task.view.id}`, { error });
|
|
56
|
-
this.cache.delete(task.view);
|
|
57
56
|
}
|
|
58
57
|
});
|
|
59
58
|
}
|
|
@@ -135,6 +134,12 @@ export class DefaultLikeC4Views {
|
|
|
135
134
|
cache.set(KEY, succeed);
|
|
136
135
|
return succeed;
|
|
137
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* Open a view in the preview panel.
|
|
139
|
+
*/
|
|
140
|
+
async openView(viewId, projectId) {
|
|
141
|
+
await this.services.Rpc.openView({ viewId, projectId });
|
|
142
|
+
}
|
|
138
143
|
// async overviewGraph(): Promise<OverviewGraph> {
|
|
139
144
|
// const KEY = 'OverviewGraph'
|
|
140
145
|
// const cache = this.services.ValidatedWorkspaceCache as WorkspaceCache<string, OverviewGraph>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@likec4/language-server",
|
|
3
3
|
"description": "LikeC4 Language Server",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.34.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bugs": "https://github.com/likec4/likec4/issues",
|
|
7
7
|
"homepage": "https://likec4.dev",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"directory": "packages/language-server"
|
|
21
21
|
},
|
|
22
22
|
"engines": {
|
|
23
|
-
"node": ">=20.19.
|
|
23
|
+
"node": ">=20.19.3"
|
|
24
24
|
},
|
|
25
25
|
"engineStrict": true,
|
|
26
26
|
"type": "module",
|
|
@@ -89,33 +89,33 @@
|
|
|
89
89
|
"access": "public"
|
|
90
90
|
},
|
|
91
91
|
"dependencies": {
|
|
92
|
-
"@hpcc-js/wasm-graphviz": "1.
|
|
92
|
+
"@hpcc-js/wasm-graphviz": "1.8.0"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
95
|
"@types/chroma-js": "^3.1.1",
|
|
96
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
97
|
-
"@msgpack/msgpack": "^3.1.
|
|
96
|
+
"@modelcontextprotocol/sdk": "^1.13.2",
|
|
97
|
+
"@msgpack/msgpack": "^3.1.2",
|
|
98
98
|
"@smithy/util-base64": "^4.0.0",
|
|
99
|
-
"@types/express": "^5.0.
|
|
100
|
-
"@types/node": "~20.19.
|
|
99
|
+
"@types/express": "^5.0.3",
|
|
100
|
+
"@types/node": "~20.19.1",
|
|
101
101
|
"@types/picomatch": "^4.0.0",
|
|
102
102
|
"@types/which": "^3.0.4",
|
|
103
103
|
"chroma-js": "^3.1.2",
|
|
104
104
|
"esm-env": "^1.2.2",
|
|
105
105
|
"express": "^5.1.0",
|
|
106
106
|
"fast-equals": "^5.2.2",
|
|
107
|
-
"fdir": "
|
|
107
|
+
"fdir": "6.4.6",
|
|
108
108
|
"indent-string": "^5.0.0",
|
|
109
109
|
"json5": "^2.2.3",
|
|
110
110
|
"langium": "3.5.0",
|
|
111
111
|
"langium-cli": "3.5.0",
|
|
112
112
|
"natural-compare-lite": "^1.4.0",
|
|
113
|
-
"p-debounce": "
|
|
114
|
-
"p-queue": "
|
|
115
|
-
"p-timeout": "
|
|
113
|
+
"p-debounce": "4.0.0",
|
|
114
|
+
"p-queue": "8.1.0",
|
|
115
|
+
"p-timeout": "6.1.4",
|
|
116
116
|
"picomatch": "^4.0.2",
|
|
117
117
|
"pretty-ms": "^9.2.0",
|
|
118
|
-
"remeda": "^2.23.
|
|
118
|
+
"remeda": "^2.23.1",
|
|
119
119
|
"strip-indent": "^4.0.0",
|
|
120
120
|
"tsx": "4.19.4",
|
|
121
121
|
"turbo": "2.5.4",
|
|
@@ -124,19 +124,19 @@
|
|
|
124
124
|
"ufo": "^1.6.1",
|
|
125
125
|
"unbuild": "3.5.0",
|
|
126
126
|
"valibot": "^1.1.0",
|
|
127
|
-
"vitest": "3.2.
|
|
127
|
+
"vitest": "3.2.4",
|
|
128
128
|
"vscode-jsonrpc": "8.2.0",
|
|
129
129
|
"vscode-languageserver": "9.0.1",
|
|
130
130
|
"vscode-languageserver-protocol": "3.17.5",
|
|
131
131
|
"vscode-languageserver-types": "3.17.5",
|
|
132
132
|
"vscode-uri": "3.1.0",
|
|
133
133
|
"which": "^5.0.0",
|
|
134
|
-
"zod": "
|
|
135
|
-
"@likec4/
|
|
136
|
-
"@likec4/
|
|
137
|
-
"@likec4/
|
|
138
|
-
"@likec4/
|
|
139
|
-
"@likec4/
|
|
134
|
+
"zod": "3.25.67",
|
|
135
|
+
"@likec4/core": "1.34.0",
|
|
136
|
+
"@likec4/icons": "1.34.0",
|
|
137
|
+
"@likec4/layouts": "1.34.0",
|
|
138
|
+
"@likec4/log": "1.34.0",
|
|
139
|
+
"@likec4/tsconfig": "1.34.0"
|
|
140
140
|
},
|
|
141
141
|
"scripts": {
|
|
142
142
|
"typecheck": "tsc -b --verbose",
|
|
@@ -148,6 +148,7 @@
|
|
|
148
148
|
"generate": "langium generate && tsx scripts/generate-icons.ts",
|
|
149
149
|
"dev": "run-p \"watch:*\"",
|
|
150
150
|
"lint": "run -T eslint src/ --fix",
|
|
151
|
+
"lint:package": "pnpx publint ./package.tgz",
|
|
151
152
|
"clean": "pnpm rimraf dist contrib lib src/generated src/generated-lib",
|
|
152
153
|
"test": "vitest run --no-isolate",
|
|
153
154
|
"test-dbg": "vitest run --no-isolate -t formating",
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { type ProjectId } from '@likec4/core';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import type { LikeC4Services } from '../module';
|
|
4
|
-
export declare namespace LikeC4MCPTools {
|
|
5
|
-
const instructions = "This server provides access to LikeC4 model.\n\nKey capabilities:\n- List all available LikeC4 projects in the workspace\n- Search for LikeC4 project and return its summary, that includes specifications, all elements and views\n- Search for LikeC4 element by title\n- Read details about LikeC4 element by id\n- Read details about LikeC4 view by id\n\n";
|
|
6
|
-
const listProjects: {
|
|
7
|
-
name: string;
|
|
8
|
-
description: string;
|
|
9
|
-
};
|
|
10
|
-
const readProjectSummary: {
|
|
11
|
-
name: string;
|
|
12
|
-
description: string;
|
|
13
|
-
paramsSchema: {
|
|
14
|
-
project: z.ZodOptional<z.ZodString>;
|
|
15
|
-
};
|
|
16
|
-
};
|
|
17
|
-
const searchElement: {
|
|
18
|
-
name: string;
|
|
19
|
-
description: string;
|
|
20
|
-
paramsSchema: {
|
|
21
|
-
search: z.ZodString;
|
|
22
|
-
};
|
|
23
|
-
};
|
|
24
|
-
const readElement: {
|
|
25
|
-
name: string;
|
|
26
|
-
description: string;
|
|
27
|
-
paramsSchema: {
|
|
28
|
-
id: z.ZodString;
|
|
29
|
-
project: z.ZodOptional<z.ZodString>;
|
|
30
|
-
};
|
|
31
|
-
};
|
|
32
|
-
const readView: {
|
|
33
|
-
name: string;
|
|
34
|
-
description: string;
|
|
35
|
-
paramsSchema: {
|
|
36
|
-
id: z.ZodString;
|
|
37
|
-
project: z.ZodOptional<z.ZodString>;
|
|
38
|
-
};
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
export interface LikeC4MCPTools {
|
|
42
|
-
listProjects(): Promise<string>;
|
|
43
|
-
/**
|
|
44
|
-
* Searches for LikeC4 project and returns its summary, specifications, elements and views
|
|
45
|
-
*
|
|
46
|
-
* @param project Project name (optional, will use default project if not specified)
|
|
47
|
-
*/
|
|
48
|
-
readProjectSummary(project?: string): Promise<string>;
|
|
49
|
-
/**
|
|
50
|
-
* Searches for LikeC4 elements that have the search string in their names
|
|
51
|
-
* Can be used to resolve projects for further requests (like read-element or read-project-summary)
|
|
52
|
-
*
|
|
53
|
-
* @param params.search non-empty string
|
|
54
|
-
*/
|
|
55
|
-
searchElement(params: {
|
|
56
|
-
search: string;
|
|
57
|
-
}): Promise<string>;
|
|
58
|
-
/**
|
|
59
|
-
* Read details about LikeC4 element.
|
|
60
|
-
*
|
|
61
|
-
* @param params.id Element id (FQN)
|
|
62
|
-
* @param params.project Project name (optional, will use default project if not specified)
|
|
63
|
-
*/
|
|
64
|
-
readElement(params: {
|
|
65
|
-
id: string;
|
|
66
|
-
project?: string | undefined;
|
|
67
|
-
}): Promise<string>;
|
|
68
|
-
/**
|
|
69
|
-
* Read details about LikeC4 view.
|
|
70
|
-
*
|
|
71
|
-
* @param params.id View id (FQN)
|
|
72
|
-
* @param params.project Project name (optional, will use default project if not specified)
|
|
73
|
-
*/
|
|
74
|
-
readView(params: {
|
|
75
|
-
id: string;
|
|
76
|
-
project?: string | undefined;
|
|
77
|
-
}): Promise<string>;
|
|
78
|
-
}
|
|
79
|
-
export declare class DefaultLikeC4MCPTools implements LikeC4MCPTools {
|
|
80
|
-
private services;
|
|
81
|
-
private readonly languageServices;
|
|
82
|
-
constructor(services: LikeC4Services);
|
|
83
|
-
listProjects(): Promise<string>;
|
|
84
|
-
readProjectSummary(_project?: ProjectId): Promise<string>;
|
|
85
|
-
searchElement(params: {
|
|
86
|
-
search: string;
|
|
87
|
-
}): Promise<string>;
|
|
88
|
-
readElement(params: {
|
|
89
|
-
id: string;
|
|
90
|
-
project?: string;
|
|
91
|
-
}): Promise<string>;
|
|
92
|
-
readView(params: {
|
|
93
|
-
id: string;
|
|
94
|
-
project?: string;
|
|
95
|
-
}): Promise<string>;
|
|
96
|
-
}
|
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
import { _type } 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
|
-
const res = toSingleLine(str)?.replaceAll('"', "'");
|
|
13
|
-
return res ? `"${res}"` : "null";
|
|
14
|
-
}
|
|
15
|
-
function outputEach(iterator, ifEmpty, output) {
|
|
16
|
-
const items = [...iterator];
|
|
17
|
-
if (items.length === 0) {
|
|
18
|
-
return [ifEmpty];
|
|
19
|
-
}
|
|
20
|
-
return flatMap(items, output);
|
|
21
|
-
}
|
|
22
|
-
export var LikeC4MCPTools;
|
|
23
|
-
((LikeC4MCPTools2) => {
|
|
24
|
-
LikeC4MCPTools2.instructions = `This server provides access to LikeC4 model.
|
|
25
|
-
|
|
26
|
-
Key capabilities:
|
|
27
|
-
- List all available LikeC4 projects in the workspace
|
|
28
|
-
- Search for LikeC4 project and return its summary, that includes specifications, all elements and views
|
|
29
|
-
- Search for LikeC4 element by title
|
|
30
|
-
- Read details about LikeC4 element by id
|
|
31
|
-
- Read details about LikeC4 view by id
|
|
32
|
-
|
|
33
|
-
`;
|
|
34
|
-
LikeC4MCPTools2.listProjects = {
|
|
35
|
-
name: "list-projects",
|
|
36
|
-
description: "Lists all available LikeC4 projects in the workspace"
|
|
37
|
-
};
|
|
38
|
-
LikeC4MCPTools2.readProjectSummary = {
|
|
39
|
-
name: "read-project-summary",
|
|
40
|
-
description: stripIndent(`
|
|
41
|
-
Searches for LikeC4 project and returns its summary, specifications, elements and views
|
|
42
|
-
|
|
43
|
-
Args:
|
|
44
|
-
project: Project name
|
|
45
|
-
`),
|
|
46
|
-
paramsSchema: {
|
|
47
|
-
project: z.string().optional()
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
LikeC4MCPTools2.searchElement = {
|
|
51
|
-
name: "search-element",
|
|
52
|
-
description: stripIndent(`
|
|
53
|
-
Search for LikeC4 elements that have the search string in their names
|
|
54
|
-
Can be used to resolve projects for further requests (like read-element or read-project-summary)
|
|
55
|
-
|
|
56
|
-
Args:
|
|
57
|
-
search: non-empty string
|
|
58
|
-
`),
|
|
59
|
-
paramsSchema: {
|
|
60
|
-
search: z.string()
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
LikeC4MCPTools2.readElement = {
|
|
64
|
-
name: "read-element",
|
|
65
|
-
description: stripIndent(`
|
|
66
|
-
Read details about a LikeC4 element
|
|
67
|
-
|
|
68
|
-
Args:
|
|
69
|
-
id: Element id (FQN)
|
|
70
|
-
project: Project name (optional, will use default project if not specified)
|
|
71
|
-
`),
|
|
72
|
-
paramsSchema: {
|
|
73
|
-
id: z.string().min(1),
|
|
74
|
-
project: z.string().optional()
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
LikeC4MCPTools2.readView = {
|
|
78
|
-
name: "read-view",
|
|
79
|
-
description: stripIndent(`
|
|
80
|
-
Read details about a LikeC4 view
|
|
81
|
-
|
|
82
|
-
Args:
|
|
83
|
-
id: View id
|
|
84
|
-
project: Project name (optional, will use default project if not specified)
|
|
85
|
-
`),
|
|
86
|
-
paramsSchema: {
|
|
87
|
-
id: z.string().min(1),
|
|
88
|
-
project: z.string().optional()
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
})(LikeC4MCPTools || (LikeC4MCPTools = {}));
|
|
92
|
-
export class DefaultLikeC4MCPTools {
|
|
93
|
-
constructor(services) {
|
|
94
|
-
this.services = services;
|
|
95
|
-
this.languageServices = services.likec4.LanguageServices;
|
|
96
|
-
}
|
|
97
|
-
languageServices;
|
|
98
|
-
async listProjects() {
|
|
99
|
-
const projects = await this.languageServices.projects();
|
|
100
|
-
const response = [];
|
|
101
|
-
for (const project of projects) {
|
|
102
|
-
if (!project.documents) {
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
|
-
response.push(
|
|
106
|
-
`<likec4project>`,
|
|
107
|
-
`id: "${project.id}"`,
|
|
108
|
-
`folder: ${project.folder.toString()}`,
|
|
109
|
-
"sources:",
|
|
110
|
-
...project.documents.map((d) => `- ${d.toString()}`),
|
|
111
|
-
""
|
|
112
|
-
);
|
|
113
|
-
try {
|
|
114
|
-
const model = await this.languageServices.computedModel(project.id);
|
|
115
|
-
const elements = [...model.elements()];
|
|
116
|
-
if (elements.length > 0) {
|
|
117
|
-
response.push(
|
|
118
|
-
"elements:",
|
|
119
|
-
...elements.flatMap((el) => [
|
|
120
|
-
`- id: ${el.id}`,
|
|
121
|
-
` kind: ${el.kind}`,
|
|
122
|
-
` title: ${singleLine(el.title)}`,
|
|
123
|
-
""
|
|
124
|
-
]),
|
|
125
|
-
""
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
const views = [...model.views()];
|
|
129
|
-
if (views.length > 0) {
|
|
130
|
-
response.push(
|
|
131
|
-
"views:",
|
|
132
|
-
...views.flatMap((v) => [
|
|
133
|
-
`- id: ${v.id}`,
|
|
134
|
-
` title: ${singleLine(v.title)}`,
|
|
135
|
-
""
|
|
136
|
-
]),
|
|
137
|
-
""
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
} catch (error) {
|
|
141
|
-
logger.error(loggable(error));
|
|
142
|
-
}
|
|
143
|
-
response.push(`</likec4project>`);
|
|
144
|
-
}
|
|
145
|
-
if (response.length === 0) {
|
|
146
|
-
response.push(
|
|
147
|
-
`<likec4project>`,
|
|
148
|
-
`id: "default"`,
|
|
149
|
-
`folder: ${this.languageServices.workspaceUri.toString()}`,
|
|
150
|
-
`</likec4project>`
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
return response.join("\n");
|
|
154
|
-
}
|
|
155
|
-
async readProjectSummary(_project) {
|
|
156
|
-
const projectId = _project ?? ProjectsManager.DefaultProjectId;
|
|
157
|
-
const project = this.languageServices.projects().find((p) => p.id === projectId);
|
|
158
|
-
if (!project) {
|
|
159
|
-
return "Project not found";
|
|
160
|
-
}
|
|
161
|
-
const model = await this.languageServices.computedModel(project.id);
|
|
162
|
-
const response = [
|
|
163
|
-
`project: "${project.id}"`,
|
|
164
|
-
`folder: ${project.folder.toString()}`
|
|
165
|
-
];
|
|
166
|
-
if (project.documents) {
|
|
167
|
-
response.push(
|
|
168
|
-
"sources:",
|
|
169
|
-
...project.documents.map((d) => `- ${d.toString()}`),
|
|
170
|
-
""
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
response.push("<specifications>");
|
|
174
|
-
const elementKinds = Object.keys(model.$model.specification.elements);
|
|
175
|
-
if (elementKinds.length > 0) {
|
|
176
|
-
response.push(
|
|
177
|
-
"element kinds:",
|
|
178
|
-
...elementKinds.map((kind) => `- ${kind}`),
|
|
179
|
-
""
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
const relationshipKinds = Object.keys(model.$model.specification.relationships);
|
|
183
|
-
if (relationshipKinds.length > 0) {
|
|
184
|
-
response.push(
|
|
185
|
-
"relationship kinds:",
|
|
186
|
-
...relationshipKinds.map((kind) => `- ${kind}`),
|
|
187
|
-
""
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
const deploymentKinds = Object.keys(model.$model.specification.deployments);
|
|
191
|
-
if (deploymentKinds.length > 0) {
|
|
192
|
-
response.push(
|
|
193
|
-
"deployment node kinds:",
|
|
194
|
-
...deploymentKinds.map((kind) => `- ${kind}`),
|
|
195
|
-
""
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
const tags = model.tags;
|
|
199
|
-
if (tags.length > 0) {
|
|
200
|
-
response.push(
|
|
201
|
-
"tags:",
|
|
202
|
-
...tags.map((t) => `- ${t}`),
|
|
203
|
-
""
|
|
204
|
-
);
|
|
205
|
-
}
|
|
206
|
-
response.push(
|
|
207
|
-
"</specifications>",
|
|
208
|
-
""
|
|
209
|
-
);
|
|
210
|
-
response.push(
|
|
211
|
-
"<elements>",
|
|
212
|
-
...outputEach(model.elements(), "No elements", (el) => [
|
|
213
|
-
`- id: ${el.id}`,
|
|
214
|
-
...el.parent ? [
|
|
215
|
-
` parentId: ${el.parent.id}`
|
|
216
|
-
] : [],
|
|
217
|
-
` kind: ${el.kind}`,
|
|
218
|
-
` shape: ${el.shape}`,
|
|
219
|
-
` title: ${singleLine(el.title)}`,
|
|
220
|
-
` description: ${singleLine(el.description)}`,
|
|
221
|
-
` technology: ${singleLine(el.technology)}`,
|
|
222
|
-
` tags: ${JSON.stringify(el.tags)}`,
|
|
223
|
-
""
|
|
224
|
-
]),
|
|
225
|
-
"</elements>",
|
|
226
|
-
"<views>",
|
|
227
|
-
...outputEach(model.views(), "No views", (v) => [
|
|
228
|
-
`- id: ${v.id}`,
|
|
229
|
-
` viewType: ${v[_type]}`,
|
|
230
|
-
` title: ${singleLine(v.title)}`,
|
|
231
|
-
""
|
|
232
|
-
]),
|
|
233
|
-
"</views>"
|
|
234
|
-
);
|
|
235
|
-
return response.join("\n");
|
|
236
|
-
}
|
|
237
|
-
async searchElement(params) {
|
|
238
|
-
const search = params.search.toLowerCase();
|
|
239
|
-
const found = [];
|
|
240
|
-
for (const project of this.languageServices.projects()) {
|
|
241
|
-
try {
|
|
242
|
-
const model = await this.languageServices.computedModel(project.id);
|
|
243
|
-
const elements = [...model.elements()].filter((el) => el.title.toLowerCase().includes(search));
|
|
244
|
-
if (elements.length > 0) {
|
|
245
|
-
found.push(
|
|
246
|
-
"<project>",
|
|
247
|
-
`project: "${project.id}"`,
|
|
248
|
-
"found:",
|
|
249
|
-
...elements.flatMap((el) => [
|
|
250
|
-
`- id: ${el.id}`,
|
|
251
|
-
` kind: ${el.kind}`,
|
|
252
|
-
` title: ${singleLine(el.title)}`,
|
|
253
|
-
""
|
|
254
|
-
]),
|
|
255
|
-
"</project>"
|
|
256
|
-
);
|
|
257
|
-
}
|
|
258
|
-
} catch (error) {
|
|
259
|
-
logger.error(loggable(error));
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
return found.length > 0 ? found.join("\n") : "No elements with this name found";
|
|
263
|
-
}
|
|
264
|
-
async readElement(params) {
|
|
265
|
-
const projectId = params.project ?? ProjectsManager.DefaultProjectId;
|
|
266
|
-
const project = this.languageServices.projects().find((p) => p.id === projectId);
|
|
267
|
-
if (!project) {
|
|
268
|
-
return `Project "${projectId}" not found`;
|
|
269
|
-
}
|
|
270
|
-
const model = await this.languageServices.computedModel(project.id);
|
|
271
|
-
const element = model.findElement(params.id);
|
|
272
|
-
if (!element) {
|
|
273
|
-
return `Element "${params.id}" not found in project "${projectId}"`;
|
|
274
|
-
}
|
|
275
|
-
return JSON.stringify(elementResource(this.languageServices, element, project.id));
|
|
276
|
-
}
|
|
277
|
-
async readView(params) {
|
|
278
|
-
const projectId = params.project ?? ProjectsManager.DefaultProjectId;
|
|
279
|
-
const project = this.languageServices.projects().find((p) => p.id === projectId);
|
|
280
|
-
if (!project) {
|
|
281
|
-
return `Project "${projectId}" not found`;
|
|
282
|
-
}
|
|
283
|
-
const model = await this.languageServices.computedModel(project.id);
|
|
284
|
-
const view = model.findView(params.id);
|
|
285
|
-
if (!view) {
|
|
286
|
-
return `View "${params.id}" not found in project "${projectId}"`;
|
|
287
|
-
}
|
|
288
|
-
return JSON.stringify(modelViewResource(this.languageServices, view, project.id));
|
|
289
|
-
}
|
|
290
|
-
}
|
|
File without changes
|
|
File without changes
|