@pascal-app/mcp 1.0.4 → 1.0.6
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/CHANGELOG.md +76 -0
- package/README.md +166 -62
- package/dist/bin/pascal-mcp.js +1 -1
- package/dist/bridge/agent-session.d.ts +18 -0
- package/dist/bridge/agent-session.d.ts.map +1 -0
- package/dist/bridge/agent-session.js +15 -0
- package/dist/bridge/index.d.ts +1 -1
- package/dist/bridge/index.d.ts.map +1 -1
- package/dist/bridge/scene-bridge.d.ts +3 -0
- package/dist/bridge/scene-bridge.d.ts.map +1 -1
- package/dist/bridge/scene-bridge.js +7 -0
- package/dist/lib/safe-fetch.d.ts +22 -4
- package/dist/lib/safe-fetch.d.ts.map +1 -1
- package/dist/lib/safe-fetch.js +233 -134
- package/dist/operations/scene-operations.d.ts +18 -0
- package/dist/operations/scene-operations.d.ts.map +1 -1
- package/dist/operations/scene-operations.js +11 -0
- package/dist/prompts/from-brief.d.ts +1 -1
- package/dist/prompts/from-brief.d.ts.map +1 -1
- package/dist/prompts/from-brief.js +3 -3
- package/dist/prompts/index.d.ts +1 -1
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/iterate-on-feedback.d.ts +1 -1
- package/dist/prompts/iterate-on-feedback.d.ts.map +1 -1
- package/dist/prompts/iterate-on-feedback.js +2 -2
- package/dist/prompts/renovation-from-photos.d.ts +1 -1
- package/dist/prompts/renovation-from-photos.d.ts.map +1 -1
- package/dist/prompts/renovation-from-photos.js +2 -2
- package/dist/prompts/scene-guidance.d.ts.map +1 -1
- package/dist/prompts/scene-guidance.js +10 -3
- package/dist/resources/agent-guide.d.ts +1 -1
- package/dist/resources/agent-guide.d.ts.map +1 -1
- package/dist/resources/agent-guide.js +52 -44
- package/dist/resources/catalog-items.d.ts +1 -1
- package/dist/resources/catalog-items.d.ts.map +1 -1
- package/dist/resources/constraints.d.ts +1 -1
- package/dist/resources/constraints.d.ts.map +1 -1
- package/dist/resources/constraints.js +1 -1
- package/dist/resources/design-schema.d.ts +1 -1
- package/dist/resources/design-schema.d.ts.map +1 -1
- package/dist/resources/index.d.ts +1 -1
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/resources/scene-current.d.ts +1 -1
- package/dist/resources/scene-current.d.ts.map +1 -1
- package/dist/resources/scene-summary.d.ts +1 -1
- package/dist/resources/scene-summary.d.ts.map +1 -1
- package/dist/server.d.ts +7 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +59 -21
- package/dist/storage/disk-artifact-store.d.ts.map +1 -1
- package/dist/storage/sqlite-scene-store.d.ts +1 -1
- package/dist/storage/sqlite-scene-store.d.ts.map +1 -1
- package/dist/storage/types.d.ts +4 -4
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/templates/empty-studio.d.ts +3 -3
- package/dist/templates/empty-studio.d.ts.map +1 -1
- package/dist/templates/garden-house.d.ts +3 -3
- package/dist/templates/garden-house.d.ts.map +1 -1
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/two-bedroom.d.ts +3 -3
- package/dist/templates/two-bedroom.d.ts.map +1 -1
- package/dist/tools/add-column.d.ts +1 -1
- package/dist/tools/add-column.d.ts.map +1 -1
- package/dist/tools/add-column.js +3 -2
- package/dist/tools/add-object.d.ts +19 -3
- package/dist/tools/add-object.d.ts.map +1 -1
- package/dist/tools/add-object.js +66 -35
- package/dist/tools/annotations.d.ts.map +1 -1
- package/dist/tools/apply-patch.d.ts +6 -2
- package/dist/tools/apply-patch.d.ts.map +1 -1
- package/dist/tools/apply-patch.js +13 -8
- package/dist/tools/asset-catalog.d.ts.map +1 -1
- package/dist/tools/asset-catalog.js +23 -0
- package/dist/tools/author-scene.d.ts +10 -0
- package/dist/tools/author-scene.d.ts.map +1 -0
- package/dist/tools/author-scene.js +140 -0
- package/dist/tools/check-collisions.d.ts +6 -6
- package/dist/tools/check-collisions.d.ts.map +1 -1
- package/dist/tools/check-collisions.js +6 -6
- package/dist/tools/clear-scene.d.ts +1 -1
- package/dist/tools/clear-scene.d.ts.map +1 -1
- package/dist/tools/clear-scene.js +3 -3
- package/dist/tools/collections.d.ts +1 -1
- package/dist/tools/collections.d.ts.map +1 -1
- package/dist/tools/collections.js +3 -2
- package/dist/tools/construction-tools.d.ts +6 -49
- package/dist/tools/construction-tools.d.ts.map +1 -1
- package/dist/tools/construction-tools.js +9 -158
- package/dist/tools/create-unit.d.ts +3 -3
- package/dist/tools/create-unit.d.ts.map +1 -1
- package/dist/tools/create-unit.js +2 -2
- package/dist/tools/errors.d.ts +5 -5
- package/dist/tools/errors.d.ts.map +1 -1
- package/dist/tools/errors.js +4 -4
- package/dist/tools/export-glb.d.ts +1 -1
- package/dist/tools/export-glb.d.ts.map +1 -1
- package/dist/tools/export-glb.js +2 -2
- package/dist/tools/export-json.d.ts +1 -1
- package/dist/tools/export-json.d.ts.map +1 -1
- package/dist/tools/export-json.js +2 -2
- package/dist/tools/get-scene.d.ts +1 -1
- package/dist/tools/get-scene.d.ts.map +1 -1
- package/dist/tools/get-scene.js +2 -2
- package/dist/tools/hosted-services.d.ts +1 -1
- package/dist/tools/hosted-services.d.ts.map +1 -1
- package/dist/tools/hosted-services.js +13 -3
- package/dist/tools/index.d.ts +4 -3
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +8 -13
- package/dist/tools/level-height-guard.d.ts +2 -0
- package/dist/tools/level-height-guard.d.ts.map +1 -0
- package/dist/tools/level-height-guard.js +11 -0
- package/dist/tools/list-units.d.ts +2 -2
- package/dist/tools/list-units.d.ts.map +1 -1
- package/dist/tools/list-units.js +2 -2
- package/dist/tools/live-sync.d.ts +1 -1
- package/dist/tools/live-sync.d.ts.map +1 -1
- package/dist/tools/live-sync.js +4 -4
- package/dist/tools/measure.d.ts +1 -1
- package/dist/tools/measure.d.ts.map +1 -1
- package/dist/tools/measure.js +7 -7
- package/dist/tools/node-world-point.d.ts +1 -1
- package/dist/tools/node-world-point.d.ts.map +1 -1
- package/dist/tools/normalize-schema-dialect.d.ts +1 -1
- package/dist/tools/normalize-schema-dialect.d.ts.map +1 -1
- package/dist/tools/normalize-schema-dialect.js +2 -3
- package/dist/tools/patch-guards.d.ts +6 -4
- package/dist/tools/patch-guards.d.ts.map +1 -1
- package/dist/tools/patch-guards.js +5 -2
- package/dist/tools/photo-to-scene/index.d.ts +1 -1
- package/dist/tools/photo-to-scene/index.d.ts.map +1 -1
- package/dist/tools/photo-to-scene/photo-to-scene.d.ts +3 -3
- package/dist/tools/photo-to-scene/photo-to-scene.d.ts.map +1 -1
- package/dist/tools/photo-to-scene/photo-to-scene.js +7 -7
- package/dist/tools/project-files.d.ts +4 -0
- package/dist/tools/project-files.d.ts.map +1 -0
- package/dist/tools/project-files.js +30 -0
- package/dist/tools/redo.d.ts +2 -2
- package/dist/tools/redo.d.ts.map +1 -1
- package/dist/tools/redo.js +2 -2
- package/dist/tools/retired-tools.d.ts +10 -0
- package/dist/tools/retired-tools.d.ts.map +1 -0
- package/dist/tools/retired-tools.js +22 -0
- package/dist/tools/roof-level-guard.d.ts +2 -0
- package/dist/tools/roof-level-guard.d.ts.map +1 -0
- package/dist/tools/roof-level-guard.js +22 -0
- package/dist/tools/room-tools.d.ts +47 -46
- package/dist/tools/room-tools.d.ts.map +1 -1
- package/dist/tools/room-tools.js +6 -5
- package/dist/tools/scene-lifecycle/create-project.d.ts +1 -1
- package/dist/tools/scene-lifecycle/create-project.d.ts.map +1 -1
- package/dist/tools/scene-lifecycle/create-project.js +5 -5
- package/dist/tools/scene-lifecycle/delete-scene.d.ts +1 -1
- package/dist/tools/scene-lifecycle/delete-scene.d.ts.map +1 -1
- package/dist/tools/scene-lifecycle/delete-scene.js +6 -6
- package/dist/tools/scene-lifecycle/get-project-status.d.ts +1 -1
- package/dist/tools/scene-lifecycle/get-project-status.d.ts.map +1 -1
- package/dist/tools/scene-lifecycle/get-project-status.js +6 -6
- package/dist/tools/scene-lifecycle/index.d.ts +1 -1
- package/dist/tools/scene-lifecycle/index.d.ts.map +1 -1
- package/dist/tools/scene-lifecycle/list-scenes.d.ts +1 -1
- package/dist/tools/scene-lifecycle/list-scenes.d.ts.map +1 -1
- package/dist/tools/scene-lifecycle/list-scenes.js +4 -4
- package/dist/tools/scene-lifecycle/load-scene.d.ts +2 -2
- package/dist/tools/scene-lifecycle/load-scene.d.ts.map +1 -1
- package/dist/tools/scene-lifecycle/load-scene.js +5 -5
- package/dist/tools/scene-lifecycle/metadata.d.ts +1 -1
- package/dist/tools/scene-lifecycle/rename-scene.d.ts +1 -1
- package/dist/tools/scene-lifecycle/rename-scene.d.ts.map +1 -1
- package/dist/tools/scene-lifecycle/rename-scene.js +6 -6
- package/dist/tools/scene-lifecycle/save-scene.d.ts +5 -3
- package/dist/tools/scene-lifecycle/save-scene.d.ts.map +1 -1
- package/dist/tools/scene-lifecycle/save-scene.js +80 -12
- package/dist/tools/scene-lifecycle/test-utils.d.ts +1 -1
- package/dist/tools/scene-lifecycle/test-utils.d.ts.map +1 -1
- package/dist/tools/set-unit-members.d.ts +2 -2
- package/dist/tools/set-unit-members.d.ts.map +1 -1
- package/dist/tools/set-unit-members.js +6 -6
- package/dist/tools/set-zone.d.ts +2 -2
- package/dist/tools/set-zone.d.ts.map +1 -1
- package/dist/tools/set-zone.js +30 -18
- package/dist/tools/shared-tools.d.ts +15 -5
- package/dist/tools/shared-tools.d.ts.map +1 -1
- package/dist/tools/shared-tools.js +242 -29
- package/dist/tools/structure-tools.d.ts +3 -3
- package/dist/tools/templates/create-from-template.d.ts +2 -2
- package/dist/tools/templates/create-from-template.d.ts.map +1 -1
- package/dist/tools/templates/create-from-template.js +6 -6
- package/dist/tools/templates/create-house-from-brief.d.ts +1 -1
- package/dist/tools/templates/create-house-from-brief.d.ts.map +1 -1
- package/dist/tools/templates/create-house-from-brief.js +6 -6
- package/dist/tools/templates/index.d.ts +1 -1
- package/dist/tools/templates/index.d.ts.map +1 -1
- package/dist/tools/templates/list-templates.d.ts +1 -1
- package/dist/tools/templates/list-templates.d.ts.map +1 -1
- package/dist/tools/templates/list-templates.js +2 -2
- package/dist/tools/undo.d.ts +2 -2
- package/dist/tools/undo.d.ts.map +1 -1
- package/dist/tools/undo.js +2 -2
- package/dist/tools/unit-members.d.ts.map +1 -1
- package/dist/tools/unit-members.js +6 -6
- package/dist/tools/variants/generate-variants.d.ts +6 -6
- package/dist/tools/variants/generate-variants.d.ts.map +1 -1
- package/dist/tools/variants/generate-variants.js +6 -6
- package/dist/tools/variants/index.d.ts +1 -1
- package/dist/tools/variants/index.d.ts.map +1 -1
- package/dist/tools/view-scene.d.ts +8 -2
- package/dist/tools/view-scene.d.ts.map +1 -1
- package/dist/tools/view-scene.js +17 -5
- package/dist/tools/vision/analyze-floorplan-image.d.ts +1 -1
- package/dist/tools/vision/analyze-floorplan-image.d.ts.map +1 -1
- package/dist/tools/vision/analyze-floorplan-image.js +7 -7
- package/dist/tools/vision/analyze-room-photo.d.ts +1 -1
- package/dist/tools/vision/analyze-room-photo.d.ts.map +1 -1
- package/dist/tools/vision/analyze-room-photo.js +7 -7
- package/dist/tools/vision/index.d.ts +1 -1
- package/dist/tools/vision/index.d.ts.map +1 -1
- package/dist/transports/http.d.ts +8 -2
- package/dist/transports/http.d.ts.map +1 -1
- package/dist/transports/http.js +9 -3
- package/dist/transports/stdio.d.ts +15 -9
- package/dist/transports/stdio.d.ts.map +1 -1
- package/dist/transports/stdio.js +18 -11
- package/examples/coordinate-conventions-demo.md +12 -13
- package/examples/embed-in-agent.ts +5 -6
- package/examples/generate-apartment.md +4 -4
- package/examples/photo-to-scene.md +2 -3
- package/examples/renovate-from-photos.md +3 -5
- package/package.json +13 -9
- package/dist/tools/describe-node.d.ts +0 -17
- package/dist/tools/describe-node.d.ts.map +0 -1
- package/dist/tools/describe-node.js +0 -99
- package/dist/tools/find-nodes.d.ts +0 -16
- package/dist/tools/find-nodes.d.ts.map +0 -1
- package/dist/tools/find-nodes.js +0 -204
- package/dist/tools/place-design.d.ts +0 -34
- package/dist/tools/place-design.d.ts.map +0 -1
- package/dist/tools/place-design.js +0 -91
- package/dist/tools/validate-design.d.ts +0 -136
- package/dist/tools/validate-design.d.ts.map +0 -1
- package/dist/tools/validate-design.js +0 -28
- package/dist/tools/validate-scene.d.ts +0 -19
- package/dist/tools/validate-scene.d.ts.map +0 -1
- package/dist/tools/validate-scene.js +0 -28
|
@@ -1,21 +1,11 @@
|
|
|
1
1
|
import { createZone, generateId } from '@pascal-app/core';
|
|
2
|
-
import { unknownMaterialPresetRefusal } from '@pascal-app/core/agent-operations';
|
|
3
|
-
import { getActiveRoofHeight, LevelNode, RoofNode, RoofSegmentNode } from '@pascal-app/core/schema';
|
|
2
|
+
import { roofLevelRefusal, unknownMaterialPresetRefusal } from '@pascal-app/core/agent-operations';
|
|
4
3
|
import { z } from 'zod';
|
|
5
4
|
import { ADDITIVE_TOOL_ANNOTATIONS } from './annotations.js';
|
|
5
|
+
import { refusalResult } from './errors.js';
|
|
6
6
|
import { liveSyncOutput, persistencePayload, publishLiveSceneSnapshot } from './live-sync.js';
|
|
7
7
|
import { measurement } from './measurement.js';
|
|
8
|
-
import { NodeIdSchema, Vec2Schema
|
|
9
|
-
const ROOF_TYPES = [
|
|
10
|
-
'hip',
|
|
11
|
-
'gable',
|
|
12
|
-
'shed',
|
|
13
|
-
'gambrel',
|
|
14
|
-
'dutch',
|
|
15
|
-
'mansard',
|
|
16
|
-
'flat',
|
|
17
|
-
'conical',
|
|
18
|
-
];
|
|
8
|
+
import { NodeIdSchema, Vec2Schema } from './schemas.js';
|
|
19
9
|
export const createStoryShellInput = {
|
|
20
10
|
levelId: NodeIdSchema,
|
|
21
11
|
footprint: z.array(Vec2Schema).min(3),
|
|
@@ -59,39 +49,6 @@ export const createStoryShellOutput = {
|
|
|
59
49
|
createdIds: z.array(z.string()),
|
|
60
50
|
...liveSyncOutput,
|
|
61
51
|
};
|
|
62
|
-
export const createRoofInput = {
|
|
63
|
-
levelId: NodeIdSchema,
|
|
64
|
-
roofLevelId: NodeIdSchema.optional(),
|
|
65
|
-
useDedicatedRoofLevel: z.boolean().default(true),
|
|
66
|
-
roofLevelLabel: z.string().default('Roof'),
|
|
67
|
-
// A level ordinal (story index), not a length — kept numeric.
|
|
68
|
-
roofLevelElevation: z.number().optional(),
|
|
69
|
-
roofLevelHeight: measurement('length', 'm', {
|
|
70
|
-
positive: true,
|
|
71
|
-
description: 'Roof level height.',
|
|
72
|
-
}).optional(),
|
|
73
|
-
center: Vec3Schema.optional(),
|
|
74
|
-
width: measurement('length', 'm', { positive: true, description: 'Roof width.' }),
|
|
75
|
-
depth: measurement('length', 'm', { positive: true, description: 'Roof depth.' }),
|
|
76
|
-
roofType: z.enum(ROOF_TYPES).default('hip'),
|
|
77
|
-
pitch: measurement('angle', 'deg', { min: 0, max: 85, description: 'Roof pitch.' }).default(35),
|
|
78
|
-
wallHeight: measurement('length', 'm', { min: 0, description: 'Knee-wall height.' }).default(0.35),
|
|
79
|
-
wallThickness: measurement('length', 'm', {
|
|
80
|
-
positive: true,
|
|
81
|
-
description: 'Wall thickness.',
|
|
82
|
-
}).default(0.16),
|
|
83
|
-
overhang: measurement('length', 'm', { min: 0, description: 'Eave overhang.' }).default(0.45),
|
|
84
|
-
materialPreset: z.string().optional(),
|
|
85
|
-
name: z.string().optional(),
|
|
86
|
-
};
|
|
87
|
-
export const createRoofOutput = {
|
|
88
|
-
referenceLevelId: z.string(),
|
|
89
|
-
roofLevelId: z.string(),
|
|
90
|
-
createdRoofLevelId: z.string().nullable(),
|
|
91
|
-
roofId: z.string(),
|
|
92
|
-
roofSegmentId: z.string(),
|
|
93
|
-
...liveSyncOutput,
|
|
94
|
-
};
|
|
95
52
|
function textResult(payload) {
|
|
96
53
|
return {
|
|
97
54
|
content: [{ type: 'text', text: JSON.stringify(payload) }],
|
|
@@ -106,29 +63,6 @@ function assertNode(bridge, id, type) {
|
|
|
106
63
|
throw new Error(`Node ${id} is a ${node.type}, expected ${type}`);
|
|
107
64
|
return node;
|
|
108
65
|
}
|
|
109
|
-
function getBuildingIdForLevel(bridge, levelId) {
|
|
110
|
-
const building = bridge.getAncestry(levelId).find((node) => node.type === 'building');
|
|
111
|
-
if (!building) {
|
|
112
|
-
throw new Error(`Building ancestor not found for level: ${levelId}`);
|
|
113
|
-
}
|
|
114
|
-
return building.id;
|
|
115
|
-
}
|
|
116
|
-
function isRoofLevel(level) {
|
|
117
|
-
return (level.type === 'level' &&
|
|
118
|
-
typeof level.metadata === 'object' &&
|
|
119
|
-
level.metadata !== null &&
|
|
120
|
-
'role' in level.metadata &&
|
|
121
|
-
level.metadata.role === 'roof');
|
|
122
|
-
}
|
|
123
|
-
function nextLevelIndex(bridge, buildingId, referenceLevel) {
|
|
124
|
-
const existing = bridge
|
|
125
|
-
.getChildren(buildingId)
|
|
126
|
-
.filter((node) => node.type === 'level')
|
|
127
|
-
.map((level) => level.level);
|
|
128
|
-
const referenceIndex = referenceLevel.type === 'level' ? referenceLevel.level : 0;
|
|
129
|
-
const candidate = referenceIndex + 1;
|
|
130
|
-
return existing.includes(candidate) ? Math.max(candidate, ...existing) + 1 : candidate;
|
|
131
|
-
}
|
|
132
66
|
/** Room zones that appeared on the level while this tool call ran. */
|
|
133
67
|
function newRoomZoneIds(bridge, levelId, before) {
|
|
134
68
|
return Object.values(bridge.getNodes())
|
|
@@ -154,8 +88,8 @@ export function registerConstructionTools(server, bridge) {
|
|
|
154
88
|
server.registerTool('create_story_shell', {
|
|
155
89
|
title: 'Create story shell',
|
|
156
90
|
description: 'Create one level-owned building shell from a footprint: the perimeter walls. The floor plate and the ceiling are DERIVED from the rooms the walls enclose — never author a slab or a ceiling here, and never pass boundary/autoFromWalls; createSlab / createCeiling / slabElevation are recorded as room intent instead. Use once per story; do not make first-floor walls span multiple stories.',
|
|
157
|
-
inputSchema: createStoryShellInput,
|
|
158
|
-
outputSchema: createStoryShellOutput,
|
|
91
|
+
inputSchema: z.object(createStoryShellInput),
|
|
92
|
+
outputSchema: z.object(createStoryShellOutput),
|
|
159
93
|
annotations: ADDITIVE_TOOL_ANNOTATIONS,
|
|
160
94
|
}, async ({ levelId, footprint, wallHeight, wallThickness, createSlab, createCeiling, slabElevation, ceilingHeight, namePrefix, wallMaterialPreset, slabMaterialPreset, ceilingMaterialPreset, }) => {
|
|
161
95
|
const preset = unknownMaterialPresetRefusal({
|
|
@@ -165,10 +99,10 @@ export function registerConstructionTools(server, bridge) {
|
|
|
165
99
|
});
|
|
166
100
|
if (preset)
|
|
167
101
|
throw new Error(preset);
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
102
|
+
assertNode(bridge, levelId, 'level');
|
|
103
|
+
const onRoofLevel = roofLevelRefusal(bridge.getNodes(), levelId, 'a story shell');
|
|
104
|
+
if (onRoofLevel)
|
|
105
|
+
return refusalResult(onRoofLevel);
|
|
172
106
|
const points = footprint;
|
|
173
107
|
const before = new Set(Object.keys(bridge.getNodes()));
|
|
174
108
|
const plan = createZone(bridge.getNodes(), {
|
|
@@ -250,87 +184,4 @@ export function registerConstructionTools(server, bridge) {
|
|
|
250
184
|
...persistencePayload(persistence),
|
|
251
185
|
});
|
|
252
186
|
});
|
|
253
|
-
server.registerTool('create_roof', {
|
|
254
|
-
title: 'Create roof',
|
|
255
|
-
description: 'Create a roof container with one roof segment. By default creates a dedicated roof level above the reference level so exploded/solo level views can isolate the roof.',
|
|
256
|
-
inputSchema: createRoofInput,
|
|
257
|
-
outputSchema: createRoofOutput,
|
|
258
|
-
annotations: ADDITIVE_TOOL_ANNOTATIONS,
|
|
259
|
-
}, async ({ levelId, roofLevelId, useDedicatedRoofLevel, roofLevelLabel, roofLevelElevation, roofLevelHeight, center, width, depth, roofType, pitch, wallHeight, wallThickness, overhang, materialPreset, name, }) => {
|
|
260
|
-
const preset = unknownMaterialPresetRefusal({ materialPreset });
|
|
261
|
-
if (preset)
|
|
262
|
-
throw new Error(preset);
|
|
263
|
-
const effectiveWidth = roofType === 'conical' ? Math.max(width, depth) : width;
|
|
264
|
-
const effectiveDepth = roofType === 'conical' ? effectiveWidth : depth;
|
|
265
|
-
// Peak height is derived from pitch + footprint + type; we still
|
|
266
|
-
// need it to size the auto-generated roof level container below.
|
|
267
|
-
const peakHeight = getActiveRoofHeight({
|
|
268
|
-
roofType,
|
|
269
|
-
pitch,
|
|
270
|
-
width: effectiveWidth,
|
|
271
|
-
depth: effectiveDepth,
|
|
272
|
-
});
|
|
273
|
-
const referenceLevel = assertNode(bridge, levelId, 'level');
|
|
274
|
-
const patches = [];
|
|
275
|
-
let targetRoofLevelId = levelId;
|
|
276
|
-
let createdRoofLevelId = null;
|
|
277
|
-
if (roofLevelId !== undefined) {
|
|
278
|
-
const roofLevel = assertNode(bridge, roofLevelId, 'level');
|
|
279
|
-
if (!isRoofLevel(roofLevel)) {
|
|
280
|
-
throw new Error(`roofLevelId ${roofLevelId} must reference a dedicated roof level with metadata.role = "roof"; omit roofLevelId to create one automatically`);
|
|
281
|
-
}
|
|
282
|
-
targetRoofLevelId = roofLevelId;
|
|
283
|
-
}
|
|
284
|
-
else if (useDedicatedRoofLevel && !isRoofLevel(referenceLevel)) {
|
|
285
|
-
const buildingId = getBuildingIdForLevel(bridge, levelId);
|
|
286
|
-
const roofLevel = LevelNode.parse({
|
|
287
|
-
name: roofLevelLabel,
|
|
288
|
-
level: roofLevelElevation ?? nextLevelIndex(bridge, buildingId, referenceLevel),
|
|
289
|
-
height: roofLevelHeight ?? Math.max(wallHeight + peakHeight, 0.2),
|
|
290
|
-
children: [],
|
|
291
|
-
metadata: {
|
|
292
|
-
role: 'roof',
|
|
293
|
-
label: roofLevelLabel,
|
|
294
|
-
referenceLevelId: levelId,
|
|
295
|
-
},
|
|
296
|
-
});
|
|
297
|
-
targetRoofLevelId = roofLevel.id;
|
|
298
|
-
createdRoofLevelId = roofLevel.id;
|
|
299
|
-
patches.push({ op: 'create', node: roofLevel, parentId: buildingId });
|
|
300
|
-
}
|
|
301
|
-
const segment = RoofSegmentNode.parse({
|
|
302
|
-
roofType,
|
|
303
|
-
width: effectiveWidth,
|
|
304
|
-
depth: effectiveDepth,
|
|
305
|
-
wallHeight,
|
|
306
|
-
pitch,
|
|
307
|
-
wallThickness,
|
|
308
|
-
overhang,
|
|
309
|
-
...(materialPreset ? { materialPreset } : {}),
|
|
310
|
-
});
|
|
311
|
-
const roof = RoofNode.parse({
|
|
312
|
-
name: name ?? 'Roof',
|
|
313
|
-
position: center ?? [0, 0, 0],
|
|
314
|
-
children: [segment.id],
|
|
315
|
-
...(materialPreset ? { materialPreset } : {}),
|
|
316
|
-
metadata: {
|
|
317
|
-
referenceLevelId: levelId,
|
|
318
|
-
roofLevelId: targetRoofLevelId,
|
|
319
|
-
},
|
|
320
|
-
});
|
|
321
|
-
bridge.applyPatch([
|
|
322
|
-
...patches,
|
|
323
|
-
{ op: 'create', node: roof, parentId: targetRoofLevelId },
|
|
324
|
-
{ op: 'create', node: segment, parentId: roof.id },
|
|
325
|
-
]);
|
|
326
|
-
const persistence = await publishLiveSceneSnapshot(bridge, 'create_roof');
|
|
327
|
-
return textResult({
|
|
328
|
-
referenceLevelId: levelId,
|
|
329
|
-
roofLevelId: targetRoofLevelId,
|
|
330
|
-
createdRoofLevelId,
|
|
331
|
-
roofId: roof.id,
|
|
332
|
-
roofSegmentId: segment.id,
|
|
333
|
-
...persistencePayload(persistence),
|
|
334
|
-
});
|
|
335
|
-
});
|
|
336
187
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import type { SceneOperations } from '../operations/index.js';
|
|
4
4
|
export declare const createUnitInput: {
|
|
@@ -6,9 +6,9 @@ export declare const createUnitInput: {
|
|
|
6
6
|
name: z.ZodString;
|
|
7
7
|
kind: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
8
8
|
apartment: "apartment";
|
|
9
|
-
"hotel-room": "hotel-room";
|
|
10
9
|
commercial: "commercial";
|
|
11
10
|
common: "common";
|
|
11
|
+
"hotel-room": "hotel-room";
|
|
12
12
|
}>>>;
|
|
13
13
|
color: z.ZodOptional<z.ZodString>;
|
|
14
14
|
memberZoneIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -18,8 +18,8 @@ export declare const createUnitOutput: {
|
|
|
18
18
|
unsaved: z.ZodOptional<z.ZodString>;
|
|
19
19
|
persistence: z.ZodOptional<z.ZodObject<{
|
|
20
20
|
status: z.ZodEnum<{
|
|
21
|
-
unbound: "unbound";
|
|
22
21
|
events_unsupported: "events_unsupported";
|
|
22
|
+
unbound: "unbound";
|
|
23
23
|
}>;
|
|
24
24
|
warning: z.ZodString;
|
|
25
25
|
}, z.core.$strip>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-unit.d.ts","sourceRoot":"","sources":["../../src/tools/create-unit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,
|
|
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"}
|
|
@@ -19,8 +19,8 @@ export function registerCreateUnit(server, bridge) {
|
|
|
19
19
|
server.registerTool('create_unit', {
|
|
20
20
|
title: 'Create unit',
|
|
21
21
|
description: 'Create a named unit in a building, optionally referencing zones across its levels.',
|
|
22
|
-
inputSchema: createUnitInput,
|
|
23
|
-
outputSchema: createUnitOutput,
|
|
22
|
+
inputSchema: z.object(createUnitInput),
|
|
23
|
+
outputSchema: z.object(createUnitOutput),
|
|
24
24
|
annotations: ADDITIVE_TOOL_ANNOTATIONS,
|
|
25
25
|
}, async ({ buildingId, name, kind, color, memberZoneIds }) => {
|
|
26
26
|
const members = validateUnitMembers(bridge, buildingId, memberZoneIds ?? []);
|
package/dist/tools/errors.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ProtocolError, ProtocolErrorCode } from '@modelcontextprotocol/server';
|
|
2
2
|
/**
|
|
3
|
-
* Throw a structured MCP error. The SDK translates `
|
|
3
|
+
* Throw a structured MCP error. The SDK translates `ProtocolError` into a
|
|
4
4
|
* JSON-RPC error response automatically.
|
|
5
5
|
*/
|
|
6
|
-
export declare function throwMcpError(code:
|
|
6
|
+
export declare function throwMcpError(code: ProtocolErrorCode, message: string, data?: unknown): never;
|
|
7
7
|
/**
|
|
8
8
|
* Return a non-throwing tool error payload — used for structured failures that
|
|
9
9
|
* we want the client to see inline in `content` rather than as a protocol
|
|
@@ -22,10 +22,10 @@ export declare function toolError(message: string, data?: Record<string, unknown
|
|
|
22
22
|
*/
|
|
23
23
|
export declare function refusalResult(error: unknown): {
|
|
24
24
|
content: {
|
|
25
|
-
type:
|
|
25
|
+
type: 'text';
|
|
26
26
|
text: string;
|
|
27
27
|
}[];
|
|
28
28
|
isError: true;
|
|
29
29
|
};
|
|
30
|
-
export {
|
|
30
|
+
export { ProtocolError, ProtocolErrorCode };
|
|
31
31
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/tools/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/tools/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAA;AAG/E;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,KAAK,CAE7F;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B;IACD,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACzC,OAAO,EAAE,IAAI,CAAA;CACd,CAUA;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO;aAlBjC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE;aAChC,IAAI;EAoBd;AAED,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,CAAA"}
|
package/dist/tools/errors.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ProtocolError, ProtocolErrorCode } from '@modelcontextprotocol/server';
|
|
2
2
|
import { isAgentRefusal } from '@pascal-app/core/agent-tools';
|
|
3
3
|
/**
|
|
4
|
-
* Throw a structured MCP error. The SDK translates `
|
|
4
|
+
* Throw a structured MCP error. The SDK translates `ProtocolError` into a
|
|
5
5
|
* JSON-RPC error response automatically.
|
|
6
6
|
*/
|
|
7
7
|
export function throwMcpError(code, message, data) {
|
|
8
|
-
throw new
|
|
8
|
+
throw new ProtocolError(code, message, data);
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
11
|
* Return a non-throwing tool error payload — used for structured failures that
|
|
@@ -32,4 +32,4 @@ export function refusalResult(error) {
|
|
|
32
32
|
return toolError(error.message, { code: error.code, ...error.details });
|
|
33
33
|
throw error;
|
|
34
34
|
}
|
|
35
|
-
export {
|
|
35
|
+
export { ProtocolError, ProtocolErrorCode };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import type { SceneOperations } from '../operations/index.js';
|
|
4
4
|
export declare const exportGlbInput: {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export-glb.d.ts","sourceRoot":"","sources":["../../src/tools/export-glb.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"export-glb.d.ts","sourceRoot":"","sources":["../../src/tools/export-glb.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAGpD,eAAO,MAAM,cAAc,IAAK,CAAA;AAEhC,eAAO,MAAM,eAAe;IAC1B,MAAM;IACN,MAAM;CACP,CAAA;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CAuBnF"}
|
package/dist/tools/export-glb.js
CHANGED
|
@@ -9,8 +9,8 @@ export function registerExportGlb(server, _bridge) {
|
|
|
9
9
|
server.registerTool('export_glb', {
|
|
10
10
|
title: 'Export GLB',
|
|
11
11
|
description: 'GLB export is not available in headless mode — it requires the Three.js renderer, which is browser-only. Returns a structured `not_implemented` tool error.',
|
|
12
|
-
inputSchema: exportGlbInput,
|
|
13
|
-
outputSchema: exportGlbOutput,
|
|
12
|
+
inputSchema: z.object(exportGlbInput),
|
|
13
|
+
outputSchema: z.object(exportGlbOutput),
|
|
14
14
|
annotations: READ_ONLY_TOOL_ANNOTATIONS,
|
|
15
15
|
}, async () => {
|
|
16
16
|
const payload = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import type { SceneOperations } from '../operations/index.js';
|
|
4
4
|
export declare const exportJsonInput: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export-json.d.ts","sourceRoot":"","sources":["../../src/tools/export-json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"export-json.d.ts","sourceRoot":"","sources":["../../src/tools/export-json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAGpD,eAAO,MAAM,eAAe;IAC1B,MAAM;CACP,CAAA;AAED,eAAO,MAAM,gBAAgB;IAC3B,IAAI;CACL,CAAA;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAqBnF"}
|
|
@@ -10,8 +10,8 @@ export function registerExportJson(server, bridge) {
|
|
|
10
10
|
server.registerTool('export_json', {
|
|
11
11
|
title: 'Export JSON',
|
|
12
12
|
description: 'Return the scene as a serialized JSON string. Pass `pretty: true` to indent with 2 spaces.',
|
|
13
|
-
inputSchema: exportJsonInput,
|
|
14
|
-
outputSchema: exportJsonOutput,
|
|
13
|
+
inputSchema: z.object(exportJsonInput),
|
|
14
|
+
outputSchema: z.object(exportJsonOutput),
|
|
15
15
|
annotations: READ_ONLY_TOOL_ANNOTATIONS,
|
|
16
16
|
}, async ({ pretty }) => {
|
|
17
17
|
const scene = bridge.exportJSON();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import type { SceneOperations } from '../operations/index.js';
|
|
4
4
|
export declare const getSceneInput: {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-scene.d.ts","sourceRoot":"","sources":["../../src/tools/get-scene.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"get-scene.d.ts","sourceRoot":"","sources":["../../src/tools/get-scene.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAGpD,eAAO,MAAM,aAAa,IAAK,CAAA;AAE/B,eAAO,MAAM,cAAc;IACzB,KAAK;IACL,WAAW;IACX,WAAW;IACX,gBAAgB;CACjB,CAAA;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAyBjF"}
|
package/dist/tools/get-scene.js
CHANGED
|
@@ -11,8 +11,8 @@ export function registerGetScene(server, bridge) {
|
|
|
11
11
|
server.registerTool('get_scene', {
|
|
12
12
|
title: 'Get scene',
|
|
13
13
|
description: 'Returns the full scene graph: flat node dictionary, root node IDs, collections, and explicit installed plugin IDs when present.',
|
|
14
|
-
inputSchema: getSceneInput,
|
|
15
|
-
outputSchema: getSceneOutput,
|
|
14
|
+
inputSchema: z.object(getSceneInput),
|
|
15
|
+
outputSchema: z.object(getSceneOutput),
|
|
16
16
|
annotations: READ_ONLY_TOOL_ANNOTATIONS,
|
|
17
17
|
}, async () => {
|
|
18
18
|
const scene = bridge.exportJSON();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
2
2
|
import { type HostedServiceExecutor } from '@pascal-app/core/agent-operations';
|
|
3
3
|
export declare function registerHostedServiceTools(server: McpServer, execute: HostedServiceExecutor): void;
|
|
4
4
|
//# sourceMappingURL=hosted-services.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hosted-services.d.ts","sourceRoot":"","sources":["../../src/tools/hosted-services.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"hosted-services.d.ts","sourceRoot":"","sources":["../../src/tools/hosted-services.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,mCAAmC,CAAA;AAQ1C,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,qBAAqB,GAC7B,IAAI,CA8CN"}
|
|
@@ -8,10 +8,20 @@ export function registerHostedServiceTools(server, execute) {
|
|
|
8
8
|
description: contract.description,
|
|
9
9
|
inputSchema: z.object(contract.input).strict(),
|
|
10
10
|
annotations: contract.annotations,
|
|
11
|
-
}, async (input,
|
|
11
|
+
}, async (input, ctx) => {
|
|
12
12
|
try {
|
|
13
|
-
const result = await executeHostedServiceTool(contract.name, input, execute,
|
|
14
|
-
|
|
13
|
+
const result = await executeHostedServiceTool(contract.name, input, execute, ctx.mcpReq.signal);
|
|
14
|
+
// A render's preview, inline in the result, is the picture the client shows the model.
|
|
15
|
+
const { preview, ...rest } = (result ?? {});
|
|
16
|
+
const picture = typeof preview === 'string' ? /^data:(image\/[a-z]+);base64,(.+)$/.exec(preview) : null;
|
|
17
|
+
if (!picture)
|
|
18
|
+
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
|
|
19
|
+
return {
|
|
20
|
+
content: [
|
|
21
|
+
{ type: 'text', text: JSON.stringify(rest) },
|
|
22
|
+
{ type: 'image', data: picture[2], mimeType: picture[1] },
|
|
23
|
+
],
|
|
24
|
+
};
|
|
15
25
|
}
|
|
16
26
|
catch (error) {
|
|
17
27
|
const result = isAgentRefusal(error)
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
2
2
|
import type { SceneOperations } from '../operations/index.js';
|
|
3
3
|
import { type GeometryScriptHost } from './add-object.js';
|
|
4
4
|
import type { AssetCatalog } from './asset-catalog.js';
|
|
5
|
+
import { type PlanReadingHosts } from './shared-tools.js';
|
|
5
6
|
import { type SceneViewHost } from './view-scene.js';
|
|
6
7
|
/**
|
|
7
8
|
* Register every non-vision MCP tool against the given server.
|
|
@@ -12,10 +13,10 @@ import { type SceneViewHost } from './view-scene.js';
|
|
|
12
13
|
* when persistence operations are available.
|
|
13
14
|
*/
|
|
14
15
|
/** What the host lends the tools: its item library, script compiles, a view. */
|
|
15
|
-
export type ToolHosts = {
|
|
16
|
+
export type ToolHosts = PlanReadingHosts & {
|
|
16
17
|
catalog?: AssetCatalog;
|
|
17
18
|
geometryScripts?: GeometryScriptHost;
|
|
18
19
|
sceneViews?: SceneViewHost;
|
|
19
20
|
};
|
|
20
|
-
export declare function registerTools(server: McpServer, operations: SceneOperations, { catalog, geometryScripts, sceneViews }?: ToolHosts): void;
|
|
21
|
+
export declare function registerTools(server: McpServer, operations: SceneOperations, { catalog, geometryScripts, sceneViews, assetViews }?: ToolHosts): void;
|
|
21
22
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAEpD,OAAO,EAEL,KAAK,kBAAkB,EAGxB,MAAM,cAAc,CAAA;AAErB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAiBnD,OAAO,EAAE,KAAK,gBAAgB,EAAuB,MAAM,gBAAgB,CAAA;AAI3E,OAAO,EAAqB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAA;AAEpE;;;;;;;GAOG;AACH,gFAAgF;AAChF,MAAM,MAAM,SAAS,GAAG,gBAAgB,GAAG;IACzC,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,eAAe,CAAC,EAAE,kBAAkB,CAAA;IACpC,UAAU,CAAC,EAAE,aAAa,CAAA;CAC3B,CAAA;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,eAAe,EAC3B,EAAE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,GAAE,SAAc,GACnE,IAAI,CA+BN"}
|
package/dist/tools/index.js
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import { registerAddColumn } from './add-column.js';
|
|
2
|
-
import { registerAddObject, registerGetSource } from './add-object.js';
|
|
2
|
+
import { compileObjectOnHost, registerAddObject, registerGetSource, } from './add-object.js';
|
|
3
3
|
import { registerApplyPatch } from './apply-patch.js';
|
|
4
|
+
import { registerAuthorScene } from './author-scene.js';
|
|
4
5
|
import { registerCheckCollisions } from './check-collisions.js';
|
|
5
6
|
import { registerClearScene } from './clear-scene.js';
|
|
6
7
|
import { registerConstructionTools } from './construction-tools.js';
|
|
7
8
|
import { registerCreateUnit } from './create-unit.js';
|
|
8
|
-
import { registerDescribeNode } from './describe-node.js';
|
|
9
9
|
import { registerExportGlb } from './export-glb.js';
|
|
10
10
|
import { registerExportJson } from './export-json.js';
|
|
11
|
-
import { registerFindNodes } from './find-nodes.js';
|
|
12
11
|
import { registerGetScene } from './get-scene.js';
|
|
13
12
|
import { registerListUnits } from './list-units.js';
|
|
14
13
|
import { registerMeasure } from './measure.js';
|
|
15
14
|
import { registerPhotoToSceneTool } from './photo-to-scene/index.js';
|
|
16
|
-
import { registerPlaceDesign } from './place-design.js';
|
|
17
15
|
import { registerRedo } from './redo.js';
|
|
18
16
|
import { registerRoomTools } from './room-tools.js';
|
|
19
17
|
import { registerSceneLifecycleTools } from './scene-lifecycle/index.js';
|
|
@@ -22,17 +20,17 @@ import { registerSetZone } from './set-zone.js';
|
|
|
22
20
|
import { registerSharedTools } from './shared-tools.js';
|
|
23
21
|
import { registerTemplateTools } from './templates/index.js';
|
|
24
22
|
import { registerUndo } from './undo.js';
|
|
25
|
-
import { registerValidateDesign } from './validate-design.js';
|
|
26
|
-
import { registerValidateScene } from './validate-scene.js';
|
|
27
23
|
import { registerVariantTools } from './variants/index.js';
|
|
28
24
|
import { registerViewScene } from './view-scene.js';
|
|
29
|
-
export function registerTools(server, operations, { catalog, geometryScripts, sceneViews } = {}) {
|
|
25
|
+
export function registerTools(server, operations, { catalog, geometryScripts, sceneViews, assetViews } = {}) {
|
|
30
26
|
registerGetScene(server, operations);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
registerSharedTools(server, operations, catalog, {
|
|
28
|
+
assetViews,
|
|
29
|
+
buildObject: (input) => compileObjectOnHost(geometryScripts, operations, input),
|
|
30
|
+
});
|
|
34
31
|
registerAddColumn(server, operations, geometryScripts);
|
|
35
32
|
registerAddObject(server, operations, geometryScripts);
|
|
33
|
+
registerAuthorScene(server, operations, geometryScripts);
|
|
36
34
|
registerGetSource(server, operations, geometryScripts);
|
|
37
35
|
registerMeasure(server, operations);
|
|
38
36
|
registerViewScene(server, operations, sceneViews);
|
|
@@ -43,14 +41,11 @@ export function registerTools(server, operations, { catalog, geometryScripts, sc
|
|
|
43
41
|
registerCreateUnit(server, operations);
|
|
44
42
|
registerSetUnitMembers(server, operations);
|
|
45
43
|
registerListUnits(server, operations);
|
|
46
|
-
registerPlaceDesign(server, operations);
|
|
47
44
|
registerSetZone(server, operations);
|
|
48
45
|
registerUndo(server, operations);
|
|
49
46
|
registerRedo(server, operations);
|
|
50
47
|
registerExportJson(server, operations);
|
|
51
48
|
registerExportGlb(server, operations);
|
|
52
|
-
registerValidateScene(server, operations);
|
|
53
|
-
registerValidateDesign(server, operations);
|
|
54
49
|
registerCheckCollisions(server, operations);
|
|
55
50
|
registerTemplateTools(server, operations);
|
|
56
51
|
if (operations.hasStore) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"level-height-guard.d.ts","sourceRoot":"","sources":["../../src/tools/level-height-guard.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { fillLevelHeights } from '@pascal-app/core/agent-operations';
|
|
2
|
+
import { registerPatchGuard } from './patch-guards.js';
|
|
3
|
+
/**
|
|
4
|
+
* A level is written with a height: a create without one, or an update clearing it, gets the height
|
|
5
|
+
* the editor's load would derive, said in the answer's notes. After the honest-update check, which
|
|
6
|
+
* turns a `null` into a cleared field.
|
|
7
|
+
*/
|
|
8
|
+
function levelHeights(patches, scene) {
|
|
9
|
+
return fillLevelHeights(patches, scene);
|
|
10
|
+
}
|
|
11
|
+
registerPatchGuard({ name: 'level-heights', order: 30, run: levelHeights });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import type { SceneOperations } from '../operations/index.js';
|
|
4
4
|
export declare const listUnitsInput: {
|
|
@@ -10,9 +10,9 @@ export declare const listUnitsOutput: {
|
|
|
10
10
|
name: z.ZodString;
|
|
11
11
|
kind: z.ZodDefault<z.ZodEnum<{
|
|
12
12
|
apartment: "apartment";
|
|
13
|
-
"hotel-room": "hotel-room";
|
|
14
13
|
commercial: "commercial";
|
|
15
14
|
common: "common";
|
|
15
|
+
"hotel-room": "hotel-room";
|
|
16
16
|
}>>;
|
|
17
17
|
color: z.ZodString;
|
|
18
18
|
members: z.ZodArray<z.ZodString>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-units.d.ts","sourceRoot":"","sources":["../../src/tools/list-units.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,
|
|
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
CHANGED
|
@@ -34,8 +34,8 @@ export function registerListUnits(server, bridge) {
|
|
|
34
34
|
server.registerTool('list_units', {
|
|
35
35
|
title: 'List units',
|
|
36
36
|
description: 'List units with their member zones and current area reports, optionally filtered by building.',
|
|
37
|
-
inputSchema: listUnitsInput,
|
|
38
|
-
outputSchema: listUnitsOutput,
|
|
37
|
+
inputSchema: z.object(listUnitsInput),
|
|
38
|
+
outputSchema: z.object(listUnitsOutput),
|
|
39
39
|
annotations: READ_ONLY_TOOL_ANNOTATIONS,
|
|
40
40
|
}, async ({ buildingId }) => {
|
|
41
41
|
if (buildingId !== undefined)
|
|
@@ -18,8 +18,8 @@ export declare const liveSyncOutput: {
|
|
|
18
18
|
unsaved: z.ZodOptional<z.ZodString>;
|
|
19
19
|
persistence: z.ZodOptional<z.ZodObject<{
|
|
20
20
|
status: z.ZodEnum<{
|
|
21
|
-
unbound: "unbound";
|
|
22
21
|
events_unsupported: "events_unsupported";
|
|
22
|
+
unbound: "unbound";
|
|
23
23
|
}>;
|
|
24
24
|
warning: z.ZodString;
|
|
25
25
|
}, z.core.$strip>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live-sync.d.ts","sourceRoot":"","sources":["../../src/tools/live-sync.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAA;AACpE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAIpD,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,SAAS,GAAG,oBAAoB,CAAA;AAE3E,6EAA6E;AAC7E,MAAM,MAAM,QAAQ,GAAG;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAA;AAEzE,KAAK,YAAY,GAAG,OAAO,CAAC,cAAc,EAAE,WAAW,CAAC,CAAA;AAExD;;;;GAIG;AACH,eAAO,MAAM,cAAc
|
|
1
|
+
{"version":3,"file":"live-sync.d.ts","sourceRoot":"","sources":["../../src/tools/live-sync.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAA;AACpE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAIpD,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,SAAS,GAAG,oBAAoB,CAAA;AAE3E,6EAA6E;AAC7E,MAAM,MAAM,QAAQ,GAAG;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAA;AAEzE,KAAK,YAAY,GAAG,OAAO,CAAC,cAAc,EAAE,WAAW,CAAC,CAAA;AAExD;;;;GAIG;AACH,eAAO,MAAM,cAAc;IACzB,OAAO;IACP,OAAO;IACP,WAAW;;;;;;;CAMZ,CAAA;AASD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,QAAQ,GAAG;IACjE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE;QAAE,MAAM,EAAE,YAAY,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;CACxD,CAOA;AAED,uGAAuG;AACvG,wBAAgB,eAAe,CAAC,UAAU,EAAE,eAAe,GAAG,QAAQ,CAGrE;AAID;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEjE;AAED;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,eAAe,EAC3B,IAAI,EAAE,MAAM;AACZ,gFAAgF;AAChF,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAO,GACzC,OAAO,CAAC,QAAQ,CAAC,CAsDnB;AAED,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,IAAI,CAAC,CAGf"}
|
package/dist/tools/live-sync.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { refuse, writeTarget } from '@pascal-app/core/agent-tools';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { SceneVersionConflictError, SceneWipeBlockedError } from '../storage/types.js';
|
|
4
|
-
import {
|
|
4
|
+
import { ProtocolError, ProtocolErrorCode, throwMcpError } from './errors.js';
|
|
5
5
|
/**
|
|
6
6
|
* Output-schema fragment for every tool that mutates the scene. Spread into
|
|
7
7
|
* the tool's `outputSchema` so `persistencePayload` fields survive the SDK's
|
|
@@ -44,7 +44,7 @@ const LIVE_SYNC_VERSION_CONFLICT = 'live_sync_version_conflict';
|
|
|
44
44
|
* loaded it. The store refuses before writing, so nothing from the call persisted.
|
|
45
45
|
*/
|
|
46
46
|
export function isLiveSyncVersionConflict(error) {
|
|
47
|
-
return error instanceof
|
|
47
|
+
return error instanceof ProtocolError && error.message.endsWith(LIVE_SYNC_VERSION_CONFLICT);
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
50
|
* Persist the bridge's current graph to the active scene and append a live
|
|
@@ -98,13 +98,13 @@ options = {}) {
|
|
|
98
98
|
: 'This write would leave the project empty, so it was blocked and not saved. Call load_scene before writing again. To empty the project on purpose, call clear_scene.', { sceneId: active.id, mutationApplied: false, sessionRestored: !!stored });
|
|
99
99
|
}
|
|
100
100
|
if (error instanceof SceneVersionConflictError) {
|
|
101
|
-
throwMcpError(
|
|
101
|
+
throwMcpError(ProtocolErrorCode.InvalidRequest, LIVE_SYNC_VERSION_CONFLICT, {
|
|
102
102
|
sceneId: active.id,
|
|
103
103
|
expectedVersion: active.version,
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
106
|
const message = error instanceof Error ? error.message : String(error);
|
|
107
|
-
throwMcpError(
|
|
107
|
+
throwMcpError(ProtocolErrorCode.InternalError, `live_sync_failed: ${message}`);
|
|
108
108
|
}
|
|
109
109
|
return { status: 'published', project };
|
|
110
110
|
}
|