beplus-mcp 0.37.0 → 0.38.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.
package/README.md CHANGED
@@ -128,7 +128,7 @@ Falam com `/api/v1/canvas`. Montam e editam o fluxo e **não geram mídia**, com
128
128
  | `canvas_read_board` | Resumo compacto: nós (tipo, nome, posição, **tamanho**, campos principais), ligações, vínculo com o IA Lab. Sem mídia. O tamanho diz a origem: `medido` (o da tela) ou `gravado` (o piso). `node_ids` traz o `data` de alguns nós, com cada corte marcado (`path=…`). Cada cartão diz a aba (`aba=<id curto>` ou `aba=avulsos`) e o topo conta os cartões de cada aba; `aba` lê uma aba só (a seção, quem mora nela e só os fios que tocam neles; o fio que vai a outra aba sai marcado como externo). **Obrigatório antes de editar.** |
129
129
  | `canvas_read_node` | O `data` de um nó **sem corte**, em JSON, com tamanho total e sha256 para conferir e fazer diff; partes explícitas (`offset`) acima de `max_chars`. O cabeçalho traz o tamanho do cartão (`medido` com a hora da medida, ou `gravado`). Na Montagem, sem `path`, traz `data.timeline` (ou `data.sequence`, o legado, quando ainda não há timeline) e diz qual veio. Não conta como leitura para editar. |
130
130
  | `canvas_create_board` | Cria board vazio ou `template: "narration"` (Contexto, Narração, Roteiro e Locução ligados). |
131
- | `canvas_add_node` | Adiciona nó de um tipo do catálogo, com `label`, `data`, `size` e ligações de entrada/saída no mesmo passo. `aba` grava `data.abaId` e, sem `position`, o cartão nasce no fim do conteúdo da aba. |
131
+ | `canvas_add_node` | Adiciona nó de um tipo do catálogo, com `label`, `data`, `size` e ligações de entrada/saída no mesmo passo. `aba` grava `data.abaId` e, sem `position`, o cartão nasce no fim do conteúdo da aba. Texto livre (`label`) sem `size {w}` nasce na largura do tamanho do texto: título 2000, subtítulo 1200, corpo 320. |
132
132
  | `canvas_update_node` | Grava chaves do `data` (null apaga), renomeia (`label`), move (`position`) e muda a caixa (`size`). |
133
133
  | `canvas_update_nodes` | Vários nós num passo (position, size, label, data), em envelopes de até 64 KB com o relato de cada um. `layout_only: true` aceita só posição e `size {w, h}`, não pede leitura e não recusa por conflito (nesses campos vale quem grava por último). |
134
134
  | `canvas_arrange_rows` | Arruma nós em linhas (uma por versão ou por take) com o tamanho da tela e as larguras da convenção; grava só posição e tamanho. A sobreposição se confere só dentro da aba (`aba`, ou a dos nós arrumados). Veja abaixo. |
@@ -155,7 +155,7 @@ Concorrência: cada edição relê o board, vai num envelope só (um `seq`) e é
155
155
 
156
156
  Abas (AB9, desde a 0.37): cada aba do Canvas é um plano sem borda. O cartão guarda a aba em `data.abaId` (o id da seção da aba), e a posição só decide quando o campo falta: o centro dentro do retângulo gravado da seção (a primeira da barra), depois a aba a até 2.000 pontos, senão Avulsos. É a mesma regra do `tab-membership.ts` do Canvas (`src/canvas/tabs.ts`, commit 749919e6); `data.abaId` apontando para aba apagada ou arquivada manda o cartão para Avulsos. `canvas_add_node` e `canvas_upload_media` recebem `aba` (o id da seção, ou o começo único dele, o `aba=…` que a leitura mostra) e gravam o campo; sem `position`, o cartão nasce no fim do conteúdo da aba (abaixo do cartão mais baixo, 120 pontos de folga, alinhado à esquerda do conteúdo). `data.abaId` só aceita o id de uma aba viva (ou `null` para tirar o campo). O cadeado (`travada`) conta quem **mora** na aba, e não quem está dentro do retângulo: mover, redimensionar, trocar ou apagar a aba (`data.abaId`) de dois ou mais membros num pedido só é recusado, um por vez segue valendo; cartão novo, mover para dentro da aba travada e gravar o `data.abaId` da aba onde o cartão já mora (o carimbo em lote da migração) passam. Seção comum travada (sem `aba`) continua pela caixa inteira dentro da moldura.
