framer-dalton 0.0.18 → 0.0.21

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/cli.js CHANGED
@@ -1,18 +1,32 @@
1
1
  #!/usr/bin/env node
2
- import fs3 from 'fs';
3
- import path4 from 'path';
2
+ import fs6 from 'fs';
3
+ import path6 from 'path';
4
4
  import { Command } from 'commander';
5
- import crypto from 'crypto';
5
+ import crypto, { randomUUID } from 'crypto';
6
6
  import http from 'http';
7
7
  import { spawn, execFile } from 'child_process';
8
- import os from 'os';
9
8
  import { z } from 'zod';
9
+ import os from 'os';
10
10
  import { fileURLToPath } from 'url';
11
11
  import { createTRPCClient, httpLink } from '@trpc/client';
12
12
 
13
- /* @framer/ai CLI v0.0.18 */
13
+ /* @framer/ai CLI v0.0.21 */
14
14
  var __defProp = Object.defineProperty;
15
15
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
16
+
17
+ // package.json
18
+ var name = "framer-dalton";
19
+
20
+ // src/check-node-version.ts
21
+ var MINIMUM_NODE_VERSION = 22;
22
+ var currentMajor = Number(process.versions.node.split(".")[0]);
23
+ if (currentMajor < MINIMUM_NODE_VERSION) {
24
+ console.error(
25
+ `${name} requires Node.js >= ${MINIMUM_NODE_VERSION}. You are running Node.js ${process.versions.node}.
26
+ Please upgrade: https://nodejs.org/`
27
+ );
28
+ process.exit(1);
29
+ }
16
30
  function openUrl(url) {
17
31
  const platform = process.platform;
18
32
  let cmd;
@@ -36,20 +50,27 @@ function openUrl(url) {
36
50
  __name(openUrl, "openUrl");
37
51
  function getConfigDir() {
38
52
  if (process.env.XDG_CONFIG_HOME) {
39
- return path4.join(process.env.XDG_CONFIG_HOME, "framer");
53
+ return path6.join(process.env.XDG_CONFIG_HOME, "framer");
40
54
  }
41
55
  if (process.platform === "win32") {
42
- return path4.join(process.env.APPDATA || os.homedir(), "framer");
56
+ return path6.join(process.env.APPDATA || os.homedir(), "framer");
43
57
  }
44
- return path4.join(os.homedir(), ".config", "framer");
58
+ return path6.join(os.homedir(), ".config", "framer");
45
59
  }
46
60
  __name(getConfigDir, "getConfigDir");
61
+ function ensureConfigDir() {
62
+ const configDir = getConfigDir();
63
+ fs6.mkdirSync(configDir, { recursive: true, mode: 448 });
64
+ }
65
+ __name(ensureConfigDir, "ensureConfigDir");
66
+
67
+ // src/config/projects.ts
47
68
  function getProjectsConfigPath() {
48
- return path4.join(getConfigDir(), "projects.json");
69
+ return path6.join(getConfigDir(), "projects.json");
49
70
  }
50
71
  __name(getProjectsConfigPath, "getProjectsConfigPath");
51
72
  function getLegacyCredentialsPath() {
52
- return path4.join(getConfigDir(), "credentials.json");
73
+ return path6.join(getConfigDir(), "credentials.json");
53
74
  }
54
75
  __name(getLegacyCredentialsPath, "getLegacyCredentialsPath");
55
76
  var ProjectsConfigSchema = z.object({
@@ -58,6 +79,7 @@ var ProjectsConfigSchema = z.object({
58
79
  z.string(),
59
80
  z.object({
60
81
  apiKey: z.string(),
82
+ userId: z.string().optional(),
61
83
  name: z.string().optional(),
62
84
  lastUsedAt: z.string().optional()
63
85
  })
@@ -65,26 +87,16 @@ var ProjectsConfigSchema = z.object({
65
87
  });
66
88
  var LegacyCredentialsSchema = z.record(z.string(), z.string());
67
89
  function readJsonFile(filePath) {
68
- if (!fs3.existsSync(filePath)) {
69
- return null;
70
- }
71
90
  try {
72
- return JSON.parse(fs3.readFileSync(filePath, "utf-8"));
91
+ return JSON.parse(fs6.readFileSync(filePath, "utf-8"));
73
92
  } catch (_error) {
74
93
  return null;
75
94
  }
76
95
  }
77
96
  __name(readJsonFile, "readJsonFile");
78
- function ensureConfigDir() {
79
- const configDir = getConfigDir();
80
- if (!fs3.existsSync(configDir)) {
81
- fs3.mkdirSync(configDir, { recursive: true, mode: 448 });
82
- }
83
- }
84
- __name(ensureConfigDir, "ensureConfigDir");
85
97
  function writeProjectsConfig(config) {
86
98
  ensureConfigDir();
87
- fs3.writeFileSync(
99
+ fs6.writeFileSync(
88
100
  getProjectsConfigPath(),
89
101
  JSON.stringify(config, null, " "),
90
102
  {
@@ -111,7 +123,7 @@ function migrateLegacyCredentials() {
111
123
  }
112
124
  const config = { version: 2, projects };
113
125
  writeProjectsConfig(config);
114
- fs3.rmSync(getLegacyCredentialsPath(), { force: true });
126
+ fs6.rmSync(getLegacyCredentialsPath(), { force: true });
115
127
  return config;
116
128
  }
117
129
  __name(migrateLegacyCredentials, "migrateLegacyCredentials");
@@ -124,23 +136,24 @@ function readProjectsConfig() {
124
136
  return result.data;
125
137
  }
126
138
  }
127
- if (fs3.existsSync(getLegacyCredentialsPath())) {
139
+ if (fs6.existsSync(getLegacyCredentialsPath())) {
128
140
  return migrateLegacyCredentials();
129
141
  }
130
142
  return { version: 2, projects: {} };
131
143
  }
132
144
  __name(readProjectsConfig, "readProjectsConfig");
145
+ var REMIX_URL_PATTERN = /\/remix\/([a-zA-Z0-9]+)/;
133
146
  function extractProjectId(input) {
134
147
  if (/^[a-zA-Z0-9]+$/.test(input)) {
135
148
  return input;
136
149
  }
150
+ const remixMatch = input.match(REMIX_URL_PATTERN);
151
+ if (remixMatch) return remixMatch[1];
137
152
  const candidate = input.match(/\/projects\/([^/?#]+)/)?.[1] ?? input;
138
153
  const slugMatch = candidate.match(
139
154
  /^(?:.+--)?([a-zA-Z0-9]+)(?:-[a-zA-Z0-9]+)?$/
140
155
  );
141
- if (slugMatch) {
142
- return slugMatch[1];
143
- }
156
+ if (slugMatch) return slugMatch[1];
144
157
  return input;
145
158
  }
146
159
  __name(extractProjectId, "extractProjectId");
@@ -156,18 +169,21 @@ function listProjects() {
156
169
  });
157
170
  }
158
171
  __name(listProjects, "listProjects");
159
- function getApiKey(projectId) {
172
+ function getProject(projectId) {
160
173
  const config = readProjectsConfig();
161
- return config.projects[projectId]?.apiKey ?? null;
174
+ const project2 = config.projects[projectId];
175
+ if (!project2) return null;
176
+ return { projectId, ...project2 };
162
177
  }
163
- __name(getApiKey, "getApiKey");
178
+ __name(getProject, "getProject");
164
179
  function saveProject(project2) {
165
180
  const config = readProjectsConfig();
166
- config.projects[project2.projectId] = {
167
- apiKey: project2.apiKey,
168
- name: project2.name,
169
- lastUsedAt: project2.lastUsedAt
170
- };
181
+ const newProject = { ...config.projects[project2.projectId] };
182
+ newProject.apiKey = project2.apiKey;
183
+ if (project2.userId) newProject.userId = project2.userId;
184
+ if (project2.name) newProject.name = project2.name;
185
+ if (project2.lastUsedAt) newProject.lastUsedAt = project2.lastUsedAt;
186
+ config.projects[project2.projectId] = newProject;
171
187
  writeProjectsConfig(config);
172
188
  }
173
189
  __name(saveProject, "saveProject");
@@ -192,6 +208,216 @@ function debug(tag, message) {
192
208
  console.error(`[debug ${timestamp}] ${tag}: ${message}`);
193
209
  }
194
210
  __name(debug, "debug");
211
+ var DEFAULT_FS_POLL_INTERVAL_MS = 1e3;
212
+ var fsPollIntervalMs = DEFAULT_FS_POLL_INTERVAL_MS;
213
+ var SettingsWatcher = class {
214
+ constructor(settingsPath) {
215
+ this.settingsPath = settingsPath;
216
+ }
217
+ settingsPath;
218
+ static {
219
+ __name(this, "SettingsWatcher");
220
+ }
221
+ start(callback) {
222
+ fs6.watchFile(
223
+ this.settingsPath,
224
+ { persistent: false, interval: fsPollIntervalMs },
225
+ (curr, prev) => {
226
+ if (
227
+ // File was modified
228
+ curr.mtimeMs !== prev.mtimeMs || // File was renamed and replaced by a new file with the same name
229
+ curr.ino !== prev.ino || // File changed without any of the above changing for some reason?
230
+ curr.size !== prev.size
231
+ ) {
232
+ callback();
233
+ }
234
+ }
235
+ );
236
+ return this;
237
+ }
238
+ stop() {
239
+ fs6.unwatchFile(this.settingsPath);
240
+ return this;
241
+ }
242
+ };
243
+
244
+ // src/config/settings.ts
245
+ var DEFAULT_MACHINE_ID = "unknown-machine-id-this-should-never-be-persisted";
246
+ var DEFAULT_SETTINGS = {
247
+ machineId: DEFAULT_MACHINE_ID,
248
+ telemetryEnabled: true,
249
+ telemetryNoticeShown: false
250
+ };
251
+ var SettingsFileSchema = z.object({
252
+ machineId: z.string().optional(),
253
+ telemetryEnabled: z.boolean().optional(),
254
+ telemetryNoticeShown: z.boolean().optional()
255
+ });
256
+ function getSettingsPath() {
257
+ return path6.join(getConfigDir(), "settings.json");
258
+ }
259
+ __name(getSettingsPath, "getSettingsPath");
260
+ var settings;
261
+ var settingsWatcher;
262
+ function getSettings() {
263
+ if (settings) return settings;
264
+ settings = readSettingsFile();
265
+ if (!settingsWatcher) {
266
+ settingsWatcher = new SettingsWatcher(getSettingsPath()).start(() => {
267
+ settings = void 0;
268
+ });
269
+ }
270
+ return settings;
271
+ }
272
+ __name(getSettings, "getSettings");
273
+ function readSettingsFile() {
274
+ const settingsPath = getSettingsPath();
275
+ try {
276
+ const raw = JSON.parse(fs6.readFileSync(settingsPath, "utf-8"));
277
+ const result = SettingsFileSchema.parse(raw);
278
+ return {
279
+ machineId: result.machineId ?? DEFAULT_SETTINGS.machineId,
280
+ telemetryEnabled: result.telemetryEnabled ?? DEFAULT_SETTINGS.telemetryEnabled,
281
+ telemetryNoticeShown: result.telemetryNoticeShown ?? DEFAULT_SETTINGS.telemetryNoticeShown
282
+ };
283
+ } catch {
284
+ return { ...DEFAULT_SETTINGS };
285
+ }
286
+ }
287
+ __name(readSettingsFile, "readSettingsFile");
288
+ function setSettings(newSettings) {
289
+ settings = newSettings;
290
+ writeSettingsFile(newSettings);
291
+ }
292
+ __name(setSettings, "setSettings");
293
+ function writeSettingsFile(settings2) {
294
+ ensureConfigDir();
295
+ fs6.writeFileSync(getSettingsPath(), JSON.stringify(settings2, null, " "), {
296
+ mode: 384
297
+ });
298
+ }
299
+ __name(writeSettingsFile, "writeSettingsFile");
300
+ function getMachineId() {
301
+ const settings2 = getSettings();
302
+ if (settings2.machineId === DEFAULT_MACHINE_ID) {
303
+ const machineId = crypto.randomUUID();
304
+ setSettings({ ...settings2, machineId });
305
+ }
306
+ return getSettings().machineId;
307
+ }
308
+ __name(getMachineId, "getMachineId");
309
+ function isTelemetryEnabled() {
310
+ return getSettings().telemetryEnabled;
311
+ }
312
+ __name(isTelemetryEnabled, "isTelemetryEnabled");
313
+ function setTelemetryEnabled(enabled2) {
314
+ const settings2 = getSettings();
315
+ setSettings({ ...settings2, telemetryEnabled: enabled2 });
316
+ }
317
+ __name(setTelemetryEnabled, "setTelemetryEnabled");
318
+ function isTelemetryNoticeShown() {
319
+ return getSettings().telemetryNoticeShown;
320
+ }
321
+ __name(isTelemetryNoticeShown, "isTelemetryNoticeShown");
322
+ function markTelemetryNoticeShown() {
323
+ const settings2 = getSettings();
324
+ setSettings({ ...settings2, telemetryNoticeShown: true });
325
+ }
326
+ __name(markTelemetryNoticeShown, "markTelemetryNoticeShown");
327
+
328
+ // src/version.ts
329
+ var VERSION = (
330
+ // typeof is used to ensure this can be used just via tsx or node etc. without build
331
+ "0.0.21"
332
+ );
333
+ var trackingEndpoint = "https://events.framer.com/track";
334
+ var inProgressTrackings = /* @__PURE__ */ new Set();
335
+ function sharedFields() {
336
+ return {
337
+ machineId: getMachineId(),
338
+ cliVersion: VERSION
339
+ };
340
+ }
341
+ __name(sharedFields, "sharedFields");
342
+ function wrapEvent(event) {
343
+ return {
344
+ source: "framer-dalton",
345
+ timestamp: Date.now(),
346
+ type: "track",
347
+ uuid: randomUUID(),
348
+ data: event
349
+ };
350
+ }
351
+ __name(wrapEvent, "wrapEvent");
352
+ function postEvent(event) {
353
+ if (!isTelemetryEnabled()) return false;
354
+ if (process.env.NODE_ENV === "test" && true) return false;
355
+ const promise = fetch(trackingEndpoint, {
356
+ method: "POST",
357
+ headers: {
358
+ "Content-Type": "application/json",
359
+ "User-Agent": `framer-dalton/${VERSION}`
360
+ },
361
+ body: JSON.stringify([wrapEvent(event)]),
362
+ signal: AbortSignal.timeout(
363
+ 5e3
364
+ /* 5 seconds */
365
+ )
366
+ }).then((response) => {
367
+ if (!response.ok) {
368
+ debug(
369
+ "tracking",
370
+ `failed to send ${event.event}: HTTP ${response.status}`
371
+ );
372
+ }
373
+ }).catch((error) => {
374
+ debug(
375
+ "tracking",
376
+ `failed to send ${event.event}: ${error instanceof Error ? error.message : String(error)}`
377
+ );
378
+ }).finally(() => {
379
+ inProgressTrackings.delete(promise);
380
+ });
381
+ inProgressTrackings.add(promise);
382
+ return true;
383
+ }
384
+ __name(postEvent, "postEvent");
385
+ function waitForTrackingToFinish() {
386
+ return Promise.allSettled(Array.from(inProgressTrackings));
387
+ }
388
+ __name(waitForTrackingToFinish, "waitForTrackingToFinish");
389
+ function trackAuthStart(payload) {
390
+ postEvent({
391
+ event: "local_agents_auth_start",
392
+ ...sharedFields(),
393
+ ...payload
394
+ });
395
+ }
396
+ __name(trackAuthStart, "trackAuthStart");
397
+ function trackAuthSuccess(payload) {
398
+ postEvent({
399
+ event: "local_agents_auth_success",
400
+ ...sharedFields(),
401
+ ...payload
402
+ });
403
+ }
404
+ __name(trackAuthSuccess, "trackAuthSuccess");
405
+ function trackSkillsInstall(payload) {
406
+ postEvent({
407
+ event: "local_agents_skills_install",
408
+ ...sharedFields(),
409
+ ...payload
410
+ });
411
+ }
412
+ __name(trackSkillsInstall, "trackSkillsInstall");
413
+ function trackError(payload) {
414
+ postEvent({
415
+ event: "local_agents_error",
416
+ ...sharedFields(),
417
+ ...payload
418
+ });
419
+ }
420
+ __name(trackError, "trackError");
195
421
 
196
422
  // src/utils.ts
197
423
  function formatError(error) {
@@ -209,6 +435,10 @@ function print(message) {
209
435
  console.log(message);
210
436
  }
211
437
  __name(print, "print");
438
+ function printWarning(message) {
439
+ console.warn(message);
440
+ }
441
+ __name(printWarning, "printWarning");
212
442
  function printError(message) {
213
443
  console.error(message);
214
444
  }
@@ -284,11 +514,11 @@ body{font-family:"Inter",system-ui,-apple-system,sans-serif;font-feature-setting
284
514
  </html>`;
285
515
  }
286
516
  __name(htmlPage, "htmlPage");
287
- function successHtml(theme) {
517
+ function successHtml(theme, message) {
288
518
  return htmlPage({
289
519
  title: "Framer \u2014 Agent Approved",
290
520
  heading: "Agent Approved",
291
- message: "Your local agent now has edit access to the project. You can close this tab and continue with the local agent.",
521
+ message: message ?? "Your local agent now has edit access to the project. You can close this tab and continue with the local agent.",
292
522
  theme
293
523
  });
294
524
  }
@@ -322,11 +552,34 @@ function parseCode(value) {
322
552
  return null;
323
553
  }
324
554
  __name(parseCode, "parseCode");
325
- async function acquireKeyFromBrowser(projectId) {
555
+ function isFramerHostname(hostname) {
556
+ return hostname === "framer.com" || hostname === "framerlocal.com" || hostname.endsWith(".framer.com") || hostname.endsWith(".framerlocal.com");
557
+ }
558
+ __name(isFramerHostname, "isFramerHostname");
559
+ function resolveProjectOrigin(projectUrlOrId) {
560
+ try {
561
+ const url = new URL(projectUrlOrId);
562
+ if (isFramerHostname(url.hostname.toLowerCase())) return url.origin;
563
+ } catch {
564
+ }
565
+ return "https://framer.com";
566
+ }
567
+ __name(resolveProjectOrigin, "resolveProjectOrigin");
568
+ function runBrowserAuthFlow(options) {
569
+ const {
570
+ deeplinkParams,
571
+ expectProjectId,
572
+ successMessage,
573
+ browserSuccessMessage,
574
+ projectOrigin = "https://framer.com",
575
+ authType,
576
+ pollProjectId
577
+ } = options;
326
578
  const state = crypto.randomBytes(16).toString("hex");
579
+ trackAuthStart({ projectId: pollProjectId ?? "unknown", authType });
327
580
  return new Promise((resolve, reject) => {
328
581
  let settled = false;
329
- let pendingApiKey = null;
582
+ let pendingAuth = null;
330
583
  function settle(fn) {
331
584
  if (settled) return;
332
585
  settled = true;
@@ -340,14 +593,20 @@ async function acquireKeyFromBrowser(projectId) {
340
593
  if (url.pathname === "/done") {
341
594
  const theme2 = parseTheme(url.searchParams.get("theme"));
342
595
  res.writeHead(200, { "Content-Type": "text/html" });
343
- res.end(successHtml(theme2), () => {
344
- if (pendingApiKey) {
345
- const apiKey2 = pendingApiKey;
346
- pendingApiKey = null;
596
+ res.end(successHtml(theme2, browserSuccessMessage), () => {
597
+ if (pendingAuth) {
598
+ const auth = pendingAuth;
599
+ pendingAuth = null;
347
600
  settle(() => {
348
601
  debug("auth", "received API key via /done, resolving");
349
- print("\u2713 Agent authorized");
350
- resolve(apiKey2);
602
+ print(`\u2713 ${successMessage}`);
603
+ trackAuthSuccess({
604
+ projectId: auth.projectId ?? pollProjectId ?? "unknown",
605
+ authMethod: "browser",
606
+ authType,
607
+ userId: auth.userId
608
+ });
609
+ resolve(auth);
351
610
  });
352
611
  }
353
612
  });
@@ -365,60 +624,85 @@ async function acquireKeyFromBrowser(projectId) {
365
624
  return;
366
625
  }
367
626
  const theme = parseTheme(url.searchParams.get("theme"));
368
- const legacyError = url.searchParams.get("error");
369
- const legacyCode = legacyError === "denied" ? "user.denied" : legacyError === "failed" ? "project.unauthorized" : null;
370
- const code = parseCode(url.searchParams.get("code")) ?? legacyCode;
627
+ const code = parseCode(url.searchParams.get("code"));
371
628
  if (code !== null) {
372
629
  res.writeHead(200, { "Content-Type": "text/html" });
373
630
  res.end(codeHtml(code, theme), () => {
374
- settle(() => reject(new Error(codeMessages[code])));
631
+ settle(() => {
632
+ trackError({
633
+ errorType: "auth_error",
634
+ projectId: pollProjectId ?? "unknown",
635
+ errorMessage: codeMessages[code]
636
+ });
637
+ reject(new Error(codeMessages[code]));
638
+ });
375
639
  });
376
640
  return;
377
641
  }
378
642
  const apiKey = url.searchParams.get("apiKey");
643
+ const userId = url.searchParams.get("userId") ?? void 0;
644
+ const returnedProjectId = url.searchParams.get("projectId") ?? void 0;
379
645
  const returnedState = url.searchParams.get("state");
380
- if (!apiKey || returnedState !== state) {
646
+ if (!apiKey || returnedState !== state || expectProjectId && !returnedProjectId) {
381
647
  res.writeHead(302, { Location: `/error?theme=${theme}` });
382
648
  res.end();
383
649
  return;
384
650
  }
385
651
  debug("auth", "received valid callback, redirecting to /done");
386
- pendingApiKey = apiKey;
652
+ pendingAuth = { apiKey, userId, projectId: returnedProjectId };
387
653
  res.writeHead(302, { Location: `/done?theme=${theme}` });
388
654
  res.end();
389
655
  });
390
656
  const POLL_INTERVAL_MS = 1e3;
391
- const pollTimer = setInterval(() => {
392
- const apiKey = getApiKey(projectId);
393
- if (apiKey) {
657
+ const pollTimer = pollProjectId ? setInterval(() => {
658
+ const project2 = getProject(pollProjectId);
659
+ if (project2) {
394
660
  settle(() => {
395
661
  debug("auth", "API key detected from config file poll");
396
662
  print("\u2713 API key detected from config");
397
- resolve(apiKey);
663
+ trackAuthSuccess({
664
+ projectId: pollProjectId,
665
+ authMethod: "config_poll",
666
+ authType,
667
+ userId: project2.userId
668
+ });
669
+ resolve({
670
+ apiKey: project2.apiKey,
671
+ userId: project2.userId
672
+ });
398
673
  });
399
674
  }
400
- }, POLL_INTERVAL_MS);
675
+ }, POLL_INTERVAL_MS) : null;
401
676
  const HINT_MS = 55e3;
402
- const hintTimer = setTimeout(() => {
403
- const settingsUrl = `https://framer.com/projects/${projectId}?view=settings%3Aproject`;
677
+ const hintTimer = pollProjectId ? setTimeout(() => {
678
+ const settingsUrl = new URL(
679
+ `/projects/${pollProjectId}`,
680
+ projectOrigin
681
+ );
682
+ settingsUrl.searchParams.set("view", "settings:project");
404
683
  print("");
405
684
  printError("Taking a while? You can generate an API key manually:");
406
685
  printError(` 1. Open Site Settings \u2192 General: ${settingsUrl}`);
407
686
  printError(" 2. Scroll to API Keys and create a new key");
408
687
  printError(
409
- ` 3. In another terminal, run: framer project auth ${projectId} <your-api-key>`
688
+ ` 3. In another terminal, run: framer project auth ${pollProjectId} <your-api-key>`
410
689
  );
411
690
  print("");
412
691
  print("Waiting for authorization in browser...");
413
- }, HINT_MS);
692
+ }, HINT_MS) : null;
414
693
  const timer = setTimeout(() => {
415
- settle(
416
- () => reject(
694
+ settle(() => {
695
+ trackError({
696
+ errorType: "auth_timeout",
697
+ projectId: pollProjectId ?? "unknown",
698
+ errorMessage: "Browser authorization timed out"
699
+ });
700
+ reject(
417
701
  new Error(
418
- "Browser authorization timed out. Use `framer project auth <projectUrlOrId> <apiKey>` instead."
702
+ pollProjectId ? "Browser authorization timed out. Use `framer project auth <projectUrlOrId> <apiKey>` instead." : "Browser authorization timed out."
419
703
  )
420
- )
421
- );
704
+ );
705
+ });
422
706
  }, TIMEOUT_MS);
423
707
  let cleaned = false;
424
708
  function cleanup() {
@@ -426,8 +710,8 @@ async function acquireKeyFromBrowser(projectId) {
426
710
  cleaned = true;
427
711
  debug("auth", "cleanup: clearing timers and closing server");
428
712
  clearTimeout(timer);
429
- clearTimeout(hintTimer);
430
- clearInterval(pollTimer);
713
+ if (hintTimer) clearTimeout(hintTimer);
714
+ if (pollTimer) clearInterval(pollTimer);
431
715
  server.close();
432
716
  server.closeAllConnections();
433
717
  }
@@ -443,10 +727,12 @@ async function acquireKeyFromBrowser(projectId) {
443
727
  }
444
728
  debug("auth", `callback server listening on port ${addr.port}`);
445
729
  const callbackUrl = `http://127.0.0.1:${addr.port}/callback`;
446
- const deeplink = new URL("https://framer.com/projects/server-api/auth");
730
+ const deeplink = new URL("/projects/server-api/auth", projectOrigin);
447
731
  deeplink.searchParams.set("callback", callbackUrl);
448
732
  deeplink.searchParams.set("state", state);
449
- deeplink.searchParams.set("projectId", projectId);
733
+ for (const [key, value] of Object.entries(deeplinkParams)) {
734
+ deeplink.searchParams.set(key, value);
735
+ }
450
736
  const deeplinkStr = deeplink.toString();
451
737
  debug("auth", "opening browser for deeplink...");
452
738
  openUrl(deeplinkStr).then((opened) => {
@@ -461,7 +747,48 @@ async function acquireKeyFromBrowser(projectId) {
461
747
  });
462
748
  });
463
749
  }
464
- __name(acquireKeyFromBrowser, "acquireKeyFromBrowser");
750
+ __name(runBrowserAuthFlow, "runBrowserAuthFlow");
751
+ async function acquireAuthFromBrowser(projectUrlOrId) {
752
+ const projectId = extractProjectId(projectUrlOrId);
753
+ const projectOrigin = resolveProjectOrigin(projectUrlOrId);
754
+ return runBrowserAuthFlow({
755
+ deeplinkParams: { projectId },
756
+ expectProjectId: false,
757
+ successMessage: "Agent authorized",
758
+ authType: "existing",
759
+ projectOrigin,
760
+ pollProjectId: projectId
761
+ });
762
+ }
763
+ __name(acquireAuthFromBrowser, "acquireAuthFromBrowser");
764
+ async function acquireAuthWithNewProject() {
765
+ return runBrowserAuthFlow({
766
+ deeplinkParams: { createProject: "true" },
767
+ expectProjectId: true,
768
+ successMessage: "Project created and agent authorized",
769
+ authType: "new_project",
770
+ browserSuccessMessage: "A new project has been created and your local agent is authorized to edit it. You can close this tab."
771
+ });
772
+ }
773
+ __name(acquireAuthWithNewProject, "acquireAuthWithNewProject");
774
+ async function acquireAuthWithRemixProject(sourceProjectUrlOrId) {
775
+ const sourceProjectId = extractProjectId(sourceProjectUrlOrId);
776
+ const projectOrigin = resolveProjectOrigin(sourceProjectUrlOrId);
777
+ const isRemixSlug = REMIX_URL_PATTERN.test(sourceProjectUrlOrId);
778
+ const deeplinkParams = {
779
+ duplicate: sourceProjectId
780
+ };
781
+ if (isRemixSlug) deeplinkParams.isRemixSlug = "true";
782
+ return runBrowserAuthFlow({
783
+ deeplinkParams,
784
+ expectProjectId: true,
785
+ successMessage: "Project remixed and agent authorized",
786
+ authType: "remix",
787
+ browserSuccessMessage: "The project has been remixed and your local agent is authorized to edit it. You can close this tab.",
788
+ projectOrigin
789
+ });
790
+ }
791
+ __name(acquireAuthWithRemixProject, "acquireAuthWithRemixProject");
465
792
 
466
793
  // src/connection-errors.ts
467
794
  var AUTH_ERROR_PATTERNS = ["does not have access", "UNAUTHORIZED"];
@@ -679,6 +1006,13 @@ var types = {
679
1006
  }
680
1007
  ]
681
1008
  },
1009
+ aiserviceversion: {
1010
+ name: "AiServiceVersion",
1011
+ description: "Major version segment for the Framer AI chat HTTP path (`/ai/v{version}/chat/`).",
1012
+ kind: "alias",
1013
+ alias: '"3"',
1014
+ references: []
1015
+ },
682
1016
  allmethods: {
683
1017
  name: "AllMethods",
684
1018
  description: "",
@@ -3654,8 +3988,8 @@ var types = {
3654
3988
  name: "FontStyle",
3655
3989
  description: "",
3656
3990
  kind: "alias",
3657
- alias: 'Pick<CSSProperties, "fontFamily" | "fontWeight" | "fontStyle" | "fontSize" | "lineHeight" | "textAlign" | "letterSpacing" | "fontFeatureSettings">',
3658
- references: ["CSSProperties"]
3991
+ alias: 'Pick<CSS.Properties<string | number>, "fontFamily" | "fontWeight" | "fontStyle" | "fontSize" | "lineHeight" | "textAlign" | "letterSpacing" | "fontFeatureSettings">',
3992
+ references: ["CSS.Properties"]
3659
3993
  },
3660
3994
  fontstyle$1: {
3661
3995
  name: "FontStyle$1",
@@ -3910,6 +4244,26 @@ var types = {
3910
4244
  alias: '"hover" | "pressed" | "loading" | "error"',
3911
4245
  references: []
3912
4246
  },
4247
+ getlocalizationgroupsfilter: {
4248
+ name: "GetLocalizationGroupsFilter",
4249
+ description: "Filter options for {@link FramerPluginAPI.getLocalizationGroups}.",
4250
+ kind: "interface",
4251
+ references: ["LocalizationGroupId"],
4252
+ members: [
4253
+ {
4254
+ name: "groupIds",
4255
+ type: "LocalizationGroupId[]",
4256
+ description: "Return only groups matching these IDs.",
4257
+ optional: true
4258
+ },
4259
+ {
4260
+ name: "type",
4261
+ type: 'LocalizationGroup["type"]',
4262
+ description: "Return only groups of this type.",
4263
+ optional: true
4264
+ }
4265
+ ]
4266
+ },
3913
4267
  gridcontentalignment: {
3914
4268
  name: "GridContentAlignment",
3915
4269
  description: "",
@@ -6779,6 +7133,12 @@ var types = {
6779
7133
  description: "@alpha",
6780
7134
  optional: false
6781
7135
  },
7136
+ {
7137
+ name: "reviewChangesForAgent",
7138
+ type: "(options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7139
+ description: "@alpha",
7140
+ optional: false
7141
+ },
6782
7142
  {
6783
7143
  name: "startAgentConversation",
6784
7144
  type: "(prompt: string, options?: StartAgentConversationOptions) => Promise<StartAgentConversationResult>",
@@ -6799,7 +7159,7 @@ var types = {
6799
7159
  },
6800
7160
  {
6801
7161
  name: "[getAiServiceInfoMessageType]",
6802
- type: "() => Promise<AiServiceInfo>",
7162
+ type: "(version?: AiServiceVersion) => Promise<AiServiceInfo>",
6803
7163
  description: "",
6804
7164
  optional: false
6805
7165
  },
@@ -6835,7 +7195,7 @@ var types = {
6835
7195
  },
6836
7196
  {
6837
7197
  name: "getAiServiceInfo",
6838
- type: "() => Promise<AiServiceInfo>",
7198
+ type: "(version?: AiServiceVersion) => Promise<AiServiceInfo>",
6839
7199
  description: "@deprecated Use `getAiServiceInfoMessageType`.",
6840
7200
  optional: false
6841
7201
  },
@@ -7774,6 +8134,13 @@ var types = {
7774
8134
  "ArrayFieldDefinitionData"
7775
8135
  ]
7776
8136
  },
8137
+ supportedlinkrelvalue: {
8138
+ name: "SupportedLinkRelValue",
8139
+ description: "Supported rel values for links. See https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel",
8140
+ kind: "alias",
8141
+ alias: '"nofollow" | "noreferrer" | "me" | "ugc" | "sponsored"',
8142
+ references: []
8143
+ },
7777
8144
  svgdata: {
7778
8145
  name: "SVGData",
7779
8146
  description: "",
@@ -8919,7 +9286,7 @@ var types = {
8919
9286
  {
8920
9287
  name: "aspectRatio",
8921
9288
  type: "number | null",
8922
- description: "Width-to-height ratio (e.g. `1.5` for 3:2).\nSetting to `null` removes the aspect ratio constraint.\nSupported by FrameNode, ComponentInstanceNode.",
9289
+ description: "Width-to-height ratio (e.g. `1.5` for 3:2).\n\nSetting to `null` removes the aspect ratio constraint.\nSupported by FrameNode, ComponentInstanceNode.",
8923
9290
  optional: false
8924
9291
  }
8925
9292
  ]
@@ -8973,7 +9340,7 @@ var types = {
8973
9340
  {
8974
9341
  name: "backgroundColor",
8975
9342
  type: "(T extends TraitVariantData ? ColorStyleData : ColorStyle) | string | null",
8976
- description: "Background color in RGBA format (e.g. `rgba(242, 59, 57, 1)`) or as a {@link ColorStyle} instance.\nSetting to `null` removes the background color. Supported by FrameNode.",
9343
+ description: "Background color in RGBA format (e.g. `rgba(242, 59, 57, 1)`) or as a {@link ColorStyle} instance.\n\nSetting to `null` removes the background color. Supported by FrameNode.",
8977
9344
  optional: false
8978
9345
  }
8979
9346
  ]
@@ -9057,7 +9424,7 @@ var types = {
9057
9424
  {
9058
9425
  name: "borderRadius",
9059
9426
  type: "BorderRadius",
9060
- description: 'Border radius for rounded corners. Single value (e.g. `"10px"` or `"50%"`)\nor per-corner (e.g. `"10px 20px 30px 40px"` for top-left, top-right, bottom-right, bottom-left).\nSetting to `null` removes the border radius. Supported by FrameNode.',
9427
+ description: 'Border radius for rounded corners.\n\nSingle value (e.g. `"10px"` or `"50%"`)\nor per-corner (e.g. `"10px 20px 30px 40px"` for top-left, top-right, bottom-right, bottom-left).\nSetting to `null` removes the border radius. Supported by FrameNode.',
9061
9428
  optional: false
9062
9429
  }
9063
9430
  ]
@@ -9071,7 +9438,7 @@ var types = {
9071
9438
  {
9072
9439
  name: "border",
9073
9440
  type: "(T extends TraitVariantData ? Marshaled<Border> : Border) | null",
9074
- description: 'Border properties including width, color, and style.\nStyles: `"solid"`, `"dashed"`, `"dotted"`, `"double"`.\nWidth can be per-side (e.g. `"1px 2px 3px 4px"`).\nSetting to `null` removes the border. Supported by FrameNode.',
9441
+ description: 'Border properties including width, color, and style.\n\nStyles: `"solid"`, `"dashed"`, `"dotted"`, `"double"`.\nWidth can be per-side (e.g. `"1px 2px 3px 4px"`).\nSetting to `null` removes the border. Supported by FrameNode.',
9075
9442
  optional: false
9076
9443
  }
9077
9444
  ]
@@ -9433,37 +9800,37 @@ var types = {
9433
9800
  {
9434
9801
  name: "gridItemFillCellWidth",
9435
9802
  type: "boolean | null",
9436
- description: "Whether to fill the grid cell width. For nodes inside a grid container. Defaults to `true`. Supported by FrameNode, TextNode.",
9803
+ description: "Whether to fill the grid cell width.\n\nFor nodes inside a grid container. Defaults to `true`. Supported by FrameNode, TextNode.",
9437
9804
  optional: false
9438
9805
  },
9439
9806
  {
9440
9807
  name: "gridItemFillCellHeight",
9441
9808
  type: "boolean | null",
9442
- description: "Whether to fill the grid cell height. For nodes inside a grid container. Defaults to `true`. Supported by FrameNode, TextNode.",
9809
+ description: "Whether to fill the grid cell height.\n\nFor nodes inside a grid container. Defaults to `true`. Supported by FrameNode, TextNode.",
9443
9810
  optional: false
9444
9811
  },
9445
9812
  {
9446
9813
  name: "gridItemHorizontalAlignment",
9447
9814
  type: "GridItemAlignment | null",
9448
- description: 'Horizontal alignment within grid cell. For nodes inside a grid container. Defaults to `"center"`. Supported by FrameNode, TextNode.',
9815
+ description: 'Horizontal alignment within grid cell.\n\nFor nodes inside a grid container. Defaults to `"center"`. Supported by FrameNode, TextNode.',
9449
9816
  optional: false
9450
9817
  },
9451
9818
  {
9452
9819
  name: "gridItemVerticalAlignment",
9453
9820
  type: "GridItemAlignment | null",
9454
- description: 'Vertical alignment within grid cell. For nodes inside a grid container. Defaults to `"center"`. Supported by FrameNode, TextNode.',
9821
+ description: 'Vertical alignment within grid cell.\n\nFor nodes inside a grid container. Defaults to `"center"`. Supported by FrameNode, TextNode.',
9455
9822
  optional: false
9456
9823
  },
9457
9824
  {
9458
9825
  name: "gridItemColumnSpan",
9459
9826
  type: "GridItemColumnSpan | null",
9460
- description: 'Number of columns to span, or `"all"` for all columns. For nodes inside a grid container. Defaults to `1`. Supported by FrameNode, TextNode.',
9827
+ description: 'Number of columns to span, or `"all"` for all columns.\n\nFor nodes inside a grid container. Defaults to `1`. Supported by FrameNode, TextNode.',
9461
9828
  optional: false
9462
9829
  },
9463
9830
  {
9464
9831
  name: "gridItemRowSpan",
9465
9832
  type: "number | null",
9466
- description: "Number of rows to span. For nodes inside a grid container. Defaults to `1`. Supported by FrameNode, TextNode.",
9833
+ description: "Number of rows to span.\n\nFor nodes inside a grid container. Defaults to `1`. Supported by FrameNode, TextNode.",
9467
9834
  optional: false
9468
9835
  }
9469
9836
  ]
@@ -9498,7 +9865,7 @@ var types = {
9498
9865
  {
9499
9866
  name: "imageRendering",
9500
9867
  type: "ImageRendering | null",
9501
- description: 'How images should be rendered when scaled: `"auto"` or `"pixelated"`.\nOnly applies to frames with image backgrounds.\nSetting to `null` uses default rendering. Supported by FrameNode.',
9868
+ description: 'How images should be rendered when scaled: `"auto"` or `"pixelated"`.\n\nOnly applies to frames with image backgrounds.\nSetting to `null` uses default rendering. Supported by FrameNode.',
9502
9869
  optional: false
9503
9870
  }
9504
9871
  ]
@@ -9540,7 +9907,7 @@ var types = {
9540
9907
  {
9541
9908
  name: "inlineTextStyle",
9542
9909
  type: "(T extends TraitVariantData ? TextStyleData : TextStyle) | null",
9543
- description: "Apply a text style preset. Setting to `null` removes the text style.\nSupported by TextNode.",
9910
+ description: "Apply a text style preset.\n\nSetting to `null` removes the text style. Supported by TextNode.",
9544
9911
  optional: false
9545
9912
  }
9546
9913
  ]
@@ -9574,19 +9941,19 @@ var types = {
9574
9941
  {
9575
9942
  name: "layout",
9576
9943
  type: "LayoutType | null",
9577
- description: "Enables stack or grid layout. Setting to `null` disables any applied layout.\nOperation is deferred and applied after the current update cycle. Supported by FrameNode.",
9944
+ description: "Enables stack or grid layout.\n\nSetting to `null` disables any applied layout.\nOperation is deferred and applied after the current update cycle. Supported by FrameNode.",
9578
9945
  optional: false
9579
9946
  },
9580
9947
  {
9581
9948
  name: "gap",
9582
9949
  type: "CSSDimension<CSSUnit.Pixel> | `${CSSDimension<CSSUnit.Pixel>} ${CSSDimension<CSSUnit.Pixel>}` | null",
9583
- description: 'Spacing between items in a layout. Single value (e.g. `"10px"`) applies to both axes;\ntwo values (e.g. `"10px 20px"`) set horizontal and vertical separately.\nOnly works with layout enabled. Supported by FrameNode.',
9950
+ description: 'Spacing between items in a layout.\n\nSingle value (e.g. `"10px"`) applies to both axes;\ntwo values (e.g. `"10px 20px"`) set horizontal and vertical separately.\nOnly works with layout enabled. Supported by FrameNode.',
9584
9951
  optional: false
9585
9952
  },
9586
9953
  {
9587
9954
  name: "padding",
9588
9955
  type: "CSSDimension<CSSUnit.Pixel> | `${CSSDimension<CSSUnit.Pixel>} ${CSSDimension<CSSUnit.Pixel>} ${CSSDimension<CSSUnit.Pixel>} ${CSSDimension<CSSUnit.Pixel>}` | null",
9589
- description: 'Inner spacing of a container with layout. Single value (e.g. `"10px"`) applies to all sides;\nfour values (e.g. `"10px 20px 30px 40px"`) set top, right, bottom, left.\nOnly works with layout enabled. Supported by FrameNode.',
9956
+ description: 'Inner spacing of a container with layout.\n\nSingle value (e.g. `"10px"`) applies to all sides;\nfour values (e.g. `"10px 20px 30px 40px"`) set top, right, bottom, left.\nOnly works with layout enabled. Supported by FrameNode.',
9590
9957
  optional: false
9591
9958
  }
9592
9959
  ],
@@ -9596,18 +9963,42 @@ var types = {
9596
9963
  name: "WithLinkTrait",
9597
9964
  description: "",
9598
9965
  kind: "interface",
9599
- references: [],
9966
+ references: ["SupportedLinkRelValue"],
9600
9967
  members: [
9601
9968
  {
9602
9969
  name: "link",
9603
9970
  type: "string | null",
9604
- description: 'URL or internal page link. External: `"https://example.com"`, internal: `"/about"`,\nemail: `"mailto:user@example.com"`. Setting to `null` removes the link.\nSupported by FrameNode, TextNode.',
9971
+ description: 'URL or internal page link.\n\nExternal: `"https://example.com"`, internal: `"/about"`,\nemail: `"mailto:user@example.com"`. Setting to `null` removes the link.\nSupported by FrameNode, TextNode.',
9605
9972
  optional: false
9606
9973
  },
9607
9974
  {
9608
9975
  name: "linkOpenInNewTab",
9609
9976
  type: "boolean | null",
9610
- description: "Whether to open the link in a new tab. Default is automatically determined based on link type.\nSupported by FrameNode, TextNode.",
9977
+ description: "Whether to open the link in a new tab.\n\nDefault is automatically determined based on link type.\nSupported by FrameNode, TextNode.",
9978
+ optional: false
9979
+ },
9980
+ {
9981
+ name: "linkSmoothScroll",
9982
+ type: "boolean | null",
9983
+ description: "Whether to use smooth scrolling for scroll-to-section links.\nSupported by FrameNode, TextNode.",
9984
+ optional: false
9985
+ },
9986
+ {
9987
+ name: "linkClickTrackingId",
9988
+ type: "string | null",
9989
+ description: "Click tracking identifier for analytics.\nSupported by FrameNode, TextNode.",
9990
+ optional: false
9991
+ },
9992
+ {
9993
+ name: "linkRelValues",
9994
+ type: "readonly SupportedLinkRelValue[] | null",
9995
+ description: "Array of rel attribute values for the link.\nSupported by FrameNode, TextNode.",
9996
+ optional: false
9997
+ },
9998
+ {
9999
+ name: "linkPreserveParams",
10000
+ type: "boolean | null",
10001
+ description: "Whether to preserve URL query parameters when navigating.\nSupported by FrameNode, TextNode.",
9611
10002
  optional: false
9612
10003
  }
9613
10004
  ]
@@ -9649,7 +10040,7 @@ var types = {
9649
10040
  {
9650
10041
  name: "locked",
9651
10042
  type: "boolean",
9652
- description: "Whether the node is locked for editing. Defaults to `false`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
10043
+ description: "Whether the node is locked for editing.\n\nDefaults to `false`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
9653
10044
  optional: false
9654
10045
  }
9655
10046
  ]
@@ -9691,7 +10082,7 @@ var types = {
9691
10082
  {
9692
10083
  name: "name",
9693
10084
  type: "string | null",
9694
- description: "The name of the node displayed in the layers panel.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode,\nComponentNode, VectorSetNode, VectorSetItemNode.",
10085
+ description: "The name of the node displayed in the layers panel.\n\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode,\nComponentNode, VectorSetNode, VectorSetItemNode.",
9695
10086
  optional: false
9696
10087
  }
9697
10088
  ]
@@ -9775,7 +10166,7 @@ var types = {
9775
10166
  {
9776
10167
  name: "opacity",
9777
10168
  type: "number",
9778
- description: "Opacity of the node, from `0` (fully transparent) to `1` (fully opaque). Defaults to `1`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
10169
+ description: "Opacity of the node, from `0` (fully transparent) to `1` (fully opaque).\n\nDefaults to `1`. Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
9779
10170
  optional: false
9780
10171
  }
9781
10172
  ]
@@ -9810,19 +10201,19 @@ var types = {
9810
10201
  {
9811
10202
  name: "overflow",
9812
10203
  type: "Overflow | null",
9813
- description: "Controls how content that exceeds the element's box is handled.\nSetting to `null` removes the overflow property. Will overwrite `overflowX` or `overflowY`.\nSupported by FrameNode, TextNode.",
10204
+ description: "Controls how content that exceeds the element's box is handled.\n\nSetting to `null` removes the overflow property. Will overwrite `overflowX` or `overflowY`.\nSupported by FrameNode, TextNode.",
9814
10205
  optional: false
9815
10206
  },
9816
10207
  {
9817
10208
  name: "overflowX",
9818
10209
  type: "AxisOverflow | null",
9819
- description: "Controls horizontal overflow behavior.\nSetting to `null` removes the overflow X property. Supported by FrameNode, TextNode.",
10210
+ description: "Controls horizontal overflow behavior.\n\nSetting to `null` removes the overflow X property. Supported by FrameNode, TextNode.",
9820
10211
  optional: false
9821
10212
  },
9822
10213
  {
9823
10214
  name: "overflowY",
9824
10215
  type: "AxisOverflow | null",
9825
- description: "Controls vertical overflow behavior.\nSetting to `null` removes the overflow Y property. Supported by FrameNode, TextNode.",
10216
+ description: "Controls vertical overflow behavior.\n\nSetting to `null` removes the overflow Y property. Supported by FrameNode, TextNode.",
9826
10217
  optional: false
9827
10218
  }
9828
10219
  ]
@@ -9836,37 +10227,37 @@ var types = {
9836
10227
  {
9837
10228
  name: "top",
9838
10229
  type: "CSSDimension<CSSUnit.Pixel> | null",
9839
- description: 'Distance from top edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
10230
+ description: 'Distance from top edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
9840
10231
  optional: false
9841
10232
  },
9842
10233
  {
9843
10234
  name: "right",
9844
10235
  type: "CSSDimension<CSSUnit.Pixel> | null",
9845
- description: 'Distance from right edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
10236
+ description: 'Distance from right edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
9846
10237
  optional: false
9847
10238
  },
9848
10239
  {
9849
10240
  name: "bottom",
9850
10241
  type: "CSSDimension<CSSUnit.Pixel> | null",
9851
- description: 'Distance from bottom edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
10242
+ description: 'Distance from bottom edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
9852
10243
  optional: false
9853
10244
  },
9854
10245
  {
9855
10246
  name: "left",
9856
10247
  type: "CSSDimension<CSSUnit.Pixel> | null",
9857
- description: 'Distance from left edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
10248
+ description: 'Distance from left edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
9858
10249
  optional: false
9859
10250
  },
9860
10251
  {
9861
10252
  name: "centerX",
9862
10253
  type: "CSSDimension<CSSUnit.Percentage> | null",
9863
- description: 'Center anchor horizontal position as percentage (e.g. `"50%"`).\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
10254
+ description: 'Center anchor horizontal position as percentage (e.g. `"50%"`).\n\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
9864
10255
  optional: false
9865
10256
  },
9866
10257
  {
9867
10258
  name: "centerY",
9868
10259
  type: "CSSDimension<CSSUnit.Percentage> | null",
9869
- description: 'Center anchor vertical position as percentage (e.g. `"50%"`).\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
10260
+ description: 'Center anchor vertical position as percentage (e.g. `"50%"`).\n\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
9870
10261
  optional: false
9871
10262
  }
9872
10263
  ]
@@ -9894,7 +10285,7 @@ var types = {
9894
10285
  {
9895
10286
  name: "rotation",
9896
10287
  type: "number",
9897
- description: "Rotation angle in degrees. Defaults to `0`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
10288
+ description: "Rotation angle in degrees.\n\nDefaults to `0`. Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
9898
10289
  optional: false
9899
10290
  }
9900
10291
  ]
@@ -9940,13 +10331,13 @@ var types = {
9940
10331
  {
9941
10332
  name: "width",
9942
10333
  type: "WidthLength | null",
9943
- description: 'Width of the node. Accepts pixel, percentage, fraction values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
10334
+ description: 'Width of the node.\n\nAccepts pixel, percentage, fraction values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
9944
10335
  optional: false
9945
10336
  },
9946
10337
  {
9947
10338
  name: "height",
9948
10339
  type: "HeightLength | null",
9949
- description: 'Height of the node. Accepts pixel, percentage, fraction, viewport-height values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
10340
+ description: 'Height of the node.\n\nAccepts pixel, percentage, fraction, viewport-height values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
9950
10341
  optional: false
9951
10342
  }
9952
10343
  ]
@@ -10016,7 +10407,7 @@ var types = {
10016
10407
  {
10017
10408
  name: "textTruncation",
10018
10409
  type: "number | null",
10019
- description: "Maximum number of lines a text node can display before being truncated with an ellipsis.\nMust be used alongside `overflow`. Setting to `null` removes the text truncation property.\nSupported by TextNode.",
10410
+ description: "Maximum number of lines before text is truncated with an ellipsis.\n\nMust be used alongside `overflow`. Setting to `null` removes the text truncation property.\nSupported by TextNode.",
10020
10411
  optional: false
10021
10412
  }
10022
10413
  ]
@@ -10100,7 +10491,7 @@ var types = {
10100
10491
  {
10101
10492
  name: "visible",
10102
10493
  type: "boolean",
10103
- description: "Whether the node is visible on the canvas. Defaults to `true`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
10494
+ description: "Whether the node is visible on the canvas.\n\nDefaults to `true`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
10104
10495
  optional: false
10105
10496
  }
10106
10497
  ]
@@ -10114,7 +10505,7 @@ var types = {
10114
10505
  {
10115
10506
  name: "zIndex",
10116
10507
  type: "number | null",
10117
- description: "Stacking order of positioned elements. Higher values appear on top of lower values.\nSetting to `null` removes the z-index property. Supported by FrameNode, TextNode.",
10508
+ description: "Stacking order of positioned elements.\n\nHigher values appear on top of lower values.\nSetting to `null` removes the z-index property. Supported by FrameNode, TextNode.",
10118
10509
  optional: false
10119
10510
  }
10120
10511
  ]
@@ -10143,55 +10534,55 @@ var types = {
10143
10534
  var classes = {
10144
10535
  arrayfield: {
10145
10536
  name: "ArrayField",
10146
- description: "A CMS Collection field that stores an array of nested fields. Currently only\nsupports a single image field, which creates a Gallery in the CMS."
10537
+ description: "A CMS Collection field that stores an array of nested fields. Currently only\nsupports a single image field, which creates a Gallery in the CMS.\n@category cms"
10147
10538
  },
10148
10539
  booleanfield: {
10149
10540
  name: "BooleanField",
10150
- description: "A CMS Collection field that stores a boolean (true or false) value."
10541
+ description: "A CMS Collection field that stores a boolean (true or false) value.\n@category cms"
10151
10542
  },
10152
10543
  booleanvariable: {
10153
10544
  name: "BooleanVariable",
10154
- description: ""
10545
+ description: "A boolean variable.\n@category canvas"
10155
10546
  },
10156
10547
  bordervariable: {
10157
10548
  name: "BorderVariable",
10158
- description: ""
10549
+ description: "A border variable.\n@category canvas"
10159
10550
  },
10160
10551
  codefile: {
10161
10552
  name: "CodeFile",
10162
- description: "Represents a code file in the Framer project, such as a code component\nor code override."
10553
+ description: "Represents a code file in the Framer project, such as a code component\nor code override.\n@category code-files"
10163
10554
  },
10164
10555
  codefileversion: {
10165
10556
  name: "CodeFileVersion",
10166
- description: "A saved version (snapshot) of a code file."
10557
+ description: "A saved version (snapshot) of a code file.\n@category code-files"
10167
10558
  },
10168
10559
  collection: {
10169
10560
  name: "Collection",
10170
- description: "A CMS Collection in the project. Collections can be created by users or\nmanaged by plugins. Use `managedBy` to check the owner.\n\nAny kind of Collection can be read from. Unmanaged Collections are those\ncreated and updated by people. Use the `collection` mode to access CMS\ndata from your plugin."
10561
+ description: "A CMS Collection in the project.\n\nCollections can be created by users or managed by plugins. Use `managedBy`\nto check the owner. Any kind of Collection can be read from, while those\nmanaged by other plugins are read-only.\n@category cms"
10171
10562
  },
10172
10563
  collectionitem: {
10173
10564
  name: "CollectionItem",
10174
- description: "An item (row) in a CMS Collection. Each item contains field data keyed by\nfield ID, a unique slug, and a draft status."
10565
+ description: "An item (row) in a CMS Collection.\n\nEach item contains field data keyed by field ID, a unique slug, and a\ndraft status.\n@category cms"
10175
10566
  },
10176
10567
  collectionreferencefield: {
10177
10568
  name: "CollectionReferenceField",
10178
- description: "A field that references an item in another collection."
10569
+ description: "A field that references an item in another collection.\n@category cms"
10179
10570
  },
10180
10571
  colorfield: {
10181
10572
  name: "ColorField",
10182
- description: "A CMS Collection field that stores a color value (RGBA/HSL/HEX format)."
10573
+ description: "A CMS Collection field that stores a color value (RGBA/HSL/HEX format).\n@category cms"
10183
10574
  },
10184
10575
  colorstyle: {
10185
10576
  name: "ColorStyle",
10186
- description: 'A reusable color style defined in the project. Supports light and dark\ntheme variants. Color styles let you manage color appearances from one\nplace in a project. In the UI, you can find them in the Assets panel.\nPlugins can use these styles to do things like sync design systems or\ncheck accessibility.\n\nColors are stored in RGBA format, e.g. `rgba(242, 59, 57, 1)`. The\n`light` attribute is the default color used in light theme. The `dark`\nattribute is an optional color used in the dark theme.\n\nTo organize color styles into folders, use `/` as a separator in the\nname, e.g. `"My Plugin/My Cool Color"`.\n\n@example\n```ts\n// Create a new color style with light and dark variants.\nconst colorStyle = await framer.createColorStyle({\n name: "My Cool Color",\n light: "rgba(242, 59, 57, 1)",\n dark: "rgba(120, 22, 11, 1)"\n})\n\n// Update an existing color style.\nawait colorStyle.setAttributes({ dark: "rgba(10, 10, 10, 0.2)" })\n\n// Remove a color style from the project.\nawait colorStyle.remove()\n\n// Store plugin data on a color style.\nawait colorStyle.setPluginData("key", "value")\n```'
10577
+ description: 'A reusable color style defined in the project. Supports light and dark\ntheme variants. Color styles let you manage color appearances from one\nplace in a project. In the UI, you can find them in the Assets panel.\nPlugins can use these styles to do things like sync design systems or\ncheck accessibility.\n\nColors are stored in RGBA format, e.g. `rgba(242, 59, 57, 1)`. The\n`light` attribute is the default color used in light theme. The `dark`\nattribute is an optional color used in the dark theme.\n\nTo organize color styles into folders, use `/` as a separator in the\nname, e.g. `"My Plugin/My Cool Color"`.\n\n@example\n```ts\n// Create a new color style with light and dark variants.\nconst colorStyle = await framer.createColorStyle({\n name: "My Cool Color",\n light: "rgba(242, 59, 57, 1)",\n dark: "rgba(120, 22, 11, 1)"\n})\n\n// Update an existing color style.\nawait colorStyle.setAttributes({ dark: "rgba(10, 10, 10, 0.2)" })\n\n// Remove a color style from the project.\nawait colorStyle.remove()\n\n// Store plugin data on a color style.\nawait colorStyle.setPluginData("key", "value")\n```\n@category canvas'
10187
10578
  },
10188
10579
  colorvariable: {
10189
10580
  name: "ColorVariable",
10190
- description: ""
10581
+ description: "A color variable.\n@category canvas"
10191
10582
  },
10192
10583
  componentinstancenode: {
10193
10584
  name: "ComponentInstanceNode",
10194
- description: "An instance of a code or design component on the canvas. Component\ninstances are identified by their {@link ComponentInstanceNode.componentIdentifier | componentIdentifier}\nand can have their control properties updated via\n{@link NodeMethods.setAttributes | setAttributes}.\n\n@example\n```ts\nif (isCodeComponentNode(selection)) {\n selection.setAttributes({\n controls: { radius: 10 }\n })\n}\n```"
10585
+ description: "An instance of a code or design component on the canvas.\n\nComponent instances are identified by their\n{@link ComponentInstanceNode.componentIdentifier | componentIdentifier}\nand can have their control properties updated via\n{@link NodeMethods.setAttributes | setAttributes}.\n\n@example\n```ts\nif (isCodeComponentNode(selection)) {\n selection.setAttributes({\n controls: { radius: 10 }\n })\n}\n```\n@category canvas"
10195
10586
  },
10196
10587
  componentinstanceplaceholder: {
10197
10588
  name: "ComponentInstancePlaceholder",
@@ -10199,35 +10590,35 @@ var classes = {
10199
10590
  },
10200
10591
  componentnode: {
10201
10592
  name: "ComponentNode",
10202
- description: "A reusable design component definition. Component nodes contain\nvariants, gesture states, and variables. They can be inserted as\ninstances via their module URL."
10593
+ description: "A reusable design component definition.\n\nComponent nodes contain variants, gesture states, and variables.\nThey can be inserted as instances via their module URL.\n@category canvas"
10203
10594
  },
10204
10595
  conicgradient: {
10205
10596
  name: "ConicGradient",
10206
- description: ""
10597
+ description: "A conic (angular) gradient with two or more color stops.\n@category canvas"
10207
10598
  },
10208
10599
  datefield: {
10209
10600
  name: "DateField",
10210
- description: "A CMS Collection field that stores a date in UTC format. Optionally displays time."
10601
+ description: "A CMS Collection field that stores a date in UTC format. Optionally displays time.\n@category cms"
10211
10602
  },
10212
10603
  datevariable: {
10213
10604
  name: "DateVariable",
10214
- description: ""
10605
+ description: "A date variable.\n@category canvas"
10215
10606
  },
10216
10607
  designpagenode: {
10217
10608
  name: "DesignPageNode",
10218
- description: "A design page (non-web canvas) in the project."
10609
+ description: "A design page (non-web canvas) in the project.\n@category canvas"
10219
10610
  },
10220
10611
  enumcase: {
10221
10612
  name: "EnumCase",
10222
- description: "An individual case (option) within an Enum Field or Enum Variable."
10613
+ description: "An individual case (option) within an Enum Field or Enum Variable.\n@category cms"
10223
10614
  },
10224
10615
  enumfield: {
10225
10616
  name: "EnumField",
10226
- description: "A CMS Collection field with a fixed set of enum cases (options) that the user\ncan choose from. Enum cases must be defined as options before they can be\nassigned to CMS items."
10617
+ description: "A CMS Collection field with a fixed set of enum cases (options) that the user\ncan choose from. Enum cases must be defined as options before they can be\nassigned to CMS items.\n@category cms"
10227
10618
  },
10228
10619
  enumvariable: {
10229
10620
  name: "EnumVariable",
10230
- description: ""
10621
+ description: "An enum variable with a fixed set of cases.\n@category canvas"
10231
10622
  },
10232
10623
  fieldbasewithrequired: {
10233
10624
  name: "FieldBaseWithRequired",
@@ -10235,35 +10626,35 @@ var classes = {
10235
10626
  },
10236
10627
  fielddivider: {
10237
10628
  name: "FieldDivider",
10238
- description: "A visual divider between fields in the CMS UI. Not a data field."
10629
+ description: "A visual divider between fields in the CMS UI. Not a data field.\n@category cms"
10239
10630
  },
10240
10631
  fileasset: {
10241
10632
  name: "FileAsset",
10242
- description: "A file asset uploaded to the Framer project."
10633
+ description: "A file asset uploaded to the Framer project.\n@category canvas"
10243
10634
  },
10244
10635
  filefield: {
10245
10636
  name: "FileField",
10246
- description: "A CMS Collection field that stores a file asset (`FileAsset`)."
10637
+ description: "A CMS Collection field that stores a file asset (`FileAsset`).\n@category cms"
10247
10638
  },
10248
10639
  filevariable: {
10249
10640
  name: "FileVariable",
10250
- description: ""
10641
+ description: "A file variable.\n@category canvas"
10251
10642
  },
10252
10643
  font: {
10253
10644
  name: "Font",
10254
- description: "A font available in the project, including custom uploaded fonts."
10645
+ description: "A font available in the project, including custom uploaded fonts.\n@category canvas"
10255
10646
  },
10256
10647
  formattedtextfield: {
10257
10648
  name: "FormattedTextField",
10258
- description: "A CMS Collection field that stores HTML-formatted text content (H1-H6, P, and other standard content elements)."
10649
+ description: "A CMS Collection field that stores HTML-formatted text content (H1-H6, P, and other standard content elements).\n@category cms"
10259
10650
  },
10260
10651
  formattedtextvariable: {
10261
10652
  name: "FormattedTextVariable",
10262
- description: ""
10653
+ description: "A formatted text (rich text) variable.\n@category canvas"
10263
10654
  },
10264
10655
  framenode: {
10265
10656
  name: "FrameNode",
10266
- description: "A frame layer on the canvas, the most common container node. Frames\ncan contain children, have layout settings, backgrounds, borders, and\ncan serve as breakpoint or component variants."
10657
+ description: "A frame layer on the canvas, the most common container node.\n\nFrames can contain children, have layout settings, backgrounds, borders,\nand can serve as breakpoint or component variants.\n@category canvas"
10267
10658
  },
10268
10659
  framer: {
10269
10660
  name: "framer",
@@ -10283,43 +10674,43 @@ var classes = {
10283
10674
  },
10284
10675
  imageasset: {
10285
10676
  name: "ImageAsset",
10286
- description: "An image that has been uploaded to the Framer project. Provides methods\nto access image data, measure dimensions, and load as bitmap or HTML element."
10677
+ description: "An image that has been uploaded to the Framer project. Provides methods\nto access image data, measure dimensions, and load as bitmap or HTML element.\n@category canvas"
10287
10678
  },
10288
10679
  imagefield: {
10289
10680
  name: "ImageField",
10290
- description: "A CMS Collection field that stores an image asset (`ImageAsset`)."
10681
+ description: "A CMS Collection field that stores an image asset (`ImageAsset`).\n@category cms"
10291
10682
  },
10292
10683
  imagevariable: {
10293
10684
  name: "ImageVariable",
10294
- description: ""
10685
+ description: "An image variable.\n@category canvas"
10295
10686
  },
10296
10687
  lineargradient: {
10297
10688
  name: "LinearGradient",
10298
- description: ""
10689
+ description: "A linear gradient with two or more color stops.\n@category canvas"
10299
10690
  },
10300
10691
  linkfield: {
10301
10692
  name: "LinkField",
10302
- description: "A CMS Collection field that stores a URL in string format."
10693
+ description: "A CMS Collection field that stores a URL in string format.\n@category cms"
10303
10694
  },
10304
10695
  linkvariable: {
10305
10696
  name: "LinkVariable",
10306
- description: ""
10697
+ description: "A link variable.\n@category canvas"
10307
10698
  },
10308
10699
  managedcollection: {
10309
10700
  name: "ManagedCollection",
10310
- description: "A CMS Collection that is fully controlled by a plugin. Managed Collections\nallow plugins to define fields and sync items programmatically. Fields and\nitems can only be added, edited, and deleted by the owning plugin, not by\nthe user (unless a field is marked `userEditable`).\n\nA Managed Collection plugin becomes available within the CMS when it supports\nboth `configureManagedCollection` and `syncManagedCollection` modes.\n\nUse `framer.getManagedCollection()` to obtain an instance when the plugin is\nlaunched in either of those modes."
10701
+ description: "A CMS Collection that is fully controlled by a plugin.\n\nManaged Collections allow plugins to define fields and sync items\nprogrammatically. Fields and items can only be added, edited, and deleted\nby the owning plugin, not by the user (unless a field is marked\n`userEditable`).\n\nA Managed Collection plugin becomes available within the CMS when it supports\nboth `configureManagedCollection` and `syncManagedCollection` modes.\n\nUse `framer.getManagedCollection()` to obtain an instance when the plugin is\nlaunched in either of those modes.\n@category cms"
10311
10702
  },
10312
10703
  multicollectionreferencefield: {
10313
10704
  name: "MultiCollectionReferenceField",
10314
- description: "A field that references multiple items in another collection."
10705
+ description: "A field that references multiple items in another collection.\n@category cms"
10315
10706
  },
10316
10707
  numberfield: {
10317
10708
  name: "NumberField",
10318
- description: "A CMS Collection field that stores a numeric value."
10709
+ description: "A CMS Collection field that stores a numeric value.\n@category cms"
10319
10710
  },
10320
10711
  numbervariable: {
10321
10712
  name: "NumberVariable",
10322
- description: ""
10713
+ description: "A number variable.\n@category canvas"
10323
10714
  },
10324
10715
  pluginengine: {
10325
10716
  name: "PluginEngine",
@@ -10327,31 +10718,31 @@ var classes = {
10327
10718
  },
10328
10719
  radialgradient: {
10329
10720
  name: "RadialGradient",
10330
- description: ""
10721
+ description: "A radial gradient with two or more color stops.\n@category canvas"
10331
10722
  },
10332
10723
  redirect: {
10333
10724
  name: "Redirect",
10334
- description: "A URL redirect configured in the project. Redirects are applied when\nthe site is published."
10725
+ description: "A URL redirect configured in the project. Redirects are applied when\nthe site is published.\n@category settings"
10335
10726
  },
10336
10727
  stringfield: {
10337
10728
  name: "StringField",
10338
- description: "A CMS Collection field that stores a text string value."
10729
+ description: "A CMS Collection field that stores a text string value.\n@category cms"
10339
10730
  },
10340
10731
  stringvariable: {
10341
10732
  name: "StringVariable",
10342
- description: ""
10733
+ description: "A string variable.\n@category canvas"
10343
10734
  },
10344
10735
  svgnode: {
10345
10736
  name: "SVGNode",
10346
- description: "An SVG graphic layer on the canvas. Contains the raw SVG string and\nsupports positioning, sizing, rotation, and visibility."
10737
+ description: "An SVG graphic layer on the canvas.\n\nContains the raw SVG string and supports positioning, sizing,\nrotation, and visibility.\n@category canvas"
10347
10738
  },
10348
10739
  textnode: {
10349
10740
  name: "TextNode",
10350
- description: 'A text layer on the canvas. Use {@link TextNode.setText | setText} and\n{@link TextNode.getText | getText} to work with plain text, or\n{@link TextNode.setHTML | setHTML} and {@link TextNode.getHTML | getHTML}\nfor rich text content.\n\n@example\n```ts\nconst selection = await framer.getSelection()\nfor (const node of selection) {\n if (isTextNode(node)) {\n node.setText("Hello!")\n }\n}\n```'
10741
+ description: 'A text layer on the canvas.\n\nUse {@link TextNode.setText | setText} and\n{@link TextNode.getText | getText} to work with plain text, or\n{@link TextNode.setHTML | setHTML} and {@link TextNode.getHTML | getHTML}\nfor rich text content.\n\n@example\n```ts\nconst selection = await framer.getSelection()\nfor (const node of selection) {\n if (isTextNode(node)) {\n node.setText("Hello!")\n }\n}\n```\n@category canvas'
10351
10742
  },
10352
10743
  textstyle: {
10353
10744
  name: "TextStyle",
10354
- description: 'A reusable text style defined in the project, including font, size,\ncolor, and responsive breakpoints. Text styles let you manage text\nappearances from one place in a project. In the UI, you can find them\nin the Assets panel.\n\nText styles support responsive breakpoints that apply different values\nat different window widths. A maximum of four breakpoints can be added.\nBreakpoints are automatically ordered from largest to smallest `minWidth`.\nEach breakpoint must have a unique `minWidth` value.\n\nBy default, text styles use a built-in font. Use\n{@link Font} to customize a text style\'s typeface. All font variants\n(bold, italic, boldItalic) must share the same font family as the base\nfont.\n\nTo organize text styles into folders, use `/` as a separator in the\nname, e.g. `"My Plugin/Heading"`.\n\n@example\n```ts\n// Create a new text style.\nconst textStyle = await framer.createTextStyle({\n name: "Heading",\n tag: "h1",\n fontSize: "30px",\n lineHeight: "1.6em",\n})\n\n// Create a text style with responsive breakpoints.\nconst textStyle = await framer.createTextStyle({\n fontSize: "24px",\n minWidth: 1280,\n breakpoints: [\n { minWidth: 1024, fontSize: "18px" },\n { minWidth: 320, fontSize: "16px" }\n ]\n})\n\n// Update an existing text style.\nawait textStyle.setAttributes({\n color: "rgba(242, 59, 57, 1)"\n})\n\n// Create a text style with a custom font.\nconst font = await framer.getFont("Open Sans")\nif (font) {\n const textStyle = await framer.createTextStyle({ font })\n}\n\n// Remove a text style from the project.\nawait textStyle.remove()\n```'
10745
+ description: 'A reusable text style defined in the project, including font, size,\ncolor, and responsive breakpoints. Text styles let you manage text\nappearances from one place in a project. In the UI, you can find them\nin the Assets panel.\n\nText styles support responsive breakpoints that apply different values\nat different window widths. A maximum of four breakpoints can be added.\nBreakpoints are automatically ordered from largest to smallest `minWidth`.\nEach breakpoint must have a unique `minWidth` value.\n\nBy default, text styles use a built-in font. Use\n{@link Font} to customize a text style\'s typeface. All font variants\n(bold, italic, boldItalic) must share the same font family as the base\nfont.\n\nTo organize text styles into folders, use `/` as a separator in the\nname, e.g. `"My Plugin/Heading"`.\n\n@example\n```ts\n// Create a new text style.\nconst textStyle = await framer.createTextStyle({\n name: "Heading",\n tag: "h1",\n fontSize: "30px",\n lineHeight: "1.6em",\n})\n\n// Create a text style with responsive breakpoints.\nconst textStyle = await framer.createTextStyle({\n fontSize: "24px",\n minWidth: 1280,\n breakpoints: [\n { minWidth: 1024, fontSize: "18px" },\n { minWidth: 320, fontSize: "16px" }\n ]\n})\n\n// Update an existing text style.\nawait textStyle.setAttributes({\n color: "rgba(242, 59, 57, 1)"\n})\n\n// Create a text style with a custom font.\nconst font = await framer.getFont("Open Sans")\nif (font) {\n const textStyle = await framer.createTextStyle({ font })\n}\n\n// Remove a text style from the project.\nawait textStyle.remove()\n```\n@category canvas'
10355
10746
  },
10356
10747
  unknownnode: {
10357
10748
  name: "UnknownNode",
@@ -10359,15 +10750,15 @@ var classes = {
10359
10750
  },
10360
10751
  unsupportedcomputedvalue: {
10361
10752
  name: "UnsupportedComputedValue",
10362
- description: ""
10753
+ description: "A computed value type not yet supported by the plugin API.\n@category canvas"
10363
10754
  },
10364
10755
  unsupportedfield: {
10365
10756
  name: "UnsupportedField",
10366
- description: "A field type that is not yet supported by the plugin API.\nReturned when Framer uses a field type that the plugin API does not recognize."
10757
+ description: "A field type that is not yet supported by the plugin API.\nReturned when Framer uses a field type that the plugin API does not recognize.\n@category cms"
10367
10758
  },
10368
10759
  unsupportedvariable: {
10369
10760
  name: "UnsupportedVariable",
10370
- description: ""
10761
+ description: "A variable type not yet supported by the plugin API.\n@category canvas"
10371
10762
  },
10372
10763
  vectorset: {
10373
10764
  name: "VectorSet",
@@ -10379,15 +10770,15 @@ var classes = {
10379
10770
  },
10380
10771
  vectorsetitemnode: {
10381
10772
  name: "VectorSetItemNode",
10382
- description: "An individual item within a VectorSet node."
10773
+ description: "An individual item within a VectorSet node.\n@category canvas"
10383
10774
  },
10384
10775
  vectorsetnode: {
10385
10776
  name: "VectorSetNode",
10386
- description: "A container node for a set of vector icons."
10777
+ description: "A container node for a set of vector icons.\n@category canvas"
10387
10778
  },
10388
10779
  webpagenode: {
10389
10780
  name: "WebPageNode",
10390
- description: "A web page in the project's site map. Web pages have a\n{@link WebPageNode.path | path} and may be associated with a CMS\ncollection when used as a detail page."
10781
+ description: "A web page in the project's site map.\n\nWeb pages have a {@link WebPageNode.path | path} and may be associated\nwith a CMS collection when used as a detail page.\n@category canvas"
10391
10782
  }
10392
10783
  };
10393
10784
  var methodsByCategory = {
@@ -10632,7 +11023,7 @@ var methodsByCategory = {
10632
11023
  name: "addFields",
10633
11024
  category: "Collection",
10634
11025
  signature: "addFields(fields: CreateField[]): Promise<Field[]>",
10635
- description: 'Create new unmanaged Collection fields. Use `Field.setAttributes` to\nupdate existing fields.\n\nUse `"Collection.addFields"` to check if this method is allowed.\n\n@param fields - The array of fields that should be added to the collection.\n@returns The newly created Field instances.\n\n@example\n```ts\nconst createdFields = await collection.addFields([\n { type: "string", name: "Name" },\n { type: "enum", name: "Status", cases: [{ name: "New" }, { name: "Done" }] },\n { type: "file", name: "Text", allowedFileTypes: ["md"] },\n { type: "collectionReference", name: "Author", collectionId: "ASh5SZOh" },\n])\n```',
11026
+ description: 'Create new unmanaged Collection fields.\n\nUse `Field.setAttributes` to update existing fields.\n\nUse `"Collection.addFields"` to check if this method is allowed.\n\n@param fields - The array of fields that should be added to the collection.\n@returns The newly created Field instances.\n\n@example\n```ts\nconst createdFields = await collection.addFields([\n { type: "string", name: "Name" },\n { type: "enum", name: "Status", cases: [{ name: "New" }, { name: "Done" }] },\n { type: "file", name: "Text", allowedFileTypes: ["md"] },\n { type: "collectionReference", name: "Author", collectionId: "ASh5SZOh" },\n])\n```',
10636
11027
  references: ["CreateField", "Field"]
10637
11028
  },
10638
11029
  {
@@ -10653,7 +11044,7 @@ var methodsByCategory = {
10653
11044
  name: "getItems",
10654
11045
  category: "Collection",
10655
11046
  signature: "getItems(): Promise<CollectionItem[]>",
10656
- description: "Retrieve all items within this Collection, in their current order.\nItems may include drafts (unpublished items).\n\n@returns An array of CollectionItem instances.\n\n@example\n```ts\nconst items = await collection.getItems()\n```",
11047
+ description: "Retrieve all items within this Collection, in their current order.\n\nItems may include drafts (unpublished items).\n\n@returns An array of CollectionItem instances.\n\n@example\n```ts\nconst items = await collection.getItems()\n```",
10657
11048
  references: ["CollectionItem"]
10658
11049
  },
10659
11050
  {
@@ -10681,7 +11072,7 @@ var methodsByCategory = {
10681
11072
  name: "navigateTo",
10682
11073
  category: "Collection",
10683
11074
  signature: "navigateTo(opts?: NavigableOptions): Promise<void>",
10684
- description: "Navigate to this collection. May switch modes to reveal the relevant view.",
11075
+ description: "Navigate to this collection.\n\nMay switch modes to reveal the relevant view.",
10685
11076
  references: ["NavigableOptions"]
10686
11077
  },
10687
11078
  {
@@ -10709,14 +11100,14 @@ var methodsByCategory = {
10709
11100
  name: "setFieldOrder",
10710
11101
  category: "Collection",
10711
11102
  signature: "setFieldOrder(fieldIds: string[]): Promise<void>",
10712
- description: 'Reorder the fields in this Collection based on an array of field IDs.\nUnknown field IDs are ignored.\n\nUse `"Collection.setFieldOrder"` to check if this method is allowed.\n\n@param fieldIds - An array of field IDs representing the desired order.\n\n@example\n```ts\nawait collection.setFieldOrder([nameField.id, ageField.id])\n```',
11103
+ description: 'Reorder the fields in this Collection based on an array of field IDs.\n\nUnknown field IDs are ignored.\n\nUse `"Collection.setFieldOrder"` to check if this method is allowed.\n\n@param fieldIds - An array of field IDs representing the desired order.\n\n@example\n```ts\nawait collection.setFieldOrder([nameField.id, ageField.id])\n```',
10713
11104
  references: []
10714
11105
  },
10715
11106
  {
10716
11107
  name: "setItemOrder",
10717
11108
  category: "Collection",
10718
11109
  signature: "setItemOrder(ids: NodeId[]): Promise<void>",
10719
- description: 'Reorder the items in this Collection based on an array of item IDs.\nUnknown item IDs are ignored.\n\nUse `"Collection.setItemOrder"` to check if this method is allowed.\n\n@param ids - An array of item IDs representing the desired order.\n\n@example\n```ts\nawait collection.setItemOrder([item3.id, item1.id, item2.id])\n```',
11110
+ description: 'Reorder the items in this Collection based on an array of item IDs.\n\nUnknown item IDs are ignored.\n\nUse `"Collection.setItemOrder"` to check if this method is allowed.\n\n@param ids - An array of item IDs representing the desired order.\n\n@example\n```ts\nawait collection.setItemOrder([item3.id, item1.id, item2.id])\n```',
10720
11111
  references: []
10721
11112
  },
10722
11113
  {
@@ -10753,7 +11144,7 @@ var methodsByCategory = {
10753
11144
  name: "fieldData",
10754
11145
  category: "CollectionItem",
10755
11146
  signature: "fieldData: Readonly<FieldData>",
10756
- description: 'The fields and corresponding values of this Collection item. Field data\nuses the field `id` as keys in an object.\n\n@example\n```ts\nconst titleFieldData = collectionItem.fieldData[titleField.id]\nconsole.log(titleFieldData.value) // "Getting Started"\n```',
11147
+ description: 'The fields and corresponding values of this Collection item.\n\nField data uses the field `id` as keys in an object.\n\n@example\n```ts\nconst titleFieldData = collectionItem.fieldData[titleField.id]\nconsole.log(titleFieldData.value) // "Getting Started"\n```',
10757
11148
  references: ["FieldData"]
10758
11149
  },
10759
11150
  {
@@ -10980,28 +11371,28 @@ var methodsByCategory = {
10980
11371
  name: "aspectRatio",
10981
11372
  category: "ComponentInstanceNode",
10982
11373
  signature: "aspectRatio: number | null",
10983
- description: "Width-to-height ratio (e.g. `1.5` for 3:2).\nSetting to `null` removes the aspect ratio constraint.\nSupported by FrameNode, ComponentInstanceNode.",
11374
+ description: "Width-to-height ratio (e.g. `1.5` for 3:2).\n\nSetting to `null` removes the aspect ratio constraint.\nSupported by FrameNode, ComponentInstanceNode.",
10984
11375
  references: []
10985
11376
  },
10986
11377
  {
10987
11378
  name: "bottom",
10988
11379
  category: "ComponentInstanceNode",
10989
11380
  signature: "bottom: CSSDimension<CSSUnit.Pixel> | null",
10990
- description: 'Distance from bottom edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
11381
+ description: 'Distance from bottom edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
10991
11382
  references: ["CSSDimension", "CSSUnit.Pixel"]
10992
11383
  },
10993
11384
  {
10994
11385
  name: "centerX",
10995
11386
  category: "ComponentInstanceNode",
10996
11387
  signature: "centerX: CSSDimension<CSSUnit.Percentage> | null",
10997
- description: 'Center anchor horizontal position as percentage (e.g. `"50%"`).\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
11388
+ description: 'Center anchor horizontal position as percentage (e.g. `"50%"`).\n\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
10998
11389
  references: ["CSSDimension", "CSSUnit.Percentage"]
10999
11390
  },
11000
11391
  {
11001
11392
  name: "centerY",
11002
11393
  category: "ComponentInstanceNode",
11003
11394
  signature: "centerY: CSSDimension<CSSUnit.Percentage> | null",
11004
- description: 'Center anchor vertical position as percentage (e.g. `"50%"`).\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
11395
+ description: 'Center anchor vertical position as percentage (e.g. `"50%"`).\n\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
11005
11396
  references: ["CSSDimension", "CSSUnit.Percentage"]
11006
11397
  },
11007
11398
  {
@@ -11043,7 +11434,7 @@ var methodsByCategory = {
11043
11434
  name: "getNodesWithAttribute",
11044
11435
  category: "ComponentInstanceNode",
11045
11436
  signature: "getNodesWithAttribute(attribute: T): Promise<Node[]>",
11046
- description: 'Get the descendants of this node that support `attribute`. This\nreturns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
11437
+ description: 'Get the descendants of this node that support `attribute`.\n\nThis returns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
11047
11438
  references: ["T", "Node"]
11048
11439
  },
11049
11440
  {
@@ -11057,7 +11448,7 @@ var methodsByCategory = {
11057
11448
  name: "getNodesWithType",
11058
11449
  category: "ComponentInstanceNode",
11059
11450
  signature: 'getNodesWithType(type: "FrameNode"): Promise<FrameNode[]>',
11060
- description: 'Get descendants of this node that match the given type. This can\nalso be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
11451
+ description: 'Get descendants of this node that match the given type.\n\nThis can also be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
11061
11452
  references: ["FrameNode"]
11062
11453
  },
11063
11454
  {
@@ -11071,7 +11462,7 @@ var methodsByCategory = {
11071
11462
  name: "getPluginData",
11072
11463
  category: "ComponentInstanceNode",
11073
11464
  signature: "getPluginData(key: string): Promise<string | null>",
11074
- description: "Get plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
11465
+ description: "Get plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
11075
11466
  references: []
11076
11467
  },
11077
11468
  {
@@ -11099,21 +11490,21 @@ var methodsByCategory = {
11099
11490
  name: "height",
11100
11491
  category: "ComponentInstanceNode",
11101
11492
  signature: "height: HeightLength | null",
11102
- description: 'Height of the node. Accepts pixel, percentage, fraction, viewport-height values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
11493
+ description: 'Height of the node.\n\nAccepts pixel, percentage, fraction, viewport-height values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
11103
11494
  references: ["HeightLength"]
11104
11495
  },
11105
11496
  {
11106
11497
  name: "left",
11107
11498
  category: "ComponentInstanceNode",
11108
11499
  signature: "left: CSSDimension<CSSUnit.Pixel> | null",
11109
- description: 'Distance from left edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
11500
+ description: 'Distance from left edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
11110
11501
  references: ["CSSDimension", "CSSUnit.Pixel"]
11111
11502
  },
11112
11503
  {
11113
11504
  name: "locked",
11114
11505
  category: "ComponentInstanceNode",
11115
11506
  signature: "locked: boolean",
11116
- description: "Whether the node is locked for editing. Defaults to `false`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
11507
+ description: "Whether the node is locked for editing.\n\nDefaults to `false`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
11117
11508
  references: []
11118
11509
  },
11119
11510
  {
@@ -11148,21 +11539,21 @@ var methodsByCategory = {
11148
11539
  name: "name",
11149
11540
  category: "ComponentInstanceNode",
11150
11541
  signature: "name: string | null",
11151
- description: "The name of the node displayed in the layers panel.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode,\nComponentNode, VectorSetNode, VectorSetItemNode.",
11542
+ description: "The name of the node displayed in the layers panel.\n\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode,\nComponentNode, VectorSetNode, VectorSetItemNode.",
11152
11543
  references: []
11153
11544
  },
11154
11545
  {
11155
11546
  name: "navigateTo",
11156
11547
  category: "ComponentInstanceNode",
11157
11548
  signature: 'navigateTo(opts?: Pick<NavigableOptions, "select" | "zoomIntoView">): Promise<void>',
11158
- description: "Navigate to this node. May switch modes to reveal the relevant view.",
11549
+ description: "Navigate to this node.\n\nMay switch modes to reveal the relevant view.",
11159
11550
  references: ["NavigableOptions"]
11160
11551
  },
11161
11552
  {
11162
11553
  name: "opacity",
11163
11554
  category: "ComponentInstanceNode",
11164
11555
  signature: "opacity: number",
11165
- description: "Opacity of the node, from `0` (fully transparent) to `1` (fully opaque). Defaults to `1`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
11556
+ description: "Opacity of the node, from `0` (fully transparent) to `1` (fully opaque).\n\nDefaults to `1`. Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
11166
11557
  references: []
11167
11558
  },
11168
11559
  {
@@ -11183,14 +11574,14 @@ var methodsByCategory = {
11183
11574
  name: "right",
11184
11575
  category: "ComponentInstanceNode",
11185
11576
  signature: "right: CSSDimension<CSSUnit.Pixel> | null",
11186
- description: 'Distance from right edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
11577
+ description: 'Distance from right edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
11187
11578
  references: ["CSSDimension", "CSSUnit.Pixel"]
11188
11579
  },
11189
11580
  {
11190
11581
  name: "rotation",
11191
11582
  category: "ComponentInstanceNode",
11192
11583
  signature: "rotation: number",
11193
- description: "Rotation angle in degrees. Defaults to `0`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
11584
+ description: "Rotation angle in degrees.\n\nDefaults to `0`. Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
11194
11585
  references: []
11195
11586
  },
11196
11587
  {
@@ -11204,21 +11595,21 @@ var methodsByCategory = {
11204
11595
  name: "setAttributes",
11205
11596
  category: "ComponentInstanceNode",
11206
11597
  signature: 'setAttributes(update: Partial<NodeClassToEditableAttributes[(typeof this)[ClassKey]]>): Promise<(typeof this)[ClassKey] extends "UnknownNode" ? never : typeof this | null>',
11207
- description: 'Set the attributes of this node. Attributes are merged with existing\nvalues, so only the provided attributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
11598
+ description: 'Set the attributes of this node.\n\nAttributes are merged with existing values, so only the provided\nattributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
11208
11599
  references: []
11209
11600
  },
11210
11601
  {
11211
11602
  name: "setPluginData",
11212
11603
  category: "ComponentInstanceNode",
11213
11604
  signature: "setPluginData(key: string, value: string | null): Promise<void>",
11214
- description: 'Set plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
11605
+ description: 'Set plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
11215
11606
  references: []
11216
11607
  },
11217
11608
  {
11218
11609
  name: "top",
11219
11610
  category: "ComponentInstanceNode",
11220
11611
  signature: "top: CSSDimension<CSSUnit.Pixel> | null",
11221
- description: 'Distance from top edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
11612
+ description: 'Distance from top edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
11222
11613
  references: ["CSSDimension", "CSSUnit.Pixel"]
11223
11614
  },
11224
11615
  {
@@ -11232,21 +11623,21 @@ var methodsByCategory = {
11232
11623
  name: "visible",
11233
11624
  category: "ComponentInstanceNode",
11234
11625
  signature: "visible: boolean",
11235
- description: "Whether the node is visible on the canvas. Defaults to `true`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
11626
+ description: "Whether the node is visible on the canvas.\n\nDefaults to `true`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
11236
11627
  references: []
11237
11628
  },
11238
11629
  {
11239
11630
  name: "walk",
11240
11631
  category: "ComponentInstanceNode",
11241
11632
  signature: "walk(this: AnyNode): AsyncGenerator<AnyNode>",
11242
- description: "Walk this node and its descendants recursively using an async\ngenerator. Yields nodes depth-first.",
11633
+ description: "Walk this node and its descendants recursively.\n\nUses an async generator. Yields nodes depth-first.",
11243
11634
  references: ["AnyNode"]
11244
11635
  },
11245
11636
  {
11246
11637
  name: "width",
11247
11638
  category: "ComponentInstanceNode",
11248
11639
  signature: "width: WidthLength | null",
11249
- description: 'Width of the node. Accepts pixel, percentage, fraction values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
11640
+ description: 'Width of the node.\n\nAccepts pixel, percentage, fraction values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
11250
11641
  references: ["WidthLength"]
11251
11642
  },
11252
11643
  {
@@ -11315,7 +11706,7 @@ var methodsByCategory = {
11315
11706
  name: "getNodesWithAttribute",
11316
11707
  category: "ComponentNode",
11317
11708
  signature: "getNodesWithAttribute(attribute: T): Promise<Node[]>",
11318
- description: 'Get the descendants of this node that support `attribute`. This\nreturns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
11709
+ description: 'Get the descendants of this node that support `attribute`.\n\nThis returns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
11319
11710
  references: ["T", "Node"]
11320
11711
  },
11321
11712
  {
@@ -11329,7 +11720,7 @@ var methodsByCategory = {
11329
11720
  name: "getNodesWithType",
11330
11721
  category: "ComponentNode",
11331
11722
  signature: 'getNodesWithType(type: "FrameNode"): Promise<FrameNode[]>',
11332
- description: 'Get descendants of this node that match the given type. This can\nalso be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
11723
+ description: 'Get descendants of this node that match the given type.\n\nThis can also be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
11333
11724
  references: ["FrameNode"]
11334
11725
  },
11335
11726
  {
@@ -11343,7 +11734,7 @@ var methodsByCategory = {
11343
11734
  name: "getPluginData",
11344
11735
  category: "ComponentNode",
11345
11736
  signature: "getPluginData(key: string): Promise<string | null>",
11346
- description: "Get plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
11737
+ description: "Get plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
11347
11738
  references: []
11348
11739
  },
11349
11740
  {
@@ -11371,7 +11762,7 @@ var methodsByCategory = {
11371
11762
  name: "navigateTo",
11372
11763
  category: "ComponentNode",
11373
11764
  signature: 'navigateTo(opts?: Pick<NavigableOptions, "select" | "zoomIntoView">): Promise<void>',
11374
- description: "Navigate to this node. May switch modes to reveal the relevant view.",
11765
+ description: "Navigate to this node.\n\nMay switch modes to reveal the relevant view.",
11375
11766
  references: ["NavigableOptions"]
11376
11767
  },
11377
11768
  {
@@ -11399,14 +11790,14 @@ var methodsByCategory = {
11399
11790
  name: "setAttributes",
11400
11791
  category: "ComponentNode",
11401
11792
  signature: 'setAttributes(update: Partial<NodeClassToEditableAttributes[(typeof this)[ClassKey]]>): Promise<(typeof this)[ClassKey] extends "UnknownNode" ? never : typeof this | null>',
11402
- description: 'Set the attributes of this node. Attributes are merged with existing\nvalues, so only the provided attributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
11793
+ description: 'Set the attributes of this node.\n\nAttributes are merged with existing values, so only the provided\nattributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
11403
11794
  references: []
11404
11795
  },
11405
11796
  {
11406
11797
  name: "setPluginData",
11407
11798
  category: "ComponentNode",
11408
11799
  signature: "setPluginData(key: string, value: string | null): Promise<void>",
11409
- description: 'Set plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
11800
+ description: 'Set plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
11410
11801
  references: []
11411
11802
  },
11412
11803
  {
@@ -11420,7 +11811,7 @@ var methodsByCategory = {
11420
11811
  name: "walk",
11421
11812
  category: "ComponentNode",
11422
11813
  signature: "walk(this: AnyNode): AsyncGenerator<AnyNode>",
11423
- description: "Walk this node and its descendants recursively using an async\ngenerator. Yields nodes depth-first.",
11814
+ description: "Walk this node and its descendants recursively.\n\nUses an async generator. Yields nodes depth-first.",
11424
11815
  references: ["AnyNode"]
11425
11816
  },
11426
11817
  {
@@ -11540,7 +11931,7 @@ var methodsByCategory = {
11540
11931
  name: "getNodesWithAttribute",
11541
11932
  category: "DesignPageNode",
11542
11933
  signature: "getNodesWithAttribute(attribute: T): Promise<Node[]>",
11543
- description: 'Get the descendants of this node that support `attribute`. This\nreturns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
11934
+ description: 'Get the descendants of this node that support `attribute`.\n\nThis returns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
11544
11935
  references: ["T", "Node"]
11545
11936
  },
11546
11937
  {
@@ -11554,7 +11945,7 @@ var methodsByCategory = {
11554
11945
  name: "getNodesWithType",
11555
11946
  category: "DesignPageNode",
11556
11947
  signature: 'getNodesWithType(type: "FrameNode"): Promise<FrameNode[]>',
11557
- description: 'Get descendants of this node that match the given type. This can\nalso be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
11948
+ description: 'Get descendants of this node that match the given type.\n\nThis can also be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
11558
11949
  references: ["FrameNode"]
11559
11950
  },
11560
11951
  {
@@ -11568,7 +11959,7 @@ var methodsByCategory = {
11568
11959
  name: "getPluginData",
11569
11960
  category: "DesignPageNode",
11570
11961
  signature: "getPluginData(key: string): Promise<string | null>",
11571
- description: "Get plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
11962
+ description: "Get plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
11572
11963
  references: []
11573
11964
  },
11574
11965
  {
@@ -11589,7 +11980,7 @@ var methodsByCategory = {
11589
11980
  name: "navigateTo",
11590
11981
  category: "DesignPageNode",
11591
11982
  signature: 'navigateTo(opts?: Pick<NavigableOptions, "select" | "zoomIntoView">): Promise<void>',
11592
- description: "Navigate to this node. May switch modes to reveal the relevant view.",
11983
+ description: "Navigate to this node.\n\nMay switch modes to reveal the relevant view.",
11593
11984
  references: ["NavigableOptions"]
11594
11985
  },
11595
11986
  {
@@ -11610,21 +12001,21 @@ var methodsByCategory = {
11610
12001
  name: "setAttributes",
11611
12002
  category: "DesignPageNode",
11612
12003
  signature: 'setAttributes(update: Partial<NodeClassToEditableAttributes[(typeof this)[ClassKey]]>): Promise<(typeof this)[ClassKey] extends "UnknownNode" ? never : typeof this | null>',
11613
- description: 'Set the attributes of this node. Attributes are merged with existing\nvalues, so only the provided attributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
12004
+ description: 'Set the attributes of this node.\n\nAttributes are merged with existing values, so only the provided\nattributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
11614
12005
  references: []
11615
12006
  },
11616
12007
  {
11617
12008
  name: "setPluginData",
11618
12009
  category: "DesignPageNode",
11619
12010
  signature: "setPluginData(key: string, value: string | null): Promise<void>",
11620
- description: 'Set plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
12011
+ description: 'Set plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
11621
12012
  references: []
11622
12013
  },
11623
12014
  {
11624
12015
  name: "walk",
11625
12016
  category: "DesignPageNode",
11626
12017
  signature: "walk(this: AnyNode): AsyncGenerator<AnyNode>",
11627
- description: "Walk this node and its descendants recursively using an async\ngenerator. Yields nodes depth-first.",
12018
+ description: "Walk this node and its descendants recursively.\n\nUses an async generator. Yields nodes depth-first.",
11628
12019
  references: ["AnyNode"]
11629
12020
  },
11630
12021
  {
@@ -11977,14 +12368,14 @@ var methodsByCategory = {
11977
12368
  name: "aspectRatio",
11978
12369
  category: "FrameNode",
11979
12370
  signature: "aspectRatio: number | null",
11980
- description: "Width-to-height ratio (e.g. `1.5` for 3:2).\nSetting to `null` removes the aspect ratio constraint.\nSupported by FrameNode, ComponentInstanceNode.",
12371
+ description: "Width-to-height ratio (e.g. `1.5` for 3:2).\n\nSetting to `null` removes the aspect ratio constraint.\nSupported by FrameNode, ComponentInstanceNode.",
11981
12372
  references: []
11982
12373
  },
11983
12374
  {
11984
12375
  name: "backgroundColor",
11985
12376
  category: "FrameNode",
11986
12377
  signature: "backgroundColor: ColorStyle | string | null",
11987
- description: "Background color in RGBA format (e.g. `rgba(242, 59, 57, 1)`) or as a {@link ColorStyle} instance.\nSetting to `null` removes the background color. Supported by FrameNode.",
12378
+ description: "Background color in RGBA format (e.g. `rgba(242, 59, 57, 1)`) or as a {@link ColorStyle} instance.\n\nSetting to `null` removes the background color. Supported by FrameNode.",
11988
12379
  references: ["ColorStyle"]
11989
12380
  },
11990
12381
  {
@@ -12005,35 +12396,35 @@ var methodsByCategory = {
12005
12396
  name: "border",
12006
12397
  category: "FrameNode",
12007
12398
  signature: "border: Border | null",
12008
- description: 'Border properties including width, color, and style.\nStyles: `"solid"`, `"dashed"`, `"dotted"`, `"double"`.\nWidth can be per-side (e.g. `"1px 2px 3px 4px"`).\nSetting to `null` removes the border. Supported by FrameNode.',
12399
+ description: 'Border properties including width, color, and style.\n\nStyles: `"solid"`, `"dashed"`, `"dotted"`, `"double"`.\nWidth can be per-side (e.g. `"1px 2px 3px 4px"`).\nSetting to `null` removes the border. Supported by FrameNode.',
12009
12400
  references: ["Border"]
12010
12401
  },
12011
12402
  {
12012
12403
  name: "borderRadius",
12013
12404
  category: "FrameNode",
12014
12405
  signature: "borderRadius: BorderRadius",
12015
- description: 'Border radius for rounded corners. Single value (e.g. `"10px"` or `"50%"`)\nor per-corner (e.g. `"10px 20px 30px 40px"` for top-left, top-right, bottom-right, bottom-left).\nSetting to `null` removes the border radius. Supported by FrameNode.',
12406
+ description: 'Border radius for rounded corners.\n\nSingle value (e.g. `"10px"` or `"50%"`)\nor per-corner (e.g. `"10px 20px 30px 40px"` for top-left, top-right, bottom-right, bottom-left).\nSetting to `null` removes the border radius. Supported by FrameNode.',
12016
12407
  references: ["BorderRadius"]
12017
12408
  },
12018
12409
  {
12019
12410
  name: "bottom",
12020
12411
  category: "FrameNode",
12021
12412
  signature: "bottom: CSSDimension<CSSUnit.Pixel> | null",
12022
- description: 'Distance from bottom edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
12413
+ description: 'Distance from bottom edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
12023
12414
  references: ["CSSDimension", "CSSUnit.Pixel"]
12024
12415
  },
12025
12416
  {
12026
12417
  name: "centerX",
12027
12418
  category: "FrameNode",
12028
12419
  signature: "centerX: CSSDimension<CSSUnit.Percentage> | null",
12029
- description: 'Center anchor horizontal position as percentage (e.g. `"50%"`).\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
12420
+ description: 'Center anchor horizontal position as percentage (e.g. `"50%"`).\n\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
12030
12421
  references: ["CSSDimension", "CSSUnit.Percentage"]
12031
12422
  },
12032
12423
  {
12033
12424
  name: "centerY",
12034
12425
  category: "FrameNode",
12035
12426
  signature: "centerY: CSSDimension<CSSUnit.Percentage> | null",
12036
- description: 'Center anchor vertical position as percentage (e.g. `"50%"`).\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
12427
+ description: 'Center anchor vertical position as percentage (e.g. `"50%"`).\n\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
12037
12428
  references: ["CSSDimension", "CSSUnit.Percentage"]
12038
12429
  },
12039
12430
  {
@@ -12047,7 +12438,7 @@ var methodsByCategory = {
12047
12438
  name: "gap",
12048
12439
  category: "FrameNode",
12049
12440
  signature: 'gap: WithLayoutTrait["gap"]',
12050
- description: 'Spacing between items in a layout. Single value (e.g. `"10px"`) applies to both axes;\ntwo values (e.g. `"10px 20px"`) set horizontal and vertical separately.\nOnly works with layout enabled. Supported by FrameNode.',
12441
+ description: 'Spacing between items in a layout.\n\nSingle value (e.g. `"10px"`) applies to both axes;\ntwo values (e.g. `"10px 20px"`) set horizontal and vertical separately.\nOnly works with layout enabled. Supported by FrameNode.',
12051
12442
  references: []
12052
12443
  },
12053
12444
  {
@@ -12061,7 +12452,7 @@ var methodsByCategory = {
12061
12452
  name: "getNodesWithAttribute",
12062
12453
  category: "FrameNode",
12063
12454
  signature: "getNodesWithAttribute(attribute: T): Promise<Node[]>",
12064
- description: 'Get the descendants of this node that support `attribute`. This\nreturns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
12455
+ description: 'Get the descendants of this node that support `attribute`.\n\nThis returns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
12065
12456
  references: ["T", "Node"]
12066
12457
  },
12067
12458
  {
@@ -12075,7 +12466,7 @@ var methodsByCategory = {
12075
12466
  name: "getNodesWithType",
12076
12467
  category: "FrameNode",
12077
12468
  signature: 'getNodesWithType(type: "FrameNode"): Promise<FrameNode[]>',
12078
- description: 'Get descendants of this node that match the given type. This can\nalso be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
12469
+ description: 'Get descendants of this node that match the given type.\n\nThis can also be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
12079
12470
  references: ["FrameNode"]
12080
12471
  },
12081
12472
  {
@@ -12089,7 +12480,7 @@ var methodsByCategory = {
12089
12480
  name: "getPluginData",
12090
12481
  category: "FrameNode",
12091
12482
  signature: "getPluginData(key: string): Promise<string | null>",
12092
- description: "Get plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
12483
+ description: "Get plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
12093
12484
  references: []
12094
12485
  },
12095
12486
  {
@@ -12145,42 +12536,42 @@ var methodsByCategory = {
12145
12536
  name: "gridItemColumnSpan",
12146
12537
  category: "FrameNode",
12147
12538
  signature: 'gridItemColumnSpan: WithGridItemTrait["gridItemColumnSpan"]',
12148
- description: 'Number of columns to span, or `"all"` for all columns. For nodes inside a grid container. Defaults to `1`. Supported by FrameNode, TextNode.',
12539
+ description: 'Number of columns to span, or `"all"` for all columns.\n\nFor nodes inside a grid container. Defaults to `1`. Supported by FrameNode, TextNode.',
12149
12540
  references: []
12150
12541
  },
12151
12542
  {
12152
12543
  name: "gridItemFillCellHeight",
12153
12544
  category: "FrameNode",
12154
12545
  signature: 'gridItemFillCellHeight: WithGridItemTrait["gridItemFillCellHeight"]',
12155
- description: "Whether to fill the grid cell height. For nodes inside a grid container. Defaults to `true`. Supported by FrameNode, TextNode.",
12546
+ description: "Whether to fill the grid cell height.\n\nFor nodes inside a grid container. Defaults to `true`. Supported by FrameNode, TextNode.",
12156
12547
  references: []
12157
12548
  },
12158
12549
  {
12159
12550
  name: "gridItemFillCellWidth",
12160
12551
  category: "FrameNode",
12161
12552
  signature: 'gridItemFillCellWidth: WithGridItemTrait["gridItemFillCellWidth"]',
12162
- description: "Whether to fill the grid cell width. For nodes inside a grid container. Defaults to `true`. Supported by FrameNode, TextNode.",
12553
+ description: "Whether to fill the grid cell width.\n\nFor nodes inside a grid container. Defaults to `true`. Supported by FrameNode, TextNode.",
12163
12554
  references: []
12164
12555
  },
12165
12556
  {
12166
12557
  name: "gridItemHorizontalAlignment",
12167
12558
  category: "FrameNode",
12168
12559
  signature: 'gridItemHorizontalAlignment: WithGridItemTrait["gridItemHorizontalAlignment"]',
12169
- description: 'Horizontal alignment within grid cell. For nodes inside a grid container. Defaults to `"center"`. Supported by FrameNode, TextNode.',
12560
+ description: 'Horizontal alignment within grid cell.\n\nFor nodes inside a grid container. Defaults to `"center"`. Supported by FrameNode, TextNode.',
12170
12561
  references: []
12171
12562
  },
12172
12563
  {
12173
12564
  name: "gridItemRowSpan",
12174
12565
  category: "FrameNode",
12175
12566
  signature: 'gridItemRowSpan: WithGridItemTrait["gridItemRowSpan"]',
12176
- description: "Number of rows to span. For nodes inside a grid container. Defaults to `1`. Supported by FrameNode, TextNode.",
12567
+ description: "Number of rows to span.\n\nFor nodes inside a grid container. Defaults to `1`. Supported by FrameNode, TextNode.",
12177
12568
  references: []
12178
12569
  },
12179
12570
  {
12180
12571
  name: "gridItemVerticalAlignment",
12181
12572
  category: "FrameNode",
12182
12573
  signature: 'gridItemVerticalAlignment: WithGridItemTrait["gridItemVerticalAlignment"]',
12183
- description: 'Vertical alignment within grid cell. For nodes inside a grid container. Defaults to `"center"`. Supported by FrameNode, TextNode.',
12574
+ description: 'Vertical alignment within grid cell.\n\nFor nodes inside a grid container. Defaults to `"center"`. Supported by FrameNode, TextNode.',
12184
12575
  references: []
12185
12576
  },
12186
12577
  {
@@ -12208,14 +12599,14 @@ var methodsByCategory = {
12208
12599
  name: "height",
12209
12600
  category: "FrameNode",
12210
12601
  signature: "height: HeightLength | null",
12211
- description: 'Height of the node. Accepts pixel, percentage, fraction, viewport-height values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
12602
+ description: 'Height of the node.\n\nAccepts pixel, percentage, fraction, viewport-height values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
12212
12603
  references: ["HeightLength"]
12213
12604
  },
12214
12605
  {
12215
12606
  name: "imageRendering",
12216
12607
  category: "FrameNode",
12217
12608
  signature: "imageRendering: ImageRendering | null",
12218
- description: 'How images should be rendered when scaled: `"auto"` or `"pixelated"`.\nOnly applies to frames with image backgrounds.\nSetting to `null` uses default rendering. Supported by FrameNode.',
12609
+ description: 'How images should be rendered when scaled: `"auto"` or `"pixelated"`.\n\nOnly applies to frames with image backgrounds.\nSetting to `null` uses default rendering. Supported by FrameNode.',
12219
12610
  references: ["ImageRendering"]
12220
12611
  },
12221
12612
  {
@@ -12236,35 +12627,63 @@ var methodsByCategory = {
12236
12627
  name: "layout",
12237
12628
  category: "FrameNode",
12238
12629
  signature: 'layout: WithLayoutTrait["layout"]',
12239
- description: "Enables stack or grid layout. Setting to `null` disables any applied layout.\nOperation is deferred and applied after the current update cycle. Supported by FrameNode.",
12630
+ description: "Enables stack or grid layout.\n\nSetting to `null` disables any applied layout.\nOperation is deferred and applied after the current update cycle. Supported by FrameNode.",
12240
12631
  references: []
12241
12632
  },
12242
12633
  {
12243
12634
  name: "left",
12244
12635
  category: "FrameNode",
12245
12636
  signature: "left: CSSDimension<CSSUnit.Pixel> | null",
12246
- description: 'Distance from left edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
12637
+ description: 'Distance from left edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
12247
12638
  references: ["CSSDimension", "CSSUnit.Pixel"]
12248
12639
  },
12249
12640
  {
12250
12641
  name: "link",
12251
12642
  category: "FrameNode",
12252
- signature: "link: string | null",
12253
- description: 'URL or internal page link. External: `"https://example.com"`, internal: `"/about"`,\nemail: `"mailto:user@example.com"`. Setting to `null` removes the link.\nSupported by FrameNode, TextNode.',
12643
+ signature: 'link: WithLinkTrait["link"]',
12644
+ description: 'URL or internal page link.\n\nExternal: `"https://example.com"`, internal: `"/about"`,\nemail: `"mailto:user@example.com"`. Setting to `null` removes the link.\nSupported by FrameNode, TextNode.',
12645
+ references: []
12646
+ },
12647
+ {
12648
+ name: "linkClickTrackingId",
12649
+ category: "FrameNode",
12650
+ signature: 'linkClickTrackingId: WithLinkTrait["linkClickTrackingId"]',
12651
+ description: "Click tracking identifier for analytics.\nSupported by FrameNode, TextNode.",
12254
12652
  references: []
12255
12653
  },
12256
12654
  {
12257
12655
  name: "linkOpenInNewTab",
12258
12656
  category: "FrameNode",
12259
- signature: "linkOpenInNewTab: boolean | null",
12260
- description: "Whether to open the link in a new tab. Default is automatically determined based on link type.\nSupported by FrameNode, TextNode.",
12657
+ signature: 'linkOpenInNewTab: WithLinkTrait["linkOpenInNewTab"]',
12658
+ description: "Whether to open the link in a new tab.\n\nDefault is automatically determined based on link type.\nSupported by FrameNode, TextNode.",
12659
+ references: []
12660
+ },
12661
+ {
12662
+ name: "linkPreserveParams",
12663
+ category: "FrameNode",
12664
+ signature: 'linkPreserveParams: WithLinkTrait["linkPreserveParams"]',
12665
+ description: "Whether to preserve URL query parameters when navigating.\nSupported by FrameNode, TextNode.",
12666
+ references: []
12667
+ },
12668
+ {
12669
+ name: "linkRelValues",
12670
+ category: "FrameNode",
12671
+ signature: 'linkRelValues: WithLinkTrait["linkRelValues"]',
12672
+ description: "Array of rel attribute values for the link.\nSupported by FrameNode, TextNode.",
12673
+ references: []
12674
+ },
12675
+ {
12676
+ name: "linkSmoothScroll",
12677
+ category: "FrameNode",
12678
+ signature: 'linkSmoothScroll: WithLinkTrait["linkSmoothScroll"]',
12679
+ description: "Whether to use smooth scrolling for scroll-to-section links.\nSupported by FrameNode, TextNode.",
12261
12680
  references: []
12262
12681
  },
12263
12682
  {
12264
12683
  name: "locked",
12265
12684
  category: "FrameNode",
12266
12685
  signature: "locked: boolean",
12267
- description: "Whether the node is locked for editing. Defaults to `false`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
12686
+ description: "Whether the node is locked for editing.\n\nDefaults to `false`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
12268
12687
  references: []
12269
12688
  },
12270
12689
  {
@@ -12299,49 +12718,49 @@ var methodsByCategory = {
12299
12718
  name: "name",
12300
12719
  category: "FrameNode",
12301
12720
  signature: "name: string | null",
12302
- description: "The name of the node displayed in the layers panel.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode,\nComponentNode, VectorSetNode, VectorSetItemNode.",
12721
+ description: "The name of the node displayed in the layers panel.\n\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode,\nComponentNode, VectorSetNode, VectorSetItemNode.",
12303
12722
  references: []
12304
12723
  },
12305
12724
  {
12306
12725
  name: "navigateTo",
12307
12726
  category: "FrameNode",
12308
12727
  signature: 'navigateTo(opts?: Pick<NavigableOptions, "select" | "zoomIntoView">): Promise<void>',
12309
- description: "Navigate to this node. May switch modes to reveal the relevant view.",
12728
+ description: "Navigate to this node.\n\nMay switch modes to reveal the relevant view.",
12310
12729
  references: ["NavigableOptions"]
12311
12730
  },
12312
12731
  {
12313
12732
  name: "opacity",
12314
12733
  category: "FrameNode",
12315
12734
  signature: "opacity: number",
12316
- description: "Opacity of the node, from `0` (fully transparent) to `1` (fully opaque). Defaults to `1`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
12735
+ description: "Opacity of the node, from `0` (fully transparent) to `1` (fully opaque).\n\nDefaults to `1`. Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
12317
12736
  references: []
12318
12737
  },
12319
12738
  {
12320
12739
  name: "overflow",
12321
12740
  category: "FrameNode",
12322
12741
  signature: 'overflow: WithOverflowTrait["overflow"]',
12323
- description: "Controls how content that exceeds the element's box is handled.\nSetting to `null` removes the overflow property. Will overwrite `overflowX` or `overflowY`.\nSupported by FrameNode, TextNode.",
12742
+ description: "Controls how content that exceeds the element's box is handled.\n\nSetting to `null` removes the overflow property. Will overwrite `overflowX` or `overflowY`.\nSupported by FrameNode, TextNode.",
12324
12743
  references: []
12325
12744
  },
12326
12745
  {
12327
12746
  name: "overflowX",
12328
12747
  category: "FrameNode",
12329
12748
  signature: 'overflowX: WithOverflowTrait["overflowX"]',
12330
- description: "Controls horizontal overflow behavior.\nSetting to `null` removes the overflow X property. Supported by FrameNode, TextNode.",
12749
+ description: "Controls horizontal overflow behavior.\n\nSetting to `null` removes the overflow X property. Supported by FrameNode, TextNode.",
12331
12750
  references: []
12332
12751
  },
12333
12752
  {
12334
12753
  name: "overflowY",
12335
12754
  category: "FrameNode",
12336
12755
  signature: 'overflowY: WithOverflowTrait["overflowY"]',
12337
- description: "Controls vertical overflow behavior.\nSetting to `null` removes the overflow Y property. Supported by FrameNode, TextNode.",
12756
+ description: "Controls vertical overflow behavior.\n\nSetting to `null` removes the overflow Y property. Supported by FrameNode, TextNode.",
12338
12757
  references: []
12339
12758
  },
12340
12759
  {
12341
12760
  name: "padding",
12342
12761
  category: "FrameNode",
12343
12762
  signature: 'padding: WithLayoutTrait["padding"]',
12344
- description: 'Inner spacing of a container with layout. Single value (e.g. `"10px"`) applies to all sides;\nfour values (e.g. `"10px 20px 30px 40px"`) set top, right, bottom, left.\nOnly works with layout enabled. Supported by FrameNode.',
12763
+ description: 'Inner spacing of a container with layout.\n\nSingle value (e.g. `"10px"`) applies to all sides;\nfour values (e.g. `"10px 20px 30px 40px"`) set top, right, bottom, left.\nOnly works with layout enabled. Supported by FrameNode.',
12345
12764
  references: []
12346
12765
  },
12347
12766
  {
@@ -12362,14 +12781,14 @@ var methodsByCategory = {
12362
12781
  name: "right",
12363
12782
  category: "FrameNode",
12364
12783
  signature: "right: CSSDimension<CSSUnit.Pixel> | null",
12365
- description: 'Distance from right edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
12784
+ description: 'Distance from right edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
12366
12785
  references: ["CSSDimension", "CSSUnit.Pixel"]
12367
12786
  },
12368
12787
  {
12369
12788
  name: "rotation",
12370
12789
  category: "FrameNode",
12371
12790
  signature: "rotation: number",
12372
- description: "Rotation angle in degrees. Defaults to `0`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
12791
+ description: "Rotation angle in degrees.\n\nDefaults to `0`. Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
12373
12792
  references: []
12374
12793
  },
12375
12794
  {
@@ -12383,14 +12802,14 @@ var methodsByCategory = {
12383
12802
  name: "setAttributes",
12384
12803
  category: "FrameNode",
12385
12804
  signature: 'setAttributes(update: Partial<NodeClassToEditableAttributes[(typeof this)[ClassKey]]>): Promise<(typeof this)[ClassKey] extends "UnknownNode" ? never : typeof this | null>',
12386
- description: 'Set the attributes of this node. Attributes are merged with existing\nvalues, so only the provided attributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
12805
+ description: 'Set the attributes of this node.\n\nAttributes are merged with existing values, so only the provided\nattributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
12387
12806
  references: []
12388
12807
  },
12389
12808
  {
12390
12809
  name: "setPluginData",
12391
12810
  category: "FrameNode",
12392
12811
  signature: "setPluginData(key: string, value: string | null): Promise<void>",
12393
- description: 'Set plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
12812
+ description: 'Set plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
12394
12813
  references: []
12395
12814
  },
12396
12815
  {
@@ -12425,35 +12844,35 @@ var methodsByCategory = {
12425
12844
  name: "top",
12426
12845
  category: "FrameNode",
12427
12846
  signature: "top: CSSDimension<CSSUnit.Pixel> | null",
12428
- description: 'Distance from top edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
12847
+ description: 'Distance from top edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
12429
12848
  references: ["CSSDimension", "CSSUnit.Pixel"]
12430
12849
  },
12431
12850
  {
12432
12851
  name: "visible",
12433
12852
  category: "FrameNode",
12434
12853
  signature: "visible: boolean",
12435
- description: "Whether the node is visible on the canvas. Defaults to `true`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
12854
+ description: "Whether the node is visible on the canvas.\n\nDefaults to `true`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
12436
12855
  references: []
12437
12856
  },
12438
12857
  {
12439
12858
  name: "walk",
12440
12859
  category: "FrameNode",
12441
12860
  signature: "walk(this: AnyNode): AsyncGenerator<AnyNode>",
12442
- description: "Walk this node and its descendants recursively using an async\ngenerator. Yields nodes depth-first.",
12861
+ description: "Walk this node and its descendants recursively.\n\nUses an async generator. Yields nodes depth-first.",
12443
12862
  references: ["AnyNode"]
12444
12863
  },
12445
12864
  {
12446
12865
  name: "width",
12447
12866
  category: "FrameNode",
12448
12867
  signature: "width: WidthLength | null",
12449
- description: 'Width of the node. Accepts pixel, percentage, fraction values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
12868
+ description: 'Width of the node.\n\nAccepts pixel, percentage, fraction values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
12450
12869
  references: ["WidthLength"]
12451
12870
  },
12452
12871
  {
12453
12872
  name: "zIndex",
12454
12873
  category: "FrameNode",
12455
12874
  signature: 'zIndex: WithZIndexTrait["zIndex"]',
12456
- description: "Stacking order of positioned elements. Higher values appear on top of lower values.\nSetting to `null` removes the z-index property. Supported by FrameNode, TextNode.",
12875
+ description: "Stacking order of positioned elements.\n\nHigher values appear on top of lower values.\nSetting to `null` removes the z-index property. Supported by FrameNode, TextNode.",
12457
12876
  references: []
12458
12877
  },
12459
12878
  {
@@ -12493,6 +12912,13 @@ var methodsByCategory = {
12493
12912
  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.',
12494
12913
  references: []
12495
12914
  },
12915
+ {
12916
+ name: "[$framerApiOnly.reviewChangesForAgent]",
12917
+ category: "framer",
12918
+ signature: "[$framerApiOnly.reviewChangesForAgent](options?: { pagePath?: string; }): Promise<unknown>",
12919
+ 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.",
12920
+ references: []
12921
+ },
12496
12922
  {
12497
12923
  name: "[$framerInternal.initialState]",
12498
12924
  category: "framer",
@@ -12518,7 +12944,7 @@ var methodsByCategory = {
12518
12944
  name: "addComponentInstance",
12519
12945
  category: "framer",
12520
12946
  signature: "addComponentInstance({ url, attributes, parentId, }: AddComponentInstanceOptions): Promise<ComponentInstanceNode>",
12521
- description: "Add a component instance by module URL.\n\n@param url - The component module URL. Can be copied from the components panel.\n@param attributes - Optional component attributes.\n\n@returns The newly created component instance node.",
12947
+ description: "Add a component instance by module URL.\n\n@param url - The component module URL. Can be copied from the components panel.\n@param attributes - Optional component attributes.\n\n@returns The newly created component instance node.\n@category canvas",
12522
12948
  references: ["AddComponentInstanceOptions", "ComponentInstanceNode"]
12523
12949
  },
12524
12950
  {
@@ -12535,42 +12961,42 @@ var methodsByCategory = {
12535
12961
  name: "addDetachedComponentLayers",
12536
12962
  category: "framer",
12537
12963
  signature: "addDetachedComponentLayers({ url, layout, attributes }: AddDetachedComponentLayersOptions): Promise<FrameNode>",
12538
- description: "Adds the layers of a component by module URL.",
12964
+ description: "Adds the layers of a component by module URL.\n@category canvas",
12539
12965
  references: ["AddDetachedComponentLayersOptions", "FrameNode"]
12540
12966
  },
12541
12967
  {
12542
12968
  name: "addImage",
12543
12969
  category: "framer",
12544
12970
  signature: "addImage(image: NamedImageAssetInput | File): Promise<void>",
12545
- description: "Upload an image, and insert on the canvas.",
12971
+ description: "Upload an image, and insert on the canvas.\n@category canvas",
12546
12972
  references: ["NamedImageAssetInput", "File"]
12547
12973
  },
12548
12974
  {
12549
12975
  name: "addImages",
12550
12976
  category: "framer",
12551
12977
  signature: "addImages(images: readonly NamedImageAssetInput[]): Promise<void>",
12552
- description: "Add multiple images, replacing the selected images, or insert on the canvas.",
12978
+ description: "Add multiple images, replacing the selected images, or insert on the canvas.\n@category canvas",
12553
12979
  references: ["NamedImageAssetInput"]
12554
12980
  },
12555
12981
  {
12556
12982
  name: "addRedirects",
12557
12983
  category: "framer",
12558
12984
  signature: "addRedirects(redirects: RedirectInput[]): Promise<Redirect[]>",
12559
- description: 'Add new redirects or update existing ones if their IDs match\n\n`from` paths can contain wildcards (`*`) which match any string, and\ncaptured groups can be referenced in the `to` path using `:1`, `:2`,\netc.\n\nThrows a `FramerPluginError` when the user lacks Site Settings permissions,\nwhen the project plan does not include Redirects, or when the maximum\nredirect count (2500) is reached.\n\n@param redirects - An array of redirect objects to add.\n@returns The added Redirects.\n\n@example\n```ts\nawait framer.addRedirects([\n { from: "/business", to: "/enterprise", expandToAllLocales: true },\n { from: "/posts/*", to: "/blog/:1", expandToAllLocales: false },\n])\n```',
12985
+ description: 'Add new redirects or update existing ones if their IDs match\n\n`from` paths can contain wildcards (`*`) which match any string, and\ncaptured groups can be referenced in the `to` path using `:1`, `:2`,\netc.\n\nThrows a `FramerPluginError` when the user lacks Site Settings permissions,\nwhen the project plan does not include Redirects, or when the maximum\nredirect count (2500) is reached.\n\n@param redirects - An array of redirect objects to add.\n@returns The added Redirects.\n\n@example\n```ts\nawait framer.addRedirects([\n { from: "/business", to: "/enterprise", expandToAllLocales: true },\n { from: "/posts/*", to: "/blog/:1", expandToAllLocales: false },\n])\n```\n@category settings',
12560
12986
  references: ["RedirectInput", "Redirect"]
12561
12987
  },
12562
12988
  {
12563
12989
  name: "addSVG",
12564
12990
  category: "framer",
12565
12991
  signature: "addSVG(svg: SVGData): Promise<void>",
12566
- description: "Add an SVG, replacing the selected SVG, or insert on the canvas.",
12992
+ description: "Add an SVG, replacing the selected SVG, or insert on the canvas.\n@category canvas",
12567
12993
  references: ["SVGData"]
12568
12994
  },
12569
12995
  {
12570
12996
  name: "addText",
12571
12997
  category: "framer",
12572
12998
  signature: "addText(text: string, options?: AddTextOptions): Promise<void>",
12573
- description: "Add a new text node to the canvas.",
12999
+ description: "Add a new text node to the canvas.\n@category canvas",
12574
13000
  references: ["AddTextOptions"]
12575
13001
  },
12576
13002
  {
@@ -12584,7 +13010,7 @@ var methodsByCategory = {
12584
13010
  name: "cloneNode",
12585
13011
  category: "framer",
12586
13012
  signature: "cloneNode(nodeId: NodeId): Promise<AnyNode | null>",
12587
- description: "Clone a node.",
13013
+ description: "Clone a node.\n@category canvas",
12588
13014
  references: ["AnyNode"]
12589
13015
  },
12590
13016
  {
@@ -12601,21 +13027,21 @@ var methodsByCategory = {
12601
13027
  name: "createCodeFile",
12602
13028
  category: "framer",
12603
13029
  signature: "createCodeFile(name: string, code: string, options?: { editViaPlugin?: boolean; }): Promise<CodeFile>",
12604
- description: 'Create a new code file in the project.\n\n@param name - The name of the code file (including extension).\n@param code - The initial content of the code file.\n@param options - Optional settings. `editViaPlugin`: when `true`, the "Edit Code" UI action will open the plugin which created the code file.\n@returns The newly created code file instance.\n\n@example\n```ts\nconst newFile = await framer.createCodeFile(\n "MyComponent",\n `export default function MyComponent() {\n return <div>Hello World</div>\n }`\n)\n```',
13030
+ description: 'Create a new code file in the project.\n\n@param name - The name of the code file (including extension).\n@param code - The initial content of the code file.\n@param options - Optional settings. `editViaPlugin`: when `true`, the "Edit Code" UI action will open the plugin which created the code file.\n@returns The newly created code file instance.\n\n@example\n```ts\nconst newFile = await framer.createCodeFile(\n "MyComponent",\n `export default function MyComponent() {\n return <div>Hello World</div>\n }`\n)\n```\n@category code-files',
12605
13031
  references: ["CodeFile"]
12606
13032
  },
12607
13033
  {
12608
13034
  name: "createCollection",
12609
13035
  category: "framer",
12610
13036
  signature: "createCollection(name: string): Promise<Collection>",
12611
- description: "Create a new collection.\n\n@param name - The name to give the new collection.",
13037
+ description: "Create a new collection.\n\n@param name - The name to give the new collection.\n@category cms",
12612
13038
  references: ["Collection"]
12613
13039
  },
12614
13040
  {
12615
13041
  name: "createColorStyle",
12616
13042
  category: "framer",
12617
13043
  signature: "createColorStyle(attributes: ColorStyleAttributes): Promise<ColorStyle>",
12618
- description: "Add a new color style to the project.",
13044
+ description: "Add a new color style to the project.\n@category canvas",
12619
13045
  references: ["ColorStyleAttributes", "ColorStyle"]
12620
13046
  },
12621
13047
  {
@@ -12629,14 +13055,14 @@ var methodsByCategory = {
12629
13055
  name: "createDesignPage",
12630
13056
  category: "framer",
12631
13057
  signature: "createDesignPage(pageName: string): Promise<DesignPageNode>",
12632
- description: 'Create a new design page.\n\nIf you want to open the newly created design page, you can `.navigateTo()` the page after creation.\n\n@param pageName - The name for the new design page.\n\n@example\n```ts\nconst designPage = await framer.createDesignPage("About")\nawait designPage.navigateTo()\n```',
13058
+ description: 'Create a new design page.\n\nIf you want to open the newly created design page, you can `.navigateTo()` the page after creation.\n\n@param pageName - The name for the new design page.\n\n@example\n```ts\nconst designPage = await framer.createDesignPage("About")\nawait designPage.navigateTo()\n```\n@category canvas',
12633
13059
  references: ["DesignPageNode"]
12634
13060
  },
12635
13061
  {
12636
13062
  name: "createFrameNode",
12637
13063
  category: "framer",
12638
13064
  signature: "createFrameNode(attributes: Partial<EditableFrameNodeAttributes>, parentId?: string): Promise<FrameNode | null>",
12639
- description: "Create a new node on the canvas.",
13065
+ description: "Create a new node on the canvas.\n@category canvas",
12640
13066
  references: ["EditableFrameNodeAttributes", "FrameNode"]
12641
13067
  },
12642
13068
  {
@@ -12650,7 +13076,7 @@ var methodsByCategory = {
12650
13076
  name: "createManagedCollection",
12651
13077
  category: "framer",
12652
13078
  signature: "createManagedCollection(name: string): Promise<ManagedCollection>",
12653
- description: "Add a new plugin-managed CMS Collection.\n\nIf a name is provided which matches an existing Collection, the promise will reject.\n\n@param name - The name to give the new collection.\n\n@example\n```ts\nconst newCollection = await framer.createManagedCollection(name)\n```",
13079
+ description: "Add a new plugin-managed CMS Collection.\n\nIf a name is provided which matches an existing Collection, the promise will reject.\n\n@param name - The name to give the new collection.\n\n@example\n```ts\nconst newCollection = await framer.createManagedCollection(name)\n```\n@category cms",
12654
13080
  references: ["ManagedCollection"]
12655
13081
  },
12656
13082
  {
@@ -12664,14 +13090,14 @@ var methodsByCategory = {
12664
13090
  name: "createTextStyle",
12665
13091
  category: "framer",
12666
13092
  signature: "createTextStyle(attributes: TextStyleAttributes): Promise<TextStyle>",
12667
- description: "Add a new text style to the project.",
13093
+ description: "Add a new text style to the project.\n@category canvas",
12668
13094
  references: ["TextStyleAttributes", "TextStyle"]
12669
13095
  },
12670
13096
  {
12671
13097
  name: "createWebPage",
12672
13098
  category: "framer",
12673
13099
  signature: "createWebPage(pagePath: string): Promise<WebPageNode>",
12674
- description: 'Create a new web page.\n\nIf you want to open the newly created web page, you can `.navigateTo()` the page after creation.\n\n@param pagePath - The path for the new web page (e.g., "/about").\n\n@example\n```ts\nconst webPage = await framer.createWebPage("/about")\nawait webPage.navigateTo()\n```',
13100
+ description: 'Create a new web page.\n\nIf you want to open the newly created web page, you can `.navigateTo()` the page after creation.\n\n@param pagePath - The path for the new web page (e.g., "/about").\n\n@example\n```ts\nconst webPage = await framer.createWebPage("/about")\nawait webPage.navigateTo()\n```\n@category canvas',
12675
13101
  references: ["WebPageNode"]
12676
13102
  },
12677
13103
  {
@@ -12713,7 +13139,7 @@ var methodsByCategory = {
12713
13139
  name: "getCanvasRoot",
12714
13140
  category: "framer",
12715
13141
  signature: "getCanvasRoot(): Promise<CanvasRootNode>",
12716
- description: "Get the root of the current canvas.",
13142
+ description: "Get the root of the current canvas.\n@category canvas",
12717
13143
  references: ["CanvasRootNode"]
12718
13144
  },
12719
13145
  {
@@ -12734,70 +13160,70 @@ var methodsByCategory = {
12734
13160
  name: "getChildren",
12735
13161
  category: "framer",
12736
13162
  signature: "getChildren(nodeId: NodeId): Promise<CanvasNode[]>",
12737
- description: "Get the children of a node.",
13163
+ description: "Get the children of a node.\n@category canvas",
12738
13164
  references: ["CanvasNode"]
12739
13165
  },
12740
13166
  {
12741
13167
  name: "getCodeFile",
12742
13168
  category: "framer",
12743
13169
  signature: "getCodeFile(id: string): Promise<CodeFile | null>",
12744
- description: 'Get a specific code file by its ID.\n\n@param id - The unique identifier of the code file.\n@returns The CodeFile instance or `null` if not found.\n\n@example\n```ts\nconst codeFile = await framer.getCodeFile("code-file-id")\n```',
13170
+ description: 'Get a specific code file by its ID.\n\n@param id - The unique identifier of the code file.\n@returns The CodeFile instance or `null` if not found.\n\n@example\n```ts\nconst codeFile = await framer.getCodeFile("code-file-id")\n```\n@category code-files',
12745
13171
  references: ["CodeFile"]
12746
13172
  },
12747
13173
  {
12748
13174
  name: "getCodeFiles",
12749
13175
  category: "framer",
12750
13176
  signature: "getCodeFiles(): Promise<readonly CodeFile[]>",
12751
- description: "Get all code files in the project.\n\n@returns An array of all CodeFile instances.\n\n@example\n```ts\nconst allFiles = await framer.getCodeFiles()\nconsole.log(`Project has ${allFiles.length} code files`)\n```",
13177
+ description: "Get all code files in the project.\n\n@returns An array of all CodeFile instances.\n\n@example\n```ts\nconst allFiles = await framer.getCodeFiles()\nconsole.log(`Project has ${allFiles.length} code files`)\n```\n@category code-files",
12752
13178
  references: ["CodeFile"]
12753
13179
  },
12754
13180
  {
12755
13181
  name: "getCollection",
12756
13182
  category: "framer",
12757
13183
  signature: "getCollection(id: NodeId): Promise<Collection | null>",
12758
- description: "Get a collection by its id.",
13184
+ description: "Get a collection by its id.\n@category cms",
12759
13185
  references: ["Collection"]
12760
13186
  },
12761
13187
  {
12762
13188
  name: "getCollections",
12763
13189
  category: "framer",
12764
13190
  signature: "getCollections(): Promise<Collection[]>",
12765
- description: "Get all Collections in the project, both managed and unmanaged.\n\n@example\n```ts\nconst collections = await framer.getCollections()\n```",
13191
+ description: "Get all Collections in the project, both managed and unmanaged.\n\n@example\n```ts\nconst collections = await framer.getCollections()\n```\n@category cms",
12766
13192
  references: ["Collection"]
12767
13193
  },
12768
13194
  {
12769
13195
  name: "getColorStyle",
12770
13196
  category: "framer",
12771
13197
  signature: "getColorStyle(id: NodeId): Promise<ColorStyle | null>",
12772
- description: "Get a specific color style.",
13198
+ description: "Get a specific color style.\n@category canvas",
12773
13199
  references: ["ColorStyle"]
12774
13200
  },
12775
13201
  {
12776
13202
  name: "getColorStyles",
12777
13203
  category: "framer",
12778
13204
  signature: "getColorStyles(): Promise<ColorStyle[]>",
12779
- description: "Get all color styles in the project.",
13205
+ description: "Get all color styles in the project.\n@category canvas",
12780
13206
  references: ["ColorStyle"]
12781
13207
  },
12782
13208
  {
12783
13209
  name: "getCurrentUser",
12784
13210
  category: "framer",
12785
13211
  signature: "getCurrentUser(): Promise<User>",
12786
- description: "Get information about the user that's interacting with the plugin.\n\n@example\n```ts\nconst user = await framer.getCurrentUser();\n```",
13212
+ description: "Get information about the user that's interacting with the plugin.\n\n@example\n```ts\nconst user = await framer.getCurrentUser();\n```\n@category user",
12787
13213
  references: ["User"]
12788
13214
  },
12789
13215
  {
12790
13216
  name: "getCustomCode",
12791
13217
  category: "framer",
12792
13218
  signature: "getCustomCode(): Promise<CustomCode>",
12793
- description: "Get custom code settings set by the plugin. Your plugin can detect if\ncustom code was set and whether the user has disabled it.\n\n@example\n```ts\nconst customCode = await framer.getCustomCode()\nif (customCode.bodyStart.disabled) {\n // Custom code was disabled by the user in settings\n}\n```",
13219
+ description: "Get custom code settings set by the plugin.\n\nYour plugin can detect if custom code was set and whether the user has\ndisabled it.\n\n@example\n```ts\nconst customCode = await framer.getCustomCode()\nif (customCode.bodyStart.disabled) {\n // Custom code was disabled by the user in settings\n}\n```\n@category code-files",
12794
13220
  references: ["CustomCode"]
12795
13221
  },
12796
13222
  {
12797
13223
  name: "getDefaultLocale",
12798
13224
  category: "framer",
12799
13225
  signature: "getDefaultLocale(): Promise<Locale>",
12800
- description: "Get the default locale of the project.\n\n@example\n```ts\nconst defaultLocale = await framer.getDefaultLocale()\n```",
13226
+ description: "Get the default locale of the project.\n\n@example\n```ts\nconst defaultLocale = await framer.getDefaultLocale()\n```\n@category localization",
12801
13227
  references: ["Locale"]
12802
13228
  },
12803
13229
  {
@@ -12811,21 +13237,21 @@ var methodsByCategory = {
12811
13237
  name: "getFont",
12812
13238
  category: "framer",
12813
13239
  signature: "getFont(family: string, attributes?: FontAttributes): Promise<Font | null>",
12814
- description: 'Get a specific font from a family by name. This is not case sensitive.\nBy default, returns a font with normal weight and style. Returns `null`\nif the font does not exist or lacks the requested weight/style combination.\n\nNote: Custom fonts are not available to plugins.\n\n@param family - The font family name (e.g., `"Noto Sans"`).\n@param attributes - Optional weight and style attributes.\n@returns The matched font or `null` if not found.\n\n@example\n```ts\n// Get Noto Sans with default weight (400) and normal style\nconst font = await framer.getFont("Noto Sans")\n\n// Get Noto Sans with a specific weight and style\nconst font = await framer.getFont("Noto Sans", {\n weight: 800,\n style: "italic"\n})\n```',
13240
+ description: 'Get a specific font from a family by name.\n\nThis is not case sensitive. By default, returns a font with normal weight\nand style. Returns `null` if the font does not exist or lacks the\nrequested weight/style combination.\n\nNote: Custom fonts are not available to plugins.\n\n@param family - The font family name (e.g., `"Noto Sans"`).\n@param attributes - Optional weight and style attributes.\n@returns The matched font or `null` if not found.\n\n@example\n```ts\n// Get Noto Sans with default weight (400) and normal style\nconst font = await framer.getFont("Noto Sans")\n\n// Get Noto Sans with a specific weight and style\nconst font = await framer.getFont("Noto Sans", {\n weight: 800,\n style: "italic"\n})\n```\n@category canvas',
12815
13241
  references: ["FontAttributes", "Font"]
12816
13242
  },
12817
13243
  {
12818
13244
  name: "getFonts",
12819
13245
  category: "framer",
12820
13246
  signature: "getFonts(): Promise<Font[]>",
12821
- description: "Get all available fonts. Unlike the Font Picker which groups fonts by\ntypeface, this lists individual fonts for each weight and style (each\nrepresenting a separate font 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```",
13247
+ 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",
12822
13248
  references: ["Font"]
12823
13249
  },
12824
13250
  {
12825
13251
  name: "getImage",
12826
13252
  category: "framer",
12827
13253
  signature: "getImage(): Promise<ImageAsset | null>",
12828
- description: "Get the image of the current selection or `null` if there is no image.\n\nIn `editImage` mode, this returns the image the user already has set,\nwhich your plugin can then modify.",
13254
+ description: "Get the image of the current selection or `null` if there is no image.\n\nIn `editImage` mode, this returns the image the user already has set,\nwhich your plugin can then modify.\n@category canvas",
12829
13255
  references: ["ImageAsset"]
12830
13256
  },
12831
13257
  {
@@ -12846,105 +13272,105 @@ var methodsByCategory = {
12846
13272
  name: "getLocales",
12847
13273
  category: "framer",
12848
13274
  signature: "getLocales(): Promise<readonly Locale[]>",
12849
- description: "Get all Locales in the project.\n\nDoes not include the default Locale. See `getDefaultLocale`.\n\n@example\n```ts\nconst locales = await framer.getLocales()\n```",
13275
+ description: "Get all Locales in the project.\n\nDoes not include the default Locale. See `getDefaultLocale`.\n\n@example\n```ts\nconst locales = await framer.getLocales()\n```\n@category localization",
12850
13276
  references: ["Locale"]
12851
13277
  },
12852
13278
  {
12853
13279
  name: "getLocalizationGroups",
12854
13280
  category: "framer",
12855
- signature: "getLocalizationGroups(): Promise<readonly LocalizationGroup[]>",
12856
- description: "Get all Localization Groups in the project.\n\n@example\n```ts\nconst groups = await framer.getLocalizationGroups()\n\nfor (const group of groups) {\n console.log(`Group: ${group.name}`)\n\n for (const source of group.sources) {\n console.log(`Source: ${source.value}`)\n }\n}\n```",
12857
- references: ["LocalizationGroup"]
13281
+ signature: "getLocalizationGroups(filter?: GetLocalizationGroupsFilter): Promise<readonly LocalizationGroup[]>",
13282
+ description: 'Get Localization Groups in the project, optionally filtered.\n\n@param filter - Optional filter to narrow down the returned groups.\n\n@example\n```ts\n// Get all groups\nconst groups = await framer.getLocalizationGroups()\n\n// Get only page groups\nconst pageGroups = await framer.getLocalizationGroups({ type: "page" })\n\n// Get specific groups by ID\nconst specific = await framer.getLocalizationGroups({ groupIds: ["id1", "id2"] })\n```\n@category localization',
13283
+ references: ["GetLocalizationGroupsFilter", "LocalizationGroup"]
12858
13284
  },
12859
13285
  {
12860
13286
  name: "getManagedCollections",
12861
13287
  category: "framer",
12862
13288
  signature: "getManagedCollections(): Promise<ManagedCollection[]>",
12863
- description: "Retrieve Collections that are managed by the current Plugin.\n\n- Only Collections created or controlled by your Plugin appear in this list.\n- These Collections can be modified without the restrictions placed on user-created Collections.\n\n@example\n```ts\nconst managedCollections = await framer.getManagedCollections();\n```",
13289
+ description: "Retrieve Collections that are managed by the current Plugin.\n\n- Only Collections created or controlled by your Plugin appear in this list.\n- These Collections can be modified without the restrictions placed on user-created Collections.\n\n@example\n```ts\nconst managedCollections = await framer.getManagedCollections();\n```\n@category cms",
12864
13290
  references: ["ManagedCollection"]
12865
13291
  },
12866
13292
  {
12867
13293
  name: "getNode",
12868
13294
  category: "framer",
12869
13295
  signature: "getNode(nodeId: NodeId): Promise<AnyNode | null>",
12870
- description: "Get a node by its id.",
13296
+ description: "Get a node by its id.\n@category canvas",
12871
13297
  references: ["AnyNode"]
12872
13298
  },
12873
13299
  {
12874
13300
  name: "getNodesWithAttribute",
12875
13301
  category: "framer",
12876
13302
  signature: "getNodesWithAttribute(attribute: T): Promise<Node[]>",
12877
- description: "Get all nodes with a certain attribute.",
13303
+ description: "Get all nodes with a certain attribute.\n@category canvas",
12878
13304
  references: ["T", "Node"]
12879
13305
  },
12880
13306
  {
12881
13307
  name: "getNodesWithAttributeSet",
12882
13308
  category: "framer",
12883
13309
  signature: "getNodesWithAttributeSet(attribute: T): Promise<Node[]>",
12884
- description: "Get all nodes with a certain attribute which value is set.",
13310
+ description: "Get all nodes with a certain attribute which value is set.\n@category canvas",
12885
13311
  references: ["T", "Node"]
12886
13312
  },
12887
13313
  {
12888
13314
  name: "getNodesWithType",
12889
13315
  category: "framer",
12890
13316
  signature: 'getNodesWithType(type: "FrameNode"): Promise<FrameNode[]>',
12891
- description: "Get all nodes of a certain class.",
13317
+ description: "Get all nodes of a certain class.\n@category canvas",
12892
13318
  references: ["FrameNode"]
12893
13319
  },
12894
13320
  {
12895
13321
  name: "getParent",
12896
13322
  category: "framer",
12897
13323
  signature: "getParent(nodeId: NodeId): Promise<AnyNode | null>",
12898
- description: "Get the parent of a node.",
13324
+ description: "Get the parent of a node.\n@category canvas",
12899
13325
  references: ["AnyNode"]
12900
13326
  },
12901
13327
  {
12902
13328
  name: "getProjectInfo",
12903
13329
  category: "framer",
12904
13330
  signature: "getProjectInfo(): Promise<ProjectInfo>",
12905
- description: "Get the project info like name and id.",
13331
+ description: "Get the project info like name and id.\n@category settings",
12906
13332
  references: ["ProjectInfo"]
12907
13333
  },
12908
13334
  {
12909
13335
  name: "getPublishInfo",
12910
13336
  category: "framer",
12911
13337
  signature: "getPublishInfo(): Promise<PublishInfo>",
12912
- description: "Get information about the published website, such as the time of the most\nrecent deploy, or the URL of the current page. Provides information about\nboth `staging` and `production` environments (either may be `null` if the\nsite has never been published).\n\n@returns The current publish info for both staging and production.",
13338
+ description: "Get information about the published website.\n\nProvides details such as the time of the most recent deploy or the URL of\nthe current page. Covers both `staging` and `production` environments\n(either may be `null` if the site has never been published).\n\n@returns The current publish info for both staging and production.\n@category settings",
12913
13339
  references: ["PublishInfo"]
12914
13340
  },
12915
13341
  {
12916
13342
  name: "getRect",
12917
13343
  category: "framer",
12918
13344
  signature: "getRect(nodeId: NodeId): Promise<Rect$1 | null>",
12919
- description: "Get the rect of a node",
13345
+ description: "Get the rect of a node\n@category canvas",
12920
13346
  references: ["Rect$1"]
12921
13347
  },
12922
13348
  {
12923
13349
  name: "getRedirects",
12924
13350
  category: "framer",
12925
13351
  signature: "getRedirects(): Promise<readonly Redirect[]>",
12926
- 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```",
13352
+ 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",
12927
13353
  references: ["Redirect"]
12928
13354
  },
12929
13355
  {
12930
13356
  name: "getText",
12931
13357
  category: "framer",
12932
13358
  signature: "getText(): Promise<string | null>",
12933
- description: "Get plaintext of the current selection or null if there is no text.",
13359
+ description: "Get plaintext of the current selection or null if there is no text.\n@category canvas",
12934
13360
  references: []
12935
13361
  },
12936
13362
  {
12937
13363
  name: "getTextStyle",
12938
13364
  category: "framer",
12939
13365
  signature: "getTextStyle(id: NodeId): Promise<TextStyle | null>",
12940
- description: "Get a specific text style.",
13366
+ description: "Get a specific text style.\n@category canvas",
12941
13367
  references: ["TextStyle"]
12942
13368
  },
12943
13369
  {
12944
13370
  name: "getTextStyles",
12945
13371
  category: "framer",
12946
13372
  signature: "getTextStyles(): Promise<TextStyle[]>",
12947
- description: "Get all text styles in the project.",
13373
+ description: "Get all text styles in the project.\n@category canvas",
12948
13374
  references: ["TextStyle"]
12949
13375
  },
12950
13376
  {
@@ -12958,7 +13384,7 @@ var methodsByCategory = {
12958
13384
  name: "mode",
12959
13385
  category: "framer",
12960
13386
  signature: "mode: Mode",
12961
- description: 'Get the current mode. A plugin can launch in a special mode where only a\nsubset of the API is allowed. The mode is set when the plugin launches\nand never changes while the plugin is active.\n\n@example\n```ts\nif (framer.mode === "image" || framer.mode === "editImage") {\n // Do image mode specific logic\n return\n}\n```',
13387
+ description: 'Get the current mode.\n\nA plugin can launch in a special mode where only a subset of the API is\nallowed. The mode is set when the plugin launches and never changes while\nthe plugin is active.\n\n@example\n```ts\nif (framer.mode === "image" || framer.mode === "editImage") {\n // Do image mode specific logic\n return\n}\n```\n@category settings',
12962
13388
  references: ["Mode"]
12963
13389
  },
12964
13390
  {
@@ -12986,14 +13412,14 @@ var methodsByCategory = {
12986
13412
  name: "removeNodes",
12987
13413
  category: "framer",
12988
13414
  signature: "removeNodes(nodeIds: NodeId[]): Promise<void>",
12989
- description: "Remove nodes from the canvas.",
13415
+ description: "Remove nodes from the canvas.\n@category canvas",
12990
13416
  references: []
12991
13417
  },
12992
13418
  {
12993
13419
  name: "removeRedirects",
12994
13420
  category: "framer",
12995
13421
  signature: "removeRedirects(redirectIds: string[]): Promise<void>",
12996
- description: "Remove Redirects from the project. Unknown Redirect IDs are ignored.\n\nThrows a `FramerPluginError` when the user lacks Site Settings permissions\nor when the project plan does not include Redirects.\n\n@param redirectIds - An array of Redirect IDs to remove.\n\n@example\n```ts\nawait framer.removeRedirects([aboutPageRedirect.id, blogPageRedirect.id])\n```",
13422
+ description: "Remove Redirects from the project.\n\nUnknown Redirect IDs are ignored.\n\nThrows a `FramerPluginError` when the user lacks Site Settings permissions\nor when the project plan does not include Redirects.\n\n@param redirectIds - An array of Redirect IDs to remove.\n\n@example\n```ts\nawait framer.removeRedirects([aboutPageRedirect.id, blogPageRedirect.id])\n```\n@category settings",
12997
13423
  references: []
12998
13424
  },
12999
13425
  {
@@ -13003,6 +13429,13 @@ var methodsByCategory = {
13003
13429
  description: "",
13004
13430
  references: []
13005
13431
  },
13432
+ {
13433
+ name: "reviewChangesForAgent",
13434
+ category: "framer",
13435
+ signature: "reviewChangesForAgent(options?: { pagePath?: string; }): Promise<unknown>",
13436
+ 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.",
13437
+ references: []
13438
+ },
13006
13439
  {
13007
13440
  name: "screenshot",
13008
13441
  category: "framer",
@@ -13010,67 +13443,74 @@ var methodsByCategory = {
13010
13443
  description: "",
13011
13444
  references: ["ScreenshotOptions", "ScreenshotResult"]
13012
13445
  },
13446
+ {
13447
+ name: "sessionId",
13448
+ category: "framer",
13449
+ signature: "sessionId: string",
13450
+ description: "",
13451
+ references: []
13452
+ },
13013
13453
  {
13014
13454
  name: "setAttributes",
13015
13455
  category: "framer",
13016
13456
  signature: "setAttributes(nodeId: NodeId, attributes: Partial<AnyEditableAttributes>): Promise<AnyNode | null>",
13017
- description: "Set the attributes of a node.",
13457
+ description: "Set the attributes of a node.\n@category canvas",
13018
13458
  references: ["AnyEditableAttributes", "AnyNode"]
13019
13459
  },
13020
13460
  {
13021
13461
  name: "setCloseWarning",
13022
13462
  category: "framer",
13023
13463
  signature: "setCloseWarning(message: string | false): Promise<void>",
13024
- description: 'When enabled, a modal confirmation will appear before close to confirm the action.\n\nPass `false` to disable the warning.\n\n@param message - The message to show when attempting to close the plugin. `false` disables the warning.\n\n@example\n```ts\n// Show a close warning when the user attempts to close the plugin\nawait framer.setCloseWarning("Are you sure?")\n\n// Remove the close warning\nawait framer.setCloseWarning(false)\n```',
13464
+ description: 'When enabled, a modal confirmation will appear before close to confirm the action.\n\nPass `false` to disable the warning.\n\n@param message - The message to show when attempting to close the plugin. `false` disables the warning.\n\n@example\n```ts\n// Show a close warning when the user attempts to close the plugin\nawait framer.setCloseWarning("Are you sure?")\n\n// Remove the close warning\nawait framer.setCloseWarning(false)\n```\n@category settings',
13025
13465
  references: []
13026
13466
  },
13027
13467
  {
13028
13468
  name: "setCustomCode",
13029
13469
  category: "framer",
13030
13470
  signature: "setCustomCode(options: SetCustomCodeOptions): Promise<void>",
13031
- description: 'Install a custom code snippet in the user\'s website via `<script>` tags.\nA plugin can only set custom HTML once per location. Custom code should be\nvalid HTML. Setting `html` to `null` clears the installed code snippet.\n\n@param options - The custom code options including `html` and `location`.\n\n@example\n```ts\nframer.setCustomCode({\n html: \'<script src="https://example.com/script.js"></script>\',\n location: "bodyEnd"\n})\n```',
13471
+ description: 'Install a custom code snippet in the user\'s website via `<script>` tags.\n\nA plugin can only set custom HTML once per location. Custom code should be\nvalid HTML. Setting `html` to `null` clears the installed code snippet.\n\n@param options - The custom code options including `html` and `location`.\n\n@example\n```ts\nframer.setCustomCode({\n html: \'<script src="https://example.com/script.js"></script>\',\n location: "bodyEnd"\n})\n```\n@category code-files',
13032
13472
  references: ["SetCustomCodeOptions"]
13033
13473
  },
13034
13474
  {
13035
13475
  name: "setImage",
13036
13476
  category: "framer",
13037
13477
  signature: "setImage(image: NamedImageAssetInput | File): Promise<void>",
13038
- description: "Upload an image and set it on the selected node.\n\nIn `image` or `editImage` mode, this is the primary method to send the\nselected or edited image back to Framer.",
13478
+ description: "Upload an image and set it on the selected node.\n\nIn `image` or `editImage` mode, this is the primary method to send the\nselected or edited image back to Framer.\n@category canvas",
13039
13479
  references: ["NamedImageAssetInput", "File"]
13040
13480
  },
13041
13481
  {
13042
13482
  name: "setLocalizationData",
13043
13483
  category: "framer",
13044
13484
  signature: "setLocalizationData(update: LocalizationData): Promise<SetLocalizationDataResult>",
13045
- description: 'Update localization data.\n\n@param update - An object representing the localization update.\n\n@example\n```ts\nawait framer.setLocalizationData({\n valuesBySource: {\n [titleSourceId]: {\n [dutchLocaleId]: { action: "set", value: "Hallo Wereld" }\n }\n },\n statusByLocaleByGroup: {\n [blogPostGroupId]: {\n [dutchLocaleId]: "ready",\n [frenchLocaleId]: "excluded"\n }\n }\n})\n```',
13485
+ description: 'Update localization data.\n\n@param update - An object representing the localization update.\n\n@example\n```ts\nawait framer.setLocalizationData({\n valuesBySource: {\n [titleSourceId]: {\n [dutchLocaleId]: { action: "set", value: "Hallo Wereld" }\n }\n },\n statusByLocaleByGroup: {\n [blogPostGroupId]: {\n [dutchLocaleId]: "ready",\n [frenchLocaleId]: "excluded"\n }\n }\n})\n```\n@category localization',
13046
13486
  references: ["LocalizationData", "SetLocalizationDataResult"]
13047
13487
  },
13048
13488
  {
13049
13489
  name: "setParent",
13050
13490
  category: "framer",
13051
13491
  signature: "setParent(nodeId: NodeId, parentId: NodeId, index?: number | undefined): Promise<void>",
13052
- description: "Set the parent of a node.",
13492
+ description: "Set the parent of a node.\n@category canvas",
13053
13493
  references: []
13054
13494
  },
13055
13495
  {
13056
13496
  name: "setRedirectOrder",
13057
13497
  category: "framer",
13058
13498
  signature: "setRedirectOrder(redirectIds: string[]): Promise<void>",
13059
- description: "Set the order of Redirects in the list. Unknown Redirect IDs are ignored.\n\nThrows a `FramerPluginError` when the user lacks Site Settings permissions\nor when the project plan does not include Redirects.\n\n@param redirectIds - An array of Redirect IDs representing the desired order.\n\n@example\n```ts\nawait framer.setRedirectOrder([aboutPageRedirect.id, blogPageRedirect.id])\n```",
13499
+ description: "Set the order of Redirects in the list.\n\nUnknown Redirect IDs are ignored.\n\nThrows a `FramerPluginError` when the user lacks Site Settings permissions\nor when the project plan does not include Redirects.\n\n@param redirectIds - An array of Redirect IDs representing the desired order.\n\n@example\n```ts\nawait framer.setRedirectOrder([aboutPageRedirect.id, blogPageRedirect.id])\n```\n@category settings",
13060
13500
  references: []
13061
13501
  },
13062
13502
  {
13063
13503
  name: "setSelection",
13064
13504
  category: "framer",
13065
13505
  signature: "setSelection(nodeIds: string | Iterable<string>): Promise<void>",
13066
- description: "Set the current selection.",
13506
+ description: "Set the current selection.\n@category canvas",
13067
13507
  references: []
13068
13508
  },
13069
13509
  {
13070
13510
  name: "setText",
13071
13511
  category: "framer",
13072
13512
  signature: "setText(text: string): Promise<void>",
13073
- description: "Set the text of the current selection or insert it onto the canvas.",
13513
+ description: "Set the text of the current selection or insert it onto the canvas.\n@category canvas",
13074
13514
  references: []
13075
13515
  },
13076
13516
  {
@@ -13097,35 +13537,35 @@ var methodsByCategory = {
13097
13537
  name: "typecheckCode",
13098
13538
  category: "framer",
13099
13539
  signature: "typecheckCode(fileName: string, content: string, compilerOptions?: ts.server.protocol.CompilerOptions, sessionId?: string): Promise<TypecheckDiagnostic[]>",
13100
- description: "Type check a code file and return the diagnostics.\n\n@param fileName - The name of the code file, must include the extension. Use `*.tsx` for TSX files, otherwise the React JSX syntax will be rejected.\n@param content - The content of the code file.\n@param compilerOptions - Optional compiler options to override the default compiler options for type checking.\n@param sessionId - Optional session ID. Pass it when repeatedly type checking the same file. If not provided, a new session will be created for each type check, which is slow.",
13540
+ description: "Type check a code file and return the diagnostics.\n\n@param fileName - The name of the code file, must include the extension. Use `*.tsx` for TSX files, otherwise the React JSX syntax will be rejected.\n@param content - The content of the code file.\n@param compilerOptions - Optional compiler options to override the default compiler options for type checking.\n@param sessionId - Optional session ID. Pass it when repeatedly type checking the same file. If not provided, a new session will be created for each type check, which is slow.\n@category code-files",
13101
13541
  references: ["ts.server.protocol.CompilerOptions", "TypecheckDiagnostic"]
13102
13542
  },
13103
13543
  {
13104
13544
  name: "uploadFile",
13105
13545
  category: "framer",
13106
13546
  signature: "uploadFile(file: NamedFileAssetInput | File): Promise<FileAsset>",
13107
- description: "Uploads a file without assigning it to a property.",
13547
+ description: "Uploads a file without assigning it to a property.\n@category canvas",
13108
13548
  references: ["NamedFileAssetInput", "File", "FileAsset"]
13109
13549
  },
13110
13550
  {
13111
13551
  name: "uploadFiles",
13112
13552
  category: "framer",
13113
13553
  signature: "uploadFiles(files: readonly NamedFileAssetInput[]): Promise<FileAsset[]>",
13114
- description: "Upload multiple files without assigning them to properties.",
13554
+ description: "Upload multiple files without assigning them to properties.\n@category canvas",
13115
13555
  references: ["NamedFileAssetInput", "FileAsset"]
13116
13556
  },
13117
13557
  {
13118
13558
  name: "uploadImage",
13119
13559
  category: "framer",
13120
13560
  signature: "uploadImage(image: NamedImageAssetInput | File): Promise<ImageAsset>",
13121
- description: "Upload an image without assigning it to a property.",
13561
+ description: "Upload an image without assigning it to a property.\n@category canvas",
13122
13562
  references: ["NamedImageAssetInput", "File", "ImageAsset"]
13123
13563
  },
13124
13564
  {
13125
13565
  name: "uploadImages",
13126
13566
  category: "framer",
13127
13567
  signature: "uploadImages(images: readonly NamedImageAssetInput[]): Promise<ImageAsset[]>",
13128
- description: "Upload multiple images without assigning them to properties.",
13568
+ description: "Upload multiple images without assigning them to properties.\n@category canvas",
13129
13569
  references: ["NamedImageAssetInput", "ImageAsset"]
13130
13570
  }
13131
13571
  ],
@@ -13321,7 +13761,7 @@ var methodsByCategory = {
13321
13761
  name: "addItems",
13322
13762
  category: "ManagedCollection",
13323
13763
  signature: "addItems(items: ManagedCollectionItemInput[]): Promise<void>",
13324
- description: 'Add new items or update existing ones if their IDs match. This method\nperforms an upsert: items with matching IDs are updated, new IDs are\ninserted.\n\nEach item requires an `id` and `slug`. Custom field data is provided via\nthe `fieldData` object, using field IDs as keys.\n\nCurrently, calling `addItems` with existing item IDs merges the provided\nfield data with the existing items\' current field data, meaning any\nomitted fields remain unchanged. In version 4.0.0, this behavior will\nchange to fully replace items, removing any fields not explicitly\nincluded. Always include all fields when updating existing items to avoid\nunexpected behavior.\n\nUse `"ManagedCollection.addItems"` to check if this method is allowed.\n\n@param items - An array of items to add or update.\n\n@example\n```ts\nawait collection.addItems([\n {\n id: "1",\n slug: "item-1",\n fieldData: {\n [nameField.id]: { type: "string", value: "Eric" },\n [ageField.id]: { type: "number", value: 47 },\n },\n },\n])\n```',
13764
+ description: 'Add new items or update existing ones if their IDs match.\n\nThis method performs an upsert: items with matching IDs are updated,\nnew IDs are inserted.\n\nEach item requires an `id` and `slug`. Custom field data is provided via\nthe `fieldData` object, using field IDs as keys.\n\nCurrently, calling `addItems` with existing item IDs merges the provided\nfield data with the existing items\' current field data, meaning any\nomitted fields remain unchanged. In version 4.0.0, this behavior will\nchange to fully replace items, removing any fields not explicitly\nincluded. Always include all fields when updating existing items to avoid\nunexpected behavior.\n\nUse `"ManagedCollection.addItems"` to check if this method is allowed.\n\n@param items - An array of items to add or update.\n\n@example\n```ts\nawait collection.addItems([\n {\n id: "1",\n slug: "item-1",\n fieldData: {\n [nameField.id]: { type: "string", value: "Eric" },\n [ageField.id]: { type: "number", value: 47 },\n },\n },\n])\n```',
13325
13765
  references: ["ManagedCollectionItemInput"]
13326
13766
  },
13327
13767
  {
@@ -13363,7 +13803,7 @@ var methodsByCategory = {
13363
13803
  name: "navigateTo",
13364
13804
  category: "ManagedCollection",
13365
13805
  signature: "navigateTo(opts?: NavigableOptions): Promise<void>",
13366
- description: "Navigate to this collection. May switch modes to reveal the relevant view.",
13806
+ description: "Navigate to this collection.\n\nMay switch modes to reveal the relevant view.",
13367
13807
  references: ["NavigableOptions"]
13368
13808
  },
13369
13809
  {
@@ -13384,7 +13824,7 @@ var methodsByCategory = {
13384
13824
  name: "setFields",
13385
13825
  category: "ManagedCollection",
13386
13826
  signature: "setFields(fields: ManagedCollectionFieldInput[]): Promise<void>",
13387
- description: 'Add, update, or remove Collection fields. Fields not included in the\narray will be removed. You can configure up to 30 custom fields.\n\nEach field requires an `id`, `name`, and `type`. For the `id`, use a\nunique identifier that stays the same across future synchronizations.\nAny change in `id` can break data assignments on the canvas. The maximum\nlength for an `id` is 64 characters.\n\nBy default, managed collection fields set by a plugin are not editable by\nusers. Set `userEditable: true` on a field to allow user editing. Note\nthat fields marked as `userEditable` can no longer have their values set\nby the plugin when using `addItems`.\n\nUse `"ManagedCollection.setFields"` to check if this method is allowed.\n\n@param fields - The array of fields that should be used for the collection.\n\n@example\n```ts\nawait collection.setFields([\n { id: "1", type: "string", name: "Name" },\n { id: "2", type: "number", name: "Age" },\n { id: "3", type: "string", name: "Description", userEditable: true },\n])\n```',
13827
+ description: 'Add, update, or remove Collection fields.\n\nFields not included in the array will be removed. You can configure\nup to 30 custom fields.\n\nEach field requires an `id`, `name`, and `type`. For the `id`, use a\nunique identifier that stays the same across future synchronizations.\nAny change in `id` can break data assignments on the canvas. The maximum\nlength for an `id` is 64 characters.\n\nBy default, managed collection fields set by a plugin are not editable by\nusers. Set `userEditable: true` on a field to allow user editing. Note\nthat fields marked as `userEditable` can no longer have their values set\nby the plugin when using `addItems`.\n\nUse `"ManagedCollection.setFields"` to check if this method is allowed.\n\n@param fields - The array of fields that should be used for the collection.\n\n@example\n```ts\nawait collection.setFields([\n { id: "1", type: "string", name: "Name" },\n { id: "2", type: "number", name: "Age" },\n { id: "3", type: "string", name: "Description", userEditable: true },\n])\n```',
13388
13828
  references: ["ManagedCollectionFieldInput"]
13389
13829
  },
13390
13830
  {
@@ -13398,7 +13838,7 @@ var methodsByCategory = {
13398
13838
  name: "setPluginData",
13399
13839
  category: "ManagedCollection",
13400
13840
  signature: "setPluginData(key: string, value: string | null): Promise<void>",
13401
- description: 'Set plugin data by key. Similar to local storage, you can store custom\ndata on the Managed Collection (e.g., the last synchronization date or a\nconnected database ID).\n\nUse `"ManagedCollection.setPluginData"` to check if this method is allowed.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\n@example\n```ts\nconst currentDate = new Date().toISOString()\nawait collection.setPluginData("lastSynchronizedAt", currentDate)\n```',
13841
+ description: 'Set plugin data by key.\n\nSimilar to local storage, you can store custom data on the Managed\nCollection (e.g., the last synchronization date or a connected database\nID).\n\nUse `"ManagedCollection.setPluginData"` to check if this method is allowed.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\n@example\n```ts\nconst currentDate = new Date().toISOString()\nawait collection.setPluginData("lastSynchronizedAt", currentDate)\n```',
13402
13842
  references: []
13403
13843
  }
13404
13844
  ],
@@ -13638,21 +14078,21 @@ var methodsByCategory = {
13638
14078
  name: "bottom",
13639
14079
  category: "SVGNode",
13640
14080
  signature: "bottom: CSSDimension<CSSUnit.Pixel> | null",
13641
- description: 'Distance from bottom edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14081
+ description: 'Distance from bottom edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
13642
14082
  references: ["CSSDimension", "CSSUnit.Pixel"]
13643
14083
  },
13644
14084
  {
13645
14085
  name: "centerX",
13646
14086
  category: "SVGNode",
13647
14087
  signature: "centerX: CSSDimension<CSSUnit.Percentage> | null",
13648
- description: 'Center anchor horizontal position as percentage (e.g. `"50%"`).\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14088
+ description: 'Center anchor horizontal position as percentage (e.g. `"50%"`).\n\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
13649
14089
  references: ["CSSDimension", "CSSUnit.Percentage"]
13650
14090
  },
13651
14091
  {
13652
14092
  name: "centerY",
13653
14093
  category: "SVGNode",
13654
14094
  signature: "centerY: CSSDimension<CSSUnit.Percentage> | null",
13655
- description: 'Center anchor vertical position as percentage (e.g. `"50%"`).\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14095
+ description: 'Center anchor vertical position as percentage (e.g. `"50%"`).\n\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
13656
14096
  references: ["CSSDimension", "CSSUnit.Percentage"]
13657
14097
  },
13658
14098
  {
@@ -13673,7 +14113,7 @@ var methodsByCategory = {
13673
14113
  name: "getNodesWithAttribute",
13674
14114
  category: "SVGNode",
13675
14115
  signature: "getNodesWithAttribute(attribute: T): Promise<Node[]>",
13676
- description: 'Get the descendants of this node that support `attribute`. This\nreturns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
14116
+ description: 'Get the descendants of this node that support `attribute`.\n\nThis returns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
13677
14117
  references: ["T", "Node"]
13678
14118
  },
13679
14119
  {
@@ -13687,7 +14127,7 @@ var methodsByCategory = {
13687
14127
  name: "getNodesWithType",
13688
14128
  category: "SVGNode",
13689
14129
  signature: 'getNodesWithType(type: "FrameNode"): Promise<FrameNode[]>',
13690
- description: 'Get descendants of this node that match the given type. This can\nalso be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
14130
+ description: 'Get descendants of this node that match the given type.\n\nThis can also be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
13691
14131
  references: ["FrameNode"]
13692
14132
  },
13693
14133
  {
@@ -13701,7 +14141,7 @@ var methodsByCategory = {
13701
14141
  name: "getPluginData",
13702
14142
  category: "SVGNode",
13703
14143
  signature: "getPluginData(key: string): Promise<string | null>",
13704
- description: "Get plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
14144
+ description: "Get plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
13705
14145
  references: []
13706
14146
  },
13707
14147
  {
@@ -13722,42 +14162,42 @@ var methodsByCategory = {
13722
14162
  name: "height",
13723
14163
  category: "SVGNode",
13724
14164
  signature: "height: HeightLength | null",
13725
- description: 'Height of the node. Accepts pixel, percentage, fraction, viewport-height values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14165
+ description: 'Height of the node.\n\nAccepts pixel, percentage, fraction, viewport-height values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
13726
14166
  references: ["HeightLength"]
13727
14167
  },
13728
14168
  {
13729
14169
  name: "left",
13730
14170
  category: "SVGNode",
13731
14171
  signature: "left: CSSDimension<CSSUnit.Pixel> | null",
13732
- description: 'Distance from left edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14172
+ description: 'Distance from left edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
13733
14173
  references: ["CSSDimension", "CSSUnit.Pixel"]
13734
14174
  },
13735
14175
  {
13736
14176
  name: "locked",
13737
14177
  category: "SVGNode",
13738
14178
  signature: "locked: boolean",
13739
- description: "Whether the node is locked for editing. Defaults to `false`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
14179
+ description: "Whether the node is locked for editing.\n\nDefaults to `false`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
13740
14180
  references: []
13741
14181
  },
13742
14182
  {
13743
14183
  name: "name",
13744
14184
  category: "SVGNode",
13745
14185
  signature: "name: string | null",
13746
- description: "The name of the node displayed in the layers panel.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode,\nComponentNode, VectorSetNode, VectorSetItemNode.",
14186
+ description: "The name of the node displayed in the layers panel.\n\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode,\nComponentNode, VectorSetNode, VectorSetItemNode.",
13747
14187
  references: []
13748
14188
  },
13749
14189
  {
13750
14190
  name: "navigateTo",
13751
14191
  category: "SVGNode",
13752
14192
  signature: 'navigateTo(opts?: Pick<NavigableOptions, "select" | "zoomIntoView">): Promise<void>',
13753
- description: "Navigate to this node. May switch modes to reveal the relevant view.",
14193
+ description: "Navigate to this node.\n\nMay switch modes to reveal the relevant view.",
13754
14194
  references: ["NavigableOptions"]
13755
14195
  },
13756
14196
  {
13757
14197
  name: "opacity",
13758
14198
  category: "SVGNode",
13759
14199
  signature: "opacity: number",
13760
- description: "Opacity of the node, from `0` (fully transparent) to `1` (fully opaque). Defaults to `1`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
14200
+ description: "Opacity of the node, from `0` (fully transparent) to `1` (fully opaque).\n\nDefaults to `1`. Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
13761
14201
  references: []
13762
14202
  },
13763
14203
  {
@@ -13778,14 +14218,14 @@ var methodsByCategory = {
13778
14218
  name: "right",
13779
14219
  category: "SVGNode",
13780
14220
  signature: "right: CSSDimension<CSSUnit.Pixel> | null",
13781
- description: 'Distance from right edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14221
+ description: 'Distance from right edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
13782
14222
  references: ["CSSDimension", "CSSUnit.Pixel"]
13783
14223
  },
13784
14224
  {
13785
14225
  name: "rotation",
13786
14226
  category: "SVGNode",
13787
14227
  signature: "rotation: number",
13788
- description: "Rotation angle in degrees. Defaults to `0`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
14228
+ description: "Rotation angle in degrees.\n\nDefaults to `0`. Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
13789
14229
  references: []
13790
14230
  },
13791
14231
  {
@@ -13799,14 +14239,14 @@ var methodsByCategory = {
13799
14239
  name: "setAttributes",
13800
14240
  category: "SVGNode",
13801
14241
  signature: 'setAttributes(update: Partial<NodeClassToEditableAttributes[(typeof this)[ClassKey]]>): Promise<(typeof this)[ClassKey] extends "UnknownNode" ? never : typeof this | null>',
13802
- description: 'Set the attributes of this node. Attributes are merged with existing\nvalues, so only the provided attributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
14242
+ description: 'Set the attributes of this node.\n\nAttributes are merged with existing values, so only the provided\nattributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
13803
14243
  references: []
13804
14244
  },
13805
14245
  {
13806
14246
  name: "setPluginData",
13807
14247
  category: "SVGNode",
13808
14248
  signature: "setPluginData(key: string, value: string | null): Promise<void>",
13809
- description: 'Set plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
14249
+ description: 'Set plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
13810
14250
  references: []
13811
14251
  },
13812
14252
  {
@@ -13820,28 +14260,28 @@ var methodsByCategory = {
13820
14260
  name: "top",
13821
14261
  category: "SVGNode",
13822
14262
  signature: "top: CSSDimension<CSSUnit.Pixel> | null",
13823
- description: 'Distance from top edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14263
+ description: 'Distance from top edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
13824
14264
  references: ["CSSDimension", "CSSUnit.Pixel"]
13825
14265
  },
13826
14266
  {
13827
14267
  name: "visible",
13828
14268
  category: "SVGNode",
13829
14269
  signature: "visible: boolean",
13830
- description: "Whether the node is visible on the canvas. Defaults to `true`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
14270
+ description: "Whether the node is visible on the canvas.\n\nDefaults to `true`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
13831
14271
  references: []
13832
14272
  },
13833
14273
  {
13834
14274
  name: "walk",
13835
14275
  category: "SVGNode",
13836
14276
  signature: "walk(this: AnyNode): AsyncGenerator<AnyNode>",
13837
- description: "Walk this node and its descendants recursively using an async\ngenerator. Yields nodes depth-first.",
14277
+ description: "Walk this node and its descendants recursively.\n\nUses an async generator. Yields nodes depth-first.",
13838
14278
  references: ["AnyNode"]
13839
14279
  },
13840
14280
  {
13841
14281
  name: "width",
13842
14282
  category: "SVGNode",
13843
14283
  signature: "width: WidthLength | null",
13844
- description: 'Width of the node. Accepts pixel, percentage, fraction values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14284
+ description: 'Width of the node.\n\nAccepts pixel, percentage, fraction values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
13845
14285
  references: ["WidthLength"]
13846
14286
  },
13847
14287
  {
@@ -13857,21 +14297,21 @@ var methodsByCategory = {
13857
14297
  name: "bottom",
13858
14298
  category: "TextNode",
13859
14299
  signature: "bottom: CSSDimension<CSSUnit.Pixel> | null",
13860
- description: 'Distance from bottom edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14300
+ description: 'Distance from bottom edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
13861
14301
  references: ["CSSDimension", "CSSUnit.Pixel"]
13862
14302
  },
13863
14303
  {
13864
14304
  name: "centerX",
13865
14305
  category: "TextNode",
13866
14306
  signature: "centerX: CSSDimension<CSSUnit.Percentage> | null",
13867
- description: 'Center anchor horizontal position as percentage (e.g. `"50%"`).\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14307
+ description: 'Center anchor horizontal position as percentage (e.g. `"50%"`).\n\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
13868
14308
  references: ["CSSDimension", "CSSUnit.Percentage"]
13869
14309
  },
13870
14310
  {
13871
14311
  name: "centerY",
13872
14312
  category: "TextNode",
13873
14313
  signature: "centerY: CSSDimension<CSSUnit.Percentage> | null",
13874
- description: 'Center anchor vertical position as percentage (e.g. `"50%"`).\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14314
+ description: 'Center anchor vertical position as percentage (e.g. `"50%"`).\n\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
13875
14315
  references: ["CSSDimension", "CSSUnit.Percentage"]
13876
14316
  },
13877
14317
  {
@@ -13906,7 +14346,7 @@ var methodsByCategory = {
13906
14346
  name: "getNodesWithAttribute",
13907
14347
  category: "TextNode",
13908
14348
  signature: "getNodesWithAttribute(attribute: T): Promise<Node[]>",
13909
- description: 'Get the descendants of this node that support `attribute`. This\nreturns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
14349
+ description: 'Get the descendants of this node that support `attribute`.\n\nThis returns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
13910
14350
  references: ["T", "Node"]
13911
14351
  },
13912
14352
  {
@@ -13920,7 +14360,7 @@ var methodsByCategory = {
13920
14360
  name: "getNodesWithType",
13921
14361
  category: "TextNode",
13922
14362
  signature: 'getNodesWithType(type: "FrameNode"): Promise<FrameNode[]>',
13923
- description: 'Get descendants of this node that match the given type. This can\nalso be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
14363
+ description: 'Get descendants of this node that match the given type.\n\nThis can also be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
13924
14364
  references: ["FrameNode"]
13925
14365
  },
13926
14366
  {
@@ -13934,7 +14374,7 @@ var methodsByCategory = {
13934
14374
  name: "getPluginData",
13935
14375
  category: "TextNode",
13936
14376
  signature: "getPluginData(key: string): Promise<string | null>",
13937
- description: "Get plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
14377
+ description: "Get plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
13938
14378
  references: []
13939
14379
  },
13940
14380
  {
@@ -13955,91 +14395,119 @@ var methodsByCategory = {
13955
14395
  name: "getText",
13956
14396
  category: "TextNode",
13957
14397
  signature: "getText(): Promise<string | null>",
13958
- description: "Get the text of this node. Plain text content, not HTML.",
14398
+ description: "Get the text of this node.\n\nPlain text content, not HTML.",
13959
14399
  references: []
13960
14400
  },
13961
14401
  {
13962
14402
  name: "gridItemColumnSpan",
13963
14403
  category: "TextNode",
13964
14404
  signature: 'gridItemColumnSpan: WithGridItemTrait["gridItemColumnSpan"]',
13965
- description: 'Number of columns to span, or `"all"` for all columns. For nodes inside a grid container. Defaults to `1`. Supported by FrameNode, TextNode.',
14405
+ description: 'Number of columns to span, or `"all"` for all columns.\n\nFor nodes inside a grid container. Defaults to `1`. Supported by FrameNode, TextNode.',
13966
14406
  references: []
13967
14407
  },
13968
14408
  {
13969
14409
  name: "gridItemFillCellHeight",
13970
14410
  category: "TextNode",
13971
14411
  signature: 'gridItemFillCellHeight: WithGridItemTrait["gridItemFillCellHeight"]',
13972
- description: "Whether to fill the grid cell height. For nodes inside a grid container. Defaults to `true`. Supported by FrameNode, TextNode.",
14412
+ description: "Whether to fill the grid cell height.\n\nFor nodes inside a grid container. Defaults to `true`. Supported by FrameNode, TextNode.",
13973
14413
  references: []
13974
14414
  },
13975
14415
  {
13976
14416
  name: "gridItemFillCellWidth",
13977
14417
  category: "TextNode",
13978
14418
  signature: 'gridItemFillCellWidth: WithGridItemTrait["gridItemFillCellWidth"]',
13979
- description: "Whether to fill the grid cell width. For nodes inside a grid container. Defaults to `true`. Supported by FrameNode, TextNode.",
14419
+ description: "Whether to fill the grid cell width.\n\nFor nodes inside a grid container. Defaults to `true`. Supported by FrameNode, TextNode.",
13980
14420
  references: []
13981
14421
  },
13982
14422
  {
13983
14423
  name: "gridItemHorizontalAlignment",
13984
14424
  category: "TextNode",
13985
14425
  signature: 'gridItemHorizontalAlignment: WithGridItemTrait["gridItemHorizontalAlignment"]',
13986
- description: 'Horizontal alignment within grid cell. For nodes inside a grid container. Defaults to `"center"`. Supported by FrameNode, TextNode.',
14426
+ description: 'Horizontal alignment within grid cell.\n\nFor nodes inside a grid container. Defaults to `"center"`. Supported by FrameNode, TextNode.',
13987
14427
  references: []
13988
14428
  },
13989
14429
  {
13990
14430
  name: "gridItemRowSpan",
13991
14431
  category: "TextNode",
13992
14432
  signature: 'gridItemRowSpan: WithGridItemTrait["gridItemRowSpan"]',
13993
- description: "Number of rows to span. For nodes inside a grid container. Defaults to `1`. Supported by FrameNode, TextNode.",
14433
+ description: "Number of rows to span.\n\nFor nodes inside a grid container. Defaults to `1`. Supported by FrameNode, TextNode.",
13994
14434
  references: []
13995
14435
  },
13996
14436
  {
13997
14437
  name: "gridItemVerticalAlignment",
13998
14438
  category: "TextNode",
13999
14439
  signature: 'gridItemVerticalAlignment: WithGridItemTrait["gridItemVerticalAlignment"]',
14000
- description: 'Vertical alignment within grid cell. For nodes inside a grid container. Defaults to `"center"`. Supported by FrameNode, TextNode.',
14440
+ description: 'Vertical alignment within grid cell.\n\nFor nodes inside a grid container. Defaults to `"center"`. Supported by FrameNode, TextNode.',
14001
14441
  references: []
14002
14442
  },
14003
14443
  {
14004
14444
  name: "height",
14005
14445
  category: "TextNode",
14006
14446
  signature: "height: HeightLength | null",
14007
- description: 'Height of the node. Accepts pixel, percentage, fraction, viewport-height values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14447
+ description: 'Height of the node.\n\nAccepts pixel, percentage, fraction, viewport-height values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14008
14448
  references: ["HeightLength"]
14009
14449
  },
14010
14450
  {
14011
14451
  name: "inlineTextStyle",
14012
14452
  category: "TextNode",
14013
14453
  signature: "inlineTextStyle: TextStyle | null",
14014
- description: "Apply a text style preset. Setting to `null` removes the text style.\nSupported by TextNode.",
14454
+ description: "Apply a text style preset.\n\nSetting to `null` removes the text style. Supported by TextNode.",
14015
14455
  references: ["TextStyle"]
14016
14456
  },
14017
14457
  {
14018
14458
  name: "left",
14019
14459
  category: "TextNode",
14020
14460
  signature: "left: CSSDimension<CSSUnit.Pixel> | null",
14021
- description: 'Distance from left edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14461
+ description: 'Distance from left edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14022
14462
  references: ["CSSDimension", "CSSUnit.Pixel"]
14023
14463
  },
14024
14464
  {
14025
14465
  name: "link",
14026
14466
  category: "TextNode",
14027
- signature: "link: string | null",
14028
- description: 'URL or internal page link. External: `"https://example.com"`, internal: `"/about"`,\nemail: `"mailto:user@example.com"`. Setting to `null` removes the link.\nSupported by FrameNode, TextNode.',
14467
+ signature: 'link: WithLinkTrait["link"]',
14468
+ description: 'URL or internal page link.\n\nExternal: `"https://example.com"`, internal: `"/about"`,\nemail: `"mailto:user@example.com"`. Setting to `null` removes the link.\nSupported by FrameNode, TextNode.',
14469
+ references: []
14470
+ },
14471
+ {
14472
+ name: "linkClickTrackingId",
14473
+ category: "TextNode",
14474
+ signature: 'linkClickTrackingId: WithLinkTrait["linkClickTrackingId"]',
14475
+ description: "Click tracking identifier for analytics.\nSupported by FrameNode, TextNode.",
14029
14476
  references: []
14030
14477
  },
14031
14478
  {
14032
14479
  name: "linkOpenInNewTab",
14033
14480
  category: "TextNode",
14034
- signature: "linkOpenInNewTab: boolean | null",
14035
- description: "Whether to open the link in a new tab. Default is automatically determined based on link type.\nSupported by FrameNode, TextNode.",
14481
+ signature: 'linkOpenInNewTab: WithLinkTrait["linkOpenInNewTab"]',
14482
+ description: "Whether to open the link in a new tab.\n\nDefault is automatically determined based on link type.\nSupported by FrameNode, TextNode.",
14483
+ references: []
14484
+ },
14485
+ {
14486
+ name: "linkPreserveParams",
14487
+ category: "TextNode",
14488
+ signature: 'linkPreserveParams: WithLinkTrait["linkPreserveParams"]',
14489
+ description: "Whether to preserve URL query parameters when navigating.\nSupported by FrameNode, TextNode.",
14490
+ references: []
14491
+ },
14492
+ {
14493
+ name: "linkRelValues",
14494
+ category: "TextNode",
14495
+ signature: 'linkRelValues: WithLinkTrait["linkRelValues"]',
14496
+ description: "Array of rel attribute values for the link.\nSupported by FrameNode, TextNode.",
14497
+ references: []
14498
+ },
14499
+ {
14500
+ name: "linkSmoothScroll",
14501
+ category: "TextNode",
14502
+ signature: 'linkSmoothScroll: WithLinkTrait["linkSmoothScroll"]',
14503
+ description: "Whether to use smooth scrolling for scroll-to-section links.\nSupported by FrameNode, TextNode.",
14036
14504
  references: []
14037
14505
  },
14038
14506
  {
14039
14507
  name: "locked",
14040
14508
  category: "TextNode",
14041
14509
  signature: "locked: boolean",
14042
- description: "Whether the node is locked for editing. Defaults to `false`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
14510
+ description: "Whether the node is locked for editing.\n\nDefaults to `false`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
14043
14511
  references: []
14044
14512
  },
14045
14513
  {
@@ -14074,42 +14542,42 @@ var methodsByCategory = {
14074
14542
  name: "name",
14075
14543
  category: "TextNode",
14076
14544
  signature: "name: string | null",
14077
- description: "The name of the node displayed in the layers panel.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode,\nComponentNode, VectorSetNode, VectorSetItemNode.",
14545
+ description: "The name of the node displayed in the layers panel.\n\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode,\nComponentNode, VectorSetNode, VectorSetItemNode.",
14078
14546
  references: []
14079
14547
  },
14080
14548
  {
14081
14549
  name: "navigateTo",
14082
14550
  category: "TextNode",
14083
14551
  signature: 'navigateTo(opts?: Pick<NavigableOptions, "select" | "zoomIntoView">): Promise<void>',
14084
- description: "Navigate to this node. May switch modes to reveal the relevant view.",
14552
+ description: "Navigate to this node.\n\nMay switch modes to reveal the relevant view.",
14085
14553
  references: ["NavigableOptions"]
14086
14554
  },
14087
14555
  {
14088
14556
  name: "opacity",
14089
14557
  category: "TextNode",
14090
14558
  signature: "opacity: number",
14091
- description: "Opacity of the node, from `0` (fully transparent) to `1` (fully opaque). Defaults to `1`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
14559
+ description: "Opacity of the node, from `0` (fully transparent) to `1` (fully opaque).\n\nDefaults to `1`. Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
14092
14560
  references: []
14093
14561
  },
14094
14562
  {
14095
14563
  name: "overflow",
14096
14564
  category: "TextNode",
14097
14565
  signature: 'overflow: WithOverflowTrait["overflow"]',
14098
- description: "Controls how content that exceeds the element's box is handled.\nSetting to `null` removes the overflow property. Will overwrite `overflowX` or `overflowY`.\nSupported by FrameNode, TextNode.",
14566
+ description: "Controls how content that exceeds the element's box is handled.\n\nSetting to `null` removes the overflow property. Will overwrite `overflowX` or `overflowY`.\nSupported by FrameNode, TextNode.",
14099
14567
  references: []
14100
14568
  },
14101
14569
  {
14102
14570
  name: "overflowX",
14103
14571
  category: "TextNode",
14104
14572
  signature: 'overflowX: WithOverflowTrait["overflowX"]',
14105
- description: "Controls horizontal overflow behavior.\nSetting to `null` removes the overflow X property. Supported by FrameNode, TextNode.",
14573
+ description: "Controls horizontal overflow behavior.\n\nSetting to `null` removes the overflow X property. Supported by FrameNode, TextNode.",
14106
14574
  references: []
14107
14575
  },
14108
14576
  {
14109
14577
  name: "overflowY",
14110
14578
  category: "TextNode",
14111
14579
  signature: 'overflowY: WithOverflowTrait["overflowY"]',
14112
- description: "Controls vertical overflow behavior.\nSetting to `null` removes the overflow Y property. Supported by FrameNode, TextNode.",
14580
+ description: "Controls vertical overflow behavior.\n\nSetting to `null` removes the overflow Y property. Supported by FrameNode, TextNode.",
14113
14581
  references: []
14114
14582
  },
14115
14583
  {
@@ -14130,14 +14598,14 @@ var methodsByCategory = {
14130
14598
  name: "right",
14131
14599
  category: "TextNode",
14132
14600
  signature: "right: CSSDimension<CSSUnit.Pixel> | null",
14133
- description: 'Distance from right edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14601
+ description: 'Distance from right edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14134
14602
  references: ["CSSDimension", "CSSUnit.Pixel"]
14135
14603
  },
14136
14604
  {
14137
14605
  name: "rotation",
14138
14606
  category: "TextNode",
14139
14607
  signature: "rotation: number",
14140
- description: "Rotation angle in degrees. Defaults to `0`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
14608
+ description: "Rotation angle in degrees.\n\nDefaults to `0`. Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.",
14141
14609
  references: []
14142
14610
  },
14143
14611
  {
@@ -14151,7 +14619,7 @@ var methodsByCategory = {
14151
14619
  name: "setAttributes",
14152
14620
  category: "TextNode",
14153
14621
  signature: 'setAttributes(update: Partial<NodeClassToEditableAttributes[(typeof this)[ClassKey]]>): Promise<(typeof this)[ClassKey] extends "UnknownNode" ? never : typeof this | null>',
14154
- description: 'Set the attributes of this node. Attributes are merged with existing\nvalues, so only the provided attributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
14622
+ description: 'Set the attributes of this node.\n\nAttributes are merged with existing values, so only the provided\nattributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
14155
14623
  references: []
14156
14624
  },
14157
14625
  {
@@ -14165,56 +14633,56 @@ var methodsByCategory = {
14165
14633
  name: "setPluginData",
14166
14634
  category: "TextNode",
14167
14635
  signature: "setPluginData(key: string, value: string | null): Promise<void>",
14168
- description: 'Set plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
14636
+ description: 'Set plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
14169
14637
  references: []
14170
14638
  },
14171
14639
  {
14172
14640
  name: "setText",
14173
14641
  category: "TextNode",
14174
14642
  signature: "setText(text: string): Promise<void>",
14175
- description: 'Set the text of this node. Plain text content, not HTML.\n\nUse `"TextNode.setText"` to check if this method is allowed.',
14643
+ description: 'Set the text of this node.\n\nPlain text content, not HTML.\n\nUse `"TextNode.setText"` to check if this method is allowed.',
14176
14644
  references: []
14177
14645
  },
14178
14646
  {
14179
14647
  name: "textTruncation",
14180
14648
  category: "TextNode",
14181
14649
  signature: 'textTruncation: WithTextTruncationTrait["textTruncation"]',
14182
- description: "Maximum number of lines a text node can display before being truncated with an ellipsis.\nMust be used alongside `overflow`. Setting to `null` removes the text truncation property.\nSupported by TextNode.",
14650
+ description: "Maximum number of lines before text is truncated with an ellipsis.\n\nMust be used alongside `overflow`. Setting to `null` removes the text truncation property.\nSupported by TextNode.",
14183
14651
  references: []
14184
14652
  },
14185
14653
  {
14186
14654
  name: "top",
14187
14655
  category: "TextNode",
14188
14656
  signature: "top: CSSDimension<CSSUnit.Pixel> | null",
14189
- description: 'Distance from top edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14657
+ description: 'Distance from top edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14190
14658
  references: ["CSSDimension", "CSSUnit.Pixel"]
14191
14659
  },
14192
14660
  {
14193
14661
  name: "visible",
14194
14662
  category: "TextNode",
14195
14663
  signature: "visible: boolean",
14196
- description: "Whether the node is visible on the canvas. Defaults to `true`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
14664
+ description: "Whether the node is visible on the canvas.\n\nDefaults to `true`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
14197
14665
  references: []
14198
14666
  },
14199
14667
  {
14200
14668
  name: "walk",
14201
14669
  category: "TextNode",
14202
14670
  signature: "walk(this: AnyNode): AsyncGenerator<AnyNode>",
14203
- description: "Walk this node and its descendants recursively using an async\ngenerator. Yields nodes depth-first.",
14671
+ description: "Walk this node and its descendants recursively.\n\nUses an async generator. Yields nodes depth-first.",
14204
14672
  references: ["AnyNode"]
14205
14673
  },
14206
14674
  {
14207
14675
  name: "width",
14208
14676
  category: "TextNode",
14209
14677
  signature: "width: WidthLength | null",
14210
- description: 'Width of the node. Accepts pixel, percentage, fraction values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14678
+ description: 'Width of the node.\n\nAccepts pixel, percentage, fraction values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14211
14679
  references: ["WidthLength"]
14212
14680
  },
14213
14681
  {
14214
14682
  name: "zIndex",
14215
14683
  category: "TextNode",
14216
14684
  signature: 'zIndex: WithZIndexTrait["zIndex"]',
14217
- description: "Stacking order of positioned elements. Higher values appear on top of lower values.\nSetting to `null` removes the z-index property. Supported by FrameNode, TextNode.",
14685
+ description: "Stacking order of positioned elements.\n\nHigher values appear on top of lower values.\nSetting to `null` removes the z-index property. Supported by FrameNode, TextNode.",
14218
14686
  references: []
14219
14687
  },
14220
14688
  {
@@ -14440,7 +14908,7 @@ var methodsByCategory = {
14440
14908
  name: "getNodesWithAttribute",
14441
14909
  category: "UnknownNode",
14442
14910
  signature: "getNodesWithAttribute(attribute: T): Promise<Node[]>",
14443
- description: 'Get the descendants of this node that support `attribute`. This\nreturns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
14911
+ description: 'Get the descendants of this node that support `attribute`.\n\nThis returns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
14444
14912
  references: ["T", "Node"]
14445
14913
  },
14446
14914
  {
@@ -14454,7 +14922,7 @@ var methodsByCategory = {
14454
14922
  name: "getNodesWithType",
14455
14923
  category: "UnknownNode",
14456
14924
  signature: 'getNodesWithType(type: "FrameNode"): Promise<FrameNode[]>',
14457
- description: 'Get descendants of this node that match the given type. This can\nalso be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
14925
+ description: 'Get descendants of this node that match the given type.\n\nThis can also be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
14458
14926
  references: ["FrameNode"]
14459
14927
  },
14460
14928
  {
@@ -14468,7 +14936,7 @@ var methodsByCategory = {
14468
14936
  name: "getPluginData",
14469
14937
  category: "UnknownNode",
14470
14938
  signature: "getPluginData(key: string): Promise<string | null>",
14471
- description: "Get plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
14939
+ description: "Get plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
14472
14940
  references: []
14473
14941
  },
14474
14942
  {
@@ -14489,7 +14957,7 @@ var methodsByCategory = {
14489
14957
  name: "navigateTo",
14490
14958
  category: "UnknownNode",
14491
14959
  signature: 'navigateTo(opts?: Pick<NavigableOptions, "select" | "zoomIntoView">): Promise<void>',
14492
- description: "Navigate to this node. May switch modes to reveal the relevant view.",
14960
+ description: "Navigate to this node.\n\nMay switch modes to reveal the relevant view.",
14493
14961
  references: ["NavigableOptions"]
14494
14962
  },
14495
14963
  {
@@ -14510,21 +14978,21 @@ var methodsByCategory = {
14510
14978
  name: "setAttributes",
14511
14979
  category: "UnknownNode",
14512
14980
  signature: 'setAttributes(update: Partial<NodeClassToEditableAttributes[(typeof this)[ClassKey]]>): Promise<(typeof this)[ClassKey] extends "UnknownNode" ? never : typeof this | null>',
14513
- description: 'Set the attributes of this node. Attributes are merged with existing\nvalues, so only the provided attributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
14981
+ description: 'Set the attributes of this node.\n\nAttributes are merged with existing values, so only the provided\nattributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
14514
14982
  references: []
14515
14983
  },
14516
14984
  {
14517
14985
  name: "setPluginData",
14518
14986
  category: "UnknownNode",
14519
14987
  signature: "setPluginData(key: string, value: string | null): Promise<void>",
14520
- description: 'Set plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
14988
+ description: 'Set plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
14521
14989
  references: []
14522
14990
  },
14523
14991
  {
14524
14992
  name: "walk",
14525
14993
  category: "UnknownNode",
14526
14994
  signature: "walk(this: AnyNode): AsyncGenerator<AnyNode>",
14527
- description: "Walk this node and its descendants recursively using an async\ngenerator. Yields nodes depth-first.",
14995
+ description: "Walk this node and its descendants recursively.\n\nUses an async generator. Yields nodes depth-first.",
14528
14996
  references: ["AnyNode"]
14529
14997
  },
14530
14998
  {
@@ -14604,21 +15072,21 @@ var methodsByCategory = {
14604
15072
  name: "bottom",
14605
15073
  category: "VectorSetItemNode",
14606
15074
  signature: "bottom: CSSDimension<CSSUnit.Pixel> | null",
14607
- description: 'Distance from bottom edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
15075
+ description: 'Distance from bottom edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14608
15076
  references: ["CSSDimension", "CSSUnit.Pixel"]
14609
15077
  },
14610
15078
  {
14611
15079
  name: "centerX",
14612
15080
  category: "VectorSetItemNode",
14613
15081
  signature: "centerX: CSSDimension<CSSUnit.Percentage> | null",
14614
- description: 'Center anchor horizontal position as percentage (e.g. `"50%"`).\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
15082
+ description: 'Center anchor horizontal position as percentage (e.g. `"50%"`).\n\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14615
15083
  references: ["CSSDimension", "CSSUnit.Percentage"]
14616
15084
  },
14617
15085
  {
14618
15086
  name: "centerY",
14619
15087
  category: "VectorSetItemNode",
14620
15088
  signature: "centerY: CSSDimension<CSSUnit.Percentage> | null",
14621
- description: 'Center anchor vertical position as percentage (e.g. `"50%"`).\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
15089
+ description: 'Center anchor vertical position as percentage (e.g. `"50%"`).\n\nUsed when pins are not set.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14622
15090
  references: ["CSSDimension", "CSSUnit.Percentage"]
14623
15091
  },
14624
15092
  {
@@ -14639,7 +15107,7 @@ var methodsByCategory = {
14639
15107
  name: "getNodesWithAttribute",
14640
15108
  category: "VectorSetItemNode",
14641
15109
  signature: "getNodesWithAttribute(attribute: T): Promise<Node[]>",
14642
- description: 'Get the descendants of this node that support `attribute`. This\nreturns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
15110
+ description: 'Get the descendants of this node that support `attribute`.\n\nThis returns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
14643
15111
  references: ["T", "Node"]
14644
15112
  },
14645
15113
  {
@@ -14653,7 +15121,7 @@ var methodsByCategory = {
14653
15121
  name: "getNodesWithType",
14654
15122
  category: "VectorSetItemNode",
14655
15123
  signature: 'getNodesWithType(type: "FrameNode"): Promise<FrameNode[]>',
14656
- description: 'Get descendants of this node that match the given type. This can\nalso be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
15124
+ description: 'Get descendants of this node that match the given type.\n\nThis can also be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
14657
15125
  references: ["FrameNode"]
14658
15126
  },
14659
15127
  {
@@ -14667,7 +15135,7 @@ var methodsByCategory = {
14667
15135
  name: "getPluginData",
14668
15136
  category: "VectorSetItemNode",
14669
15137
  signature: "getPluginData(key: string): Promise<string | null>",
14670
- description: "Get plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
15138
+ description: "Get plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
14671
15139
  references: []
14672
15140
  },
14673
15141
  {
@@ -14688,35 +15156,35 @@ var methodsByCategory = {
14688
15156
  name: "height",
14689
15157
  category: "VectorSetItemNode",
14690
15158
  signature: "height: HeightLength | null",
14691
- description: 'Height of the node. Accepts pixel, percentage, fraction, viewport-height values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
15159
+ description: 'Height of the node.\n\nAccepts pixel, percentage, fraction, viewport-height values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14692
15160
  references: ["HeightLength"]
14693
15161
  },
14694
15162
  {
14695
15163
  name: "left",
14696
15164
  category: "VectorSetItemNode",
14697
15165
  signature: "left: CSSDimension<CSSUnit.Pixel> | null",
14698
- description: 'Distance from left edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
15166
+ description: 'Distance from left edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14699
15167
  references: ["CSSDimension", "CSSUnit.Pixel"]
14700
15168
  },
14701
15169
  {
14702
15170
  name: "locked",
14703
15171
  category: "VectorSetItemNode",
14704
15172
  signature: "locked: boolean",
14705
- description: "Whether the node is locked for editing. Defaults to `false`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
15173
+ description: "Whether the node is locked for editing.\n\nDefaults to `false`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
14706
15174
  references: []
14707
15175
  },
14708
15176
  {
14709
15177
  name: "name",
14710
15178
  category: "VectorSetItemNode",
14711
15179
  signature: "name: string | null",
14712
- description: "The name of the node displayed in the layers panel.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode,\nComponentNode, VectorSetNode, VectorSetItemNode.",
15180
+ description: "The name of the node displayed in the layers panel.\n\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode,\nComponentNode, VectorSetNode, VectorSetItemNode.",
14713
15181
  references: []
14714
15182
  },
14715
15183
  {
14716
15184
  name: "navigateTo",
14717
15185
  category: "VectorSetItemNode",
14718
15186
  signature: 'navigateTo(opts?: Pick<NavigableOptions, "select" | "zoomIntoView">): Promise<void>',
14719
- description: "Navigate to this node. May switch modes to reveal the relevant view.",
15187
+ description: "Navigate to this node.\n\nMay switch modes to reveal the relevant view.",
14720
15188
  references: ["NavigableOptions"]
14721
15189
  },
14722
15190
  {
@@ -14730,7 +15198,7 @@ var methodsByCategory = {
14730
15198
  name: "right",
14731
15199
  category: "VectorSetItemNode",
14732
15200
  signature: "right: CSSDimension<CSSUnit.Pixel> | null",
14733
- description: 'Distance from right edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
15201
+ description: 'Distance from right edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14734
15202
  references: ["CSSDimension", "CSSUnit.Pixel"]
14735
15203
  },
14736
15204
  {
@@ -14744,42 +15212,42 @@ var methodsByCategory = {
14744
15212
  name: "setAttributes",
14745
15213
  category: "VectorSetItemNode",
14746
15214
  signature: 'setAttributes(update: Partial<NodeClassToEditableAttributes[(typeof this)[ClassKey]]>): Promise<(typeof this)[ClassKey] extends "UnknownNode" ? never : typeof this | null>',
14747
- description: 'Set the attributes of this node. Attributes are merged with existing\nvalues, so only the provided attributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
15215
+ description: 'Set the attributes of this node.\n\nAttributes are merged with existing values, so only the provided\nattributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
14748
15216
  references: []
14749
15217
  },
14750
15218
  {
14751
15219
  name: "setPluginData",
14752
15220
  category: "VectorSetItemNode",
14753
15221
  signature: "setPluginData(key: string, value: string | null): Promise<void>",
14754
- description: 'Set plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
15222
+ description: 'Set plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
14755
15223
  references: []
14756
15224
  },
14757
15225
  {
14758
15226
  name: "top",
14759
15227
  category: "VectorSetItemNode",
14760
15228
  signature: "top: CSSDimension<CSSUnit.Pixel> | null",
14761
- description: 'Distance from top edge when using absolute/fixed positioning.\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
15229
+ description: 'Distance from top edge when using absolute/fixed positioning.\n\nOnly applies when position is not `"relative"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14762
15230
  references: ["CSSDimension", "CSSUnit.Pixel"]
14763
15231
  },
14764
15232
  {
14765
15233
  name: "visible",
14766
15234
  category: "VectorSetItemNode",
14767
15235
  signature: "visible: boolean",
14768
- description: "Whether the node is visible on the canvas. Defaults to `true`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
15236
+ description: "Whether the node is visible on the canvas.\n\nDefaults to `true`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.",
14769
15237
  references: []
14770
15238
  },
14771
15239
  {
14772
15240
  name: "walk",
14773
15241
  category: "VectorSetItemNode",
14774
15242
  signature: "walk(this: AnyNode): AsyncGenerator<AnyNode>",
14775
- description: "Walk this node and its descendants recursively using an async\ngenerator. Yields nodes depth-first.",
15243
+ description: "Walk this node and its descendants recursively.\n\nUses an async generator. Yields nodes depth-first.",
14776
15244
  references: ["AnyNode"]
14777
15245
  },
14778
15246
  {
14779
15247
  name: "width",
14780
15248
  category: "VectorSetItemNode",
14781
15249
  signature: "width: WidthLength | null",
14782
- description: 'Width of the node. Accepts pixel, percentage, fraction values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
15250
+ description: 'Width of the node.\n\nAccepts pixel, percentage, fraction values, or `"fit-content"`.\nSupported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.',
14783
15251
  references: ["WidthLength"]
14784
15252
  },
14785
15253
  {
@@ -14809,7 +15277,7 @@ var methodsByCategory = {
14809
15277
  name: "getNodesWithAttribute",
14810
15278
  category: "VectorSetNode",
14811
15279
  signature: "getNodesWithAttribute(attribute: T): Promise<Node[]>",
14812
- description: 'Get the descendants of this node that support `attribute`. This\nreturns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
15280
+ description: 'Get the descendants of this node that support `attribute`.\n\nThis returns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
14813
15281
  references: ["T", "Node"]
14814
15282
  },
14815
15283
  {
@@ -14823,7 +15291,7 @@ var methodsByCategory = {
14823
15291
  name: "getNodesWithType",
14824
15292
  category: "VectorSetNode",
14825
15293
  signature: 'getNodesWithType(type: "FrameNode"): Promise<FrameNode[]>',
14826
- description: 'Get descendants of this node that match the given type. This can\nalso be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
15294
+ description: 'Get descendants of this node that match the given type.\n\nThis can also be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
14827
15295
  references: ["FrameNode"]
14828
15296
  },
14829
15297
  {
@@ -14837,7 +15305,7 @@ var methodsByCategory = {
14837
15305
  name: "getPluginData",
14838
15306
  category: "VectorSetNode",
14839
15307
  signature: "getPluginData(key: string): Promise<string | null>",
14840
- description: "Get plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
15308
+ description: "Get plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
14841
15309
  references: []
14842
15310
  },
14843
15311
  {
@@ -14858,7 +15326,7 @@ var methodsByCategory = {
14858
15326
  name: "navigateTo",
14859
15327
  category: "VectorSetNode",
14860
15328
  signature: 'navigateTo(opts?: Pick<NavigableOptions, "select" | "zoomIntoView">): Promise<void>',
14861
- description: "Navigate to this node. May switch modes to reveal the relevant view.",
15329
+ description: "Navigate to this node.\n\nMay switch modes to reveal the relevant view.",
14862
15330
  references: ["NavigableOptions"]
14863
15331
  },
14864
15332
  {
@@ -14879,21 +15347,21 @@ var methodsByCategory = {
14879
15347
  name: "setAttributes",
14880
15348
  category: "VectorSetNode",
14881
15349
  signature: 'setAttributes(update: Partial<NodeClassToEditableAttributes[(typeof this)[ClassKey]]>): Promise<(typeof this)[ClassKey] extends "UnknownNode" ? never : typeof this | null>',
14882
- description: 'Set the attributes of this node. Attributes are merged with existing\nvalues, so only the provided attributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
15350
+ description: 'Set the attributes of this node.\n\nAttributes are merged with existing values, so only the provided\nattributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
14883
15351
  references: []
14884
15352
  },
14885
15353
  {
14886
15354
  name: "setPluginData",
14887
15355
  category: "VectorSetNode",
14888
15356
  signature: "setPluginData(key: string, value: string | null): Promise<void>",
14889
- description: 'Set plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
15357
+ description: 'Set plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
14890
15358
  references: []
14891
15359
  },
14892
15360
  {
14893
15361
  name: "walk",
14894
15362
  category: "VectorSetNode",
14895
15363
  signature: "walk(this: AnyNode): AsyncGenerator<AnyNode>",
14896
- description: "Walk this node and its descendants recursively using an async\ngenerator. Yields nodes depth-first.",
15364
+ description: "Walk this node and its descendants recursively.\n\nUses an async generator. Yields nodes depth-first.",
14897
15365
  references: ["AnyNode"]
14898
15366
  },
14899
15367
  {
@@ -14930,7 +15398,7 @@ var methodsByCategory = {
14930
15398
  name: "getActiveCollectionItem",
14931
15399
  category: "WebPageNode",
14932
15400
  signature: "getActiveCollectionItem(): Promise<CollectionItem | null>",
14933
- description: "Get the active collection item for this CMS detail page.\nReturns null if this is not a detail page or the collection is empty.\n\n@alpha",
15401
+ description: "Get the active collection item for this CMS detail page.\n\nReturns null if this is not a detail page or the collection is empty.\n\n@alpha",
14934
15402
  references: ["CollectionItem"]
14935
15403
  },
14936
15404
  {
@@ -14951,7 +15419,7 @@ var methodsByCategory = {
14951
15419
  name: "getNodesWithAttribute",
14952
15420
  category: "WebPageNode",
14953
15421
  signature: "getNodesWithAttribute(attribute: T): Promise<Node[]>",
14954
- description: 'Get the descendants of this node that support `attribute`. This\nreturns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
15422
+ description: 'Get the descendants of this node that support `attribute`.\n\nThis returns nodes that have the given attribute defined in their type,\nregardless of whether it has been set.\n\n@param attribute - The attribute name to filter by.\n@returns An array of nodes that support the attribute.\n\n@example\n```ts\n// Get any kind of node that has a background color attribute.\nconst nodes = await framer.getNodesWithAttribute("backgroundColor")\n```',
14955
15423
  references: ["T", "Node"]
14956
15424
  },
14957
15425
  {
@@ -14965,7 +15433,7 @@ var methodsByCategory = {
14965
15433
  name: "getNodesWithType",
14966
15434
  category: "WebPageNode",
14967
15435
  signature: 'getNodesWithType(type: "FrameNode"): Promise<FrameNode[]>',
14968
- description: 'Get descendants of this node that match the given type. This can\nalso be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
15436
+ description: 'Get descendants of this node that match the given type.\n\nThis can also be used to query within a selection subtree.\n\n@param type - The node type to search for.\n@returns An array of matching descendant nodes.\n\n@example\n```ts\n// Get all frame nodes in a project.\nconst frameNodes = await framer.getNodesWithType("FrameNode")\n\n// Query within a selection subtree.\nconst selection = await framer.getSelection()\nif (selection.length === 1) {\n const frameNodes = await selection[0].getNodesWithType("FrameNode")\n}\n```',
14969
15437
  references: ["FrameNode"]
14970
15438
  },
14971
15439
  {
@@ -14979,7 +15447,7 @@ var methodsByCategory = {
14979
15447
  name: "getPluginData",
14980
15448
  category: "WebPageNode",
14981
15449
  signature: "getPluginData(key: string): Promise<string | null>",
14982
- description: "Get plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
15450
+ description: "Get plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@returns The stored value, or `null` if no data exists for the key.",
14983
15451
  references: []
14984
15452
  },
14985
15453
  {
@@ -15000,7 +15468,7 @@ var methodsByCategory = {
15000
15468
  name: "navigateTo",
15001
15469
  category: "WebPageNode",
15002
15470
  signature: 'navigateTo(opts?: Pick<NavigableOptions, "select" | "zoomIntoView">): Promise<void>',
15003
- description: "Navigate to this node. May switch modes to reveal the relevant view.",
15471
+ description: "Navigate to this node.\n\nMay switch modes to reveal the relevant view.",
15004
15472
  references: ["NavigableOptions"]
15005
15473
  },
15006
15474
  {
@@ -15028,21 +15496,21 @@ var methodsByCategory = {
15028
15496
  name: "setAttributes",
15029
15497
  category: "WebPageNode",
15030
15498
  signature: 'setAttributes(update: Partial<NodeClassToEditableAttributes[(typeof this)[ClassKey]]>): Promise<(typeof this)[ClassKey] extends "UnknownNode" ? never : typeof this | null>',
15031
- description: 'Set the attributes of this node. Attributes are merged with existing\nvalues, so only the provided attributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
15499
+ description: 'Set the attributes of this node.\n\nAttributes are merged with existing values, so only the provided\nattributes are updated.\n\n@param update - The attributes to update.\n@returns The updated node, or `null` if the node was not found.\n@throws If the node is an `UnknownNode`.\n\nUse `"Node.setAttributes"` to check if this method is allowed.',
15032
15500
  references: []
15033
15501
  },
15034
15502
  {
15035
15503
  name: "setPluginData",
15036
15504
  category: "WebPageNode",
15037
15505
  signature: "setPluginData(key: string, value: string | null): Promise<void>",
15038
- description: 'Set plugin data by key. Plugin data lets you store arbitrary\nstring values on individual nodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
15506
+ description: 'Set plugin data by key.\n\nPlugin data lets you store arbitrary string values on individual\nnodes, scoped to your plugin.\n\n@param key - The plugin data key.\n@param value - The value to set, or `null` to remove.\n\nUse `"Node.setPluginData"` to check if this method is allowed.',
15039
15507
  references: []
15040
15508
  },
15041
15509
  {
15042
15510
  name: "walk",
15043
15511
  category: "WebPageNode",
15044
15512
  signature: "walk(this: AnyNode): AsyncGenerator<AnyNode>",
15045
- description: "Walk this node and its descendants recursively using an async\ngenerator. Yields nodes depth-first.",
15513
+ description: "Walk this node and its descendants recursively.\n\nUses an async generator. Yields nodes depth-first.",
15046
15514
  references: ["AnyNode"]
15047
15515
  },
15048
15516
  {
@@ -15061,15 +15529,15 @@ function getMethod(query) {
15061
15529
  return methods?.find((m) => m.name === methodName);
15062
15530
  }
15063
15531
  __name(getMethod, "getMethod");
15064
- function getClass(name) {
15065
- const info = classes[name.toLowerCase()];
15532
+ function getClass(name2) {
15533
+ const info = classes[name2.toLowerCase()];
15066
15534
  if (!info) return void 0;
15067
- const methods = methodsByCategory[name.toLowerCase()] ?? [];
15535
+ const methods = methodsByCategory[name2.toLowerCase()] ?? [];
15068
15536
  return { info, methods };
15069
15537
  }
15070
15538
  __name(getClass, "getClass");
15071
- function getType(name) {
15072
- return types[name.toLowerCase()];
15539
+ function getType(name2) {
15540
+ return types[name2.toLowerCase()];
15073
15541
  }
15074
15542
  __name(getType, "getType");
15075
15543
 
@@ -15086,10 +15554,10 @@ function formatDocComment(text, indent = "") {
15086
15554
  ].join("\n");
15087
15555
  }
15088
15556
  __name(formatDocComment, "formatDocComment");
15089
- function formatClass(name, description, methods) {
15557
+ function formatClass(name2, description, methods) {
15090
15558
  const lines = [];
15091
15559
  if (description) lines.push(formatDocComment(description));
15092
- lines.push(`class ${name} {`);
15560
+ lines.push(`class ${name2} {`);
15093
15561
  let first = true;
15094
15562
  for (const method of methods) {
15095
15563
  if (method.signature.startsWith("[")) continue;
@@ -15219,15 +15687,58 @@ ${typeDef}`);
15219
15687
  }
15220
15688
  __name(renderDocs, "renderDocs");
15221
15689
 
15222
- // src/version.ts
15223
- var VERSION = (
15224
- // typeof is used to ensure this can be used just via tsx or node etc. without build
15225
- "0.0.18"
15226
- );
15227
-
15228
- // src/relay-client.ts
15690
+ // src/headless-server-url.ts
15691
+ var PROD_HEADLESS_SERVER_URL = "wss://api.framer.com/channel/headless-plugin";
15692
+ var DEV_HEADLESS_SERVER_URL = "wss://api.development.framer.com/channel/headless-plugin";
15693
+ function normalizeHeadlessServerUrl(headlessServerUrl) {
15694
+ const url = new URL(headlessServerUrl);
15695
+ url.protocol = url.protocol === "https:" ? "wss:" : url.protocol === "http:" ? "ws:" : url.protocol;
15696
+ return url.toString();
15697
+ }
15698
+ __name(normalizeHeadlessServerUrl, "normalizeHeadlessServerUrl");
15699
+ function resolveHeadlessServerUrl(projectUrlOrId, overrideHeadlessServerUrl) {
15700
+ const override = overrideHeadlessServerUrl?.trim();
15701
+ if (override) {
15702
+ return normalizeHeadlessServerUrl(override);
15703
+ }
15704
+ return inferHeadlessServerUrl(projectUrlOrId);
15705
+ }
15706
+ __name(resolveHeadlessServerUrl, "resolveHeadlessServerUrl");
15707
+ function createProjectBaseUrl(origin) {
15708
+ return new URL("/projects/", origin).toString();
15709
+ }
15710
+ __name(createProjectBaseUrl, "createProjectBaseUrl");
15711
+ function inferHeadlessServerUrl(projectUrlOrId) {
15712
+ try {
15713
+ const projectUrl = new URL(projectUrlOrId);
15714
+ const hostname = projectUrl.hostname.toLowerCase();
15715
+ if (hostname === "development.framer.com") {
15716
+ return DEV_HEADLESS_SERVER_URL;
15717
+ }
15718
+ if (hostname.endsWith(".beta.framer.com")) {
15719
+ const headlessServerUrl = new URL(PROD_HEADLESS_SERVER_URL);
15720
+ headlessServerUrl.searchParams.set(
15721
+ "baseUrl",
15722
+ createProjectBaseUrl(projectUrl.origin)
15723
+ );
15724
+ return headlessServerUrl.toString();
15725
+ }
15726
+ if (hostname.endsWith(".beta.development.framer.com")) {
15727
+ const headlessServerUrl = new URL(DEV_HEADLESS_SERVER_URL);
15728
+ headlessServerUrl.searchParams.set(
15729
+ "baseUrl",
15730
+ createProjectBaseUrl(projectUrl.origin)
15731
+ );
15732
+ return headlessServerUrl.toString();
15733
+ }
15734
+ return PROD_HEADLESS_SERVER_URL;
15735
+ } catch {
15736
+ return PROD_HEADLESS_SERVER_URL;
15737
+ }
15738
+ }
15739
+ __name(inferHeadlessServerUrl, "inferHeadlessServerUrl");
15229
15740
  var __filename$1 = fileURLToPath(import.meta.url);
15230
- var __dirname$1 = path4.dirname(__filename$1);
15741
+ var __dirname$1 = path6.dirname(__filename$1);
15231
15742
  var RELAY_PORT = Number(process.env.FRAMER_CLI_PORT) || 19988;
15232
15743
  var client = createTRPCClient({
15233
15744
  links: [
@@ -15295,7 +15806,7 @@ async function ensureRelayServerRunning(options = {}) {
15295
15806
  logger?.log("Relay server not running, starting it...");
15296
15807
  }
15297
15808
  const isRunningFromSource = __filename$1.endsWith(".ts");
15298
- const scriptPath = isRunningFromSource ? path4.resolve(__dirname$1, "./start-relay-server.ts") : path4.resolve(__dirname$1, "./start-relay-server.js");
15809
+ const scriptPath = isRunningFromSource ? path6.resolve(__dirname$1, "./start-relay-server.ts") : path6.resolve(__dirname$1, "./start-relay-server.js");
15299
15810
  debug("relay", `spawning server process: ${scriptPath}`);
15300
15811
  const serverProcess = spawn(
15301
15812
  isRunningFromSource ? "tsx" : process.execPath,
@@ -15322,32 +15833,30 @@ async function ensureRelayServerRunning(options = {}) {
15322
15833
  throw new Error("Failed to start relay server after 5 seconds");
15323
15834
  }
15324
15835
  __name(ensureRelayServerRunning, "ensureRelayServerRunning");
15325
- var FRAMER_TEMPORARY_DIR = path4.join(os.tmpdir(), "framer");
15836
+ var FRAMER_TEMPORARY_DIR = path6.join(os.tmpdir(), "framer");
15326
15837
  function ensureTemporaryDir() {
15327
- fs3.mkdirSync(FRAMER_TEMPORARY_DIR, { recursive: true });
15838
+ fs6.mkdirSync(FRAMER_TEMPORARY_DIR, { recursive: true });
15328
15839
  }
15329
15840
  __name(ensureTemporaryDir, "ensureTemporaryDir");
15330
- function isTemporaryFile(filePath) {
15331
- const absolutePath = path4.resolve(filePath);
15332
- const isInTemporaryDir = absolutePath.startsWith(
15333
- FRAMER_TEMPORARY_DIR + path4.sep
15334
- );
15335
- const isFile = fs3.statSync(absolutePath, { throwIfNoEntry: false })?.isFile() ?? false;
15336
- return isInTemporaryDir && isFile;
15337
- }
15338
- __name(isTemporaryFile, "isTemporaryFile");
15339
- function removeTemporaryFile(filePath) {
15340
- fs3.unlinkSync(filePath);
15841
+ function cleanupStaleSessionCodeFiles(activeSessionIds) {
15842
+ if (!fs6.existsSync(FRAMER_TEMPORARY_DIR)) return;
15843
+ const activeSessionIdsSet = new Set(activeSessionIds);
15844
+ for (const entry of fs6.readdirSync(FRAMER_TEMPORARY_DIR)) {
15845
+ const [sessionId] = entry.split("-");
15846
+ if (activeSessionIdsSet.has(sessionId)) continue;
15847
+ const filePath = path6.join(FRAMER_TEMPORARY_DIR, entry);
15848
+ fs6.rmSync(filePath, { recursive: true, force: true, maxRetries: 2 });
15849
+ }
15341
15850
  }
15342
- __name(removeTemporaryFile, "removeTemporaryFile");
15851
+ __name(cleanupStaleSessionCodeFiles, "cleanupStaleSessionCodeFiles");
15343
15852
 
15344
15853
  // src/skills.ts
15345
15854
  var META_SKILL_NAME = "framer";
15346
15855
  var CODE_COMPONENTS_SKILL_NAME = "framer-code-components";
15347
- var __dirname2 = path4.dirname(fileURLToPath(import.meta.url));
15348
- var skillsDocsDir = path4.join(__dirname2, "..", "docs", "skills");
15349
- function readSkillDoc(name) {
15350
- return fs3.readFileSync(path4.join(skillsDocsDir, name), "utf-8").trimEnd();
15856
+ var __dirname2 = path6.dirname(fileURLToPath(import.meta.url));
15857
+ var skillsDocsDir = path6.join(__dirname2, "..", "docs", "skills");
15858
+ function readSkillDoc(name2) {
15859
+ return fs6.readFileSync(path6.join(skillsDocsDir, name2), "utf-8").trimEnd();
15351
15860
  }
15352
15861
  __name(readSkillDoc, "readSkillDoc");
15353
15862
  function buildMetaSkill() {
@@ -15369,13 +15878,13 @@ function renderTemplate(template, values) {
15369
15878
  return rendered;
15370
15879
  }
15371
15880
  __name(renderTemplate, "renderTemplate");
15372
- function toProjectSkillName(projectId) {
15373
- const safeProjectId = projectId.replace(/[^a-zA-Z0-9_-]/g, "-");
15374
- return `framer-canvas-editing-project-${safeProjectId}`;
15881
+ var CANVAS_SKILL_PREFIX = "framer-canvas-editing-project-";
15882
+ function toSafeProjectId(projectId) {
15883
+ return projectId.replace(/[^a-zA-Z0-9_-]/g, "-");
15375
15884
  }
15376
- __name(toProjectSkillName, "toProjectSkillName");
15885
+ __name(toSafeProjectId, "toSafeProjectId");
15377
15886
  function buildProjectCanvasSkill(projectId, agentContext, canvasPrompt) {
15378
- const skillName = toProjectSkillName(projectId);
15887
+ const skillName = `${CANVAS_SKILL_PREFIX}${toSafeProjectId(projectId)}`;
15379
15888
  const template = readSkillDoc("framer-canvas-editing-project.md");
15380
15889
  const content = `${renderTemplate(template, {
15381
15890
  SKILL_NAME: skillName,
@@ -15390,32 +15899,48 @@ function buildProjectCanvasSkill(projectId, agentContext, canvasPrompt) {
15390
15899
  }
15391
15900
  __name(buildProjectCanvasSkill, "buildProjectCanvasSkill");
15392
15901
  function writeSkill(root, skillName, content) {
15393
- fs3.mkdirSync(root, { recursive: true });
15394
- const rootStat = fs3.statSync(root);
15902
+ fs6.mkdirSync(root, { recursive: true });
15903
+ const rootStat = fs6.statSync(root);
15395
15904
  if (!rootStat.isDirectory()) {
15396
15905
  throw new Error(`Skill root is not a directory: ${root}`);
15397
15906
  }
15398
- const skillDir = path4.join(root, skillName);
15399
- const filePath = path4.join(skillDir, "SKILL.md");
15400
- if (fs3.existsSync(skillDir)) {
15401
- const current = fs3.lstatSync(skillDir);
15402
- if (current.isSymbolicLink() || !current.isDirectory()) {
15403
- fs3.rmSync(skillDir, { recursive: true, force: true });
15404
- }
15907
+ const skillDir = path6.join(root, skillName);
15908
+ const filePath = path6.join(skillDir, "SKILL.md");
15909
+ const current = fs6.lstatSync(skillDir, { throwIfNoEntry: false });
15910
+ if (current && (current.isSymbolicLink() || !current.isDirectory())) {
15911
+ fs6.rmSync(skillDir, { recursive: true, force: true });
15405
15912
  }
15406
- fs3.mkdirSync(skillDir, { recursive: true });
15407
- fs3.writeFileSync(filePath, content, "utf-8");
15913
+ fs6.mkdirSync(skillDir, { recursive: true });
15914
+ fs6.writeFileSync(filePath, content, "utf-8");
15408
15915
  return filePath;
15409
15916
  }
15410
15917
  __name(writeSkill, "writeSkill");
15411
15918
  function getDefaultSkillRoots() {
15412
15919
  const home = os.homedir();
15413
15920
  return [
15414
- path4.join(home, ".agents", "skills"),
15415
- path4.join(home, ".claude", "skills")
15921
+ path6.join(home, ".agents", "skills"),
15922
+ path6.join(home, ".claude", "skills")
15416
15923
  ];
15417
15924
  }
15418
15925
  __name(getDefaultSkillRoots, "getDefaultSkillRoots");
15926
+ function cleanupStaleSkills(activeProjectIds, skillRoots) {
15927
+ const roots = skillRoots ?? getDefaultSkillRoots();
15928
+ const sanitizedActiveProjectIds = new Set(
15929
+ [...activeProjectIds].map(toSafeProjectId)
15930
+ );
15931
+ for (const root of roots) {
15932
+ if (!fs6.existsSync(root)) continue;
15933
+ for (const entry of fs6.readdirSync(root)) {
15934
+ if (!entry.startsWith(CANVAS_SKILL_PREFIX)) continue;
15935
+ const sanitizedProjectId = entry.slice(CANVAS_SKILL_PREFIX.length);
15936
+ const isActive = sanitizedActiveProjectIds.has(sanitizedProjectId);
15937
+ if (isActive) continue;
15938
+ const skillDir = path6.join(root, entry);
15939
+ fs6.rmSync(skillDir, { recursive: true, force: true, maxRetries: 2 });
15940
+ }
15941
+ }
15942
+ }
15943
+ __name(cleanupStaleSkills, "cleanupStaleSkills");
15419
15944
  function installSkills(options = { type: "base" }) {
15420
15945
  const skillRoots = options.skillRoots ?? getDefaultSkillRoots();
15421
15946
  const skills = [
@@ -15436,18 +15961,24 @@ function installSkills(options = { type: "base" }) {
15436
15961
  content: projectSkill.content
15437
15962
  });
15438
15963
  }
15439
- return skills.map((skill) => ({
15964
+ const results = skills.map((skill) => ({
15440
15965
  skillName: skill.name,
15441
15966
  paths: skillRoots.map(
15442
15967
  (root) => writeSkill(root, skill.name, skill.content)
15443
15968
  )
15444
15969
  }));
15970
+ trackSkillsInstall({
15971
+ skillType: options.type,
15972
+ skillCount: results.length
15973
+ });
15974
+ return results;
15445
15975
  }
15446
15976
  __name(installSkills, "installSkills");
15447
15977
 
15448
15978
  // src/cli.ts
15979
+ var PROGRAM_NAME = "framer-dalton";
15449
15980
  var program = new Command();
15450
- program.name("framer").version(VERSION).description("Framer Server API CLI").option("--debug", "Enable debug logging").hook("preAction", (thisCommand) => {
15981
+ program.name(PROGRAM_NAME).version(VERSION).description("Framer Server API CLI").option("--debug", "Enable debug logging").hook("preAction", (thisCommand) => {
15451
15982
  const opts = thisCommand.opts();
15452
15983
  if (opts.debug) {
15453
15984
  setDebugEnabled(true);
@@ -15466,8 +15997,8 @@ function printSetupSummary(results) {
15466
15997
  const installLocations = /* @__PURE__ */ new Set();
15467
15998
  for (const result of results) {
15468
15999
  for (const filePath of result.paths) {
15469
- const skillDir = path4.dirname(filePath);
15470
- const root = path4.dirname(skillDir);
16000
+ const skillDir = path6.dirname(filePath);
16001
+ const root = path6.dirname(skillDir);
15471
16002
  installLocations.add(root);
15472
16003
  }
15473
16004
  }
@@ -15476,6 +16007,17 @@ function printSetupSummary(results) {
15476
16007
  );
15477
16008
  }
15478
16009
  __name(printSetupSummary, "printSetupSummary");
16010
+ function printTelemetryNotice() {
16011
+ if (isTelemetryNoticeShown()) {
16012
+ return;
16013
+ }
16014
+ printWarning("");
16015
+ printWarning(
16016
+ `Note: Framer collects telemetry. This helps us analyze errors and improve agent UX. Thank you for helping us. You can opt out at any time by running: ${PROGRAM_NAME} telemetry disable`
16017
+ );
16018
+ markTelemetryNoticeShown();
16019
+ }
16020
+ __name(printTelemetryNotice, "printTelemetryNotice");
15479
16021
  async function getAgentSystemPrompt(sessionId) {
15480
16022
  debug("exec", "getAgentSystemPrompt: calling relay...");
15481
16023
  const result = await client.exec.mutate({
@@ -15528,29 +16070,35 @@ async function refreshSkillsFromSession(sessionId, projectId) {
15528
16070
  });
15529
16071
  debug("skills", "skills installed");
15530
16072
  } catch (err) {
15531
- printError(
16073
+ throw new Error(
15532
16074
  `Failed to refresh skills for session ${sessionId}: ${formatError(err)}`
15533
16075
  );
15534
- process.exit(1);
15535
16076
  }
15536
16077
  }
15537
16078
  __name(refreshSkillsFromSession, "refreshSkillsFromSession");
15538
16079
  async function resolveSessionCredentials(projectUrlOrId) {
16080
+ const projectId = extractProjectId(projectUrlOrId);
15539
16081
  try {
15540
- const projectId = extractProjectId(projectUrlOrId);
15541
16082
  debug("credentials", `projectId=${projectId}`);
15542
- const cachedApiKey = getApiKey(projectId);
15543
- if (cachedApiKey) {
16083
+ const cachedProject = getProject(projectId);
16084
+ if (cachedProject) {
15544
16085
  debug("credentials", "using cached API key");
15545
- return { projectId, apiKey: cachedApiKey };
16086
+ return { apiKey: cachedProject.apiKey, userId: cachedProject.userId };
15546
16087
  }
15547
16088
  debug("credentials", "no cached key, starting browser auth flow...");
15548
- const newApiKey = await acquireKeyFromBrowser(projectId);
16089
+ const { apiKey, userId } = await acquireAuthFromBrowser(projectUrlOrId);
15549
16090
  debug("credentials", "browser auth complete, saving project");
15550
- saveProject({ projectId, apiKey: newApiKey });
15551
- return { projectId, apiKey: newApiKey };
16091
+ saveProject({ projectId, apiKey, userId });
16092
+ return { apiKey, userId };
15552
16093
  } catch (err) {
15553
- printError(`Failed to resolve credentials: ${formatError(err)}`);
16094
+ const message = formatError(err);
16095
+ trackError({
16096
+ errorType: "credentials_resolve_error",
16097
+ projectId,
16098
+ errorMessage: message
16099
+ });
16100
+ printError(`Failed to resolve credentials: ${message}`);
16101
+ await waitForTrackingToFinish();
15554
16102
  process.exit(1);
15555
16103
  }
15556
16104
  }
@@ -15573,13 +16121,22 @@ async function getProjectName(sessionId) {
15573
16121
  return projectName;
15574
16122
  }
15575
16123
  __name(getProjectName, "getProjectName");
15576
- async function ensureRelayForCli() {
16124
+ async function ensureRelayForCli(context) {
15577
16125
  try {
15578
16126
  debug("relay", "ensuring relay server is running...");
15579
16127
  await ensureRelayServerRunning({ logger: { log: print } });
15580
16128
  debug("relay", "relay server ready");
15581
16129
  } catch (err) {
15582
- printError(`Failed to check relay status: ${formatError(err)}`);
16130
+ const message = formatError(err);
16131
+ trackError({
16132
+ errorType: context?.errorType ?? "relay_check_error",
16133
+ projectId: context?.projectId,
16134
+ sessionId: context?.sessionId,
16135
+ userId: context?.userId,
16136
+ errorMessage: message
16137
+ });
16138
+ printError(`Failed to check relay status: ${message}`);
16139
+ await waitForTrackingToFinish();
15583
16140
  process.exit(1);
15584
16141
  }
15585
16142
  }
@@ -15597,10 +16154,12 @@ async function execAndPrint(sessionId, code) {
15597
16154
  }
15598
16155
  if (result.error) {
15599
16156
  printError(`Error: ${result.error}`);
16157
+ await waitForTrackingToFinish();
15600
16158
  process.exit(1);
15601
16159
  }
15602
16160
  } catch (err) {
15603
16161
  printError(`Execution failed: ${formatError(err)}`);
16162
+ await waitForTrackingToFinish();
15604
16163
  process.exit(1);
15605
16164
  }
15606
16165
  }
@@ -15614,14 +16173,12 @@ program.command("exec").description("Execute code in a session").requiredOption(
15614
16173
  let code = evalCode;
15615
16174
  if (!code && filePath) {
15616
16175
  try {
15617
- code = fs3.readFileSync(filePath, "utf-8");
16176
+ code = fs6.readFileSync(filePath, "utf-8");
15618
16177
  } catch (err) {
15619
16178
  printError(`Failed to read file: ${formatError(err)}`);
16179
+ await waitForTrackingToFinish();
15620
16180
  process.exit(1);
15621
16181
  }
15622
- if (isTemporaryFile(filePath)) {
15623
- removeTemporaryFile(filePath);
15624
- }
15625
16182
  }
15626
16183
  if (!code && !process.stdin.isTTY) {
15627
16184
  code = await readStdin();
@@ -15657,6 +16214,7 @@ program.command("read-project").description("Read project state for a page").req
15657
16214
  queries = JSON.parse(queriesJson);
15658
16215
  } catch {
15659
16216
  printError("Invalid JSON for --queries");
16217
+ await waitForTrackingToFinish();
15660
16218
  process.exit(1);
15661
16219
  }
15662
16220
  const code = `
@@ -15666,53 +16224,104 @@ program.command("read-project").description("Read project state for a page").req
15666
16224
  await execAndPrint(sessionId, code);
15667
16225
  });
15668
16226
  var session = program.command("session").description("Manage sessions");
15669
- session.command("new <projectUrlOrId>").description("Create a new session and print the session ID").action(async (projectUrlOrId) => {
15670
- debug("session.new", `starting for ${projectUrlOrId}`);
15671
- debug("session.new", "resolving credentials + ensuring relay...");
15672
- const [credentials] = await Promise.all([
15673
- resolveSessionCredentials(projectUrlOrId),
15674
- ensureRelayForCli()
15675
- ]);
15676
- debug(
15677
- "session.new",
15678
- `credentials resolved for project=${credentials.projectId}`
15679
- );
15680
- try {
15681
- debug("session.new", "calling createSession on relay...");
15682
- const result = await client.createSession.mutate({
15683
- projectId: credentials.projectId,
15684
- apiKey: credentials.apiKey
15685
- });
15686
- const sessionId = result.id;
15687
- debug("session.new", `session created id=${sessionId}`);
15688
- debug("session.new", "fetching project name + refreshing skills...");
15689
- const [projectName] = await Promise.all([
15690
- getProjectName(sessionId),
15691
- refreshSkillsFromSession(sessionId, credentials.projectId)
15692
- ]);
15693
- debug("session.new", `project name="${projectName}", skills refreshed`);
15694
- saveProject({
15695
- projectId: credentials.projectId,
15696
- apiKey: credentials.apiKey,
15697
- name: projectName,
15698
- lastUsedAt: (/* @__PURE__ */ new Date()).toISOString()
15699
- });
15700
- debug("session.new", "project saved, printing session id");
15701
- print(sessionId);
15702
- debug("session.new", "done \u2014 process should exit now");
15703
- } catch (err) {
15704
- const message = formatError(err);
15705
- printError(`Failed to create session: ${message}`);
15706
- if (isAuthError(message)) {
15707
- clearApiKey(credentials.projectId);
15708
- printError("The stored API key was invalid and has been removed.");
15709
- printError(
15710
- `Please try creating a session again. This will start a browser authentication flow`
16227
+ session.command("new <projectUrlOrId>").description("Create a new session and print the session ID").option(
16228
+ "--server-url <url>",
16229
+ "Override the headless server URL for this session"
16230
+ ).action(
16231
+ async (projectUrlOrId, options) => {
16232
+ const projectId = extractProjectId(projectUrlOrId);
16233
+ let sessionId;
16234
+ let userId;
16235
+ try {
16236
+ debug("session.new", `starting for ${projectUrlOrId}`);
16237
+ const headlessServerUrl = resolveHeadlessServerUrl(
16238
+ projectUrlOrId,
16239
+ options.serverUrl
15711
16240
  );
16241
+ debug("session.new", `headlessServerUrl=${headlessServerUrl}`);
16242
+ debug("session.new", "resolving credentials + ensuring relay...");
16243
+ const [credentials] = await Promise.all([
16244
+ resolveSessionCredentials(projectUrlOrId),
16245
+ ensureRelayForCli({
16246
+ projectId,
16247
+ errorType: "session_new_relay_error"
16248
+ })
16249
+ ]);
16250
+ userId = credentials.userId;
16251
+ debug("session.new", `credentials resolved for project=${projectId}`);
16252
+ debug("session.new", "calling createSession on relay...");
16253
+ const result = await client.createSession.mutate({
16254
+ projectId,
16255
+ apiKey: credentials.apiKey,
16256
+ userId: credentials.userId,
16257
+ headlessServerUrl
16258
+ });
16259
+ sessionId = result.id;
16260
+ debug("session.new", `session created id=${sessionId}`);
16261
+ debug("session.new", "fetching project name + refreshing skills...");
16262
+ const [projectName] = await Promise.all([
16263
+ getProjectName(sessionId),
16264
+ refreshSkillsFromSession(sessionId, projectId)
16265
+ ]);
16266
+ debug("session.new", `project name="${projectName}", skills refreshed`);
16267
+ saveProject({
16268
+ projectId,
16269
+ apiKey: credentials.apiKey,
16270
+ userId: credentials.userId,
16271
+ name: projectName,
16272
+ lastUsedAt: (/* @__PURE__ */ new Date()).toISOString()
16273
+ });
16274
+ debug("session.new", "cleaning up stale artifacts...");
16275
+ const activeSessions = await client.listSessions.query();
16276
+ const activeProjectIds = activeSessions.map(
16277
+ (activeSession) => activeSession.projectId
16278
+ );
16279
+ try {
16280
+ cleanupStaleSkills(activeProjectIds);
16281
+ } catch (error) {
16282
+ printWarning(
16283
+ `Failed to clean up stale skills: ${formatError(error)}`
16284
+ );
16285
+ }
16286
+ const activeSessionIds = activeSessions.map(
16287
+ (activeSession) => activeSession.id
16288
+ );
16289
+ try {
16290
+ cleanupStaleSessionCodeFiles(activeSessionIds);
16291
+ } catch (error) {
16292
+ printWarning(
16293
+ `Failed to clean up stale session code files: ${formatError(error)}`
16294
+ );
16295
+ }
16296
+ debug(
16297
+ "session.new",
16298
+ `finished cleaning up stale artifacts: projects=${activeProjectIds.join(", ")}, sessions=${activeSessionIds.join(", ")}`
16299
+ );
16300
+ debug("session.new", "project saved, printing session id");
16301
+ print(sessionId);
16302
+ printTelemetryNotice();
16303
+ debug("session.new", "done \u2014 process should exit now");
16304
+ } catch (err) {
16305
+ const message = formatError(err);
16306
+ trackError({
16307
+ errorType: "session_new_error",
16308
+ projectId,
16309
+ userId,
16310
+ errorMessage: message
16311
+ });
16312
+ printError(`Failed to create session: ${message}`);
16313
+ if (isAuthError(message)) {
16314
+ clearApiKey(projectId);
16315
+ printError("The stored API key was invalid and has been removed.");
16316
+ printError(
16317
+ `Please try creating a session again. This will start a browser authentication flow`
16318
+ );
16319
+ }
16320
+ await waitForTrackingToFinish();
16321
+ process.exit(1);
15712
16322
  }
15713
- process.exit(1);
15714
16323
  }
15715
- });
16324
+ );
15716
16325
  session.command("list").description("List all active sessions").action(async () => {
15717
16326
  await ensureRelayForCli();
15718
16327
  try {
@@ -15721,32 +16330,76 @@ session.command("list").description("List all active sessions").action(async ()
15721
16330
  print("No active sessions");
15722
16331
  return;
15723
16332
  }
15724
- printJson(sessions);
16333
+ printJson(
16334
+ sessions.map((session2) => {
16335
+ if (session2.headlessServerUrl !== PROD_HEADLESS_SERVER_URL) {
16336
+ return session2;
16337
+ }
16338
+ return {
16339
+ id: session2.id,
16340
+ projectId: session2.projectId,
16341
+ stateKeys: session2.stateKeys
16342
+ };
16343
+ })
16344
+ );
15725
16345
  } catch (err) {
15726
16346
  printError(`Failed to list sessions: ${formatError(err)}`);
16347
+ await waitForTrackingToFinish();
15727
16348
  process.exit(1);
15728
16349
  }
15729
16350
  });
15730
16351
  var project = program.command("project").description("Manage projects");
15731
16352
  project.command("list").description("List recently used projects").action(() => {
15732
16353
  printJson(
15733
- listProjects().map(({ projectId, name, lastUsedAt }) => ({
16354
+ listProjects().map(({ projectId, name: name2, lastUsedAt }) => ({
15734
16355
  projectId,
15735
- name,
16356
+ name: name2,
15736
16357
  lastUsedAt
15737
16358
  }))
15738
16359
  );
15739
16360
  });
15740
16361
  project.command("auth <projectUrlOrId> [apiKey]").description("Authorize and save a project").action(async (projectUrlOrId, apiKey) => {
15741
16362
  const projectId = extractProjectId(projectUrlOrId);
16363
+ const credentials = apiKey ? { apiKey } : await resolveSessionCredentials(projectUrlOrId);
15742
16364
  if (apiKey) {
15743
- saveProject({ projectId, apiKey });
15744
- } else {
15745
- const credentials = await resolveSessionCredentials(projectUrlOrId);
15746
- saveProject(credentials);
16365
+ trackAuthSuccess({
16366
+ projectId,
16367
+ authMethod: "manual"
16368
+ });
15747
16369
  }
16370
+ saveProject({
16371
+ projectId,
16372
+ apiKey: credentials.apiKey,
16373
+ userId: credentials.userId
16374
+ });
15748
16375
  print(`Project ${projectId} saved`);
15749
16376
  });
16377
+ async function saveAuthResult(verb, authFn) {
16378
+ try {
16379
+ const result = await authFn();
16380
+ const { projectId } = result;
16381
+ if (!projectId) throw new Error("No project ID returned from browser flow");
16382
+ debug(`project.${verb}`, `${projectId} \u2014 saving credentials`);
16383
+ saveProject({ projectId, apiKey: result.apiKey, userId: result.userId });
16384
+ print(`Project ${projectId} saved`);
16385
+ } catch (error) {
16386
+ printError(`Failed to ${verb} project: ${formatError(error)}`);
16387
+ await waitForTrackingToFinish();
16388
+ process.exit(1);
16389
+ }
16390
+ }
16391
+ __name(saveAuthResult, "saveAuthResult");
16392
+ project.command("new").description(
16393
+ "Create a new Framer project via browser approval and save its credentials"
16394
+ ).action(() => saveAuthResult("create", acquireAuthWithNewProject));
16395
+ project.command("remix <sourceProjectUrlOrId>").description(
16396
+ "Remix (duplicate) an existing Framer project via browser approval and save its credentials"
16397
+ ).action(
16398
+ (sourceProjectUrlOrId) => saveAuthResult(
16399
+ "remix",
16400
+ () => acquireAuthWithRemixProject(sourceProjectUrlOrId)
16401
+ )
16402
+ );
15750
16403
  session.command("destroy <sessionId>").description("Destroy a session").action(async (sessionId) => {
15751
16404
  await ensureRelayForCli();
15752
16405
  try {
@@ -15754,6 +16407,7 @@ session.command("destroy <sessionId>").description("Destroy a session").action(a
15754
16407
  print(`Session ${sessionId} destroyed`);
15755
16408
  } catch (err) {
15756
16409
  printError(`Failed to destroy session: ${formatError(err)}`);
16410
+ await waitForTrackingToFinish();
15757
16411
  process.exit(1);
15758
16412
  }
15759
16413
  });
@@ -15777,23 +16431,38 @@ relay.command("restart").description("Restart the relay server").action(async ()
15777
16431
  });
15778
16432
  program.command("setup").description(
15779
16433
  "Install Framer skills into ~/.agents/skills and ~/.claude/skills"
15780
- ).action(() => {
16434
+ ).action(async () => {
15781
16435
  try {
15782
16436
  const results = installSkills();
15783
16437
  printSetupSummary(results);
16438
+ printTelemetryNotice();
15784
16439
  } catch (err) {
15785
16440
  printError(`Setup failed: ${formatError(err)}`);
16441
+ await waitForTrackingToFinish();
15786
16442
  process.exit(1);
15787
16443
  }
15788
16444
  });
15789
16445
  program.command("docs [queries...]").description(
15790
16446
  "Look up API documentation. Use: docs, docs ClassName, docs Class.method, or docs TypeName"
15791
- ).action((queries) => {
16447
+ ).action(async (queries) => {
15792
16448
  const { lines, errors } = renderDocs(queries);
15793
16449
  for (const line of lines) print(line);
15794
16450
  if (errors.length > 0) {
15795
16451
  for (const error of errors) printError(error);
16452
+ await waitForTrackingToFinish();
15796
16453
  process.exit(1);
15797
16454
  }
15798
16455
  });
16456
+ var telemetry = program.command("telemetry").description("Manage telemetry");
16457
+ telemetry.command("enable").description("Enable telemetry").action(() => {
16458
+ setTelemetryEnabled(true);
16459
+ print("Telemetry enabled");
16460
+ });
16461
+ telemetry.command("disable").description("Disable telemetry").action(() => {
16462
+ setTelemetryEnabled(false);
16463
+ print("Telemetry disabled");
16464
+ });
16465
+ telemetry.command("status").description("Show current telemetry status").action(() => {
16466
+ print(`Telemetry is ${isTelemetryEnabled() ? "enabled" : "disabled"}`);
16467
+ });
15799
16468
  program.parse();