@pixerate/editor 0.268.0 → 0.268.2

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.
@@ -110,6 +110,7 @@ import {
110
110
  applyProcess2Adjustments,
111
111
  applyProcess2Float,
112
112
  applySmartFilters,
113
+ assertAdjustmentParams,
113
114
  backgroundLayer,
114
115
  blackWhiteGray,
115
116
  blurFilter,
@@ -408,7 +409,7 @@ import {
408
409
  writePsd,
409
410
  xyToTempTint,
410
411
  xyToUv
411
- } from "../chunk-74ODPZLX.js";
412
+ } from "../chunk-LDOD7VCT.js";
412
413
  import {
413
414
  flattenPath,
414
415
  rasterizeCoverage
@@ -14005,7 +14006,7 @@ function createImageSelectionTools(controller) {
14005
14006
  properties: {
14006
14007
  layerId: { type: "string", description: "Existing adjustment layer to mask." },
14007
14008
  kind: { type: "string", enum: ADJUSTMENT_KINDS.map((k) => k.kind), description: "Kind of a new layer to add and mask (instead of layerId)." },
14008
- params: { type: "object", description: "Parameters for the new layer (see list_controls)." },
14009
+ params: { type: "object", description: 'Parameters for the new layer, nested as in add_adjustment_layer: {"master":{"gamma":1.2}}, not dotted control ids.' },
14009
14010
  density: { type: "number", minimum: 0, maximum: 1, description: "Mask density 0-1." },
14010
14011
  feather: { type: "number", minimum: 0, maximum: 1e3, description: "Mask feather in pixels." }
14011
14012
  },
@@ -14025,6 +14026,7 @@ function createImageSelectionTools(controller) {
14025
14026
  controller.applySelectionAsLayerMask(layerId, props);
14026
14027
  id = layerId;
14027
14028
  } else if (isAdjustmentKind(kind)) {
14029
+ assertAdjustmentParams(kind, params);
14028
14030
  id = controller.addAdjustmentLayer({
14029
14031
  kind,
14030
14032
  params,
@@ -18554,12 +18556,12 @@ function createImageEditorToolProvider(controller, options = {}) {
18554
18556
  const addLayer = {
18555
18557
  name: "add_adjustment_layer",
18556
18558
  title: "Add an adjustment layer",
18557
- description: "Adds a non-destructive adjustment layer on top of the stack (one undoable step) and returns it; with a selection it is masked by it (useSelection, default true; masked in the result says so). clipped clips it to the layer directly below in the same step, so it adjusts only that layer (clipped in the result). Kinds: " + ADJUSTMENT_KINDS.map((k) => k.kind).join(", ") + ". Omitted params are neutral.",
18559
+ description: "Adds a non-destructive adjustment layer on top of the stack (one undoable step) and returns it; with a selection it is masked by it (useSelection, default true; masked in the result says so). clipped clips it to the layer directly below in the same step, so it adjusts only that layer (clipped in the result). Kinds: " + ADJUSTMENT_KINDS.map((k) => k.kind).join(", ") + ". Omitted params are neutral; an unknown or mistyped key is refused with the accepted shape.",
18558
18560
  inputSchema: {
18559
18561
  type: "object",
18560
18562
  properties: {
18561
18563
  kind: { type: "string", enum: ADJUSTMENT_KINDS.map((k) => k.kind), description: "Adjustment kind." },
18562
- params: { type: "object", description: "Initial parameters (see list_controls); merged with neutral defaults." },
18564
+ params: { type: "object", description: 'Initial parameters, merged with neutral defaults. Nested, not dotted control ids: levels gamma is {"master":{"gamma":1.2}}, not {"master.gamma":1.2}. See list_controls for the ranges.' },
18563
18565
  opacity: { type: "number", minimum: 0, maximum: 1, description: "Layer opacity 0-1 (default 1)." },
18564
18566
  blend: { type: "string", enum: BLEND_MODES.map((m) => m.id), description: "Blend mode (default normal)." },
18565
18567
  name: { type: "string", description: "Layer name shown in the layers panel." },
@@ -18586,6 +18588,7 @@ function createImageEditorToolProvider(controller, options = {}) {
18586
18588
  if (ref !== void 0 && !controller.getLayer(ref)) throw new Error(`Unknown layer "${ref}". Call list_layers for ids.`);
18587
18589
  }
18588
18590
  if (parentId !== void 0 && controller.getLayer(parentId)?.type !== "group") throw new Error(`Layer "${parentId}" is not a group.`);
18591
+ assertAdjustmentParams(kind, params);
18589
18592
  const id = controller.addAdjustmentLayer({ kind, params, opacity, blend, name, aboveId, parentId, useSelection: useSelection !== false, clipped: clipped === true });
18590
18593
  const layer = controller.getAdjustmentLayer(id);
18591
18594
  return { layer: JSON.parse(JSON.stringify(layer)), index: controller.getAdjustmentLayers().findIndex((l) => l.id === id), masked: Boolean(layer.mask), clipped: Boolean(controller.getLayer(id)?.clipped) };
@@ -21836,6 +21839,7 @@ export {
21836
21839
  applyStrokeToDeepTile,
21837
21840
  applyStrokeToTile,
21838
21841
  applyToneToDeepTile,
21842
+ assertAdjustmentParams,
21839
21843
  backgroundLayer,
21840
21844
  base64ToBytes,
21841
21845
  baseProjection,
@@ -34,7 +34,7 @@ var _chunk7TD63DZPcjs = require('../chunk-7TD63DZP.cjs');
34
34
 
35
35
 
36
36
 
37
- var _chunkB3G7BKUVcjs = require('../chunk-B3G7BKUV.cjs');
37
+ var _chunkJ4GXP53Rcjs = require('../chunk-J4GXP53R.cjs');
38
38
  require('../chunk-YZWM6ZIP.cjs');
39
39
  require('../chunk-3ZRNK3RO.cjs');
40
40
 
@@ -2850,11 +2850,11 @@ function header(state, options) {
2850
2850
  return out;
2851
2851
  }
2852
2852
  function serializePaintDocument(state, options = {}) {
2853
- const { layers, assets } = _chunkB3G7BKUVcjs.serializeLayers.call(void 0, state.layers);
2853
+ const { layers, assets } = _chunkJ4GXP53Rcjs.serializeLayers.call(void 0, state.layers);
2854
2854
  return { ...header(state, options), layers, assets };
2855
2855
  }
2856
2856
  async function serializePaintDocumentExternal(state, store, options = {}) {
2857
- const { layers, assets } = await _chunkB3G7BKUVcjs.serializeLayersExternal.call(void 0, state.layers, store);
2857
+ const { layers, assets } = await _chunkJ4GXP53Rcjs.serializeLayersExternal.call(void 0, state.layers, store);
2858
2858
  return { ...header(state, options), layers, assets };
2859
2859
  }
2860
2860
  function paintLayersOnly(layers, problems) {
@@ -2891,7 +2891,7 @@ function deserializePaintDocument(raw) {
2891
2891
  const canvas = normalizeCanvas({ width: r.width, height: r.height, dpi: _nullishCoalesce(r.dpi, () => ( void 0)) });
2892
2892
  const paper = _chunkJBB3GDBBcjs.normalizePaper.call(void 0, _nullishCoalesce(r.paper, () => ( {})));
2893
2893
  const assets = r.assets && typeof r.assets === "object" ? r.assets : {};
2894
- const layers = paintLayersOnly(_chunkB3G7BKUVcjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
2894
+ const layers = paintLayersOnly(_chunkJ4GXP53Rcjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
2895
2895
  const wanted = typeof r.activeLayerId === "string" ? r.activeLayerId : null;
2896
2896
  const activeLayerId = wanted && _chunkPVJMTLPJcjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkPVJMTLPJcjs.flattenLayers.call(void 0, layers), 'access', _124 => _124.filter, 'call', _125 => _125((l) => l.type === "pixel"), 'access', _126 => _126.pop, 'call', _127 => _127(), 'optionalAccess', _128 => _128.id]), () => ( null));
2897
2897
  const wetEvents = Array.isArray(r.wetEvents) ? r.wetEvents.filter((e) => e && typeof e === "object" && Number.isInteger(e.clock) && typeof e.kind === "string") : [];
@@ -2907,7 +2907,7 @@ async function deserializePaintDocumentAsync(raw, store) {
2907
2907
  if (!raw || typeof raw !== "object") throw new Error("Not a paint document: expected a JSON object.");
2908
2908
  const r = raw;
2909
2909
  const problems = [];
2910
- const assets = await _chunkB3G7BKUVcjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
2910
+ const assets = await _chunkJ4GXP53Rcjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
2911
2911
  const loaded = deserializePaintDocument({ ...r, assets });
2912
2912
  return { ...loaded, problems: [...problems, ...loaded.problems] };
2913
2913
  }
@@ -7377,7 +7377,7 @@ var PaintEditorController = (_class14 = class _PaintEditorController {
7377
7377
  return next.type === "group" ? { ...next, children: toStandard(next.children) } : next;
7378
7378
  });
7379
7379
  const layers = toStandard(dried);
7380
- const result = _chunkB3G7BKUVcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
7380
+ const result = _chunkJ4GXP53Rcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
7381
7381
  for (const [mode, names] of changed) {
7382
7382
  const label = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _416 => _416.find, 'call', _417 => _417((m) => m.id === mode), 'optionalAccess', _418 => _418.label]), () => ( mode));
7383
7383
  const std = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _419 => _419.find, 'call', _420 => _420((m) => m.id === _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _421 => _421.label]), () => ( _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)));
@@ -10710,7 +10710,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
10710
10710
  tools.push(..._chunk62MFUHSIcjs.createPigmentTools.call(void 0, ));
10711
10711
  tools.push(..._chunkPFHJS4HEcjs.createStickerTools.call(void 0, { provider: () => c.stickersProvider }));
10712
10712
  tools.push(
10713
- ..._chunkB3G7BKUVcjs.createLayerEffectTools.call(void 0,
10713
+ ..._chunkJ4GXP53Rcjs.createLayerEffectTools.call(void 0,
10714
10714
  {
10715
10715
  requireLayer: (id) => void c.getLayerEffects(id),
10716
10716
  getLayerEffects: (id) => c.getLayerEffects(id),
@@ -12092,7 +12092,7 @@ function toolList(provider) {
12092
12092
  function uiTables() {
12093
12093
  return {
12094
12094
  tools: PAINT_TOOLS,
12095
- brushOptions: _chunkB3G7BKUVcjs.BRUSH_OPTION_CONTROLS,
12095
+ brushOptions: _chunkJ4GXP53Rcjs.BRUSH_OPTION_CONTROLS,
12096
12096
  blendMenu: BLEND_MENU_GROUPS,
12097
12097
  layerEffects: _chunkPVJMTLPJcjs.LAYER_EFFECT_MENU.map(({ kind, label }) => ({ kind, label, controls: _chunkPVJMTLPJcjs.layerEffectControls.call(void 0, _chunkPVJMTLPJcjs.defaultLayerEffect.call(void 0, kind, kind)) })),
12098
12098
  sliders: { paper: PAPER_SLIDERS, wet: WET_PARAM_SLIDERS, wetTilt: WET_TILT_SLIDERS, wetSpeed: WET_SPEED_SLIDER, light: LIGHT_SLIDERS, stroke: STROKE_SLIDERS, sticker: STICKER_SLIDERS },
@@ -34,7 +34,7 @@ import {
34
34
  resolveExternalAssets,
35
35
  serializeLayers,
36
36
  serializeLayersExternal
37
- } from "../chunk-74ODPZLX.js";
37
+ } from "../chunk-LDOD7VCT.js";
38
38
  import "../chunk-ADMRNWR7.js";
39
39
  import "../chunk-WJ4WQJCC.js";
40
40
  import {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixerate/editor",
3
- "version": "0.268.0",
3
+ "version": "0.268.2",
4
4
  "description": "UI-agnostic rich text and media editing core library",
5
5
  "author": "Pixerate",
6
6
  "license": "MIT",
@@ -375,6 +375,115 @@
375
375
  }
376
376
  }
377
377
  },
378
+ "typesVersions": {
379
+ "*": {
380
+ "grammar": [
381
+ "./dist/grammar/index.d.ts"
382
+ ],
383
+ "extensions": [
384
+ "./dist/extensions/index.d.ts"
385
+ ],
386
+ "serializers": [
387
+ "./dist/serializers/index.d.ts"
388
+ ],
389
+ "spreadsheet": [
390
+ "./dist/spreadsheet/index.d.ts"
391
+ ],
392
+ "history": [
393
+ "./dist/history/index.d.ts"
394
+ ],
395
+ "animation": [
396
+ "./dist/animation/index.d.ts"
397
+ ],
398
+ "animation-editor": [
399
+ "./dist/animation-editor/index.d.ts"
400
+ ],
401
+ "video-editor": [
402
+ "./dist/video-editor/index.d.ts"
403
+ ],
404
+ "canvas": [
405
+ "./dist/canvas/index.d.ts"
406
+ ],
407
+ "agent": [
408
+ "./dist/agent/index.d.ts"
409
+ ],
410
+ "tools": [
411
+ "./dist/tools/index.d.ts"
412
+ ],
413
+ "raster": [
414
+ "./dist/raster/index.d.ts"
415
+ ],
416
+ "cms": [
417
+ "./dist/cms/index.d.ts"
418
+ ],
419
+ "paint": [
420
+ "./dist/paint/index.d.ts"
421
+ ],
422
+ "image-editor": [
423
+ "./dist/image-editor/index.d.ts"
424
+ ],
425
+ "image-editor/selection-worker": [
426
+ "./dist/image-editor/selection-worker.d.ts"
427
+ ],
428
+ "paint-editor": [
429
+ "./dist/paint-editor/index.d.ts"
430
+ ],
431
+ "brushes": [
432
+ "./dist/brushes/index.d.ts"
433
+ ],
434
+ "commands": [
435
+ "./dist/commands/index.d.ts"
436
+ ],
437
+ "persistence": [
438
+ "./dist/persistence/index.d.ts"
439
+ ],
440
+ "generation": [
441
+ "./dist/generation/index.d.ts"
442
+ ],
443
+ "compare": [
444
+ "./dist/compare/index.d.ts"
445
+ ],
446
+ "tokens": [
447
+ "./dist/tokens/index.d.ts"
448
+ ],
449
+ "color": [
450
+ "./dist/color/index.d.ts"
451
+ ],
452
+ "typography": [
453
+ "./dist/typography/index.d.ts"
454
+ ],
455
+ "gradient": [
456
+ "./dist/gradient/index.d.ts"
457
+ ],
458
+ "export": [
459
+ "./dist/export/index.d.ts"
460
+ ],
461
+ "parameters": [
462
+ "./dist/parameters/index.d.ts"
463
+ ],
464
+ "vector": [
465
+ "./dist/vector/index.d.ts"
466
+ ],
467
+ "chart": [
468
+ "./dist/chart/index.d.ts"
469
+ ],
470
+ "chart-maps": [
471
+ "./dist/chart-maps/index.d.ts"
472
+ ],
473
+ "effects": [
474
+ "./dist/effects/index.d.ts"
475
+ ],
476
+ "stickers": [
477
+ "./dist/stickers/index.d.ts"
478
+ ],
479
+ "diagram": [
480
+ "./dist/diagram/index.d.ts"
481
+ ],
482
+ "bridge": [
483
+ "./dist/bridge/index.d.ts"
484
+ ]
485
+ }
486
+ },
378
487
  "bin": {
379
488
  "pixerate-mcp-bridge": "./dist/bridge/cli.js"
380
489
  },
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: pixerate-brushes
3
- description: How to find, describe, create, change, check and share brushes in the Pixerate brush library through list_brush_presets, describe_brush, create_brush, update_brush, duplicate_brush, remove_brush, check_brush, export_brushes, import_brushes, preview_brush, add_brush_source and list_brush_sources - brushes made of facets (kind, medium and variety or tool, tip, marks, dynamics, behaviour, light, motion, colour), image tips and tip grain made from image sources, the built-in presets, and the host profiles that say what the paint editor, image editor, canvas and vector strokes can render. Use when asked to make, design, tweak, save, copy, delete, export, import or check a brush, make a brush from an image (a scanned mark, a leaf, a texture), give a brush grain, find a brush for a medium (pencil, ink, watercolour, oil, airbrush, highlighter), or make a brush work in another editor.
3
+ description: How to find, describe, create, change, check and share brushes in the Pixerate brush library through list_brush_presets, describe_brush, create_brush, update_brush, duplicate_brush, remove_brush, check_brush, export_brushes, import_brushes, import_brush_pack, preview_brush, add_brush_source and list_brush_sources - brushes made of facets (kind, medium and variety or tool, tip, marks, dynamics, behaviour, light, motion, colour), image tips and tip grain made from image sources, the built-in presets, and the host profiles that say what the paint editor, image editor, canvas and vector strokes can render. Use when asked to make, design, tweak, save, copy, delete, export, import or check a brush, make a brush from an image (a scanned mark, a leaf, a texture), give a brush grain, bring in a Photoshop .abr or Procreate .brush / .brushset pack, find a brush for a medium (pencil, ink, watercolour, oil, airbrush, highlighter), or make a brush work in another editor.
4
4
  ---
5
5
 
6
6
  # Brushes
@@ -79,7 +79,10 @@ drawn.
79
79
  part; keep the `licence` it came with), then `create_brush` with `tip: { shape: "stamp",
80
80
  stamps: ["source:<id>"] }` for an image tip, or `tip.grain.source` for grain.
81
81
  `list_brush_sources` lists them and which brushes use each.
82
- 7. **Share it.** `export_brushes` writes a library file; `import_brushes` adds one (version 1
82
+ 7. **Bring in a pack.** `import_brush_pack` with the file (base64), its `fileName` and the
83
+ `licence` it came with. Read `brushes` (with `renderable` for this host), `unsupported` (what
84
+ was not mapped) and `licence`, then `preview_brush` a few and tune them with `update_brush`.
85
+ 8. **Share it.** `export_brushes` writes a library file; `import_brushes` adds one (version 1
83
86
  files of the paint editor's older brushes are migrated). `check_brush` with `host` before
84
87
  handing a brush to another editor.
85
88
 
@@ -132,6 +135,11 @@ drawn.
132
135
  not strokes already painted. Objects marks take stickers only, so an image source there is
133
136
  dropped (`problems` says so). Brush packs are often licensed for personal use only: keep the
134
137
  `licence` text with the source.
138
+ - **Brush packs.** Only the tips (and Procreate grain) are imported: dynamics, pencil curves,
139
+ patterns, dual brushes and wet settings are listed in `unsupported`, so imported brushes paint
140
+ with default feel; tune them. Imported image tips are stamp tips, so canvas, vector and the image
141
+ editor can't paint them (`renderable` false). Packs are often for personal use only: pass and
142
+ keep their `licence`; never redistribute a library file of imported brushes without checking it.
135
143
  - **Out-of-range values** are refused by the schema (`tip.size` is 1..2500 px); a stored brush
136
144
  is clamped on import and reported in `problems`.
137
145
  - **The paint editor paints from this library.** Its `set_brush` picks a brush by id here and
@@ -159,4 +167,5 @@ drawn.
159
167
  | `import_brushes` | Add a library `file` (v2, v1 migrated, or a bare list): built-in ids and taken ids are skipped unless `overwrite`. Returns `added`, `replaced`, `skipped`, `problems`. |
160
168
  | `preview_brush` | Only when the host renders previews: a sample stroke with a brush (`id`, `width`, `height`, `color`) as an image. |
161
169
  | `add_brush_source` | Add an image (`name`, `image` PNG data: URL, optional `id`, `channel` auto / alpha / darkness / lightness, `invert`, `licence`, `origin`, `overwrite`) as a source for image tips and grain. Returns `id`, `ref` (`source:<id>`), `width`, `height`, `problems`, `replaced`. Then `create_brush` / `update_brush` with the ref in `tip.stamps` or `tip.grain.source`. |
170
+ | `import_brush_pack` | Import a Photoshop `.abr` or Procreate `.brush` / `.brushset` (`file` base64 or a data: URL, `fileName`, optional `format`, `prefix`, `licence`, `overwrite`). Returns `format`, `brushes` (id, name, `renderable` here), `sources`, `skipped`, `unsupported`, `licence`, `problems`. Then `preview_brush` and `update_brush` to tune. |
162
171
  | `list_brush_sources` | The library's image sources (`text`, `offset`, `limit`). Returns `sources` (id, ref, name, width, height, licence, origin, `usedBy` brush ids) and `total`. Call before naming a `source:` ref. |
@@ -63,6 +63,7 @@ Ask when you cannot tell from the request; say what you assumed when you can.
63
63
  | A colour that depends on the background (chalk, white ink) | `colour.default` as a light / dark pair `{ light, dark }`: the editor takes the side for its colour scheme when the brush is chosen. |
64
64
  | A shape as the tip (stars, leaves, a logo) | `tip.shape` stamp with `stamps` (an editor stamp or a ref from `find_stickers`), continuous marks; it paints in the user's colour. Keep the sticker's colours with `marks` objects. Paint editor only. |
65
65
  | A spray can or mist | `basedOn` `spray-can`, or `medium` spray with `marks` scatter (`density`, `size`). Paint editor only. |
66
+ | From a brush pack the user owns (.abr, .brushset) | `import_brush_pack` with its `licence`, pick the closest imported brush, then `update_brush` its feel (pressure, jitter, grain): packs import tips, not dynamics. |
66
67
  | A change to a built-in | `duplicate_brush`, then `update_brush` the copy. |
67
68
  | Tune a brush from a host that can't paint all of it | `update_brush` there: what the host can't use is kept (`kept`), not stripped; refused only if the change adds it. |
68
69
 
@@ -101,3 +102,4 @@ channel: "darkness" }` → `create_brush` `{ id: "scan-charcoal", name: "Scan ch
101
102
  - `check_brush`: prove it works for the host, and get a degraded spec when it doesn't.
102
103
  - `preview_brush`: look at a sample stroke when the host renders previews.
103
104
  - `add_brush_source`, `list_brush_sources`: images for image tips and grain.
105
+ - `import_brush_pack`: tips and grain from a Photoshop or Procreate pack.
@@ -195,7 +195,7 @@ in the source frame at the document's bit depth, colour mode and profile. Read
195
195
  | Tool | Use it to |
196
196
  | --- | --- |
197
197
  | `set_adjustments` | Set base controls and existing layer parameters in one undo step: `values` is a map of control id or `layers.<layerId>.<controlId>` path to number; `label` is echoed. Values are clamped to range; returns `applied` and `clamped` (and a note when `tint` is set on a process 1 edit). Unknown ids fail and change nothing. Cannot set curves points, booleans or colours. |
198
- | `add_adjustment_layer` | Add a layer above the other adjustment layers and below annotations (or directly above `aboveId`, or at the top of group `parentId`): `kind` (curves, levels, hueSaturation, vibrance, colorBalance, blackWhite, photoFilter, invert, posterize, threshold), optional `params` merged with neutral defaults, `opacity` 0..1 (default 1), `blend` (default normal), `name`. With a selection the layer is masked by it (`useSelection`, default true; `false` for a global layer; `masked` in the result). `clipped: true` (with `aboveId`) clips it to the layer below in the same undo step so it adjusts only that layer; refused when nothing is below. Returns the layer (with its new id), its stack index, `masked` and `clipped`. The only tool that sets curves points, `colorize`, `preserveLuminosity`, a black and white `tint` or a photo filter `color`. |
198
+ | `add_adjustment_layer` | Add a layer above the other adjustment layers and below annotations (or directly above `aboveId`, or at the top of group `parentId`): `kind` (curves, levels, hueSaturation, vibrance, colorBalance, blackWhite, photoFilter, invert, posterize, threshold), optional `params` merged with neutral defaults and nested, not dotted (`{ master: { gamma: 1.2 } }`, never `{ "master.gamma": 1.2 }`; an unknown or mistyped key is refused and the error lists the accepted shape), `opacity` 0..1 (default 1), `blend` (default normal), `name`. With a selection the layer is masked by it (`useSelection`, default true; `false` for a global layer; `masked` in the result). `clipped: true` (with `aboveId`) clips it to the layer below in the same undo step so it adjusts only that layer; refused when nothing is below. Returns the layer (with its new id), its stack index, `masked` and `clipped`. The only tool that sets curves points, `colorize`, `preserveLuminosity`, a black and white `tint` or a photo filter `color`. |
199
199
  | `select_all` | Select › All. Returns the selection summary (`empty`, `bounds`, `area`, `percent`). |
200
200
  | `deselect` | Clear the selection so edits apply to the whole layer. Returns the empty summary. |
201
201
  | `invert_selection` | Select › Inverse (soft edges stay soft; with nothing selected, selects all). Returns the summary. |