@likec4/language-server 1.37.0 → 1.38.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.
- package/dist/LikeC4LanguageServices.d.ts +8 -4
- package/dist/LikeC4LanguageServices.js +12 -2
- package/dist/Rpc.js +2 -2
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +1 -1
- package/dist/bundled.mjs +4259 -3106
- package/dist/empty.d.ts +2 -0
- package/dist/empty.js +1 -0
- package/dist/filesystem/ChokidarWatcher.d.ts +14 -0
- package/dist/filesystem/ChokidarWatcher.js +64 -0
- package/dist/filesystem/FileSystemWatcher.d.ts +19 -0
- package/dist/filesystem/FileSystemWatcher.js +11 -0
- package/dist/filesystem/LikeC4FileSystem.d.ts +5 -0
- package/dist/filesystem/LikeC4FileSystem.js +56 -0
- package/dist/filesystem/index.d.ts +20 -0
- package/dist/filesystem/index.js +16 -0
- package/dist/index.d.ts +18 -4
- package/dist/index.js +23 -10
- package/dist/mcp/{sseserver/MCPServerFactory.d.ts → MCPServerFactory.d.ts} +1 -1
- package/dist/mcp/MCPServerFactory.js +69 -0
- package/dist/mcp/NoopLikeC4MCPServer.d.ts +4 -10
- package/dist/mcp/NoopLikeC4MCPServer.js +5 -10
- package/dist/mcp/interfaces.d.ts +7 -5
- package/dist/mcp/interfaces.js +4 -0
- package/dist/mcp/server/StdioLikeC4MCPServer.d.ts +16 -0
- package/dist/mcp/server/StdioLikeC4MCPServer.js +43 -0
- package/dist/mcp/{sseserver/MCPServer.d.ts → server/StreamableLikeC4MCPServer.d.ts} +3 -2
- package/dist/mcp/server/StreamableLikeC4MCPServer.js +156 -0
- package/dist/mcp/server/WithMCPServer.d.ts +2 -0
- package/dist/mcp/server/WithMCPServer.js +57 -0
- package/dist/mcp/tools/_common.d.ts +24 -5
- package/dist/mcp/tools/_common.js +31 -3
- package/dist/mcp/tools/find-relationships.d.ts +13 -0
- package/dist/mcp/tools/find-relationships.js +151 -0
- package/dist/mcp/tools/list-projects.js +40 -12
- package/dist/mcp/tools/open-view.d.ts +4 -3
- package/dist/mcp/tools/open-view.js +37 -14
- package/dist/mcp/tools/{read-project-elements.d.ts → read-deployment.d.ts} +6 -3
- package/dist/mcp/tools/read-deployment.js +130 -0
- package/dist/mcp/tools/read-element.d.ts +4 -3
- package/dist/mcp/tools/read-element.js +114 -51
- package/dist/mcp/tools/read-project-summary.d.ts +3 -2
- package/dist/mcp/tools/read-project-summary.js +139 -32
- package/dist/mcp/tools/read-view.d.ts +4 -3
- package/dist/mcp/tools/read-view.js +146 -105
- package/dist/mcp/tools/search-element.js +81 -30
- package/dist/mcp/utils.js +7 -4
- package/dist/model/builder/MergedSpecification.d.ts +1 -1
- package/dist/model/builder/buildModel.d.ts +1 -1
- package/dist/module.d.ts +9 -9
- package/dist/module.js +24 -29
- package/dist/protocol.d.ts +1 -1
- package/dist/protocol.js +1 -1
- package/dist/test/testServices.js +3 -2
- package/dist/workspace/LangiumDocuments.d.ts +4 -1
- package/dist/workspace/LangiumDocuments.js +15 -0
- package/dist/workspace/ProjectsManager.d.ts +1 -1
- package/dist/workspace/ProjectsManager.js +18 -19
- package/dist/workspace/WorkspaceManager.d.ts +9 -2
- package/dist/workspace/WorkspaceManager.js +30 -39
- package/package.json +16 -12
- package/dist/LikeC4FileSystem.d.ts +0 -14
- package/dist/LikeC4FileSystem.js +0 -39
- package/dist/mcp/sseserver/MCPServer.js +0 -80
- package/dist/mcp/sseserver/MCPServerFactory.js +0 -50
- package/dist/mcp/sseserver/WithMCPServer.d.ts +0 -9
- package/dist/mcp/sseserver/WithMCPServer.js +0 -53
- package/dist/mcp/tools/read-project-elements.js +0 -93
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { invariant } from "@likec4/core";
|
|
2
|
+
import z from "zod";
|
|
3
|
+
import { likec4Tool } from "../utils.js";
|
|
4
|
+
import { includedInViews, includedInViewsSchema, locationSchema, mkLocate, projectIdSchema } from "./_common.js";
|
|
5
|
+
export const readDeployment = likec4Tool({
|
|
6
|
+
name: "read-deployment",
|
|
7
|
+
description: `
|
|
8
|
+
Read details about a deployment node or a deployed instance in a LikeC4 project.
|
|
9
|
+
|
|
10
|
+
What it does:
|
|
11
|
+
- Returns metadata about a deployment entity (node or instance), including kind, tags, color/shape, children, which views include it, and its source location.
|
|
12
|
+
|
|
13
|
+
Inputs:
|
|
14
|
+
- id: string \u2014 Deployment id (FQN)
|
|
15
|
+
- project: string (optional, defaults to "default") \u2014 Project id
|
|
16
|
+
|
|
17
|
+
Output fields:
|
|
18
|
+
- type: "deployment-node" | "deployed-instance"
|
|
19
|
+
- id: string \u2014 Deployment id (FQN)
|
|
20
|
+
- kind: string \u2014 Deployment node kind, or element kind for deployed instances
|
|
21
|
+
- name: string \u2014 Name of the deployment entity
|
|
22
|
+
- title: string \u2014 Title of the deployment entity
|
|
23
|
+
- description: string|null \u2014 Description text
|
|
24
|
+
- technology: string|null \u2014 Technology info, if any
|
|
25
|
+
- tags: string[] \u2014 Tags assigned to this entity
|
|
26
|
+
- project: string \u2014 Project id
|
|
27
|
+
- metadata: Record<string, string>
|
|
28
|
+
- shape: string \u2014 Rendered shape
|
|
29
|
+
- color: string \u2014 Rendered color
|
|
30
|
+
- children: string[] \u2014 Child deployment ids (empty for instances)
|
|
31
|
+
- includedInViews: View[] \u2014 Views that include this entity
|
|
32
|
+
- instanceof: { id: string, title: string, kind: string } | null \u2014 If type is "deployed-instance", the referenced element
|
|
33
|
+
- sourceLocation: { path: string, range: { start: { line: number, character: number }, end: { line: number, character: number } } } | null
|
|
34
|
+
|
|
35
|
+
View (object) fields:
|
|
36
|
+
- id: string \u2014 view identifier
|
|
37
|
+
- title: string \u2014 view title
|
|
38
|
+
- type: "element" | "deployment" | "dynamic"
|
|
39
|
+
|
|
40
|
+
Notes:
|
|
41
|
+
- Read-only, idempotent; does not mutate the model.
|
|
42
|
+
|
|
43
|
+
Example request:
|
|
44
|
+
{ "id": "k8s.cluster.frontend", "project": "default" }
|
|
45
|
+
|
|
46
|
+
Example response (deployed instance):
|
|
47
|
+
{
|
|
48
|
+
"type": "deployed-instance",
|
|
49
|
+
"id": "k8s.cluster.frontend",
|
|
50
|
+
"kind": "k8s.pod",
|
|
51
|
+
"name": "frontend",
|
|
52
|
+
"title": "Frontend Pod",
|
|
53
|
+
"description": null,
|
|
54
|
+
"technology": "Kubernetes",
|
|
55
|
+
"tags": ["prod"],
|
|
56
|
+
"project": "default",
|
|
57
|
+
"metadata": {},
|
|
58
|
+
"shape": "rectangle",
|
|
59
|
+
"color": "#2F80ED",
|
|
60
|
+
"children": [],
|
|
61
|
+
"includedInViews": [
|
|
62
|
+
{ "id": "runtime-overview", "title": "Runtime Overview", "type": "deployment" }
|
|
63
|
+
],
|
|
64
|
+
"instanceof": { "id": "shop.frontend", "title": "Frontend", "kind": "component" },
|
|
65
|
+
"sourceLocation": {
|
|
66
|
+
"path": "/abs/path/project/model.c4",
|
|
67
|
+
"range": { "start": { "line": 10, "character": 0 }, "end": { "line": 25, "character": 0 } }
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
`,
|
|
71
|
+
annotations: {
|
|
72
|
+
readOnlyHint: true,
|
|
73
|
+
idempotentHint: true,
|
|
74
|
+
title: "Read deployment entity"
|
|
75
|
+
},
|
|
76
|
+
inputSchema: {
|
|
77
|
+
id: z.string().describe("Deployment id (FQN)"),
|
|
78
|
+
project: projectIdSchema
|
|
79
|
+
},
|
|
80
|
+
outputSchema: {
|
|
81
|
+
type: z.enum(["deployment-node", "deployed-instance"]),
|
|
82
|
+
id: z.string().describe("Deployment id (FQN)"),
|
|
83
|
+
kind: z.string().describe("Deployment node kind, or element kind for deployed instances"),
|
|
84
|
+
name: z.string(),
|
|
85
|
+
title: z.string(),
|
|
86
|
+
description: z.string().nullable(),
|
|
87
|
+
technology: z.string().nullable(),
|
|
88
|
+
tags: z.array(z.string()),
|
|
89
|
+
project: z.string(),
|
|
90
|
+
metadata: z.record(z.string()),
|
|
91
|
+
shape: z.string(),
|
|
92
|
+
color: z.string(),
|
|
93
|
+
children: z.array(z.string()).describe("Children of this deployment node (Array of Deployment ids)"),
|
|
94
|
+
includedInViews: includedInViewsSchema.describe("Views that include this deployment node"),
|
|
95
|
+
instanceof: z.object({
|
|
96
|
+
id: z.string().describe("Element ID (FQN)"),
|
|
97
|
+
title: z.string(),
|
|
98
|
+
kind: z.string()
|
|
99
|
+
}).nullable().describe('If type is "deployed-instance", the referenced element'),
|
|
100
|
+
sourceLocation: locationSchema
|
|
101
|
+
}
|
|
102
|
+
}, async (languageServices, args) => {
|
|
103
|
+
const projectId = languageServices.projectsManager.ensureProjectId(args.project);
|
|
104
|
+
const model = await languageServices.computedModel(projectId);
|
|
105
|
+
const element = model.deployment.findElement(args.id);
|
|
106
|
+
invariant(element, `Deployment entity "${args.id}" not found in project "${projectId}"`);
|
|
107
|
+
const locate = mkLocate(languageServices, projectId);
|
|
108
|
+
return {
|
|
109
|
+
type: element.isInstance() ? "deployed-instance" : "deployment-node",
|
|
110
|
+
id: element.id,
|
|
111
|
+
name: element.name,
|
|
112
|
+
kind: element.kind,
|
|
113
|
+
title: element.title,
|
|
114
|
+
description: element.description.text,
|
|
115
|
+
technology: element.technology,
|
|
116
|
+
tags: [...element.tags],
|
|
117
|
+
project: projectId,
|
|
118
|
+
metadata: element.getMetadata(),
|
|
119
|
+
shape: element.shape,
|
|
120
|
+
color: element.color,
|
|
121
|
+
children: element.isInstance() ? [] : [...element.children()].map((c) => c.id),
|
|
122
|
+
includedInViews: includedInViews(element.views()),
|
|
123
|
+
instanceof: element.isInstance() ? {
|
|
124
|
+
id: element.element.id,
|
|
125
|
+
title: element.element.title,
|
|
126
|
+
kind: element.element.kind
|
|
127
|
+
} : null,
|
|
128
|
+
sourceLocation: locate({ deployment: element.id })
|
|
129
|
+
};
|
|
130
|
+
});
|
|
@@ -2,9 +2,10 @@ import z from 'zod';
|
|
|
2
2
|
export declare const readElement: (languageServices: import("../..").LikeC4LanguageServices) => [string, {
|
|
3
3
|
inputSchema?: {
|
|
4
4
|
id: z.ZodString;
|
|
5
|
-
project: z.ZodOptional<z.ZodString
|
|
5
|
+
project: z.ZodDefault<z.ZodOptional<z.ZodEffects<z.ZodString, ProjectId, string>>>;
|
|
6
6
|
} | undefined;
|
|
7
7
|
}, (args: {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
[x: string]: any;
|
|
9
|
+
id?: unknown;
|
|
10
|
+
project?: unknown;
|
|
10
11
|
}, extra: import("@modelcontextprotocol/sdk/shared/protocol").RequestHandlerExtra<import("@modelcontextprotocol/sdk/types").ServerRequest, import("@modelcontextprotocol/sdk/types").ServerNotification>) => import("@modelcontextprotocol/sdk/types").CallToolResult | Promise<import("@modelcontextprotocol/sdk/types").CallToolResult>];
|
|
@@ -1,92 +1,154 @@
|
|
|
1
1
|
import { invariant } from "@likec4/core";
|
|
2
2
|
import z from "zod";
|
|
3
|
-
import { safeCall } from "../../utils/index.js";
|
|
4
|
-
import { ProjectsManager } from "../../workspace/index.js";
|
|
5
3
|
import { likec4Tool } from "../utils.js";
|
|
6
|
-
import { locationSchema } from "./_common.js";
|
|
4
|
+
import { includedInViews, includedInViewsSchema, locationSchema, mkLocate, projectIdSchema } from "./_common.js";
|
|
7
5
|
export const readElement = likec4Tool({
|
|
8
6
|
name: "read-element",
|
|
9
7
|
description: `
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
|
|
8
|
+
Read detailed information about a LikeC4 element.
|
|
9
|
+
|
|
10
|
+
Request:
|
|
11
|
+
- id: string \u2014 element id (FQN)
|
|
12
|
+
- project: string (optional) \u2014 project id. Defaults to "default" if omitted.
|
|
13
|
+
|
|
14
|
+
Response (JSON object):
|
|
15
|
+
- id: string \u2014 element id (FQN)
|
|
16
|
+
- name: string \u2014 element name
|
|
17
|
+
- kind: string \u2014 element kind
|
|
18
|
+
- title: string \u2014 human-readable title
|
|
19
|
+
- description: string|null \u2014 optional description
|
|
20
|
+
- technology: string|null \u2014 optional technology
|
|
21
|
+
- tags: string[] \u2014 assigned tags
|
|
22
|
+
- project: string \u2014 project id this element belongs to
|
|
23
|
+
- metadata: Record<string, string> \u2014 element metadata
|
|
24
|
+
- shape: string \u2014 rendered shape
|
|
25
|
+
- color: string \u2014 rendered color
|
|
26
|
+
- children: string[] \u2014 ids (FQNs) of direct child elements
|
|
27
|
+
- defaultView: string|null \u2014 default view name if set
|
|
28
|
+
- includedInViews: View[] \u2014 views that include this element
|
|
29
|
+
- relationships: object \u2014 relationships of this element (direct and indirect)
|
|
30
|
+
- incoming: Array<{ source: { id: string, title: string, kind: string }, kind: string|null, target: string, title: string|null, description: string|null, technology: string|null, tags: string[] }>
|
|
31
|
+
- outgoing: Array<{ source: string, target: { id: string, title: string, kind: string }, kind: string|null, title: string|null, description: string|null, technology: string|null, tags: string[] }>
|
|
32
|
+
- deployedInstances: string[] \u2014 deployed instance ids (Deployment FQNs)
|
|
33
|
+
- sourceLocation: { path: string, range: { start: { line: number, character: number }, end: { line: number, character: number } } } | null \u2014 source location if available
|
|
34
|
+
|
|
35
|
+
View (object) fields:
|
|
36
|
+
- id: string \u2014 view identifier
|
|
37
|
+
- title: string \u2014 view title
|
|
38
|
+
- type: "element" | "deployment" | "dynamic"
|
|
39
|
+
|
|
40
|
+
Notes:
|
|
41
|
+
- Read-only, idempotent, no side effects.
|
|
42
|
+
- Safe to call repeatedly.
|
|
43
|
+
|
|
44
|
+
Example response:
|
|
45
|
+
{
|
|
46
|
+
"id": "shop.frontend",
|
|
47
|
+
"name": "frontend",
|
|
48
|
+
"kind": "container",
|
|
49
|
+
"title": "Frontend",
|
|
50
|
+
"description": "User-facing web app",
|
|
51
|
+
"technology": "React",
|
|
52
|
+
"tags": ["public"],
|
|
53
|
+
"project": "default",
|
|
54
|
+
"metadata": { "owner": "web" },
|
|
55
|
+
"shape": "rounded-rectangle",
|
|
56
|
+
"color": "#2F80ED",
|
|
57
|
+
"children": ["shop.frontend.auth"],
|
|
58
|
+
"defaultView": "frontend-overview",
|
|
59
|
+
"includedInViews": [
|
|
60
|
+
{
|
|
61
|
+
"id": "frontend-overview",
|
|
62
|
+
"title": "Frontend Overview",
|
|
63
|
+
"type": "element"
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"relationships": {
|
|
67
|
+
"incoming": [
|
|
68
|
+
{
|
|
69
|
+
"source": { "id": "shop.api", "title": "API", "kind": "container" },
|
|
70
|
+
"kind": "uses",
|
|
71
|
+
"target": "shop.frontend",
|
|
72
|
+
"title": "Calls",
|
|
73
|
+
"description": null,
|
|
74
|
+
"technology": "HTTPS",
|
|
75
|
+
"tags": []
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
"outgoing": []
|
|
79
|
+
},
|
|
80
|
+
"deployedInstances": ["k8s.cluster.frontend"],
|
|
81
|
+
"sourceLocation": {
|
|
82
|
+
"path": "/abs/path/project/model.c4",
|
|
83
|
+
"range": { "start": { "line": 10, "character": 0 }, "end": { "line": 25, "character": 0 } }
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
`,
|
|
29
87
|
annotations: {
|
|
30
|
-
readOnlyHint: true
|
|
88
|
+
readOnlyHint: true,
|
|
89
|
+
idempotentHint: true,
|
|
90
|
+
title: "Read element"
|
|
31
91
|
},
|
|
32
92
|
inputSchema: {
|
|
33
93
|
id: z.string().describe("Element id (FQN)"),
|
|
34
|
-
project:
|
|
94
|
+
project: projectIdSchema
|
|
35
95
|
},
|
|
36
96
|
outputSchema: {
|
|
37
97
|
id: z.string().describe("Element id (FQN)"),
|
|
38
98
|
kind: z.string().describe("Element kind"),
|
|
39
99
|
name: z.string().describe("Element name"),
|
|
40
100
|
title: z.string(),
|
|
41
|
-
description: z.string().
|
|
42
|
-
technology: z.string().
|
|
101
|
+
description: z.string().nullable(),
|
|
102
|
+
technology: z.string().nullable(),
|
|
43
103
|
tags: z.array(z.string()),
|
|
44
104
|
project: z.string(),
|
|
45
105
|
metadata: z.record(z.string()),
|
|
46
106
|
shape: z.string(),
|
|
107
|
+
color: z.string(),
|
|
47
108
|
children: z.array(z.string()).describe("Children of this element (Array of FQNs)"),
|
|
48
|
-
defaultView: z.string().
|
|
49
|
-
includedInViews:
|
|
109
|
+
defaultView: z.string().nullable().describe("Name of the default view of this element"),
|
|
110
|
+
includedInViews: includedInViewsSchema.describe("Views that include this element"),
|
|
50
111
|
relationships: z.object({
|
|
51
112
|
incoming: z.array(z.object({
|
|
52
113
|
source: z.object({
|
|
53
114
|
id: z.string(),
|
|
54
115
|
title: z.string(),
|
|
55
116
|
kind: z.string()
|
|
56
|
-
}),
|
|
57
|
-
kind: z.string().
|
|
117
|
+
}).describe("Source element of this relationship"),
|
|
118
|
+
kind: z.string().nullable().describe("Relationship kind"),
|
|
58
119
|
target: z.string().describe(
|
|
59
120
|
"Target element id (FQN), either this element or nested element, if relationship is indirect"
|
|
60
121
|
),
|
|
61
|
-
title: z.string().
|
|
62
|
-
description: z.string().
|
|
63
|
-
technology: z.string().
|
|
122
|
+
title: z.string().nullable().describe("Relationship title"),
|
|
123
|
+
description: z.string().nullable().describe("Relationship description"),
|
|
124
|
+
technology: z.string().nullable().describe("Relationship technology"),
|
|
64
125
|
tags: z.array(z.string()).describe("Relationship tags")
|
|
65
|
-
})),
|
|
126
|
+
})).describe("Incoming relationships of this element (direct and indirect, incoming to nested elements)"),
|
|
66
127
|
outgoing: z.array(z.object({
|
|
67
|
-
source: z.string().describe(
|
|
128
|
+
source: z.string().describe(
|
|
129
|
+
"Source element id (FQN), either this element or nested element, if relationship is indirect"
|
|
130
|
+
),
|
|
68
131
|
target: z.object({
|
|
69
132
|
id: z.string(),
|
|
70
133
|
title: z.string(),
|
|
71
134
|
kind: z.string()
|
|
72
|
-
}),
|
|
73
|
-
kind: z.string().
|
|
74
|
-
title: z.string().
|
|
75
|
-
description: z.string().
|
|
76
|
-
technology: z.string().
|
|
135
|
+
}).describe("Target element of this relationship"),
|
|
136
|
+
kind: z.string().nullable().describe("Relationship kind"),
|
|
137
|
+
title: z.string().nullable().describe("Relationship title"),
|
|
138
|
+
description: z.string().nullable().describe("Relationship description"),
|
|
139
|
+
technology: z.string().nullable().describe("Relationship technology"),
|
|
77
140
|
tags: z.array(z.string()).describe("Relationship tags")
|
|
78
|
-
}))
|
|
79
|
-
}).describe("Relationships of this element
|
|
141
|
+
})).describe("Outgoing relationships of this element (direct and indirect, outgoing from nested elements)")
|
|
142
|
+
}).describe("Relationships of this element"),
|
|
80
143
|
deployedInstances: z.array(z.string()).describe("Deployed instances of this element (Array of Deployment FQNs)"),
|
|
81
|
-
sourceLocation: locationSchema
|
|
144
|
+
sourceLocation: locationSchema
|
|
82
145
|
}
|
|
83
146
|
}, async (languageServices, args) => {
|
|
84
|
-
const projectId = args.project
|
|
85
|
-
const
|
|
86
|
-
invariant(project, `Project "${projectId}" not found`);
|
|
87
|
-
const model = await languageServices.computedModel(project.id);
|
|
147
|
+
const projectId = languageServices.projectsManager.ensureProjectId(args.project);
|
|
148
|
+
const model = await languageServices.computedModel(projectId);
|
|
88
149
|
const element = model.findElement(args.id);
|
|
89
150
|
invariant(element, `Element "${args.id}" not found in project "${projectId}"`);
|
|
151
|
+
const locate = mkLocate(languageServices, projectId);
|
|
90
152
|
return {
|
|
91
153
|
id: element.id,
|
|
92
154
|
name: element.name,
|
|
@@ -95,12 +157,13 @@ Returns information about LikeC4 element, includes:
|
|
|
95
157
|
description: element.description.text,
|
|
96
158
|
technology: element.technology,
|
|
97
159
|
tags: [...element.tags],
|
|
98
|
-
project:
|
|
160
|
+
project: projectId,
|
|
99
161
|
metadata: element.getMetadata(),
|
|
100
162
|
shape: element.shape,
|
|
163
|
+
color: element.color,
|
|
101
164
|
children: [...element.children()].map((c) => c.id),
|
|
102
|
-
defaultView: element.defaultView?.id,
|
|
103
|
-
includedInViews:
|
|
165
|
+
defaultView: element.defaultView?.id || null,
|
|
166
|
+
includedInViews: includedInViews(element.views()),
|
|
104
167
|
relationships: {
|
|
105
168
|
incoming: [...element.incoming()].map((r) => ({
|
|
106
169
|
source: {
|
|
@@ -130,6 +193,6 @@ Returns information about LikeC4 element, includes:
|
|
|
130
193
|
}))
|
|
131
194
|
},
|
|
132
195
|
deployedInstances: [...element.deployments()].map((i) => i.id),
|
|
133
|
-
sourceLocation:
|
|
196
|
+
sourceLocation: locate({ element: element.id })
|
|
134
197
|
};
|
|
135
198
|
});
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import z from 'zod';
|
|
2
2
|
export declare const readProjectSummary: (languageServices: import("../..").LikeC4LanguageServices) => [string, {
|
|
3
3
|
inputSchema?: {
|
|
4
|
-
project: z.ZodOptional<z.ZodString
|
|
4
|
+
project: z.ZodDefault<z.ZodOptional<z.ZodEffects<z.ZodString, ProjectId, string>>>;
|
|
5
5
|
} | undefined;
|
|
6
6
|
}, (args: {
|
|
7
|
-
|
|
7
|
+
[x: string]: any;
|
|
8
|
+
project?: unknown;
|
|
8
9
|
}, extra: import("@modelcontextprotocol/sdk/shared/protocol").RequestHandlerExtra<import("@modelcontextprotocol/sdk/types").ServerRequest, import("@modelcontextprotocol/sdk/types").ServerNotification>) => import("@modelcontextprotocol/sdk/types").CallToolResult | Promise<import("@modelcontextprotocol/sdk/types").CallToolResult>];
|
|
@@ -1,32 +1,93 @@
|
|
|
1
|
-
import { invariant } from "@likec4/core";
|
|
2
1
|
import { keys } from "remeda";
|
|
3
2
|
import z from "zod";
|
|
4
|
-
import { ProjectsManager } from "../../workspace/index.js";
|
|
5
3
|
import { likec4Tool } from "../utils.js";
|
|
6
|
-
import {
|
|
4
|
+
import { projectIdSchema } from "./_common.js";
|
|
7
5
|
export const readProjectSummary = likec4Tool({
|
|
8
6
|
name: "read-project-summary",
|
|
9
7
|
annotations: {
|
|
10
|
-
readOnlyHint: true
|
|
8
|
+
readOnlyHint: true,
|
|
9
|
+
idempotentHint: true,
|
|
10
|
+
title: "Read project summary"
|
|
11
11
|
},
|
|
12
12
|
description: `
|
|
13
|
-
|
|
14
|
-
- project
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
|
|
13
|
+
Request:
|
|
14
|
+
- project: string (optional) \u2014 project id. Defaults to "default" if omitted.
|
|
15
|
+
|
|
16
|
+
Response (JSON object):
|
|
17
|
+
- title: string \u2014 human-readable project title
|
|
18
|
+
- folder: string \u2014 absolute path to the project root
|
|
19
|
+
- sources: string[] \u2014 absolute file paths of model documents
|
|
20
|
+
- specification: object
|
|
21
|
+
- elementKinds: string[] \u2014 all element kinds
|
|
22
|
+
- relationshipKinds: string[] \u2014 all relationship kinds
|
|
23
|
+
- deploymentKinds: string[] \u2014 all deployment kinds
|
|
24
|
+
- tags: string[] \u2014 all tags
|
|
25
|
+
- metadataKeys: string[] \u2014 used metadata keys
|
|
26
|
+
- elements: Element[] \u2014 list of elements
|
|
27
|
+
- deployments: Deployment[] \u2014 list of deployment entities
|
|
28
|
+
- views: View[] \u2014 list of views defined in the model
|
|
29
|
+
|
|
30
|
+
Element (object) fields:
|
|
31
|
+
- id: string \u2014 element id (FQN)
|
|
32
|
+
- kind: string \u2014 element kind
|
|
33
|
+
- title: string \u2014 element title
|
|
34
|
+
- tags: string[] \u2014 element tags
|
|
35
|
+
|
|
36
|
+
Deployment (object) fields:
|
|
37
|
+
- type = "deployment-node": { id: string, kind: string, title: string, tags: string[] }
|
|
38
|
+
- type = "deployed-instance": { id: string, title: string, tags: string[], referencedElementId: string }
|
|
39
|
+
|
|
40
|
+
View (object) fields:
|
|
41
|
+
- id: string \u2014 view identifier
|
|
42
|
+
- title: string \u2014 view title
|
|
43
|
+
- type: "element" | "deployment" | "dynamic"
|
|
44
|
+
|
|
45
|
+
Notes:
|
|
46
|
+
- Read-only, idempotent, no side effects.
|
|
47
|
+
- Safe to call repeatedly.
|
|
48
|
+
|
|
49
|
+
Example response:
|
|
50
|
+
{
|
|
51
|
+
"title": "Cloud Boutique",
|
|
52
|
+
"folder": "/abs/path/to/workspace/examples/cloud-system",
|
|
53
|
+
"sources": [
|
|
54
|
+
"/abs/path/to/workspace/examples/cloud-system/model.c4"
|
|
55
|
+
],
|
|
56
|
+
"specification": {
|
|
57
|
+
"elementKinds": ["system", "container", "component"],
|
|
58
|
+
"relationshipKinds": ["uses", "depends-on"],
|
|
59
|
+
"deploymentKinds": ["node", "cluster"],
|
|
60
|
+
"tags": ["public", "internal"],
|
|
61
|
+
"metadataKeys": ["owner", "tier"]
|
|
62
|
+
},
|
|
63
|
+
"elements": [
|
|
64
|
+
{
|
|
65
|
+
"id": "shop.frontend",
|
|
66
|
+
"kind": "component",
|
|
67
|
+
"title": "Frontend",
|
|
68
|
+
"tags": ["public"]
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
"deployments": [
|
|
72
|
+
{
|
|
73
|
+
"type": "deployment-node",
|
|
74
|
+
"id": "k8s.shop.frontend",
|
|
75
|
+
"kind": "cluster",
|
|
76
|
+
"title": "Frontend",
|
|
77
|
+
"tags": []
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
"views": [
|
|
81
|
+
{
|
|
82
|
+
"name": "system-overview",
|
|
83
|
+
"title": "System Overview",
|
|
84
|
+
"type": "element"
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
27
88
|
`,
|
|
28
89
|
inputSchema: {
|
|
29
|
-
project:
|
|
90
|
+
project: projectIdSchema
|
|
30
91
|
},
|
|
31
92
|
outputSchema: {
|
|
32
93
|
title: z.string(),
|
|
@@ -39,22 +100,43 @@ Searches for LikeC4 project by name in workspace and returns its summary:
|
|
|
39
100
|
tags: z.array(z.string()),
|
|
40
101
|
metadataKeys: z.array(z.string())
|
|
41
102
|
}),
|
|
103
|
+
elements: z.array(z.object({
|
|
104
|
+
id: z.string(),
|
|
105
|
+
kind: z.string(),
|
|
106
|
+
title: z.string(),
|
|
107
|
+
tags: z.array(z.string())
|
|
108
|
+
})).describe("List of elements in the project"),
|
|
109
|
+
deployments: z.array(
|
|
110
|
+
z.discriminatedUnion("type", [
|
|
111
|
+
z.object({
|
|
112
|
+
type: z.literal("deployment-node"),
|
|
113
|
+
id: z.string().describe("Node ID"),
|
|
114
|
+
kind: z.string().describe("Deployment node kind"),
|
|
115
|
+
title: z.string().describe("Node title"),
|
|
116
|
+
tags: z.array(z.string())
|
|
117
|
+
}),
|
|
118
|
+
z.object({
|
|
119
|
+
type: z.literal("deployed-instance"),
|
|
120
|
+
id: z.string().describe("Node ID"),
|
|
121
|
+
title: z.string().describe("Node title"),
|
|
122
|
+
tags: z.array(z.string()),
|
|
123
|
+
referencedElementId: z.string().describe("Element ID (FQN)")
|
|
124
|
+
})
|
|
125
|
+
])
|
|
126
|
+
).describe("List of deployment nodes and deployed instances in the project"),
|
|
42
127
|
views: z.array(z.object({
|
|
43
|
-
|
|
44
|
-
title: z.string()
|
|
45
|
-
type: z.enum(["element", "deployment", "dynamic"])
|
|
46
|
-
sourceLocation: locationSchema.nullish()
|
|
128
|
+
id: z.string(),
|
|
129
|
+
title: z.string(),
|
|
130
|
+
type: z.enum(["element", "deployment", "dynamic"])
|
|
47
131
|
}))
|
|
48
132
|
}
|
|
49
133
|
}, async (languageServices, args) => {
|
|
50
|
-
const projectId = args.project
|
|
51
|
-
const project = languageServices.
|
|
52
|
-
|
|
53
|
-
const model = await languageServices.computedModel(project.id);
|
|
134
|
+
const projectId = languageServices.projectsManager.ensureProjectId(args.project);
|
|
135
|
+
const project = languageServices.project(projectId);
|
|
136
|
+
const model = await languageServices.computedModel(projectId);
|
|
54
137
|
return {
|
|
55
138
|
title: project.title,
|
|
56
|
-
folder: project.folder.
|
|
57
|
-
sources: project.documents?.map((d) => d.toString()) ?? [],
|
|
139
|
+
folder: project.folder.fsPath,
|
|
58
140
|
specification: {
|
|
59
141
|
elementKinds: keys(model.specification.elements),
|
|
60
142
|
relationshipKinds: keys(model.specification.relationships),
|
|
@@ -62,10 +144,35 @@ Searches for LikeC4 project by name in workspace and returns its summary:
|
|
|
62
144
|
tags: [...model.tags],
|
|
63
145
|
metadataKeys: model.specification.metadataKeys ?? []
|
|
64
146
|
},
|
|
147
|
+
elements: [...model.elements()].filter((e) => !e.imported).map((e) => ({
|
|
148
|
+
id: e.id,
|
|
149
|
+
kind: e.kind,
|
|
150
|
+
title: e.title,
|
|
151
|
+
tags: [...e.tags]
|
|
152
|
+
})),
|
|
153
|
+
deployments: [...model.deployment.elements()].map((d) => {
|
|
154
|
+
if (d.isInstance()) {
|
|
155
|
+
return {
|
|
156
|
+
type: "deployed-instance",
|
|
157
|
+
id: d.id,
|
|
158
|
+
title: d.title,
|
|
159
|
+
tags: [...d.tags],
|
|
160
|
+
referencedElementId: d.element.id
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
type: "deployment-node",
|
|
165
|
+
id: d.id,
|
|
166
|
+
kind: d.kind,
|
|
167
|
+
title: d.title,
|
|
168
|
+
tags: [...d.tags]
|
|
169
|
+
};
|
|
170
|
+
}),
|
|
65
171
|
views: [...model.views()].map((v) => ({
|
|
66
|
-
|
|
67
|
-
title: v.
|
|
172
|
+
id: v.id,
|
|
173
|
+
title: v.titleOrId,
|
|
68
174
|
type: v.$view._type
|
|
69
|
-
}))
|
|
175
|
+
})),
|
|
176
|
+
sources: project.documents?.map((d) => d.fsPath) ?? []
|
|
70
177
|
};
|
|
71
178
|
});
|
|
@@ -2,9 +2,10 @@ import z from 'zod';
|
|
|
2
2
|
export declare const readView: (languageServices: import("../..").LikeC4LanguageServices) => [string, {
|
|
3
3
|
inputSchema?: {
|
|
4
4
|
viewId: z.ZodString;
|
|
5
|
-
project: z.ZodOptional<z.ZodString
|
|
5
|
+
project: z.ZodDefault<z.ZodOptional<z.ZodEffects<z.ZodString, ProjectId, string>>>;
|
|
6
6
|
} | undefined;
|
|
7
7
|
}, (args: {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
[x: string]: any;
|
|
9
|
+
viewId?: unknown;
|
|
10
|
+
project?: unknown;
|
|
10
11
|
}, extra: import("@modelcontextprotocol/sdk/shared/protocol").RequestHandlerExtra<import("@modelcontextprotocol/sdk/types").ServerRequest, import("@modelcontextprotocol/sdk/types").ServerNotification>) => import("@modelcontextprotocol/sdk/types").CallToolResult | Promise<import("@modelcontextprotocol/sdk/types").CallToolResult>];
|