@mulmoclaude/shapescript-plugin 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +19 -0
  2. package/dist/core/dispatch.d.ts +8 -3
  3. package/dist/core/dispatch.d.ts.map +1 -1
  4. package/dist/core/index.d.ts +5 -2
  5. package/dist/core/index.d.ts.map +1 -1
  6. package/dist/core/paths.d.ts +5 -0
  7. package/dist/core/paths.d.ts.map +1 -1
  8. package/dist/core-CpVzK-0i.js +53 -0
  9. package/dist/core-bcFgqR_m.cjs +1 -0
  10. package/dist/core.cjs +1 -1
  11. package/dist/core.js +4 -3
  12. package/dist/export/tool.d.ts +45 -0
  13. package/dist/export/tool.d.ts.map +1 -0
  14. package/dist/export/usdz.d.ts +17 -0
  15. package/dist/export/usdz.d.ts.map +1 -0
  16. package/dist/index.cjs +1 -1
  17. package/dist/index.js +4 -4
  18. package/dist/lang/de.d.ts.map +1 -1
  19. package/dist/lang/en.d.ts.map +1 -1
  20. package/dist/lang/es.d.ts.map +1 -1
  21. package/dist/lang/fr.d.ts.map +1 -1
  22. package/dist/lang/ja.d.ts.map +1 -1
  23. package/dist/lang/ko.d.ts.map +1 -1
  24. package/dist/lang/messages.d.ts +2 -0
  25. package/dist/lang/messages.d.ts.map +1 -1
  26. package/dist/lang/ptBR.d.ts.map +1 -1
  27. package/dist/lang/zh.d.ts.map +1 -1
  28. package/dist/render/index.d.ts +2 -0
  29. package/dist/render/index.d.ts.map +1 -1
  30. package/dist/render/renderer.d.ts +11 -0
  31. package/dist/render/renderer.d.ts.map +1 -1
  32. package/dist/render/tool.d.ts +118 -0
  33. package/dist/render/tool.d.ts.map +1 -0
  34. package/dist/render.cjs +2 -2
  35. package/dist/render.js +115 -11
  36. package/dist/samples-DPOGWslc.js +1038 -0
  37. package/dist/samples-DZNAeuSZ.cjs +210 -0
  38. package/dist/style.css +1 -1
  39. package/dist/{toThreeJS-B5LiF110.js → toThreeJS-BX_aeGdA.js} +18 -18
  40. package/dist/{toThreeJS-BOBpx5Dc.cjs → toThreeJS-XGDoVISb.cjs} +1 -1
  41. package/dist/vue/View.vue.d.ts.map +1 -1
  42. package/dist/vue.cjs +16 -16
  43. package/dist/vue.js +1760 -1716
  44. package/package.json +1 -1
  45. package/dist/samples-DHEKUNs5.cjs +0 -186
  46. package/dist/samples-SaXsqbHJ.js +0 -180
package/dist/render.js CHANGED
@@ -1,4 +1,4 @@
1
- import { In as e, Pn as t, n } from "./toThreeJS-B5LiF110.js";
1
+ import { In as e, Rn as t, r as n } from "./toThreeJS-BX_aeGdA.js";
2
2
  import { readFile as r } from "node:fs/promises";
3
3
  import { createRequire as i } from "node:module";
4
4
  import { pathToFileURL as a } from "node:url";
@@ -81,7 +81,7 @@ function f(e) {
81
81
  var p = 60 * d, m = 30 * d, h = 9e4, g = "renderShapeScript needs Puppeteer's headless Chromium, which this host does not have. Run `npx puppeteer browsers install chrome`, then retry. Everything else, including presentShapeScript, works without it.", _ = class extends Error {};
82
82
  function v(e, t) {
83
83
  try {
84
- e.onWarning?.(t);
84
+ e?.(t);
85
85
  } catch {}
86
86
  }
87
87
  function y() {
@@ -91,13 +91,13 @@ function y() {
91
91
  throw Error("shapescript render: cannot locate this module to resolve three from");
92
92
  }
93
93
  var b = i(y());
94
- function x(t) {
95
- return e(t) && typeof t.launch == "function";
94
+ function x(e) {
95
+ return t(e) && typeof e.launch == "function";
96
96
  }
97
97
  async function S() {
98
98
  try {
99
- let t = await import("puppeteer");
100
- return x(t) ? t : e(t) && x(t.default) ? t.default : null;
99
+ let e = await import("puppeteer");
100
+ return x(e) ? e : t(e) && x(e.default) ? e.default : null;
101
101
  } catch {
102
102
  return null;
103
103
  }
@@ -145,11 +145,11 @@ async function k(e, t) {
145
145
  })();
146
146
  });
147
147
  }
