@pascal-app/mcp 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (305) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/README.md +181 -56
  3. package/dist/bin/pascal-mcp.js +9 -3
  4. package/dist/bridge/agent-session.d.ts +18 -0
  5. package/dist/bridge/agent-session.d.ts.map +1 -0
  6. package/dist/bridge/agent-session.js +15 -0
  7. package/dist/bridge/index.d.ts +1 -1
  8. package/dist/bridge/index.d.ts.map +1 -1
  9. package/dist/bridge/scene-bridge.d.ts +42 -6
  10. package/dist/bridge/scene-bridge.d.ts.map +1 -1
  11. package/dist/bridge/scene-bridge.js +232 -45
  12. package/dist/index.d.ts +3 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -0
  15. package/dist/lib/safe-fetch.d.ts +22 -4
  16. package/dist/lib/safe-fetch.d.ts.map +1 -1
  17. package/dist/lib/safe-fetch.js +233 -134
  18. package/dist/operations/scene-operations.d.ts +41 -3
  19. package/dist/operations/scene-operations.d.ts.map +1 -1
  20. package/dist/operations/scene-operations.js +42 -1
  21. package/dist/prompts/from-brief.d.ts +1 -1
  22. package/dist/prompts/from-brief.d.ts.map +1 -1
  23. package/dist/prompts/from-brief.js +3 -3
  24. package/dist/prompts/index.d.ts +1 -1
  25. package/dist/prompts/index.d.ts.map +1 -1
  26. package/dist/prompts/iterate-on-feedback.d.ts +1 -1
  27. package/dist/prompts/iterate-on-feedback.d.ts.map +1 -1
  28. package/dist/prompts/iterate-on-feedback.js +3 -3
  29. package/dist/prompts/renovation-from-photos.d.ts +1 -1
  30. package/dist/prompts/renovation-from-photos.d.ts.map +1 -1
  31. package/dist/prompts/renovation-from-photos.js +2 -2
  32. package/dist/prompts/scene-guidance.d.ts.map +1 -1
  33. package/dist/prompts/scene-guidance.js +13 -6
  34. package/dist/resources/agent-guide.d.ts +1 -1
  35. package/dist/resources/agent-guide.d.ts.map +1 -1
  36. package/dist/resources/agent-guide.js +62 -33
  37. package/dist/resources/catalog-items.d.ts +5 -6
  38. package/dist/resources/catalog-items.d.ts.map +1 -1
  39. package/dist/resources/catalog-items.js +7 -9
  40. package/dist/resources/constraints.d.ts +1 -1
  41. package/dist/resources/constraints.d.ts.map +1 -1
  42. package/dist/resources/constraints.js +1 -1
  43. package/dist/resources/design-schema.d.ts +9 -0
  44. package/dist/resources/design-schema.d.ts.map +1 -0
  45. package/dist/resources/design-schema.js +21 -0
  46. package/dist/resources/index.d.ts +4 -2
  47. package/dist/resources/index.d.ts.map +1 -1
  48. package/dist/resources/index.js +5 -2
  49. package/dist/resources/scene-current.d.ts +1 -1
  50. package/dist/resources/scene-current.d.ts.map +1 -1
  51. package/dist/resources/scene-summary.d.ts +1 -1
  52. package/dist/resources/scene-summary.d.ts.map +1 -1
  53. package/dist/server.d.ts +25 -1
  54. package/dist/server.d.ts.map +1 -1
  55. package/dist/server.js +71 -25
  56. package/dist/storage/disk-artifact-store.d.ts +9 -0
  57. package/dist/storage/disk-artifact-store.d.ts.map +1 -0
  58. package/dist/storage/disk-artifact-store.js +46 -0
  59. package/dist/storage/index.d.ts +1 -0
  60. package/dist/storage/index.d.ts.map +1 -1
  61. package/dist/storage/index.js +1 -0
  62. package/dist/storage/sqlite-scene-store.d.ts +3 -3
  63. package/dist/storage/sqlite-scene-store.d.ts.map +1 -1
  64. package/dist/storage/sqlite-scene-store.js +4 -3
  65. package/dist/storage/types.d.ts +36 -7
  66. package/dist/storage/types.d.ts.map +1 -1
  67. package/dist/storage/types.js +12 -0
  68. package/dist/templates/empty-studio.d.ts +3 -3
  69. package/dist/templates/empty-studio.d.ts.map +1 -1
  70. package/dist/templates/garden-house.d.ts +3 -3
  71. package/dist/templates/garden-house.d.ts.map +1 -1
  72. package/dist/templates/index.d.ts.map +1 -1
  73. package/dist/templates/two-bedroom.d.ts +3 -3
  74. package/dist/templates/two-bedroom.d.ts.map +1 -1
  75. package/dist/tools/add-column.d.ts +5 -0
  76. package/dist/tools/add-column.d.ts.map +1 -0
  77. package/dist/tools/add-column.js +59 -0
  78. package/dist/tools/add-object.d.ts +76 -0
  79. package/dist/tools/add-object.d.ts.map +1 -0
  80. package/dist/tools/add-object.js +187 -0
  81. package/dist/tools/annotations.d.ts.map +1 -1
  82. package/dist/tools/apply-patch.d.ts +9 -2
  83. package/dist/tools/apply-patch.d.ts.map +1 -1
  84. package/dist/tools/apply-patch.js +36 -5
  85. package/dist/tools/asset-catalog.d.ts +9 -5
  86. package/dist/tools/asset-catalog.d.ts.map +1 -1
  87. package/dist/tools/asset-catalog.js +33 -12
  88. package/dist/tools/author-scene.d.ts +10 -0
  89. package/dist/tools/author-scene.d.ts.map +1 -0
  90. package/dist/tools/author-scene.js +140 -0
  91. package/dist/tools/check-collisions.d.ts +7 -7
  92. package/dist/tools/check-collisions.d.ts.map +1 -1
  93. package/dist/tools/check-collisions.js +7 -8
  94. package/dist/tools/clear-scene.d.ts +9 -0
  95. package/dist/tools/clear-scene.d.ts.map +1 -0
  96. package/dist/tools/clear-scene.js +59 -0
  97. package/dist/tools/collections.d.ts +4 -0
  98. package/dist/tools/collections.d.ts.map +1 -0
  99. package/dist/tools/collections.js +53 -0
  100. package/dist/tools/construction-tools.d.ts +12 -88
  101. package/dist/tools/construction-tools.d.ts.map +1 -1
  102. package/dist/tools/construction-tools.js +122 -381
  103. package/dist/tools/create-unit.d.ts +5 -3
  104. package/dist/tools/create-unit.d.ts.map +1 -1
  105. package/dist/tools/create-unit.js +2 -2
  106. package/dist/tools/errors.d.ts +15 -4
  107. package/dist/tools/errors.d.ts.map +1 -1
  108. package/dist/tools/errors.js +14 -4
  109. package/dist/tools/export-glb.d.ts +1 -1
  110. package/dist/tools/export-glb.d.ts.map +1 -1
  111. package/dist/tools/export-glb.js +2 -2
  112. package/dist/tools/export-json.d.ts +1 -1
  113. package/dist/tools/export-json.d.ts.map +1 -1
  114. package/dist/tools/export-json.js +2 -2
  115. package/dist/tools/geometry-script-worker.d.ts +2 -0
  116. package/dist/tools/geometry-script-worker.d.ts.map +1 -0
  117. package/dist/tools/geometry-script-worker.js +21 -0
  118. package/dist/tools/get-scene.d.ts +2 -1
  119. package/dist/tools/get-scene.d.ts.map +1 -1
  120. package/dist/tools/get-scene.js +5 -3
  121. package/dist/tools/honest-patch-guard.d.ts +2 -0
  122. package/dist/tools/honest-patch-guard.d.ts.map +1 -0
  123. package/dist/tools/honest-patch-guard.js +32 -0
  124. package/dist/tools/hosted-services.d.ts +4 -0
  125. package/dist/tools/hosted-services.d.ts.map +1 -0
  126. package/dist/tools/hosted-services.js +40 -0
  127. package/dist/tools/index.d.ts +12 -2
  128. package/dist/tools/index.d.ts.map +1 -1
  129. package/dist/tools/index.js +18 -32
  130. package/dist/tools/level-height-guard.d.ts +2 -0
  131. package/dist/tools/level-height-guard.d.ts.map +1 -0
  132. package/dist/tools/level-height-guard.js +11 -0
  133. package/dist/tools/list-units.d.ts +2 -2
  134. package/dist/tools/list-units.d.ts.map +1 -1
  135. package/dist/tools/list-units.js +2 -2
  136. package/dist/tools/live-sync.d.ts +25 -6
  137. package/dist/tools/live-sync.d.ts.map +1 -1
  138. package/dist/tools/live-sync.js +48 -27
  139. package/dist/tools/local-geometry-scripts.d.ts +8 -0
  140. package/dist/tools/local-geometry-scripts.d.ts.map +1 -0
  141. package/dist/tools/local-geometry-scripts.js +67 -0
  142. package/dist/tools/measure.d.ts +7 -1
  143. package/dist/tools/measure.d.ts.map +1 -1
  144. package/dist/tools/measure.js +38 -70
  145. package/dist/tools/measurement.d.ts +1 -36
  146. package/dist/tools/measurement.d.ts.map +1 -1
  147. package/dist/tools/measurement.js +2 -94
  148. package/dist/tools/node-world-point.d.ts +37 -0
  149. package/dist/tools/node-world-point.d.ts.map +1 -0
  150. package/dist/tools/node-world-point.js +457 -0
  151. package/dist/tools/normalize-schema-dialect.d.ts +1 -1
  152. package/dist/tools/normalize-schema-dialect.d.ts.map +1 -1
  153. package/dist/tools/normalize-schema-dialect.js +22 -3
  154. package/dist/tools/patch-guards.d.ts +60 -0
  155. package/dist/tools/patch-guards.d.ts.map +1 -0
  156. package/dist/tools/patch-guards.js +256 -0
  157. package/dist/tools/photo-to-scene/index.d.ts +1 -1
  158. package/dist/tools/photo-to-scene/index.d.ts.map +1 -1
  159. package/dist/tools/photo-to-scene/photo-to-scene.d.ts +3 -3
  160. package/dist/tools/photo-to-scene/photo-to-scene.d.ts.map +1 -1
  161. package/dist/tools/photo-to-scene/photo-to-scene.js +10 -9
  162. package/dist/tools/project-files.d.ts +4 -0
  163. package/dist/tools/project-files.d.ts.map +1 -0
  164. package/dist/tools/project-files.js +30 -0
  165. package/dist/tools/redo.d.ts +4 -2
  166. package/dist/tools/redo.d.ts.map +1 -1
  167. package/dist/tools/redo.js +4 -4
  168. package/dist/tools/retired-tools.d.ts +10 -0
  169. package/dist/tools/retired-tools.d.ts.map +1 -0
  170. package/dist/tools/retired-tools.js +22 -0
  171. package/dist/tools/roof-level-guard.d.ts +2 -0
  172. package/dist/tools/roof-level-guard.d.ts.map +1 -0
  173. package/dist/tools/roof-level-guard.js +22 -0
  174. package/dist/tools/room-tools.d.ts +36 -98
  175. package/dist/tools/room-tools.d.ts.map +1 -1
  176. package/dist/tools/room-tools.js +130 -565
  177. package/dist/tools/scene-lifecycle/create-project.d.ts +1 -1
  178. package/dist/tools/scene-lifecycle/create-project.d.ts.map +1 -1
  179. package/dist/tools/scene-lifecycle/create-project.js +31 -6
  180. package/dist/tools/scene-lifecycle/delete-scene.d.ts +3 -1
  181. package/dist/tools/scene-lifecycle/delete-scene.d.ts.map +1 -1
  182. package/dist/tools/scene-lifecycle/delete-scene.js +10 -9
  183. package/dist/tools/scene-lifecycle/get-project-status.d.ts +1 -1
  184. package/dist/tools/scene-lifecycle/get-project-status.d.ts.map +1 -1
  185. package/dist/tools/scene-lifecycle/get-project-status.js +6 -6
  186. package/dist/tools/scene-lifecycle/index.d.ts +1 -1
  187. package/dist/tools/scene-lifecycle/index.d.ts.map +1 -1
  188. package/dist/tools/scene-lifecycle/list-scenes.d.ts +1 -1
  189. package/dist/tools/scene-lifecycle/list-scenes.d.ts.map +1 -1
  190. package/dist/tools/scene-lifecycle/list-scenes.js +4 -4
  191. package/dist/tools/scene-lifecycle/load-scene.d.ts +2 -2
  192. package/dist/tools/scene-lifecycle/load-scene.d.ts.map +1 -1
  193. package/dist/tools/scene-lifecycle/load-scene.js +5 -5
  194. package/dist/tools/scene-lifecycle/metadata.d.ts +1 -1
  195. package/dist/tools/scene-lifecycle/rename-scene.d.ts +1 -1
  196. package/dist/tools/scene-lifecycle/rename-scene.d.ts.map +1 -1
  197. package/dist/tools/scene-lifecycle/rename-scene.js +6 -6
  198. package/dist/tools/scene-lifecycle/save-scene.d.ts +6 -3
  199. package/dist/tools/scene-lifecycle/save-scene.d.ts.map +1 -1
  200. package/dist/tools/scene-lifecycle/save-scene.js +124 -16
  201. package/dist/tools/scene-lifecycle/test-utils.d.ts +3 -3
  202. package/dist/tools/scene-lifecycle/test-utils.d.ts.map +1 -1
  203. package/dist/tools/scene-lifecycle/test-utils.js +2 -1
  204. package/dist/tools/set-unit-members.d.ts +4 -2
  205. package/dist/tools/set-unit-members.d.ts.map +1 -1
  206. package/dist/tools/set-unit-members.js +6 -6
  207. package/dist/tools/set-zone.d.ts +4 -2
  208. package/dist/tools/set-zone.d.ts.map +1 -1
  209. package/dist/tools/set-zone.js +30 -18
  210. package/dist/tools/shared-tools.d.ts +40 -0
  211. package/dist/tools/shared-tools.d.ts.map +1 -0
  212. package/dist/tools/shared-tools.js +574 -0
  213. package/dist/tools/structure-tools.d.ts +57 -0
  214. package/dist/tools/structure-tools.d.ts.map +1 -0
  215. package/dist/tools/structure-tools.js +57 -0
  216. package/dist/tools/templates/create-from-template.d.ts +2 -2
  217. package/dist/tools/templates/create-from-template.d.ts.map +1 -1
  218. package/dist/tools/templates/create-from-template.js +6 -6
  219. package/dist/tools/templates/create-house-from-brief.d.ts +1 -1
  220. package/dist/tools/templates/create-house-from-brief.d.ts.map +1 -1
  221. package/dist/tools/templates/create-house-from-brief.js +6 -6
  222. package/dist/tools/templates/index.d.ts +1 -1
  223. package/dist/tools/templates/index.d.ts.map +1 -1
  224. package/dist/tools/templates/list-templates.d.ts +1 -1
  225. package/dist/tools/templates/list-templates.d.ts.map +1 -1
  226. package/dist/tools/templates/list-templates.js +2 -2
  227. package/dist/tools/undo.d.ts +4 -2
  228. package/dist/tools/undo.d.ts.map +1 -1
  229. package/dist/tools/undo.js +4 -4
  230. package/dist/tools/unit-members.d.ts.map +1 -1
  231. package/dist/tools/unit-members.js +6 -6
  232. package/dist/tools/variants/generate-variants.d.ts +6 -6
  233. package/dist/tools/variants/generate-variants.d.ts.map +1 -1
  234. package/dist/tools/variants/generate-variants.js +6 -6
  235. package/dist/tools/variants/index.d.ts +1 -1
  236. package/dist/tools/variants/index.d.ts.map +1 -1
  237. package/dist/tools/variants/mutations.js +1 -1
  238. package/dist/tools/view-scene.d.ts +44 -0
  239. package/dist/tools/view-scene.d.ts.map +1 -0
  240. package/dist/tools/view-scene.js +75 -0
  241. package/dist/tools/vision/analyze-floorplan-image.d.ts +1 -1
  242. package/dist/tools/vision/analyze-floorplan-image.d.ts.map +1 -1
  243. package/dist/tools/vision/analyze-floorplan-image.js +7 -7
  244. package/dist/tools/vision/analyze-room-photo.d.ts +1 -1
  245. package/dist/tools/vision/analyze-room-photo.d.ts.map +1 -1
  246. package/dist/tools/vision/analyze-room-photo.js +7 -7
  247. package/dist/tools/vision/index.d.ts +1 -1
  248. package/dist/tools/vision/index.d.ts.map +1 -1
  249. package/dist/transports/http.d.ts +8 -2
  250. package/dist/transports/http.d.ts.map +1 -1
  251. package/dist/transports/http.js +9 -3
  252. package/dist/transports/stdio.d.ts +15 -9
  253. package/dist/transports/stdio.d.ts.map +1 -1
  254. package/dist/transports/stdio.js +18 -11
  255. package/dist/version.d.ts +5 -0
  256. package/dist/version.d.ts.map +1 -1
  257. package/dist/version.js +17 -3
  258. package/examples/coordinate-conventions-demo.md +12 -13
  259. package/examples/embed-in-agent.ts +6 -7
  260. package/examples/generate-apartment.md +13 -15
  261. package/examples/photo-to-scene.md +3 -4
  262. package/examples/renovate-from-photos.md +6 -9
  263. package/package.json +19 -9
  264. package/dist/tools/create-level.d.ts +0 -21
  265. package/dist/tools/create-level.d.ts.map +0 -1
  266. package/dist/tools/create-level.js +0 -63
  267. package/dist/tools/create-wall.d.ts +0 -22
  268. package/dist/tools/create-wall.d.ts.map +0 -1
  269. package/dist/tools/create-wall.js +0 -57
  270. package/dist/tools/cut-opening.d.ts +0 -25
  271. package/dist/tools/cut-opening.d.ts.map +0 -1
  272. package/dist/tools/cut-opening.js +0 -61
  273. package/dist/tools/delete-node.d.ts +0 -19
  274. package/dist/tools/delete-node.d.ts.map +0 -1
  275. package/dist/tools/delete-node.js +0 -40
  276. package/dist/tools/describe-node.d.ts +0 -17
  277. package/dist/tools/describe-node.d.ts.map +0 -1
  278. package/dist/tools/describe-node.js +0 -97
  279. package/dist/tools/door-clearance.d.ts +0 -135
  280. package/dist/tools/door-clearance.d.ts.map +0 -1
  281. package/dist/tools/door-clearance.js +0 -334
  282. package/dist/tools/duplicate-level.d.ts +0 -19
  283. package/dist/tools/duplicate-level.d.ts.map +0 -1
  284. package/dist/tools/duplicate-level.js +0 -60
  285. package/dist/tools/find-nodes.d.ts +0 -32
  286. package/dist/tools/find-nodes.d.ts.map +0 -1
  287. package/dist/tools/find-nodes.js +0 -107
  288. package/dist/tools/geometry.d.ts +0 -24
  289. package/dist/tools/geometry.d.ts.map +0 -1
  290. package/dist/tools/geometry.js +0 -94
  291. package/dist/tools/get-node.d.ts +0 -11
  292. package/dist/tools/get-node.d.ts.map +0 -1
  293. package/dist/tools/get-node.js +0 -29
  294. package/dist/tools/layout-clearance.d.ts +0 -105
  295. package/dist/tools/layout-clearance.d.ts.map +0 -1
  296. package/dist/tools/layout-clearance.js +0 -190
  297. package/dist/tools/place-item.d.ts +0 -22
  298. package/dist/tools/place-item.d.ts.map +0 -1
  299. package/dist/tools/place-item.js +0 -89
  300. package/dist/tools/scene-query.d.ts +0 -62
  301. package/dist/tools/scene-query.d.ts.map +0 -1
  302. package/dist/tools/scene-query.js +0 -670
  303. package/dist/tools/validate-scene.d.ts +0 -19
  304. package/dist/tools/validate-scene.d.ts.map +0 -1
  305. package/dist/tools/validate-scene.js +0 -28
