narraleaf-studio 1.4.5 → 1.6.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/dist/_api.d.ts CHANGED
@@ -78,6 +78,104 @@ type FileDetails = {
78
78
  type TextEncodingId = "utf8" | "utf8bom" | "utf16le" | "utf16be" | "gbk" | "gb18030" | "big5" | "shiftjis" | "euckr" | "windows1252" | "iso88591";
79
79
  type PersistedTextEol = "lf" | "crlf";
80
80
  type FsTextEncoding = BufferEncoding | TextEncodingId;
81
+ type AgentErrorCode =
82
+ /** The arguments do not fit the tool's schema. */
83
+ "invalid_args"
84
+ /** No tool by that name. */
85
+ | "unknown_tool"
86
+ /** No workspace window has the project open, or more than one does and none was named. */
87
+ | "no_workspace"
88
+ /** The author has not switched on write access for agents. */
89
+ | "writes_disabled"
90
+ /** The author paused the agent from the status bar. */
91
+ | "paused"
92
+ /** The project is frozen for writing (a version-control operation, a recovery, a reload). */
93
+ | "frozen"
94
+ /** A Team live session is running; agent writes would race the room. */
95
+ | "live_session"
96
+ /** The page or scene changed since the agent read it - read it again and redo the edit. */
97
+ | "stale_revision"
98
+ /** The source did not compile, or the check found something at error severity. Nothing was written. */
99
+ | "check_failed"
100
+ /** A surface, scene, element, asset or character the call names does not exist. */
101
+ | "not_found"
102
+ /**
103
+ * A file path outside the directories the author allowed agents to read, or a folder agents are
104
+ * never handed at all - to read from or to write into (Studio's own folders, the home folder
105
+ * itself, a file-system root).
106
+ */
107
+ | "path_not_allowed"
108
+ /** The project is not trusted, so its code may not run (play-test, build). */
109
+ | "untrusted"
110
+ /** The call is valid but the operation is not possible in this state. */
111
+ | "unavailable"
112
+ /** Something broke that is not the agent's fault. */
113
+ | "internal";
114
+ type AgentJsonSchema = {
115
+ type?: "object" | "string" | "number" | "integer" | "boolean" | "array" | "null";
116
+ description?: string;
117
+ properties?: Record<string, AgentJsonSchema>;
118
+ required?: string[];
119
+ items?: AgentJsonSchema;
120
+ enum?: readonly (string | number)[];
121
+ additionalProperties?: boolean | AgentJsonSchema;
122
+ minimum?: number;
123
+ maximum?: number;
124
+ default?: unknown;
125
+ oneOf?: AgentJsonSchema[];
126
+ };
127
+ /** Refusal codes a plugin may answer with. The gate's own codes (paused, frozen…) are Studio's alone. */
128
+ export type PluginAgentToolErrorCode = Extract<AgentErrorCode, "invalid_args" | "not_found" | "check_failed" | "stale_revision" | "unavailable">;
129
+ /** An answer: text the model reads, optionally the same facts as data, optionally one picture. */
130
+ export type PluginAgentToolAnswer = {
131
+ text: string;
132
+ /** Sent as MCP `structuredContent`. Plain JSON; dropped when larger than 60 000 characters. */
133
+ data?: Record<string, unknown>;
134
+ /** One PNG or JPEG, base64 without a `data:` prefix. */
135
+ image?: {
136
+ mimeType: "image/png" | "image/jpeg";
137
+ data: string;
138
+ };
139
+ };
140
+ /** A refusal the agent can act on: what is wrong, and what to do about it. */
141
+ export type PluginAgentToolRefusal = {
142
+ error: {
143
+ code?: PluginAgentToolErrorCode;
144
+ message: string;
145
+ hint?: string;
146
+ };
147
+ };
148
+ /** A bare string is a text answer. */
149
+ export type PluginAgentToolResult = string | PluginAgentToolAnswer | PluginAgentToolRefusal;
150
+ /** What a plugin tool's handler is given besides its arguments. Deliberately nothing that reaches Studio. */
151
+ export type PluginAgentToolContext = {
152
+ /** The name the MCP client gave (`clientInfo.name`), when it gave one. */
153
+ readonly clientName: string | null;
154
+ };
155
+ /** The JSON-schema subset a plugin tool's arguments are described in; see {@link checkAgentPluginToolSchema}. */
156
+ export type PluginAgentJsonSchema = AgentJsonSchema;
157
+ /** One tool a plugin offers AI agents connected to Studio. */
158
+ export type PluginAgentToolDef = {
159
+ /** `<pluginId>.<tool>`, `[a-z0-9_.-]`, declared in `contributes.agentTools`. */
160
+ name: string;
161
+ /** Short, shown in the author's Agent log. At most 80 characters. */
162
+ title: string;
163
+ /** Written for the model: what it is for, when to use it, the mistake to avoid. At most 1200 characters. */
164
+ description: string;
165
+ /** The arguments, checked before the handler runs. Studio adds `project` itself. */
166
+ inputSchema: PluginAgentJsonSchema & {
167
+ type: "object";
168
+ };
169
+ /**
170
+ * Changes the project. Marked `true`: refused unless the author allowed agent writes, and while
171
+ * paused, frozen or in a live session; while it runs, every `writeJson` is captured into one step
172
+ * of undo. Marked `false`: none of that gating applies, and the only thing refused while it runs
173
+ * is `services.storage.writeJson` - the host cannot see the plugin's other routes to the project,
174
+ * so a tool that changes it by any of them must be marked `true`.
175
+ */
176
+ write: boolean;
177
+ handler(args: Record<string, unknown>, context: PluginAgentToolContext): PluginAgentToolResult | Promise<PluginAgentToolResult>;
178
+ };
81
179
  type StoryExprBinaryOp = "+" | "-" | "*" | "/" | "%" | "==" | "!=" | "<" | "<=" | ">" | ">=" | "&&" | "||";
82
180
  type StoryExprUnaryOp = "-" | "!";
83
181
  declare const STORY_EXPR_FUNCTIONS: readonly [
@@ -229,6 +327,74 @@ type StoryExpression = {
229
327
  source: string;
230
328
  ast: StoryExpr;
231
329
  };
330
+ type StoryRumblePresetId = "tap" | "pulse" | "impact" | "quake" | "alert" | "custom";
331
+ type StoryInputWaitFields = {
332
+ /**
333
+ * The project input action this row waits for (`UIDocument.actions` key). Absent means any of
334
+ * them: the first action the player performs, whichever it is.
335
+ */
336
+ actionId?: string;
337
+ /**
338
+ * Give up after this long. Absent waits for as long as it takes - which is the right default for a
339
+ * row whose whole point is the player's gesture, and the reason a row that wants a deadline has to
340
+ * say so.
341
+ */
342
+ timeoutMs?: number;
343
+ /**
344
+ * A boolean variable to write the outcome into: `true` when the player did it in time, `false` when
345
+ * the deadline passed first. Absent leaves nothing behind, so a row without a deadline does not
346
+ * need one.
347
+ */
348
+ resultTarget?: StoryVariableRef;
349
+ };
350
+ type StoryInputActionPayload = {
351
+ action: "input";
352
+ /** Shake every connected pad. */
353
+ operation: "rumble";
354
+ preset?: StoryRumblePresetId;
355
+ /** Overrides the preset's left motor (or, under `custom`, is the left motor). */
356
+ strongMagnitude?: number;
357
+ /** Overrides the preset's right motor. */
358
+ weakMagnitude?: number;
359
+ /** Overrides the preset's length. */
360
+ durationMs?: number;
361
+ /** Hold the story until the rumble has finished. Absent lets the story move on at once. */
362
+ wait?: boolean;
363
+ } | {
364
+ action: "input";
365
+ /** End any rumble still running. */
366
+ operation: "stopRumble";
367
+ } | {
368
+ action: "input";
369
+ /**
370
+ * Take the story out of the player's hands: a click, the advance key, auto-forward and
371
+ * skipping all do nothing until an `unlock` row runs. Rows that do not wait for the player
372
+ * go on playing, which is what makes a locked passage a cutscene rather than a frozen frame -
373
+ * and why a dialogue line inside one strands the player.
374
+ *
375
+ * Its own member rather than `"lock" | "unlock"` on one, so a check of the two narrows the
376
+ * union the way every other operation here does.
377
+ */
378
+ operation: "lock";
379
+ } | {
380
+ action: "input";
381
+ /** Give the story back to the player. */
382
+ operation: "unlock";
383
+ } | ({
384
+ action: "input";
385
+ /** Wait for one press of the action. */
386
+ operation: "wait";
387
+ } & StoryInputWaitFields) | ({
388
+ action: "input";
389
+ /** Wait for the action to be held down, unbroken, for `holdMs`. */
390
+ operation: "hold";
391
+ holdMs: number;
392
+ } & StoryInputWaitFields) | ({
393
+ action: "input";
394
+ /** Wait for the action to be pressed `count` times. */
395
+ operation: "mash";
396
+ count: number;
397
+ } & StoryInputWaitFields);
232
398
  type AssetAxisResidency = "build" | "runtime";
233
399
  type AssetSetAxisKind = "locale" | "release";
234
400
  interface AssetSetAxis {
@@ -540,7 +706,8 @@ type StoryActionPayload = {
540
706
  value: StoryLiteralValue;
541
707
  /**
542
708
  * A computed right-hand side (`/set gold gold + 1`). **When present it wins**, and `value`
543
- * is only the last literal the row held - never read by the compiler.
709
+ * is never read by the compiler. A row written with an expression stores `null` there;
710
+ * older rows may hold the `true` a new assignment block starts with.
544
711
  *
545
712
  * Why not fold the literal case in here too: `/set gold 100` is the overwhelmingly common
546
713
  * row, `value` is what the inspector's literal editor binds to, and every document written
@@ -653,12 +820,18 @@ type StoryActionPayload = {
653
820
  transform?: StoryTransformRef;
654
821
  } | {
655
822
  action: "layer";
656
- operation: "create" | "setZIndex" | "show" | "hide" | "transform";
657
- objectName: string;
658
823
  /**
659
- * Which layer non-`create` ops act on - a built-in (`background`/`displayable`) or a custom
660
- * layer bound by its create block. `create` names a new custom layer via `objectName`.
824
+ * A step the story takes with one of the scene's layers. Declaring a layer is not one: the
825
+ * scene's layers are `StoryScene.layers` (v30), and `create` / `setDepth` are gone with it.
826
+ *
827
+ * `setZIndex` is kept for the rows that hold it and is no longer offered: it moves a layer in
828
+ * the stacking order part way through a scene, which the scene's stack - one order, the same
829
+ * as the layers' distances - has no way to say. A row that holds it still plays as it did.
661
830
  */
831
+ operation: "setZIndex" | "show" | "hide" | "transform";
832
+ /** The layer's name as the row was written, the fallback when {@link target} does not resolve. */
833
+ objectName: string;
834
+ /** Which layer the row acts on - a built-in (`background` / `displayable`) or one of the scene's own. */
662
835
  target?: StoryLayerRef;
663
836
  zIndex?: number;
664
837
  transform?: StoryTransformRef;
@@ -875,12 +1048,15 @@ type StoryActionPayload = {
875
1048
  /** The plugin's story-action id, itself namespaced by `pluginId`. */
876
1049
  actionId: string;
877
1050
  /**
878
- * What the author filled in on the row, for the owning pass to interpret. Studio never
879
- * reads inside it - the keys are the plugin's vocabulary - so it is only constrained to be
880
- * JSON, which is what makes the row survive a round trip through the project file.
1051
+ * What the author filled in on the row, for the owning plugin to interpret. Studio never
1052
+ * interprets it - the keys are the plugin's vocabulary - and writes a key only through a
1053
+ * field the plugin's action declares (`params` on its registration). It is only constrained
1054
+ * to be JSON, which is what makes the row survive a round trip through the project file.
881
1055
  */
882
1056
  params: Record<string, StoryPluginActionParamValue>;
883
- };
1057
+ }
1058
+ /** The player's hands: a pad that shakes, a locked passage, a row that waits for a gesture. */
1059
+ | StoryInputActionPayload;
884
1060
  type StoryPluginActionParamValue = string | number | boolean | null | StoryPluginActionParamValue[] | {
885
1061
  [key: string]: StoryPluginActionParamValue;
886
1062
  };
@@ -1177,9 +1353,10 @@ type StoryDisplayableTargetRef = {
1177
1353
  label?: string;
1178
1354
  /**
1179
1355
  * Stable identity of the displayable: the id of the action block that introduced it
1180
- * (character enter / image / text / layer). Displayables can only be declared statically,
1181
- * so this always points at a real creator block. When present it is the source of truth -
1182
- * the current stage name is resolved from that block, so the reference survives renames.
1356
+ * (character enter / image / text), or for a layer the id of the scene layer (v30: a layer is
1357
+ * declared by the scene, under the id its `create` row had). Displayables can only be declared
1358
+ * statically, so this always points at a real declaration. When present it is the source of
1359
+ * truth - the current stage name is resolved from it, so the reference survives renames.
1183
1360
  * `name` remains as a legacy fallback and last-known label when the source is unresolvable.
1184
1361
  */
1185
1362
  sourceBlockId?: StoryBlockId;
@@ -1194,9 +1371,10 @@ type StoryLayerRef = {
1194
1371
  layer: "background" | "displayable";
1195
1372
  } | {
1196
1373
  kind: "custom";
1197
- sourceBlockId?: StoryBlockId;
1374
+ sourceBlockId?: StorySceneLayerId;
1198
1375
  name?: string;
1199
1376
  };
1377
+ type StorySceneLayerId = string;
1200
1378
  type StoryActionableBuiltin = "bgm";
1201
1379
  type StoryActionableTargetRef = {
1202
1380
  /**
@@ -1817,6 +1995,10 @@ declare const en: {
1817
1995
  readonly one: "{count} warning";
1818
1996
  readonly other: "{count} warnings";
1819
1997
  };
1998
+ readonly minorWarnings: {
1999
+ readonly one: "{count} minor warning";
2000
+ readonly other: "{count} minor warnings";
2001
+ };
1820
2002
  readonly infos: {
1821
2003
  readonly one: "{count} info";
1822
2004
  readonly other: "{count} info";
@@ -1831,6 +2013,23 @@ declare const en: {
1831
2013
  readonly down: "down";
1832
2014
  readonly left: "left";
1833
2015
  readonly right: "right";
2016
+ readonly overview: "Overview";
2017
+ };
2018
+ readonly keys: {
2019
+ readonly arrowUp: "Arrow Up";
2020
+ readonly arrowDown: "Arrow Down";
2021
+ readonly arrowLeft: "Arrow Left";
2022
+ readonly arrowRight: "Arrow Right";
2023
+ readonly space: "Space";
2024
+ readonly plus: "Plus";
2025
+ readonly dpadUp: "D-pad Up";
2026
+ readonly dpadDown: "D-pad Down";
2027
+ readonly dpadLeft: "D-pad Left";
2028
+ readonly dpadRight: "D-pad Right";
2029
+ readonly leftStickUp: "Left Stick Up";
2030
+ readonly leftStickDown: "Left Stick Down";
2031
+ readonly leftStickLeft: "Left Stick Left";
2032
+ readonly leftStickRight: "Left Stick Right";
1834
2033
  };
1835
2034
  };
1836
2035
  readonly menu: {
@@ -1889,9 +2088,9 @@ declare const en: {
1889
2088
  readonly minimize: "Minimize";
1890
2089
  readonly zoom: "Zoom";
1891
2090
  readonly front: "Bring All to Front";
1892
- readonly leftSidebar: "Show Left Bar";
1893
- readonly bottomPanel: "Show Bottom Bar";
1894
- readonly rightSidebar: "Show Right Bar";
2091
+ readonly leftSidebar: "Toggle Left Bar";
2092
+ readonly bottomPanel: "Toggle Bottom Bar";
2093
+ readonly rightSidebar: "Toggle Right Bar";
1895
2094
  };
1896
2095
  readonly help: {
1897
2096
  readonly title: "Help";
@@ -1968,6 +2167,10 @@ declare const en: {
1968
2167
  readonly label: "Network";
1969
2168
  readonly description: "Where Studio downloads plugins, templates and build tooling from.";
1970
2169
  };
2170
+ readonly agent: {
2171
+ readonly label: "Agent access";
2172
+ readonly description: "Let AI agents connect to Studio over MCP and work on the open project.";
2173
+ };
1971
2174
  readonly data: {
1972
2175
  readonly label: "Data";
1973
2176
  readonly description: "Cached files, resetting preferences, and moving them between machines.";
@@ -1980,7 +2183,7 @@ declare const en: {
1980
2183
  };
1981
2184
  readonly developerMode: {
1982
2185
  readonly label: "Developer options";
1983
- readonly description: "Right-click menus gain a section for copying the ID of the item clicked.";
2186
+ readonly description: "Right-click menus gain a section for copying the ID of the item clicked, and the blueprint add-node menu shows each node's type ID.";
1984
2187
  };
1985
2188
  readonly screenEffectThreads: {
1986
2189
  readonly label: "Threads for screen effects";
@@ -2147,8 +2350,18 @@ declare const en: {
2147
2350
  readonly label: "Download address rewrites";
2148
2351
  };
2149
2352
  readonly useSystemProxy: {
2150
- readonly label: "Use this computer's proxy";
2151
- readonly description: "Studio downloads follow the proxy this computer already uses.";
2353
+ readonly label: "Use system proxy settings";
2354
+ readonly description: "Studio downloads connect through the proxy set in the operating system.";
2355
+ };
2356
+ readonly storeSource: {
2357
+ readonly label: "Store download source";
2358
+ readonly description: "Where the plugin store, the template store and spelling dictionaries are downloaded from. Automatic connects to GitHub and GitCode at once and uses the first to respond.";
2359
+ readonly options: {
2360
+ readonly auto: "Automatic";
2361
+ readonly gitcode: "GitCode (mainland China)";
2362
+ readonly custom: "Custom";
2363
+ };
2364
+ readonly customOnly: "Used when the store download source is Custom.";
2152
2365
  };
2153
2366
  readonly pluginRegistryUrl: {
2154
2367
  readonly label: "Plugin registry URL";
@@ -2226,6 +2439,13 @@ declare const en: {
2226
2439
  readonly keybindings: {
2227
2440
  readonly label: "Keyboard shortcuts";
2228
2441
  };
2442
+ readonly agentAccess: {
2443
+ readonly label: "MCP endpoint";
2444
+ };
2445
+ readonly agentFollow: {
2446
+ readonly label: "Follow the agent's edits";
2447
+ readonly description: "Open each page, scene or blueprint an agent changes, bring it to the front and outline the change.";
2448
+ };
2229
2449
  readonly projectTrust: {
2230
2450
  readonly label: "Trusted projects";
2231
2451
  readonly description: "Projects that Studio did not create, and whether they may run.";
@@ -2333,14 +2553,75 @@ declare const en: {
2333
2553
  readonly unknown: "The server could not be added.";
2334
2554
  };
2335
2555
  };
2556
+ readonly agent: {
2557
+ readonly loading: "Reading\u2026";
2558
+ readonly enable: "Allow agents to connect";
2559
+ readonly enableHint: "Serves an MCP endpoint on this computer for AI agents such as Claude Code and opencode.";
2560
+ readonly allowWrites: "Allow agents to change projects";
2561
+ readonly allowWritesHint: "When off, agents can read projects but every change they try is refused.";
2562
+ readonly fullAccess: "Allow agents full access";
2563
+ readonly fullAccessHint: "Agents may change projects and read any folder without asking, except Studio's own folders, the home folder as a whole and drive roots.";
2564
+ readonly endpoint: "Endpoint address";
2565
+ readonly running: "Listening.";
2566
+ readonly portMoved: "The endpoint moved to port {port}. Copy the connection configuration again for clients set up before.";
2567
+ readonly copyAddress: "Copy address";
2568
+ readonly stopped: "Not running.";
2569
+ readonly failed: "Could not start: {message}";
2570
+ readonly token: "Access token";
2571
+ readonly tokenHint: "Every request must carry it. It is part of the copied configuration.";
2572
+ readonly show: "Show";
2573
+ readonly hide: "Hide";
2574
+ readonly regenerate: "Regenerate access token";
2575
+ readonly regenerateHint: "Clients set up with the current token stop being let in.";
2576
+ readonly regenerateAction: "Regenerate";
2577
+ readonly copied: "Copied";
2578
+ readonly importRoots: "Folders agents may import from";
2579
+ readonly importRootsHint: "Agents can always import files from inside the project. When an agent needs another folder, Studio asks you and adds it here.";
2580
+ readonly importRootsEmpty: "No other folders.";
2581
+ readonly addFolder: "Add folder\u2026";
2582
+ readonly removeFolder: "Remove";
2583
+ readonly pluginTools: "Plugin tools";
2584
+ readonly pluginToolsHint: "Tools the enabled plugins offer agents. A plugin switched off here has its tools hidden from agents and their calls refused.";
2585
+ readonly pluginToolsEmpty: "No enabled plugin offers agent tools.";
2586
+ readonly pluginToolsCount: "{tools} tools, {writes} of which can change the project";
2587
+ readonly pluginToolsAllow: "Allow the agent tools of {plugin}";
2588
+ readonly guide: {
2589
+ readonly app: "Agent application";
2590
+ readonly appHint: "The connection configuration and Agent Skill below are for this application.";
2591
+ readonly other: "Other";
2592
+ readonly connection: "Connection configuration";
2593
+ readonly offHint: "Available once \"Allow agents to connect\" is on.";
2594
+ readonly runCommand: "Run in a terminal.";
2595
+ readonly mergeInto: "Merge into {file}.";
2596
+ readonly claudeDesktop: "Merge into claude_desktop_config.json (Settings \u25B8 Developer \u25B8 Edit Config in Claude), then restart Claude.";
2597
+ readonly otherClient: "Streamable HTTP. Enter this address and header in the client's MCP settings.";
2598
+ readonly skill: "Agent Skill";
2599
+ readonly skillFolder: "Installs into {path}. Other skills there are kept.";
2600
+ readonly skillInstall: "Install Agent Skill";
2601
+ readonly skillReinstall: "Reinstall";
2602
+ readonly skillInstalled: "Installed in {path}.";
2603
+ readonly skillUpload: "Saves a zip file to upload in Claude under Settings \u25B8 Capabilities \u25B8 Skills.";
2604
+ readonly skillSave: "Save zip file\u2026";
2605
+ readonly skillSaved: "Saved to {path}.";
2606
+ readonly skillServed: "Other applications read the same guide from Studio's MCP server.";
2607
+ readonly skillExport: "Export Agent Skill\u2026";
2608
+ readonly skillExported: "Exported to {path}.";
2609
+ readonly copyFailed: "The connection configuration could not be copied: {error}";
2610
+ readonly installFailed: "The Agent Skill could not be installed: {error}";
2611
+ readonly saveFailed: "The Agent Skill could not be saved: {error}";
2612
+ readonly exportFailed: "The Agent Skill could not be exported: {error}";
2613
+ };
2614
+ };
2336
2615
  readonly data: {
2337
2616
  readonly projectTrust: {
2338
2617
  readonly loading: "Reading\u2026";
2339
- readonly empty: "Every project opened so far was created by Studio.";
2618
+ readonly empty: "No projects.";
2340
2619
  readonly waiting: "Waiting for a decision";
2341
2620
  readonly granted: "Trusted";
2342
2621
  readonly trust: "Trust";
2343
- readonly remove: "Remove";
2622
+ readonly revoke: "Revoke";
2623
+ readonly delete: "Remove from list";
2624
+ readonly deleteCovered: "Inside a trusted project and cannot be removed";
2344
2625
  readonly reloadNote: "A project that is open reloads when its trust changes.";
2345
2626
  readonly origin: {
2346
2627
  readonly package: "From a package";
@@ -2403,6 +2684,10 @@ declare const en: {
2403
2684
  readonly label: "PSD import working files";
2404
2685
  readonly description: "Layer images written while importing a PSD.";
2405
2686
  };
2687
+ readonly payloadReaders: {
2688
+ readonly label: "Protected build readers";
2689
+ readonly description: "Readers copied from builds with asset protection to export a patch or DLC. Copied again the next time one is exported.";
2690
+ };
2406
2691
  readonly logs: {
2407
2692
  readonly label: "Logs";
2408
2693
  readonly description: "The logs an exported diagnostics file is built from.";
@@ -2973,6 +3258,217 @@ declare const en: {
2973
3258
  readonly surfaceEdit: "interface edit";
2974
3259
  readonly blueprintEdit: "blueprint edit";
2975
3260
  readonly replaceText: "text replacement";
3261
+ readonly agentEdit: "agent edit";
3262
+ readonly agentPluginEdit: "agent: {tool}";
3263
+ };
3264
+ };
3265
+ readonly agent: {
3266
+ readonly status: {
3267
+ readonly editing: "Agent editing: {name}";
3268
+ readonly working: "Agent working";
3269
+ readonly connected: "Agent: {client}";
3270
+ readonly edited: "Agent edited: {name}";
3271
+ readonly unknownClient: "external agent";
3272
+ readonly paused: "Agent paused";
3273
+ };
3274
+ readonly menu: {
3275
+ readonly pause: "Pause agent";
3276
+ readonly resume: "Resume agent";
3277
+ readonly follow: "Follow the agent's edits";
3278
+ };
3279
+ readonly tooltip: "Agent options";
3280
+ readonly appMenu: {
3281
+ readonly title: "Agent";
3282
+ readonly status: "Agent: {client} \u00B7 {state}";
3283
+ readonly statusOff: "Agent access: Off";
3284
+ readonly notConnected: "Not connected";
3285
+ readonly state: {
3286
+ readonly working: "Working";
3287
+ readonly idle: "Idle";
3288
+ readonly paused: "Paused";
3289
+ };
3290
+ readonly log: "Agent log";
3291
+ readonly enable: "Enable agent access";
3292
+ readonly allowWrites: "Allow agents to change projects";
3293
+ readonly fullAccess: "Allow agents full access";
3294
+ readonly copyConfig: "Copy connection configuration";
3295
+ readonly exportSkill: "Export Agent Skill\u2026";
3296
+ readonly settings: "Agent access settings\u2026";
3297
+ readonly notice: {
3298
+ readonly copied: "Configuration for {client} copied";
3299
+ readonly copyFailed: "The configuration could not be copied: {error}";
3300
+ readonly toggleFailed: "Agent access could not be changed: {error}";
3301
+ readonly exported: "Agent Skill exported to {path}";
3302
+ readonly exportFailed: "The Agent Skill could not be exported: {error}";
3303
+ };
3304
+ };
3305
+ readonly confirm: {
3306
+ readonly window: "Agent Access";
3307
+ readonly loadError: "The request could not be read.";
3308
+ readonly enable: {
3309
+ readonly message: "Turn on agent access?";
3310
+ readonly detail: "Agents connected to Studio can then read every project open in Studio. Changing projects needs a separate permission.";
3311
+ readonly allow: "Turn on";
3312
+ };
3313
+ readonly allowWrites: {
3314
+ readonly message: "Allow agents to change projects?";
3315
+ readonly detail: "Connected agents can then create, change and delete content in open projects. Most changes can be undone.";
3316
+ readonly allow: "Allow";
3317
+ };
3318
+ readonly exportSkill: {
3319
+ readonly title: "Export Agent Skill";
3320
+ readonly existsMessage: "This folder already contains {folder}";
3321
+ readonly existsDetail: "Files with the same name are replaced. Other files in the folder are kept.";
3322
+ readonly replace: "Replace";
3323
+ };
3324
+ readonly installSkill: {
3325
+ readonly title: "Install Agent Skill";
3326
+ readonly changedOne: "This folder holds a SKILL.md that differs from Studio's";
3327
+ readonly changedMany: "These folders hold a SKILL.md that differs from Studio's";
3328
+ readonly changedDetail: "Files with the same name are replaced with this version of Studio's Agent Skill. Other skills are kept.";
3329
+ readonly replace: "Replace";
3330
+ };
3331
+ readonly folderAccess: {
3332
+ readonly title: "Allow agents to read folders?";
3333
+ readonly messageOne: "{client} wants to read this folder";
3334
+ readonly messageMany: "{client} wants to read these folders";
3335
+ readonly detail: "The agent reads the files there to import them into this project. Nothing outside the project is changed.";
3336
+ readonly reason: "Purpose stated by the agent: {reason}";
3337
+ readonly settings: "Allowed folders stay allowed for every agent until removed in Settings \u25B8 Agent access, which also offers full access.";
3338
+ readonly allowOne: "Allow this folder";
3339
+ readonly allowMany: "Allow these folders";
3340
+ readonly deny: "Deny";
3341
+ readonly unknownClient: "An external agent";
3342
+ };
3343
+ readonly fullAccess: {
3344
+ readonly message: "Allow agents full access?";
3345
+ readonly detail: "Connected agents can then change projects and read files in any folder without asking, except Studio's own folders, the home folder as a whole and drive roots. Turn it off in the Agent menu or in Settings \u25B8 Agent access.";
3346
+ readonly allow: "Allow full access";
3347
+ };
3348
+ };
3349
+ readonly log: {
3350
+ readonly pluginTool: "A tool of the plugin {plugin}";
3351
+ readonly target: {
3352
+ readonly standardScreens: "Standard screens";
3353
+ };
3354
+ readonly filter: {
3355
+ readonly all: "All calls";
3356
+ readonly writes: "Changes only";
3357
+ readonly failures: "Failures only";
3358
+ };
3359
+ readonly filterAria: "Filter calls";
3360
+ readonly listAria: "Agent calls";
3361
+ readonly export: "Export\u2026";
3362
+ readonly exportHint: "Export as JSON Lines";
3363
+ readonly empty: "No agent calls";
3364
+ readonly emptyHint: "Agents connect through Agent access in Settings.";
3365
+ readonly emptyFiltered: "No calls match this filter";
3366
+ readonly running: "Running";
3367
+ readonly ok: "Succeeded";
3368
+ readonly durationMs: "{value} ms";
3369
+ readonly durationS: "{value} s";
3370
+ readonly showChange: "Show the change";
3371
+ readonly targetGone: "That item no longer exists";
3372
+ readonly message: "Reply sent to the agent";
3373
+ readonly hint: "Hint sent to the agent";
3374
+ readonly exported: "Agent log exported to {path}";
3375
+ readonly exportFailed: "The Agent log could not be exported: {error}";
3376
+ readonly exportEmpty: "The Agent log is empty";
3377
+ readonly code: {
3378
+ readonly invalid_args: "Invalid arguments";
3379
+ readonly unknown_tool: "Unknown tool";
3380
+ readonly no_workspace: "No open project";
3381
+ readonly writes_disabled: "Changes not allowed";
3382
+ readonly paused: "Paused";
3383
+ readonly frozen: "Project frozen";
3384
+ readonly live_session: "Live session running";
3385
+ readonly stale_revision: "Changed since read";
3386
+ readonly check_failed: "Check failed";
3387
+ readonly not_found: "Not found";
3388
+ readonly path_not_allowed: "Folder not allowed";
3389
+ readonly untrusted: "Project not trusted";
3390
+ readonly unavailable: "Unavailable";
3391
+ readonly internal: "Internal error";
3392
+ };
3393
+ };
3394
+ readonly tool: {
3395
+ readonly agent_status: "Studio status";
3396
+ readonly agent_guide: "Read the guide";
3397
+ readonly request_folder_access: "Ask for folder access";
3398
+ readonly project_create: "Create a project";
3399
+ readonly project_open: "Open a project";
3400
+ readonly project_info: "Project overview";
3401
+ readonly project_settings_set: "Change project settings";
3402
+ readonly assets_list: "List assets";
3403
+ readonly assets_import: "Import files";
3404
+ readonly assets_placeholder: "Make a placeholder image";
3405
+ readonly asset_delete: "Delete an asset";
3406
+ readonly characters_list: "List characters";
3407
+ readonly character_upsert: "Create or update a character";
3408
+ readonly character_layered_set: "Lay out a layered character";
3409
+ readonly character_layers_import: "Build a layered character from files";
3410
+ readonly character_preview: "Preview a character look";
3411
+ readonly variables_list: "List variables";
3412
+ readonly variable_upsert: "Create or update a variable";
3413
+ readonly variable_delete: "Delete a variable";
3414
+ readonly audio_tracks_list: "List audio tracks";
3415
+ readonly story_commands: "Story command catalog";
3416
+ readonly story_command: "Story command details";
3417
+ readonly story_targets: "Names a story line can use";
3418
+ readonly story_list: "List stories and scenes";
3419
+ readonly story_rename: "Rename a story";
3420
+ readonly story_show: "Read a scene as text";
3421
+ readonly story_apply: "Write a scene";
3422
+ readonly scene_create: "Create a scene";
3423
+ readonly scene_rename: "Rename a scene";
3424
+ readonly scene_set_entry: "Set the entry scene";
3425
+ readonly scene_delete: "Delete a scene";
3426
+ readonly character_delete: "Delete a character";
3427
+ readonly ui_widgets: "Widget catalog";
3428
+ readonly ui_widget: "Widget details";
3429
+ readonly ui_usage: "Widget usage examples";
3430
+ readonly ui_surfaces: "List pages and components";
3431
+ readonly ui_show: "Read a page as text";
3432
+ readonly ui_selection: "What the author selected";
3433
+ readonly ui_screenshot: "Look at a page";
3434
+ readonly ui_apply: "Write pages";
3435
+ readonly ui_patch: "Edit elements";
3436
+ readonly ui_templates: "Interface templates";
3437
+ readonly ui_template_apply: "Apply a template";
3438
+ readonly ui_page_rename: "Rename a page";
3439
+ readonly ui_page_delete: "Delete a page";
3440
+ readonly ui_page_set_entry: "Set the entry page";
3441
+ readonly ui_install_standard_screens: "Install the standard screens";
3442
+ readonly brand_get: "Read the palette";
3443
+ readonly brand_set: "Change the palette";
3444
+ readonly blueprint_nodes: "Blueprint node catalog";
3445
+ readonly blueprint_node: "Blueprint node details";
3446
+ readonly blueprint_list: "List blueprints";
3447
+ readonly blueprint_show: "Read a blueprint as text";
3448
+ readonly blueprint_apply: "Write blueprints";
3449
+ readonly blueprint_remove: "Remove a blueprint";
3450
+ readonly localization_status: "Translation progress";
3451
+ readonly localization_list: "List text to translate";
3452
+ readonly localization_set: "Write translations";
3453
+ readonly voice_status: "Voice-over progress";
3454
+ readonly voice_list: "List voiced lines";
3455
+ readonly voice_link: "Link voice takes";
3456
+ readonly voice_auto_link: "Link takes by name";
3457
+ readonly voice_settings_set: "Change voice settings";
3458
+ readonly lint: "Check the project";
3459
+ readonly test: "Run a project test";
3460
+ readonly playtest_start: "Play the game";
3461
+ readonly playtest_advance: "Advance the game";
3462
+ readonly playtest_screenshot: "Look at the game";
3463
+ readonly asset_usage: "Where an asset is used";
3464
+ readonly chapter_rename: "Rename a chapter";
3465
+ readonly chapter_delete: "Delete a chapter";
3466
+ readonly playtest_click: "Click in the game";
3467
+ readonly playtest_hover: "Hover in the game";
3468
+ readonly playtest_key: "Press a key in the game";
3469
+ readonly playtest_stop: "Stop playing";
3470
+ readonly console_read: "Read Studio's console";
3471
+ readonly build: "Build the game";
2976
3472
  };
2977
3473
  };
2978
3474
  readonly shell: {
@@ -3110,10 +3606,6 @@ declare const en: {
3110
3606
  readonly noActiveEditor: "No active editor";
3111
3607
  readonly closePanel: "Close panel";
3112
3608
  readonly closeTab: "Close {name}";
3113
- readonly newTab: "New tab";
3114
- readonly newTabPage: {
3115
- readonly title: "New Tab";
3116
- };
3117
3609
  readonly tabMenu: {
3118
3610
  readonly keepOpen: "Keep open";
3119
3611
  readonly close: "Close";
@@ -3125,9 +3617,6 @@ declare const en: {
3125
3617
  readonly closeSplit: "Close split";
3126
3618
  readonly reopenClosed: "Reopen closed tab";
3127
3619
  };
3128
- readonly toggleLeftSidebar: "Toggle left sidebar";
3129
- readonly toggleRightSidebar: "Toggle right sidebar";
3130
- readonly toggleBottomPanel: "Toggle bottom panel";
3131
3620
  readonly mainMenu: {
3132
3621
  readonly label: "Main menu";
3133
3622
  readonly modes: {
@@ -3201,6 +3690,8 @@ declare const en: {
3201
3690
  readonly editorPlateOpacity: "Editor background opacity";
3202
3691
  readonly sidebarPlate: "Sidebar background";
3203
3692
  readonly sidebarPlateOpacity: "Sidebar background opacity";
3693
+ readonly framePlate: "Frame background";
3694
+ readonly framePlateOpacity: "Frame background opacity";
3204
3695
  readonly fill: {
3205
3696
  readonly cover: "Scale to fill";
3206
3697
  readonly contain: "Fit";
@@ -3222,6 +3713,7 @@ declare const en: {
3222
3713
  readonly asset: "Asset";
3223
3714
  readonly blueprint: "Blueprint";
3224
3715
  };
3716
+ readonly ordinal: "Item {n}";
3225
3717
  };
3226
3718
  readonly statusBar: {
3227
3719
  readonly distrusted: {
@@ -3283,6 +3775,7 @@ declare const en: {
3283
3775
  readonly textEncoding: "Text encoding";
3284
3776
  readonly textLineEnding: "Line ending";
3285
3777
  readonly textSelection: "Cursor position";
3778
+ readonly agent: "Agent";
3286
3779
  };
3287
3780
  };
3288
3781
  readonly save: {
@@ -3631,6 +4124,7 @@ declare const en: {
3631
4124
  readonly openSettings: "Customize Keyboard Shortcuts";
3632
4125
  readonly cheatSheetTitle: "Shortcuts and Mouse Actions";
3633
4126
  readonly cheatSheetCustomize: "Customize\u2026";
4127
+ readonly cheatSheetFocused: "Focused: {name}";
3634
4128
  readonly categories: {
3635
4129
  readonly general: "General";
3636
4130
  readonly run: "Run";
@@ -3703,13 +4197,36 @@ declare const en: {
3703
4197
  readonly storyMotion: {
3704
4198
  readonly undo: "Undo";
3705
4199
  readonly redo: "Redo";
3706
- readonly delete: "Delete Keyframe";
4200
+ readonly delete: "Delete Selected Keyframes";
3707
4201
  readonly prevFrame: "Step Playhead Back One Frame";
3708
4202
  readonly nextFrame: "Step Playhead Forward One Frame";
3709
4203
  readonly prevFrames: "Step Playhead Back Ten Frames";
3710
4204
  readonly nextFrames: "Step Playhead Forward Ten Frames";
3711
4205
  readonly playheadStart: "Move Playhead to Start";
3712
4206
  readonly playheadEnd: "Move Playhead to End";
4207
+ readonly playPause: "Play or Pause";
4208
+ readonly playReverse: "Play Backwards";
4209
+ readonly stop: "Stop";
4210
+ readonly playForward: "Play Forwards";
4211
+ readonly loop: "Toggle Loop";
4212
+ readonly prevKeyframe: "Go to Previous Keyframe";
4213
+ readonly nextKeyframe: "Go to Next Keyframe";
4214
+ readonly insertKeyframe: "Add Keyframes at Playhead";
4215
+ readonly selectAll: "Select All Keyframes";
4216
+ readonly clearSelection: "Clear Selection";
4217
+ readonly copy: "Copy Keyframes";
4218
+ readonly cut: "Cut Keyframes";
4219
+ readonly paste: "Paste Keyframes at Playhead";
4220
+ readonly nudgeLeft: "Move Keyframes Back One Frame";
4221
+ readonly nudgeRight: "Move Keyframes Forward One Frame";
4222
+ readonly nudgeLeftLarge: "Move Keyframes Back Ten Frames";
4223
+ readonly nudgeRightLarge: "Move Keyframes Forward Ten Frames";
4224
+ readonly zoomIn: "Zoom Timeline In";
4225
+ readonly zoomOut: "Zoom Timeline Out";
4226
+ readonly zoomFit: "Fit Motion in Timeline";
4227
+ readonly libraryRename: "Rename Motion";
4228
+ readonly libraryDuplicate: "Duplicate Selected Motions";
4229
+ readonly libraryDelete: "Delete Selected Motions";
3713
4230
  };
3714
4231
  };
3715
4232
  readonly gestures: {
@@ -3742,7 +4259,11 @@ declare const en: {
3742
4259
  readonly doubleClickGroupTitle: "Double-click a group's title";
3743
4260
  readonly middleClickTitle: "Middle-click the title row";
3744
4261
  readonly doubleClickTrack: "Double-click a track";
4262
+ readonly dragKeyframe: "Drag a keyframe";
4263
+ readonly clickKeyframe: "Click a keyframe";
4264
+ readonly dragAcrossTracks: "Drag across the tracks";
3745
4265
  readonly clickAsset: "Click an asset";
4266
+ readonly clickMotion: "Click a motion";
3746
4267
  readonly doubleClick: "Double-click";
3747
4268
  readonly dragToEditorArea: "Drag into the editor area";
3748
4269
  readonly dragOntoGroup: "Drag onto a group";
@@ -3790,11 +4311,17 @@ declare const en: {
3790
4311
  readonly renameGroup: "Rename a Group";
3791
4312
  };
3792
4313
  readonly storyMotion: {
3793
- readonly noFrameSnap: "Drag Without Frame Snapping";
4314
+ readonly noFrameSnap: "Drag Without Snapping";
4315
+ readonly moveKeyframes: "Move Keyframes";
4316
+ readonly boxSelect: "Select Keyframes in a Box";
4317
+ readonly selectTrack: "Select a Track's Keyframes";
3794
4318
  readonly addKeyframe: "Add a Keyframe";
3795
4319
  readonly panPreview: "Pan the Preview";
3796
4320
  readonly zoom: "Zoom the Preview or Timeline";
3797
4321
  readonly scrollTimeline: "Scroll the Timeline Sideways";
4322
+ readonly openMotion: "Open a Motion";
4323
+ readonly selectMotionRange: "Select a Range of Motions";
4324
+ readonly selectAllMotions: "Select All Motions";
3798
4325
  };
3799
4326
  readonly assets: {
3800
4327
  readonly selectAssetRange: "Select a Range of Assets";
@@ -3808,6 +4335,9 @@ declare const en: {
3808
4335
  readonly clearMarker: "Clear a Marker";
3809
4336
  readonly videoZoom: "Zoom the Picture";
3810
4337
  readonly videoActualSize: "Switch Between Fit and Actual Pixels";
4338
+ readonly moveSelection: "Move the Selection";
4339
+ readonly extendSelection: "Extend the Selection";
4340
+ readonly moveThroughGroupTree: "Move Through the Group Tree";
3811
4341
  };
3812
4342
  };
3813
4343
  };
@@ -4052,6 +4582,7 @@ declare const en: {
4052
4582
  };
4053
4583
  readonly reason: {
4054
4584
  readonly blueprintAction: "A blueprint runs this row, and a blueprint has no script form.";
4585
+ readonly inputAction: "This row works with the player's input or the controller's rumble, and has no script form.";
4055
4586
  readonly blueprintCondition: "A blueprint decides this condition.";
4056
4587
  readonly blueprintInterpolation: "A blueprint computes a value inside this text.";
4057
4588
  readonly inlineEvent: "The text carries an event that fires while it is being typed out.";
@@ -4077,6 +4608,7 @@ declare const en: {
4077
4608
  readonly danglingBranch: "This branch has no condition above it.";
4078
4609
  readonly badTag: "This line carries a formatting tag that is unknown, or left open.";
4079
4610
  readonly badExpression: "This expression does not resolve.";
4611
+ readonly layerDeclaration: "A script cannot declare a layer. Add it to the scene's layers";
4080
4612
  };
4081
4613
  readonly view: {
4082
4614
  readonly open: "Read as a script";
@@ -4308,10 +4840,35 @@ declare const en: {
4308
4840
  };
4309
4841
  readonly layerField: {
4310
4842
  readonly label: "Layer";
4311
- readonly defaultName: "Displayable layer";
4312
- readonly notOnStageTitle: "No layer with this name is declared earlier in this scene. Pick an existing layer";
4313
- readonly hint: "Layer";
4843
+ readonly defaultName: "Base layer";
4844
+ readonly notOnStageTitle: "This scene has no layer with this name. Pick one of its layers";
4314
4845
  readonly createNew: "Create new layer";
4846
+ readonly backgroundName: "Background layer";
4847
+ readonly displayableHint: "The default layer, always at distance 1";
4848
+ readonly backgroundHint: "No nearer than the base layer";
4849
+ readonly manage: "Manage layers\u2026";
4850
+ };
4851
+ readonly sceneLayers: {
4852
+ readonly open: "Scene layers";
4853
+ readonly unnamed: "Unnamed layer";
4854
+ readonly defaultName: "Layer {index}";
4855
+ readonly distance: "Distance {value}";
4856
+ readonly distanceColumn: "Distance";
4857
+ readonly distanceTip: "Measured from the base layer, which is at 1. Larger values are farther away and move less with the camera; at \u221E the layer stays still";
4858
+ readonly distanceInvalid: "Enter a value from 0.5 to 100, or \u221E";
4859
+ readonly levelKeepsBase: "The base layer stays at 1; the other layers at this level move together";
4860
+ readonly frontToBack: "Front to back";
4861
+ readonly fixedTip: "The base layer is always at distance 1; every other distance is measured from it";
4862
+ readonly backgroundDragTip: "Drag to change the layer's distance; the background layer cannot come nearer than the base layer";
4863
+ readonly dragTip: "Drag to change the layer's distance";
4864
+ readonly remove: "Remove layer";
4865
+ readonly inUseOne: "1 row uses this layer";
4866
+ readonly inUseMany: "{count} rows use this layer";
4867
+ readonly nameTaken: "This scene already has a layer with this name";
4868
+ readonly nameReserved: "This name refers to a built-in layer";
4869
+ readonly swayCaption: "Camera moving";
4870
+ readonly framingCaption: "This row's shot";
4871
+ readonly lookHint: "The camera follows the pointer; scroll to zoom";
4315
4872
  };
4316
4873
  readonly appearance: {
4317
4874
  readonly noPoses: "This character has no poses yet.";
@@ -4445,6 +5002,16 @@ declare const en: {
4445
5002
  readonly labelName: "Label";
4446
5003
  readonly endingName: "Ending";
4447
5004
  readonly quitPage: "Page";
5005
+ readonly rumblePreset: "Shape";
5006
+ readonly rumbleLeft: "Left Motor";
5007
+ readonly rumbleRight: "Right Motor";
5008
+ readonly rumbleWait: "Wait for the rumble";
5009
+ readonly inputLock: "Lock / Unlock";
5010
+ readonly inputAction: "Input Action";
5011
+ readonly inputTimeout: "Time Limit";
5012
+ readonly inputResult: "Result Variable";
5013
+ readonly holdDuration: "Hold Seconds";
5014
+ readonly mashCount: "Presses";
4448
5015
  readonly scene: "Scene";
4449
5016
  readonly track: "Audio Track";
4450
5017
  readonly appTag: "Build Variant";
@@ -4470,7 +5037,8 @@ declare const en: {
4470
5037
  readonly hold: "Hold Seconds";
4471
5038
  readonly opacity: "Opacity";
4472
5039
  readonly size: "Font Size";
4473
- readonly z: "Z-Index";
5040
+ readonly xOffset: "X Offset px";
5041
+ readonly yOffset: "Y Offset px";
4474
5042
  readonly zoom: "Zoom";
4475
5043
  readonly scale: "Scale";
4476
5044
  readonly scaleX: "Scale X";
@@ -4508,6 +5076,15 @@ declare const en: {
4508
5076
  readonly conceal: "Conceal";
4509
5077
  };
4510
5078
  readonly enumValue: {
5079
+ readonly tap: "tap";
5080
+ readonly pulse: "pulse";
5081
+ readonly impact: "impact";
5082
+ readonly quake: "quake";
5083
+ readonly alert: "alert";
5084
+ readonly custom: "custom";
5085
+ readonly stop: "stop";
5086
+ readonly lock: "lock";
5087
+ readonly unlock: "unlock";
4511
5088
  readonly loop: "loop";
4512
5089
  readonly reverse: "reverse";
4513
5090
  readonly mirror: "mirror";
@@ -4692,6 +5269,7 @@ declare const en: {
4692
5269
  readonly label: "Label in this scene";
4693
5270
  readonly appTag: "Build variant";
4694
5271
  readonly surface: "Page";
5272
+ readonly inputAction: "Input action";
4695
5273
  readonly variable: "Variable";
4696
5274
  readonly content: "New content, typed by the target";
4697
5275
  readonly color: "Color";
@@ -4735,8 +5313,6 @@ declare const en: {
4735
5313
  };
4736
5314
  readonly insert: "Insert a blank row after this one";
4737
5315
  readonly delete: "Delete this row";
4738
- readonly insertTitle: "Insert a blank row after this one ({keys})";
4739
- readonly deleteTitle: "Delete this row ({keys})";
4740
5316
  readonly playFromRow: "Play from this row";
4741
5317
  readonly playBranch: "Play this branch";
4742
5318
  readonly insertPlaceholder: "Type narration, {trigger} for actions, # for characters\u2026";
@@ -4804,6 +5380,8 @@ declare const en: {
4804
5380
  readonly dock: "Dock in the scene editor";
4805
5381
  readonly pip: "Picture-in-picture";
4806
5382
  readonly skipTyping: "Skip typing animation";
5383
+ readonly viewStage: "Stage";
5384
+ readonly viewLayers: "Layers";
4807
5385
  readonly selectRow: "Select a story row to preview its stage state.";
4808
5386
  readonly failed: "Preview failed";
4809
5387
  readonly settleTimeout: "The stage did not finish setting up in time.";
@@ -4916,7 +5494,7 @@ declare const en: {
4916
5494
  readonly notOnStage: {
4917
5495
  readonly image: "Image \u201C{name}\u201D is not on stage; an earlier row has to create it.";
4918
5496
  readonly text: "Text \u201C{name}\u201D is not on stage; an earlier row has to create it.";
4919
- readonly layer: "Layer \u201C{name}\u201D is not on stage; an earlier row has to create it.";
5497
+ readonly layer: "This scene has no layer \u201C{name}\u201D.";
4920
5498
  readonly video: "Video \u201C{name}\u201D is not on stage; an earlier row has to play it.";
4921
5499
  readonly ambience: "Ambience effect \u201C{name}\u201D is not on stage; an earlier row has to create it.";
4922
5500
  readonly character: "Character \u201C{name}\u201D is not on stage; an earlier row has to bring it on stage.";
@@ -5101,7 +5679,7 @@ declare const en: {
5101
5679
  };
5102
5680
  readonly layer: {
5103
5681
  readonly label: "Layer";
5104
- readonly detail: "Create a render layer";
5682
+ readonly detail: "Add a layer to this scene";
5105
5683
  };
5106
5684
  readonly swap: {
5107
5685
  readonly label: "Swap";
@@ -5235,6 +5813,26 @@ declare const en: {
5235
5813
  readonly label: "Quit to page";
5236
5814
  readonly detail: "End this playthrough at this line and show a page. No ending is recorded";
5237
5815
  };
5816
+ readonly rumble: {
5817
+ readonly label: "Rumble";
5818
+ readonly detail: "Vibrate the player's controller. Pick a preset, or set each motor";
5819
+ };
5820
+ readonly input: {
5821
+ readonly label: "Input lock";
5822
+ readonly detail: "Lock or unlock player input. While locked, clicking to advance, the advance key, auto-forward and skipping do nothing; choices can still be picked. Unlock before the next line of dialogue";
5823
+ };
5824
+ readonly waitInput: {
5825
+ readonly label: "Wait for input";
5826
+ readonly detail: "Wait until the player performs an input action, optionally within a time limit";
5827
+ };
5828
+ readonly hold: {
5829
+ readonly label: "Hold";
5830
+ readonly detail: "Wait until the player holds an input action down for a number of seconds";
5831
+ };
5832
+ readonly mash: {
5833
+ readonly label: "Mash";
5834
+ readonly detail: "Wait until the player presses an input action a number of times";
5835
+ };
5238
5836
  readonly blueprint: {
5239
5837
  readonly label: "Blueprint";
5240
5838
  readonly detail: "Run a Story Action Blueprint";
@@ -5297,6 +5895,8 @@ declare const en: {
5297
5895
  readonly cut: "Cut point";
5298
5896
  readonly ending: "Ending";
5299
5897
  readonly quit: "Quit to page";
5898
+ readonly rumble: "Rumble";
5899
+ readonly input: "Input";
5300
5900
  readonly jump: "Jump";
5301
5901
  readonly note: "Note";
5302
5902
  readonly invalid: "Invalid";
@@ -5341,6 +5941,7 @@ declare const en: {
5341
5941
  readonly image: "{operation} image {name}";
5342
5942
  readonly text: "{operation} text {name}";
5343
5943
  readonly layer: "{operation} layer {name}";
5944
+ readonly layerZIndex: "Layer {name} to z-index {z}";
5344
5945
  readonly video: "{operation} video {name}";
5345
5946
  readonly vfx: "{operation} ambience {name}";
5346
5947
  readonly nvl: "NVL block";
@@ -5362,6 +5963,17 @@ declare const en: {
5362
5963
  readonly cutUnknown: "Cut point";
5363
5964
  readonly ending: "Ending {name}";
5364
5965
  readonly quit: "Quit to {page}";
5966
+ readonly rumble: "Rumble: {shape}";
5967
+ readonly rumbleStop: "Stop rumble";
5968
+ readonly inputLock: "Lock player input";
5969
+ readonly inputUnlock: "Unlock player input";
5970
+ readonly inputActionNamed: "\"{name}\"";
5971
+ readonly inputAnyAction: "any input";
5972
+ readonly inputActionUnknown: "an input action";
5973
+ readonly inputActionNotFound: "unknown input action";
5974
+ readonly inputWait: "Wait for {action}";
5975
+ readonly inputHold: "Hold {action} for {seconds}s";
5976
+ readonly inputMash: "Press {action} {count} times";
5365
5977
  readonly quitUnset: "Quit to page";
5366
5978
  readonly jump: "Jump {scene}";
5367
5979
  readonly note: "Note";
@@ -5404,6 +6016,7 @@ declare const en: {
5404
6016
  readonly history: {
5405
6017
  readonly deleteScene: "delete scene {name}";
5406
6018
  readonly deleteChapter: "delete chapter {name}";
6019
+ readonly renameChapter: "rename chapter {name}";
5407
6020
  readonly deleteStory: "delete story {name}";
5408
6021
  readonly deleteAnimation: "delete motion {name}";
5409
6022
  readonly moveScene: "move scene {name}";
@@ -5503,6 +6116,11 @@ declare const en: {
5503
6116
  duplicateVariable: string;
5504
6117
  compoundWithoutTarget: string;
5505
6118
  };
6119
+ assetType: {
6120
+ image: string;
6121
+ audio: string;
6122
+ video: string;
6123
+ };
5506
6124
  reason: {
5507
6125
  unknownCommand: string;
5508
6126
  unknownCommandNear: string;
@@ -5519,17 +6137,22 @@ declare const en: {
5519
6137
  unknownLabel: string;
5520
6138
  unknownAppTag: string;
5521
6139
  unknownSurface: string;
6140
+ unknownInputAction: string;
5522
6141
  unknownVariable: string;
5523
6142
  unknownForm: string;
5524
6143
  notPuppetCharacter: string;
5525
6144
  ambiguousName: string;
5526
6145
  conflictingParams: string;
6146
+ positionOutOfRange: string;
6147
+ offsetWithoutPosition: string;
5527
6148
  repeatTimesAndUntil: string;
5528
6149
  expressionError: string;
5529
6150
  expressionNotBoolean: string;
5530
6151
  expressionTypeMismatch: string;
5531
6152
  duplicateVariable: string;
5532
6153
  reservedVariableName: string;
6154
+ duplicateLayer: string;
6155
+ reservedLayerName: string;
5533
6156
  unknownTarget: string;
5534
6157
  unsupportedTarget: string;
5535
6158
  unsupportedTargetLayer: string;
@@ -5940,6 +6563,9 @@ declare const en: {
5940
6563
  readonly targetScene: "Target scene";
5941
6564
  readonly returnable: "Return after the target scene";
5942
6565
  };
6566
+ readonly setVariable: {
6567
+ readonly missingScene: "Missing scene";
6568
+ };
5943
6569
  readonly note: {
5944
6570
  readonly label: "Note";
5945
6571
  };
@@ -5947,6 +6573,9 @@ declare const en: {
5947
6573
  readonly storyActionTitle: "Story Action";
5948
6574
  readonly name: "Blueprint name";
5949
6575
  };
6576
+ readonly plugin: {
6577
+ readonly missingOption: "{value} (missing)";
6578
+ };
5950
6579
  readonly audio: {
5951
6580
  readonly track: "Track";
5952
6581
  readonly trackDefault: "Default ({name})";
@@ -5972,8 +6601,8 @@ declare const en: {
5972
6601
  readonly text: "Text";
5973
6602
  };
5974
6603
  readonly layer: {
5975
- readonly layerName: "Layer name";
5976
6604
  readonly zIndex: "Z-index";
6605
+ readonly zIndexRowHint: "A layer's starting order is set by the scene's layers.";
5977
6606
  };
5978
6607
  readonly video: {
5979
6608
  readonly videoName: "Video name";
@@ -5984,6 +6613,20 @@ declare const en: {
5984
6613
  readonly waitForEnd: "Wait for the video";
5985
6614
  readonly skipHint: "The player can end the video early by clicking or pressing the skip key.";
5986
6615
  };
6616
+ readonly input: {
6617
+ readonly shape: "Shape";
6618
+ readonly leftMotor: "Left motor (0-1)";
6619
+ readonly rightMotor: "Right motor (0-1)";
6620
+ readonly waitForRumble: "Wait for the rumble to end";
6621
+ readonly state: "State";
6622
+ readonly action: "Input action";
6623
+ readonly anyAction: "Any input action";
6624
+ readonly holdSeconds: "Hold (s)";
6625
+ readonly pressCount: "Presses";
6626
+ readonly timeout: "Time limit (s)";
6627
+ readonly result: "Result variable";
6628
+ readonly noResult: "None";
6629
+ };
5987
6630
  readonly nvl: {
5988
6631
  readonly hint: "Child rows run in NVL mode. The transform below animates the NVL layer as it enters.";
5989
6632
  readonly motionLabel: "NVL enter animation";
@@ -6647,11 +7290,17 @@ declare const en: {
6647
7290
  readonly zoomIn: "Zoom In";
6648
7291
  readonly zoomOut: "Zoom Out";
6649
7292
  readonly resetView: "Reset View";
7293
+ readonly keybindings: {
7294
+ readonly zoomIn: "Zoom image in";
7295
+ readonly zoomOut: "Zoom image out";
7296
+ readonly resetView: "Reset image view";
7297
+ };
6650
7298
  };
6651
7299
  readonly shortcuts: {
6652
7300
  readonly copy: "Copy selected assets";
6653
7301
  readonly cut: "Cut selected assets";
6654
7302
  readonly paste: "Paste assets";
7303
+ readonly delete: "Delete selected assets or groups";
6655
7304
  readonly rename: "Rename selected asset or group";
6656
7305
  };
6657
7306
  readonly previewEditor: {
@@ -6899,6 +7548,9 @@ declare const en: {
6899
7548
  readonly node: {
6900
7549
  readonly contextInvalid: "Node \"{name}\" is not allowed in {owner}.{hint}";
6901
7550
  readonly contextValueReturnHint: " Return Value only belongs in Blueprint Value graphs.";
7551
+ readonly elementOtherSurface: "\"{node}\" refers to {element} on another page or Game UI. A blueprint reaches only the elements of its own page or component, and at run time this node is refused. Move the change to a blueprint on that page.";
7552
+ readonly elementNamed: "\"{name}\"";
7553
+ readonly elementUnnamed: "an unnamed element";
6902
7554
  readonly contextListItemHint: " It reads the list row it runs for, and nothing here draws one.";
6903
7555
  readonly noRuntime: "Node \"{node}\" has no runtime.";
6904
7556
  readonly inputMissing: "\"{node}\" has nothing connected to \"{pin}\".";
@@ -6906,6 +7558,7 @@ declare const en: {
6906
7558
  readonly stepLimitGlobal: "\"{head}\" in App logic stopped at \"{node}\" after {steps} steps without a wait.";
6907
7559
  readonly unknownType: "Unknown node type \"{type}\". Its plugin may be uninstalled or disabled.";
6908
7560
  readonly variableIdInvalid: "Node \"{node}\": pick a variable.";
7561
+ readonly loopBodyNotClosed: "\"{node}\" runs its loop body once. The end of the body is not connected back to this node's In. To run the next pass, connect the end of the body to \"{node}\".";
6909
7562
  readonly persistentVariableIdInvalid: "Node \"{node}\": pick a persistent variable.";
6910
7563
  readonly savedVariableIdInvalid: "Node \"{node}\": pick a saved variable.";
6911
7564
  readonly fieldMissing: "\"{node}\": {struct} has no field \"{field}\".";
@@ -7176,6 +7829,31 @@ declare const en: {
7176
7829
  readonly unbound: "Unbound";
7177
7830
  readonly clear: "Clear binding";
7178
7831
  };
7832
+ readonly family: {
7833
+ readonly compare: "Compare";
7834
+ readonly key: "On Key";
7835
+ readonly gamepadButton: "On Gamepad Button";
7836
+ readonly getPreference: "Get Preference";
7837
+ readonly setPreference: "Set Preference";
7838
+ readonly trim: "Trim Whitespace";
7839
+ readonly changeCase: "Change Case";
7840
+ readonly pad: "Pad Text";
7841
+ readonly replace: "Replace Text";
7842
+ readonly checkType: "Check Type";
7843
+ readonly convert: "Convert Type";
7844
+ readonly rounding: "Rounding";
7845
+ readonly random: "Random Number";
7846
+ readonly literal: "Literal";
7847
+ readonly saveInfo: "Get Save Info";
7848
+ readonly getTextStyle: "Get Text Style";
7849
+ readonly setTextStyle: "Set Text Style";
7850
+ readonly getImageFraming: "Get Image Framing";
7851
+ readonly setImageFraming: "Set Image Framing";
7852
+ readonly getVisibleEnabled: "Get Visible or Enabled";
7853
+ readonly setVisibleEnabled: "Set Visible or Enabled";
7854
+ readonly rowSubtitle: "{category} \u00B7 {count} nodes";
7855
+ readonly switchLabel: "Switch to another node of this kind";
7856
+ };
7179
7857
  readonly element: {
7180
7858
  readonly select: "Select element";
7181
7859
  readonly selectNamed: "Select element {name}";
@@ -7361,6 +8039,7 @@ declare const en: {
7361
8039
  readonly slider: "Slider";
7362
8040
  readonly sound: "Sound";
7363
8041
  readonly switch: "Switch";
8042
+ readonly video: "Video";
7364
8043
  readonly text: "Text";
7365
8044
  readonly textInput: "Text Input";
7366
8045
  readonly variables: "Variables";
@@ -7451,6 +8130,9 @@ declare const en: {
7451
8130
  readonly heightPct: "Height %";
7452
8131
  readonly insert: "Insert";
7453
8132
  readonly isPlaying: "Is Playing";
8133
+ readonly isEnded: "Is Ended";
8134
+ readonly muted: "Muted";
8135
+ readonly speed: "Speed";
7454
8136
  readonly keys: "Keys";
7455
8137
  readonly label: "Label";
7456
8138
  readonly leftPct: "Left %";
@@ -7635,6 +8317,7 @@ declare const en: {
7635
8317
  readonly success: "Success";
7636
8318
  readonly string: "String";
7637
8319
  readonly switch: "Switch";
8320
+ readonly video: "Video";
7638
8321
  readonly targetElement: "Target element";
7639
8322
  readonly targetPage: "Target page";
7640
8323
  readonly text: "Text";
@@ -7962,6 +8645,7 @@ declare const en: {
7962
8645
  readonly getNametag: "Get Nametag";
7963
8646
  readonly getNormalizedValue: "Get Normalized Value";
7964
8647
  readonly getNotifications: "Get Notifications";
8648
+ readonly postNotification: "Post Notification";
7965
8649
  readonly getOpacity: "Get Opacity";
7966
8650
  readonly getPageParam: "Get Page Param";
7967
8651
  readonly getPageProps: "Get Page Props";
@@ -8234,6 +8918,21 @@ declare const en: {
8234
8918
  readonly turnSwitchOn: "Turn Switch On";
8235
8919
  readonly turnedOff: "Turned Off";
8236
8920
  readonly turnedOn: "Turned On";
8921
+ readonly playbackEnded: "Playback Ended";
8922
+ readonly playVideo: "Play Video";
8923
+ readonly pauseVideo: "Pause Video";
8924
+ readonly stopVideo: "Stop Video";
8925
+ readonly seekVideo: "Seek Video";
8926
+ readonly getVideoTime: "Get Video Time";
8927
+ readonly getVideoDuration: "Get Video Duration";
8928
+ readonly isVideoPlaying: "Is Video Playing";
8929
+ readonly isVideoEnded: "Is Video Ended";
8930
+ readonly setVideoVolume: "Set Video Volume";
8931
+ readonly setVideoMuted: "Set Video Muted";
8932
+ readonly setVideoLoop: "Set Video Loop";
8933
+ readonly setVideoSpeed: "Set Video Speed";
8934
+ readonly getVideoVolume: "Get Video Volume";
8935
+ readonly isVideoMuted: "Is Video Muted";
8237
8936
  readonly undoLastHistoryEntry: "Undo Last History Entry";
8238
8937
  readonly unmount: "Unmount";
8239
8938
  readonly valueChanged: "Value Changed";
@@ -8266,8 +8965,8 @@ declare const en: {
8266
8965
  readonly nodeDescription: {
8267
8966
  readonly getComponentParam: "The value this placement sets for the chosen parameter, or the parameter's default when it sets none. A Text parameter that reads from a translation key gives the key's name; Translation Key Text gives its words.";
8268
8967
  readonly getPageParam: "The value the page was opened with for the chosen param, or the param's default when it was given none. Params are declared in the page's properties.";
8269
- readonly compareEqual: "True when A and B are the same value of the same type. The number 1 and the text \"1\" are not equal.";
8270
- readonly compareNotEqual: "True when A and B differ in value or in type. The number 1 and the text \"1\" count as different.";
8968
+ readonly compareEqual: "True when A and B are the same value of the same type. Lists and objects are compared by their contents, an element by which element it is. The number 1 and the text \"1\" are not equal; an input left unconnected counts as Null.";
8969
+ readonly compareNotEqual: "True when A and B differ in value or in type, judged as Equal judges them. The number 1 and the text \"1\" count as different.";
8271
8970
  readonly compareGreaterThan: "True when A is greater than B. Both sides are compared as numbers; a side that cannot be read as a number gives false.";
8272
8971
  readonly compareGreaterThanOrEqual: "True when A is greater than or equal to B. Both sides are compared as numbers; a side that cannot be read as a number gives false.";
8273
8972
  readonly compareLessThan: "True when A is less than B. Both sides are compared as numbers; a side that cannot be read as a number gives false.";
@@ -8281,11 +8980,27 @@ declare const en: {
8281
8980
  readonly goBack: "Closes the current page and returns to the page beneath it. On the bottom page it does nothing.";
8282
8981
  readonly replacePage: "Opens a page in place of the current page, and closes the current page. Go back and Go Page set to None do not return to it.";
8283
8982
  readonly isGameOverlay: "True when this page, layer or Game UI is shown over a running game. In App logic, true while a page or a modal layer covers the story.";
8983
+ readonly postNotification: "Shows Message as a notification in the running game, in the same place as the game's own notices. A project with a Notifications Game UI shows it there. Duration is in seconds, and 3 seconds when left empty. Get Notifications lists the notification until it closes. Needs a running game.";
8284
8984
  readonly localizationGetText: "Gets a translation key's text in the player's current language, or its source text when that language has no translation. A key that does not exist gives its name. Translation Key Text gives the same text and can also be used in Blueprint Value and functions.";
8285
8985
  readonly translationKeyText: "A translation key's text in the player's current language, or its source text when that language has no translation. A key that does not exist gives its name. The same text as Get Text, and also usable in Blueprint Value and functions. A Blueprint Value that shows it updates when the player changes language.";
8286
8986
  readonly format: "Replaces the placeholders in Template with values: {0}, {1} and so on with the items of an array, {name} with the field of that name in an object. A placeholder with no value becomes empty. A translated template comes from Translation Key Text.";
8287
8987
  readonly formatText: "Replaces {0}, {1} and so on in Text with the items of Values. Format does the same, also fills {name} from an object, and can be used in Blueprint Value and functions.";
8288
8988
  readonly getField: "One field of the struct wired into Object, picked from that struct's fields. Inside a list row, leave Object unwired to read the row. Use Get JSON Field for an object whose fields are not declared.";
8989
+ readonly playbackEnded: "Runs each time the clip plays to its end. Does not run while Loop is on, when the clip is replaced, or when the page closes before the end.";
8990
+ readonly playVideo: "Starts the video, or resumes it from where it was paused. After the clip has ended, plays it again from the start. Plays at the volume the player has set, as Autoplay does. A clip that has not loaded yet starts once it has.";
8991
+ readonly pauseVideo: "Pauses the video where it is. Play Video resumes it from there.";
8992
+ readonly stopVideo: "Pauses the video and returns it to the start of the clip.";
8993
+ readonly seekVideo: "Moves the video to Time, in seconds from the start of the clip. A time past the end moves it to the end, and a negative time to the start. A playing video keeps playing and a paused one stays paused. A playing video moved to its end runs Playback Ended.";
8994
+ readonly getVideoTime: "Where the video is, in seconds from the start of the clip. 0 while there is no clip on screen.";
8995
+ readonly getVideoDuration: "How long the clip is, in seconds. 0 until the clip has loaded.";
8996
+ readonly isVideoPlaying: "True while the video is playing. False while it is paused, stopped or at its end, and while there is no clip on screen.";
8997
+ readonly isVideoEnded: "True once the clip has played to its end, until it is played or moved again. Never true while Loop is on.";
8998
+ readonly setVideoVolume: "Sets the video's volume, from 0 to 1, in place of the volume set on the widget. The player's volume settings and the audio track still apply on top.";
8999
+ readonly setVideoMuted: "Mutes or unmutes the video. A muted video plays silently at any volume.";
9000
+ readonly setVideoLoop: "Turns Loop on or off. While Loop is on, the clip starts over at its end and Playback Ended does not run.";
9001
+ readonly setVideoSpeed: "Sets how fast the video plays: 1 is normal speed, 2 twice as fast, 0.5 half as fast. Kept between 0.0625 and 16.";
9002
+ readonly getVideoVolume: "The video's volume, from 0 to 1: the one set on the widget, or by Set Video Volume. The player's volume settings are not included.";
9003
+ readonly isVideoMuted: "True while the video is muted.";
8289
9004
  };
8290
9005
  readonly live: {
8291
9006
  readonly nodeClaimed: "{name} is editing this node";
@@ -8346,6 +9061,8 @@ declare const en: {
8346
9061
  readonly history: {
8347
9062
  readonly deleteCharacter: "delete character {name}";
8348
9063
  readonly renameCharacter: "rename character {name}";
9064
+ readonly createCharacter: "create character {name}";
9065
+ readonly editCharacter: "edit character {name}";
8349
9066
  readonly deleteGroup: "delete group {name}";
8350
9067
  };
8351
9068
  readonly create: {
@@ -8625,6 +9342,17 @@ declare const en: {
8625
9342
  readonly backgroundImage: "Background Image";
8626
9343
  readonly animation: "Animation";
8627
9344
  readonly logic: "Logic";
9345
+ readonly navigation: {
9346
+ readonly title: "Navigation";
9347
+ readonly defaultFocus: "Starting focus";
9348
+ readonly defaultFocusAuto: "Automatic";
9349
+ readonly autoFocus: "Focus on open";
9350
+ readonly autoFocusTip: "Whether a control takes the focus when this interface opens. By default only when the player last used a keyboard or a gamepad.";
9351
+ readonly autoFocusDevice: "Keyboard or gamepad";
9352
+ readonly autoFocusAlways: "Always";
9353
+ readonly autoFocusNever: "Never";
9354
+ readonly wrap: "Loop at edges";
9355
+ };
8628
9356
  readonly input: {
8629
9357
  readonly title: "Input";
8630
9358
  readonly actions: "Actions answered";
@@ -8663,6 +9391,27 @@ declare const en: {
8663
9391
  readonly uiElement: "UI Element";
8664
9392
  readonly linkedComponent: "Linked Component";
8665
9393
  };
9394
+ readonly navigation: {
9395
+ readonly title: "Navigation";
9396
+ readonly focusable: "Focusable";
9397
+ readonly focusableTip: "Whether keyboard and gamepad navigation can move onto this element. Controls can by default. Never also excludes every element inside it.";
9398
+ readonly focusableAuto: "Automatic";
9399
+ readonly focusableAlways: "Always";
9400
+ readonly focusableNever: "Never";
9401
+ readonly preferredOnEntry: "Use as starting focus";
9402
+ readonly preferredOnEntryTip: "The focus starts on this element when the interface opens, unless the interface's Starting focus names another.";
9403
+ readonly region: "Navigation group";
9404
+ readonly regionTip: "Navigation stays inside this element while a control inside lies in the pressed direction.";
9405
+ readonly wrap: "Loop at edges";
9406
+ readonly rememberLast: "Remember last focus";
9407
+ readonly up: "Up";
9408
+ readonly down: "Down";
9409
+ readonly left: "Left";
9410
+ readonly right: "Right";
9411
+ readonly byLayout: "By layout";
9412
+ readonly neighborsTip: "Where each direction goes when the focus leaves this element. By layout picks the nearest control in that direction.";
9413
+ readonly numbered: "{name} {index}";
9414
+ };
8666
9415
  readonly interactionSound: {
8667
9416
  readonly title: "Sound";
8668
9417
  readonly hover: "Hover";
@@ -9021,42 +9770,74 @@ declare const en: {
9021
9770
  readonly motionAsset: "Motion asset";
9022
9771
  readonly choosePlaceholder: "Choose motion\u2026";
9023
9772
  };
9024
- readonly panel: {
9773
+ readonly library: {
9025
9774
  readonly searchPlaceholder: "Search motions";
9026
- readonly libraryActions: "Import and export";
9027
- readonly createMotion: "Create motion";
9028
- readonly empty: "No motions.";
9775
+ readonly targetKind: "Target";
9776
+ readonly allKinds: "All targets";
9029
9777
  readonly newMotion: "New Motion";
9030
- readonly motionActions: "Motion actions";
9031
- readonly repeat: "Repeat";
9032
- readonly repeatDelaySeconds: "Repeat delay (s)";
9033
- readonly actionUses: "Current action uses {name}";
9034
- readonly actionUsesMissing: "Current action uses a motion this project no longer has";
9035
- readonly previewAssetMissing: "Missing image";
9036
- readonly actionNoMotion: "Current action has no motion asset";
9037
- readonly bindToAction: "Bind to action";
9038
- readonly target: "Target";
9039
- readonly background: "Background";
9040
- readonly previewTarget: "Preview target";
9041
- readonly previewBackground: "Preview background";
9042
- readonly previewTargetTitle: "Preview target image (editor only)";
9043
- readonly previewBackgroundTitle: "Preview background image (editor only)";
9044
- readonly selectOrCreate: "Select or create a story motion.";
9045
- readonly deleteConfirm: "Delete motion \"{name}\"?";
9778
+ readonly blankMotion: "Blank motion";
9779
+ readonly noMatches: "No matching motions.";
9780
+ readonly unreadable: "Could not be read";
9781
+ readonly repeats: {
9782
+ readonly one: "Repeats once";
9783
+ readonly other: "Repeats {count} times";
9784
+ };
9785
+ readonly inUseTip: "The current row uses this motion.";
9786
+ readonly copyName: "{name} copy";
9787
+ readonly deleteOne: "Delete motion \"{name}\"?";
9788
+ readonly deleteMany: "Delete {count} motions?";
9046
9789
  readonly deleteDetail: "The motion asset is removed and related editors are closed.";
9047
- readonly clearAria: "Clear {name}";
9790
+ readonly useOnRow: "Use on Current Row";
9791
+ readonly useOnRowTip: "Sets the selected motion on the row focused in the story editor.";
9792
+ readonly useOnRowNeedsOne: "Select one motion.";
9793
+ readonly useOnRowWrongKind: "The current row takes a {kind} motion.";
9794
+ readonly useOnRowAlready: "The current row already uses this motion.";
9795
+ readonly selected: {
9796
+ readonly one: "{count} selected";
9797
+ readonly other: "{count} selected";
9798
+ };
9799
+ readonly count: {
9800
+ readonly one: "{count} motion";
9801
+ readonly other: "{count} motions";
9802
+ };
9803
+ };
9804
+ readonly inspector: {
9805
+ readonly target: "Target";
9806
+ readonly duration: "Duration";
9807
+ readonly properties: "Properties";
9808
+ readonly noProperties: "None";
9809
+ readonly listSeparator: ", ";
9810
+ readonly playback: "Playback";
9811
+ readonly repeat: "Repeats";
9812
+ readonly repeatDelaySeconds: "Pause between repeats (s)";
9813
+ readonly previewImages: "Preview pictures";
9814
+ readonly previewImagesTip: "Drawn only in the editor's previews. In the game the row's own object moves.";
9815
+ readonly previewTarget: "Object";
9816
+ readonly previewBackground: "Background";
9048
9817
  };
9049
9818
  readonly editor: {
9050
9819
  readonly loading: "Loading motion asset\u2026";
9051
9820
  readonly assetDeleted: "Motion asset was deleted.";
9052
9821
  readonly play: "Play";
9053
9822
  readonly pause: "Pause";
9054
- readonly animatedProperties: "Animated properties";
9823
+ readonly toStart: "Go to start";
9824
+ readonly previousFrame: "Previous frame";
9825
+ readonly nextFrame: "Next frame";
9826
+ readonly loop: "Loop";
9827
+ readonly stageZoom: "Stage zoom";
9828
+ readonly zoomFit: "Fit";
9829
+ readonly resizeTimeline: "Resize timeline";
9830
+ readonly frame: "Frame {frame} of {total}";
9831
+ readonly keyframesSelected: "{count} keyframes";
9055
9832
  readonly addProperty: "Add property";
9056
9833
  readonly addKeyframeAtPlayhead: "Add keyframe at playhead";
9834
+ readonly addKeyframeHere: "Add keyframe here";
9057
9835
  readonly addKeyframeAria: "Add {property} keyframe at playhead";
9836
+ readonly removeKeyframeAria: "Remove {property} keyframe at playhead";
9837
+ readonly previousKeyframe: "Previous keyframe";
9838
+ readonly nextKeyframe: "Next keyframe";
9839
+ readonly selectTrackKeyframes: "Select keyframes on this track";
9058
9840
  readonly deleteTrack: "Delete track";
9059
- readonly deleteTrackAria: "Delete {property} track";
9060
9841
  };
9061
9842
  readonly keyframe: {
9062
9843
  readonly loading: "Loading keyframe\u2026";
@@ -9283,6 +10064,21 @@ declare const en: {
9283
10064
  readonly one: "{count} interface";
9284
10065
  readonly other: "{count} interfaces";
9285
10066
  };
10067
+ readonly navigationTitle: "Focus navigation";
10068
+ readonly navigation: {
10069
+ readonly up: "Move up";
10070
+ readonly down: "Move down";
10071
+ readonly left: "Move left";
10072
+ readonly right: "Move right";
10073
+ readonly next: "Next control";
10074
+ readonly previous: "Previous control";
10075
+ readonly confirm: "Confirm";
10076
+ readonly cancel: "Back";
10077
+ readonly menu: "Quick menu";
10078
+ };
10079
+ readonly navigationNone: "None";
10080
+ readonly navigationTag: "Focus navigation: {slot}";
10081
+ readonly fillNavigationSlots: "Add actions for empty slots";
9286
10082
  readonly noBindings: "No bindings";
9287
10083
  readonly addBinding: "Add binding";
9288
10084
  readonly removeBinding: "Remove {binding}";
@@ -9800,6 +10596,37 @@ declare const en: {
9800
10596
  readonly image: {
9801
10597
  readonly title: "Image";
9802
10598
  };
10599
+ readonly inputHints: {
10600
+ readonly title: "Input Hints";
10601
+ readonly sectionContent: "Content";
10602
+ readonly sectionStyle: "Style";
10603
+ readonly sectionWords: "Words";
10604
+ readonly showFor: "Show for";
10605
+ readonly showForKeysAndGamepad: "Keyboard and gamepad";
10606
+ readonly showForGamepad: "Gamepad only";
10607
+ readonly showForAlways: "Every device";
10608
+ readonly showForTip: "The inputs the bar shows hints for. While any other input is in use, it shows none.";
10609
+ readonly glyphStyle: "Button glyphs";
10610
+ readonly glyphAuto: "Match the connected controller";
10611
+ readonly glyphXbox: "Xbox";
10612
+ readonly glyphPlayStation: "PlayStation";
10613
+ readonly glyphNintendo: "Nintendo";
10614
+ readonly align: "Alignment";
10615
+ readonly alignStart: "Start";
10616
+ readonly alignCenter: "Center";
10617
+ readonly alignEnd: "End";
10618
+ readonly fontSize: "Font size";
10619
+ readonly color: "Text color";
10620
+ readonly glyphBackground: "Glyph fill";
10621
+ readonly glyphColor: "Glyph text";
10622
+ readonly gap: "Spacing";
10623
+ readonly wordsTip: "Left empty, each hint uses Studio's own word in the player's language. Actions the project declares are named by their own names.";
10624
+ readonly wordSelect: "Select";
10625
+ readonly wordConfirm: "Confirm";
10626
+ readonly wordBack: "Back";
10627
+ readonly wordAdvance: "Advance";
10628
+ readonly wordStageControls: "Quick menu";
10629
+ };
9803
10630
  readonly video: {
9804
10631
  readonly title: "Video";
9805
10632
  readonly sectionSource: "Source";
@@ -9818,7 +10645,7 @@ declare const en: {
9818
10645
  readonly loop: "Loop";
9819
10646
  readonly muted: "Muted";
9820
10647
  readonly autoplay: "Autoplay";
9821
- readonly autoplayHint: "Applies in the game. The editor canvas stays paused; use the docker bar to preview.";
10648
+ readonly autoplayHint: "Applies in the game. The editor canvas stays paused; use the toolbar to preview.";
9822
10649
  readonly volume: "Volume";
9823
10650
  readonly volumeHint: "0 to 1. A blueprint volume pin overrides this at runtime.";
9824
10651
  readonly audioTrack: "Audio Track";
@@ -9836,6 +10663,7 @@ declare const en: {
9836
10663
  readonly previewPlay: "Preview playback";
9837
10664
  readonly previewPause: "Pause preview";
9838
10665
  readonly previewRestart: "Back to first frame";
10666
+ readonly playRefused: "Video \u201C{name}\u201D did not start playing. A video with sound plays only after the player has clicked or pressed a key; a muted one plays at once.";
9839
10667
  };
9840
10668
  readonly puppet: {
9841
10669
  readonly title: "Model";
@@ -9917,6 +10745,9 @@ declare const en: {
9917
10745
  readonly nameText: "{name} text";
9918
10746
  };
9919
10747
  readonly defaults: {
10748
+ readonly inputHints: {
10749
+ readonly name: "Input Hints";
10750
+ };
9920
10751
  readonly button: {
9921
10752
  readonly name: "Button";
9922
10753
  readonly label: "Button";
@@ -10388,6 +11219,8 @@ declare const en: {
10388
11219
  readonly buildDescription: "Build, packaging, and preview pipeline output";
10389
11220
  readonly storyDescription: "Story scene preview diagnostics and warnings";
10390
11221
  readonly storageDescription: "Project file writes: failed saves, retries, and recoveries";
11222
+ readonly agent: "Agent";
11223
+ readonly agentDescription: "Calls from AI agents connected to Studio";
10391
11224
  };
10392
11225
  readonly sources: {
10393
11226
  readonly blueprintLog: "Blueprint Log";
@@ -10989,11 +11822,12 @@ declare const en: {
10989
11822
  readonly identity: "Author";
10990
11823
  readonly team: "Team";
10991
11824
  readonly story: "Story editor";
11825
+ readonly agent: "Agent access";
10992
11826
  readonly done: "Done";
10993
11827
  };
10994
11828
  readonly welcome: {
10995
11829
  readonly title: "Welcome";
10996
- readonly expectation: "Six interface and story-editor settings. Each one takes effect immediately and remains available in Settings.";
11830
+ readonly expectation: "Seven settings for the interface, the story editor and agent access. Each one takes effect immediately and remains available in Settings.";
10997
11831
  readonly haveSettings: "Settings from another installation";
10998
11832
  };
10999
11833
  readonly language: {
@@ -11027,6 +11861,11 @@ declare const en: {
11027
11861
  readonly title: "Story editor";
11028
11862
  readonly expectation: "How the scene editor is read and typed in.";
11029
11863
  };
11864
+ readonly agent: {
11865
+ readonly title: "Agent access";
11866
+ readonly expectation: "An AI agent connects to Studio over MCP and edits the open project. An agent is optional.";
11867
+ readonly toggleFailed: "Agent access could not be changed: {error}";
11868
+ };
11030
11869
  readonly import: {
11031
11870
  readonly action: "Import settings\u2026";
11032
11871
  readonly leaves: "Applying these settings ends setup and opens Studio.";
@@ -11197,6 +12036,7 @@ declare const en: {
11197
12036
  readonly assets: "Assets";
11198
12037
  readonly console: "Console";
11199
12038
  readonly problems: "Problems";
12039
+ readonly agentLog: "Agent Log";
11200
12040
  readonly storyMotion: "Story Motion";
11201
12041
  readonly dashboard: "Dashboard";
11202
12042
  readonly audioPreview: "Audio Preview";
@@ -11273,9 +12113,9 @@ declare const en: {
11273
12113
  readonly name: "Project Name";
11274
12114
  readonly namePlaceholder: "Project name";
11275
12115
  readonly appIdPlaceholder: "App identifier";
11276
- readonly appIdHelper: "Lowercase letters, digits and hyphens only. Cannot be changed after creation.";
12116
+ readonly appIdHelper: "Lowercase letters, digits and hyphens, or a reverse-domain id such as com.studio.game. Cannot be changed after creation.";
11277
12117
  readonly appIdRequired: "App ID is required";
11278
- readonly appIdInvalid: "App ID can only contain lowercase letters, numbers, and hyphens";
12118
+ readonly appIdInvalid: "App ID can only contain lowercase letters, numbers and hyphens, with dots only between the parts of a reverse-domain id such as com.studio.game";
11279
12119
  readonly locationPlaceholder: "Project location";
11280
12120
  readonly browseLocation: "Choose folder";
11281
12121
  readonly validatingDirectory: "Checking the folder\u2026";
@@ -11628,8 +12468,18 @@ declare const en: {
11628
12468
  readonly network: "Data the game requests";
11629
12469
  readonly networkNote: "This plugin requests data from these addresses while the game runs.";
11630
12470
  readonly studio: "Studio permissions";
12471
+ readonly agentTools: "AI agents";
11631
12472
  };
11632
12473
  readonly sidecarPlatforms: "Runs on {platforms}";
12474
+ readonly agentToolsSummary: "{tools} ({writes})";
12475
+ readonly agentTools: {
12476
+ readonly one: "Offers {count} tool to AI agents connected to Studio";
12477
+ readonly other: "Offers {count} tools to AI agents connected to Studio";
12478
+ };
12479
+ readonly agentToolsWrites: {
12480
+ readonly one: "{count} can change the project";
12481
+ readonly other: "{count} can change the project";
12482
+ };
11633
12483
  readonly sidecarKind: {
11634
12484
  readonly executable: "Runs as a separate program";
11635
12485
  readonly node: "Runs the plugin's own code as part of the game";
@@ -12692,6 +13542,19 @@ declare const en: {
12692
13542
  readonly deleted: "The page this row names is no longer in the project, so the playthrough ends with nothing on screen";
12693
13543
  readonly help: string;
12694
13544
  };
13545
+ readonly storyInputActionMissing: {
13546
+ readonly title: "Wait for a missing input action";
13547
+ readonly description: "A /waitinput, /hold or /mash row naming an input action the project no longer has";
13548
+ readonly message: "The input action this row waits for is no longer in the project, so the story stops here for good";
13549
+ readonly timed: "The input action this row waits for is no longer in the project, so the row always fails when its time limit ends";
13550
+ readonly help: string;
13551
+ };
13552
+ readonly storyInputLockedDialogue: {
13553
+ readonly title: "Line inside a locked passage";
13554
+ readonly description: "A line or /wait click after /input lock with no /input unlock before it";
13555
+ readonly message: "Player input is locked here, so this row cannot be advanced. Add /input unlock before it";
13556
+ readonly help: string;
13557
+ };
12695
13558
  readonly storyEndingNameDuplicate: {
12696
13559
  readonly title: "Two endings with one name";
12697
13560
  readonly description: "More than one ending sharing a display name";
@@ -12715,6 +13578,7 @@ declare const en: {
12715
13578
  readonly description: "A row acting on an object no row in the scene creates";
12716
13579
  readonly message: "No row in this scene creates {object}, so this row has nothing to act on";
12717
13580
  readonly messageCharacter: "No row in this scene brings {object} on stage, so this row has nothing to act on";
13581
+ readonly messageLayer: "This scene has no layer {object}, so this row has nothing to act on";
12718
13582
  readonly help: string;
12719
13583
  };
12720
13584
  readonly storyDeclaredNeverShown: {
@@ -13113,6 +13977,7 @@ declare const en: {
13113
13977
  readonly severity: {
13114
13978
  readonly error: "Error";
13115
13979
  readonly warning: "Warning";
13980
+ readonly minor: "Minor warning";
13116
13981
  readonly info: "Info";
13117
13982
  readonly off: "Off";
13118
13983
  };
@@ -13120,7 +13985,7 @@ declare const en: {
13120
13985
  readonly title: "Problems";
13121
13986
  readonly empty: "No problems found";
13122
13987
  readonly running: "Checking\u2026";
13123
- readonly counts: "{errors}, {warnings}, {infos}";
13988
+ readonly counts: "{errors}, {warnings}, {minorWarnings}, {infos}";
13124
13989
  readonly filtered: "{shown} of {total}";
13125
13990
  readonly rerun: "Run again";
13126
13991
  readonly filterAll: "All";
@@ -13148,7 +14013,7 @@ declare const en: {
13148
14013
  readonly jumpFailed: "This location can no longer be opened";
13149
14014
  };
13150
14015
  readonly statusBar: {
13151
- readonly counts: "Problems: {errors}, {warnings}, {infos}";
14016
+ readonly counts: "Problems: {errors}, {warnings}, {minorWarnings}, {infos}";
13152
14017
  };
13153
14018
  readonly command: {
13154
14019
  readonly runProject: "Check project";
@@ -14191,6 +15056,14 @@ declare const en: {
14191
15056
  readonly title: "Actions in blueprints";
14192
15057
  readonly body: string;
14193
15058
  };
15059
+ readonly focusNavigation: {
15060
+ readonly title: "Focus navigation";
15061
+ readonly body: string;
15062
+ };
15063
+ readonly focusNavigationSettings: {
15064
+ readonly title: "Navigation settings";
15065
+ readonly body: string;
15066
+ };
14194
15067
  readonly uiSurfaces: {
14195
15068
  readonly title: "Game screens";
14196
15069
  readonly body: string;
@@ -14504,6 +15377,13 @@ declare const en: {
14504
15377
  };
14505
15378
  };
14506
15379
  readonly game: {
15380
+ readonly inputHints: {
15381
+ readonly select: "Select";
15382
+ readonly confirm: "Confirm";
15383
+ readonly back: "Back";
15384
+ readonly advance: "Next";
15385
+ readonly stageControls: "Menu";
15386
+ };
14507
15387
  readonly saveLoad: {
14508
15388
  readonly refused: "This save could not be loaded. The game continues from the current point.";
14509
15389
  readonly refusedOtherStory: "This save was written from a different version of the story. The game continues from the current point.";
@@ -14744,7 +15624,7 @@ type PluginFileSystemPermissionMode = "read" | "write" | "readwrite";
14744
15624
  * - **Author-declared** (`filesystem`, `api`) — privileged Studio controls the
14745
15625
  * plugin asks for explicitly in `permissions[]`.
14746
15626
  * - **Derived** (`runtime`, `sidecar`, `buildDependency`, `externalLink`,
14747
- * `network`) — computed from `contributes` by {@link validatePluginManifest}
15627
+ * `network`, `agentTools`) — computed from `contributes` by {@link validatePluginManifest}
14748
15628
  * and *rejected* if written by
14749
15629
  * hand. A capability is declared in exactly one place, so what the prompt shows
14750
15630
  * and what the plugin can actually reach cannot drift apart. Adding a
@@ -14817,6 +15697,21 @@ export type PluginInstallPermission = {
14817
15697
  */
14818
15698
  kind: "network";
14819
15699
  patterns: string[];
15700
+ } | {
15701
+ /**
15702
+ * Derived from `contributes.agentTools`: tools this plugin offers the AI agents an author
15703
+ * connects to Studio. Informational more than it is a power - every call still passes the
15704
+ * author's own switches (agent access, write access, pause) - but it is code an outside
15705
+ * program can start, and the author hears about it here, by count, before it can happen.
15706
+ *
15707
+ * Names rather than a count, so a later version that adds a tool, or turns a reading tool
15708
+ * into one that changes the project, widens the set and asks again.
15709
+ */
15710
+ kind: "agentTools";
15711
+ /** Every declared tool. */
15712
+ tools: string[];
15713
+ /** The ones that change the project; a subset of `tools`. */
15714
+ writeTools: string[];
14820
15715
  };
14821
15716
  type PluginSidecarKind = "executable" | "node";
14822
15717
  declare const PluginRuntimeCapability: {
@@ -15219,6 +16114,31 @@ export type PluginContributes = {
15219
16114
  * any plugin code runs. Ids must start with the plugin id.
15220
16115
  */
15221
16116
  structs?: PluginStructContribution[];
16117
+ /**
16118
+ * Tools this plugin offers the AI agents an author connects to Studio (the built-in MCP
16119
+ * endpoint), registered by the studio entry with `app.services.agent.registerTool`.
16120
+ *
16121
+ * Declared here, and refused at registration when not, for the reason `tests` are: the install
16122
+ * prompt is read before any plugin code runs, and an outside program reaching into the plugin is
16123
+ * something the author should be told about there. Unlike `tests` it derives an install
16124
+ * permission (`kind: "agentTools"`), because a tool is callable by somebody other than the author
16125
+ * the moment the plugin loads - and `write` is part of the declaration, so a tool that starts
16126
+ * changing the project in a later version asks again.
16127
+ */
16128
+ agentTools?: PluginAgentToolContribution[];
16129
+ /**
16130
+ * Package-relative path to a Markdown chapter for agents (`agent/guide.md`), served by
16131
+ * `agent_guide` as `plugin:<pluginId>` and as the resource `narraleaf://guide/plugin/<pluginId>`.
16132
+ * Empty when the plugin ships none.
16133
+ */
16134
+ agentGuide?: string;
16135
+ };
16136
+ /** One tool a plugin offers AI agents, as its manifest declares it. */
16137
+ export type PluginAgentToolContribution = {
16138
+ /** `<pluginId>.<tool>`: lower case, digits, `_`, `.` and `-`. */
16139
+ name: string;
16140
+ /** The tool changes the project. Must match the registration. */
16141
+ write: boolean;
15222
16142
  };
15223
16143
  type PluginStructContribution = {
15224
16144
  /** Prefixed with the plugin id: `narraleaf.gallery.entry`. */
@@ -15527,6 +16447,59 @@ type GameProcessMemoryReading = {
15527
16447
  /** The sum of every process's private bytes, or null where the platform does not report them. */
15528
16448
  privateBytes: number | null;
15529
16449
  };
16450
+ declare const UI_NAVIGATION_DIRECTIONS: readonly [
16451
+ "up",
16452
+ "down",
16453
+ "left",
16454
+ "right"
16455
+ ];
16456
+ type UINavigationDirection = (typeof UI_NAVIGATION_DIRECTIONS)[number];
16457
+ declare const UI_FOCUSABILITY_VALUES: readonly [
16458
+ "auto",
16459
+ "always",
16460
+ "never"
16461
+ ];
16462
+ type UIFocusability = (typeof UI_FOCUSABILITY_VALUES)[number];
16463
+ type UINavigationRegion = {
16464
+ /** Moving past the last control inside comes back round to the first, rather than leaving. */
16465
+ wrap?: boolean;
16466
+ /** Coming back into the group lands on the control the player left it from. */
16467
+ rememberLast?: boolean;
16468
+ };
16469
+ type UIElementNavigation = {
16470
+ focusable?: UIFocusability;
16471
+ /** Where one direction goes from here, by element id, overriding what the layout would say. */
16472
+ neighbors?: Partial<Record<UINavigationDirection, UIElementId>>;
16473
+ /** Present makes this element a group. Only meaningful on an element that holds children. */
16474
+ region?: UINavigationRegion;
16475
+ /** Where the focus lands when the surface opens, unless the surface names an element itself. */
16476
+ preferredOnEntry?: boolean;
16477
+ };
16478
+ declare const UI_NAVIGATION_AUTO_FOCUS_VALUES: readonly [
16479
+ "device",
16480
+ "always",
16481
+ "never"
16482
+ ];
16483
+ type UINavigationAutoFocus = (typeof UI_NAVIGATION_AUTO_FOCUS_VALUES)[number];
16484
+ type UISurfaceNavigation = {
16485
+ /** The element the focus starts on. Absent: the one marked `preferredOnEntry`, else the first. */
16486
+ defaultFocusElementId?: UIElementId;
16487
+ autoFocus?: UINavigationAutoFocus;
16488
+ /** Moving past the edge of the surface comes back round from the other side. */
16489
+ wrap?: boolean;
16490
+ };
16491
+ declare const UI_NAVIGATION_SLOTS: readonly [
16492
+ "up",
16493
+ "down",
16494
+ "left",
16495
+ "right",
16496
+ "next",
16497
+ "previous",
16498
+ "confirm",
16499
+ "cancel",
16500
+ "menu"
16501
+ ];
16502
+ type UINavigationSlot = (typeof UI_NAVIGATION_SLOTS)[number];
15530
16503
  declare const UI_INPUT_POINTER_GESTURES: readonly [
15531
16504
  "click",
15532
16505
  "doubleClick",
@@ -15555,6 +16528,12 @@ type UIInputActionDef = {
15555
16528
  name: string;
15556
16529
  /** The bindings a surface gets unless it overrides them. */
15557
16530
  bindings: UIInputBinding[];
16531
+ /**
16532
+ * The navigation operation this intent performs, if any (see `navigation.ts`): its bindings move
16533
+ * the focus, confirm, back out. One intent per slot - the library keeps the first that claims
16534
+ * one - and absent on every intent of a project that has no keyboard or pad navigation.
16535
+ */
16536
+ navigationSlot?: UINavigationSlot;
15558
16537
  };
15559
16538
  type UISurfaceActionEnablement = {
15560
16539
  actionId: string;
@@ -15730,6 +16709,8 @@ type UISurfaceSettings = {
15730
16709
  */
15731
16710
  backgroundImage?: UISurfaceBackgroundImage;
15732
16711
  pageAnimation?: UIPageAnimationSettings;
16712
+ /** Where the focus starts when this Surface opens, and whether it is put there. See `navigation.ts`. */
16713
+ navigation?: UISurfaceNavigation;
15733
16714
  /**
15734
16715
  * What the asset set this Surface's own background names resolves to, per locale. Build-written
15735
16716
  * exactly as {@link UIElement.assetVariants} is, and here rather than on the Surface so the
@@ -15790,6 +16771,15 @@ type UIElement = {
15790
16771
  * even though its props come from the definition.
15791
16772
  */
15792
16773
  animation?: UIPageAnimationSettings;
16774
+ /**
16775
+ * How the player reaches this element without a pointer - whether it can hold the focus, where
16776
+ * a direction goes from it, whether it is a group. Absent on almost every element: a control is
16777
+ * reachable without saying so. Read it through `navigation.ts`.
16778
+ *
16779
+ * Its own field for the reason {@link animation} is: it belongs to the placement, every type has
16780
+ * one, and a linked component instance may set it.
16781
+ */
16782
+ navigation?: UIElementNavigation;
15793
16783
  extra?: Record<string, unknown>;
15794
16784
  /**
15795
16785
  * What each asset set THIS element names resolves to, per locale.
@@ -17166,6 +18156,15 @@ declare class Character {
17166
18156
  * same way. Both would break if a record were a new object.
17167
18157
  */
17168
18158
  adopt(config: CharacterConfig): void;
18159
+ /**
18160
+ * Tell this character's own subscribers that it changed, after an {@link adopt} that told nobody.
18161
+ *
18162
+ * The service's change handler is deliberately left out: whoever adopted a record has already
18163
+ * decided whether it is dirty and announced it to the cast. What is left is the editor holding
18164
+ * this object, which re-renders only from these listeners - without this it would go on drawing
18165
+ * the record from before an undo.
18166
+ */
18167
+ notifySubscribers(): void;
17169
18168
  setOnChange(handler: (() => void) | null): void;
17170
18169
  setOnAssetChange(handler: AssetChangeCallback | null): void;
17171
18170
  /**
@@ -17183,6 +18182,9 @@ type StoryBlockSelection = {
17183
18182
  /** The focused row, or null when the scene itself is the subject. */
17184
18183
  blockId: StoryBlockId | null;
17185
18184
  };
18185
+ type StoryMotionAssetSelection = {
18186
+ animationId: string;
18187
+ };
17186
18188
  type StoryMotionKeyframeSelection = {
17187
18189
  editor: "story-motion";
17188
18190
  tabId: string;
@@ -17352,6 +18354,9 @@ type SelectionState = {
17352
18354
  | {
17353
18355
  type: "scene";
17354
18356
  data: UISurfaceId;
18357
+ } | {
18358
+ type: "storyMotion";
18359
+ data: StoryMotionAssetSelection;
17355
18360
  } | {
17356
18361
  type: "storyMotionKeyframe";
17357
18362
  data: StoryMotionKeyframeSelection;
@@ -17429,6 +18434,10 @@ type LiveUIOp =
17429
18434
  */
17430
18435
  updates?: readonly LiveUIElementRef[];
17431
18436
  };
18437
+ type HistoryLabel = {
18438
+ key: TranslationKey;
18439
+ params?: Record<string, string | number>;
18440
+ };
17432
18441
  type MoveRejectReason = "invalid_surface" | "invalid_target" | "invalid_movers" | "cycle" | "root_locked";
17433
18442
  type MoveUiElementsResult = {
17434
18443
  ok: true;
@@ -17507,6 +18516,21 @@ type ImportTemplateResult = {
17507
18516
  skippedSlots: UIStageSlotId[];
17508
18517
  /** Components copied into the project's library; empty for surface-only templates. */
17509
18518
  importedComponents: UIComponentDefinition[];
18519
+ /** Each imported surface's id in this document, by its id in the source. Skipped ones are absent. */
18520
+ surfaceIdMap: Record<string, string>;
18521
+ /**
18522
+ * Input actions the arriving surfaces answer that this project's vocabulary lacked, adopted under
18523
+ * the source's ids. Unlike the files and translations, they go with the import's undo step (the
18524
+ * caller's, when it records the step itself): an action left behind is not inert - its bindings
18525
+ * keep answering keys - so it is taken back with the surfaces that brought it, unless something
18526
+ * else in the project has come to answer or name it by then.
18527
+ */
18528
+ adoptedActionIds: string[];
18529
+ /**
18530
+ * Key and pad-button bindings of the adopted actions that were left off, by action id, because the
18531
+ * project already gives that key or button a meaning of its own (`adoptArrivingInputActions`).
18532
+ */
18533
+ heldBackBindings: Record<string, UIInputBinding[]>;
17510
18534
  };
17511
18535
  declare const IMPORT_PLACEMENT_FROM_SOURCE: "sourceSurface";
17512
18536
  type ImportTemplatePlacement = UITemplateSurfacePlacement | typeof IMPORT_PLACEMENT_FROM_SOURCE;
@@ -17546,6 +18570,8 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
17546
18570
  /** Where edits go instead of into the document, when something else owns them. See {@link UIOpSink}. */
17547
18571
  private opSink;
17548
18572
  private historySuppressionDepth;
18573
+ /** How deep inside {@link runDetachedDraft} this is: edits then land on a private copy and nowhere else. */
18574
+ private draftDepth;
17549
18575
  private readonly contentRevisions;
17550
18576
  /** What the v13 step changed that an author can see, until the workspace has said so. */
17551
18577
  private textSourceMigrationChanges;
@@ -17613,7 +18639,76 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
17613
18639
  restoreDocumentFromHistory(document: UIDocument, options?: {
17614
18640
  skipAfterMutateHook?: boolean;
17615
18641
  }): void;
17616
- runSurfaceHistoryTransaction(surfaceId: string, action: () => void): void;
18642
+ /**
18643
+ * Run several of this service's own edits as one undo step on `surfaceId`'s stack.
18644
+ *
18645
+ * `label` names the step in the Edit menu when it is something more particular than an edit to
18646
+ * the surface - an agent's batch of edits says so, so the author can tell it from their own.
18647
+ */
18648
+ runSurfaceHistoryTransaction(surfaceId: string, action: () => void, options?: {
18649
+ label?: HistoryLabel;
18650
+ }): void;
18651
+ /**
18652
+ * {@link runSurfaceHistoryTransaction}, all or nothing: when `action` throws, `surfaceId`'s slice
18653
+ * of both documents - its elements and its widgets' blueprints - is put back exactly as the
18654
+ * editor's own undo would put it, nothing is recorded, and the error is rethrown.
18655
+ *
18656
+ * Through the history snapshot rather than a copy of the interface document, because the edits
18657
+ * inside have already run the blueprint reconcile: a deleted widget's graph is gone, and putting
18658
+ * the element back alone would have the reconcile give it a fresh, empty graph under the same id.
18659
+ */
18660
+ runAtomicSurfaceTransaction(surfaceId: string, action: () => void, options?: {
18661
+ label?: HistoryLabel;
18662
+ }): void;
18663
+ /**
18664
+ * Run this service's own edits against a private copy of the document, then throw the copy away.
18665
+ *
18666
+ * What a dry run needs: every check an edit makes runs exactly as it would for real, against the
18667
+ * document as the earlier edits in the same run left it, and nothing outside this service hears of
18668
+ * any of it - no `documentChanged`, no auto-save, no undo step, no live-session message and, above
18669
+ * all, no blueprint reconcile. The reconcile is not undone by putting the document back: it deletes
18670
+ * the graph of every widget the copy lost, and then gives the restored widget an empty one.
18671
+ *
18672
+ * The document's revision does not move, so nothing that reads it should be asked inside.
18673
+ */
18674
+ runDetachedDraft<T>(action: () => T): T;
18675
+ /**
18676
+ * An edit made by an agent connected over MCP, written as one step of undo.
18677
+ *
18678
+ * Through the private mutator like every gesture, which is the whole point: the canvas redraws
18679
+ * on `documentChanged`, auto-save picks the change up, the blueprint reconcile hook runs, and the
18680
+ * author's Ctrl+Z takes it back - an agent's edit is an edit like any other.
18681
+ *
18682
+ * `scope` says which stack the step belongs on. One page or one component definition: that
18683
+ * editor's own stack, as a snapshot of its slice, so Ctrl+Z inside its tab undoes it. Null - an
18684
+ * edit across several pages, or to a table the pages share - goes on the project's stack as a
18685
+ * command over the delta, diffed both ways, because no one editor's slice covers it (the shape
18686
+ * {@link pushLibraryStep} uses for library operations) - with the private blueprints the write's
18687
+ * reconcile created or deleted, which a delta of interface records alone would leave behind (see
18688
+ * `reconciledBlueprintOwners.ts`).
18689
+ *
18690
+ * Not for a live session: {@link applyLiveOp} is the path for somebody else's edit, and records
18691
+ * nothing. Agent writes are refused while a session runs, before they get here.
18692
+ */
18693
+ applyAgentMutation(scope: {
18694
+ surfaceId: string;
18695
+ } | {
18696
+ componentId: string;
18697
+ } | null, label: HistoryLabel, mutator: (document: UIDocument) => void): void;
18698
+ /**
18699
+ * Write a compiled `.ui` document's pages and definitions, as one step of undo.
18700
+ *
18701
+ * The compile and the write itself belong to the agent core, which hands its writer in as
18702
+ * `mutate` so this service does not depend on it. What is decided here is only where the step is
18703
+ * recorded: one page or one definition goes on that editor's stack, anything wider on the
18704
+ * project's - see {@link applyAgentMutation}.
18705
+ */
18706
+ applyCompiledUi(input: {
18707
+ surfaceIds: readonly string[];
18708
+ componentIds: readonly string[];
18709
+ label: HistoryLabel;
18710
+ mutate: (document: UIDocument) => void;
18711
+ }): void;
17617
18712
  isDirty(): boolean;
17618
18713
  getRevision(): number;
17619
18714
  /**
@@ -17751,6 +18846,22 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
17751
18846
  * being a project-level table; a surface that had said otherwise keeps what it said.
17752
18847
  */
17753
18848
  setInputActionBindings(actionId: string, bindings: readonly UIInputBinding[]): void;
18849
+ /**
18850
+ * Put an intent in a navigation slot, or take it out of the one it fills (`slot` null).
18851
+ *
18852
+ * A slot holds one intent, so the intent that held it before gives it up in the same step: the
18853
+ * panel offers every intent for every slot, and picking one is the whole of moving it.
18854
+ */
18855
+ setInputActionNavigationSlot(actionId: string, slot: UINavigationSlot | null): void;
18856
+ /**
18857
+ * Give every empty navigation slot an intent of its own, bound to the keys and pad buttons a
18858
+ * player expects (`UI_NAVIGATION_SLOT_PRESET_BINDINGS`), named in the author's language.
18859
+ *
18860
+ * The way an existing project takes up keyboard and pad navigation: the bindings are written into
18861
+ * the project as the template's are, and are the author's from then on. A slot already filled is
18862
+ * left as the author filled it. Returns how many intents were made.
18863
+ */
18864
+ fillEmptyNavigationSlots(names: Readonly<Record<UINavigationSlot, string>>): number;
17754
18865
  /**
17755
18866
  * Drop one vocabulary entry, and every surface's answer to it, in one transaction.
17756
18867
  *
@@ -17824,7 +18935,24 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
17824
18935
  updateElementAnimation(elementId: string, animation: UIPageAnimationSettings | null, options?: {
17825
18936
  mergeKey?: string;
17826
18937
  }): void;
18938
+ /**
18939
+ * How the player reaches this element without a pointer. `null` clears it.
18940
+ *
18941
+ * Allowed on a linked component instance, as its animation is: it belongs to where the instance
18942
+ * was placed. Which element is up from a Back button depends on the page it is on.
18943
+ */
18944
+ updateElementNavigation(elementId: string, navigation: UIElementNavigation | null, options?: {
18945
+ mergeKey?: string;
18946
+ }): void;
17827
18947
  updateElementExtra(elementId: string, extraPatch: Record<string, unknown>): void;
18948
+ /**
18949
+ * Merge CSS overrides into an element's `style`; a `null` value removes that override.
18950
+ *
18951
+ * The renderer spreads `style` over the widget's own styles (`extractStyleOverrides`), so this is
18952
+ * the bag a `.ui` file's `style.*` lines write. Nothing in the editor's panels writes it; the
18953
+ * agent's `ui_patch` does, with the same refusal for a placed component that props have.
18954
+ */
18955
+ updateElementStyle(elementId: string, stylePatch: Record<string, unknown>): void;
17828
18956
  reorderChildren(parentId: string, orderedChildIds: string[]): void;
17829
18957
  moveElementsInSurface(surfaceId: string, elementIds: string[], targetParentId: string, beforeChildId: string | null): MoveUiElementsResult;
17830
18958
  /**
@@ -17937,6 +19065,30 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
17937
19065
  * operation sink taking the gesture looks like (the reasoning {@link reorderSurfaces} gives).
17938
19066
  */
17939
19067
  private recordLibraryAddition;
19068
+ /**
19069
+ * Take input actions an import adopted back out of the vocabulary, and return them as they stood.
19070
+ *
19071
+ * Only the ones nothing left in the project answers or names. This runs after the import's own
19072
+ * surfaces and blueprints have gone, so an action a surface still answers, or a blueprint node
19073
+ * still picks, is one the author has put to use since - taking it would leave that surface or node
19074
+ * answering nothing (the rule an agent's outline step keeps for a chapter it added). Empty when
19075
+ * nothing left this copy of the document: an operation sink took the gesture.
19076
+ */
19077
+ private takeAdoptedInputActions;
19078
+ /**
19079
+ * Remove vocabulary entries by id, recording nothing. A vocabulary left empty is left out of the
19080
+ * document, as it is in one that never had an action - so taking back the import that brought a
19081
+ * project its first actions gives back the document it had.
19082
+ */
19083
+ private dropInputActions;
19084
+ /**
19085
+ * Put actions {@link takeAdoptedInputActions} returned back. An id the vocabulary has gained in
19086
+ * the meantime keeps what it holds, and a navigation slot another action has come to fill stays
19087
+ * with that one - the rule the adoption itself follows.
19088
+ */
19089
+ private putInputActions;
19090
+ /** Every input action id a node of any blueprint in the project picks. */
19091
+ private inputActionIdsPickedByBlueprints;
17940
19092
  private getElementSurfaceId;
17941
19093
  private getCommonSurfaceIdForElements;
17942
19094
  private filterLinkedComponentLayoutPatch;
@@ -18034,6 +19186,36 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
18034
19186
  * the way to delete the page it starts on is to make another page the entry first.
18035
19187
  */
18036
19188
  deleteSurface(surfaceId: string): void;
19189
+ /**
19190
+ * Take surfaces out of the project with their trees and their blueprints, as one step on the
19191
+ * project's undo stack - the shape {@link deleteComponents} gives definitions. Undo puts each one
19192
+ * back where it stood, blueprints first.
19193
+ *
19194
+ * The entry page is refused for the reason {@link deleteSurface} gives, and nothing is taken when
19195
+ * one of the ids is it. Returns the surfaces taken, empty when nothing was.
19196
+ */
19197
+ deleteSurfaces(surfaceIds: readonly string[], label: HistoryLabel): UISurface[];
19198
+ /**
19199
+ * Bring a bundle in, in place of some of the project's surfaces, and make one of its pages the
19200
+ * entry - as one step on the project's undo stack.
19201
+ *
19202
+ * What `importTemplateBundle` does on its own leaves the rest of such a change as separate steps,
19203
+ * and an undo that took back only the import would leave a project with neither the surfaces it
19204
+ * removed nor the ones it brought. Here one Ctrl+Z puts back exactly what was there: the removed
19205
+ * surfaces with their blueprints, the entry page as the document named it, and none of the
19206
+ * arrivals - the input actions the import adopted included, as for a plain import. Files and
19207
+ * translations stay, as they do for a plain import.
19208
+ *
19209
+ * `removeSurfaceIds` may name the entry page; `entrySourceSurfaceId` names a page of the bundle by
19210
+ * its id there. When it is absent or did not arrive, the entry is left to the document's own rule.
19211
+ */
19212
+ installBundle(input: Omit<ImportTemplateBundleInput, "history"> & {
19213
+ removeSurfaceIds: readonly string[];
19214
+ entrySourceSurfaceId?: string;
19215
+ label: HistoryLabel;
19216
+ }): ImportTemplateResult & {
19217
+ removedSurfaces: UISurface[];
19218
+ };
18037
19219
  /**
18038
19220
  * Put the surfaces in the order given.
18039
19221
  *
@@ -18071,7 +19253,16 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
18071
19253
  setEntrySurface(surfaceId: string): void;
18072
19254
  private applyEntrySurface;
18073
19255
  private applySurfaceOrder;
18074
- renameSurface(surfaceId: string, name: string): void;
19256
+ /**
19257
+ * Rename a surface, as a step on its own undo stack.
19258
+ *
19259
+ * `label` is for a rename nobody typed - an agent's - and makes it a step of its own under that
19260
+ * name. Merged into the author's typing, as a typed name is merged a keystroke at a time, one
19261
+ * Ctrl+Z would take back the author's rename and the agent's together.
19262
+ */
19263
+ renameSurface(surfaceId: string, name: string, options?: {
19264
+ label?: HistoryLabel;
19265
+ }): void;
18075
19266
  /**
18076
19267
  * Edit a surface's own record - its name, its background, its page animation, its slot.
18077
19268
  *
@@ -18111,6 +19302,31 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
18111
19302
  * or clobbering a surface.
18112
19303
  */
18113
19304
  importTemplateBundle(input: ImportTemplateBundleInput): ImportTemplateResult;
19305
+ /**
19306
+ * Give this project's input vocabulary the actions the arriving surfaces answer and it lacks.
19307
+ *
19308
+ * A surface keeps its replies to the project's actions (`surface.actions`) when it is copied in -
19309
+ * a dialogue box that advances on a click or Space does so because it answers `advance` - and a
19310
+ * reply to an action the project has never declared answers nothing. So each such action comes
19311
+ * along under its own id, with its bindings. One the project already has is the project's, and
19312
+ * keeps the author's bindings; a navigation slot another of the project's actions claims stays
19313
+ * with that one.
19314
+ *
19315
+ * So does a key or a pad button the project already binds to an action of its own: the arriving
19316
+ * action comes without that binding, and keeps the rest. A key is aimed at no place - it reaches
19317
+ * whatever answers it - so a second action bound to the author's key would change what that key
19318
+ * does in the author's game, which a page brought in must not do behind their back; the author can
19319
+ * bind it on purpose under Input Actions. The action still arrives, so the surface answers it by
19320
+ * its remaining bindings, and nothing is lost that adding it unbound would have kept.
19321
+ *
19322
+ * Two kinds of binding are not held back, because sharing them is how the vocabulary is meant to
19323
+ * be used. A pointer gesture lands on whatever surface is under the pointer and fires what that
19324
+ * surface answers. And a key the project gives to a navigation intent (a focus move, Confirm,
19325
+ * Cancel) is shared with the actions surfaces answer by design - the starter template binds Space
19326
+ * to both Advance and Confirm - so a project that took up keyboard navigation still gets a
19327
+ * dialogue box that reads on with Space.
19328
+ */
19329
+ private adoptArrivingInputActions;
18114
19330
  /**
18115
19331
  * Copy a template's component library into this project, under fresh ids.
18116
19332
  *
@@ -18253,7 +19469,12 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
18253
19469
  updateComponentElementAnimation(componentId: string, elementId: string, animation: UIPageAnimationSettings | null, options?: {
18254
19470
  mergeKey?: string;
18255
19471
  }): void;
19472
+ updateComponentElementNavigation(componentId: string, elementId: string, navigation: UIElementNavigation | null, options?: {
19473
+ mergeKey?: string;
19474
+ }): void;
18256
19475
  updateComponentElementExtra(componentId: string, elementId: string, extraPatch: Record<string, unknown>): void;
19476
+ /** The component-definition counterpart of {@link updateElementStyle}. */
19477
+ updateComponentElementStyle(componentId: string, elementId: string, stylePatch: Record<string, unknown>): void;
18257
19478
  renameComponentElement(componentId: string, elementId: string, name: string): void;
18258
19479
  reorderComponentChildren(componentId: string, parentId: string, orderedChildIds: string[]): void;
18259
19480
  deleteComponentElements(componentId: string, elementIds: string[]): void;
@@ -18283,9 +19504,17 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
18283
19504
  * placement look as they did, and the root can now be given siblings.
18284
19505
  */
18285
19506
  wrapComponentRoot(componentId: string): string | null;
19507
+ /**
19508
+ * An element id a caller asked for, checked against every pool it could collide in - the
19509
+ * project's elements and every component definition's - or null when none was asked for.
19510
+ */
19511
+ private claimElementId;
18286
19512
  /** An element as an Edit menu step names it: its own name, or its widget's. */
18287
19513
  private describeElementForHistory;
18288
- createComponentElement(componentId: string, parentId: string, type: string, layoutPatch?: Partial<UILayout>): UIElement | null;
19514
+ /** `options.id`: see {@link createElement}. */
19515
+ createComponentElement(componentId: string, parentId: string, type: string, layoutPatch?: Partial<UILayout>, options?: {
19516
+ id?: string;
19517
+ }): UIElement | null;
18289
19518
  pasteComponentClipboardPayload(componentId: string, targetParentId: string, beforeChildId: string | null, incoming: UIEditorClipboardPayload): {
18290
19519
  ok: true;
18291
19520
  newRootIds: string[];
@@ -18293,9 +19522,18 @@ declare class UIDocumentService extends Service<UIDocumentService> implements IU
18293
19522
  ok: false;
18294
19523
  reason: "invalid_clipboard" | "invalid_target";
18295
19524
  };
18296
- createComponentInstance(parentId: string, componentId: string, layoutPatch?: Partial<UILayout>): UIElement;
19525
+ /** `options.id`: see {@link createElement}. */
19526
+ createComponentInstance(parentId: string, componentId: string, layoutPatch?: Partial<UILayout>, options?: {
19527
+ id?: string;
19528
+ }): UIElement;
18297
19529
  unlinkComponentInstance(elementId: string): string[];
18298
- createElement(parentId: string, type: string, layoutPatch?: Partial<UILayout>): UIElement;
19530
+ /**
19531
+ * `options.id` gives the new element an id of the caller's choosing - an agent naming an element
19532
+ * so a blueprint it writes next can refer to it. Refused when the id is already in use.
19533
+ */
19534
+ createElement(parentId: string, type: string, layoutPatch?: Partial<UILayout>, options?: {
19535
+ id?: string;
19536
+ }): UIElement;
18299
19537
  pasteClipboardPayload(surfaceId: string, targetParentId: string, beforeChildId: string | null, incoming: UIEditorClipboardPayload): {
18300
19538
  ok: true;
18301
19539
  newRootIds: string[];
@@ -18534,6 +19772,84 @@ type PropertyFieldBindingMeta = {
18534
19772
  /** Current literal from the document when creating a binding (persisted as fallback). */
18535
19773
  readLiteral: (data: UIInspectorData) => string | number | boolean | null;
18536
19774
  };
19775
+ declare const HELP_TOPIC_IDS: readonly [
19776
+ "gettingHelp",
19777
+ "workspaceLayout",
19778
+ "newProject",
19779
+ "runModes",
19780
+ "keyboard",
19781
+ "search",
19782
+ "undo",
19783
+ "studioSettings",
19784
+ "storyScene",
19785
+ "storyCommands",
19786
+ "storyVariables",
19787
+ "storyExpressions",
19788
+ "storyFlow",
19789
+ "storyScript",
19790
+ "storyPaste",
19791
+ "sceneSnapshot",
19792
+ "storyMotion",
19793
+ "dictionary",
19794
+ "dictionaryMarks",
19795
+ "assets",
19796
+ "assetSources",
19797
+ "assetSets",
19798
+ "assetSetAxes",
19799
+ "mediaConversion",
19800
+ "characters",
19801
+ "appearances",
19802
+ "puppetRuntimes",
19803
+ "audio",
19804
+ "audioClips",
19805
+ "videoClips",
19806
+ "voice",
19807
+ "localization",
19808
+ "brand",
19809
+ "uiSurfaces",
19810
+ "inputActions",
19811
+ "inputActionBindings",
19812
+ "inputActionAnswering",
19813
+ "inputActionsInBlueprints",
19814
+ "focusNavigation",
19815
+ "focusNavigationSettings",
19816
+ "uiComponents",
19817
+ "blueprints",
19818
+ "scripts",
19819
+ "uiBindings",
19820
+ "networkNodes",
19821
+ "spellcheck",
19822
+ "lint",
19823
+ "tests",
19824
+ "dashboard",
19825
+ "recovery",
19826
+ "versionControl",
19827
+ "versionChanges",
19828
+ "versionViewing",
19829
+ "versionRestore",
19830
+ "versionConflicts",
19831
+ "versionServer",
19832
+ "freeze",
19833
+ "build",
19834
+ "saveLocation",
19835
+ "olderSaves",
19836
+ "saveSameStory",
19837
+ "saveStoryChanged",
19838
+ "patches",
19839
+ "buildVariant",
19840
+ "appTags",
19841
+ "variantContent",
19842
+ "icons",
19843
+ "signing",
19844
+ "assetProtection",
19845
+ "networkAllowlist",
19846
+ "assetCompression",
19847
+ "screenEffects",
19848
+ "plugins"
19849
+ ];
19850
+ type StaticHelpTopicId = (typeof HELP_TOPIC_IDS)[number];
19851
+ type LintRuleHelpTopicId = `lintRule.${string}`;
19852
+ type HelpTopicId = StaticHelpTopicId | LintRuleHelpTopicId;
18537
19853
  type FieldType = "text" | "textarea" | "number" | "toggle" | "select" | "tags" | "custom" | "info" | "thumbnail" | "section" | "colorPicker" | "colorPickerGroup" | "iconButtonGroup" | "dropdownGroup" | "menuTrigger" | "inputGroup" | "inlineRow" | "imageFill" | "fontAsset";
18538
19854
  interface BaseFieldDefinition<TData = any> {
18539
19855
  /** Unique identifier for the field */
@@ -18801,6 +20117,13 @@ interface SectionFieldDefinition<TData = any> extends BaseFieldDefinition<TData>
18801
20117
  collapsible?: boolean;
18802
20118
  /** Whether the section is collapsed by default */
18803
20119
  defaultCollapsed?: boolean;
20120
+ /**
20121
+ * The help topic about the whole section: `F1` anywhere inside it, and a `?` in its header.
20122
+ *
20123
+ * For a section whose effect cannot be read off its own fields, under the rule in
20124
+ * `docs/help-system.md` §5. A section that explains itself through its fields' tips passes none.
20125
+ */
20126
+ helpTopic?: HelpTopicId;
18804
20127
  }
18805
20128
  interface CustomFieldProps<TData = any> {
18806
20129
  data: TData;
@@ -19305,6 +20628,19 @@ export type TestFinding = {
19305
20628
  severity: TestFindingSeverity;
19306
20629
  message: TestText;
19307
20630
  target?: SearchJumpTarget;
20631
+ /**
20632
+ * A stable, machine-readable name for the rule or check that produced this finding (for the
20633
+ * project-diagnostics test, the lint rule id such as `story/dead-end`). Optional: a finding
20634
+ * without one is still a finding. Never translated, so a script or an agent can match on it.
20635
+ */
20636
+ ruleId?: string;
20637
+ /**
20638
+ * The message in English, for machine readers (Studio's agent connection hands findings to
20639
+ * agents whose tool descriptions are English). Optional; when absent the agent gets `message`
20640
+ * rendered as well as it can be. Never shown in Studio's own report, which follows the editor
20641
+ * language through `message`.
20642
+ */
20643
+ englishMessage?: string;
19308
20644
  };
19309
20645
  /**
19310
20646
  * What `run` may return. Note the absence of `cancelled` and `errored`: see the header.
@@ -19652,7 +20988,11 @@ declare enum Services {
19652
20988
  /** "The working tree changed under the editors": drops in-memory documents and re-reads them */
19653
20989
  WorkspaceReload = "workspaceReload",
19654
20990
  /** Recovery mode's own state: which subsystems have been tried, and what they said */
19655
- Recovery = "recovery"
20991
+ Recovery = "recovery",
20992
+ /** What the author sees of a connected AI agent, and the pause and follow switches over it */
20993
+ AgentFollow = "agentFollow",
20994
+ /** Carries out the calls an AI agent makes over Studio's MCP endpoint; see `agent/AgentBridgeService` */
20995
+ AgentBridge = "agentBridge"
19656
20996
  }
19657
20997
  interface IUIDocumentService extends IService {
19658
20998
  load(): Promise<UIDocument>;
@@ -19755,6 +21095,17 @@ export type StoryPluginActionCreateInput = {
19755
21095
  generateId: () => string;
19756
21096
  initialText?: string;
19757
21097
  };
21098
+ /**
21099
+ * One field the scene inspector shows on a row of a plugin story action, editing `params[key]`.
21100
+ *
21101
+ * The descriptor a plugin node's `inspectorParams` already takes, narrowed to the kinds a row's params
21102
+ * can hold: a pick (static `options`, or a `dynamicOptionsSource` registered through
21103
+ * `app.services.blueprintNodes`), a string, or a number. A plugin that offers the same choice on a
21104
+ * node and on a row passes both the same object, so both list the same options.
21105
+ */
21106
+ export type StoryPluginActionParamDef = Pick<BlueprintInspectorParamDef, "key" | "label" | "options" | "dynamicOptionsSource" | "emptyOptionLabel"> & {
21107
+ kind: "select" | "string" | "number";
21108
+ };
19758
21109
  export type StoryPluginActionRegistration = {
19759
21110
  id: string;
19760
21111
  label: string;
@@ -19767,83 +21118,23 @@ export type StoryPluginActionRegistration = {
19767
21118
  * editor, so an action whose params change what the row does says what they are here.
19768
21119
  */
19769
21120
  describe?: (params: Record<string, unknown>) => string | null | undefined;
21121
+ /**
21122
+ * Words a typed command finds this action by in every interface language, as a built-in command
21123
+ * answers to its own word: with `keywords: ["unlock"]`, `/unlock ACH_WIN` commits this action with
21124
+ * "ACH_WIN" as its initial text. Without them a typed command has to start the label or the id.
21125
+ * Single words; a built-in command's word stays the built-in's.
21126
+ */
21127
+ keywords?: readonly string[];
21128
+ /**
21129
+ * The fields the scene inspector shows when one of this action's `{action:"plugin"}` rows is
21130
+ * selected, each editing one key of the row's `params`. Without them a row keeps whatever
21131
+ * `createBlock` wrote, and changing it means inserting the row again.
21132
+ *
21133
+ * A field of a kind this Studio does not know is left out of the inspector, so a plugin written
21134
+ * for a later Studio still registers here.
21135
+ */
21136
+ params?: readonly StoryPluginActionParamDef[];
19770
21137
  };
19771
- declare const HELP_TOPIC_IDS: readonly [
19772
- "gettingHelp",
19773
- "workspaceLayout",
19774
- "newProject",
19775
- "runModes",
19776
- "keyboard",
19777
- "search",
19778
- "undo",
19779
- "studioSettings",
19780
- "storyScene",
19781
- "storyCommands",
19782
- "storyVariables",
19783
- "storyExpressions",
19784
- "storyFlow",
19785
- "storyScript",
19786
- "storyPaste",
19787
- "sceneSnapshot",
19788
- "storyMotion",
19789
- "dictionary",
19790
- "dictionaryMarks",
19791
- "assets",
19792
- "assetSources",
19793
- "assetSets",
19794
- "assetSetAxes",
19795
- "mediaConversion",
19796
- "characters",
19797
- "appearances",
19798
- "puppetRuntimes",
19799
- "audio",
19800
- "audioClips",
19801
- "videoClips",
19802
- "voice",
19803
- "localization",
19804
- "brand",
19805
- "uiSurfaces",
19806
- "inputActions",
19807
- "inputActionBindings",
19808
- "inputActionAnswering",
19809
- "inputActionsInBlueprints",
19810
- "uiComponents",
19811
- "blueprints",
19812
- "scripts",
19813
- "uiBindings",
19814
- "networkNodes",
19815
- "spellcheck",
19816
- "lint",
19817
- "tests",
19818
- "dashboard",
19819
- "recovery",
19820
- "versionControl",
19821
- "versionChanges",
19822
- "versionViewing",
19823
- "versionRestore",
19824
- "versionConflicts",
19825
- "versionServer",
19826
- "freeze",
19827
- "build",
19828
- "saveLocation",
19829
- "olderSaves",
19830
- "saveSameStory",
19831
- "saveStoryChanged",
19832
- "patches",
19833
- "buildVariant",
19834
- "appTags",
19835
- "variantContent",
19836
- "icons",
19837
- "signing",
19838
- "assetProtection",
19839
- "networkAllowlist",
19840
- "assetCompression",
19841
- "screenEffects",
19842
- "plugins"
19843
- ];
19844
- type StaticHelpTopicId = (typeof HELP_TOPIC_IDS)[number];
19845
- type LintRuleHelpTopicId = `lintRule.${string}`;
19846
- type HelpTopicId = StaticHelpTopicId | LintRuleHelpTopicId;
19847
21138
  interface PanelComponentProps<TPayload = any> {
19848
21139
  panelId: string;
19849
21140
  payload?: TPayload;
@@ -22156,6 +23447,40 @@ export type PluginLocalizationService = {
22156
23447
  */
22157
23448
  registerWords(source: PluginWordsSource): PluginCleanup;
22158
23449
  };
23450
+ /**
23451
+ * Tools this plugin offers the AI agents an author connects to Studio's MCP endpoint (Claude Code,
23452
+ * Codex, Cursor and the like).
23453
+ *
23454
+ * Each tool is declared by name and `write` in the manifest's `contributes.agentTools` - registering
23455
+ * an undeclared one throws - and is advertised to agents as `<plugin id>__<tool>`, with every `.`
23456
+ * and `-` turned into `_` (`acme.notes.add_note` is `acme_notes__add_note`). A Markdown chapter at
23457
+ * `contributes.agentGuide` is served to agents as `agent_guide {chapter: "plugin:<plugin id>"}`.
23458
+ *
23459
+ * What the host does around every call, so the plugin does not have to:
23460
+ *
23461
+ * - **Gates it** exactly as it gates Studio's own tools: a `write: true` tool is refused unless the
23462
+ * author allowed agent writes, and while they paused the agent, the project is frozen or a live
23463
+ * session runs. The author can also switch a plugin's tools off in Settings > Agent access.
23464
+ * - **Checks the arguments** against `inputSchema` before the handler runs, and removes `project`
23465
+ * (the host's routing argument).
23466
+ * - **Holds a reading tool to its plugin storage:** while a `write: false` tool runs,
23467
+ * `storage.writeJson` throws. That is the whole of it - a `write: false` tool is not gated by the
23468
+ * author's write switch, and anything else your `app` can do, its handler can do too. Declare a
23469
+ * tool `write: true` if it changes the project by any route.
23470
+ * - **Makes a writing tool's edit one undo step:** every `storage.writeJson` it does is captured,
23471
+ * and Ctrl+Z puts every namespace back as it was, then calls the reloader you registered with
23472
+ * `workspace.registerReloader` - so register one, or undo will change the file and not your
23473
+ * memory of it.
23474
+ * - **Caps the answer:** text past 60 000 characters is cut, `data` past 60 000 characters of JSON
23475
+ * is left out, and at most one image is passed on.
23476
+ *
23477
+ * A handler receives the arguments and the client's name, nothing else: whatever it does, it does
23478
+ * with this plugin's own `app`.
23479
+ */
23480
+ export type PluginAgentService = {
23481
+ registerTool(def: PluginAgentToolDef): PluginCleanup;
23482
+ registerTools(defs: PluginAgentToolDef[]): PluginCleanup;
23483
+ };
22159
23484
  export type PluginServices = {
22160
23485
  storage: PluginStorageService;
22161
23486
  assets: PluginAssetsService;
@@ -22170,6 +23495,8 @@ export type PluginServices = {
22170
23495
  localization: PluginLocalizationService;
22171
23496
  /** Contribute checks to Run > Test; see {@link PluginTestService}. */
22172
23497
  tests: PluginTestService;
23498
+ /** Offer tools to AI agents connected to Studio; see {@link PluginAgentService}. */
23499
+ agent: PluginAgentService;
22173
23500
  ui: {
22174
23501
  panels: {
22175
23502
  register<TPayload = unknown>(panel: PanelDefinition<TPayload>): PluginCleanup;
@@ -22228,11 +23555,14 @@ export type PluginServices = {
22228
23555
  listScenes(storyId: string): Promise<PluginSceneEntry[]>;
22229
23556
  actions: {
22230
23557
  /**
22231
- * Register a scene-editor palette action (shown under the Plugin
22232
- * category) that creates story blocks. The blocks it returns are
22233
- * standard story blocks - the document does not depend on the
22234
- * plugin after creation. Action ids must be prefixed with the
23558
+ * Register a scene-editor palette action (shown under Tools)
23559
+ * that creates story blocks. Action ids must be prefixed with the
22235
23560
  * plugin id.
23561
+ *
23562
+ * A standard story block owes the plugin nothing once inserted. A
23563
+ * `{action:"plugin"}` row is the plugin's own: the runtime entry's
23564
+ * `app.game.storyActions` runs it, and the fields in `params` are
23565
+ * what the scene inspector lets the author change on it.
22236
23566
  */
22237
23567
  register(registration: StoryPluginActionRegistration): PluginCleanup;
22238
23568
  registerMany(registrations: StoryPluginActionRegistration[]): PluginCleanup;