@pinepaper.studio/mcp-server 1.6.25 → 1.6.27

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 (67) hide show
  1. package/README.md +108 -7
  2. package/SECURITY.md +15 -1
  3. package/dist/agent/types.d.ts +3 -3
  4. package/dist/browser/puppeteer-controller.d.ts +12 -1
  5. package/dist/browser/puppeteer-controller.d.ts.map +1 -1
  6. package/dist/browser/puppeteer-controller.js +105 -15
  7. package/dist/browser/puppeteer-controller.js.map +1 -1
  8. package/dist/build-info.json +2 -2
  9. package/dist/ontology/hints.d.ts +3 -1
  10. package/dist/ontology/hints.d.ts.map +1 -1
  11. package/dist/ontology/hints.js +4 -2
  12. package/dist/ontology/hints.js.map +1 -1
  13. package/dist/ontology/upstream-vocabulary.d.ts +1 -1
  14. package/dist/ontology/upstream-vocabulary.js +1 -1
  15. package/dist/ontology/vocabulary.d.ts.map +1 -1
  16. package/dist/ontology/vocabulary.js +2 -0
  17. package/dist/ontology/vocabulary.js.map +1 -1
  18. package/dist/tools/definitions.d.ts.map +1 -1
  19. package/dist/tools/definitions.js +23 -10
  20. package/dist/tools/definitions.js.map +1 -1
  21. package/dist/tools/engine-lists.d.ts +11 -1
  22. package/dist/tools/engine-lists.d.ts.map +1 -1
  23. package/dist/tools/engine-lists.js +109 -1
  24. package/dist/tools/engine-lists.js.map +1 -1
  25. package/dist/tools/engine-methods.d.ts.map +1 -1
  26. package/dist/tools/engine-methods.js +1 -0
  27. package/dist/tools/engine-methods.js.map +1 -1
  28. package/dist/tools/engine-surface.d.ts +1 -1
  29. package/dist/tools/engine-surface.d.ts.map +1 -1
  30. package/dist/tools/engine-surface.js +7 -4
  31. package/dist/tools/engine-surface.js.map +1 -1
  32. package/dist/tools/export-file-receipt.d.ts +43 -0
  33. package/dist/tools/export-file-receipt.d.ts.map +1 -1
  34. package/dist/tools/export-file-receipt.js +65 -3
  35. package/dist/tools/export-file-receipt.js.map +1 -1
  36. package/dist/tools/expression-grammar.d.ts +10 -0
  37. package/dist/tools/expression-grammar.d.ts.map +1 -0
  38. package/dist/tools/expression-grammar.js +33 -0
  39. package/dist/tools/expression-grammar.js.map +1 -0
  40. package/dist/tools/handlers/export.d.ts.map +1 -1
  41. package/dist/tools/handlers/export.js +54 -4
  42. package/dist/tools/handlers/export.js.map +1 -1
  43. package/dist/tools/handlers.d.ts.map +1 -1
  44. package/dist/tools/handlers.js +61 -2
  45. package/dist/tools/handlers.js.map +1 -1
  46. package/dist/tools/lane.d.ts +4 -3
  47. package/dist/tools/lane.d.ts.map +1 -1
  48. package/dist/tools/lane.js +31 -5
  49. package/dist/tools/lane.js.map +1 -1
  50. package/dist/tools/scene-cache-export.d.ts +52 -0
  51. package/dist/tools/scene-cache-export.d.ts.map +1 -0
  52. package/dist/tools/scene-cache-export.js +227 -0
  53. package/dist/tools/scene-cache-export.js.map +1 -0
  54. package/dist/tools/shape-params.d.ts +2 -2
  55. package/dist/tools/shape-params.js +2 -2
  56. package/dist/tools/stick-vocabulary.d.ts +1 -1
  57. package/dist/tools/stick-vocabulary.js +1 -1
  58. package/dist/types/code-generator.d.ts +1 -0
  59. package/dist/types/code-generator.d.ts.map +1 -1
  60. package/dist/types/code-generator.js +459 -249
  61. package/dist/types/code-generator.js.map +1 -1
  62. package/dist/types/schemas.d.ts +211 -199
  63. package/dist/types/schemas.d.ts.map +1 -1
  64. package/dist/types/schemas.js +7 -1
  65. package/dist/types/schemas.js.map +1 -1
  66. package/manifest.json +1 -1
  67. package/package.json +1 -9
@@ -16,11 +16,12 @@
16
16
  /**
17
17
  * The lane's tools. The first five are the lane as it shipped, in the order an agent uses them; O10 (mcp-server#29)
18
18
  * added the two after them, appended so nothing a lane client had moves: events (timed and clicked; their reactions
19
- * ride in the batch as relation ops) and clearing (start over, so a replay gets the same ids).
19
+ * ride in the batch as relation ops) and clearing (start over, so a replay gets the same ids). #36 appended custom
20
+ * relations: one definition drives many items, and a parameter edit is one call instead of a keyframe rebuild.
20
21
  */
21
- export declare const LANE_TOOL_NAMES: readonly ["pinepaper_agent_batch_execute", "pinepaper_keyframe_animate", "pinepaper_pattern", "pinepaper_agent_export", "pinepaper_lint_scene", "pinepaper_event", "pinepaper_clear_canvas"];
22
+ export declare const LANE_TOOL_NAMES: readonly ["pinepaper_agent_batch_execute", "pinepaper_keyframe_animate", "pinepaper_pattern", "pinepaper_agent_export", "pinepaper_lint_scene", "pinepaper_event", "pinepaper_clear_canvas", "pinepaper_register_custom_relation"];
22
23
  /** Read by the model before any tool: what the lane is, the order of work, and what it cannot do. */