157
157
 
158
- Tamanho do cartão: o `size` gravado é **piso**; o cartão cresce com o conteúdo (um Prompt de 340 de largura com o `!!ESTILO` resolvido vira uma coluna de 1.800). O Canvas grava o tamanho desenhado em `data.__measured = { w, h, at }` quando o cartão passa do piso; as leituras mostram esse (`medido`) ou o piso (`gravado`). É campo interno: não aparece como dado e nenhuma ferramenta grava nele. `size: {w, h}` muda a caixa; `size: "titulo" | "subtitulo" | "corpo"` é o tamanho do texto do Texto livre (`data.size` do nó `label`).
158
+ Tamanho do cartão: o `size` gravado é **piso**; o cartão cresce com o conteúdo (um Prompt de 340 de largura com o `!!ESTILO` resolvido vira uma coluna de 1.800). O Canvas grava o tamanho desenhado em `data.__measured = { w, h, at }` quando o cartão passa do piso; as leituras mostram esse (`medido`) ou o piso (`gravado`). É campo interno: não aparece como dado e nenhuma ferramenta grava nele. `size: {w, h}` muda a caixa; `size: "titulo" | "subtitulo" | "corpo"` é o tamanho do texto do Texto livre (`data.size` do nó `label`). Desde a 0.37.1, ao criar (`canvas_add_node`), o Texto livre sem `size {w}` nasce na largura do tamanho do texto, os mesmos números do Canvas: `titulo` 2000, `subtitulo` 1200, `corpo` 320 (o tamanho vem do `size` em texto ou do `data.size`; o `size` em texto vence). Um título de grupo não vira mais uma torre estreita de texto por cima dos cartões. `size {w}` vale o que veio (um lado só vale: com só `h`, a largura vem do tamanho do texto), e o que já existe não muda: `canvas_update_node` e `canvas_update_nodes` gravam só o que foi pedido.
159
159
 
160
160
  Menção (`!!` de Bloco, `##` de texto): gravar `{{var}}` no `template` do Prompt com `data.mentions = { var: { node, port } }` (o Bloco sai pela porta `text`) cria, no mesmo envelope, a ligação fina que o Canvas desenha no navegador (`viaMention`, id `mention:<origem>:<porta>><prompt>:<var>`, o mesmo dos dois lados). Tirar a var ou a menção tira a ligação. Porta já ligada à mão não ganha segunda ligação, e menção que fecharia ciclo não liga. As ligações das outras regras do conciliador (mídia `@@`, `prompt.refs → gerador.refs`, seções) o Canvas faz ao abrir o board.
161
161
 
