@pascal-app/mcp 1.0.6 → 1.1.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 +32 -11
- package/dist/bin/pascal-mcp.js +2 -0
- package/dist/bridge/agent-session.d.ts +2 -1
- package/dist/bridge/agent-session.d.ts.map +1 -1
- package/dist/bridge/agent-session.js +0 -1
- package/dist/bridge/scene-bridge.d.ts +22 -14
- package/dist/bridge/scene-bridge.d.ts.map +1 -1
- package/dist/bridge/scene-bridge.js +180 -198
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/safe-fetch.d.ts +6 -0
- package/dist/lib/safe-fetch.d.ts.map +1 -1
- package/dist/lib/safe-fetch.js +135 -41
- package/dist/operations/scene-operations.d.ts +7 -0
- package/dist/operations/scene-operations.d.ts.map +1 -1
- package/dist/operations/scene-operations.js +4 -0
- package/dist/prompts/from-brief.js +1 -1
- package/dist/prompts/iterate-on-feedback.js +1 -1
- package/dist/prompts/renovation-from-photos.js +1 -1
- package/dist/prompts/scene-guidance.js +2 -2
- package/dist/resources/agent-guide.d.ts.map +1 -1
- package/dist/resources/agent-guide.js +8 -3
- package/dist/resources/catalog-items.d.ts +4 -1
- package/dist/resources/catalog-items.d.ts.map +1 -1
- package/dist/resources/catalog-items.js +14 -6
- package/dist/server.d.ts +9 -5
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +21 -5
- package/dist/templates/empty-studio.d.ts.map +1 -1
- package/dist/templates/empty-studio.js +2 -3
- package/dist/templates/garden-house.d.ts.map +1 -1
- package/dist/templates/garden-house.js +2 -3
- package/dist/templates/two-bedroom.d.ts.map +1 -1
- package/dist/templates/two-bedroom.js +2 -3
- package/dist/tools/add-column.d.ts.map +1 -1
- package/dist/tools/add-column.js +9 -6
- package/dist/tools/add-object.d.ts +44 -5
- package/dist/tools/add-object.d.ts.map +1 -1
- package/dist/tools/add-object.js +75 -21
- package/dist/tools/apply-patch.js +1 -1
- package/dist/tools/asset-catalog.d.ts +5 -6
- package/dist/tools/asset-catalog.d.ts.map +1 -1
- package/dist/tools/asset-catalog.js +1 -9
- package/dist/tools/author-scene.d.ts +8 -5
- package/dist/tools/author-scene.d.ts.map +1 -1
- package/dist/tools/author-scene.js +302 -51
- package/dist/tools/clear-scene.js +2 -2
- package/dist/tools/collections.d.ts.map +1 -1
- package/dist/tools/collections.js +8 -5
- package/dist/tools/honest-patch-guard.js +6 -5
- package/dist/tools/hosted-services.d.ts.map +1 -1
- package/dist/tools/hosted-services.js +2 -2
- package/dist/tools/index.d.ts +7 -2
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +3 -9
- package/dist/tools/local-geometry-scripts.d.ts.map +1 -1
- package/dist/tools/local-geometry-scripts.js +7 -2
- package/dist/tools/patch-guards.d.ts.map +1 -1
- package/dist/tools/patch-guards.js +32 -15
- package/dist/tools/project-files.d.ts.map +1 -1
- package/dist/tools/project-files.js +2 -2
- package/dist/tools/room-tools.d.ts +1 -0
- package/dist/tools/room-tools.d.ts.map +1 -1
- package/dist/tools/room-tools.js +11 -8
- package/dist/tools/scene-scope.d.ts +4 -0
- package/dist/tools/scene-scope.d.ts.map +1 -0
- package/dist/tools/scene-scope.js +4 -0
- package/dist/tools/shared-tools.d.ts +0 -2
- package/dist/tools/shared-tools.d.ts.map +1 -1
- package/dist/tools/shared-tools.js +146 -31
- package/dist/tools/templates/create-house-from-brief.js +1 -1
- package/dist/tools/view-scene.js +2 -2
- package/examples/coordinate-conventions-demo.md +1 -0
- package/examples/photo-to-scene.md +1 -0
- package/examples/renovate-from-photos.md +2 -0
- package/package.json +10 -10
- package/dist/tools/create-unit.d.ts +0 -29
- package/dist/tools/create-unit.d.ts.map +0 -1
- package/dist/tools/create-unit.js +0 -36
- package/dist/tools/list-units.d.ts +0 -38
- package/dist/tools/list-units.d.ts.map +0 -1
- package/dist/tools/list-units.js +0 -61
- package/dist/tools/set-unit-members.d.ts +0 -22
- package/dist/tools/set-unit-members.d.ts.map +0 -1
- package/dist/tools/set-unit-members.js +0 -43
- package/dist/tools/unit-members.d.ts +0 -4
- package/dist/tools/unit-members.d.ts.map +0 -1
- package/dist/tools/unit-members.js +0 -24
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pascal-app/mcp",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Model Context Protocol server for Pascal 3D editor",
|
|
5
5
|
"mcpName": "app.pascal/editor",
|
|
6
6
|
"type": "module",
|
|
@@ -62,21 +62,21 @@
|
|
|
62
62
|
"prepublishOnly": "bun run build && bun test && bun run smoke:node"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
65
|
-
"@pascal-app/core": "^1.0
|
|
65
|
+
"@pascal-app/core": "^1.1.0"
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@hono/node-server": "^1.
|
|
69
|
-
"@modelcontextprotocol/node": "^2.1.
|
|
70
|
-
"@modelcontextprotocol/server": "^2.
|
|
71
|
-
"@pascal-app/geometry-script": "^1.0
|
|
68
|
+
"@hono/node-server": "^2.1.6",
|
|
69
|
+
"@modelcontextprotocol/node": "^2.1.2",
|
|
70
|
+
"@modelcontextprotocol/server": "^2.4.0",
|
|
71
|
+
"@pascal-app/geometry-script": "^1.1.0",
|
|
72
72
|
"@pascal-app/lingo": "^0.5.0",
|
|
73
73
|
"zod": ">=4.6.7 <4.7"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@modelcontextprotocol/client": "^2.
|
|
77
|
-
"@pascal-app/core": "^1.0
|
|
76
|
+
"@modelcontextprotocol/client": "^2.4.0",
|
|
77
|
+
"@pascal-app/core": "^1.1.0",
|
|
78
78
|
"@pascal/typescript-config": "*",
|
|
79
|
-
"@types/node": "^26.6.
|
|
79
|
+
"@types/node": "^26.6.6",
|
|
80
80
|
"typescript": "7.0.2"
|
|
81
81
|
},
|
|
82
82
|
"keywords": [
|
|
@@ -94,6 +94,6 @@
|
|
|
94
94
|
"directory": "packages/mcp"
|
|
95
95
|
},
|
|
96
96
|
"license": "MIT",
|
|
97
|
-
"homepage": "https://
|
|
97
|
+
"homepage": "https://editor.pascal.app/docs/developers/mcp",
|
|
98
98
|
"bugs": "https://github.com/pascalorg/editor/issues"
|
|
99
99
|
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/server';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import type { SceneOperations } from '../operations/index.js';
|
|
4
|
-
export declare const createUnitInput: {
|
|
5
|
-
buildingId: z.ZodString;
|
|
6
|
-
name: z.ZodString;
|
|
7
|
-
kind: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
8
|
-
apartment: "apartment";
|
|
9
|
-
commercial: "commercial";
|
|
10
|
-
common: "common";
|
|
11
|
-
"hotel-room": "hotel-room";
|
|
12
|
-
}>>>;
|
|
13
|
-
color: z.ZodOptional<z.ZodString>;
|
|
14
|
-
memberZoneIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
15
|
-
};
|
|
16
|
-
export declare const createUnitOutput: {
|
|
17
|
-
project: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
18
|
-
unsaved: z.ZodOptional<z.ZodString>;
|
|
19
|
-
persistence: z.ZodOptional<z.ZodObject<{
|
|
20
|
-
status: z.ZodEnum<{
|
|
21
|
-
events_unsupported: "events_unsupported";
|
|
22
|
-
unbound: "unbound";
|
|
23
|
-
}>;
|
|
24
|
-
warning: z.ZodString;
|
|
25
|
-
}, z.core.$strip>>;
|
|
26
|
-
unitId: z.ZodString;
|
|
27
|
-
};
|
|
28
|
-
export declare function registerCreateUnit(server: McpServer, bridge: SceneOperations): void;
|
|
29
|
-
//# sourceMappingURL=create-unit.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"create-unit.d.ts","sourceRoot":"","sources":["../../src/tools/create-unit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAG7D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAMpD,eAAO,MAAM,eAAe;IAC1B,UAAU;IACV,IAAI;IACJ,IAAI;;;;;;IACJ,KAAK;IACL,aAAa;CACd,CAAA;AAED,eAAO,MAAM,gBAAgB;;;;;;;;;;;CAG5B,CAAA;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAuBnF"}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { UnitNode } from '@pascal-app/core/schema';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import { ADDITIVE_TOOL_ANNOTATIONS } from './annotations.js';
|
|
4
|
-
import { liveSyncOutput, persistencePayload, publishLiveSceneSnapshot } from './live-sync.js';
|
|
5
|
-
import { NodeIdSchema } from './schemas.js';
|
|
6
|
-
import { validateUnitMembers } from './unit-members.js';
|
|
7
|
-
export const createUnitInput = {
|
|
8
|
-
buildingId: NodeIdSchema,
|
|
9
|
-
name: z.string(),
|
|
10
|
-
kind: UnitNode.shape.kind.optional(),
|
|
11
|
-
color: z.string().optional(),
|
|
12
|
-
memberZoneIds: z.array(NodeIdSchema).optional(),
|
|
13
|
-
};
|
|
14
|
-
export const createUnitOutput = {
|
|
15
|
-
unitId: z.string(),
|
|
16
|
-
...liveSyncOutput,
|
|
17
|
-
};
|
|
18
|
-
export function registerCreateUnit(server, bridge) {
|
|
19
|
-
server.registerTool('create_unit', {
|
|
20
|
-
title: 'Create unit',
|
|
21
|
-
description: 'Create a named unit in a building, optionally referencing zones across its levels.',
|
|
22
|
-
inputSchema: z.object(createUnitInput),
|
|
23
|
-
outputSchema: z.object(createUnitOutput),
|
|
24
|
-
annotations: ADDITIVE_TOOL_ANNOTATIONS,
|
|
25
|
-
}, async ({ buildingId, name, kind, color, memberZoneIds }) => {
|
|
26
|
-
const members = validateUnitMembers(bridge, buildingId, memberZoneIds ?? []);
|
|
27
|
-
const unit = UnitNode.parse({ name, kind, color, members });
|
|
28
|
-
const id = bridge.createNode(unit, buildingId);
|
|
29
|
-
const persistence = await publishLiveSceneSnapshot(bridge, 'create_unit');
|
|
30
|
-
const payload = { unitId: id, ...persistencePayload(persistence) };
|
|
31
|
-
return {
|
|
32
|
-
content: [{ type: 'text', text: JSON.stringify(payload) }],
|
|
33
|
-
structuredContent: payload,
|
|
34
|
-
};
|
|
35
|
-
});
|
|
36
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/server';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import type { SceneOperations } from '../operations/index.js';
|
|
4
|
-
export declare const listUnitsInput: {
|
|
5
|
-
buildingId: z.ZodOptional<z.ZodString>;
|
|
6
|
-
};
|
|
7
|
-
export declare const listUnitsOutput: {
|
|
8
|
-
units: z.ZodArray<z.ZodObject<{
|
|
9
|
-
unitId: z.ZodString;
|
|
10
|
-
name: z.ZodString;
|
|
11
|
-
kind: z.ZodDefault<z.ZodEnum<{
|
|
12
|
-
apartment: "apartment";
|
|
13
|
-
commercial: "commercial";
|
|
14
|
-
common: "common";
|
|
15
|
-
"hotel-room": "hotel-room";
|
|
16
|
-
}>>;
|
|
17
|
-
color: z.ZodString;
|
|
18
|
-
members: z.ZodArray<z.ZodString>;
|
|
19
|
-
report: z.ZodObject<{
|
|
20
|
-
memberCount: z.ZodNumber;
|
|
21
|
-
levelSpan: z.ZodNullable<z.ZodObject<{
|
|
22
|
-
minOrdinal: z.ZodNumber;
|
|
23
|
-
maxOrdinal: z.ZodNumber;
|
|
24
|
-
count: z.ZodNumber;
|
|
25
|
-
}, z.core.$strip>>;
|
|
26
|
-
grossAreaM2: z.ZodNumber;
|
|
27
|
-
members: z.ZodArray<z.ZodObject<{
|
|
28
|
-
zoneId: z.ZodString;
|
|
29
|
-
name: z.ZodString;
|
|
30
|
-
levelId: z.ZodNullable<z.ZodString>;
|
|
31
|
-
levelOrdinal: z.ZodNullable<z.ZodNumber>;
|
|
32
|
-
areaM2: z.ZodNumber;
|
|
33
|
-
}, z.core.$strip>>;
|
|
34
|
-
}, z.core.$strip>;
|
|
35
|
-
}, z.core.$strip>>;
|
|
36
|
-
};
|
|
37
|
-
export declare function registerListUnits(server: McpServer, bridge: SceneOperations): void;
|
|
38
|
-
//# sourceMappingURL=list-units.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"list-units.d.ts","sourceRoot":"","sources":["../../src/tools/list-units.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAG7D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAKpD,eAAO,MAAM,cAAc;IACzB,UAAU;CACX,CAAA;AAED,eAAO,MAAM,eAAe;IAC1B,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyBN,CAAA;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAgClF"}
|
package/dist/tools/list-units.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { buildUnitReport } from '@pascal-app/core';
|
|
2
|
-
import { UnitNode } from '@pascal-app/core/schema';
|
|
3
|
-
import { z } from 'zod';
|
|
4
|
-
import { READ_ONLY_TOOL_ANNOTATIONS } from './annotations.js';
|
|
5
|
-
import { NodeIdSchema } from './schemas.js';
|
|
6
|
-
import { validateUnitMembers } from './unit-members.js';
|
|
7
|
-
export const listUnitsInput = {
|
|
8
|
-
buildingId: NodeIdSchema.optional(),
|
|
9
|
-
};
|
|
10
|
-
export const listUnitsOutput = {
|
|
11
|
-
units: z.array(z.object({
|
|
12
|
-
unitId: z.string(),
|
|
13
|
-
name: z.string(),
|
|
14
|
-
kind: UnitNode.shape.kind,
|
|
15
|
-
color: z.string(),
|
|
16
|
-
members: z.array(z.string()),
|
|
17
|
-
report: z.object({
|
|
18
|
-
memberCount: z.number(),
|
|
19
|
-
levelSpan: z
|
|
20
|
-
.object({ minOrdinal: z.number(), maxOrdinal: z.number(), count: z.number() })
|
|
21
|
-
.nullable(),
|
|
22
|
-
grossAreaM2: z.number(),
|
|
23
|
-
members: z.array(z.object({
|
|
24
|
-
zoneId: z.string(),
|
|
25
|
-
name: z.string(),
|
|
26
|
-
levelId: z.string().nullable(),
|
|
27
|
-
levelOrdinal: z.number().nullable(),
|
|
28
|
-
areaM2: z.number(),
|
|
29
|
-
})),
|
|
30
|
-
}),
|
|
31
|
-
})),
|
|
32
|
-
};
|
|
33
|
-
export function registerListUnits(server, bridge) {
|
|
34
|
-
server.registerTool('list_units', {
|
|
35
|
-
title: 'List units',
|
|
36
|
-
description: 'List units with their member zones and current area reports, optionally filtered by building.',
|
|
37
|
-
inputSchema: z.object(listUnitsInput),
|
|
38
|
-
outputSchema: z.object(listUnitsOutput),
|
|
39
|
-
annotations: READ_ONLY_TOOL_ANNOTATIONS,
|
|
40
|
-
}, async ({ buildingId }) => {
|
|
41
|
-
if (buildingId !== undefined)
|
|
42
|
-
validateUnitMembers(bridge, buildingId, []);
|
|
43
|
-
const nodes = bridge.getNodes();
|
|
44
|
-
const units = Object.values(nodes)
|
|
45
|
-
.filter((node) => node.type === 'unit')
|
|
46
|
-
.filter((unit) => buildingId === undefined || unit.parentId === buildingId)
|
|
47
|
-
.map((unit) => ({
|
|
48
|
-
unitId: unit.id,
|
|
49
|
-
name: unit.name,
|
|
50
|
-
kind: unit.kind,
|
|
51
|
-
color: unit.color,
|
|
52
|
-
members: unit.members,
|
|
53
|
-
report: buildUnitReport(unit, nodes),
|
|
54
|
-
}));
|
|
55
|
-
const payload = { units };
|
|
56
|
-
return {
|
|
57
|
-
content: [{ type: 'text', text: JSON.stringify(payload) }],
|
|
58
|
-
structuredContent: payload,
|
|
59
|
-
};
|
|
60
|
-
});
|
|
61
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/server';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import type { SceneOperations } from '../operations/index.js';
|
|
4
|
-
export declare const setUnitMembersInput: {
|
|
5
|
-
unitId: z.ZodString;
|
|
6
|
-
memberZoneIds: z.ZodArray<z.ZodString>;
|
|
7
|
-
};
|
|
8
|
-
export declare const setUnitMembersOutput: {
|
|
9
|
-
project: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
10
|
-
unsaved: z.ZodOptional<z.ZodString>;
|
|
11
|
-
persistence: z.ZodOptional<z.ZodObject<{
|
|
12
|
-
status: z.ZodEnum<{
|
|
13
|
-
events_unsupported: "events_unsupported";
|
|
14
|
-
unbound: "unbound";
|
|
15
|
-
}>;
|
|
16
|
-
warning: z.ZodString;
|
|
17
|
-
}, z.core.$strip>>;
|
|
18
|
-
unitId: z.ZodString;
|
|
19
|
-
memberCount: z.ZodNumber;
|
|
20
|
-
};
|
|
21
|
-
export declare function registerSetUnitMembers(server: McpServer, bridge: SceneOperations): void;
|
|
22
|
-
//# sourceMappingURL=set-unit-members.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"set-unit-members.d.ts","sourceRoot":"","sources":["../../src/tools/set-unit-members.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAE7D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAOpD,eAAO,MAAM,mBAAmB;IAC9B,MAAM;IACN,aAAa;CACd,CAAA;AAED,eAAO,MAAM,oBAAoB;;;;;;;;;;;;CAIhC,CAAA;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAmCvF"}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { DESTRUCTIVE_TOOL_ANNOTATIONS } from './annotations.js';
|
|
3
|
-
import { ProtocolErrorCode, throwMcpError } from './errors.js';
|
|
4
|
-
import { liveSyncOutput, persistencePayload, publishLiveSceneSnapshot } from './live-sync.js';
|
|
5
|
-
import { NodeIdSchema } from './schemas.js';
|
|
6
|
-
import { validateUnitMembers } from './unit-members.js';
|
|
7
|
-
export const setUnitMembersInput = {
|
|
8
|
-
unitId: NodeIdSchema,
|
|
9
|
-
memberZoneIds: z.array(NodeIdSchema),
|
|
10
|
-
};
|
|
11
|
-
export const setUnitMembersOutput = {
|
|
12
|
-
unitId: z.string(),
|
|
13
|
-
memberCount: z.number(),
|
|
14
|
-
...liveSyncOutput,
|
|
15
|
-
};
|
|
16
|
-
export function registerSetUnitMembers(server, bridge) {
|
|
17
|
-
server.registerTool('set_unit_members', {
|
|
18
|
-
title: 'Set unit members',
|
|
19
|
-
description: 'Replace the zones referenced by a unit. Every zone must belong to a level in the same building.',
|
|
20
|
-
inputSchema: z.object(setUnitMembersInput),
|
|
21
|
-
outputSchema: z.object(setUnitMembersOutput),
|
|
22
|
-
annotations: { ...DESTRUCTIVE_TOOL_ANNOTATIONS, idempotentHint: true },
|
|
23
|
-
}, async ({ unitId, memberZoneIds }) => {
|
|
24
|
-
const unit = bridge.getNode(unitId);
|
|
25
|
-
if (!unit) {
|
|
26
|
-
throwMcpError(ProtocolErrorCode.InvalidParams, `Unit not found: ${unitId}`);
|
|
27
|
-
}
|
|
28
|
-
if (unit.type !== 'unit') {
|
|
29
|
-
throwMcpError(ProtocolErrorCode.InvalidParams, `Node ${unitId} is a ${unit.type}, expected unit`);
|
|
30
|
-
}
|
|
31
|
-
if (!unit.parentId) {
|
|
32
|
-
throwMcpError(ProtocolErrorCode.InvalidParams, `Unit ${unitId} must belong to a building`);
|
|
33
|
-
}
|
|
34
|
-
const members = validateUnitMembers(bridge, unit.parentId, memberZoneIds);
|
|
35
|
-
bridge.updateNode(unit.id, { members });
|
|
36
|
-
const persistence = await publishLiveSceneSnapshot(bridge, 'set_unit_members');
|
|
37
|
-
const payload = { unitId, memberCount: members.length, ...persistencePayload(persistence) };
|
|
38
|
-
return {
|
|
39
|
-
content: [{ type: 'text', text: JSON.stringify(payload) }],
|
|
40
|
-
structuredContent: payload,
|
|
41
|
-
};
|
|
42
|
-
});
|
|
43
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { ZoneNode } from '@pascal-app/core/schema';
|
|
2
|
-
import type { SceneOperations } from '../operations/index.js';
|
|
3
|
-
export declare function validateUnitMembers(bridge: SceneOperations, buildingId: string, memberZoneIds: string[]): ZoneNode['id'][];
|
|
4
|
-
//# sourceMappingURL=unit-members.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"unit-members.d.ts","sourceRoot":"","sources":["../../src/tools/unit-members.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAGpD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,eAAe,EACvB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EAAE,GACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,CAgClB"}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { ProtocolErrorCode, throwMcpError } from './errors.js';
|
|
2
|
-
export function validateUnitMembers(bridge, buildingId, memberZoneIds) {
|
|
3
|
-
const building = bridge.getNode(buildingId);
|
|
4
|
-
if (!building) {
|
|
5
|
-
throwMcpError(ProtocolErrorCode.InvalidParams, `Building not found: ${buildingId}`);
|
|
6
|
-
}
|
|
7
|
-
if (building.type !== 'building') {
|
|
8
|
-
throwMcpError(ProtocolErrorCode.InvalidParams, `Node ${buildingId} is a ${building.type}, expected building`);
|
|
9
|
-
}
|
|
10
|
-
return memberZoneIds.map((zoneId) => {
|
|
11
|
-
const zone = bridge.getNode(zoneId);
|
|
12
|
-
if (!zone) {
|
|
13
|
-
throwMcpError(ProtocolErrorCode.InvalidParams, `Zone not found: ${zoneId}`);
|
|
14
|
-
}
|
|
15
|
-
if (zone.type !== 'zone') {
|
|
16
|
-
throwMcpError(ProtocolErrorCode.InvalidParams, `Node ${zoneId} is a ${zone.type}, expected zone`);
|
|
17
|
-
}
|
|
18
|
-
const [, level, parent] = bridge.getAncestry(zone.id);
|
|
19
|
-
if (level?.type !== 'level' || parent?.id !== building.id) {
|
|
20
|
-
throwMcpError(ProtocolErrorCode.InvalidParams, `Zone ${zoneId} must belong to a level in building ${buildingId}`);
|
|
21
|
-
}
|
|
22
|
-
return zone.id;
|
|
23
|
-
});
|
|
24
|
-
}
|