@popcraft/cli 0.53.2 → 0.53.4

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 (2) hide show
  1. package/dist/popcraft.mjs +68 -20
  2. package/package.json +2 -2
package/dist/popcraft.mjs CHANGED
@@ -1196,7 +1196,7 @@ function operations(spec = openapi) {
1196
1196
  }
1197
1197
  async function call(target2, method, path, opts = {}) {
1198
1198
  const qs = new URLSearchParams(opts.query ?? {}).toString();
1199
- const headers = { "user-agent": `popcraft-cli/${"0.53.2"}`, ...opts.headers };
1199
+ const headers = { "user-agent": `popcraft-cli/${"0.53.4"}`, ...opts.headers };
1200
1200
  if (target2.token) headers.authorization = `Bearer ${target2.token}`;
1201
1201
  if (opts.contentType) headers["content-type"] = opts.contentType;
1202
1202
  try {
@@ -94509,7 +94509,6 @@ function hasMessage(key5) {
94509
94509
  var current2, loading, listeners, formats, asts;
94510
94510
  var init_runtime = __esm({
94511
94511
  "lib/i18n/runtime.ts"() {
94512
- "use strict";
94513
94512
  init_intl_messageformat();
94514
94513
  init_icu_messageformat_parser();
94515
94514
  init_catalogs();
@@ -96869,7 +96868,6 @@ function releaseMediaMemory(hash3) {
96869
96868
  var key2, peaksKey, objectUrls, sourceKey, remoteResolver, MEDIA_FETCH_TIMEOUT_MS, SHIPPED_MEDIA_PATH, notShipped, MEDIA_SCHEME, isImageDataUrl, memory, pendingLoads, sourceAliases, PAINT_KEYS, URL_KEYS;
96870
96869
  var init_media_store = __esm({
96871
96870
  "lib/storage/media-store.ts"() {
96872
- "use strict";
96873
96871
  init_media_types();
96874
96872
  init_idb();
96875
96873
  init_media_hash();
@@ -97386,6 +97384,7 @@ function selectionWorldBounds(nodes, ids2, scrollState) {
97386
97384
  }
97387
97385
  var init_selection_bounds = __esm({
97388
97386
  "lib/editor/selection-bounds.ts"() {
97387
+ "use strict";
97389
97388
  init_scene_graph();
97390
97389
  init_transform();
97391
97390
  }
@@ -248025,6 +248024,7 @@ function repairCompositions(comps, nodes) {
248025
248024
  var isObj5, finite6, optFinite, isVec2, TIMELINE_COLOR_IDS, TIMELINE_COLORS, UNITS, ORDERS, PROP_KEYS, ANIMATOR_ID, MOTION_TYPES, TRANSITIONS, isFraction, MEDIA_HASH;
248026
248025
  var init_invariants = __esm({
248027
248026
  "lib/motion/invariants.ts"() {
248027
+ "use strict";
248028
248028
  init_easing();
248029
248029
  init_properties();
248030
248030
  init_markers();
@@ -253122,7 +253122,6 @@ function getActiveRenderer() {
253122
253122
  var active;
253123
253123
  var init_renderer_registry = __esm({
253124
253124
  "lib/engine/renderer-registry.ts"() {
253125
- "use strict";
253126
253125
  active = null;
253127
253126
  }
253128
253127
  });
@@ -256741,7 +256740,6 @@ function mergeFonts(fonts, incoming) {
256741
256740
  var fontWeightOf, fontStyleOf, sameSlot, hashOf, documentFontHashes;
256742
256741
  var init_document_fonts = __esm({
256743
256742
  "lib/fonts/document-fonts.ts"() {
256744
- "use strict";
256745
256743
  init_media_store();
256746
256744
  init_media_hash();
256747
256745
  fontWeightOf = (f2) => f2.weight ?? 400;
@@ -262759,7 +262757,6 @@ function formatDate(date5, opts = { month: "short", day: "numeric", year: "numer
262759
262757
  var cache5, nf;
262760
262758
  var init_format = __esm({
262761
262759
  "lib/i18n/format.ts"() {
262762
- "use strict";
262763
262760
  init_runtime();
262764
262761
  cache5 = /* @__PURE__ */ new Map();
262765
262762
  nf = (opts) => cached2("n", opts, (l) => new Intl.NumberFormat(l, opts));
@@ -262779,6 +262776,7 @@ function formatLimit(key5, max3) {
262779
262776
  var formatBytes;
262780
262777
  var init_limits2 = __esm({
262781
262778
  "lib/billing/limits.ts"() {
262779
+ "use strict";
262782
262780
  init_format();
262783
262781
  init_plans();
262784
262782
  formatBytes = formatFileSize;
@@ -306995,6 +306993,7 @@ function decodeSource(key5, label3) {
306995
306993
  var DECODE_CACHE_BYTES, cache7, pending4, held, sizeOf, lengths, decodedLengths, DECODE_TIMEOUT_MS, decodedAudio, decodedSource, pcmOf;
306996
306994
  var init_audio_decode = __esm({
306997
306995
  "lib/motion/audio-decode.ts"() {
306996
+ "use strict";
306998
306997
  init_media_store();
306999
306998
  init_audio_plan();
307000
306999
  init_time_stretch();
@@ -312384,7 +312383,6 @@ function creditLine(c2) {
312384
312383
  var MAX_PHOTO_PAGE, MAX_PHOTO_QUERY, UUID, isPhotoId, photoImagePath;
312385
312384
  var init_stock = __esm({
312386
312385
  "lib/photos/stock.ts"() {
312387
- "use strict";
312388
312386
  MAX_PHOTO_PAGE = 12;
312389
312387
  MAX_PHOTO_QUERY = 200;
312390
312388
  UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -317507,7 +317505,6 @@ async function exportSettingFile(renderer, node2, setting, doc2, styles) {
317507
317505
  var MIME, DEFAULT_EXPORT, exportSettingsOf;
317508
317506
  var init_export = __esm({
317509
317507
  "lib/io/export.ts"() {
317510
- "use strict";
317511
317508
  init_download();
317512
317509
  init_scene_graph();
317513
317510
  init_codecs();
@@ -317599,6 +317596,7 @@ async function selectionReferenceImages(doc2, selection, opts = {}) {
317599
317596
  var FIT_QUALITIES, FIT_SCALES, blobToDataUrl;
317600
317597
  var init_reference_images = __esm({
317601
317598
  "lib/ai/reference-images.ts"() {
317599
+ "use strict";
317602
317600
  init_export();
317603
317601
  init_selection_bounds();
317604
317602
  init_renderer_registry();
@@ -319063,7 +319061,10 @@ var init_doc_helpers = __esm({
319063
319061
  init_invariants2();
319064
319062
  MAX_NODES = 200;
319065
319063
  plural2 = (n, one, many = `${one}s`) => `${n} ${n === 1 ? one : many}`;
319066
- hexOf = (c2) => c2 ? "#" + [c2.r, c2.g, c2.b].map((v) => Math.round(Math.max(0, Math.min(1, v)) * 255).toString(16).padStart(2, "0")).join("") : "";
319064
+ hexOf = (c2) => c2 ? "#" + [c2.r, c2.g, c2.b].map((v) => {
319065
+ const n = Number.isFinite(v) ? Math.max(0, Math.min(1, v)) : 0;
319066
+ return Math.round(n * 255).toString(16).padStart(2, "0");
319067
+ }).join("") : "";
319067
319068
  isVirtualId2 = (id3) => id3.includes("::");
319068
319069
  near3 = (a, b, tol) => !!a && Math.abs(a.r - b.r) <= tol && Math.abs(a.g - b.g) <= tol && Math.abs(a.b - b.b) <= tol;
319069
319070
  localBox = (doc2, ids2) => {
@@ -319305,6 +319306,15 @@ function descendants(doc2, rootId, skipRoot = true) {
319305
319306
  }
319306
319307
  return out;
319307
319308
  }
319309
+ function geometryMismatch(doc2, id3) {
319310
+ const n = doc2.nodes[id3];
319311
+ if (!n || n.type !== "VECTOR" || !n.paths?.length) return void 0;
319312
+ const pb = pathBounds(n.paths);
319313
+ if (!pb) return void 0;
319314
+ const gw = pb.maxX - pb.minX, gh = pb.maxY - pb.minY;
319315
+ if (Math.abs(gw - n.width) <= 1 && Math.abs(gh - n.height) <= 1) return void 0;
319316
+ return `box is ${Math.round(n.width)}\xD7${Math.round(n.height)} but the artwork is ${Math.round(gw)}\xD7${Math.round(gh)} \u2014 resize_nodes to reconcile them`;
319317
+ }
319308
319318
  function normalizeColor(c2, key5) {
319309
319319
  if (typeof c2 === "string") return parseHex(c2);
319310
319320
  const o = c2;
@@ -319317,6 +319327,15 @@ function normalizeColor(c2, key5) {
319317
319327
  const a = typeof o.a === "number" && Number.isFinite(o.a) ? o.a > 1 ? o.a / 255 : o.a : 1;
319318
319328
  return createColor(nums2[0] / scale, nums2[1] / scale, nums2[2] / scale, a);
319319
319329
  }
319330
+ function normalizeSegments(v) {
319331
+ if (!Array.isArray(v)) return v;
319332
+ return v.map((seg) => {
319333
+ if (!seg || typeof seg !== "object") return seg;
319334
+ const s = { ...seg };
319335
+ for (const k2 of ["fills", "strokes", "textDecorationColor"]) if (k2 in s) s[k2] = normalizePaints(s[k2], k2);
319336
+ return s;
319337
+ });
319338
+ }
319320
319339
  function normalizePaints(v, key5) {
319321
319340
  if (!Array.isArray(v)) throw new ToolError(`${key5} must be an array of paints.`);
319322
319341
  return v.map((p2) => {
@@ -319341,6 +319360,7 @@ var init_node = __esm({
319341
319360
  init_selection_bounds();
319342
319361
  init_scene_graph();
319343
319362
  init_types();
319363
+ init_svg_import();
319344
319364
  init_errors();
319345
319365
  init_scale_geometry();
319346
319366
  init_plugin_shim();
@@ -319406,10 +319426,12 @@ var init_node = __esm({
319406
319426
  hits.push(n);
319407
319427
  if (hits.length >= limit) break;
319408
319428
  }
319429
+ const truncated = hits.length >= limit;
319409
319430
  return {
319410
- summary: `${plural2(hits.length, "match", "matches")} for ${q || type || args2.name || "everything here"}`,
319431
+ summary: `${plural2(hits.length, "match", "matches")}${truncated ? "+ (capped)" : ""} for ${q || type || args2.name || "everything here"}`,
319411
319432
  data: {
319412
319433
  count: hits.length,
319434
+ truncated,
319413
319435
  nodes: args2.detail === "full" ? plain(hits) : hits.map((n) => ({ ...brief(n), page: pageOf2(doc2, n.id) }))
319414
319436
  }
319415
319437
  };
@@ -319451,7 +319473,10 @@ var init_node = __esm({
319451
319473
  return n2 ? plain(n2) : null;
319452
319474
  }
319453
319475
  const n = resolvedNodeOrThrow(doc2, id3);
319454
- return args2.detail === "full" ? plain(n) : describeProps(doc2, n);
319476
+ if (args2.detail === "full") return plain(n);
319477
+ const props = describeProps(doc2, n);
319478
+ const warning = geometryMismatch(doc2, n.id);
319479
+ return warning ? { ...props, warning } : props;
319455
319480
  });
319456
319481
  return { summary: `Read ${plural2(nodes.length, "layer")}`, data: { nodes } };
319457
319482
  }
@@ -319484,7 +319509,8 @@ var init_node = __esm({
319484
319509
  });
319485
319510
  const each = ids2.map((id3) => {
319486
319511
  const rb = getWorldRenderBounds(doc2, id3);
319487
- return { id: id3, name: doc2.nodes[id3].name, bounds: rb ? round5(rb) : null };
319512
+ const warning = geometryMismatch(doc2, id3);
319513
+ return { id: id3, name: doc2.nodes[id3].name, bounds: rb ? round5(rb) : null, ...warning ? { warning } : {} };
319488
319514
  });
319489
319515
  const combined = round5(box2);
319490
319516
  return { summary: `Bounds: ${combined.width}\xD7${combined.height} at ${combined.x},${combined.y}`, data: { combined, nodes: each } };
@@ -319677,13 +319703,34 @@ var init_node = __esm({
319677
319703
  for (const [k2, v] of Object.entries(u.props)) {
319678
319704
  if (args2.strict && FORBIDDEN_PROPS.has(k2)) throw new ToolError(`update_nodes cannot change "${k2}". Use reparent, delete_nodes or create_node instead.`);
319679
319705
  if (FORBIDDEN_PROPS.has(k2) || v === void 0) continue;
319680
- patch2[k2] = k2 === "fills" || k2 === "strokes" ? normalizePaints(v, k2) : v;
319706
+ patch2[k2] = k2 === "fills" || k2 === "strokes" ? normalizePaints(v, k2) : k2 === "styledSegments" ? normalizeSegments(v) : v;
319681
319707
  changedKeys.add(k2);
319682
319708
  }
319709
+ if ("fills" in patch2) patch2.fillStyleId = void 0;
319710
+ if ("strokes" in patch2) patch2.strokeStyleId = void 0;
319683
319711
  if (args2.strict && !Object.keys(patch2).length) throw new ToolError(`No properties given for "${u.id}".`);
319684
319712
  patches.set(u.id, patch2);
319685
319713
  }
319686
- commitUpdates(ctx2, doc2, patches);
319714
+ for (const [id3, patch2] of patches) {
319715
+ const p2 = patch2;
319716
+ if (!("width" in p2) && !("height" in p2)) continue;
319717
+ const n = doc2.nodes[id3];
319718
+ if (n.width <= 0 || n.height <= 0) continue;
319719
+ const w = p2.width ?? n.width, h = p2.height ?? n.height;
319720
+ if (n.type === "FRAME" || n.type === "COMPONENT" || n.type === "SECTION") continue;
319721
+ for (const [pid, sub2] of scaleSubtreePatches(doc2.nodes, id3, w / n.width, h / n.height)) {
319722
+ patches.set(pid, { ...patches.get(pid), ...sub2 });
319723
+ }
319724
+ }
319725
+ let committed = doc2;
319726
+ for (const [id3, patch2] of patches) {
319727
+ const p2 = patch2;
319728
+ const n = doc2.nodes[id3];
319729
+ if (("width" in p2 || "height" in p2) && (n.type === "FRAME" || n.type === "COMPONENT" || n.type === "SECTION")) {
319730
+ committed = applyConstraints(committed, id3, n.width, n.height, p2.width ?? n.width, p2.height ?? n.height);
319731
+ }
319732
+ }
319733
+ commitUpdates(ctx2, committed, patches);
319687
319734
  return { summary: `Updated ${plural2(patches.size, "layer")} (${[...changedKeys].slice(0, 6).join(", ")})`, data: { ids: [...patches.keys()] } };
319688
319735
  }
319689
319736
  });
@@ -319826,7 +319873,7 @@ var init_node = __esm({
319826
319873
  plugin: { method: "reparentNodes" },
319827
319874
  agent: {
319828
319875
  name: "reparent",
319829
- description: "Move layers into another parent (frame, group or page), optionally at a child index. Positions stay in the new parent's coordinates, so move_nodes afterwards if they land off-screen."
319876
+ description: "Move layers into another parent (frame, group or page), optionally at a child index. Each layer keeps its position on screen (its coordinates are rebased into the new parent)."
319830
319877
  }
319831
319878
  },
319832
319879
  run: (args2, ctx2) => {
@@ -319837,6 +319884,8 @@ var init_node = __esm({
319837
319884
  for (const id3 of args2.ids) {
319838
319885
  nodeOrThrow(doc2, id3);
319839
319886
  if (id3 === args2.parentId) throw new ToolError("A layer cannot be its own parent.");
319887
+ const placed2 = placementUnder(next2, id3, args2.parentId);
319888
+ if (placed2) next2 = updateNode(next2, id3, placed2);
319840
319889
  next2 = reparentNode(next2, id3, args2.parentId, args2.index);
319841
319890
  }
319842
319891
  ctx2.commit(applyInvariants(next2, [...args2.ids, args2.parentId]));
@@ -320989,7 +321038,7 @@ var init_paint = __esm({
320989
321038
  else if (mode2 === "replace" || !existing.length) fills = [paint];
320990
321039
  else if (mode2 === "add") fills = [...existing, paint];
320991
321040
  else fills = [paint, ...existing.slice(1)];
320992
- patches.set(id3, { fills });
321041
+ patches.set(id3, { fills, ...args2.remove ? {} : { fillStyleId: void 0 } });
320993
321042
  }
320994
321043
  const what = args2.gradient ? `a ${args2.gradient.type.toLowerCase()} gradient` : args2.image ? "an image" : args2.color;
320995
321044
  commitUpdates(ctx2, doc2, patches);
@@ -321056,7 +321105,7 @@ var init_paint = __esm({
321056
321105
  ...args2.join !== void 0 ? { join: args2.join } : {},
321057
321106
  ...args2.dashPattern !== void 0 ? { dashPattern: args2.dashPattern } : {}
321058
321107
  };
321059
- patches.set(id3, { strokes: [merged, ...existing.slice(1)], ...order2 });
321108
+ patches.set(id3, { strokes: [merged, ...existing.slice(1)], strokeStyleId: void 0, ...order2 });
321060
321109
  }
321061
321110
  commitUpdates(ctx2, doc2, patches);
321062
321111
  return {
@@ -328696,7 +328745,7 @@ var init_package = __esm({
328696
328745
  "packages/runtime/package.json"() {
328697
328746
  package_default = {
328698
328747
  name: "@popcraft/runtime",
328699
- version: "0.53.2",
328748
+ version: "0.53.4",
328700
328749
  description: "What code exported from PopCraft shares: the meaning of expressions (operators and functions) and, as it grows, the parts of a design's behaviour that are common code rather than generated React.",
328701
328750
  license: "MIT",
328702
328751
  homepage: "https://popcraft.app/docs/exporting/nextjs",
@@ -353404,7 +353453,6 @@ function compileModule(module2) {
353404
353453
  var import_sucrase, BUILT_IN, memo4;
353405
353454
  var init_compile2 = __esm({
353406
353455
  "lib/code/compile.ts"() {
353407
- "use strict";
353408
353456
  import_sucrase = __toESM(require_dist2());
353409
353457
  init_source2();
353410
353458
  init_source2();
@@ -414284,7 +414332,7 @@ init_resources();
414284
414332
  init_desktop();
414285
414333
  init_hypery();
414286
414334
  import { createInterface } from "node:readline";
414287
- var VERSION2 = "0.53.2";
414335
+ var VERSION2 = "0.53.4";
414288
414336
  var HELP = `popcraft ${VERSION2} \u2014 the PopCraft command line
414289
414337
 
414290
414338
  Files (headless, on .popcraft files):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@popcraft/cli",
3
- "version": "0.53.2",
3
+ "version": "0.53.4",
4
4
  "description": "The PopCraft command line: edit .popcraft files headlessly, call the REST API, publish to the marketplace and manage the desktop app's local plugins, themes, fonts, skills and agents.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://popcraft.app/docs/api/cli",
@@ -34,7 +34,7 @@
34
34
  "esbuild": "0.28.2"
35
35
  },
36
36
  "dependencies": {
37
- "@popcraft/kit": "0.53.2"
37
+ "@popcraft/kit": "0.53.4"
38
38
  },
39
39
  "scripts": {
40
40
  "build": "node build.mjs",