@compilr-dev/sdk 0.38.0 → 0.39.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.
@@ -21,10 +21,26 @@ export declare const SCENE_EXTRUDE_AXES: readonly ExtrudeAxis[];
21
21
  export interface SceneMaterial {
22
22
  /** 0..1, default 0.78 */
23
23
  roughness?: number;
24
- /** 0..1, default 0.02 */
24
+ /**
25
+ * 0..1, default 0.02.
26
+ *
27
+ * ⚠️ Metal is MIRROR, not colour: a metal with nothing to reflect renders near-black. The
28
+ * viewer lights the scene with a neutral room environment so this means something; without
29
+ * one, raising it made objects darker, which is why it had looked like a dead knob.
30
+ */
25
31
  metalness?: number;
26
32
  /** 0.05..1, default 1 (transparent when < 1) */
27
33
  opacity?: number;
34
+ /**
35
+ * '#RRGGBB' the object gives off, default '#000000' (none). Emission is NOT light: it
36
+ * brightens the object itself and casts nothing on its neighbours, so it marks a thing as
37
+ * live or active — an indicator, a hot path, a selected step — rather than lighting a room.
38
+ */
39
+ emissive?: string;
40
+ /** How strong the emission is. 0..5, default 1. Only means anything with `emissive` set. */
41
+ emissiveIntensity?: number;
42
+ /** Draw the edges only. Default false. For the parts of a diagram that are logical, not built. */
43
+ wireframe?: boolean;
28
44
  }