23
- export declare const LANE_INSTRUCTIONS = "PinePaper Studio, agent lane: seven tools that build an animated scene on a live canvas and export it to a file.\n\nORDER OF WORK:\n1. pinepaper_agent_batch_execute: ONE call with the canvas size, the background, every item, their keyframes and any relations.\n2. pinepaper_lint_scene: check the scene before exporting (text running off the frame, unrelated items).\n3. pinepaper_agent_export: format, duration and fps for a video. It returns the file path and the file's sha256 (a small SVG comes back inline).\nUse pinepaper_keyframe_animate to re-key one item afterwards, and pinepaper_pattern to move many named items with one declaration.\nSomething that happens AT a time or ON a click (show, hide, recolour): make the event with pinepaper_event first, then bind it in the batch with relation ops.\nTo start over, call pinepaper_clear_canvas: it empties the canvas and ids start again at item_1, so the same batch gives the same ids.\n\nUNITS: pixels, top-left origin, y down; time in seconds; angles in degrees; colours as \"#rrggbb\".\nEvery call acts on the live canvas at once: re-sending a batch ADDS its items again (clear first to replay it). A failed atomic batch removes the items it made, so fix it and send it again (edits it made to items that already existed stay: the result says so).\nReport a tool error as it is; do not write HTML or other code instead of these tools.\nThis lane is for scenes built from shapes, text, keyframes and relations. For characters, styled scenes, maps, diagrams or sound, the full surface is PINEPAPER_TOOLKIT=agent.";
24
+ export declare const LANE_INSTRUCTIONS = "PinePaper Studio, agent lane: eight tools that build an animated scene on a live canvas and export it to a file.\n\nORDER OF WORK:\n1. pinepaper_agent_batch_execute: ONE call with the canvas size, the background, every item, their keyframes and any relations.\n2. pinepaper_lint_scene: check the scene before exporting (text running off the frame, unrelated items).\n3. pinepaper_agent_export: format, duration and fps for a video. It returns the file path and the file's sha256 (a small SVG comes back inline).\nUse pinepaper_keyframe_animate to re-key one item afterwards, and pinepaper_pattern to move many named items with one declaration.\nSomething that happens AT a time or ON a click (show, hide, recolour): make the event with pinepaper_event first, then bind it in the batch with relation ops.\nTo start over, call pinepaper_clear_canvas: it empties the canvas and ids start again at item_1, so the same batch gives the same ids.\nMOTION THAT IS A FUNCTION OF TIME (a bob, a pulse, a sweep, a wave) is a relation, not keyframes: a track of hundreds of keys computed from a formula is the sign of the wrong route.\n- One item: a relation op {\"type\":\"relation\",\"sourceId\":\"$0\",\"relationType\":\"time_expression\",\"relationOptions\":{\"property\":\"y\",\"expression\":\"360 + 40*sin(2*PI*t)\"}} with no targetId; property is x, y, rotation, opacity or scale.\n- Many items, each offset (a wave across dots): define it once with pinepaper_register_custom_relation, its formula reading params.index, and bind it to a name pattern (sourceId \"dot-*\"): each member gets index and count. Adding members later is the same op again.\n\nUNITS: pixels, top-left origin, y down; time in seconds; angles in degrees; colours as \"#rrggbb\".\nEvery call acts on the live canvas at once: re-sending a batch ADDS its items again (clear first to replay it). A failed atomic batch removes the items it made, so fix it and send it again (edits it made to items that already existed stay: the result says so).\nReport a tool error as it is; do not write HTML or other code instead of these tools.\nThis lane is for scenes built from shapes, text, keyframes and relations. For characters, styled scenes, maps, diagrams or sound, the full surface is PINEPAPER_TOOLKIT=agent.";
24
25
  interface LaneTool {
25
26
  description: string;
26
27
  inputSchema: Record<string, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"lane.d.ts","sourceRoot":"","sources":["../../src/tools/lane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;GAIG;AACH,eAAO,MAAM,eAAe,8LAQlB,CAAC;AAKX,qGAAqG;AACrG,eAAO,MAAM,iBAAiB,oiDAaiJ,CAAC;AAEhL,UAAU,QAAQ;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAqBD,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CA4KnF,CAAC;AAEF,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,2FAA2F;AAC3F,wBAAgB,SAAS,CAAC,CAAC,SAAS,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAS7D;AAED,+GAA+G;AAC/G,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAE1D"}
1
+ {"version":3,"file":"lane.d.ts","sourceRoot":"","sources":["../../src/tools/lane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH;;;;;GAKG;AACH,eAAO,MAAM,eAAe,oOASlB,CAAC;AAKX,qGAAqG;AACrG,eAAO,MAAM,iBAAiB,ouEAgBiJ,CAAC;AAEhL,UAAU,QAAQ;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAqBD,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAiMnF,CAAC;AAEF,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,2FAA2F;AAC3F,wBAAgB,SAAS,CAAC,CAAC,SAAS,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAS7D;AAED,+GAA+G;AAC/G,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAE1D"}
@@ -13,10 +13,12 @@
13
13
  * call the lane teaches is a call the full server accepts; lane.test.ts holds that). Nothing here is a second
14
14
  * implementation, and a lane call is billed, validated and reported exactly as the same call on the full surface.
15
15
  */
16
+ import { expressionGrammarText } from './expression-grammar.js';
16
17
  /**
17
18
  * The lane's tools. The first five are the lane as it shipped, in the order an agent uses them; O10 (mcp-server#29)
18
19
  * added the two after them, appended so nothing a lane client had moves: events (timed and clicked; their reactions
19
- * ride in the batch as relation ops) and clearing (start over, so a replay gets the same ids).
20
+ * ride in the batch as relation ops) and clearing (start over, so a replay gets the same ids). #36 appended custom
21
+ * relations: one definition drives many items, and a parameter edit is one call instead of a keyframe rebuild.
20
22
  */
21
23
  export const LANE_TOOL_NAMES = [
22
24
  'pinepaper_agent_batch_execute', // create / batch, with names
@@ -26,11 +28,12 @@ export const LANE_TOOL_NAMES = [
26
28
  'pinepaper_lint_scene', // inspect / lint
27
29
  'pinepaper_event', // events: timed (at) or fired by a click / key (O10)
28
30
  'pinepaper_clear_canvas', // start over (O10)
31
+ 'pinepaper_register_custom_relation', // a motion of your own, bound in the batch (mcp-server#36)
29
32
  ];
30
33
  /** The one keyframe shape, said once and used by both tools that take keyframes. */
31
34
  const KEYFRAME_RULE = `A keyframe is {"time": seconds, "properties": {…}, "easing"?: name}. The values go INSIDE properties, never beside time: {"time":1,"properties":{"opacity":1}}, not {"time":1,"opacity":1} (refused). easing shapes the move ARRIVING at that key: linear (default), easeIn, easeOut, easeInOut, easeOutBack, easeInOutCubic, easeOutBounce, spring, hold. Before its first key an item holds the first key's values; after its last, the last key's. Keyable: x, y (the centre), opacity, scale, scaleX, scaleY, rotation (degrees), fillColor, strokeColor, strokeWidth, width, height, radius, fontSize, trimEnd (0→1 draws a path on).`;
32
35
  /** Read by the model before any tool: what the lane is, the order of work, and what it cannot do. */
33
- export const LANE_INSTRUCTIONS = `PinePaper Studio, agent lane: seven tools that build an animated scene on a live canvas and export it to a file.
36
+ export const LANE_INSTRUCTIONS = `PinePaper Studio, agent lane: eight tools that build an animated scene on a live canvas and export it to a file.
34
37
 
35
38
  ORDER OF WORK:
36
39
  1. pinepaper_agent_batch_execute: ONE call with the canvas size, the background, every item, their keyframes and any relations.
@@ -39,6 +42,9 @@ ORDER OF WORK:
39
42
  Use pinepaper_keyframe_animate to re-key one item afterwards, and pinepaper_pattern to move many named items with one declaration.
40
43
  Something that happens AT a time or ON a click (show, hide, recolour): make the event with pinepaper_event first, then bind it in the batch with relation ops.
41
44
  To start over, call pinepaper_clear_canvas: it empties the canvas and ids start again at item_1, so the same batch gives the same ids.
45
+ MOTION THAT IS A FUNCTION OF TIME (a bob, a pulse, a sweep, a wave) is a relation, not keyframes: a track of hundreds of keys computed from a formula is the sign of the wrong route.
46
+ - One item: a relation op {"type":"relation","sourceId":"$0","relationType":"time_expression","relationOptions":{"property":"y","expression":"360 + 40*sin(2*PI*t)"}} with no targetId; property is x, y, rotation, opacity or scale.
47
+ - Many items, each offset (a wave across dots): define it once with pinepaper_register_custom_relation, its formula reading params.index, and bind it to a name pattern (sourceId "dot-*"): each member gets index and count. Adding members later is the same op again.
42
48
 
43
49
  UNITS: pixels, top-left origin, y down; time in seconds; angles in degrees; colours as "#rrggbb".
44
50
  Every call acts on the live canvas at once: re-sending a batch ADDS its items again (clear first to replay it). A failed atomic batch removes the items it made, so fix it and send it again (edits it made to items that already existed stay: the result says so).
@@ -88,7 +94,7 @@ RULES (each one has cost a failed build):
88
94
  - Name every item (properties.name). pinepaper_pattern selects members by name, e.g. "bar-*".
89
95
  - properties.id chooses an item's id ("dot"), so a replay after pinepaper_clear_canvas addresses the same ids.
90
96
  - A shape with a strokeColor and no color is an outline.
91
- - Relations: orbits {radius, speed (turns per second), direction, phaseDegrees}, follows {offset, smoothing}, attached_to {offset}, points_at, moves_along_path {path:[{x,y},…], speed}. sourceId moves; targetId is what it moves relative to.
97
+ - Relations: orbits {radius, speed (turns per second), direction, phaseDegrees}, follows {offset, smoothing}, attached_to {offset}, points_at, moves_along_path {path:[{x,y},…], speed}, time_expression {property, expression} (no targetId; the formula grammar: ${expressionGrammarText()}). sourceId moves; targetId is what it moves relative to. A name pattern as sourceId ("dot-*") binds every item named like it, in name order, each with index and count added to relationOptions; send the same op again after adding members and they join, with index and count updated. update: true changes the relationOptions of a relation already bound (same sourceId, targetId, relationType) instead of adding one.
92
98
  - Events (item_9 above is an eventId from pinepaper_event): an event → item relation is a reaction, run each time it fires: on_event_set_visibility {visible: true|false}, on_event_set_color {color}, on_event_set_property {property, value}. An item → event relation fires it: on_click_fire, on_pointer_enter_fire, on_key_fire {key}. An item a reaction reveals starts hidden: properties.visible false.
93
99
  - set_canvas_size comes first; a video exports at the canvas size.
94
100
  - The call is LIVE: sending it twice makes every item twice. atomic (default) stops at the first failure and removes every item the call created, so the canvas holds no half batch: fix the op it names and send it again. Edits to items that already existed are not undone; the result says what was removed.
@@ -114,7 +120,8 @@ itemType: text, circle, rectangle, ellipse, star, triangle, polygon, line, arc,
114
120
  groupName: { type: 'string', description: 'group' },
115
121
  keyframes: { ...KEYFRAMES, description: 'keyframe_animate' },
116
122
  append: { type: 'boolean', description: "keyframe_animate: add to the item's track instead of replacing it" },
117
- sourceId: { type: 'string', description: 'relation: the item that moves' },
123
+ sourceId: { type: 'string', description: 'relation: the item that moves, or a name pattern ("dot-*")' },
124
+ update: { type: 'boolean', description: 'relation: change the params of the relation already bound' },
118
125
  targetId: { type: 'string', description: 'relation: what it moves relative to' },
119
126
  relationType: { type: 'string', description: 'relation' },
120
127
  relationOptions: { type: 'object', description: 'relation: its parameters' },
@@ -191,6 +198,7 @@ RETURNS "File: <path>", plus file {sha256, bytes}: the sha256 of the file on dis
191
198
  fps: { type: 'number', description: 'video: frames per second' },
192
199
  time: { type: 'number', description: 'still: the moment to render, in seconds' },
193
200
  deterministic: { type: 'boolean', description: 'mp4 / webm: the same scene gives the same bytes' },
201
+ perScene: { type: 'boolean', description: 'mp4 / webm of a scene chain: cached per scene, so an export after an edit renders only the changed scenes (needs ffmpeg)' },
194
202
  },
195
203
  required: ['format'],
196
204
  },