package/dist/index.js CHANGED
@@ -22145,6 +22145,7 @@ async function buildImageBlocks(urls, cfg) {
22145
22145
 
22146
22146
  // src/schemas/enums.ts
22147
22147
  var IMAGE_MODELS = [
22148
+ "google/nano-banana-2.1",
22148
22149
  "google/nano-banana-2",
22149
22150
  "google/nano-banana-pro",
22150
22151
  "openai/gpt-image-2",
@@ -22237,7 +22238,7 @@ var VIDEO_ASPECT_RATIOS = [...ASPECT_RATIOS, "adaptive"];
22237
22238
  var IMAGE_RESOLUTIONS = ["1K", "2K", "4K"];
22238
22239
  var VIDEO_RESOLUTIONS = ["480p", "720p", "1080p", "4K"];
22239
22240
  var DEFAULTS = {
22240
- imageModel: "google/nano-banana-2",
22241
+ imageModel: "google/nano-banana-2.1",
22241
22242
  imageAspect: "1:1",
22242
22243
  imageResolution: "1K",
22243
22244
  videoModel: "bytedance/seedance-2.0-fast",
@@ -22283,7 +22284,7 @@ function registerGenerationTools(server, client, cfg) {
22283
22284
  // que o modelo aceita (Seedream/nano-banana não têm limite publicado).
22284
22285
  prompt: external_exports.string().min(1).describe("Descri\xE7\xE3o da imagem desejada."),
22285
22286
  model: external_exports.enum(IMAGE_MODELS).default(DEFAULTS.imageModel).describe(
22286
- "nano-banana-2 = barato/r\xE1pido; nano-banana-pro = melhor qualidade; gpt-image-2 = OpenAI; gpt-image-1 = OpenAI, \xDANICO que faz fundo transparente de verdade (PNG/WebP com alpha) \u2014 o gpt-image-2 N\xC3O faz, use este pra recorte/sticker; seedream-5.0-lite = mais barato do cat\xE1logo, \xFAnico que chega a 4K, gera s\xE9ries e mant\xE9m o ESTILO da imagem de refer\xEAncia; seedream-5.0-pro = acabamento fotorrealista, s\xF3 at\xE9 2K (1K/1.5K/2K, propor\xE7\xE3o, tamanho livre e at\xE9 4 imagens por pedido) \u2014 preserva o personagem da refer\xEAncia mas costuma reinterpretar o estilo (um vetor flat volta em 3D)."
22287
+ "nano-banana-2.1 = padr\xE3o, o mais novo e o mais barato do Google (metade do 2, texto mais n\xEDtido); nano-banana-2 = vers\xE3o anterior, mesmo comportamento; nano-banana-pro = melhor qualidade; gpt-image-2 = OpenAI; gpt-image-1 = OpenAI, \xDANICO que faz fundo transparente de verdade (PNG/WebP com alpha) \u2014 o gpt-image-2 N\xC3O faz, use este pra recorte/sticker; seedream-5.0-lite = mais barato do cat\xE1logo, \xFAnico que chega a 4K, gera s\xE9ries e mant\xE9m o ESTILO da imagem de refer\xEAncia; seedream-5.0-pro = acabamento fotorrealista, s\xF3 at\xE9 2K (1K/1.5K/2K, propor\xE7\xE3o, tamanho livre e at\xE9 4 imagens por pedido) \u2014 preserva o personagem da refer\xEAncia mas costuma reinterpretar o estilo (um vetor flat volta em 3D)."
22287
22288
  ),
22288
22289
  aspect_ratio: external_exports.enum(ASPECT_RATIOS).optional().describe(
22289
22290
  "Propor\xE7\xE3o. nano-banana: padr\xE3o 1:1. Seedream Pro: combina com size (1K/1.5K/2K) e vira LARGURAxALTURA no backend; sem ela o modelo escolhe o formato pelo prompt."
@@ -22292,8 +22293,8 @@ function registerGenerationTools(server, client, cfg) {
22292
22293
  reference_images: external_exports.array(external_exports.string().min(1)).max(16).optional().describe(
22293
22294
  "Imagens de refer\xEAncia (image-to-image): URL p\xFAblica OU caminho de arquivo local (o MCP faz upload pro R2 automaticamente). At\xE9 14 (nano-banana) / 16 (gpt-image-1/2)."
22294
22295
  ),
22295
- google_search: external_exports.boolean().optional().describe("nano-banana-2: aterra a imagem em busca web do Google (fatos atuais). Padr\xE3o false."),
22296
- image_search: external_exports.boolean().optional().describe("nano-banana-2: usa busca de imagens do Google como refer\xEAncia visual. Padr\xE3o false."),
22296
+ google_search: external_exports.boolean().optional().describe("nano-banana-2.1 e 2: aterra a imagem em busca web do Google (fatos atuais). Padr\xE3o false."),
22297
+ image_search: external_exports.boolean().optional().describe("nano-banana-2.1 e 2: usa busca de imagens do Google como refer\xEAncia visual. Padr\xE3o false."),
22297
22298
  size: external_exports.union([
22298
22299
  external_exports.enum(["1024x1024", "1536x1024", "1024x1536", "auto", "1K", "1.5K", "2K", "3K", "4K"]),
22299
22300
  external_exports.string().regex(/^\d{3,5}x\d{3,5}$/, "use LARGURAxALTURA, ex.: 2048x1152")
@@ -24437,7 +24438,7 @@ var KINDS = {
24437
24438
  block: { title: "Bloco", size: { w: 260, h: 140 }, data: { text: "" }, inputs: [], outputs: ["text"], main: "text" },
24438
24439
  prompt: {
24439
24440
  title: "Prompt",
24440
- size: { w: 340, h: 200 },
24441
+ size: { w: 1024, h: 516 },
24441
24442
  data: { template: "" },
24442
24443
  inputs: ["refs"],
24443
24444
  outputs: ["text", "refs"],
@@ -24488,7 +24489,7 @@ var KINDS = {
24488
24489
  media: { title: "M\xEDdia", size: { w: 320, h: 280 }, data: { items: [] }, inputs: [], outputs: ["image"], dynamic: "sa\xEDda por tipo de item (image, video, audio, file)", main: "items" },
24489
24490
  image: {
24490
24491
  title: "Gerador de imagem",
24491
- size: { w: 320, h: 380 },
24492
+ size: { w: 516, h: 516 },
24492
24493
  data: { model: "google/nano-banana-2", aspect_ratio: "1:1", count: 1 },
24493
24494
  inputs: ["prompt"],
24494
24495
  outputs: ["image"],
@@ -24496,7 +24497,7 @@ var KINDS = {
24496
24497
  },
24497
24498
  video: {
24498
24499
  title: "Gerador de v\xEDdeo",
24499
- size: { w: 360, h: 320 },
24500
+ size: { w: 917, h: 516 },
24500
24501
  data: { model: "bytedance/seedance-2.0-mini", aspect_ratio: "16:9", duration: 5, generateAudio: true },
24501
24502
  inputs: ["prompt"],
24502
24503
  outputs: ["video"],
@@ -24585,6 +24586,28 @@ var KINDS = {
24585
24586
  main: "text"
24586
24587
  }
24587
24588
  };
24589
+ var LABEL_BIRTH_WIDTH = { titulo: 2e3, subtitulo: 1200, corpo: 320 };
24590
+ function labelBirthWidth(size) {
24591
+ return typeof size === "string" && Object.hasOwn(LABEL_BIRTH_WIDTH, size) ? LABEL_BIRTH_WIDTH[size] : LABEL_BIRTH_WIDTH.titulo;
24592
+ }
24593
+ var CREATION_HEIGHT = 516;
24594
+ var STAGE_RATIO_MIN = 0.5;
24595
+ var STAGE_RATIO_MAX = 2.4;
24596
+ function ratioOfAspect(aspect) {
24597
+ if (typeof aspect !== "string") return null;
24598
+ const match = /^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?)$/.exec(aspect.trim());
24599
+ if (match === null) return null;
24600
+ const width2 = Number(match[1]);
24601
+ const height = Number(match[2]);
24602
+ return width2 > 0 && height > 0 ? width2 / height : null;
24603
+ }
24604
+ function isGeneratorKind(kind) {
24605
+ return kind === "image" || kind === "video";
24606
+ }
24607
+ function generatorBirthWidth(kind, aspect) {
24608
+ const ratio = ratioOfAspect(aspect) ?? (kind === "video" ? 16 / 9 : 1);
24609
+ return Math.round(CREATION_HEIGHT * Math.min(STAGE_RATIO_MAX, Math.max(STAGE_RATIO_MIN, ratio)));
24610
+ }
24588
24611
  function kindList() {
24589
24612
  return Object.entries(KINDS).map(([k, s]) => `${k} (${s.title})`).join(", ");
24590
24613
  }
@@ -24826,7 +24849,7 @@ function sizeLabel(node) {
24826
24849
  if (u.source === "medido" && u.estimated) return `${base} (medido em ${Math.round(readMeasured(node).w)} de largura: altura estimada)`;
24827
24850
  return base;
24828
24851
  }
24829
- var DEFAULT_WIDTHS = { prompt: 1024, image: 560, video: 560, reference: 320, frame: 320, title: 1024 };
24852
+ var DEFAULT_WIDTHS = { prompt: 1024, reference: 320, frame: 320, title: 1024 };
24830
24853
  var DEFAULT_GAP = 80;
24831
24854
  var FRAME_PORTS = /* @__PURE__ */ new Set(["frame"]);
24832
24855
  var FEEDS = /* @__PURE__ */ new Set(["prompt", "image", "video"]);
@@ -24848,9 +24871,14 @@ function hangsRight(doc, node) {
24848
24871
  return out.some((e) => doc.nodes[e.target] && FEEDS.has(kindOf(doc.nodes[e.target])));
24849
24872
  }
24850
24873
  var overlap = (a, b) => a.x < b.x + b.w && b.x < a.x + a.w && a.y < b.y + b.h && b.y < a.y + a.h;
24851
- function arrangeRows(doc, rows, origin, gap = DEFAULT_GAP, widths = DEFAULT_WIDTHS, scope) {
24874
+ function arrangeRows(doc, rows, origin, gap = DEFAULT_GAP, widths = {}, scope) {
24852
24875
  const placed = [];
24853
- const floorOf = (node, role) => role === "other" ? node.size.w : widths[role];
24876
+ const floorOf = (node, role) => {
24877
+ if (role === "other") return node.size.w;
24878
+ const given = widths[role] ?? DEFAULT_WIDTHS[role];
24879
+ if (given !== void 0) return given;
24880
+ return generatorBirthWidth(role === "video" ? "video" : "image", node.data.aspect_ratio);
24881
+ };
24854
24882
  const place = (id, row, asTitle, x, y2, alignRight) => {
24855
24883
  const node = doc.nodes[id];
24856
24884
  const role = roleOf(doc, node, asTitle);
@@ -25895,7 +25923,7 @@ function registerCanvasLayoutTools(server, deps) {
25895
25923
  "canvas_arrange_rows",
25896
25924
  {
25897
25925
  title: "Canvas: arrumar em linhas",
25898
- description: "Arruma n\xF3s em linhas, uma por vers\xE3o (revis\xE3o de imagem) ou por take (anima\xE7\xE3o), de cima para baixo a partir de origin: title em cima; \xE0 esquerda a coluna left (prompt; m\xEDdia/imagem que alimenta o prompt ou o gerador, como a refer\xEAncia e o frame de entrada, fica alinhada \xE0 direita embaixo dele); \xE0 direita a coluna right (gerador) com o topo no do prompt. Qualquer tipo entra em qualquer coluna. Usa o tamanho medido da tela (ou o gravado, avisando) e p\xF5e a largura pelo tipo real do n\xF3: prompt 1024, gerador de imagem 560, de v\xEDdeo 560, refer\xEAncia (m\xEDdia) 320, frame (m\xEDdia/imagem ligada na porta frame do v\xEDdeo) 320, t\xEDtulo 1024. Grava s\xF3 posi\xE7\xE3o e tamanho num passo, sem pedir releitura. Devolve as caixas, as sobreposi\xE7\xF5es com os tamanhos usados e os n\xF3s sem medida (a altura deles pode crescer quando o board abrir: rode de novo depois). Se a \xE1rea encostar em outro n\xF3 da mesma aba (aba, ou a dos n\xF3s arrumados), n\xE3o grava nada e sugere uma origem livre. dry_run: true s\xF3 calcula.",
25926
+ description: "Arruma n\xF3s em linhas, uma por vers\xE3o (revis\xE3o de imagem) ou por take (anima\xE7\xE3o), de cima para baixo a partir de origin: title em cima; \xE0 esquerda a coluna left (prompt; m\xEDdia/imagem que alimenta o prompt ou o gerador, como a refer\xEAncia e o frame de entrada, fica alinhada \xE0 direita embaixo dele); \xE0 direita a coluna right (gerador) com o topo no do prompt. Qualquer tipo entra em qualquer coluna. Usa o tamanho medido da tela (ou o gravado, avisando) e p\xF5e a largura pelo tipo real do n\xF3: prompt 1024, gerador de imagem e de v\xEDdeo na largura do aspect_ratio do dado, na altura de cria\xE7\xE3o 516 (16:9 917, 9:16 290, 1:1 516), refer\xEAncia (m\xEDdia) 320, frame (m\xEDdia/imagem ligada na porta frame do v\xEDdeo) 320, t\xEDtulo 1024. Grava s\xF3 posi\xE7\xE3o e tamanho num passo, sem pedir releitura. Devolve as caixas, as sobreposi\xE7\xF5es com os tamanhos usados e os n\xF3s sem medida (a altura deles pode crescer quando o board abrir: rode de novo depois). Se a \xE1rea encostar em outro n\xF3 da mesma aba (aba, ou a dos n\xF3s arrumados), n\xE3o grava nada e sugere uma origem livre. dry_run: true s\xF3 calcula.",
25899
25927
  inputSchema: {
25900
25928
  board_id: external_exports.string().uuid(),
25901
25929
  origin: external_exports.object({ x: external_exports.number().finite(), y: external_exports.number().finite() }).describe("Canto de cima \xE0 esquerda da \xE1rea."),
@@ -25916,7 +25944,7 @@ function registerCanvasLayoutTools(server, deps) {
25916
25944
  reference: width.optional(),
25917
25945
  frame: width.optional(),
25918
25946
  title: width.optional()
25919
- }).strict().optional().describe("Troca larguras da conven\xE7\xE3o (prompt 1024, image 560, video 560, reference 320, frame 320, title 1024)."),
25947
+ }).strict().optional().describe("Troca larguras da conven\xE7\xE3o (prompt 1024, reference 320, frame 320, title 1024). image e video, sem troca, seguem o aspect_ratio do dado na altura de cria\xE7\xE3o 516 (16:9 917, 9:16 290, 1:1 516); com n\xFAmero, vale o n\xFAmero."),
25920
25948
  dry_run: external_exports.boolean().optional().describe("true: s\xF3 calcula e mostra, sem gravar.")
25921
25949
  },
25922
25950
  annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
@@ -25924,7 +25952,7 @@ function registerCanvasLayoutTools(server, deps) {
25924
25952
  async (args) => run(async () => {
25925
25953
  const rows = args.rows.map((r) => ({ title: r.title, left: r.left ?? [], right: r.right ?? [] }));
25926
25954
  const { generator, ...own } = args.widths ?? {};
25927
- const widths = { ...DEFAULT_WIDTHS, ...generator ? { image: generator, video: generator } : {}, ...own };
25955
+ const widths = { ...generator ? { image: generator, video: generator } : {}, ...own };
25928
25956
  const gap = args.gap ?? DEFAULT_GAP;
25929
25957
  const plan = (doc) => {
25930
25958
  checkRows(doc, rows);
@@ -26761,7 +26789,7 @@ var point = external_exports.object({ x: external_exports.number().finite(), y:
26761
26789
  var LABEL_TEXT_SIZES = ["titulo", "subtitulo", "corpo"];
26762
26790
  var dim = external_exports.number().finite().min(16).max(2e4);
26763
26791
  var sizeArg = external_exports.union([external_exports.object({ w: dim.optional(), h: dim.optional() }).strict(), external_exports.enum(LABEL_TEXT_SIZES)]).describe(
26764
- '{w, h}: caixa do n\xF3 (piso: o cart\xE3o cresce com o conte\xFAdo; um lado s\xF3 vale). "titulo" | "subtitulo" | "corpo": tamanho do texto do Texto livre (label), gravado em data.size.'
26792
+ '{w, h}: caixa do n\xF3 (piso: o cart\xE3o cresce com o conte\xFAdo; um lado s\xF3 vale). "titulo" | "subtitulo" | "corpo": tamanho do texto do Texto livre (label), gravado em data.size. Ao criar um Texto livre sem w, a largura vem do tamanho do texto: titulo 2000, subtitulo 1200, corpo 320.'
26765
26793
  );
26766
26794
  var isLayoutOp = (op) => op.type === "batch" ? op.ops.every(isLayoutOp) : op.type === "node.set" && /^(position\.[xy]|size\.[wh])$/.test(op.path);
26767
26795
  function textSizeFor(kind, size) {
@@ -26776,6 +26804,10 @@ function boxOf(size) {
26776
26804
  if (size.w === void 0 && size.h === void 0) throw new CanvasToolError("size {w, h}: informe w, h ou os dois.");
26777
26805
  return size;
26778
26806
  }
26807
+ function birthBox(kind, spec, data, asked) {
26808
+ const w = asked?.w ?? (kind === "label" ? labelBirthWidth(data.size) : isGeneratorKind(kind) ? generatorBirthWidth(kind, data.aspect_ratio) : spec.size.w);
26809
+ return { w, h: asked?.h ?? spec.size.h };
26810
+ }
26779
26811
  function registerCanvasTools(server, client, cfg) {
26780
26812
  const api = new CanvasApi(client, cfg);
26781
26813
  const seen = /* @__PURE__ */ new Map();
@@ -27142,7 +27174,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
27142
27174
  "canvas_add_node",
27143
27175
  {
27144
27176
  title: "Canvas: adicionar n\xF3",
27145
- description: `Adiciona um n\xF3 (n\xE3o executa). ${READ}kind: ${kindList()}. data completa o padr\xE3o do tipo; label d\xE1 o nome. Sem position, nasce ao lado do n\xF3 ligado ou \xE0 direita do board (com aba, no fim do conte\xFAdo da aba); aba grava data.abaId. inputs/outputs j\xE1 ligam o n\xF3 no mesmo passo. ` + MENTION_NOTE + MONTAGE_NOTE,
27177
+ description: `Adiciona um n\xF3 (n\xE3o executa). ${READ}kind: ${kindList()}. data completa o padr\xE3o do tipo; label d\xE1 o nome. Sem position, nasce ao lado do n\xF3 ligado ou \xE0 direita do board (com aba, no fim do conte\xFAdo da aba); aba grava data.abaId. Texto livre (label) sem size {w} nasce na largura do tamanho do texto: titulo 2000, subtitulo 1200, corpo 320. Prompt sem size nasce com 1024 \xD7 516; gerador de imagem ou v\xEDdeo, com altura 516 e a largura do aspect_ratio (16:9 917, 9:16 290, 1:1 516). inputs/outputs j\xE1 ligam o n\xF3 no mesmo passo. ` + MENTION_NOTE + MONTAGE_NOTE,
27146
27178
  inputSchema: {
27147
27179
  board_id: boardId3,
27148
27180
  kind: external_exports.string().min(1).max(40),
@@ -27163,12 +27195,8 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
27163
27195
  const me = await api.me();
27164
27196
  const data = { ...spec.data, ...parseData(args.data), [KIND_FIELD]: args.kind };
27165
27197
  if (args.label) data.label = args.label;
27166
- let box = spec.size;
27167
27198
  if (typeof args.size === "string") data.size = textSizeFor(args.kind, args.size);
27168
- else if (args.size) {
27169
- const b = boxOf(args.size);
27170
- box = { w: b.w ?? spec.size.w, h: b.h ?? spec.size.h };
27171
- }
27199
+ const box = birthBox(args.kind, spec, data, args.size && typeof args.size !== "string" ? boxOf(args.size) : void 0);
27172
27200
  const byParam = args.aba ? resolveTab(doc, args.aba) : void 0;
27173
27201
  const written = data[TAB_ID_FIELD];
27174
27202
  const byData = typeof written === "string" && written !== "" ? resolveTab(doc, written) : void 0;
@@ -27531,7 +27559,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
27531
27559
  import { createRequire } from "module";
27532
27560
  var require2 = createRequire(import.meta.url);
27533
27561
  function readVersion() {
27534
- if ("0.37.0") return "0.37.0";
27562
+ if ("0.38.0") return "0.38.0";
27535
27563
  try {
27536
27564
  const pkg = require2("../package.json");
27537
27565
  return pkg.version ?? "0.0.0-unknown";