framer-dalton 0.0.25 → 0.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli.js +346 -311
- package/dist/start-relay-server.js +111 -27
- package/docs/skills/framer-project.md +36 -19
- package/docs/skills/framer.md +1 -1
- package/package.json +8 -7
package/dist/cli.js
CHANGED
|
@@ -12,7 +12,7 @@ import net from 'net';
|
|
|
12
12
|
import { fileURLToPath } from 'url';
|
|
13
13
|
import { createTRPCClient, httpLink } from '@trpc/client';
|
|
14
14
|
|
|
15
|
-
/* @framer/ai CLI v0.0.
|
|
15
|
+
/* @framer/ai CLI v0.0.27 */
|
|
16
16
|
var __defProp = Object.defineProperty;
|
|
17
17
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
18
18
|
|
|
@@ -29,6 +29,51 @@ Please upgrade: https://nodejs.org/`
|
|
|
29
29
|
);
|
|
30
30
|
process.exit(1);
|
|
31
31
|
}
|
|
32
|
+
|
|
33
|
+
// src/agent-thread-context.ts
|
|
34
|
+
var MAX_AGENT_THREAD_ID_LENGTH = 256;
|
|
35
|
+
var MAX_AGENT_PROVIDER_LENGTH = 64;
|
|
36
|
+
var SAFE_VALUE_PATTERN = /^[A-Za-z0-9._:-]+$/;
|
|
37
|
+
var providerEnvVars = [
|
|
38
|
+
{ provider: "codex", envVar: "CODEX_THREAD_ID" },
|
|
39
|
+
{ provider: "claude", envVar: "CLAUDE_CODE_SESSION_ID" },
|
|
40
|
+
{ provider: "claude", envVar: "CLAUDE_CODE_REMOTE_SESSION_ID" }
|
|
41
|
+
];
|
|
42
|
+
function normalizeValue(value, maxLength) {
|
|
43
|
+
const trimmed = value?.trim();
|
|
44
|
+
if (!trimmed) return void 0;
|
|
45
|
+
if (trimmed.length > maxLength) return void 0;
|
|
46
|
+
if (!SAFE_VALUE_PATTERN.test(trimmed)) return void 0;
|
|
47
|
+
return trimmed;
|
|
48
|
+
}
|
|
49
|
+
__name(normalizeValue, "normalizeValue");
|
|
50
|
+
function normalizeAgentThreadContext(input) {
|
|
51
|
+
const agentThreadId = normalizeValue(
|
|
52
|
+
input.agentThreadId,
|
|
53
|
+
MAX_AGENT_THREAD_ID_LENGTH
|
|
54
|
+
);
|
|
55
|
+
if (!agentThreadId) return {};
|
|
56
|
+
const agentProvider = normalizeValue(
|
|
57
|
+
input.agentProvider,
|
|
58
|
+
MAX_AGENT_PROVIDER_LENGTH
|
|
59
|
+
);
|
|
60
|
+
return {
|
|
61
|
+
agentThreadId,
|
|
62
|
+
...agentProvider ? { agentProvider } : {}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
__name(normalizeAgentThreadContext, "normalizeAgentThreadContext");
|
|
66
|
+
function resolveAgentThreadContext(env = process.env) {
|
|
67
|
+
for (const { provider, envVar } of providerEnvVars) {
|
|
68
|
+
const agentThreadContext = normalizeAgentThreadContext({
|
|
69
|
+
agentThreadId: env[envVar],
|
|
70
|
+
agentProvider: provider
|
|
71
|
+
});
|
|
72
|
+
if (agentThreadContext.agentThreadId) return agentThreadContext;
|
|
73
|
+
}
|
|
74
|
+
return {};
|
|
75
|
+
}
|
|
76
|
+
__name(resolveAgentThreadContext, "resolveAgentThreadContext");
|
|
32
77
|
function openUrl(url) {
|
|
33
78
|
const platform = process.platform;
|
|
34
79
|
let cmd;
|
|
@@ -330,7 +375,7 @@ __name(markTelemetryNoticeShown, "markTelemetryNoticeShown");
|
|
|
330
375
|
// src/version.ts
|
|
331
376
|
var VERSION = (
|
|
332
377
|
// typeof is used to ensure this can be used just via tsx or node etc. without build
|
|
333
|
-
"0.0.
|
|
378
|
+
"0.0.27"
|
|
334
379
|
);
|
|
335
380
|
var trackingEndpoint = "https://events.framer.com/track";
|
|
336
381
|
var inProgressTrackings = /* @__PURE__ */ new Set();
|
|
@@ -420,6 +465,45 @@ function trackError(payload) {
|
|
|
420
465
|
});
|
|
421
466
|
}
|
|
422
467
|
__name(trackError, "trackError");
|
|
468
|
+
|
|
469
|
+
// src/connection-errors.ts
|
|
470
|
+
var RELAY_CONNECTION_LOST_PATTERNS = [
|
|
471
|
+
"fetch failed",
|
|
472
|
+
// undici top-level: relay gone / socket closed mid-request
|
|
473
|
+
"other side closed",
|
|
474
|
+
// undici SocketError: relay exited mid-request
|
|
475
|
+
"UND_ERR_SOCKET",
|
|
476
|
+
// undici socket error code
|
|
477
|
+
"ECONNREFUSED",
|
|
478
|
+
// relay not listening
|
|
479
|
+
"ECONNRESET",
|
|
480
|
+
// connection reset mid-request
|
|
481
|
+
"socket hang up"
|
|
482
|
+
];
|
|
483
|
+
function isRelayConnectionLost(err) {
|
|
484
|
+
const seen = /* @__PURE__ */ new Set();
|
|
485
|
+
const stack = [err];
|
|
486
|
+
while (stack.length > 0) {
|
|
487
|
+
const node = stack.pop();
|
|
488
|
+
if (node == null || seen.has(node)) continue;
|
|
489
|
+
seen.add(node);
|
|
490
|
+
const e = node;
|
|
491
|
+
const text = `${typeof e.message === "string" ? e.message : ""} ${typeof e.code === "string" ? e.code : ""}`;
|
|
492
|
+
if (RELAY_CONNECTION_LOST_PATTERNS.some((pattern) => text.includes(pattern)))
|
|
493
|
+
return true;
|
|
494
|
+
if (e.cause != null) stack.push(e.cause);
|
|
495
|
+
if (Array.isArray(e.errors)) stack.push(...e.errors);
|
|
496
|
+
}
|
|
497
|
+
return false;
|
|
498
|
+
}
|
|
499
|
+
__name(isRelayConnectionLost, "isRelayConnectionLost");
|
|
500
|
+
var AUTH_ERROR_PATTERNS = ["does not have access", "UNAUTHORIZED"];
|
|
501
|
+
function isAuthError(errorMessage) {
|
|
502
|
+
return AUTH_ERROR_PATTERNS.some((p) => errorMessage.includes(p));
|
|
503
|
+
}
|
|
504
|
+
__name(isAuthError, "isAuthError");
|
|
505
|
+
|
|
506
|
+
// src/utils.ts
|
|
423
507
|
function rehydrateFramerAPIError(error) {
|
|
424
508
|
if (!(error instanceof Error)) return null;
|
|
425
509
|
const framerApi = error.data?.framerApi;
|
|
@@ -448,10 +532,12 @@ function formatError(error) {
|
|
|
448
532
|
return String(error);
|
|
449
533
|
}
|
|
450
534
|
__name(formatError, "formatError");
|
|
451
|
-
function formatErrorForUser(error) {
|
|
535
|
+
function formatErrorForUser(error, opts) {
|
|
452
536
|
if (!(error instanceof Error)) return String(error);
|
|
453
537
|
const rehydrated = rehydrateFramerAPIError(error);
|
|
454
538
|
if (rehydrated) return rehydrated.toString();
|
|
539
|
+
if (!opts?.fromExecResult && isRelayConnectionLost(error))
|
|
540
|
+
return "Connection to the Framer server was lost. Run `framer session new` to reconnect.";
|
|
455
541
|
const ref = getErrorRef(error);
|
|
456
542
|
return ref ? `${error.message} [ref: ${ref}]` : error.message;
|
|
457
543
|
}
|
|
@@ -819,13 +905,6 @@ async function acquireAuthWithRemixProject(sourceProjectUrlOrId) {
|
|
|
819
905
|
}
|
|
820
906
|
__name(acquireAuthWithRemixProject, "acquireAuthWithRemixProject");
|
|
821
907
|
|
|
822
|
-
// src/connection-errors.ts
|
|
823
|
-
var AUTH_ERROR_PATTERNS = ["does not have access", "UNAUTHORIZED"];
|
|
824
|
-
function isAuthError(errorMessage) {
|
|
825
|
-
return AUTH_ERROR_PATTERNS.some((p) => errorMessage.includes(p));
|
|
826
|
-
}
|
|
827
|
-
__name(isAuthError, "isAuthError");
|
|
828
|
-
|
|
829
908
|
// src/closest-match.ts
|
|
830
909
|
function levenshteinDistance(source, target) {
|
|
831
910
|
const sourceLength = source.length;
|
|
@@ -7210,12 +7289,48 @@ var types = {
|
|
|
7210
7289
|
description: "@alpha",
|
|
7211
7290
|
optional: false
|
|
7212
7291
|
},
|
|
7292
|
+
{
|
|
7293
|
+
name: "readComponentControlsForAgent",
|
|
7294
|
+
type: "(input: {\n componentIds: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
|
|
7295
|
+
description: "@alpha",
|
|
7296
|
+
optional: false
|
|
7297
|
+
},
|
|
7298
|
+
{
|
|
7299
|
+
name: "readIconSetControlsForAgent",
|
|
7300
|
+
type: "(input: {\n iconSetNames: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
|
|
7301
|
+
description: "@alpha",
|
|
7302
|
+
optional: false
|
|
7303
|
+
},
|
|
7304
|
+
{
|
|
7305
|
+
name: "readIconsForAgent",
|
|
7306
|
+
type: "(input: {\n iconSetName: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<string[]>",
|
|
7307
|
+
description: "@alpha",
|
|
7308
|
+
optional: false
|
|
7309
|
+
},
|
|
7310
|
+
{
|
|
7311
|
+
name: "readLayoutTemplateControlsForAgent",
|
|
7312
|
+
type: "(input: {\n layoutTemplateIds: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
|
|
7313
|
+
description: "@alpha",
|
|
7314
|
+
optional: false
|
|
7315
|
+
},
|
|
7316
|
+
{
|
|
7317
|
+
name: "readShaderControlsForAgent",
|
|
7318
|
+
type: "(input: {\n shaderNames: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
|
|
7319
|
+
description: "@alpha",
|
|
7320
|
+
optional: false
|
|
7321
|
+
},
|
|
7213
7322
|
{
|
|
7214
7323
|
name: "applyAgentChanges",
|
|
7215
7324
|
type: "(dsl: string, options?: {\n pagePath?: string;\n }) => Promise<void>",
|
|
7216
7325
|
description: "@alpha",
|
|
7217
7326
|
optional: false
|
|
7218
7327
|
},
|
|
7328
|
+
{
|
|
7329
|
+
name: "ping",
|
|
7330
|
+
type: "() => Promise<void>",
|
|
7331
|
+
description: "@alpha Liveness round-trip; resolves when Vekter's plugin handler answers.",
|
|
7332
|
+
optional: false
|
|
7333
|
+
},
|
|
7219
7334
|
{
|
|
7220
7335
|
name: "publishForAgent",
|
|
7221
7336
|
type: "(input?: Record<string, unknown>) => Promise<unknown>",
|
|
@@ -7825,6 +7940,18 @@ var types = {
|
|
|
7825
7940
|
type: "string",
|
|
7826
7941
|
description: "JSONL string with one training row per inner-agent step, present when `captureTrainingData` was set.",
|
|
7827
7942
|
optional: true
|
|
7943
|
+
},
|
|
7944
|
+
{
|
|
7945
|
+
name: "fixtureFilename",
|
|
7946
|
+
type: "string",
|
|
7947
|
+
description: "Document fixture filename, always present after a completed run.",
|
|
7948
|
+
optional: false
|
|
7949
|
+
},
|
|
7950
|
+
{
|
|
7951
|
+
name: "fixtureContent",
|
|
7952
|
+
type: "string",
|
|
7953
|
+
description: "Document fixture JSON content (tree + code files).",
|
|
7954
|
+
optional: false
|
|
7828
7955
|
}
|
|
7829
7956
|
]
|
|
7830
7957
|
},
|
|
@@ -10909,6 +11036,10 @@ var classes = {
|
|
|
10909
11036
|
name: "framer",
|
|
10910
11037
|
description: ""
|
|
10911
11038
|
},
|
|
11039
|
+
frameragentapi: {
|
|
11040
|
+
name: "FramerAgentAPI",
|
|
11041
|
+
description: 'Agent-specific methods exposed by framer-api as its agent namespace.\n\nEach method delegates to the corresponding wire-protocol name on the engine\n(e.g. `agent.publish(...)` invokes `"publishForAgent"`).'
|
|
11042
|
+
},
|
|
10912
11043
|
framerapierror: {
|
|
10913
11044
|
name: "FramerAPIError",
|
|
10914
11045
|
description: ""
|
|
@@ -13134,136 +13265,10 @@ var methodsByCategory = {
|
|
|
13134
13265
|
],
|
|
13135
13266
|
framer: [
|
|
13136
13267
|
{
|
|
13137
|
-
name: "[$framerApiOnly.
|
|
13268
|
+
name: "[$framerApiOnly.ping]",
|
|
13138
13269
|
category: "framer",
|
|
13139
|
-
signature: "[$framerApiOnly.
|
|
13140
|
-
description:
|
|
13141
|
-
references: []
|
|
13142
|
-
},
|
|
13143
|
-
{
|
|
13144
|
-
name: "[$framerApiOnly.flattenComponentInstanceForAgent]",
|
|
13145
|
-
category: "framer",
|
|
13146
|
-
signature: "[$framerApiOnly.flattenComponentInstanceForAgent](input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13147
|
-
description: 'Flattens a local component instance into raw editable layers.\n\n@param input - `{ id }`: the id of the component instance to flatten.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The flatten result \u2014 `success` with a `replacementId`, or `blocked` with a reason.',
|
|
13148
|
-
references: []
|
|
13149
|
-
},
|
|
13150
|
-
{
|
|
13151
|
-
name: "[$framerApiOnly.getAgentContext]",
|
|
13152
|
-
category: "framer",
|
|
13153
|
-
signature: "[$framerApiOnly.getAgentContext](options?: { pagePath?: string; }): Promise<string>",
|
|
13154
|
-
description: 'Returns the dynamic project context as a string.\n\nThe context includes project-specific data:\n- **Available fonts** \u2014 font families loaded in the project.\n- **Components** \u2014 component names and their controls.\n- **Design tokens** \u2014 color tokens defined in the project.\n- **Style presets** \u2014 text style presets defined in the project.\n- **Icon sets** \u2014 available icon sets and their definitions.\n\nThis data changes per project and page. Pair with the static prompt\nfrom {@link getAgentSystemPrompt} for complete agent context.\n\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns A string containing the project context.',
|
|
13155
|
-
references: []
|
|
13156
|
-
},
|
|
13157
|
-
{
|
|
13158
|
-
name: "[$framerApiOnly.getAgentSystemPrompt]",
|
|
13159
|
-
category: "framer",
|
|
13160
|
-
signature: "[$framerApiOnly.getAgentSystemPrompt](): Promise<string>",
|
|
13161
|
-
description: "Returns the static agent system prompt as a string.\n\nThe prompt includes:\n- **Command reference** \u2014 syntax for adding, updating, removing, moving, and duplicating nodes.\n- **Design rules** \u2014 spacing, layout, typography, and responsive design guidance.\n- **Examples** \u2014 common UI patterns expressed as commands.\n- **`readProjectForAgent` query reference** \u2014 available query types and their parameters.\n\nThis is the sole documentation for the command syntax used by {@link applyAgentChanges}\nand the query types used by {@link readProjectForAgent}.\n\nThe prompt is static and does not depend on any specific project.\nCall {@link getAgentContext} to get the project-specific context.\n\n@returns A string containing the agent system prompt.",
|
|
13162
|
-
references: []
|
|
13163
|
-
},
|
|
13164
|
-
{
|
|
13165
|
-
name: "[$framerApiOnly.getAncestorsForAgent]",
|
|
13166
|
-
category: "framer",
|
|
13167
|
-
signature: "[$framerApiOnly.getAncestorsForAgent](input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13168
|
-
description: 'Get every ancestor of a node, from the direct parent up to the page root.\n\n@param input - `{ id }`: the id of the node to start from.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The ancestors ordered from closest parent to the page root.',
|
|
13169
|
-
references: []
|
|
13170
|
-
},
|
|
13171
|
-
{
|
|
13172
|
-
name: "[$framerApiOnly.getGroundNodeForAgent]",
|
|
13173
|
-
category: "framer",
|
|
13174
|
-
signature: "[$framerApiOnly.getGroundNodeForAgent](input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13175
|
-
description: 'Get the top-level node on the canvas that contains the given node.\n\n@param input - `{ id }`: the id of a descendant node.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The top-level node, or `null` if none applies.',
|
|
13176
|
-
references: []
|
|
13177
|
-
},
|
|
13178
|
-
{
|
|
13179
|
-
name: "[$framerApiOnly.getNodeForAgent]",
|
|
13180
|
-
category: "framer",
|
|
13181
|
-
signature: "[$framerApiOnly.getNodeForAgent](input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13182
|
-
description: 'Get a single node on the page, including its children.\n\n@param input - `{ id }`: the id of the node to read.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The node, or `null` if no node with that id exists on the page.',
|
|
13183
|
-
references: []
|
|
13184
|
-
},
|
|
13185
|
-
{
|
|
13186
|
-
name: "[$framerApiOnly.getNodesForAgent]",
|
|
13187
|
-
category: "framer",
|
|
13188
|
-
signature: "[$framerApiOnly.getNodesForAgent](input: { ids: readonly string[]; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13189
|
-
description: 'Get multiple nodes on the page, including their children.\nIds that don\'t resolve to a node are skipped.\n\n@param input - `{ ids }`: the ids of the nodes to read.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The nodes that were found, in input order.',
|
|
13190
|
-
references: []
|
|
13191
|
-
},
|
|
13192
|
-
{
|
|
13193
|
-
name: "[$framerApiOnly.getNodesOfTypesForAgent]",
|
|
13194
|
-
category: "framer",
|
|
13195
|
-
signature: "[$framerApiOnly.getNodesOfTypesForAgent](input: { types: readonly string[]; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13196
|
-
description: 'Get every node on the page of one or more kinds (e.g. `"FrameNode"`, `"RichTextNode"`, `"ComponentInstanceNode"`).\n\n@param input - `{ types }`: the node kinds to match.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The matching nodes without their children.',
|
|
13197
|
-
references: []
|
|
13198
|
-
},
|
|
13199
|
-
{
|
|
13200
|
-
name: "[$framerApiOnly.getParentNodeForAgent]",
|
|
13201
|
-
category: "framer",
|
|
13202
|
-
signature: "[$framerApiOnly.getParentNodeForAgent](input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13203
|
-
description: 'Get the direct parent of a node.\n\n@param input - `{ id }`: the id of the child node.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The parent node, or `null` if the node has no parent or doesn\'t exist.',
|
|
13204
|
-
references: []
|
|
13205
|
-
},
|
|
13206
|
-
{
|
|
13207
|
-
name: "[$framerApiOnly.getScopeNodeForAgent]",
|
|
13208
|
-
category: "framer",
|
|
13209
|
-
signature: "[$framerApiOnly.getScopeNodeForAgent](input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13210
|
-
description: 'Get the scope node (page or component) that contains the given node.\n\n@param input - `{ id }`: the id of a node inside the scope.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The enclosing scope node, or `null` if the node isn\'t in any scope.',
|
|
13211
|
-
references: []
|
|
13212
|
-
},
|
|
13213
|
-
{
|
|
13214
|
-
name: "[$framerApiOnly.makeExternalComponentLocalForAgent]",
|
|
13215
|
-
category: "framer",
|
|
13216
|
-
signature: "[$framerApiOnly.makeExternalComponentLocalForAgent](input: { id: string; replaceAll?: boolean; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13217
|
-
description: 'Converts an external component into a local project component.\n\n@param input - `{ id, replaceAll? }`: the id of the external instance, and whether to replace all instances.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns `success` (with the local component name), `needs_confirmation` (retry with `replaceAll`), or `blocked` with a reason.',
|
|
13218
|
-
references: []
|
|
13219
|
-
},
|
|
13220
|
-
{
|
|
13221
|
-
name: "[$framerApiOnly.paginateForAgent]",
|
|
13222
|
-
category: "framer",
|
|
13223
|
-
signature: "[$framerApiOnly.paginateForAgent](input: { items: readonly unknown[]; keyName?: never; cursor?: never; } | { keyName: string; cursor: number; items?: never; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13224
|
-
description: 'Paginate a large array of values across multiple calls. The cursor is\nopaque and only valid within the same headless session and page.\n\n- First page: pass `{ items }`.\n- Continuation: pass `{ keyName, cursor }` using values returned by a previous call.\n\n@param input - `{ items }` for a fresh array, or `{ keyName, cursor }` for continuation.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The current page, including `keyName`, `cursor`, `results`, `totalResults`, and (if more pages remain) `nextCursor`.',
|
|
13225
|
-
references: []
|
|
13226
|
-
},
|
|
13227
|
-
{
|
|
13228
|
-
name: "[$framerApiOnly.publishForAgent]",
|
|
13229
|
-
category: "framer",
|
|
13230
|
-
signature: "[$framerApiOnly.publishForAgent](input?: Record<string, unknown>): Promise<unknown>",
|
|
13231
|
-
description: "Executes the publish flow on behalf of an agent.\n\nThe input schema is documented in the string returned by {@link getAgentSystemPrompt}.\n\n@param input - Action-discriminated input object (preview / confirm_publish / deploy_to_production).\n@returns The action's result \u2014 status, publish URLs, and any errors, warnings, or changes.",
|
|
13232
|
-
references: []
|
|
13233
|
-
},
|
|
13234
|
-
{
|
|
13235
|
-
name: "[$framerApiOnly.queryImagesForAgent]",
|
|
13236
|
-
category: "framer",
|
|
13237
|
-
signature: "[$framerApiOnly.queryImagesForAgent](input: Record<string, unknown>): Promise<unknown>",
|
|
13238
|
-
description: 'Searches for stock images to use on the canvas (e.g. `"FrameNode"` `fill` values). Returns\ncandidate images with preview thumbnails and a `url` field for each. The returned URLs are\nregistered as trusted for this session so they can be applied directly via `fill="<url>"`\nin a subsequent {@link applyAgentChanges} DSL command. Without calling this method first,\nexternal image URLs are rejected at apply time.\n\nThe input schema is documented in the string returned by {@link getAgentSystemPrompt}.\n\n@param input - Search input object (source / query / count / orientation).\n@returns An object describing the candidates or an error.',
|
|
13239
|
-
references: []
|
|
13240
|
-
},
|
|
13241
|
-
{
|
|
13242
|
-
name: "[$framerApiOnly.readProjectForAgent]",
|
|
13243
|
-
category: "framer",
|
|
13244
|
-
signature: "[$framerApiOnly.readProjectForAgent](queries: Record<string, unknown>[], options?: { pagePath?: string; }): Promise<{ results: unknown[]; }>",
|
|
13245
|
-
description: 'Reads project state by executing an array of queries against the project.\n\nReturns one result per query. Available query types and their parameters\nare documented in the string returned by {@link getAgentSystemPrompt}.\n\n@param queries - Array of query objects. See {@link getAgentSystemPrompt} for available types.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns An object with a `results` array, one entry per query.',
|
|
13246
|
-
references: []
|
|
13247
|
-
},
|
|
13248
|
-
{
|
|
13249
|
-
name: "[$framerApiOnly.reviewChangesForAgent]",
|
|
13250
|
-
category: "framer",
|
|
13251
|
-
signature: "[$framerApiOnly.reviewChangesForAgent](options?: { pagePath?: string; }): Promise<unknown>",
|
|
13252
|
-
description: "Reviews changes made by prior {@link applyAgentChanges} calls in this session.\n\nConsumes accumulated diagnostics from the session's agent context.\n\n@param options.pagePath - Target page path (e.g. `\"/about\"`). Defaults to the active page.\n@returns The session's accumulated changes, errors, warnings, and deferred trait reports.",
|
|
13253
|
-
references: []
|
|
13254
|
-
},
|
|
13255
|
-
{
|
|
13256
|
-
name: "[$framerApiOnly.serializeForAgent]",
|
|
13257
|
-
category: "framer",
|
|
13258
|
-
signature: "[$framerApiOnly.serializeForAgent](input: { id: string; depth?: number; attributeFilter?: readonly string[]; ancestorPath?: boolean; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13259
|
-
description: 'Serialize a single node on the page.\n\n@param input - `{ id }` plus optional serialization options:\n - `depth` \u2014 limit how many descendant levels to include.\n - `attributeFilter` \u2014 only return the listed attributes per node.\n - `ancestorPath` \u2014 also return the path of ancestors up to the page root.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The serialized node, or `null` if no node with that id exists on the page.',
|
|
13260
|
-
references: []
|
|
13261
|
-
},
|
|
13262
|
-
{
|
|
13263
|
-
name: "[$framerApiOnly.serializeNodesForAgent]",
|
|
13264
|
-
category: "framer",
|
|
13265
|
-
signature: "[$framerApiOnly.serializeNodesForAgent](input: { ids: readonly string[]; depth?: number; attributeFilter?: readonly string[]; ancestorPath?: boolean; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13266
|
-
description: 'Serialize multiple nodes on the page. Ids that don\'t resolve to a node are skipped.\n\n@param input - `{ ids }` plus optional serialization options:\n - `depth` \u2014 limit how many descendant levels to include.\n - `attributeFilter` \u2014 only return the listed attributes per node.\n - `ancestorPath` \u2014 also return the path of ancestors up to the page root.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The serialized nodes that were found, in input order.',
|
|
13270
|
+
signature: "[$framerApiOnly.ping](): Promise<void>",
|
|
13271
|
+
description: "Liveness round-trip: resolves once Vekter's plugin handler answers. Used by the headless backend to verify the transport actually routes, not just that the page is alive.",
|
|
13267
13272
|
references: []
|
|
13268
13273
|
},
|
|
13269
13274
|
{
|
|
@@ -13347,11 +13352,11 @@ var methodsByCategory = {
|
|
|
13347
13352
|
references: ["AddTextOptions"]
|
|
13348
13353
|
},
|
|
13349
13354
|
{
|
|
13350
|
-
name: "
|
|
13355
|
+
name: "agent",
|
|
13351
13356
|
category: "framer",
|
|
13352
|
-
signature: "
|
|
13353
|
-
description: '
|
|
13354
|
-
references: []
|
|
13357
|
+
signature: "agent: FramerAgentAPI",
|
|
13358
|
+
description: 'Agent-specific methods exposed by framer-api as its agent namespace.\n\nEach method delegates to the corresponding wire-protocol name on the engine\n(e.g. `agent.publish(...)` invokes `"publishForAgent"`).',
|
|
13359
|
+
references: ["FramerAgentAPI"]
|
|
13355
13360
|
},
|
|
13356
13361
|
{
|
|
13357
13362
|
name: "cloneNode",
|
|
@@ -13360,16 +13365,6 @@ var methodsByCategory = {
|
|
|
13360
13365
|
description: "Clone a node.\n@category canvas",
|
|
13361
13366
|
references: ["AnyNode"]
|
|
13362
13367
|
},
|
|
13363
|
-
{
|
|
13364
|
-
name: "continueAgentConversation",
|
|
13365
|
-
category: "framer",
|
|
13366
|
-
signature: "continueAgentConversation(prompt: string, options: ContinueAgentConversationOptions): Promise<ContinueAgentConversationResult>",
|
|
13367
|
-
description: "",
|
|
13368
|
-
references: [
|
|
13369
|
-
"ContinueAgentConversationOptions",
|
|
13370
|
-
"ContinueAgentConversationResult"
|
|
13371
|
-
]
|
|
13372
|
-
},
|
|
13373
13368
|
{
|
|
13374
13369
|
name: "createCodeFile",
|
|
13375
13370
|
category: "framer",
|
|
@@ -13468,34 +13463,6 @@ var methodsByCategory = {
|
|
|
13468
13463
|
description: "",
|
|
13469
13464
|
references: []
|
|
13470
13465
|
},
|
|
13471
|
-
{
|
|
13472
|
-
name: "flattenComponentInstanceForAgent",
|
|
13473
|
-
category: "framer",
|
|
13474
|
-
signature: "flattenComponentInstanceForAgent(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13475
|
-
description: 'Flattens a local component instance into raw editable layers.\n\n@param input - `{ id }`: the id of the component instance to flatten.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The flatten result \u2014 `success` with a `replacementId`, or `blocked` with a reason.',
|
|
13476
|
-
references: []
|
|
13477
|
-
},
|
|
13478
|
-
{
|
|
13479
|
-
name: "getAgentContext",
|
|
13480
|
-
category: "framer",
|
|
13481
|
-
signature: "getAgentContext(options?: { pagePath?: string; }): Promise<string>",
|
|
13482
|
-
description: 'Returns the dynamic project context as a string.\n\nThe context includes project-specific data:\n- **Available fonts** \u2014 font families loaded in the project.\n- **Components** \u2014 component names and their controls.\n- **Design tokens** \u2014 color tokens defined in the project.\n- **Style presets** \u2014 text style presets defined in the project.\n- **Icon sets** \u2014 available icon sets and their definitions.\n\nThis data changes per project and page. Pair with the static prompt\nfrom {@link getAgentSystemPrompt} for complete agent context.\n\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns A string containing the project context.',
|
|
13483
|
-
references: []
|
|
13484
|
-
},
|
|
13485
|
-
{
|
|
13486
|
-
name: "getAgentSystemPrompt",
|
|
13487
|
-
category: "framer",
|
|
13488
|
-
signature: "getAgentSystemPrompt(): Promise<string>",
|
|
13489
|
-
description: "Returns the static agent system prompt as a string.\n\nThe prompt includes:\n- **Command reference** \u2014 syntax for adding, updating, removing, moving, and duplicating nodes.\n- **Design rules** \u2014 spacing, layout, typography, and responsive design guidance.\n- **Examples** \u2014 common UI patterns expressed as commands.\n- **`readProjectForAgent` query reference** \u2014 available query types and their parameters.\n\nThis is the sole documentation for the command syntax used by {@link applyAgentChanges}\nand the query types used by {@link readProjectForAgent}.\n\nThe prompt is static and does not depend on any specific project.\nCall {@link getAgentContext} to get the project-specific context.\n\n@returns A string containing the agent system prompt.",
|
|
13490
|
-
references: []
|
|
13491
|
-
},
|
|
13492
|
-
{
|
|
13493
|
-
name: "getAncestorsForAgent",
|
|
13494
|
-
category: "framer",
|
|
13495
|
-
signature: "getAncestorsForAgent(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13496
|
-
description: 'Get every ancestor of a node, from the direct parent up to the page root.\n\n@param input - `{ id }`: the id of the node to start from.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The ancestors ordered from closest parent to the page root.',
|
|
13497
|
-
references: []
|
|
13498
|
-
},
|
|
13499
13466
|
{
|
|
13500
13467
|
name: "getCanvasRoot",
|
|
13501
13468
|
category: "framer",
|
|
@@ -13608,13 +13575,6 @@ var methodsByCategory = {
|
|
|
13608
13575
|
description: "Get all available fonts.\n\nUnlike the Font Picker which groups fonts by typeface, this lists\nindividual fonts for each weight and style (each representing a separate\nfont file).\n\nNote: Custom fonts are not available to plugins.\n\n@returns An array of all available fonts.\n\n@example\n```ts\nconst fonts = await framer.getFonts()\n```\n@category canvas",
|
|
13609
13576
|
references: ["Font"]
|
|
13610
13577
|
},
|
|
13611
|
-
{
|
|
13612
|
-
name: "getGroundNodeForAgent",
|
|
13613
|
-
category: "framer",
|
|
13614
|
-
signature: "getGroundNodeForAgent(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13615
|
-
description: 'Get the top-level node on the canvas that contains the given node.\n\n@param input - `{ id }`: the id of a descendant node.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The top-level node, or `null` if none applies.',
|
|
13616
|
-
references: []
|
|
13617
|
-
},
|
|
13618
13578
|
{
|
|
13619
13579
|
name: "getImage",
|
|
13620
13580
|
category: "framer",
|
|
@@ -13664,27 +13624,6 @@ var methodsByCategory = {
|
|
|
13664
13624
|
description: "Get a node by its id.\n@category canvas",
|
|
13665
13625
|
references: ["AnyNode"]
|
|
13666
13626
|
},
|
|
13667
|
-
{
|
|
13668
|
-
name: "getNodeForAgent",
|
|
13669
|
-
category: "framer",
|
|
13670
|
-
signature: "getNodeForAgent(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13671
|
-
description: 'Get a single node on the page, including its children.\n\n@param input - `{ id }`: the id of the node to read.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The node, or `null` if no node with that id exists on the page.',
|
|
13672
|
-
references: []
|
|
13673
|
-
},
|
|
13674
|
-
{
|
|
13675
|
-
name: "getNodesForAgent",
|
|
13676
|
-
category: "framer",
|
|
13677
|
-
signature: "getNodesForAgent(input: { ids: readonly string[]; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13678
|
-
description: 'Get multiple nodes on the page, including their children.\nIds that don\'t resolve to a node are skipped.\n\n@param input - `{ ids }`: the ids of the nodes to read.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The nodes that were found, in input order.',
|
|
13679
|
-
references: []
|
|
13680
|
-
},
|
|
13681
|
-
{
|
|
13682
|
-
name: "getNodesOfTypesForAgent",
|
|
13683
|
-
category: "framer",
|
|
13684
|
-
signature: "getNodesOfTypesForAgent(input: { types: readonly string[]; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13685
|
-
description: 'Get every node on the page of one or more kinds (e.g. `"FrameNode"`, `"RichTextNode"`, `"ComponentInstanceNode"`).\n\n@param input - `{ types }`: the node kinds to match.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The matching nodes without their children.',
|
|
13686
|
-
references: []
|
|
13687
|
-
},
|
|
13688
13627
|
{
|
|
13689
13628
|
name: "getNodesWithAttribute",
|
|
13690
13629
|
category: "framer",
|
|
@@ -13713,13 +13652,6 @@ var methodsByCategory = {
|
|
|
13713
13652
|
description: "Get the parent of a node.\n@category canvas",
|
|
13714
13653
|
references: ["AnyNode"]
|
|
13715
13654
|
},
|
|
13716
|
-
{
|
|
13717
|
-
name: "getParentNodeForAgent",
|
|
13718
|
-
category: "framer",
|
|
13719
|
-
signature: "getParentNodeForAgent(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13720
|
-
description: 'Get the direct parent of a node.\n\n@param input - `{ id }`: the id of the child node.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The parent node, or `null` if the node has no parent or doesn\'t exist.',
|
|
13721
|
-
references: []
|
|
13722
|
-
},
|
|
13723
13655
|
{
|
|
13724
13656
|
name: "getProjectInfo",
|
|
13725
13657
|
category: "framer",
|
|
@@ -13748,13 +13680,6 @@ var methodsByCategory = {
|
|
|
13748
13680
|
description: "Get all Redirects in the project.\n\n@returns All of the Redirects in the project.\n\n@example\n```ts\nconst redirects = await framer.getRedirects()\n```\n@category settings",
|
|
13749
13681
|
references: ["Redirect"]
|
|
13750
13682
|
},
|
|
13751
|
-
{
|
|
13752
|
-
name: "getScopeNodeForAgent",
|
|
13753
|
-
category: "framer",
|
|
13754
|
-
signature: "getScopeNodeForAgent(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13755
|
-
description: 'Get the scope node (page or component) that contains the given node.\n\n@param input - `{ id }`: the id of a node inside the scope.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The enclosing scope node, or `null` if the node isn\'t in any scope.',
|
|
13756
|
-
references: []
|
|
13757
|
-
},
|
|
13758
13683
|
{
|
|
13759
13684
|
name: "getText",
|
|
13760
13685
|
category: "framer",
|
|
@@ -13783,13 +13708,6 @@ var methodsByCategory = {
|
|
|
13783
13708
|
description: "Get all available vector sets.\n\n@alpha",
|
|
13784
13709
|
references: ["VectorSet"]
|
|
13785
13710
|
},
|
|
13786
|
-
{
|
|
13787
|
-
name: "makeExternalComponentLocalForAgent",
|
|
13788
|
-
category: "framer",
|
|
13789
|
-
signature: "makeExternalComponentLocalForAgent(input: { id: string; replaceAll?: boolean; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13790
|
-
description: 'Converts an external component into a local project component.\n\n@param input - `{ id, replaceAll? }`: the id of the external instance, and whether to replace all instances.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns `success` (with the local component name), `needs_confirmation` (retry with `replaceAll`), or `blocked` with a reason.',
|
|
13791
|
-
references: []
|
|
13792
|
-
},
|
|
13793
13711
|
{
|
|
13794
13712
|
name: "mode",
|
|
13795
13713
|
category: "framer",
|
|
@@ -13798,10 +13716,10 @@ var methodsByCategory = {
|
|
|
13798
13716
|
references: ["Mode"]
|
|
13799
13717
|
},
|
|
13800
13718
|
{
|
|
13801
|
-
name: "
|
|
13719
|
+
name: "ping",
|
|
13802
13720
|
category: "framer",
|
|
13803
|
-
signature: "
|
|
13804
|
-
description:
|
|
13721
|
+
signature: "ping(): Promise<void>",
|
|
13722
|
+
description: "Liveness round-trip: resolves once Vekter's plugin handler answers. Used by the headless backend to verify the transport actually routes, not just that the page is alive.",
|
|
13805
13723
|
references: []
|
|
13806
13724
|
},
|
|
13807
13725
|
{
|
|
@@ -13811,27 +13729,6 @@ var methodsByCategory = {
|
|
|
13811
13729
|
description: "",
|
|
13812
13730
|
references: ["PublishResult"]
|
|
13813
13731
|
},
|
|
13814
|
-
{
|
|
13815
|
-
name: "publishForAgent",
|
|
13816
|
-
category: "framer",
|
|
13817
|
-
signature: "publishForAgent(input?: Record<string, unknown>): Promise<unknown>",
|
|
13818
|
-
description: "Executes the publish flow on behalf of an agent.\n\nThe input schema is documented in the string returned by {@link getAgentSystemPrompt}.\n\n@param input - Action-discriminated input object (preview / confirm_publish / deploy_to_production).\n@returns The action's result \u2014 status, publish URLs, and any errors, warnings, or changes.",
|
|
13819
|
-
references: []
|
|
13820
|
-
},
|
|
13821
|
-
{
|
|
13822
|
-
name: "queryImagesForAgent",
|
|
13823
|
-
category: "framer",
|
|
13824
|
-
signature: "queryImagesForAgent(input: Record<string, unknown>): Promise<unknown>",
|
|
13825
|
-
description: 'Searches for stock images to use on the canvas (e.g. `"FrameNode"` `fill` values). Returns\ncandidate images with preview thumbnails and a `url` field for each. The returned URLs are\nregistered as trusted for this session so they can be applied directly via `fill="<url>"`\nin a subsequent {@link applyAgentChanges} DSL command. Without calling this method first,\nexternal image URLs are rejected at apply time.\n\nThe input schema is documented in the string returned by {@link getAgentSystemPrompt}.\n\n@param input - Search input object (source / query / count / orientation).\n@returns An object describing the candidates or an error.',
|
|
13826
|
-
references: []
|
|
13827
|
-
},
|
|
13828
|
-
{
|
|
13829
|
-
name: "readProjectForAgent",
|
|
13830
|
-
category: "framer",
|
|
13831
|
-
signature: "readProjectForAgent(queries: Record<string, unknown>[], options?: { pagePath?: string; }): Promise<{ results: unknown[]; }>",
|
|
13832
|
-
description: 'Reads project state by executing an array of queries against the project.\n\nReturns one result per query. Available query types and their parameters\nare documented in the string returned by {@link getAgentSystemPrompt}.\n\n@param queries - Array of query objects. See {@link getAgentSystemPrompt} for available types.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns An object with a `results` array, one entry per query.',
|
|
13833
|
-
references: []
|
|
13834
|
-
},
|
|
13835
13732
|
{
|
|
13836
13733
|
name: "rejectAllPending",
|
|
13837
13734
|
category: "framer",
|
|
@@ -13860,23 +13757,6 @@ var methodsByCategory = {
|
|
|
13860
13757
|
description: "",
|
|
13861
13758
|
references: []
|
|
13862
13759
|
},
|
|
13863
|
-
{
|
|
13864
|
-
name: "reviewChangesForAgent",
|
|
13865
|
-
category: "framer",
|
|
13866
|
-
signature: "reviewChangesForAgent(options?: { pagePath?: string; }): Promise<unknown>",
|
|
13867
|
-
description: "Reviews changes made by prior {@link applyAgentChanges} calls in this session.\n\nConsumes accumulated diagnostics from the session's agent context.\n\n@param options.pagePath - Target page path (e.g. `\"/about\"`). Defaults to the active page.\n@returns The session's accumulated changes, errors, warnings, and deferred trait reports.",
|
|
13868
|
-
references: []
|
|
13869
|
-
},
|
|
13870
|
-
{
|
|
13871
|
-
name: "runSupervisorAgentCommand",
|
|
13872
|
-
category: "framer",
|
|
13873
|
-
signature: "runSupervisorAgentCommand(options: RunSupervisorAgentCommandOptions): Promise<RunSupervisorAgentCommandResult>",
|
|
13874
|
-
description: "",
|
|
13875
|
-
references: [
|
|
13876
|
-
"RunSupervisorAgentCommandOptions",
|
|
13877
|
-
"RunSupervisorAgentCommandResult"
|
|
13878
|
-
]
|
|
13879
|
-
},
|
|
13880
13760
|
{
|
|
13881
13761
|
name: "screenshot",
|
|
13882
13762
|
category: "framer",
|
|
@@ -13884,20 +13764,6 @@ var methodsByCategory = {
|
|
|
13884
13764
|
description: "",
|
|
13885
13765
|
references: ["ScreenshotOptions", "ScreenshotResult"]
|
|
13886
13766
|
},
|
|
13887
|
-
{
|
|
13888
|
-
name: "serializeForAgent",
|
|
13889
|
-
category: "framer",
|
|
13890
|
-
signature: "serializeForAgent(input: { id: string; depth?: number; attributeFilter?: readonly string[]; ancestorPath?: boolean; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13891
|
-
description: 'Serialize a single node on the page.\n\n@param input - `{ id }` plus optional serialization options:\n - `depth` \u2014 limit how many descendant levels to include.\n - `attributeFilter` \u2014 only return the listed attributes per node.\n - `ancestorPath` \u2014 also return the path of ancestors up to the page root.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The serialized node, or `null` if no node with that id exists on the page.',
|
|
13892
|
-
references: []
|
|
13893
|
-
},
|
|
13894
|
-
{
|
|
13895
|
-
name: "serializeNodesForAgent",
|
|
13896
|
-
category: "framer",
|
|
13897
|
-
signature: "serializeNodesForAgent(input: { ids: readonly string[]; depth?: number; attributeFilter?: readonly string[]; ancestorPath?: boolean; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13898
|
-
description: 'Serialize multiple nodes on the page. Ids that don\'t resolve to a node are skipped.\n\n@param input - `{ ids }` plus optional serialization options:\n - `depth` \u2014 limit how many descendant levels to include.\n - `attributeFilter` \u2014 only return the listed attributes per node.\n - `ancestorPath` \u2014 also return the path of ancestors up to the page root.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The serialized nodes that were found, in input order.',
|
|
13899
|
-
references: []
|
|
13900
|
-
},
|
|
13901
13767
|
{
|
|
13902
13768
|
name: "sessionId",
|
|
13903
13769
|
category: "framer",
|
|
@@ -13968,26 +13834,6 @@ var methodsByCategory = {
|
|
|
13968
13834
|
description: "Set the text of the current selection or insert it onto the canvas.\n@category canvas",
|
|
13969
13835
|
references: []
|
|
13970
13836
|
},
|
|
13971
|
-
{
|
|
13972
|
-
name: "startAgentConversation",
|
|
13973
|
-
category: "framer",
|
|
13974
|
-
signature: "startAgentConversation(prompt: string, options?: StartAgentConversationOptions): Promise<StartAgentConversationResult>",
|
|
13975
|
-
description: "",
|
|
13976
|
-
references: [
|
|
13977
|
-
"StartAgentConversationOptions",
|
|
13978
|
-
"StartAgentConversationResult"
|
|
13979
|
-
]
|
|
13980
|
-
},
|
|
13981
|
-
{
|
|
13982
|
-
name: "submitAgentClarification",
|
|
13983
|
-
category: "framer",
|
|
13984
|
-
signature: "submitAgentClarification(options: SubmitAgentClarificationOptions): Promise<SubmitAgentClarificationResult>",
|
|
13985
|
-
description: "",
|
|
13986
|
-
references: [
|
|
13987
|
-
"SubmitAgentClarificationOptions",
|
|
13988
|
-
"SubmitAgentClarificationResult"
|
|
13989
|
-
]
|
|
13990
|
-
},
|
|
13991
13837
|
{
|
|
13992
13838
|
name: "typecheckCode",
|
|
13993
13839
|
category: "framer",
|
|
@@ -14024,6 +13870,192 @@ var methodsByCategory = {
|
|
|
14024
13870
|
references: ["NamedImageAssetInput", "ImageAsset"]
|
|
14025
13871
|
}
|
|
14026
13872
|
],
|
|
13873
|
+
frameragentapi: [
|
|
13874
|
+
{
|
|
13875
|
+
name: "applyChanges",
|
|
13876
|
+
category: "FramerAgentAPI",
|
|
13877
|
+
signature: "applyChanges(dsl: string, options?: { pagePath?: string; }): Promise<void>",
|
|
13878
|
+
description: 'Applies commands to the canvas to create, update, remove, move, or duplicate nodes.\n\nThe command syntax is documented in the string returned by {@link getSystemPrompt}.\nEach call is scoped to a single page.\n\n@param dsl - A string of commands separated by `;`. See {@link getSystemPrompt} for syntax.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.',
|
|
13879
|
+
references: []
|
|
13880
|
+
},
|
|
13881
|
+
{
|
|
13882
|
+
name: "flattenComponentInstance",
|
|
13883
|
+
category: "FramerAgentAPI",
|
|
13884
|
+
signature: "flattenComponentInstance(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13885
|
+
description: 'Flattens a local component instance into raw editable layers.\n\n@param input - `{ id }`: the id of the component instance to flatten.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The flatten result \u2014 `success` with a `replacementId`, or `blocked` with a reason.',
|
|
13886
|
+
references: []
|
|
13887
|
+
},
|
|
13888
|
+
{
|
|
13889
|
+
name: "getAncestors",
|
|
13890
|
+
category: "FramerAgentAPI",
|
|
13891
|
+
signature: "getAncestors(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13892
|
+
description: 'Get every ancestor of a node, from the direct parent up to the page root.\n\n@param input - `{ id }`: the id of the node to start from.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The ancestors ordered from closest parent to the page root.',
|
|
13893
|
+
references: []
|
|
13894
|
+
},
|
|
13895
|
+
{
|
|
13896
|
+
name: "getContext",
|
|
13897
|
+
category: "FramerAgentAPI",
|
|
13898
|
+
signature: "getContext(options?: { pagePath?: string; }): Promise<string>",
|
|
13899
|
+
description: 'Returns the dynamic project context as a string.\n\nThe context includes project-specific data:\n- **Available fonts** \u2014 font families loaded in the project.\n- **Components** \u2014 component names and their controls.\n- **Design tokens** \u2014 color tokens defined in the project.\n- **Style presets** \u2014 text style presets defined in the project.\n- **Icon sets** \u2014 available icon sets and their definitions.\n\nThis data changes per project and page. Pair with the static prompt\nfrom {@link getSystemPrompt} for complete agent context.\n\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns A string containing the project context.',
|
|
13900
|
+
references: []
|
|
13901
|
+
},
|
|
13902
|
+
{
|
|
13903
|
+
name: "getGroundNode",
|
|
13904
|
+
category: "FramerAgentAPI",
|
|
13905
|
+
signature: "getGroundNode(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13906
|
+
description: 'Get the top-level node on the canvas that contains the given node.\n\n@param input - `{ id }`: the id of a descendant node.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The top-level node, or `null` if none applies.',
|
|
13907
|
+
references: []
|
|
13908
|
+
},
|
|
13909
|
+
{
|
|
13910
|
+
name: "getNode",
|
|
13911
|
+
category: "FramerAgentAPI",
|
|
13912
|
+
signature: "getNode(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13913
|
+
description: 'Get a single node on the page, including its children.\n\n@param input - `{ id }`: the id of the node to read.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The node, or `null` if no node with that id exists on the page.',
|
|
13914
|
+
references: []
|
|
13915
|
+
},
|
|
13916
|
+
{
|
|
13917
|
+
name: "getNodes",
|
|
13918
|
+
category: "FramerAgentAPI",
|
|
13919
|
+
signature: "getNodes(input: { ids: readonly string[]; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13920
|
+
description: 'Get multiple nodes on the page, including their children.\nIds that don\'t resolve to a node are skipped.\n\n@param input - `{ ids }`: the ids of the nodes to read.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The nodes that were found, in input order.',
|
|
13921
|
+
references: []
|
|
13922
|
+
},
|
|
13923
|
+
{
|
|
13924
|
+
name: "getNodesOfTypes",
|
|
13925
|
+
category: "FramerAgentAPI",
|
|
13926
|
+
signature: "getNodesOfTypes(input: { types: readonly string[]; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13927
|
+
description: 'Get every node on the page of one or more kinds (e.g. `"FrameNode"`, `"RichTextNode"`, `"ComponentInstanceNode"`).\n\n@param input - `{ types }`: the node kinds to match.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The matching nodes without their children.',
|
|
13928
|
+
references: []
|
|
13929
|
+
},
|
|
13930
|
+
{
|
|
13931
|
+
name: "getParentNode",
|
|
13932
|
+
category: "FramerAgentAPI",
|
|
13933
|
+
signature: "getParentNode(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13934
|
+
description: 'Get the direct parent of a node.\n\n@param input - `{ id }`: the id of the child node.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The parent node, or `null` if the node has no parent or doesn\'t exist.',
|
|
13935
|
+
references: []
|
|
13936
|
+
},
|
|
13937
|
+
{
|
|
13938
|
+
name: "getScopeNode",
|
|
13939
|
+
category: "FramerAgentAPI",
|
|
13940
|
+
signature: "getScopeNode(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13941
|
+
description: 'Get the scope node (page or component) that contains the given node.\n\n@param input - `{ id }`: the id of a node inside the scope.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The enclosing scope node, or `null` if the node isn\'t in any scope.',
|
|
13942
|
+
references: []
|
|
13943
|
+
},
|
|
13944
|
+
{
|
|
13945
|
+
name: "getSystemPrompt",
|
|
13946
|
+
category: "FramerAgentAPI",
|
|
13947
|
+
signature: "getSystemPrompt(): Promise<string>",
|
|
13948
|
+
description: "Returns the static agent system prompt as a string.\n\nThe prompt includes:\n- **Command reference** \u2014 syntax for adding, updating, removing, moving, and duplicating nodes.\n- **Design rules** \u2014 spacing, layout, typography, and responsive design guidance.\n- **Examples** \u2014 common UI patterns expressed as commands.\n- **`readProject` query reference** \u2014 available query types and their parameters.\n\nThis is the sole documentation for the command syntax used by {@link applyChanges}\nand the query types used by {@link readProject}.\n\nThe prompt is static and does not depend on any specific project.\nCall {@link getContext} to get the project-specific context.\n\n@returns A string containing the agent system prompt.",
|
|
13949
|
+
references: []
|
|
13950
|
+
},
|
|
13951
|
+
{
|
|
13952
|
+
name: "makeExternalComponentLocal",
|
|
13953
|
+
category: "FramerAgentAPI",
|
|
13954
|
+
signature: "makeExternalComponentLocal(input: { id: string; replaceAll?: boolean; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13955
|
+
description: 'Converts an external component into a local project component.\n\n@param input - `{ id, replaceAll? }`: the id of the external instance, and whether to replace all instances.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns `success` (with the local component name), `needs_confirmation` (retry with `replaceAll`), or `blocked` with a reason.',
|
|
13956
|
+
references: []
|
|
13957
|
+
},
|
|
13958
|
+
{
|
|
13959
|
+
name: "paginate",
|
|
13960
|
+
category: "FramerAgentAPI",
|
|
13961
|
+
signature: "paginate(input: { items: readonly unknown[]; keyName?: never; cursor?: never; } | { keyName: string; cursor: number; items?: never; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13962
|
+
description: 'Paginate a large array of values across multiple calls. The cursor is\nopaque and only valid within the same headless session and page.\n\n- First page: pass `{ items }`.\n- Continuation: pass `{ keyName, cursor }` using values returned by a previous call.\n\n@param input - `{ items }` for a fresh array, or `{ keyName, cursor }` for continuation.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The current page, including `keyName`, `cursor`, `results`, `totalResults`, and (if more pages remain) `nextCursor`.',
|
|
13963
|
+
references: []
|
|
13964
|
+
},
|
|
13965
|
+
{
|
|
13966
|
+
name: "publish",
|
|
13967
|
+
category: "FramerAgentAPI",
|
|
13968
|
+
signature: "publish(input?: Record<string, unknown>): Promise<unknown>",
|
|
13969
|
+
description: "Executes the publish flow on behalf of an agent.\n\nThe input schema is documented in the string returned by {@link getSystemPrompt}.\n\n@param input - Action-discriminated input object (preview / confirm_publish / deploy_to_production).\n@returns The action's result \u2014 status, publish URLs, and any errors, warnings, or changes.",
|
|
13970
|
+
references: []
|
|
13971
|
+
},
|
|
13972
|
+
{
|
|
13973
|
+
name: "queryImages",
|
|
13974
|
+
category: "FramerAgentAPI",
|
|
13975
|
+
signature: "queryImages(input: Record<string, unknown>): Promise<unknown>",
|
|
13976
|
+
description: 'Searches for stock images to use on the canvas (e.g. `"FrameNode"` `fill` values). Returns\ncandidate images with preview thumbnails and a `url` field for each. The returned URLs are\nregistered as trusted for this session so they can be applied directly via `fill="<url>"`\nin a subsequent {@link applyChanges} DSL command. Without calling this method first,\nexternal image URLs are rejected at apply time.\n\nThe input schema is documented in the string returned by {@link getSystemPrompt}.\n\n@param input - Search input object (source / query / count / orientation).\n@returns An object describing the candidates or an error.',
|
|
13977
|
+
references: []
|
|
13978
|
+
},
|
|
13979
|
+
{
|
|
13980
|
+
name: "readComponentControls",
|
|
13981
|
+
category: "FramerAgentAPI",
|
|
13982
|
+
signature: "readComponentControls(input: { componentIds: readonly string[]; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13983
|
+
description: 'Reads control definitions for project components.\n\n@param input - `{ componentIds }`: component ids from project context or previous reads.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The matching component control definitions.',
|
|
13984
|
+
references: []
|
|
13985
|
+
},
|
|
13986
|
+
{
|
|
13987
|
+
name: "readIcons",
|
|
13988
|
+
category: "FramerAgentAPI",
|
|
13989
|
+
signature: "readIcons(input: { iconSetName: string; }, options?: { pagePath?: string; }): Promise<string[]>",
|
|
13990
|
+
description: 'Reads exact icon names for an icon set.\n\n@param input - `{ iconSetName }`: icon set name from project context or previous reads.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The available icon names in that set.',
|
|
13991
|
+
references: []
|
|
13992
|
+
},
|
|
13993
|
+
{
|
|
13994
|
+
name: "readIconSetControls",
|
|
13995
|
+
category: "FramerAgentAPI",
|
|
13996
|
+
signature: "readIconSetControls(input: { iconSetNames: readonly string[]; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
13997
|
+
description: 'Reads icon-set control definitions.\n\n@param input - `{ iconSetNames }`: icon set names from project context or previous reads.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The matching icon-set control definitions.',
|
|
13998
|
+
references: []
|
|
13999
|
+
},
|
|
14000
|
+
{
|
|
14001
|
+
name: "readLayoutTemplateControls",
|
|
14002
|
+
category: "FramerAgentAPI",
|
|
14003
|
+
signature: "readLayoutTemplateControls(input: { layoutTemplateIds: readonly string[]; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
14004
|
+
description: 'Reads layout-template control definitions.\n\n@param input - `{ layoutTemplateIds }`: layout template ids from project context or previous reads.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The matching layout-template control definitions.',
|
|
14005
|
+
references: []
|
|
14006
|
+
},
|
|
14007
|
+
{
|
|
14008
|
+
name: "readProject",
|
|
14009
|
+
category: "FramerAgentAPI",
|
|
14010
|
+
signature: "readProject(queries: Record<string, unknown>[], options?: { pagePath?: string; }): Promise<{ results: unknown[]; }>",
|
|
14011
|
+
description: 'Reads project state by executing an array of queries against the project.\n\nReturns one result per query. Available query types and their parameters\nare documented in the string returned by {@link getSystemPrompt}.\n\n@param queries - Array of query objects. See {@link getSystemPrompt} for available types.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns An object with a `results` array, one entry per query.',
|
|
14012
|
+
references: []
|
|
14013
|
+
},
|
|
14014
|
+
{
|
|
14015
|
+
name: "readShaderControls",
|
|
14016
|
+
category: "FramerAgentAPI",
|
|
14017
|
+
signature: "readShaderControls(input: { shaderNames: readonly string[]; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
14018
|
+
description: 'Reads shader control definitions.\n\n@param input - `{ shaderNames }`: shader names from project context or previous reads.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The matching shader control definitions.',
|
|
14019
|
+
references: []
|
|
14020
|
+
},
|
|
14021
|
+
{
|
|
14022
|
+
name: "reviewChanges",
|
|
14023
|
+
category: "FramerAgentAPI",
|
|
14024
|
+
signature: "reviewChanges(options?: { pagePath?: string; }): Promise<unknown>",
|
|
14025
|
+
description: "Reviews changes made by prior {@link applyChanges} calls in this session.\n\nConsumes accumulated diagnostics from the session's agent context.\n\n@param options.pagePath - Target page path (e.g. `\"/about\"`). Defaults to the active page.\n@returns The session's accumulated changes, errors, warnings, and deferred trait reports.",
|
|
14026
|
+
references: []
|
|
14027
|
+
},
|
|
14028
|
+
{
|
|
14029
|
+
name: "serialize",
|
|
14030
|
+
category: "FramerAgentAPI",
|
|
14031
|
+
signature: "serialize(input: { id: string; depth?: number; attributeFilter?: readonly string[]; ancestorPath?: boolean; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
14032
|
+
description: 'Serialize a single node on the page.\n\n@param input - `{ id }` plus optional serialization options:\n - `depth` \u2014 limit how many descendant levels to include.\n - `attributeFilter` \u2014 only return the listed attributes per node.\n - `ancestorPath` \u2014 also return the path of ancestors up to the page root.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The serialized node, or `null` if no node with that id exists on the page.',
|
|
14033
|
+
references: []
|
|
14034
|
+
},
|
|
14035
|
+
{
|
|
14036
|
+
name: "serializeNodes",
|
|
14037
|
+
category: "FramerAgentAPI",
|
|
14038
|
+
signature: "serializeNodes(input: { ids: readonly string[]; depth?: number; attributeFilter?: readonly string[]; ancestorPath?: boolean; }, options?: { pagePath?: string; }): Promise<unknown>",
|
|
14039
|
+
description: 'Serialize multiple nodes on the page. Ids that don\'t resolve to a node are skipped.\n\n@param input - `{ ids }` plus optional serialization options:\n - `depth` \u2014 limit how many descendant levels to include.\n - `attributeFilter` \u2014 only return the listed attributes per node.\n - `ancestorPath` \u2014 also return the path of ancestors up to the page root.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The serialized nodes that were found, in input order.',
|
|
14040
|
+
references: []
|
|
14041
|
+
}
|
|
14042
|
+
],
|
|
14043
|
+
framerapierror: [
|
|
14044
|
+
{
|
|
14045
|
+
name: "recentMethods",
|
|
14046
|
+
category: "FramerAPIError",
|
|
14047
|
+
signature: "recentMethods: string[]",
|
|
14048
|
+
description: "@see FramerAPIErrorOptions.recentMethods",
|
|
14049
|
+
references: []
|
|
14050
|
+
},
|
|
14051
|
+
{
|
|
14052
|
+
name: "retryable",
|
|
14053
|
+
category: "FramerAPIError",
|
|
14054
|
+
signature: "retryable: boolean",
|
|
14055
|
+
description: "@see FramerAPIErrorOptions.retryable",
|
|
14056
|
+
references: []
|
|
14057
|
+
}
|
|
14058
|
+
],
|
|
14027
14059
|
imageasset: [
|
|
14028
14060
|
{
|
|
14029
14061
|
name: "altText",
|
|
@@ -16602,7 +16634,7 @@ async function getAgentSystemPrompt(sessionId) {
|
|
|
16602
16634
|
debug("exec", "getAgentSystemPrompt: calling relay...");
|
|
16603
16635
|
const result = await client.exec.mutate({
|
|
16604
16636
|
sessionId,
|
|
16605
|
-
code: "return await framer.
|
|
16637
|
+
code: "return await framer.agent.getSystemPrompt();",
|
|
16606
16638
|
cwd: process.cwd()
|
|
16607
16639
|
});
|
|
16608
16640
|
debug("exec", "getAgentSystemPrompt: relay responded");
|
|
@@ -16618,7 +16650,7 @@ async function getAgentContext(sessionId) {
|
|
|
16618
16650
|
debug("exec", "getAgentContext: calling relay...");
|
|
16619
16651
|
const result = await client.exec.mutate({
|
|
16620
16652
|
sessionId,
|
|
16621
|
-
code: "return await framer.
|
|
16653
|
+
code: "return await framer.agent.getContext({ pagePath: '/' });",
|
|
16622
16654
|
cwd: process.cwd()
|
|
16623
16655
|
});
|
|
16624
16656
|
debug("exec", "getAgentContext: relay responded");
|
|
@@ -16729,7 +16761,7 @@ async function execAndPrint(sessionId, code) {
|
|
|
16729
16761
|
}
|
|
16730
16762
|
if (result.error) {
|
|
16731
16763
|
printError(
|
|
16732
|
-
`Error: ${formatErrorForUser(errorWithRef(result.error, result.errorRef))}`
|
|
16764
|
+
`Error: ${formatErrorForUser(errorWithRef(result.error, result.errorRef), { fromExecResult: true })}`
|
|
16733
16765
|
);
|
|
16734
16766
|
await waitForTrackingToFinish();
|
|
16735
16767
|
process.exit(1);
|
|
@@ -16772,7 +16804,7 @@ program.command("apply-changes").description("Apply canvas DSL changes to a page
|
|
|
16772
16804
|
).requiredOption("-e, --eval <dsl>", "DSL string to apply").option("-p, --page <path>", "Target page path", "/").action(async (options) => {
|
|
16773
16805
|
const { session: sessionId, eval: dsl, page: pagePath } = options;
|
|
16774
16806
|
const code = `
|
|
16775
|
-
const result = await framer.
|
|
16807
|
+
const result = await framer.agent.applyChanges(${JSON.stringify(dsl)}, { pagePath: ${JSON.stringify(pagePath)} });
|
|
16776
16808
|
if (result) console.log(JSON.stringify(result, null, 2));
|
|
16777
16809
|
`;
|
|
16778
16810
|
await execAndPrint(sessionId, code);
|
|
@@ -16795,7 +16827,7 @@ program.command("read-project").description("Read project state for a page").req
|
|
|
16795
16827
|
process.exit(1);
|
|
16796
16828
|
}
|
|
16797
16829
|
const code = `
|
|
16798
|
-
const result = await framer.
|
|
16830
|
+
const result = await framer.agent.readProject(${JSON.stringify(queries)}, { pagePath: ${JSON.stringify(pagePath)} });
|
|
16799
16831
|
if (result) console.log(JSON.stringify(result, null, 2));
|
|
16800
16832
|
`;
|
|
16801
16833
|
await execAndPrint(sessionId, code);
|
|
@@ -16807,6 +16839,7 @@ session.command("new <projectUrlOrId>").description("Create a new session and pr
|
|
|
16807
16839
|
).action(
|
|
16808
16840
|
async (projectUrlOrId, options) => {
|
|
16809
16841
|
const projectId = extractProjectId(projectUrlOrId);
|
|
16842
|
+
const agentThreadContext = resolveAgentThreadContext();
|
|
16810
16843
|
let sessionId;
|
|
16811
16844
|
let userId;
|
|
16812
16845
|
try {
|
|
@@ -16831,7 +16864,8 @@ session.command("new <projectUrlOrId>").description("Create a new session and pr
|
|
|
16831
16864
|
projectId,
|
|
16832
16865
|
apiKey: credentials.apiKey,
|
|
16833
16866
|
userId: credentials.userId,
|
|
16834
|
-
headlessServerUrl
|
|
16867
|
+
headlessServerUrl,
|
|
16868
|
+
...agentThreadContext
|
|
16835
16869
|
});
|
|
16836
16870
|
sessionId = result.id;
|
|
16837
16871
|
debug("session.new", `session created id=${sessionId}`);
|
|
@@ -16885,6 +16919,7 @@ session.command("new <projectUrlOrId>").description("Create a new session and pr
|
|
|
16885
16919
|
errorType: "session_new_error",
|
|
16886
16920
|
projectId,
|
|
16887
16921
|
userId,
|
|
16922
|
+
...agentThreadContext,
|
|
16888
16923
|
errorMessage: message
|
|
16889
16924
|
});
|
|
16890
16925
|
printError(`Failed to create session: ${formatErrorForUser(err)}`);
|