@popcraft/cli 0.53.15 → 0.53.17

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 +170 -49
  2. package/package.json +2 -2
package/dist/popcraft.mjs CHANGED
@@ -1198,7 +1198,7 @@ function operations(spec = openapi) {
1198
1198
  }
1199
1199
  async function call(target2, method, path, opts = {}) {
1200
1200
  const qs = new URLSearchParams(opts.query ?? {}).toString();
1201
- const headers = { "user-agent": `popcraft-cli/${"0.53.15"}`, ...opts.headers };
1201
+ const headers = { "user-agent": `popcraft-cli/${"0.53.17"}`, ...opts.headers };
1202
1202
  if (target2.token) headers.authorization = `Bearer ${target2.token}`;
1203
1203
  if (opts.contentType) headers["content-type"] = opts.contentType;
1204
1204
  try {
@@ -8179,6 +8179,8 @@ function duplicateNode(document2, nodeId2, offset = { x: 10, y: 10 }) {
8179
8179
  }
8180
8180
  const newNode = cloneNode(node2);
8181
8181
  let doc2 = addNode(document2, newNode, node2.parentId);
8182
+ const at4 = document2.nodes[node2.parentId]?.childIds.indexOf(nodeId2) ?? -1;
8183
+ if (at4 >= 0) doc2 = reparentNode(doc2, newNode.id, node2.parentId, at4 + 1);
8182
8184
  function cloneChildren(originalId, newParentId) {
8183
8185
  const original = document2.nodes[originalId];
8184
8186
  if (!original) return;
@@ -8188,6 +8190,7 @@ function duplicateNode(document2, nodeId2, offset = { x: 10, y: 10 }) {
8188
8190
  const newChild = cloneNode(child);
8189
8191
  newChild.x = child.x;
8190
8192
  newChild.y = child.y;
8193
+ newChild.name = child.name;
8191
8194
  doc2 = addNode(doc2, newChild, newParentId);
8192
8195
  cloneChildren(childId, newChild.id);
8193
8196
  }
@@ -29182,6 +29185,73 @@ var init_flags = __esm({
29182
29185
  }
29183
29186
  });
29184
29187
 
29188
+ // lib/document/z-order.ts
29189
+ function reorderSelection(doc2, ids2, dir) {
29190
+ const selected = new Set(ids2);
29191
+ const parents = /* @__PURE__ */ new Set();
29192
+ for (const id3 of ids2) {
29193
+ const p2 = doc2.nodes[id3]?.parentId;
29194
+ if (p2 && doc2.nodes[p2]) parents.add(p2);
29195
+ }
29196
+ if (!parents.size) return doc2;
29197
+ const nodes = { ...doc2.nodes };
29198
+ let changed = false;
29199
+ for (const pid of parents) {
29200
+ const list2 = [...nodes[pid].childIds];
29201
+ if (dir === "top" || dir === "bottom") {
29202
+ const sel = list2.filter((id3) => selected.has(id3)), rest = list2.filter((id3) => !selected.has(id3));
29203
+ const next2 = dir === "top" ? [...rest, ...sel] : [...sel, ...rest];
29204
+ if (next2.some((id3, i2) => id3 !== list2[i2])) {
29205
+ nodes[pid] = { ...nodes[pid], childIds: next2 };
29206
+ changed = true;
29207
+ }
29208
+ continue;
29209
+ }
29210
+ let moved3 = false;
29211
+ if (dir === "up") {
29212
+ for (let i2 = list2.length - 2; i2 >= 0; i2--) {
29213
+ if (selected.has(list2[i2]) && !selected.has(list2[i2 + 1])) {
29214
+ [list2[i2], list2[i2 + 1]] = [list2[i2 + 1], list2[i2]];
29215
+ moved3 = true;
29216
+ }
29217
+ }
29218
+ } else {
29219
+ for (let i2 = 1; i2 < list2.length; i2++) {
29220
+ if (selected.has(list2[i2]) && !selected.has(list2[i2 - 1])) {
29221
+ [list2[i2], list2[i2 - 1]] = [list2[i2 - 1], list2[i2]];
29222
+ moved3 = true;
29223
+ }
29224
+ }
29225
+ }
29226
+ if (moved3) {
29227
+ nodes[pid] = { ...nodes[pid], childIds: list2 };
29228
+ changed = true;
29229
+ }
29230
+ }
29231
+ return changed ? { ...doc2, nodes } : doc2;
29232
+ }
29233
+ var init_z_order = __esm({
29234
+ "lib/document/z-order.ts"() {
29235
+ }
29236
+ });
29237
+
29238
+ // lib/editor/selection-drill.ts
29239
+ function selectAllTargets(doc2, pageId2, selection) {
29240
+ const parentId = (selection.length ? resolveVirtualNode2(doc2.nodes, selection[0])?.parentId : null) ?? pageId2;
29241
+ const parent = doc2.nodes[parentId] ?? doc2.nodes[pageId2];
29242
+ return (parent?.childIds ?? []).filter((id3) => selectable(doc2, id3));
29243
+ }
29244
+ var selectable;
29245
+ var init_selection_drill = __esm({
29246
+ "lib/editor/selection-drill.ts"() {
29247
+ init_scene_graph();
29248
+ selectable = (doc2, id3) => {
29249
+ const n = doc2.nodes[id3];
29250
+ return !!n && n.visible !== false && !n.locked;
29251
+ };
29252
+ }
29253
+ });
29254
+
29185
29255
  // lib/document/history-group.ts
29186
29256
  function withHistoryGroup(group2, fn) {
29187
29257
  if (!group2) return fn();
@@ -94515,6 +94585,7 @@ function hasMessage(key5) {
94515
94585
  var current2, loading, listeners, formats, asts;
94516
94586
  var init_runtime = __esm({
94517
94587
  "lib/i18n/runtime.ts"() {
94588
+ "use strict";
94518
94589
  init_intl_messageformat();
94519
94590
  init_icu_messageformat_parser();
94520
94591
  init_catalogs();
@@ -96217,6 +96288,7 @@ function repairDocumentPaints(doc2) {
96217
96288
  var broken;
96218
96289
  var init_paint_repair = __esm({
96219
96290
  "lib/document/paint-repair.ts"() {
96291
+ "use strict";
96220
96292
  init_shader_graph();
96221
96293
  broken = (p2) => {
96222
96294
  if (!p2 || typeof p2 !== "object") return false;
@@ -97390,7 +97462,6 @@ function selectionWorldBounds(nodes, ids2, scrollState) {
97390
97462
  }
97391
97463
  var init_selection_bounds = __esm({
97392
97464
  "lib/editor/selection-bounds.ts"() {
97393
- "use strict";
97394
97465
  init_scene_graph();
97395
97466
  init_transform();
97396
97467
  }
@@ -248031,7 +248102,6 @@ function repairCompositions(comps, nodes) {
248031
248102
  var isObj5, finite6, optFinite, isVec2, TIMELINE_COLOR_IDS, TIMELINE_COLORS, UNITS, ORDERS, PROP_KEYS, ANIMATOR_ID, MOTION_TYPES, TRANSITIONS, isFraction, MEDIA_HASH;
248032
248103
  var init_invariants = __esm({
248033
248104
  "lib/motion/invariants.ts"() {
248034
- "use strict";
248035
248105
  init_easing();
248036
248106
  init_properties();
248037
248107
  init_markers();
@@ -249103,6 +249173,11 @@ function openingMode(doc2) {
249103
249173
  };
249104
249174
  return moves3(first2.id) ? "ANIMATE" : "VIEW";
249105
249175
  }
249176
+ function fileOpeningMode(doc2, opts = {}) {
249177
+ const mode2 = openingMode(doc2);
249178
+ if (mode2 !== "VIEW") return mode2;
249179
+ return opts.shared && !opts.seenBefore ? "VIEW" : "DESIGN";
249180
+ }
249106
249181
  var KIND_PROFILES, kindProfile;
249107
249182
  var init_kinds = __esm({
249108
249183
  "lib/templates/kinds.ts"() {
@@ -254495,11 +254570,12 @@ function openTabPatch(s, tab) {
254495
254570
  }
254496
254571
  function createModeSlice(set4, get4) {
254497
254572
  return {
254498
- mode: "VIEW",
254573
+ // The editor starts ready to edit. Read only is for someone else's file on its first open (lib/client/cloud/sync.ts),
254574
+ // and a file of another kind picks its own mode when it opens (lib/templates/kinds.ts `fileOpeningMode`).
254575
+ mode: "DESIGN",
254499
254576
  viewFlags: { ...DEFAULT_VIEW_FLAGS },
254500
254577
  leftTab: "composition",
254501
- // Read only's own tab: the editor starts in it (the file it opens may then pick another mode).
254502
- rightTab: MODE_PROFILES.VIEW.rightTab,
254578
+ rightTab: MODE_PROFILES.DESIGN.rightTab,
254503
254579
  leftPanelOpen: true,
254504
254580
  rightPanelOpen: true,
254505
254581
  tabSides: loadTabSides(),
@@ -257163,7 +257239,6 @@ function followPeers(peers) {
257163
257239
  var PALETTE, usePresence, awareness, CURSOR_SEND_MS, VIEWPORT_SEND_MS, cursorTimer, pendingCursor, sentCursor, EMOTE_MS, lastFollowCamera;
257164
257240
  var init_presence = __esm({
257165
257241
  "lib/collab/presence.ts"() {
257166
- "use strict";
257167
257242
  init_esm();
257168
257243
  init_editor_store();
257169
257244
  init_status_announcements();
@@ -311677,10 +311752,31 @@ async function linkActive(link2) {
311677
311752
  activeLink = link2;
311678
311753
  await setCloudLink(link2);
311679
311754
  applyReadOnly(link2.role);
311755
+ firstOpenOfShared(link2);
311680
311756
  ensureCollab(link2);
311681
311757
  setStatus(liveStatus());
311682
311758
  void healMedia(link2);
311683
311759
  }
311760
+ function seenShared() {
311761
+ try {
311762
+ return new Set(JSON.parse(localStorage.getItem(SEEN_KEY) || "[]"));
311763
+ } catch {
311764
+ return /* @__PURE__ */ new Set();
311765
+ }
311766
+ }
311767
+ function firstOpenOfShared(link2) {
311768
+ if (link2.role === "owner" || link2.anonymous) return;
311769
+ const seen = seenShared();
311770
+ const first2 = !seen.has(link2.key);
311771
+ seen.add(link2.key);
311772
+ try {
311773
+ localStorage.setItem(SEEN_KEY, JSON.stringify([...seen].slice(-500)));
311774
+ } catch {
311775
+ }
311776
+ const st = useEditorStore.getState();
311777
+ if (st.document.id !== link2.docId || st.mode !== "DESIGN") return;
311778
+ if (fileOpeningMode(st.document, { shared: true, seenBefore: !first2 }) === "VIEW") st.setMode("VIEW");
311779
+ }
311684
311780
  function applyReadOnly(role) {
311685
311781
  readOnlyDoc = canEdit(role) ? null : useEditorStore.getState().document;
311686
311782
  }
@@ -311786,10 +311882,10 @@ function startCloudSync() {
311786
311882
  setStatus(liveStatus());
311787
311883
  });
311788
311884
  }
311789
- var status, readOnlyDoc, activeLink, statusListeners, notice, urlArmed, opening, syncStatus, canEdit, uploaded, MEDIA_UPLOAD_PARALLEL, pushTimer, pushing, dirty, pendingMedia, collab, collabSession, collabAnonymous, uploadedThumbs, thumbCheckedAt, THUMB_EVERY_MS, THUMB_MIN_GAP_MS, putThumbnail, openingFiles, mediaHealed, started2;
311885
+ var status, readOnlyDoc, activeLink, statusListeners, notice, urlArmed, opening, syncStatus, canEdit, uploaded, MEDIA_UPLOAD_PARALLEL, pushTimer, pushing, dirty, pendingMedia, collab, collabSession, collabAnonymous, uploadedThumbs, thumbCheckedAt, THUMB_EVERY_MS, THUMB_MIN_GAP_MS, putThumbnail, openingFiles, mediaHealed, SEEN_KEY, started2;
311790
311886
  var init_sync2 = __esm({
311791
311887
  "lib/client/cloud/sync.ts"() {
311792
- "use strict";
311888
+ init_kinds();
311793
311889
  init_paint_repair();
311794
311890
  init_migrate();
311795
311891
  init_view();
@@ -311839,6 +311935,7 @@ var init_sync2 = __esm({
311839
311935
  });
311840
311936
  openingFiles = /* @__PURE__ */ new Map();
311841
311937
  mediaHealed = /* @__PURE__ */ new Set();
311938
+ SEEN_KEY = "popcraft.sharedFilesOpened";
311842
311939
  started2 = false;
311843
311940
  if (typeof module !== "undefined") module.hot?.decline();
311844
311941
  }
@@ -311999,6 +312096,7 @@ async function dispatchShaped(key5, options) {
311999
312096
  var onViolation;
312000
312097
  var init_dispatch = __esm({
312001
312098
  "lib/commands/dispatch.ts"() {
312099
+ "use strict";
312002
312100
  init_errors();
312003
312101
  init_registry();
312004
312102
  init_confirm();
@@ -317615,7 +317713,6 @@ async function selectionReferenceImages(doc2, selection, opts = {}) {
317615
317713
  var FIT_QUALITIES, FIT_SCALES, blobToDataUrl;
317616
317714
  var init_reference_images = __esm({
317617
317715
  "lib/ai/reference-images.ts"() {
317618
- "use strict";
317619
317716
  init_export();
317620
317717
  init_selection_bounds();
317621
317718
  init_renderer_registry();
@@ -319394,6 +319491,7 @@ var nodeFind, nodeGet, nodeMeasure, docOutline, CREATABLE, nodeCreate, FORBIDDEN
319394
319491
  var init_node = __esm({
319395
319492
  "lib/commands/node.ts"() {
319396
319493
  "use strict";
319494
+ init_z_order();
319397
319495
  init_zod();
319398
319496
  init_limits();
319399
319497
  init_search();
@@ -320051,7 +320149,7 @@ var init_node = __esm({
320051
320149
  run: (args2, ctx2) => {
320052
320150
  const { doc: doc2, ids: ids2 } = resolveTargets(ctx2, args2.ids, "order");
320053
320151
  let next2 = doc2;
320054
- for (const id3 of ids2) next2 = moveNodeInZOrder(next2, id3, args2.direction);
320152
+ next2 = reorderSelection(next2, ids2, args2.direction);
320055
320153
  ctx2.commit(next2);
320056
320154
  return { summary: `Moved ${plural2(ids2.length, "layer")} ${args2.direction}`, data: { ids: ids2 } };
320057
320155
  }
@@ -328843,7 +328941,7 @@ var init_package = __esm({
328843
328941
  "packages/runtime/package.json"() {
328844
328942
  package_default = {
328845
328943
  name: "@popcraft/runtime",
328846
- version: "0.53.15",
328944
+ version: "0.53.17",
328847
328945
  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.",
328848
328946
  license: "MIT",
328849
328947
  homepage: "https://popcraft.app/docs/exporting/nextjs",
@@ -353509,6 +353607,7 @@ function exportsOf(source3) {
353509
353607
  var CODE_LIMITS, packageOf;
353510
353608
  var init_source2 = __esm({
353511
353609
  "lib/code/source.ts"() {
353610
+ "use strict";
353512
353611
  CODE_LIMITS = { modules: 100, sourceLength: 2e5, packages: 12 };
353513
353612
  packageOf = (spec) => spec.split("/").slice(0, spec.startsWith("@") ? 2 : 1).join("/");
353514
353613
  }
@@ -353551,6 +353650,7 @@ function compileModule(module2) {
353551
353650
  var import_sucrase, BUILT_IN, memo4;
353552
353651
  var init_compile2 = __esm({
353553
353652
  "lib/code/compile.ts"() {
353653
+ "use strict";
353554
353654
  import_sucrase = __toESM(require_dist2());
353555
353655
  init_source2();
353556
353656
  init_source2();
@@ -362608,6 +362708,7 @@ var init_delete_current_file = __esm({
362608
362708
  var storeOpsSeam;
362609
362709
  var init_seams = __esm({
362610
362710
  "lib/commands/seams.ts"() {
362711
+ "use strict";
362611
362712
  storeOpsSeam = (st) => ({
362612
362713
  booleanOperation: (op4) => st().booleanOperation(op4),
362613
362714
  flatten: () => st().flattenSelection(),
@@ -406883,6 +406984,7 @@ function registerBuiltinCommands() {
406883
406984
  var builtinCommands, uiOnlyCommands;
406884
406985
  var init_builtin4 = __esm({
406885
406986
  "lib/commands/builtin.ts"() {
406987
+ "use strict";
406886
406988
  init_registry();
406887
406989
  init_node();
406888
406990
  init_node();
@@ -408095,6 +408197,8 @@ function placeInstance(document2, mainComponentId, pageId2, x2, y) {
408095
408197
  var STICKY_PROP_KEYS, initialDocument, initialPageId, TABS_PREFS_KEY, isUnsavedPlaceholder, libraryDocs, markLibraryDocument, isPersistableDocument, resetLibraryDocuments, MAX_OPEN_NODES, sessionDocumentInLibrary, saveFailureNotified, saveTimeout, latestValue, isSaving, firstPendingAt, SAVE_IDLE_MS, SAVE_MAX_WAIT_MS, pendingSave, customIdbPersistStorage, readOnlyToldAt, useEditorStore, useSelection, useActiveTool, useCamera, useCurrentPageId, useDocument, glideToken, useMode;
408096
408198
  var init_editor_store = __esm({
408097
408199
  "lib/store/editor-store.ts"() {
408200
+ init_z_order();
408201
+ init_selection_drill();
408098
408202
  init_history_group();
408099
408203
  init_pixel_art();
408100
408204
  init_runtime();
@@ -408450,7 +408554,7 @@ var init_editor_store = __esm({
408450
408554
  cropEdit: null,
408451
408555
  imageEdit: null
408452
408556
  });
408453
- get4().setMode(openingMode(snap.document));
408557
+ get4().setMode(fileOpeningMode(snap.document));
408454
408558
  {
408455
408559
  const st = get4();
408456
408560
  const comp = st.mode === "ANIMATE" ? Object.values(openedDoc.compositions ?? {}).find((c2) => c2.clips?.length) : void 0;
@@ -409310,12 +409414,29 @@ var init_editor_store = __esm({
409310
409414
  const topLevelNodes = nodes.filter((n) => !n.parentId || !clipboardIds.has(n.parentId));
409311
409415
  const newNodes = { ...doc2.nodes };
409312
409416
  const updatedParents = /* @__PURE__ */ new Map();
409417
+ const PASTE_INTO = /* @__PURE__ */ new Set(["FRAME", "COMPONENT", "SECTION"]);
409418
+ const sel = state.selection.length === 1 ? doc2.nodes[state.selection[0]] : void 0;
409419
+ const into = sel && PASTE_INTO.has(sel.type) && !clipboardIds.has(sel.id) ? sel : void 0;
409420
+ const pageOf4 = (d, id3) => {
409421
+ let n = d.nodes[id3];
409422
+ for (let guard2 = 0; n && n.type !== "PAGE" && guard2 < 64; guard2++) n = n.parentId ? d.nodes[n.parentId] : void 0;
409423
+ return n?.id;
409424
+ };
409425
+ const parentFor = (n) => {
409426
+ if (into) return into.id;
409427
+ if (n.parentId && doc2.nodes[n.parentId] && doc2.nodes[n.parentId].type !== "PAGE" && pageOf4(doc2, n.parentId) === state.currentPageId) return n.parentId;
409428
+ return state.currentPageId;
409429
+ };
409313
409430
  nodes.forEach((n) => {
409314
409431
  const newNode = { ...n, id: idMap.get(n.id) };
409315
409432
  if (topLevelNodes.includes(n)) {
409316
409433
  newNode.x += offset.x;
409317
409434
  newNode.y += offset.y;
409318
- newNode.parentId = state.currentPageId;
409435
+ newNode.parentId = parentFor(n);
409436
+ if (into && n.parentId !== into.id && (newNode.x < 0 || newNode.y < 0 || newNode.x > into.width || newNode.y > into.height)) {
409437
+ newNode.x = (into.width - newNode.width) / 2;
409438
+ newNode.y = (into.height - newNode.height) / 2;
409439
+ }
409319
409440
  newSelection.push(newNode.id);
409320
409441
  } else {
409321
409442
  newNode.parentId = idMap.get(n.parentId);
@@ -409489,10 +409610,7 @@ var init_editor_store = __esm({
409489
409610
  })),
409490
409611
  selectAll: () => {
409491
409612
  const state = get4();
409492
- const page = state.document.nodes[state.currentPageId];
409493
- if (page) {
409494
- set4({ selection: [...page.childIds] });
409495
- }
409613
+ set4({ selection: selectAllTargets(state.document, state.currentPageId, state.selection) });
409496
409614
  },
409497
409615
  deselectAll: () => set4({ selection: [] }),
409498
409616
  toggleSelectionVisibility: () => {
@@ -410257,57 +410375,59 @@ var init_editor_store = __esm({
410257
410375
  }
410258
410376
  };
410259
410377
  }),
410260
- // Z-order actions
410261
- bringToFront: () => {
410378
+ // Z-order actions: the selection moves as a block, keeps its own order, and can be undone (lib/document/z-order.ts).
410379
+ bringToFront: () => get4().reorderSelectionZ("top"),
410380
+ sendToBack: () => get4().reorderSelectionZ("bottom"),
410381
+ bringForward: () => get4().reorderSelectionZ("up"),
410382
+ sendBackward: () => get4().reorderSelectionZ("down"),
410383
+ reorderSelectionZ: (dir) => {
410262
410384
  const state = get4();
410263
- state.selection.forEach((id3) => {
410264
- set4({ document: moveNodeInZOrder(get4().document, id3, "top") });
410265
- });
410266
- },
410267
- sendToBack: () => {
410268
- const state = get4();
410269
- state.selection.forEach((id3) => {
410270
- set4({ document: moveNodeInZOrder(get4().document, id3, "bottom") });
410271
- });
410272
- },
410273
- bringForward: () => {
410274
- const state = get4();
410275
- state.selection.forEach((id3) => {
410276
- set4({ document: moveNodeInZOrder(get4().document, id3, "up") });
410277
- });
410278
- },
410279
- sendBackward: () => {
410280
- const state = get4();
410281
- state.selection.forEach((id3) => {
410282
- set4({ document: moveNodeInZOrder(get4().document, id3, "down") });
410283
- });
410385
+ const next2 = reorderSelection(state.document, state.selection, dir);
410386
+ if (next2 === state.document) return;
410387
+ const label3 = { top: "Bring to front", bottom: "Send to back", up: "Bring forward", down: "Send backward" }[dir];
410388
+ set4({ document: next2, history: pushCommand(state.history, createCommand("REORDER", label3, state.document, next2)) });
410284
410389
  },
410285
410390
  // Group actions
410286
410391
  groupSelection: () => {
410287
410392
  const state = get4();
410288
410393
  if (state.selection.length < 2) return;
410289
410394
  const documentBefore = state.document;
410395
+ let base = state.document;
410396
+ const order2 = /* @__PURE__ */ new Map();
410397
+ const walk4 = (id3) => {
410398
+ order2.set(id3, order2.size);
410399
+ for (const c2 of base.nodes[id3]?.childIds ?? []) walk4(c2);
410400
+ };
410401
+ walk4(state.currentPageId);
410402
+ const topmost = [...state.selection].sort((x2, y) => (order2.get(y) ?? 0) - (order2.get(x2) ?? 0))[0];
410403
+ const target2 = base.nodes[topmost]?.parentId ?? state.currentPageId;
410404
+ for (const id3 of state.selection) {
410405
+ const n = base.nodes[id3];
410406
+ if (!n || n.parentId === target2) continue;
410407
+ const placed2 = placementUnder(base, id3, target2);
410408
+ if (placed2) base = updateNode(base, id3, placed2);
410409
+ base = reparentNode(base, id3, target2);
410410
+ }
410290
410411
  let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
410291
410412
  state.selection.forEach((id3) => {
410292
- const n = state.document.nodes[id3];
410413
+ const n = base.nodes[id3];
410293
410414
  if (!n) return;
410294
410415
  minX = Math.min(minX, n.x);
410295
410416
  minY = Math.min(minY, n.y);
410296
410417
  maxX = Math.max(maxX, n.x + n.width);
410297
410418
  maxY = Math.max(maxY, n.y + n.height);
410298
410419
  });
410299
- const firstNode = state.document.nodes[state.selection[0]];
410300
- const parentId = firstNode?.parentId ?? state.currentPageId;
410420
+ const parentId = target2;
410301
410421
  const group2 = createGroup([]);
410302
410422
  group2.x = minX;
410303
410423
  group2.y = minY;
410304
410424
  group2.width = maxX - minX;
410305
410425
  group2.height = maxY - minY;
410306
410426
  group2.name = "Group";
410307
- const siblings = state.document.nodes[parentId]?.childIds ?? [];
410427
+ const siblings = base.nodes[parentId]?.childIds ?? [];
410308
410428
  const ordered2 = [...state.selection].sort((a, b) => siblings.indexOf(a) - siblings.indexOf(b));
410309
410429
  const top = Math.max(...ordered2.map((id3) => siblings.indexOf(id3)));
410310
- let doc2 = addNode(state.document, group2, parentId);
410430
+ let doc2 = addNode(base, group2, parentId);
410311
410431
  if (top >= 0) doc2 = reparentNode(doc2, group2.id, parentId, top + 1);
410312
410432
  ordered2.forEach((id3) => {
410313
410433
  doc2 = reparentNode(doc2, id3, group2.id);
@@ -410339,8 +410459,9 @@ var init_editor_store = __esm({
410339
410459
  return;
410340
410460
  }
410341
410461
  const parentId = node2.parentId ?? state.currentPageId;
410342
- node2.childIds.forEach((childId) => {
410343
- doc2 = reparentNode(doc2, childId, parentId);
410462
+ const slot2 = doc2.nodes[parentId]?.childIds.indexOf(id3) ?? -1;
410463
+ node2.childIds.forEach((childId, i2) => {
410464
+ doc2 = reparentNode(doc2, childId, parentId, slot2 >= 0 ? slot2 + i2 : void 0);
410344
410465
  const child = doc2.nodes[childId];
410345
410466
  if (child) {
410346
410467
  doc2.nodes[childId] = {
@@ -414448,7 +414569,7 @@ init_resources();
414448
414569
  init_desktop();
414449
414570
  init_hypery();
414450
414571
  import { createInterface } from "node:readline";
414451
- var VERSION2 = "0.53.15";
414572
+ var VERSION2 = "0.53.17";
414452
414573
  var HELP = `popcraft ${VERSION2} \u2014 the PopCraft command line
414453
414574
 
414454
414575
  Files (headless, on .popcraft files):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@popcraft/cli",
3
- "version": "0.53.15",
3
+ "version": "0.53.17",
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.15"
37
+ "@popcraft/kit": "0.53.17"
38
38
  },
39
39
  "scripts": {
40
40
  "build": "node build.mjs",