package/dist/server.js CHANGED
@@ -1,49 +1,95 @@
1
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
1
+ import { McpServer, ProtocolError, ProtocolErrorCode, } from '@modelcontextprotocol/server';
2
+ import { recordMade, } from '@pascal-app/core/agent-operations';
2
3
  import { createSceneOperations } from './operations/index.js';
3
4
  import { registerPrompts } from './prompts/index.js';
4
5
  import { registerResources } from './resources/index.js';
5
6
  import { registerTools } from './tools/index.js';
7
+ import { cachedCatalog } from './tools/asset-catalog.js';
8
+ import { registerHostedServiceTools } from './tools/hosted-services.js';
6
9
  import { normalizeToolSchemaDialect } from './tools/normalize-schema-dialect.js';
10
+ import { registerProjectFileTools } from './tools/project-files.js';
11
+ import { answerRetiredTools } from './tools/retired-tools.js';
7
12
  import { registerVisionTools } from './tools/vision/index.js';
8
13
  import { version } from './version.js';
9
14
  export function createPascalMcpServer(opts) {
10
- const server = new McpServer({
11
- name: opts.name ?? 'pascal-mcp-server',
12
- version: opts.version ?? version,
15
+ // A client shows these before the agent's first call.
16
+ const server = new McpServer({ name: opts.name ?? 'pascal-mcp-server', version: opts.version ?? version }, {
17
+ instructions: `Pascal builds and edits 3D buildings; the agent guide is the resource pascal://agent-guide.${opts.instructions ? `\n${opts.instructions}` : ''}`,
13
18
  });
14
- if (opts.executeTool)
15
- installToolExecutor(server, opts.executeTool);
19
+ answerInvalidInputWithCode(server);
16
20
  const operations = opts.operations ?? createSceneOperations({ bridge: opts.bridge, store: opts.store });
17
- registerTools(server, operations);
21
+ const executeTool = recordingWhatToolsMake(operations, opts.executeTool);
22
+ if (executeTool)
23
+ installToolExecutor(server, executeTool);
24
+ const catalog = opts.catalog ? cachedCatalog(opts.catalog) : undefined;
25
+ registerTools(server, operations, {
26
+ catalog,
27
+ geometryScripts: opts.geometryScripts,
28
+ sceneViews: opts.sceneViews,
29
+ assetViews: opts.assetViews,
30
+ });
18
31
  registerVisionTools(server, operations);
19
- registerResources(server, operations);
32
+ if (opts.services)
33
+ registerHostedServiceTools(server, opts.services);
34
+ if (opts.files)
35
+ registerProjectFileTools(server, opts.files);
36
+ registerResources(server, operations, catalog);
20
37
  registerPrompts(server, operations);
21
38
  normalizeToolSchemaDialect(server);
39
+ answerRetiredTools(server);
22
40
  return server;
23
41
  }
42
+ /**
43
+ * Arguments a tool's schema rejects come back with the code `invalid_input`, as every other refusal
44
+ * names its code and as the chat answers them: the SDK's own answer is a bare message. The SDK
45
+ * checks the arguments in its server's validateToolInput and turns what it throws into the tool's
46
+ * error text, so a JSON message carries the code; `server-invalid-input.test` fails if an SDK upgrade
47
+ * moves that check.
48
+ */
49
+ function answerInvalidInputWithCode(server) {
50
+ const sdk = server;
51
+ const validate = sdk.validateToolInput.bind(server);
52
+ sdk.validateToolInput = async (tool, args, name) => {
53
+ try {
54
+ return await validate(tool, args, name);
55
+ }
56
+ catch (error) {
57
+ if (!(error instanceof ProtocolError && error.code === ProtocolErrorCode.InvalidParams))
58
+ throw error;
59
+ throw new Error(JSON.stringify({
60
+ error: error.message,
61
+ code: 'invalid_input',
62
+ }));
63
+ }
64
+ };
65
+ }
66
+ /**
67
+ * Inside the host's executor, so that what a call made is in the session by the time the host
68
+ * saves it: every tool that writes, however it writes, leaves what it created with the agent's
69
+ * session, and the first call of any kind begins it.
70
+ */
71
+ function recordingWhatToolsMake(operations, outer) {
72
+ const session = operations.agentSession;
73
+ if (!session)
74
+ return outer;
75
+ const recording = (input) => recordMade({
76
+ getNodes: () => operations.getNodes(),
77
+ readSession: () => session.read(),
78
+ keep: (keep) => session.keep(keep),
79
+ }, input.execute);
80
+ return outer ? (input) => outer({ ...input, execute: () => recording(input) }) : recording;
81
+ }
24
82
  function installToolExecutor(server, executeTool) {
25
83
  const registerTool = server.registerTool.bind(server);
26
- const wrappedRegisterTool = (name, config, callback) => {
27
- const runtimeCallback = callback;
28
- const registration = registerTool(name, config, wrapToolCallback(name, runtimeCallback, executeTool));
29
- return wrapRegisteredTool(registration, name, runtimeCallback, executeTool);
30
- };
31
- server.registerTool = wrappedRegisterTool;
32
- const tool = server.tool.bind(server);
33
- server.tool = ((name, ...args) => {
34
- const callback = args.at(-1);
35
- if (typeof callback !== 'function') {
36
- return Reflect.apply(tool, undefined, [name, ...args]);
37
- }
38
- const runtimeCallback = callback;
39
- args[args.length - 1] = wrapToolCallback(name, runtimeCallback, executeTool);
40
- const registration = Reflect.apply(tool, undefined, [name, ...args]);
41
- return wrapRegisteredTool(registration, name, runtimeCallback, executeTool);
84
+ server.registerTool = ((name, config, callback) => {
85
+ const registration = registerTool(name, config, wrapToolCallback(name, callback, executeTool));
86
+ return wrapRegisteredTool(registration, name, callback, executeTool);
42
87
  });
43
88
  }
44
89
  function wrapToolCallback(name, callback, executeTool) {
45
90
  return (...args) => executeTool({
46
91
  name,
92
+ arguments: args.length > 1 ? args[0] : undefined,
47
93
  signal: toolRequestSignal(args),
48
94
  execute: () => Promise.resolve(Reflect.apply(callback, undefined, args)),
49
95
  });
@@ -69,5 +115,5 @@ function wrapRegisteredTool(registration, initialName, initialCallback, executeT
69
115
  return registration;
70
116
  }
71
117
  function toolRequestSignal(args) {
72
- return args.at(-1).signal;
118
+ return args.at(-1).mcpReq.signal;
73
119
  }
@@ -0,0 +1,9 @@
1
+ /** Immutable artifacts beside the SQLite scene database. */
2
+ export declare class DiskArtifactStore {
3
+ readonly directory: string;
4
+ constructor(projectPath: string);
5
+ private path;
6
+ put(sha256: string, bytes: ArrayBuffer | Uint8Array): Promise<void>;
7
+ read(sha256: string): Promise<Uint8Array | null>;
8
+ }
9
+ //# sourceMappingURL=disk-artifact-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disk-artifact-store.d.ts","sourceRoot":"","sources":["../../src/storage/disk-artifact-store.ts"],"names":[],"mappings":"AAIA,4DAA4D;AAC5D,qBAAa,iBAAiB;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAE1B,YAAY,WAAW,EAAE,MAAM,EAE9B;IAED,OAAO,CAAC,IAAI;IAKN,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBxE;IAEK,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAOrD;CACF"}
@@ -0,0 +1,46 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { link, mkdir, readFile, rm, writeFile } from 'node:fs/promises';
3
+ import { join, resolve } from 'node:path';
4
+ /** Immutable artifacts beside the SQLite scene database. */
5
+ export class DiskArtifactStore {
6
+ directory;
7
+ constructor(projectPath) {
8
+ this.directory = `${resolve(projectPath)}.artifacts`;
9
+ }
10
+ path(sha256) {
11
+ if (!/^[0-9a-f]{64}$/.test(sha256))
12
+ throw new Error('Invalid artifact hash');
13
+ return join(this.directory, sha256);
14
+ }
15
+ async put(sha256, bytes) {
16
+ const path = this.path(sha256);
17
+ const data = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
18
+ if (createHash('sha256').update(data).digest('hex') !== sha256) {
19
+ throw new Error('Artifact hash mismatch');
20
+ }
21
+ await mkdir(this.directory, { recursive: true });
22
+ const temporary = join(this.directory, `.${randomUUID()}`);
23
+ try {
24
+ await writeFile(temporary, data, { flag: 'wx' });
25
+ // A hard link publishes complete bytes atomically without replacing another writer's file.
26
+ await link(temporary, path);
27
+ }
28
+ catch (error) {
29
+ if (error.code !== 'EEXIST')
30
+ throw error;
31
+ }
32
+ finally {
33
+ await rm(temporary, { force: true });
34
+ }
35
+ }
36
+ async read(sha256) {
37
+ try {
38
+ return await readFile(this.path(sha256));
39
+ }
40
+ catch (error) {
41
+ if (error.code === 'ENOENT')
42
+ return null;
43
+ throw error;
44
+ }
45
+ }
46
+ }
@@ -1,4 +1,5 @@
1
1
  import type { SceneStore } from './types.js';
2
+ export * from './disk-artifact-store.js';
2
3
  export * from './slug.js';
3
4
  export * from './sqlite-scene-store.js';
4
5
  export * from './types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEzC,cAAc,QAAQ,CAAA;AACtB,cAAc,sBAAsB,CAAA;AACpC,cAAc,SAAS,CAAA;AAEvB;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAGnF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEzC,cAAc,uBAAuB,CAAA;AACrC,cAAc,QAAQ,CAAA;AACtB,cAAc,sBAAsB,CAAA;AACpC,cAAc,SAAS,CAAA;AAEvB;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAGnF"}
@@ -1,3 +1,4 @@
1
+ export * from './disk-artifact-store.js';
1
2
  export * from './slug.js';
2
3
  export * from './sqlite-scene-store.js';
3
4
  export * from './types.js';
@@ -1,4 +1,4 @@
1
- import { type ProjectCreateOptions, type ProjectStatus, type SceneEvent, type SceneEventAppendOptions, type SceneEventListOptions, type SceneListOptions, type SceneMeta, type SceneMutateOptions, type SceneSaveOptions, type SceneStore, type SceneWithGraph } from './types.js';
1
+ import { type ProjectCreateOptions, type ProjectStatus, type SceneDeleteResult, type SceneEvent, type SceneEventAppendOptions, type SceneEventListOptions, type SceneListOptions, type SceneMeta, type SceneMutateOptions, type SceneSaveOptions, type SceneStore, type SceneWithGraph } from './types.js';
2
2
  export interface SqliteSceneStoreOptions {
3
3
  /** Exact SQLite database file path. If omitted, resolved from env. */
4
4
  databasePath?: string;
@@ -25,7 +25,7 @@ export declare function resolveDefaultDatabasePath(env?: NodeJS.ProcessEnv): str
25
25
  * so a local editor and MCP process can safely share scenes on one machine.
26
26
  */
27
27
  export declare class SqliteSceneStore implements SceneStore {
28
- readonly backend: "sqlite";
28
+ readonly backend: 'sqlite';
29
29
  readonly databasePath: string;
30
30
  private readonly maxSceneBytes;
31
31
  private readonly projectPlaceholders;
@@ -37,7 +37,7 @@ export declare class SqliteSceneStore implements SceneStore {
37
37
  save(opts: SceneSaveOptions): Promise<SceneMeta>;
38
38
  load(id: string): Promise<SceneWithGraph | null>;
39
39
  list(opts?: SceneListOptions): Promise<SceneMeta[]>;
40
- delete(id: string, opts?: SceneMutateOptions): Promise<boolean>;
40
+ delete(id: string, opts?: SceneMutateOptions): Promise<SceneDeleteResult>;
41
41
  rename(id: string, newName: string, opts?: SceneMutateOptions): Promise<SceneMeta>;
42
42
  appendSceneEvent(opts: SceneEventAppendOptions): Promise<SceneEvent>;
43
43
  listSceneEvents(sceneId: string, opts?: SceneEventListOptions): Promise<SceneEvent[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite-scene-store.d.ts","sourceRoot":"","sources":["../../src/storage/sqlite-scene-store.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAE1B,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,KAAK,kBAAkB,EAEvB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EAGf,KAAK,cAAc,EACpB,MAAM,SAAS,CAAA;AAOhB,MAAM,WAAW,uBAAuB;IACtC,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAgDD;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAmBvF;AAkKD;;;;;GAKG;AACH,qBAAa,gBAAiB,YAAW,UAAU;IACjD,QAAQ,CAAC,OAAO,EAAG,QAAQ,CAAS;IAEpC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAE7B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAwC;IAC5E,OAAO,CAAC,EAAE,CAA8B;IACxC,OAAO,CAAC,SAAS,CAAuC;gBAE5C,IAAI,GAAE,uBAA4B;IAMxC,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC;IAuBjE,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAS3D,IAAI,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC;IAyHhD,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAUhD,IAAI,CAAC,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAiCvD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,OAAO,CAAC;IAenE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,SAAS,CAAC;IAsCtF,gBAAgB,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC,UAAU,CAAC;IA6BpE,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAmB/F,KAAK,IAAI,IAAI;YAMC,QAAQ;IAiBtB,OAAO,CAAC,OAAO;YAgDD,oBAAoB;IAiBlC,OAAO,CAAC,MAAM;IAad,OAAO,CAAC,gBAAgB;CAOzB"}
1
+ {"version":3,"file":"sqlite-scene-store.d.ts","sourceRoot":"","sources":["../../src/storage/sqlite-scene-store.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAE1B,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,KAAK,kBAAkB,EAEvB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EAGf,KAAK,cAAc,EACpB,MAAM,SAAS,CAAA;AAOhB,MAAM,WAAW,uBAAuB;IACtC,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAgDD;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAmBvF;AAkKD;;;;;GAKG;AACH,qBAAa,gBAAiB,YAAW,UAAU;IACjD,QAAQ,CAAC,OAAO,EAAG,QAAQ,CAAS;IAEpC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAE7B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAwC;IAC5E,OAAO,CAAC,EAAE,CAA8B;IACxC,OAAO,CAAC,SAAS,CAAuC;IAExD,YAAY,IAAI,GAAE,uBAA4B,EAM7C;IAEK,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC,CAqBtE;IAEK,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAOhE;IAEK,IAAI,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC,CAuHrD;IAEK,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAQrD;IAEK,IAAI,CAAC,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CA+B5D;IAEK,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAalF;IAEK,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,SAAS,CAAC,CAoC3F;IAEK,gBAAgB,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC,UAAU,CAAC,CA2BzE;IAEK,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAiB9F;IAED,KAAK,IAAI,IAAI,CAIZ;YAEa,QAAQ;IAiBtB,OAAO,CAAC,OAAO;YAgDD,oBAAoB;IAiBlC,OAAO,CAAC,MAAM;IAad,OAAO,CAAC,gBAAgB;CAOzB"}
@@ -207,7 +207,8 @@ export class SqliteSceneStore {
207
207
  dbPromise = null;
208
208
  constructor(opts = {}) {
209
209
  const env = opts.env ?? process.env;
210
- this.databasePath = path.resolve(opts.databasePath ?? resolveDefaultDatabasePath(env));
210
+ this.databasePath = path.resolve(
211
+ /* turbopackIgnore: true */ opts.databasePath ?? resolveDefaultDatabasePath(env));
211
212
  this.maxSceneBytes = resolveMaxSceneBytes(env, opts.maxSceneBytes);
212
213
  }
213
214
  async createProject(opts) {
@@ -357,12 +358,12 @@ export class SqliteSceneStore {
357
358
  const safeId = sanitizeSlug(id);
358
359
  const existing = this.getRow(db, safeId);
359
360
  if (!existing)
360
- return false;
361
+ return { deleted: false, hidden: false };
361
362
  if (opts.expectedVersion !== undefined && existing.version !== opts.expectedVersion) {
362
363
  throw new SceneVersionConflictError(`Scene "${safeId}" version mismatch: expected ${opts.expectedVersion}, got ${existing.version}`);
363
364
  }
364
365
  db.query('DELETE FROM scenes WHERE id = ?').run(safeId);
365
- return true;
366
+ return { deleted: true, hidden: false };
366
367
  });
367
368
  }
368
369
  async rename(id, newName, opts = {}) {
@@ -21,7 +21,7 @@ export interface SceneMeta {
21
21
  editorUrl?: string;
22
22
  /** Backward-compatible alias for clients that still read url. */
23
23
  url?: string;
24
- /** True when this save is browser-visible without a separate publish call. */
24
+ /** True when this version is the published one (hosted: what the project's viewers see). */
25
25
  published?: boolean;
26
26
  /** True when the saved graph is still the mutable browser-visible draft. */
27
27
  isDraft?: boolean;
@@ -50,14 +50,25 @@ export interface SceneSaveOptions {
50
50
  thumbnailUrl?: string | null;
51
51
  /** When set, save fails with `SceneVersionConflictError` on mismatch. */
52
52
  expectedVersion?: number;
53
+ /**
54
+ * When set, save fails with `SceneVersionConflictError` unless the stored graph still hashes to
55
+ * this. A draft saved in place keeps its version number, so only the content tells that an
56
+ * open editor wrote in between.
57
+ */
58
+ expectedGraphHash?: string | null;
53
59
  /** `draft` updates the browser-visible working model; `checkpoint` records version history. */
54
60
  saveMode?: SceneSaveMode;
55
- /** Whether a checkpoint should become the published/browser-visible head. */
61
+ /** Publish this checkpoint. Only an explicit `true` publishes; a checkpoint alone never does. */
56
62
  publish?: boolean;
57
63
  /** Optional hosted MCP session id for project presence/debug metadata. */
58
64
  agentSessionId?: string;
59
65
  /** Optional high-level operation name for presence/debug metadata. */
60
66
  operation?: string;
67
+ /**
68
+ * The write empties a populated project on purpose (clear_scene). A store may refuse a write that
69
+ * empties the project unless this is set, with `SceneWipeBlockedError`.
70
+ */
71
+ allowSceneWipe?: boolean;
61
72
  }
62
73
  export type SceneSaveMode = 'draft' | 'checkpoint';
63
74
  export interface SceneListOptions {
@@ -68,6 +79,15 @@ export interface SceneListOptions {
68
79
  export interface SceneMutateOptions {
69
80
  expectedVersion?: number;
70
81
  }
82
+ /**
83
+ * What `delete` did. A local store removes the scene; hosted Pascal never deletes a project this
84
+ * way and only hides it, with a `message` saying so.
85
+ */
86
+ export type SceneDeleteResult = {
87
+ deleted: boolean;
88
+ hidden: boolean;
89
+ message?: string;
90
+ };
71
91
  export interface SceneEventAppendOptions {
72
92
  sceneId: SceneId;
73
93
  version: number;
@@ -112,25 +132,34 @@ export interface SceneStore {
112
132
  save(opts: SceneSaveOptions): Promise<SceneMeta>;
113
133
  load(id: SceneId): Promise<SceneWithGraph | null>;
114
134
  list(opts?: SceneListOptions): Promise<SceneMeta[]>;
115
- delete(id: SceneId, opts?: SceneMutateOptions): Promise<boolean>;
135
+ delete(id: SceneId, opts?: SceneMutateOptions): Promise<SceneDeleteResult>;
116
136
  rename(id: SceneId, newName: string, opts?: SceneMutateOptions): Promise<SceneMeta>;
117
137
  appendSceneEvent?(opts: SceneEventAppendOptions): Promise<SceneEvent>;
118
138
  listSceneEvents?(sceneId: SceneId, opts?: SceneEventListOptions): Promise<SceneEvent[]>;
119
139
  }
120
140
  export declare class SceneNotFoundError extends Error {
121
- readonly code: "not_found";
141
+ readonly code: 'not_found';
122
142
  constructor(message?: string);
123
143
  }
124
144
  export declare class SceneVersionConflictError extends Error {
125
- readonly code: "version_conflict";
145
+ readonly code: 'version_conflict';
126
146
  constructor(message?: string);
127
147
  }
128
148
  export declare class SceneInvalidError extends Error {
129
- readonly code: "invalid";
149
+ readonly code: 'invalid';
150
+ constructor(message?: string);
151
+ }
152
+ /**
153
+ * A store refused a write that would empty a populated project without `allowSceneWipe`: far more
154
+ * often an accident (a client that never finished loading, a deletion of everything) than an intent.
155
+ * Still an invalid write to a caller that only knows `SceneInvalidError`; the MCP answers it
156
+ * `scene_wipe_blocked`, naming clear_scene.
157
+ */
158
+ export declare class SceneWipeBlockedError extends SceneInvalidError {
130
159
  constructor(message?: string);
131
160
  }
132
161
  export declare class SceneTooLargeError extends Error {
133
- readonly code: "too_large";
162
+ readonly code: 'too_large';
134
163
  constructor(message?: string);
135
164
  }
136
165
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/storage/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/storage/types.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,18 @@ export class SceneInvalidError extends Error {
19
19
  this.name = 'SceneInvalidError';
20
20
  }
21
21
  }
22
+ /**
23
+ * A store refused a write that would empty a populated project without `allowSceneWipe`: far more
24
+ * often an accident (a client that never finished loading, a deletion of everything) than an intent.
25
+ * Still an invalid write to a caller that only knows `SceneInvalidError`; the MCP answers it
26
+ * `scene_wipe_blocked`, naming clear_scene.
27
+ */
28
+ export class SceneWipeBlockedError extends SceneInvalidError {
29
+ constructor(message = 'Scene wipe blocked') {
30
+ super(message);
31
+ this.name = 'SceneWipeBlockedError';
32
+ }
33
+ }
22
34
  export class SceneTooLargeError extends Error {
23
35
  code = 'too_large';
24
36
  constructor(message = 'Scene too large') {
@@ -1,8 +1,8 @@
1
1
  import type { SceneGraph } from '@pascal-app/core/clone-scene-graph';
2
2
  export declare const template: SceneGraph;
3
3
  export declare const metadata: {
4
- readonly id: "empty-studio";
5
- readonly name: "Empty studio";
6
- readonly description: "40 m² single-room studio apartment: 4 walls, 1 living/kitchen zone, 1 window, 1 front door.";
4
+ readonly id: 'empty-studio';
5
+ readonly name: 'Empty studio';
6
+ readonly description: '40 m² single-room studio apartment: 4 walls, 1 living/kitchen zone, 1 window, 1 front door.';
7
7
  };
8
8
  //# sourceMappingURL=empty-studio.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"empty-studio.d.ts","sourceRoot":"","sources":["../../src/templates/empty-studio.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAA;AAmPpE,eAAO,MAAM,QAAQ,EAAE,UAA4B,CAAA;AAEnD,eAAO,MAAM,QAAQ;;;;CAKX,CAAA"}
1
+ {"version":3,"file":"empty-studio.d.ts","sourceRoot":"","sources":["../../src/templates/empty-studio.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAA;AAmPpE,eAAO,MAAM,QAAQ,EAAE,UAA4B,CAAA;AAEnD,eAAO,MAAM,QAAQ;aACnB,EAAE,EAAE,cAAc;aAClB,IAAI,EAAE,cAAc;aACpB,WAAW,EACT,6FAA6F;CACvF,CAAA"}
@@ -1,8 +1,8 @@
1
1
  import type { SceneGraph } from '@pascal-app/core/clone-scene-graph';
2
2
  export declare const template: SceneGraph;
3
3
  export declare const metadata: {
4
- readonly id: "garden-house";
5
- readonly name: "Garden house";
6
- readonly description: "12 × 8 m single-level house with a fenced back-garden zone; 4 walls, 2 doors, 4 windows, 3 privacy fences.";
4
+ readonly id: 'garden-house';
5
+ readonly name: 'Garden house';
6
+ readonly description: '12 × 8 m single-level house with a fenced back-garden zone; 4 walls, 2 doors, 4 windows, 3 privacy fences.';
7
7
  };
8
8
  //# sourceMappingURL=garden-house.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"garden-house.d.ts","sourceRoot":"","sources":["../../src/templates/garden-house.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAA;AAkRpE,eAAO,MAAM,QAAQ,EAAE,UAA4B,CAAA;AAEnD,eAAO,MAAM,QAAQ;;;;CAKX,CAAA"}
1
+ {"version":3,"file":"garden-house.d.ts","sourceRoot":"","sources":["../../src/templates/garden-house.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAA;AAkRpE,eAAO,MAAM,QAAQ,EAAE,UAA4B,CAAA;AAEnD,eAAO,MAAM,QAAQ;aACnB,EAAE,EAAE,cAAc;aAClB,IAAI,EAAE,cAAc;aACpB,WAAW,EACT,4GAA4G;CACtG,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAA;AAKpE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,yDAAyD;IACzD,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,kFAAkF;IAClF,QAAQ,EAAE,UAAU,CAAA;CACrB,CAAA;AAWD,eAAO,MAAM,SAAS;;;;CAIZ,CAAA;AAEV,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,SAAS,CAAA;AAE/C,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,UAAU,CAEzD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAA;AAKpE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,yDAAyD;IACzD,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,kFAAkF;IAClF,QAAQ,EAAE,UAAU,CAAA;CACrB,CAAA;AAWD,eAAO,MAAM,SAAS;aACpB,cAAc;aACd,aAAa;aACb,cAAc;CACN,CAAA;AAEV,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,SAAS,CAAA;AAE/C,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,UAAU,CAEzD"}
@@ -1,8 +1,8 @@
1
1
  import type { SceneGraph } from '@pascal-app/core/clone-scene-graph';
2
2
  export declare const template: SceneGraph;
3
3
  export declare const metadata: {
4
- readonly id: "two-bedroom";
5
- readonly name: "Two-bedroom apartment";
6
- readonly description: "80 m² two-bedroom flat: 9 walls, 4 zones (living/kitchen, 2 bedrooms, bath), 4 doors and 5 windows.";
4
+ readonly id: 'two-bedroom';
5
+ readonly name: 'Two-bedroom apartment';
6
+ readonly description: '80 m² two-bedroom flat: 9 walls, 4 zones (living/kitchen, 2 bedrooms, bath), 4 doors and 5 windows.';
7
7
  };
8
8
  //# sourceMappingURL=two-bedroom.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"two-bedroom.d.ts","sourceRoot":"","sources":["../../src/templates/two-bedroom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAA;AA2SpE,eAAO,MAAM,QAAQ,EAAE,UAA4B,CAAA;AAEnD,eAAO,MAAM,QAAQ;;;;CAKX,CAAA"}
1
+ {"version":3,"file":"two-bedroom.d.ts","sourceRoot":"","sources":["../../src/templates/two-bedroom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAA;AA2SpE,eAAO,MAAM,QAAQ,EAAE,UAA4B,CAAA;AAEnD,eAAO,MAAM,QAAQ;aACnB,EAAE,EAAE,aAAa;aACjB,IAAI,EAAE,uBAAuB;aAC7B,WAAW,EACT,qGAAqG;CAC/F,CAAA"}
@@ -0,0 +1,5 @@
1
+ import type { McpServer } from '@modelcontextprotocol/server';
2
+ import type { SceneOperations } from '../operations/index.js';
3
+ import { type GeometryScriptHost } from './add-object.js';
4
+ export declare function registerAddColumn(server: McpServer, bridge: SceneOperations, host?: GeometryScriptHost): void;
5
+ //# sourceMappingURL=add-column.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-column.d.ts","sourceRoot":"","sources":["../../src/tools/add-column.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAW7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,EAAmB,KAAK,kBAAkB,EAAc,MAAM,cAAc,CAAA;AAMnF,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,eAAe,EACvB,IAAI,CAAC,EAAE,kBAAkB,QAqD1B"}
@@ -0,0 +1,59 @@
1
+ import { isScriptedNode, scriptedObjectMeta } from '@pascal-app/core';
2
+ import { addColumn, columnScriptParams, editedScriptLanguage, } from '@pascal-app/core/agent-operations';
3
+ import { addColumnTool, isAgentRefusal, refuse } from '@pascal-app/core/agent-tools';
4
+ import { GeometryReuseFields } from '@pascal-app/core/schema';
5
+ import { z } from 'zod';
6
+ import { compileAndStore, readScript } from './add-object.js';
7
+ import { DESTRUCTIVE_TOOL_ANNOTATIONS } from './annotations.js';
8
+ import { refusalResult, toolError } from './errors.js';
9
+ import { persistencePayload, publishLiveSceneSnapshot } from './live-sync.js';
10
+ import { toPatches } from './shared-tools.js';
11
+ export function registerAddColumn(server, bridge, host) {
12
+ server.registerTool(addColumnTool.name, {
13
+ title: addColumnTool.title,
14
+ description: addColumnTool.description,
15
+ inputSchema: z.object(addColumnTool.input),
16
+ annotations: DESTRUCTIVE_TOOL_ANNOTATIONS,
17
+ }, async (input) => {
18
+ try {
19
+ const nodes = bridge.getNodes();
20
+ const previous = input.nodeId ? nodes[input.nodeId] : undefined;
21
+ const params = columnScriptParams(previous?.type === 'column' ? previous : undefined, input);
22
+ let compiled;
23
+ if (params) {
24
+ if (!host)
25
+ refuse('scripts_unavailable', 'This Pascal server cannot run geometry scripts.');
26
+ const scene = bridge.getActiveScene();
27
+ if (!scene)
28
+ refuse('no_active_scene', 'Open or save a scene first.');
29
+ const code = input.code ?? (await readScript(host, scene.id, bridge, input.nodeId));
30
+ const language = editedScriptLanguage(previous, input);
31
+ compiled = await compileAndStore(host, scene.id, { code, language, params }, 'column', {
32
+ nodeId: input.nodeId,
33
+ metadata: {
34
+ ...(isScriptedNode(previous) ? scriptedObjectMeta(previous) : {}),
35
+ ...GeometryReuseFields.parse(input),
36
+ },
37
+ });
38
+ }
39
+ const outcome = addColumn(nodes, { ...input, compiled }, { activeLevelId: bridge.activeLevelId?.() ?? null });
40
+ if (outcome.changes)
41
+ bridge.applyPatch(toPatches(outcome.changes));
42
+ const payload = {
43
+ ...outcome.result,
44
+ ...persistencePayload(await publishLiveSceneSnapshot(bridge, addColumnTool.name)),
45
+ };
46
+ return {
47
+ content: [{ type: 'text', text: JSON.stringify(payload) }],
48
+ structuredContent: payload,
49
+ };
50
+ }
51
+ catch (error) {
52
+ if (isAgentRefusal(error))
53
+ return refusalResult(error);
54
+ return toolError(error instanceof Error ? error.message : String(error), {
55
+ code: 'script_failed',
56
+ });
57
+ }
58
+ });
59
+ }
@@ -0,0 +1,76 @@
1
+ import type { McpServer } from '@modelcontextprotocol/server';
2
+ import { type AddObjectInput } from '@pascal-app/core/agent-operations';
3
+ import { type CompiledGeometryScript, GeometryArtifactMetadata, type GeometryScriptLanguage, type GeometryScriptParamValue } from '@pascal-app/core/schema';
4
+ import type { SceneOperations } from '../operations/index.js';
5
+ /**
6
+ * How a host runs `add_object`'s module and keeps the result. Running
7
+ * model-written code is the host's call: it decides the isolation, and where
8
+ * artifacts live for the active scene.
9
+ */
10
+ export type GeometryScriptHost = {
11
+ readonly signal?: AbortSignal;
12
+ /** Recheck the host's active authorization after a long compile and before scene mutation. */
13
+ assertActive?(): Promise<void>;
14
+ compile(input: {
15
+ code: string;
16
+ language: GeometryScriptLanguage;
17
+ params?: Record<string, GeometryScriptParamValue>;
18
+ /** What the host builds it for (a room's floor, a wall's face: `floorScriptInputs`, `wallFaceScriptInputs`), kept in the host's frame. */
19
+ inputs?: Record<string, unknown>;
20
+ }): Promise<CompiledGeometryScript & {
21
+ glb: Uint8Array;
22
+ }>;
23
+ storeArtifact(input: {
24
+ sceneId: string;
25
+ sha256: string;
26
+ bytes: Uint8Array;
27
+ mimeType: string;
28
+ nodeId?: string;
29
+ metadata?: GeometryArtifactMetadata;
30
+ }): Promise<string>;
31
+ /** A stored artifact's bytes (an object's script), or null when missing; only for principals who may edit the scene. */
32
+ readArtifact(input: {
33
+ sceneId: string;
34
+ sha256: string;
35
+ }): Promise<Uint8Array | null>;
36
+ /**
37
+ * Compiles and stores in one step, for a host whose compiler keeps the artifacts itself (the
38
+ * hosted MCP's user editor tab); preferred over `compile` + `storeArtifact` when present.
39
+ */
40
+ build?(input: {
41
+ sceneId: string;
42
+ code: string;
43
+ language: GeometryScriptLanguage;
44
+ params?: Record<string, GeometryScriptParamValue>;
45
+ inputs?: Record<string, unknown>;
46
+ /** What the script builds, for the host to name it to the user. */
47
+ kind: ScriptedKind;
48
+ nodeId: string;
49
+ metadata?: GeometryArtifactMetadata;
50
+ }): Promise<CompiledGeometryScript>;
51
+ };
52
+ export type ScriptedKind = 'object' | 'window' | 'door' | 'column' | 'floor' | 'wall-face';
53
+ /** Compiles a module on the host and stores its GLB and text for the scene: the step every scripted tool shares. */
54
+ export declare function compileAndStore(host: GeometryScriptHost, sceneId: string, { code, language, params, inputs, }: {
55
+ code: string;
56
+ language: GeometryScriptLanguage;
57
+ params: Record<string, GeometryScriptParamValue> | undefined;
58
+ inputs?: Record<string, unknown>;
59
+ }, kind: ScriptedKind, context?: {
60
+ nodeId?: string;
61
+ metadata?: GeometryArtifactMetadata;
62
+ }): Promise<CompiledGeometryScript>;
63
+ export declare function readScript(host: GeometryScriptHost, sceneId: string, bridge: SceneOperations, nodeId: string): Promise<string>;
64
+ /**
65
+ * One object's module compiled and stored by the host: a new one from its code, an edit from its
66
+ * code or its stored script, with the params it keeps. The step a lone add_object and each
67
+ * add_object of a run_batch share.
68
+ */
69
+ export declare function compileObject(host: GeometryScriptHost, sceneId: string, bridge: SceneOperations, args: Omit<AddObjectInput, 'compiled'>): Promise<CompiledGeometryScript>;
70
+ /** What a batch's add_object builds with: the host's compile, on the scene open now. */
71
+ export declare function compileObjectOnHost(host: GeometryScriptHost | undefined, bridge: SceneOperations, args: Omit<AddObjectInput, 'compiled'>): Promise<CompiledGeometryScript>;
72
+ /** `add_object` on the MCP: the shared contract and operation, with the host's compile in front. */
73
+ export declare function registerAddObject(server: McpServer, bridge: SceneOperations, host: GeometryScriptHost | undefined): void;
74
+ /** `get_source` on the MCP: the object's module text, read back through the host's store. */
75
+ export declare function registerGetSource(server: McpServer, bridge: SceneOperations, host: GeometryScriptHost | undefined): void;
76
+ //# sourceMappingURL=add-object.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-object.d.ts","sourceRoot":"","sources":["../../src/tools/add-object.ts"],"names":[],"mappings":"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"}