@@ -218,8 +226,26 @@ A TIMED event fires itself at scene times, in the preview and in every video exp
218
226
  description: `Start over: remove every item (events included), relation, keyframe track and uploaded clip, and the background colour; the canvas size stays. Ids start again at item_1, so a batch sent after a clear returns the same ids as the first time it was sent. Takes no arguments.`,
219
227
  inputSchema: { type: 'object', properties: {} },
220
228
  },
229
+ pinepaper_register_custom_relation: {
230
+ description: `Define a relation of your own, then bind it in pinepaper_agent_batch_execute with relation ops: relationType is its name, relationOptions its params, targetId optional (leave it out when the motion needs no other item). One definition drives many items: bind it to a name pattern (sourceId "dot-*", each member gets index and count), and change a param later with one relation op with update: true. pinepaper_lint_scene lists the relations bound and the definitions registered. It lasts for this session: register it again after a restart.
231
+
232
+ computeFunction is a function BODY that gets fromPosition, toPosition, params, delta and time (scene seconds) and returns what apply needs. applyFunction is a body that gets item, target, computed and params and changes the item.
233
+ {"name":"bobs","params":{"amp":{"type":"number","default":40}},"computeFunction":"return {y: 360 + params.amp * Math.sin(Math.PI * time)};","applyFunction":"if (computed) item.position.y = computed.y;"}
234
+ then in the batch: {"type":"relation","sourceId":"$0","relationType":"bobs","relationOptions":{"amp":100}}`,
235
+ inputSchema: {
236
+ type: 'object',
237
+ properties: {
238
+ name: { type: 'string', description: 'the relation type name, used as relationType' },
239
+ params: { type: 'object', description: 'its parameters: {"amp": {"type": "number", "default": 40}}' },
240
+ computeFunction: { type: 'string', description: 'function body: (fromPosition, toPosition, params, delta, time) → computed' },
241
+ applyFunction: { type: 'string', description: 'function body: (item, target, computed, params) → changes the item' },
242
+ description: { type: 'string' },
243
+ },
244
+ required: ['name', 'computeFunction', 'applyFunction'],
245
+ },
246
+ },
221
247
  pinepaper_lint_scene: {
222
- description: `Check the live scene before exporting; read-only. Returns warnings (a text that runs past the frame edge, by item, side and pixels, where the studio reports it), density (how many items are tied together by relations) and suggestions (relations that would hold the layout together: {from, to, type, params}). Fix a clipped text by moving its centre in with a modify op in pinepaper_agent_batch_execute ({"type":"modify","itemId":"item_1","properties":{"x":474}}: the centre is the left edge plus half the width), or delete it and create it again with properties.anchor; a modify does not read anchor.`,
248
+ description: `Check the live scene before exporting; read-only. Returns relations (every relation bound: from, fromName, to, type, params; the first 200), customRelations (each pinepaper_register_custom_relation definition, as given), warnings (a text that runs past the frame edge, by item, side and pixels, where the studio reports it), density (how many items are tied together by relations) and suggestions (relations that would hold the layout together: {from, to, type, params}). Fix a clipped text by moving its centre in with a modify op in pinepaper_agent_batch_execute ({"type":"modify","itemId":"item_1","properties":{"x":474}}: the centre is the left edge plus half the width), or delete it and create it again with properties.anchor; a modify does not read anchor.`,
223
249
  inputSchema: {
224
250
  type: 'object',
225
251
  properties: {
@@ -1 +1 @@
1
- {"version":3,"file":"lane.js","sourceRoot":"","sources":["../../src/tools/lane.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lane.js","sourceRoot":"","sources":["../../src/tools/lane.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { CallToolResult } from '../mcp/index.js';
2
+ import { segmentStreams, concatSegments, muxAudio, muxSilence } from './export-file-receipt.js';
3
+ interface ChainEntry {
4
+ sceneId: string;
5
+ duration: number;
6
+ transition: string | null;
7
+ cutSound: boolean;
8
+ }
9
+ /** What the export needs from the studio and the server, injected so the flow is testable without either. */
10
+ export interface SceneCacheDeps {
11
+ exec: (code: string) => Promise<{
12
+ success: boolean;
13
+ result?: unknown;
14
+ error?: string;
15
+ }>;
16
+ exportOnce: (args: Record<string, unknown>) => Promise<CallToolResult>;
17
+ exportDir: string;
18
+ /** The studio's program audio for `seconds` (exportProgramAudio), saved to a local WAV; null when it cannot. */
19
+ programAudio?: (seconds: number) => Promise<{
20
+ file: string;
21
+ } | {
22
+ none: true;
23
+ } | {
24
+ reason: string;
25
+ }>;
26
+ ffmpeg?: {
27
+ available: () => Promise<boolean>;
28
+ streams: typeof segmentStreams;
29
+ concat: typeof concatSegments;
30
+ mux?: typeof muxAudio;
31
+ silence?: typeof muxSilence;
32
+ };
33
+ }
34
+ /** True when the only obstacle is something a time-range render keeps (a transition or a cut sound spans a cut). */
35
+ export declare function needsRanges(chain: ChainEntry[] | undefined): boolean;
36
+ /**
37
+ * Segment boundaries for a range render: the cut instants (the sum of the entry durations before each, as the
38
+ * engine's chainCutTimes defines them), snapped to frames. Segment k is [cut k, cut k+1): the transition into
39
+ * scene k (scene k-1's last frame held under it) and scene k itself, so it depends on scenes k-1 and k.
40
+ */
41
+ export declare function rangeSegments(chain: ChainEntry[], fps: number): Array<{
42
+ index: number;
43
+ start: number;
44
+ duration: number;
45
+ }>;
46
+ /** Why this chain cannot be exported per scene, or null when it can. */
47
+ export declare function perSceneRefusal(chain: ChainEntry[] | undefined, format: string): string | null;
48
+ /** The cache key of one segment: everything its pixels and sound depend on. */
49
+ export declare function segmentKey(sceneData: unknown, durationMs: number, settings: Record<string, unknown>, buildId: string | null): string;
50
+ export declare function exportPerScene(args: Record<string, unknown>, format: string, deps: SceneCacheDeps): Promise<CallToolResult>;
51
+ export {};
52
+ //# sourceMappingURL=scene-cache-export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene-cache-export.d.ts","sourceRoot":"","sources":["../../src/tools/scene-cache-export.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAa,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAG3G,UAAU,UAAU;IAAG,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE;AAGxG,6GAA6G;AAC7G,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxF,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IACvE,SAAS,EAAE,MAAM,CAAC;IAClB,gHAAgH;IAChH,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpG,MAAM,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QAAC,OAAO,EAAE,OAAO,cAAc,CAAC;QAAC,MAAM,EAAE,OAAO,cAAc,CAAC;QAAC,GAAG,CAAC,EAAE,OAAO,QAAQ,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,UAAU,CAAA;KAAE,CAAC;CACnK;AAuCD,oHAAoH;AACpH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,SAAS,GAAG,OAAO,CAEpE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAKzH;AAED,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAO9F;AAED,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAEpI;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAgHjI"}
@@ -0,0 +1,227 @@
1
+ /**
2
+ * agent_export { perScene: true }: a long scene chain exported as segments, each cached by what it depends on, and
3
+ * joined: the video without re-encoding, the audio re-encoded so the seams are seamless.
4
+ *
5
+ * WHY. Editing one scene of a ten-minute piece re-rendered all ten minutes. Agents on the local server learned to
6
+ * export scene by scene and join the files themselves, and that alone made local edits 2–2.5x faster in the
7
+ * benchmark (mcp-server#37's run). This builds it in: a segment whose inputs did not change comes from the cache.
8
+ *
9
+ * WHAT A SEGMENT DEPENDS ON is hashed: the scene's own saved data (sceneManager.exportScenes), its length, every
10
+ * export setting, and the studio build. A change to any of them is a new hash and a new render; nothing is
11
+ * invalidated by hand.
12
+ *
13
+ * HARD CUTS ONLY, for now: each scene is rendered alone (the chain set aside, then put back), so a crossfade or a
14
+ * cut sound, which spans two scenes, would be lost. A chain with either is exported whole, as before, and the
15
+ * result says why. The join needs ffmpeg on PATH; without it the chain is exported whole too. When the engine
16
+ * can render a time range of the chain (app.exportEngine.supportsTimeRange, FxTool branch claude/export-time-range),
17
+ * segments become ranges of the chain timeline and transitions stay in.
18
+ */
19
+ import { createHash } from 'node:crypto';
20
+ import { mkdir, stat, copyFile } from 'node:fs/promises';
21
+ import { existsSync } from 'node:fs';
22
+ import { join } from 'node:path';
23
+ import { hasFfmpeg, segmentStreams, concatSegments, muxAudio, muxSilence } from './export-file-receipt.js';
24
+ import { exportFileLink } from '../utils/export-dir.js';
25
+ const READ_CHAIN = `(function () {
26
+ const sm = app.sceneManager;
27
+ if (!sm || !Array.isArray(sm.sceneChain)) return { ok: false, reason: 'this studio has no scene manager' };
28
+ return {
29
+ ok: true,
30
+ chain: sm.sceneChain.map((e) => ({ sceneId: e.sceneId, duration: e.duration, transition: e.transition || null, cutSound: !!e.cutSound })),
31
+ entries: JSON.parse(JSON.stringify(sm.sceneChain)),
32
+ loop: sm.chainLoop === true,
33
+ ranges: !!(app.exportEngine && app.exportEngine.supportsTimeRange === true),
34
+ programAudio: !!(app.exportEngine && app.exportEngine.supportsProgramAudio === true),
35
+ current: sm.currentSceneId || null,
36
+ scenes: typeof sm.exportScenes === 'function' ? sm.exportScenes() : '',
37
+ buildId: app.buildId || null,
38
+ };
39
+ })();`;
40
+ /** Set the chain aside and load one scene, so a plain export renders that scene alone. */
41
+ const LOAD_ALONE = (sceneId) => `(async function () {
42
+ const sm = app.sceneManager;
43
+ if (window.__ppSceneCacheChain === undefined) window.__ppSceneCacheChain = sm.sceneChain;
44
+ sm.sceneChain = [];
45
+ const ok = await sm.loadSceneForRender(${JSON.stringify(sceneId)});
46
+ return { success: ok !== false };
47
+ })();`;
48
+ /** Put the chain back and the scene that was showing. */
49
+ const RESTORE = (current) => `(async function () {
50
+ const sm = app.sceneManager;
51
+ if (window.__ppSceneCacheChain !== undefined) { sm.sceneChain = window.__ppSceneCacheChain; delete window.__ppSceneCacheChain; }
52
+ ${current ? `try { await sm.loadSceneForRender(${JSON.stringify(current)}); } catch (e) { /* the chain is back; the scene shown is the last rendered */ }` : ''}
53
+ return { success: true };
54
+ })();`;
55
+ function textOf(r) {
56
+ return (r.content ?? []).map((c) => ('text' in c ? String(c.text ?? '') : '')).join('\n');
57
+ }
58
+ /** True when the only obstacle is something a time-range render keeps (a transition or a cut sound spans a cut). */
59
+ export function needsRanges(chain) {
60
+ return !!chain && chain.length >= 2 && (chain.slice(1).some((e) => e.transition && e.transition !== 'cut' && e.transition !== 'none') || chain.some((e) => e.cutSound));
61
+ }
62
+ /**
63
+ * Segment boundaries for a range render: the cut instants (the sum of the entry durations before each, as the
64
+ * engine's chainCutTimes defines them), snapped to frames. Segment k is [cut k, cut k+1): the transition into
65
+ * scene k (scene k-1's last frame held under it) and scene k itself, so it depends on scenes k-1 and k.
66
+ */
67
+ export function rangeSegments(chain, fps) {
68
+ const snap = (t) => Math.round(t * fps) / fps;
69
+ const cuts = [0];
70
+ for (let k = 1; k <= chain.length; k++)
71
+ cuts.push(cuts[k - 1] + Math.max(0, chain[k - 1].duration) / 1000);
72
+ return chain.map((_, k) => ({ index: k, start: snap(cuts[k]), duration: snap(cuts[k + 1]) - snap(cuts[k]) })).filter((x) => x.duration > 0);
73
+ }
74
+ /** Why this chain cannot be exported per scene, or null when it can. */
75
+ export function perSceneRefusal(chain, format) {
76
+ if (format !== 'mp4' && format !== 'webm')
77
+ return `perScene joins video segments, and ${format} is not mp4 or webm`;
78
+ if (!chain || chain.length < 2)
79
+ return 'perScene needs a scene chain of two or more scenes (pinepaper_scene_playback create_chain)';
80
+ const crossed = chain.slice(1).filter((e) => e.transition && e.transition !== 'cut' && e.transition !== 'none');
81
+ if (crossed.length)
82
+ return `${crossed.length} cut(s) in the chain are transitions (${[...new Set(crossed.map((e) => e.transition))].join(', ')}), which span two scenes; per-scene segments are rendered one scene at a time, so it is exported whole. create_chain with transition 'cut' makes it cacheable`;
83
+ if (chain.some((e) => e.cutSound))
84
+ return 'the chain has cut sounds, which play across a cut; it is exported whole';
85
+ return null;
86
+ }
87
+ /** The cache key of one segment: everything its pixels and sound depend on. */
88
+ export function segmentKey(sceneData, durationMs, settings, buildId) {
89
+ return createHash('sha256').update(JSON.stringify({ sceneData, durationMs, settings, buildId })).digest('hex').slice(0, 32);
90
+ }
91
+ export async function exportPerScene(args, format, deps) {
92
+ const ff = deps.ffmpeg ?? { available: hasFfmpeg, streams: segmentStreams, concat: concatSegments, mux: muxAudio, silence: muxSilence };
93
+ const { perScene: _p, ...settings } = args;
94
+ let chainSeconds;
95
+ const whole = async (why) => {
96
+ // A chain exported whole runs its length: the export's own default (5 s) would cut a longer one short.
97
+ const r = await deps.exportOnce(args.duration === undefined && chainSeconds ? { ...settings, duration: chainSeconds } : settings);
98
+ const note = `perScene was not used: ${why}.`;
99
+ return { ...r, content: [{ type: 'text', text: note }, ...(r.content ?? [])] };
100
+ };
101
+ const info = (await deps.exec(READ_CHAIN)).result;
102
+ if (!info || !info.ok)
103
+ return whole(info?.reason ?? 'the studio did not report its scene chain');
104
+ chainSeconds = (info.chain ?? []).reduce((a, e) => a + Math.max(0, e.duration) / 1000, 0) || undefined;
105
+ if (info.loop)
106
+ return whole('the chain loops, and a per-scene export joins one pass; export it whole');
107
+ const refusal = perSceneRefusal(info.chain, format);
108
+ const ranges = !!refusal && needsRanges(info.chain) && info.ranges === true && (format === 'mp4' || format === 'webm');
109
+ if (refusal && !ranges)
110
+ return whole(refusal + (needsRanges(info.chain) && !info.ranges ? ' (a studio that renders time ranges keeps them: update PinePaper Studio)' : ''));
111
+ if (!(await ff.available()))
112
+ return whole('ffmpeg is not on PATH, and the segments are joined with it (install ffmpeg to cache per scene)');
113
+ let scenesById = new Map();
114
+ try {
115
+ const parsed = JSON.parse(info.scenes || '{}');
116
+ scenesById = new Map((parsed.scenes ?? []).filter((s) => s && typeof s.id === 'string').map((s) => [s.id, s]));
117
+ }
118
+ catch {
119
+ return whole('the studio\'s scene export did not parse');
120
+ }
121
+ // PROGRAM AUDIO (FxTool #251): segments render without sound and the studio's own full-export audio goes on once,
122
+ // after the join. A cached segment's sound would otherwise carry a master level an edit elsewhere has changed.
123
+ const program = info.programAudio === true && !!deps.programAudio && !!ff.mux;
124
+ const segSettings = program ? { ...settings, audio: false } : settings;
125
+ const cacheDir = join(deps.exportDir, '.scene-cache');
126
+ await mkdir(cacheDir, { recursive: true });
127
+ const segments = [];
128
+ if (ranges) {
129
+ // RANGES of the chain timeline (FxTool #250): transitions and cut sounds render as in a whole export. Each range
130
+ // still renders the frames before its start (unencoded), so this path is for chains a hard cut cannot carry.
131
+ const fps = Number(settings.fps) > 0 ? Number(settings.fps) : 30;
132
+ const chain = info.chain;
133
+ for (const seg of rangeSegments(chain, fps)) {
134
+ const inputs = [seg.index - 1, seg.index].filter((k) => k >= 0).map((k) => ({ scene: scenesById.get(chain[k].sceneId) ?? null, entry: (info.entries ?? [])[k] ?? null }));
135
+ const file = join(cacheDir, `${segmentKey({ range: seg, inputs }, Math.round(seg.duration * 1000), segSettings, info.buildId ?? null)}.${format}`);
136
+ const sceneId = chain[seg.index].sceneId;
137
+ if (existsSync(file)) {
138
+ segments.push({ sceneId, file, cached: true, seconds: seg.duration });
139
+ continue;
140
+ }
141
+ const r = await deps.exportOnce({ ...segSettings, startTime: seg.start, duration: seg.duration });
142
+ const made = /File: (\S+)/.exec(textOf(r))?.[1];
143
+ if (r.isError || !made)
144
+ return whole(`the range from ${seg.start} s (scene ${JSON.stringify(sceneId)}) did not export: ${textOf(r).slice(0, 200)}`);
145
+ await copyFile(made, file);
146
+ segments.push({ sceneId, file, cached: false, seconds: seg.duration });
147
+ }
148
+ }
149
+ else
150
+ try {
151
+ for (const entry of info.chain) {
152
+ const scene = scenesById.get(entry.sceneId);
153
+ if (!scene)
154
+ return whole(`scene ${JSON.stringify(entry.sceneId)} is in the chain but not in the studio's scene list`);
155
+ const seconds = entry.duration / 1000;
156
+ const file = join(cacheDir, `${segmentKey(scene, entry.duration, segSettings, info.buildId ?? null)}.${format}`);
157
+ if (existsSync(file)) {
158
+ segments.push({ sceneId: entry.sceneId, file, cached: true, seconds });
159
+ continue;
160
+ }
161
+ const loaded = await deps.exec(LOAD_ALONE(entry.sceneId));
162
+ if (!loaded.success || loaded.result?.success === false) {
163
+ return whole(`scene ${JSON.stringify(entry.sceneId)} could not be loaded on its own`);
164
+ }
165
+ const r = await deps.exportOnce({ ...segSettings, duration: seconds });
166
+ const made = /File: (\S+)/.exec(textOf(r))?.[1];
167
+ if (r.isError || !made)
168
+ return whole(`scene ${JSON.stringify(entry.sceneId)} did not export: ${textOf(r).slice(0, 200)}`);
169
+ await copyFile(made, file);
170
+ segments.push({ sceneId: entry.sceneId, file, cached: false, seconds });
171
+ }
172
+ }
173
+ finally {
174
+ await deps.exec(RESTORE(info.current ?? null)).catch(() => undefined);
175
+ }
176
+ // Every segment must carry the same streams, or a stream copy cannot join them.
177
+ const sigs = await Promise.all(segments.map((s) => ff.streams(s.file)));
178
+ const bad = sigs.findIndex((s) => !s.ok || s.signature !== sigs[0].signature);
179
+ if (bad >= 0)
180
+ return whole(`segment ${bad + 1} (${segments[bad].sceneId}) does not match the first one's streams${sigs[bad].reason ? ': ' + sigs[bad].reason : ''} (a scene with sound beside one without, for instance)`);
181
+ const out = join(deps.exportDir, `pinepaper_scenes_${Date.now()}.${format}`);
182
+ const total = Math.round(segments.reduce((a, s) => a + s.seconds, 0) * 1000) / 1000;
183
+ const hasAudio = /"audio"/.test(sigs[0].signature ?? '');
184
+ let audioNote;
185
+ if (program) {
186
+ const videoOnly = join(cacheDir, `video_${Date.now()}.${format}`);
187
+ const joined = await ff.concat(segments.map((s) => s.file), join(cacheDir, `join_${Date.now()}.txt`), videoOnly, { format, videoOnly: true });
188
+ if (!joined.ok)
189
+ return whole(`ffmpeg could not join the segments: ${joined.reason}`);
190
+ const wav = await deps.programAudio(total);
191
+ if ('none' in wav) {
192
+ // Nothing in the program makes a sound: a silent track, as a whole export carries one.
193
+ const quiet = ff.silence ? await ff.silence(videoOnly, out, { format, seconds: total }) : { ok: false };
194
+ if (!quiet.ok)
195
+ await copyFile(videoOnly, out);
196
+ audioNote = quiet.ok ? 'the program has no sound: the audio track is silent, as in a whole export' : 'the program has no sound, so the file has no audio track';
197
+ }
198
+ else if ('reason' in wav) {
199
+ return whole(`the program audio could not be rendered: ${wav.reason}`);
200
+ }
201
+ else {
202
+ const muxed = await ff.mux(videoOnly, wav.file, out, { format, seconds: total });
203
+ if (!muxed.ok)
204
+ return whole(`ffmpeg could not put the program audio on: ${muxed.reason}`);
205
+ audioNote = 'the audio is the whole program, rendered once by the studio (the same mix a whole export carries)';
206
+ }
207
+ }
208
+ else {
209
+ const joined = await ff.concat(segments.map((s) => s.file), join(cacheDir, `join_${Date.now()}.txt`), out, { audio: hasAudio, format });
210
+ if (!joined.ok)
211
+ return whole(`ffmpeg could not join the segments: ${joined.reason}`);
212
+ if (hasAudio)
213
+ audioNote = 'the audio is joined from the segments (re-encoded at the seams); a studio with program audio renders it whole';
214
+ }
215
+ const bytes = (await stat(out)).size;
216
+ const reused = segments.filter((s) => s.cached).length;
217
+ const result = {
218
+ success: true, format, filePath: out, bytes,
219
+ duration: total,
220
+ ...(audioNote ? { audio: audioNote } : {}),
221
+ perScene: { mode: ranges ? 'chain ranges (transitions kept)' : 'scene by scene (hard cuts)', segments: segments.length, rendered: segments.length - reused, reused, cache: cacheDir },
222
+ scenes: segments.map((s) => ({ sceneId: s.sceneId, seconds: s.seconds, cached: s.cached })),
223
+ note: reused ? `${reused} of ${segments.length} scenes came from the cache: only what changed was rendered.` : 'every scene was rendered and cached; an export after editing one scene renders only that one.',
224
+ };
225
+ return { content: [{ type: 'text', text: `Export saved to file:\nFile: ${out}\n\n${JSON.stringify(result, null, 2)}` }, exportFileLink(out, bytes)] };
226
+ }
227
+ //# sourceMappingURL=scene-cache-export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene-cache-export.js","sourceRoot":"","sources":["../../src/tools/scene-cache-export.ts"],"names":[],"mappings":"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"}
@@ -3,9 +3,9 @@
3
3
  *
4
4
  * What each registry-backed shape reads, and how a caller reaches it.
5
5
  *
6
- * Source: FxTool origin/main cca1ba5e721eb2361300bd29d53ebe9f5a6daeb3
6
+ * Source: FxTool origin/main ac6c66f06faf5f28767694399550322545b771eb
7
7
  * js/PinePaper.js + 5 shape modules
8
- * sha256: 17edb304be05e83e
8
+ * sha256: 14461a6304fecda7
9
9
  *
10
10
  * A shape's `create` receives a `config`, never the caller's `params`.
11
11
  * PinePaper.js's registryConfig literal is the only bridge between the two, so
@@ -3,9 +3,9 @@
3
3
  *
4
4
  * What each registry-backed shape reads, and how a caller reaches it.
5
5
  *
6
- * Source: FxTool origin/main cca1ba5e721eb2361300bd29d53ebe9f5a6daeb3
6
+ * Source: FxTool origin/main ac6c66f06faf5f28767694399550322545b771eb
7
7
  * js/PinePaper.js + 5 shape modules
8
- * sha256: 17edb304be05e83e
8
+ * sha256: 14461a6304fecda7
9
9
  *
10
10
  * A shape's `create` receives a `config`, never the caller's `params`.
11
11
  * PinePaper.js's registryConfig literal is the only bridge between the two, so
@@ -9,7 +9,7 @@
9
9
  * across five lists is exactly the shape that drifts, and every enum this repo
10
10
  * hand-maintained against FxTool drifted silently.
11
11
  *
12
- * Source: FxTool origin/main cca1ba5e721eb2361300bd29d53ebe9f5a6daeb3
12
+ * Source: FxTool origin/main ac6c66f06faf5f28767694399550322545b771eb
13
13
  * js/vendor/stick/figure-rigged.js
14
14
  * sha256: 582d1fd66061000d
15
15
  */
@@ -9,7 +9,7 @@
9
9
  * across five lists is exactly the shape that drifts, and every enum this repo
10
10
  * hand-maintained against FxTool drifted silently.
11
11
  *
12
- * Source: FxTool origin/main cca1ba5e721eb2361300bd29d53ebe9f5a6daeb3
12
+ * Source: FxTool origin/main ac6c66f06faf5f28767694399550322545b771eb
13
13
  * js/vendor/stick/figure-rigged.js
14
14
  * sha256: 582d1fd66061000d
15
15
  */
@@ -56,6 +56,7 @@ export declare function fireIfProblem(params: Record<string, unknown> | undefine
56
56
  * the check does not depend on which tool built the relation.
57
57
  */
58
58
  export declare function relationSpecProblem(relationType: unknown, params: unknown): string | null;
59
+ export declare function relationOptionWarning(relationType: unknown, params: unknown, injected?: readonly string[]): string | null;
59
60
  /**
60
61
  * The per-burst particle cap of the CURRENT studio (FxTool ParticleEmitter
61
62
  * MAX_BURST_COUNT, B144). Studios before that change capped at