29
45
  export interface SceneObjectBase {
30
46
  /** Unique in the scene; /^[a-z0-9][a-z0-9_-]{0,47}$/ */
@@ -260,6 +276,8 @@ export declare const SCENE_NEUTRAL_PALETTE: readonly string[];
260
276
  /** Accessible names for the palette swatches, same order (Q-10). */
261
277
  export declare const SCENE_PALETTE_NAMES: readonly string[];
262
278
  export declare const SCENE_DEFAULT_MATERIAL: Readonly<Required<SceneMaterial>>;
279
+ /** `material.emissiveIntensity` range. Above ~5 everything clips to white. */
280
+ export declare const SCENE_EMISSIVE_INTENSITY_MAX = 5;
263
281
  /** The reference camera, used for an empty scene. */
264
282
  export declare const SCENE_DEFAULT_CAMERA: Readonly<SceneCamera>;
265
283
  /** Vertical field of view of the viewer camera, degrees. */
@@ -105,7 +105,12 @@ export const SCENE_DEFAULT_MATERIAL = {
105
105
  roughness: 0.78,
106
106
  metalness: 0.02,
107
107
  opacity: 1,
108
+ emissive: '#000000',
109
+ emissiveIntensity: 1,
110
+ wireframe: false,
108
111
  };
112
+ /** `material.emissiveIntensity` range. Above ~5 everything clips to white. */
113
+ export const SCENE_EMISSIVE_INTENSITY_MAX = 5;
109
114
  /** The reference camera, used for an empty scene. */
110
115
  export const SCENE_DEFAULT_CAMERA = {
111
116
  position: [7, 5.5, 8],
@@ -216,7 +221,14 @@ const TYPE_SHAPE = {
216
221
  group: 'a group is a container: id, name, position, rotation, group, locked, tags only — colour its children',
217
222
  label: 'label takes text and optional size (cap height in metres), background, face ("camera" or "fixed"); color is the ink and material is not allowed',
218
223
  };
219
- const MATERIAL_KEYS = new Set(['roughness', 'metalness', 'opacity']);
224
+ const MATERIAL_KEYS = new Set([
225
+ 'roughness',
226
+ 'metalness',
227
+ 'opacity',
228
+ 'emissive',
229
+ 'emissiveIntensity',
230
+ 'wireframe',
231
+ ]);
220
232
  const HEX_RE = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
221
233
  /** Short, stable number rendering for messages and summaries. */
222
234
  export function fmtNum(n) {
@@ -422,7 +434,7 @@ function validateObject(raw, i, errors) {
422
434
  const m = raw.material;
423
435
  for (const k of Object.keys(m)) {
424
436
  if (!MATERIAL_KEYS.has(k)) {
425
- errors.push(`${label}.material.${k} is not a material field — roughness, metalness, opacity.`);
437
+ errors.push(`${label}.material.${k} is not a material field — roughness, metalness, opacity, emissive, emissiveIntensity, wireframe.`);
426
438
  }
427
439
  }
428
440
  if (m.roughness !== undefined)
@@ -431,6 +443,15 @@ function validateObject(raw, i, errors) {
431
443
  checkNumber(m.metalness, `${label}.material.metalness`, 0, 1, 'metalness is 0–1', errors);
432
444
  if (m.opacity !== undefined)
433
445
  checkNumber(m.opacity, `${label}.material.opacity`, SCENE_OPACITY_MIN, 1, `opacity is ${fmtNum(SCENE_OPACITY_MIN)}–1`, errors);
446
+ if (m.emissive !== undefined &&
447
+ (typeof m.emissive !== 'string' || !HEX_RE.test(m.emissive))) {
448
+ errors.push(`${label}.material.emissive = ${show(m.emissive)} — a colour the object gives off, "#RGB" or "#RRGGBB" ("#000000" for none).`);
449
+ }
450
+ if (m.emissiveIntensity !== undefined)
451
+ checkNumber(m.emissiveIntensity, `${label}.material.emissiveIntensity`, 0, SCENE_EMISSIVE_INTENSITY_MAX, `emissiveIntensity is 0–${String(SCENE_EMISSIVE_INTENSITY_MAX)}, and only does anything with emissive set`, errors);
452
+ if (m.wireframe !== undefined && typeof m.wireframe !== 'boolean') {
453
+ errors.push(`${label}.material.wireframe = ${show(m.wireframe)} — true or false.`);
454
+ }
434
455
  }
435
456
  }
436
457
  // Type-specific dimensions.
@@ -288,11 +288,30 @@ const OBJECT_PROPERTIES = {
288
288
  },
289
289
  material: {
290
290
  type: 'object',
291
- description: '{ roughness 0–1, metalness 0–1, opacity 0.05–1 }. Not on a group.',
291
+ description: 'Not on a group or a label. { roughness 0–1 (0 = mirror-smooth, 1 = matt) · metalness 0–1 ' +
292
+ '(metal is MIRROR, not colour: it shows the room, so it reads dark against a plain ' +
293
+ 'background — use it for a few accents, not everything) · opacity 0.05–1 (a pane of glass, ' +
294
+ 'a volume you want to see into) · emissive "#RRGGBB" + emissiveIntensity 0–5 · wireframe }.',
292
295
  properties: {
293
296
  roughness: { type: 'number' },
294
297
  metalness: { type: 'number' },
295
298
  opacity: { type: 'number' },
299
+ emissive: {
300
+ type: 'string',
301
+ description: 'A colour the object GIVES OFF, so it reads as live rather than lit: an indicator, an ' +
302
+ 'active path, the step being explained. ⚠️ It brightens the object only — it casts no ' +
303
+ "light on its neighbours and draws no halo. Pair it with the object's own colour, and " +
304
+ 'use it on a few things: everything glowing is nothing glowing.',
305
+ },
306
+ emissiveIntensity: {
307
+ type: 'number',
308
+ description: '0–5, default 1. Does nothing without emissive. Past ~3 the colour clips to white.',
309
+ },
310
+ wireframe: {
311
+ type: 'boolean',
312
+ description: 'Edges only. For the parts of a diagram that are LOGICAL rather than built — a boundary, ' +
313
+ 'a planned phase, a region — beside solid objects that are real.',
314
+ },
296
315
  },
297
316
  },
298
317
  locked: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compilr-dev/sdk",
3
- "version": "0.38.0",
3
+ "version": "0.39.0",
4
4
  "description": "Universal agent runtime for building AI-powered applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",