148
- async function A(e) {
148
+ async function A(t) {
149
149
  let r = await S();
150
150
  if (!r) throw new _(g);
151
- let i = n(t(e.script)).toJSON(), a = u({
152
- ...e,
151
+ let i = n(e(t.script)).toJSON(), a = u({
152
+ ...t,
153
153
  threeUrl: D,
154
154
  sceneJson: i
155
155
  }), o;
@@ -180,8 +180,112 @@ async function A(e) {
180
180
  if (typeof n != "string" || !n.startsWith("data:image/png;base64,")) throw Error("the render page produced no image");
181
181
  return n.slice(22);
182
182
  } finally {
183
- await o.close().catch((t) => v(e, `chromium close failed: ${f(t)}`));
183
+ await o.close().catch((e) => v(t.onWarning, `chromium close failed: ${f(e)}`));
184
184
  }
185
185
  }
186
186
  //#endregion
187
- export { g as CHROMIUM_HINT, m as LAUNCH_TIMEOUT_MS, h as RENDER_BUDGET_MS, p as RENDER_TIMEOUT_MS, _ as RenderUnavailableError, u as buildRenderPage, s as gridFor, A as renderShapeScriptSheet };
187
+ //#region src/render/tool.ts
188
+ var j = 30, M = 25, N = 1, P = 480, F = 900, I = 160, L = 85, R = h + 3e4, z = "renderShapeScript", B = "Render a ShapeScript model to a PNG image and save it, so you can LOOK at the model you wrote and check it before showing it to the user. Returns the image path — read that file to see the result. By default it renders four camera angles onto one sheet, because a single view cannot settle what is in front of what. Takes the same source as presentShapeScript: inline `script`, or `path` to a saved .shape file.", V = "Use renderShapeScript to CHECK a 3D model you wrote before presenting it — it saves a PNG and returns the path, which you then read to see what the model actually looks like. Fix what you see and re-render. Rendering needs a local headless browser; if it reports one is missing, say so and continue with presentShapeScript rather than retrying.", H = {
189
+ type: "object",
190
+ properties: {
191
+ script: {
192
+ type: "string",
193
+ description: "ShapeScript source to render. Provide either this or `path`, not both."
194
+ },
195
+ path: {
196
+ type: "string",
197
+ description: "Path to an existing .shape file to render (e.g. one presentShapeScript saved under artifacts/shapes/)."
198
+ },
199
+ azimuth: {
200
+ type: "number",
201
+ description: `Camera rotation around the model in degrees, 0 = looking from +Z. Default ${j}. In the default four-view sheet this is the FIRST view's angle; the others are offset from it.`
202
+ },
203
+ elevation: {
204
+ type: "number",
205
+ description: `Camera height in degrees above the horizon, 90 = straight down. Default ${M}. Avoid 0 and 90 for the main view — an axis-aligned shot flattens depth.`
206
+ },
207
+ zoom: {
208
+ type: "number",
209
+ description: "Multiplier on the automatic framing, which fits the whole model. 1 = fit (default), 2 = twice as close, 0.5 = further out. Prefer this over guessing a camera distance: it means the same thing at any model scale."
210
+ },
211
+ views: {
212
+ type: "string",
213
+ enum: ["quad", "single"],
214
+ description: "`quad` (default) renders four angles on one sheet — use it to judge shape and layout. `single` renders only `azimuth`/`elevation`, for a close look at one detail."
215
+ },
216
+ projection: {
217
+ type: "string",
218
+ enum: ["perspective", "orthographic"],
219
+ description: "`perspective` (default) looks natural; `orthographic` keeps parallel edges parallel, which is better for comparing proportions."
220
+ },
221
+ width: {
222
+ type: "number",
223
+ description: `Pixel width of ONE view. Default ${P}, clamped to ${I}–${F}.`
224
+ },
225
+ height: {
226
+ type: "number",
227
+ description: `Pixel height of ONE view. Default ${P}, clamped to ${I}–${F}.`
228
+ }
229
+ },
230
+ required: []
231
+ };
232
+ function U(e, t) {
233
+ return typeof e != "number" || !Number.isFinite(e) ? t : Math.min(F, Math.max(I, Math.round(e)));
234
+ }
235
+ function W(e, t) {
236
+ return typeof e == "number" && Number.isFinite(e) ? e : t;
237
+ }
238
+ var G = (e) => `${Math.round(e)}°`;
239
+ function K(e, t, n) {
240
+ let r = (e, t, n) => ({
241
+ azimuth: e,
242
+ elevation: t,
243
+ label: `${n} — az ${G(e)}, el ${G(t)}`
244
+ });
245
+ return n ? [r(e, t, "view")] : [
246
+ r(e, t, "front-right"),
247
+ r(e + 90, t, "back-right"),
248
+ r(e + 180, t, "back-left"),
249
+ r(e, L, "top")
250
+ ];
251
+ }
252
+ async function q(e, t) {
253
+ let n = typeof t.script == "string" && t.script.trim() !== "" ? t.script : void 0, r = typeof t.path == "string" && t.path.trim() !== "" ? t.path : void 0;
254
+ if (n && r) throw Error("Provide either `script` or `path`, not both");
255
+ if (n) return n;
256
+ if (r) return e.readShape(r);
257
+ throw Error("Provide either `script` (inline source) or `path` (an existing .shape file)");
258
+ }
259
+ function J(e, t, n, r) {
260
+ return {
261
+ script: t,
262
+ views: n,
263
+ width: U(e.width, P),
264
+ height: U(e.height, P),
265
+ zoom: Math.max(W(e.zoom, N), .01),
266
+ projection: e.projection === "orthographic" ? "orthographic" : "perspective",
267
+ ...r ? { onWarning: r } : {}
268
+ };
269
+ }
270
+ function Y(e, t) {
271
+ let n = t.map((e) => e.label).join("; ");
272
+ return `Saved render to ${e} (${t.length === 1 ? "1 view" : `${t.length} views`}: ${n}). Read that file to see the model.`;
273
+ }
274
+ async function X(e, t) {
275
+ let n = await q(e, t), r = K(W(t.azimuth, j), W(t.elevation, M), t.views === "single");
276
+ try {
277
+ let i = await A(J(t, n, r, e.onWarning));
278
+ return {
279
+ message: Y(await e.saveImage(i), r),
280
+ rendered: !0
281
+ };
282
+ } catch (t) {
283
+ if (t instanceof _) return v(e.onWarning, `renderShapeScript: unavailable — ${t.message}`), {
284
+ message: t.message,
285
+ rendered: !1
286
+ };
287
+ throw t;
288
+ }
289
+ }
290
+ //#endregion
291
+ export { g as CHROMIUM_HINT, m as LAUNCH_TIMEOUT_MS, h as RENDER_BUDGET_MS, B as RENDER_SHAPE_SCRIPT_DESCRIPTION, V as RENDER_SHAPE_SCRIPT_PROMPT, H as RENDER_SHAPE_SCRIPT_SCHEMA, z as RENDER_SHAPE_SCRIPT_TOOL_NAME, p as RENDER_TIMEOUT_MS, R as RENDER_TOOL_TIMEOUT_MS, _ as RenderUnavailableError, u as buildRenderPage, X as executeRenderShapeScript, s as gridFor, J as renderOptionsFrom, A as renderShapeScriptSheet, Y as savedMessage, K as viewAngles };