@neta-art/cohub-cli 10.6.0 → 10.8.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 (37) hide show
  1. package/README.md +8 -5
  2. package/dist/board-kernel.js +207 -119
  3. package/dist/commands/boards/examples.js +16 -16
  4. package/dist/commands/boards.js +1 -1
  5. package/dist/commands/generations.js +23 -2
  6. package/dist/commands/runtime.js +3 -14
  7. package/dist/runtime/harnesses/chained-transcript.d.ts +24 -0
  8. package/dist/runtime/harnesses/chained-transcript.js +62 -0
  9. package/dist/runtime/harnesses/claude-transcript.d.ts +8 -0
  10. package/dist/runtime/harnesses/claude-transcript.js +138 -0
  11. package/dist/runtime/harnesses/claude.js +79 -2
  12. package/dist/runtime/harnesses/codex.js +1 -1
  13. package/dist/runtime/harnesses/cursor-transcript.d.ts +37 -0
  14. package/dist/runtime/harnesses/cursor-transcript.js +183 -0
  15. package/dist/runtime/harnesses/cursor.d.ts +24 -0
  16. package/dist/runtime/harnesses/cursor.js +620 -0
  17. package/dist/runtime/harnesses/index.d.ts +1 -3
  18. package/dist/runtime/harnesses/index.js +4 -10
  19. package/dist/runtime/harnesses/pi.js +1 -1
  20. package/dist/runtime/harnesses/stream-json.d.ts +7 -1
  21. package/dist/runtime/harnesses/stream-json.js +35 -12
  22. package/dist/runtime/harnesses/types.d.ts +10 -5
  23. package/dist/runtime/harnesses/workbuddy-transcript.d.ts +8 -0
  24. package/dist/runtime/harnesses/workbuddy-transcript.js +127 -0
  25. package/dist/runtime/harnesses/workbuddy.d.ts +1 -1
  26. package/dist/runtime/harnesses/workbuddy.js +31 -7
  27. package/dist/runtime/json-rpc.d.ts +2 -0
  28. package/dist/runtime/json-rpc.js +9 -0
  29. package/dist/runtime/native/attach.d.ts +1 -1
  30. package/dist/runtime/native/attach.js +1 -4
  31. package/dist/runtime/native/execution.js +14 -3
  32. package/dist/runtime/native/ingest.d.ts +14 -0
  33. package/dist/runtime/native/ingest.js +51 -5
  34. package/dist/runtime/native/sessions.js +6 -1
  35. package/dist/runtime/native/transcript.d.ts +19 -0
  36. package/dist/runtime/native/transcript.js +33 -2
  37. package/package.json +3 -3
@@ -5650,6 +5650,51 @@ function json(params) {
5650
5650
  return jsonSchema;
5651
5651
  }
5652
5652
  const BOARD_ARROW_STROKE_SIZE = 2.5;
5653
+ const BOARD_DEFAULT_ITEM_SIZE$1 = {
5654
+ width: 240,
5655
+ height: 160
5656
+ };
5657
+ const BOARD_DEFAULT_SIZES$1 = {
5658
+ frame: {
5659
+ width: 480,
5660
+ height: 320
5661
+ },
5662
+ shape: {
5663
+ width: 200,
5664
+ height: 140
5665
+ },
5666
+ image: {
5667
+ width: 480,
5668
+ height: 270
5669
+ },
5670
+ video: {
5671
+ width: 480,
5672
+ height: 270
5673
+ },
5674
+ audio: {
5675
+ width: 320,
5676
+ height: 112
5677
+ },
5678
+ file: {
5679
+ width: 260,
5680
+ height: 132
5681
+ },
5682
+ task: {
5683
+ width: 480,
5684
+ height: 270
5685
+ },
5686
+ effect: {
5687
+ width: 240,
5688
+ height: 240
5689
+ },
5690
+ custom: {
5691
+ width: 480,
5692
+ height: 320
5693
+ }
5694
+ };
5695
+ function boardDefaultSize(type) {
5696
+ return { ...Object.hasOwn(BOARD_DEFAULT_SIZES$1, type) ? BOARD_DEFAULT_SIZES$1[type] : BOARD_DEFAULT_ITEM_SIZE$1 };
5697
+ }
5653
5698
  const BOARD_FONT_STACK = "\"Geist\", system-ui, -apple-system, \"Noto Sans CJK SC\", \"Noto Sans SC\", \"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans Math\", \"Noto Sans Symbols 2\", \"DejaVu Sans\", \"FreeSans\", \"FreeSerif\", sans-serif";
5654
5699
  const BOARD_MONO_FONT_STACK = "\"Geist Mono\", \"Fira Code\", ui-monospace, \"Noto Sans Mono CJK SC\", \"Noto Sans Math\", \"DejaVu Sans\", \"FreeSans\", \"FreeSerif\", monospace";
5655
5700
  //#endregion
@@ -5827,12 +5872,9 @@ const itemEnvelope$1 = {
5827
5872
  locked: boolean().optional(),
5828
5873
  metadata: record(string(), unknown()).optional()
5829
5874
  };
5830
- const boxed$1 = (width, height) => ({
5875
+ const boxed$1 = (size) => ({
5831
5876
  ...itemEnvelope$1,
5832
- size: BoardSizeSchema$1.default({
5833
- width,
5834
- height
5835
- })
5877
+ size: BoardSizeSchema$1.default({ ...size })
5836
5878
  });
5837
5879
  const unsized$1 = { ...itemEnvelope$1 };
5838
5880
  const fontSize$1 = finite$1.min(2).max(512);
@@ -5850,7 +5892,7 @@ const BOARD_SHAPE_GEOMETRIES$1 = [
5850
5892
  "path"
5851
5893
  ];
5852
5894
  const BoardFrameItemSchema$1 = object({
5853
- ...boxed$1(480, 320),
5895
+ ...boxed$1(BOARD_DEFAULT_SIZES$1.frame),
5854
5896
  type: literal("frame"),
5855
5897
  props: object({
5856
5898
  label: string().max(280).default(""),
@@ -5874,7 +5916,7 @@ const BoardTextItemSchema$1 = object({
5874
5916
  }).strict().prefault({})
5875
5917
  }).strict();
5876
5918
  const BoardShapeItemSchema$1 = object({
5877
- ...boxed$1(240, 160),
5919
+ ...boxed$1(BOARD_DEFAULT_SIZES$1.shape),
5878
5920
  type: literal("shape"),
5879
5921
  props: object({
5880
5922
  geometry: _enum(BOARD_SHAPE_GEOMETRIES$1).default("rectangle"),
@@ -5972,7 +6014,7 @@ const BoardCropSchema$1 = object({
5972
6014
  h: ratio$1
5973
6015
  }).strict().describe("Region shown, as fractions of the image. Without it the whole image fits inside size.");
5974
6016
  const BoardImageItemSchema$1 = object({
5975
- ...boxed$1(640, 360),
6017
+ ...boxed$1(BOARD_DEFAULT_SIZES$1.image),
5976
6018
  type: literal("image"),
5977
6019
  props: object({
5978
6020
  ...mediaProps$1,
@@ -5980,17 +6022,17 @@ const BoardImageItemSchema$1 = object({
5980
6022
  }).strict()
5981
6023
  }).strict();
5982
6024
  const BoardVideoItemSchema$1 = object({
5983
- ...boxed$1(640, 360),
6025
+ ...boxed$1(BOARD_DEFAULT_SIZES$1.video),
5984
6026
  type: literal("video"),
5985
6027
  props: object(timedFileProps$1).strict()
5986
6028
  }).strict();
5987
6029
  const BoardAudioItemSchema$1 = object({
5988
- ...boxed$1(480, 96),
6030
+ ...boxed$1(BOARD_DEFAULT_SIZES$1.audio),
5989
6031
  type: literal("audio"),
5990
6032
  props: object(timedFileProps$1).strict()
5991
6033
  }).strict();
5992
6034
  const BoardFileItemSchema$1 = object({
5993
- ...boxed$1(360, 220),
6035
+ ...boxed$1(BOARD_DEFAULT_SIZES$1.file),
5994
6036
  type: literal("file"),
5995
6037
  props: object(fileProps$1).strict()
5996
6038
  }).strict();
@@ -6047,7 +6089,7 @@ const BoardTaskSnapshotSchema$1 = object({
6047
6089
  updatedAt: string().optional()
6048
6090
  }).strict();
6049
6091
  const BoardTaskItemSchema$1 = object({
6050
- ...boxed$1(420, 240),
6092
+ ...boxed$1(BOARD_DEFAULT_SIZES$1.task),
6051
6093
  type: literal("task"),
6052
6094
  props: object({
6053
6095
  taskRunId: string().min(1).max(160).describe("The generation run shown; the server keeps the card's status and results up to date."),
@@ -6062,7 +6104,7 @@ const BOARD_EFFECT_KINDS$1 = [
6062
6104
  "glow"
6063
6105
  ];
6064
6106
  const BoardEffectItemSchema$1 = object({
6065
- ...boxed$1(240, 240),
6107
+ ...boxed$1(BOARD_DEFAULT_SIZES$1.effect),
6066
6108
  type: literal("effect"),
6067
6109
  props: object({
6068
6110
  kind: _enum(BOARD_EFFECT_KINDS$1),
@@ -6079,18 +6121,14 @@ const BoardEffectItemSchema$1 = object({
6079
6121
  }).strict()
6080
6122
  }).strict();
6081
6123
  const BoardCustomItemSchema$1 = object({
6082
- ...boxed$1(480, 320),
6124
+ ...boxed$1(BOARD_DEFAULT_SIZES$1.custom),
6083
6125
  type: literal("custom"),
6084
6126
  script: BoardScriptSchema$1,
6085
6127
  props: object({}).strict().default({})
6086
6128
  }).strict();
6087
6129
  const BOARD_EXTENSION_TYPE_PATTERN$1 = /^[a-z][a-z0-9]*(?:\.[a-z0-9-]+)+$/;
6088
6130
  const BoardExtensionItemSchema$1 = object({
6089
- ...itemEnvelope$1,
6090
- size: BoardSizeSchema$1.default({
6091
- width: 240,
6092
- height: 160
6093
- }),
6131
+ ...boxed$1(BOARD_DEFAULT_ITEM_SIZE$1),
6094
6132
  type: string().regex(BOARD_EXTENSION_TYPE_PATTERN$1),
6095
6133
  props: record(string(), unknown()).default({})
6096
6134
  }).strict();
@@ -6540,8 +6578,7 @@ function createBoardLayout(initialLookup, dependents) {
6540
6578
  } else box = {
6541
6579
  x: 0,
6542
6580
  y: 0,
6543
- width: 240,
6544
- height: 160
6581
+ ...boardDefaultSize(item.type)
6545
6582
  };
6546
6583
  boxes.set(id, box);
6547
6584
  return box;
@@ -27490,9 +27527,14 @@ function fitTextToWidth(text, value, width) {
27490
27527
  }
27491
27528
  //#endregion
27492
27529
  //#region ../sdk/src/board/render/text-resolution.ts
27493
- const MAX_BOARD_RESOLUTION = 2;
27494
- function getBoardResolution() {
27495
- return Math.min(globalThis.devicePixelRatio || 1, MAX_BOARD_RESOLUTION);
27530
+ const MAX_BOARD_RESOLUTION = 3;
27531
+ const MAX_BOARD_PIXELS = 8e6;
27532
+ const MAX_TEXT_RESOLUTION = 6;
27533
+ function getBoardResolution(size, devicePixelRatio = globalThis.devicePixelRatio) {
27534
+ const density = Number.isFinite(devicePixelRatio) && devicePixelRatio > 0 ? devicePixelRatio : 1;
27535
+ const pixels = size ? size.width * size.height : 0;
27536
+ const budget = pixels > 0 ? Math.sqrt(MAX_BOARD_PIXELS / pixels) : MAX_BOARD_RESOLUTION;
27537
+ return Math.min(density, MAX_BOARD_RESOLUTION, budget);
27496
27538
  }
27497
27539
  /**
27498
27540
  * Zoom buckets for text re-rasterisation. Pixi Text is a bitmap: at high zoom it
@@ -27518,12 +27560,12 @@ function boardCardDetailed(zoom) {
27518
27560
  /** Effective text resolution for a given camera zoom. */
27519
27561
  function textResolutionForZoom(zoom) {
27520
27562
  const bucket = textZoomBucket(zoom);
27521
- return Math.min(getBoardResolution() * Math.max(1, bucket), 6);
27563
+ return Math.min(getBoardResolution() * Math.max(1, bucket), MAX_TEXT_RESOLUTION);
27522
27564
  }
27523
27565
  /** Update a Pixi text texture only when zoom crosses a resolution bucket. */
27524
27566
  function syncTextResolution(text, state, zoom) {
27525
27567
  const resolution = textResolutionForZoom(zoom);
27526
- if (resolution === state.resolution) return;
27568
+ if (resolution === state.resolution && resolution === text.resolution) return;
27527
27569
  text.resolution = resolution;
27528
27570
  state.resolution = resolution;
27529
27571
  }
@@ -27963,6 +28005,19 @@ function traceCardOutline(graphics, rect, style, grow = 0) {
27963
28005
  const radius = Math.min(Math.max(0, style.radius + grow), width / 2, height / 2);
27964
28006
  return radius > 0 ? graphics.roundRect(x, y, width, height, radius) : graphics.rect(x, y, width, height);
27965
28007
  }
28008
+ function fillCardPicture(graphics, texture, picture, style, crop) {
28009
+ const sampling = texture.source.style;
28010
+ if (sampling.addressMode !== "mirror-repeat") {
28011
+ sampling.addressMode = "mirror-repeat";
28012
+ sampling.update();
28013
+ }
28014
+ const matrix = crop ? new Matrix(1 / crop.w, 0, 0, 1 / crop.h, -crop.x / crop.w, -crop.y / crop.h) : void 0;
28015
+ return traceCardOutline(graphics, picture, style).fill({
28016
+ texture,
28017
+ textureSpace: "local",
28018
+ ...matrix ? { matrix } : {}
28019
+ });
28020
+ }
27966
28021
  function tracePixelRect(graphics, x, y, width, height, step) {
27967
28022
  const s = Math.min(step, width / 4, height / 4);
27968
28023
  if (s <= 0) return graphics.rect(x, y, width, height);
@@ -28056,13 +28111,10 @@ function cardElevation(context, id) {
28056
28111
  }
28057
28112
  //#endregion
28058
28113
  //#region ../sdk/src/board/render/renderers/base-card-renderer.ts
28059
- const TEXT_OPTIONS = {
28060
- resolution: getBoardResolution(),
28061
- roundPixels: true
28062
- };
28063
28114
  function createLabel(text, style) {
28064
28115
  return new Text({
28065
- ...TEXT_OPTIONS,
28116
+ resolution: getBoardResolution(),
28117
+ roundPixels: true,
28066
28118
  text,
28067
28119
  style: {
28068
28120
  fontFamily: BOARD_FONT_STACK,
@@ -28301,6 +28353,9 @@ const audioCardRenderer = {
28301
28353
  update: (container, item, context) => {
28302
28354
  if (item.type === "audio") sync$13(container, item, context);
28303
28355
  },
28356
+ resolution: (container, item, context) => {
28357
+ if (item.type === "audio") sync$13(container, item, context);
28358
+ },
28304
28359
  renderFar: (graphics, item, context) => {
28305
28360
  drawFarPlate(graphics, item.frame, {
28306
28361
  fill: context.palette.surface,
@@ -28349,7 +28404,7 @@ function sync$12(container, item, context) {
28349
28404
  const elevation = cardElevation(context, item.id);
28350
28405
  const sig = [
28351
28406
  key ?? "",
28352
- texture ? `${texture.width}x${texture.height}` : "none",
28407
+ texture?.uid ?? "none",
28353
28408
  failed,
28354
28409
  width,
28355
28410
  height,
@@ -28418,6 +28473,9 @@ const modelCardRenderer = {
28418
28473
  update: (container, item, context) => {
28419
28474
  if (item.type === "file") sync$12(container, item, context);
28420
28475
  },
28476
+ resolution: (container, item, context) => {
28477
+ if (item.type === "file") sync$12(container, item, context);
28478
+ },
28421
28479
  zoom: (container, zoom) => {
28422
28480
  const tag = partsByContainer$12.get(container)?.tag;
28423
28481
  if (tag) zoomCardTag(tag, zoom);
@@ -28558,6 +28616,10 @@ const arrowCardRenderer = {
28558
28616
  update: (container, item, context) => {
28559
28617
  if (item.type === "arrow") sync$11(container, item, context);
28560
28618
  },
28619
+ resolution: (container, _item, context) => {
28620
+ const parts = partsByContainer$11.get(container);
28621
+ if (parts) syncTextResolution(parts.label, parts, context.zoom);
28622
+ },
28561
28623
  renderFar: (graphics, item, context) => {
28562
28624
  if (item.type !== "arrow") return;
28563
28625
  const arrow = item;
@@ -28967,7 +29029,7 @@ function sync$8(container, item, context) {
28967
29029
  height,
28968
29030
  detail,
28969
29031
  elevation,
28970
- texture ? `${texture.width}x${texture.height}` : "none",
29032
+ texture?.uid ?? "none",
28971
29033
  coverFailed,
28972
29034
  fileState,
28973
29035
  kind,
@@ -29152,6 +29214,9 @@ const fileCardRenderer = {
29152
29214
  update: (container, item, context) => {
29153
29215
  if (item.type === "file") sync$8(container, item, context);
29154
29216
  },
29217
+ resolution: (container, item, context) => {
29218
+ if (item.type === "file") sync$8(container, item, context);
29219
+ },
29155
29220
  zoom: (container, zoom) => {
29156
29221
  const tag = partsByContainer$8.get(container)?.tag;
29157
29222
  if (tag) zoomCardTag(tag, zoom);
@@ -29264,6 +29329,10 @@ const frameCardRenderer = {
29264
29329
  update: (container, item, context) => {
29265
29330
  if (item.type === "frame") sync$7(container, item, context);
29266
29331
  },
29332
+ resolution: (container, _item, context) => {
29333
+ const parts = partsByContainer$7.get(container);
29334
+ if (parts) syncTextResolution(parts.label, parts, context.zoom);
29335
+ },
29267
29336
  renderFar: (graphics, item, context) => {
29268
29337
  if (item.type !== "frame" || item.props.decoration === "none") return;
29269
29338
  drawFarPlate(graphics, item.frame, {
@@ -29470,6 +29539,10 @@ const shapeCardRenderer = {
29470
29539
  update: (container, item, context) => {
29471
29540
  if (item.type === "shape") sync$6(container, item, context);
29472
29541
  },
29542
+ resolution: (container, _item, context) => {
29543
+ const parts = partsByContainer$6.get(container);
29544
+ if (parts) syncTextResolution(parts.label, parts, context.zoom);
29545
+ },
29473
29546
  renderFar: (graphics, item, context) => {
29474
29547
  if (item.type !== "shape") return;
29475
29548
  drawFarPlate(graphics, item.frame, {
@@ -29495,9 +29568,9 @@ function sync$5(container, item, context) {
29495
29568
  parts.id = item.id;
29496
29569
  }
29497
29570
  positionShell(parts.root, item);
29571
+ syncTextResolution(parts.label, parts.label, context.zoom);
29498
29572
  const { width, height } = item.frame;
29499
- const resolution = Math.min(4, Math.max(.25, context.zoom * getBoardResolution()));
29500
- const texture = context.scripts?.frame(item, context.time, resolution) ?? null;
29573
+ const texture = context.scripts?.frame(item, context.time) ?? null;
29501
29574
  const error = context.scripts?.error(item.id) ?? null;
29502
29575
  parts.sprite.visible = Boolean(texture);
29503
29576
  const display = texture ?? Texture.EMPTY;
@@ -29562,6 +29635,10 @@ const customCardRenderer = {
29562
29635
  update: (container, item, context) => {
29563
29636
  if (item.type === "custom") sync$5(container, item, context);
29564
29637
  },
29638
+ resolution: (container, _item, context) => {
29639
+ const parts = partsByContainer$5.get(container);
29640
+ if (parts) syncTextResolution(parts.label, parts.label, context.zoom);
29641
+ },
29565
29642
  renderFar: (graphics, item, context) => {
29566
29643
  drawFarPlate(graphics, item.frame, {
29567
29644
  fill: context.palette.muted,
@@ -29589,28 +29666,6 @@ function cropRect(crop) {
29589
29666
  h
29590
29667
  } : null;
29591
29668
  }
29592
- function showTexture(parts, texture, crop) {
29593
- const rect = texture ? cropRect(crop) : null;
29594
- const key = rect ? `${rect.x}|${rect.y}|${rect.w}|${rect.h}` : "";
29595
- const previous = parts.cropped;
29596
- const reusable = previous && parts.cropSource === texture && parts.cropKey === key;
29597
- if (texture && rect && !reusable) {
29598
- const { frame } = texture;
29599
- const width = Math.max(1, frame.width * rect.w);
29600
- const height = Math.max(1, frame.height * rect.h);
29601
- const x = frame.x + Math.min(frame.width * rect.x, frame.width - width);
29602
- const y = frame.y + Math.min(frame.height * rect.y, frame.height - height);
29603
- parts.cropped = new Texture({
29604
- source: texture.source,
29605
- frame: new Rectangle(x, y, width, height)
29606
- });
29607
- } else if (!rect) parts.cropped = null;
29608
- parts.cropSource = rect ? texture : null;
29609
- parts.cropKey = key;
29610
- const display = parts.cropped ?? texture ?? Texture.EMPTY;
29611
- if (parts.sprite.texture !== display) parts.sprite.texture = display;
29612
- if (previous && previous !== parts.cropped) previous.destroy(false);
29613
- }
29614
29669
  const PRINT_MARGIN = 6;
29615
29670
  function sync$4(container, item, context) {
29616
29671
  const parts = partsByContainer$4.get(container);
@@ -29625,7 +29680,7 @@ function sync$4(container, item, context) {
29625
29680
  key ?? "",
29626
29681
  width,
29627
29682
  height,
29628
- texture ? `${texture.width}x${texture.height}` : "none",
29683
+ texture?.uid ?? "none",
29629
29684
  JSON.stringify(item.props.crop ?? null),
29630
29685
  failed,
29631
29686
  elevation,
@@ -29633,8 +29688,7 @@ function sync$4(container, item, context) {
29633
29688
  ].join("|");
29634
29689
  if (sig === parts.sig) return;
29635
29690
  parts.sig = sig;
29636
- showTexture(parts, texture, item.props.crop);
29637
- const display = parts.sprite.texture;
29691
+ const crop = cropRect(item.props.crop);
29638
29692
  const framed = context.style.media === "framed";
29639
29693
  const margin = framed ? Math.min(PRINT_MARGIN, width / 8, height / 8) : 0;
29640
29694
  const area = {
@@ -29643,7 +29697,7 @@ function sync$4(container, item, context) {
29643
29697
  width: width - margin * 2,
29644
29698
  height: height - margin * 2
29645
29699
  };
29646
- const fitted = texture ? containRect(area.width, area.height, display.width, display.height) : {
29700
+ const fitted = texture ? containRect(area.width, area.height, texture.width * (crop?.w ?? 1), texture.height * (crop?.h ?? 1)) : {
29647
29701
  ...area,
29648
29702
  x: 0,
29649
29703
  y: 0
@@ -29660,16 +29714,11 @@ function sync$4(container, item, context) {
29660
29714
  width: picture.width + margin * 2,
29661
29715
  height: picture.height + margin * 2
29662
29716
  } : picture;
29663
- parts.sprite.visible = Boolean(texture);
29664
- if (texture) {
29665
- parts.sprite.position.set(picture.x, picture.y);
29666
- parts.sprite.width = picture.width;
29667
- parts.sprite.height = picture.height;
29668
- }
29669
- traceCardOutline(parts.mask.clear(), picture, framed ? {
29717
+ parts.picture.clear();
29718
+ if (texture) fillCardPicture(parts.picture, texture, picture, framed ? {
29670
29719
  corner: "round",
29671
29720
  radius: 0
29672
- } : context.style).fill({ color: 16777215 });
29721
+ } : context.style, crop);
29673
29722
  parts.placeholder.clear();
29674
29723
  if (texture && !framed) return;
29675
29724
  drawCardSurface(parts.placeholder, card, context.style, {
@@ -29696,20 +29745,14 @@ const imageCardRenderer = {
29696
29745
  canRender: (item) => item.type === "image",
29697
29746
  create: (item, context) => {
29698
29747
  const root = new Container();
29699
- const sprite = new Sprite(Texture.EMPTY);
29700
29748
  const placeholder = new Graphics();
29701
- const mask = new Graphics();
29702
- root.addChild(placeholder, sprite, mask);
29703
- sprite.mask = mask;
29749
+ const picture = new Graphics();
29750
+ root.addChild(placeholder, picture);
29704
29751
  partsByContainer$4.set(root, {
29705
29752
  root,
29706
- sprite,
29707
29753
  placeholder,
29708
- mask,
29709
- sig: "",
29710
- cropped: null,
29711
- cropSource: null,
29712
- cropKey: ""
29754
+ picture,
29755
+ sig: ""
29713
29756
  });
29714
29757
  if (item.type === "image") sync$4(root, item, context);
29715
29758
  return root;
@@ -29724,9 +29767,7 @@ const imageCardRenderer = {
29724
29767
  });
29725
29768
  },
29726
29769
  destroy: (container) => {
29727
- const parts = partsByContainer$4.get(container);
29728
- parts?.root.destroy({ children: true });
29729
- parts?.cropped?.destroy(false);
29770
+ partsByContainer$4.get(container)?.root.destroy({ children: true });
29730
29771
  partsByContainer$4.delete(container);
29731
29772
  }
29732
29773
  };
@@ -29982,7 +30023,7 @@ function sync$3(container, item, context) {
29982
30023
  if (key !== parts.assetKey) {
29983
30024
  if (parts.assetKey) context.releaseTexture(parts.assetKey);
29984
30025
  parts.assetKey = key;
29985
- if (key) context.acquireTexture(key);
30026
+ if (key) context.acquireTexture(key, item);
29986
30027
  }
29987
30028
  const texture = key ? context.getTexture(key) : null;
29988
30029
  const previewFailed = Boolean(key && !texture && context.hasError(key));
@@ -30055,7 +30096,7 @@ function sync$3(container, item, context) {
30055
30096
  artifact?.type ?? "none",
30056
30097
  artifact?.id ?? "none",
30057
30098
  item.props.taskRunId,
30058
- texture ? `${texture.width}x${texture.height}` : "none",
30099
+ texture?.uid ?? "none",
30059
30100
  context.themeKey
30060
30101
  ].join("|");
30061
30102
  if (visualSig !== parts.visualSig) {
@@ -30224,6 +30265,9 @@ const taskCardRenderer = {
30224
30265
  const parts = partsByContainer$3.get(container);
30225
30266
  return parts ? advance(parts, clock) : null;
30226
30267
  },
30268
+ resolution: (container, item, context) => {
30269
+ if (item.type === "task") sync$3(container, item, context);
30270
+ },
30227
30271
  zoom: (container, zoom) => {
30228
30272
  const tag = partsByContainer$3.get(container)?.tag;
30229
30273
  if (tag) zoomCardTag(tag, zoom);
@@ -30334,6 +30378,10 @@ const textCardRenderer = {
30334
30378
  update: (container, item, context) => {
30335
30379
  if (item.type === "text") sync$2(container, item, context);
30336
30380
  },
30381
+ resolution: (container, _item, context) => {
30382
+ const parts = partsByContainer$2.get(container);
30383
+ if (parts) syncTextResolution(parts.body, parts, context.zoom * Math.max(1, parts.body.scale.x));
30384
+ },
30337
30385
  renderFar: (graphics, item, context) => {
30338
30386
  if (item.type !== "text") return;
30339
30387
  drawFarPlate(graphics, item.frame, {
@@ -30426,6 +30474,10 @@ const unknownCardRenderer = {
30426
30474
  update: (container, item, context) => {
30427
30475
  sync$1(container, item, context);
30428
30476
  },
30477
+ resolution: (container, _item, context) => {
30478
+ const parts = partsByContainer$1.get(container);
30479
+ if (parts) syncTextResolution(parts.label, parts, context.zoom);
30480
+ },
30429
30481
  renderFar: (graphics, item, context) => {
30430
30482
  drawFarPlate(graphics, item.frame, {
30431
30483
  fill: context.palette.muted,
@@ -30463,7 +30515,7 @@ function sync(container, item, context) {
30463
30515
  const elevation = cardElevation(context, item.id);
30464
30516
  const sig = [
30465
30517
  key ?? "",
30466
- texture ? `${texture.width}x${texture.height}` : "none",
30518
+ texture?.uid ?? "none",
30467
30519
  width,
30468
30520
  height,
30469
30521
  elevation,
@@ -30493,17 +30545,18 @@ function sync(container, item, context) {
30493
30545
  elevation
30494
30546
  });
30495
30547
  if (framed) drawFilmRails(parts.plate, width, height, rail, context.palette.bg);
30496
- traceCardOutline(parts.mask.clear(), framed ? screen : rect, framed ? {
30497
- corner: "round",
30498
- radius: 1
30499
- } : context.style).fill({ color: 16777215 });
30500
- if (texture && parts.sprite.texture !== texture) parts.sprite.texture = texture;
30501
- parts.sprite.visible = Boolean(texture);
30548
+ parts.picture.clear();
30502
30549
  if (texture) {
30503
30550
  const fitted = containRect(screen.width, screen.height, texture.width, texture.height);
30504
- parts.sprite.position.set(screen.x + fitted.x, screen.y + fitted.y);
30505
- parts.sprite.width = fitted.width;
30506
- parts.sprite.height = fitted.height;
30551
+ const picture = {
30552
+ ...fitted,
30553
+ x: screen.x + fitted.x,
30554
+ y: screen.y + fitted.y
30555
+ };
30556
+ fillCardPicture(parts.picture, texture, picture, framed ? {
30557
+ corner: "round",
30558
+ radius: 1
30559
+ } : context.style);
30507
30560
  }
30508
30561
  parts.chrome.clear();
30509
30562
  if (boardCardDetailed(context.zoom)) drawMediaPlayKey(parts.chrome, screen.x + screen.width / 2, screen.y + screen.height / 2, Math.min(18, Math.min(screen.width, screen.height) * .16), context);
@@ -30528,17 +30581,14 @@ const videoCardRenderer = {
30528
30581
  create: (item, context) => {
30529
30582
  const root = new Container();
30530
30583
  const plate = new Graphics();
30531
- const sprite = new Sprite(Texture.EMPTY);
30532
- const mask = new Graphics();
30584
+ const picture = new Graphics();
30533
30585
  const chrome = new Graphics();
30534
30586
  const tag = createCardTag();
30535
- root.addChild(plate, sprite, mask, chrome, tag.root);
30536
- sprite.mask = mask;
30587
+ root.addChild(plate, picture, chrome, tag.root);
30537
30588
  partsByContainer.set(root, {
30538
30589
  root,
30539
30590
  plate,
30540
- sprite,
30541
- mask,
30591
+ picture,
30542
30592
  chrome,
30543
30593
  tag,
30544
30594
  sig: ""
@@ -30549,6 +30599,9 @@ const videoCardRenderer = {
30549
30599
  update: (container, item, context) => {
30550
30600
  if (item.type === "video") sync(container, item, context);
30551
30601
  },
30602
+ resolution: (container, item, context) => {
30603
+ if (item.type === "video") sync(container, item, context);
30604
+ },
30552
30605
  zoom: (container, zoom) => {
30553
30606
  const tag = partsByContainer.get(container)?.tag;
30554
30607
  if (tag) zoomCardTag(tag, zoom);
@@ -30603,6 +30656,48 @@ function createBoardCardRendererResolver(renderers = []) {
30603
30656
  }
30604
30657
  /** The built-in renderers alone. */
30605
30658
  const getBoardCardRenderer = createBoardCardRendererResolver();
30659
+ const BOARD_DEFAULT_ITEM_SIZE = {
30660
+ width: 240,
30661
+ height: 160
30662
+ };
30663
+ const BOARD_DEFAULT_SIZES = {
30664
+ frame: {
30665
+ width: 480,
30666
+ height: 320
30667
+ },
30668
+ shape: {
30669
+ width: 200,
30670
+ height: 140
30671
+ },
30672
+ image: {
30673
+ width: 480,
30674
+ height: 270
30675
+ },
30676
+ video: {
30677
+ width: 480,
30678
+ height: 270
30679
+ },
30680
+ audio: {
30681
+ width: 320,
30682
+ height: 112
30683
+ },
30684
+ file: {
30685
+ width: 260,
30686
+ height: 132
30687
+ },
30688
+ task: {
30689
+ width: 480,
30690
+ height: 270
30691
+ },
30692
+ effect: {
30693
+ width: 240,
30694
+ height: 240
30695
+ },
30696
+ custom: {
30697
+ width: 480,
30698
+ height: 320
30699
+ }
30700
+ };
30606
30701
  //#endregion
30607
30702
  //#region ../protocol/dist/board-url.js
30608
30703
  const BOARD_REMOTE_URL_MAX_LENGTH = 4096;
@@ -30778,12 +30873,9 @@ const itemEnvelope = {
30778
30873
  locked: boolean().optional(),
30779
30874
  metadata: record(string(), unknown()).optional()
30780
30875
  };
30781
- const boxed = (width, height) => ({
30876
+ const boxed = (size) => ({
30782
30877
  ...itemEnvelope,
30783
- size: BoardSizeSchema.default({
30784
- width,
30785
- height
30786
- })
30878
+ size: BoardSizeSchema.default({ ...size })
30787
30879
  });
30788
30880
  const unsized = { ...itemEnvelope };
30789
30881
  const fontSize = finite.min(2).max(512);
@@ -30801,7 +30893,7 @@ const BOARD_SHAPE_GEOMETRIES = [
30801
30893
  "path"
30802
30894
  ];
30803
30895
  object({
30804
- ...boxed(480, 320),
30896
+ ...boxed(BOARD_DEFAULT_SIZES.frame),
30805
30897
  type: literal("frame"),
30806
30898
  props: object({
30807
30899
  label: string().max(280).default(""),
@@ -30825,7 +30917,7 @@ object({
30825
30917
  }).strict().prefault({})
30826
30918
  }).strict();
30827
30919
  object({
30828
- ...boxed(240, 160),
30920
+ ...boxed(BOARD_DEFAULT_SIZES.shape),
30829
30921
  type: literal("shape"),
30830
30922
  props: object({
30831
30923
  geometry: _enum(BOARD_SHAPE_GEOMETRIES).default("rectangle"),
@@ -30923,7 +31015,7 @@ const BoardCropSchema = object({
30923
31015
  h: ratio
30924
31016
  }).strict().describe("Region shown, as fractions of the image. Without it the whole image fits inside size.");
30925
31017
  object({
30926
- ...boxed(640, 360),
31018
+ ...boxed(BOARD_DEFAULT_SIZES.image),
30927
31019
  type: literal("image"),
30928
31020
  props: object({
30929
31021
  ...mediaProps,
@@ -30931,17 +31023,17 @@ object({
30931
31023
  }).strict()
30932
31024
  }).strict();
30933
31025
  object({
30934
- ...boxed(640, 360),
31026
+ ...boxed(BOARD_DEFAULT_SIZES.video),
30935
31027
  type: literal("video"),
30936
31028
  props: object(timedFileProps).strict()
30937
31029
  }).strict();
30938
31030
  object({
30939
- ...boxed(480, 96),
31031
+ ...boxed(BOARD_DEFAULT_SIZES.audio),
30940
31032
  type: literal("audio"),
30941
31033
  props: object(timedFileProps).strict()
30942
31034
  }).strict();
30943
31035
  object({
30944
- ...boxed(360, 220),
31036
+ ...boxed(BOARD_DEFAULT_SIZES.file),
30945
31037
  type: literal("file"),
30946
31038
  props: object(fileProps).strict()
30947
31039
  }).strict();
@@ -30998,7 +31090,7 @@ const BoardTaskSnapshotSchema = object({
30998
31090
  updatedAt: string().optional()
30999
31091
  }).strict();
31000
31092
  object({
31001
- ...boxed(420, 240),
31093
+ ...boxed(BOARD_DEFAULT_SIZES.task),
31002
31094
  type: literal("task"),
31003
31095
  props: object({
31004
31096
  taskRunId: string().min(1).max(160).describe("The generation run shown; the server keeps the card's status and results up to date."),
@@ -31013,7 +31105,7 @@ const BOARD_EFFECT_KINDS = [
31013
31105
  "glow"
31014
31106
  ];
31015
31107
  object({
31016
- ...boxed(240, 240),
31108
+ ...boxed(BOARD_DEFAULT_SIZES.effect),
31017
31109
  type: literal("effect"),
31018
31110
  props: object({
31019
31111
  kind: _enum(BOARD_EFFECT_KINDS),
@@ -31030,18 +31122,14 @@ object({
31030
31122
  }).strict()
31031
31123
  }).strict();
31032
31124
  object({
31033
- ...boxed(480, 320),
31125
+ ...boxed(BOARD_DEFAULT_SIZES.custom),
31034
31126
  type: literal("custom"),
31035
31127
  script: BoardScriptSchema,
31036
31128
  props: object({}).strict().default({})
31037
31129
  }).strict();
31038
31130
  const BOARD_EXTENSION_TYPE_PATTERN = /^[a-z][a-z0-9]*(?:\.[a-z0-9-]+)+$/;
31039
31131
  object({
31040
- ...itemEnvelope,
31041
- size: BoardSizeSchema.default({
31042
- width: 240,
31043
- height: 160
31044
- }),
31132
+ ...boxed(BOARD_DEFAULT_ITEM_SIZE),
31045
31133
  type: string().regex(BOARD_EXTENSION_TYPE_PATTERN),
31046
31134
  props: record(string(), unknown()).default({})
31047
31135
  }).strict();