@framer/agent 0.0.36 → 0.0.38

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,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import fs8 from 'fs';
3
- import path7 from 'path';
3
+ import path6 from 'path';
4
4
  import { Command } from 'commander';
5
5
  import crypto, { randomUUID } from 'crypto';
6
6
  import http from 'http';
@@ -9,11 +9,11 @@ import { z } from 'zod';
9
9
  import os2 from 'os';
10
10
  import isWsl from 'is-wsl';
11
11
  import { ErrorCode, FramerAPIError } from 'framer-api';
12
- import net from 'net';
13
12
  import { fileURLToPath } from 'url';
13
+ import net from 'net';
14
14
  import { createTRPCClient, httpLink } from '@trpc/client';
15
15
 
16
- /* @framer/ai CLI v0.0.36 */
16
+ /* @framer/ai CLI v0.0.38 */
17
17
  var __defProp = Object.defineProperty;
18
18
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
19
19
 
@@ -107,12 +107,12 @@ function openUrl(url) {
107
107
  __name(openUrl, "openUrl");
108
108
  function getConfigDir() {
109
109
  if (process.env.XDG_CONFIG_HOME) {
110
- return path7.join(process.env.XDG_CONFIG_HOME, "framer");
110
+ return path6.join(process.env.XDG_CONFIG_HOME, "framer");
111
111
  }
112
112
  if (process.platform === "win32") {
113
- return path7.join(process.env.APPDATA || os2.homedir(), "framer");
113
+ return path6.join(process.env.APPDATA || os2.homedir(), "framer");
114
114
  }
115
- return path7.join(os2.homedir(), ".config", "framer");
115
+ return path6.join(os2.homedir(), ".config", "framer");
116
116
  }
117
117
  __name(getConfigDir, "getConfigDir");
118
118
  function ensureConfigDir() {
@@ -123,11 +123,11 @@ __name(ensureConfigDir, "ensureConfigDir");
123
123
 
124
124
  // src/config/projects.ts
125
125
  function getProjectsConfigPath() {
126
- return path7.join(getConfigDir(), "projects.json");
126
+ return path6.join(getConfigDir(), "projects.json");
127
127
  }
128
128
  __name(getProjectsConfigPath, "getProjectsConfigPath");
129
129
  function getLegacyCredentialsPath() {
130
- return path7.join(getConfigDir(), "credentials.json");
130
+ return path6.join(getConfigDir(), "credentials.json");
131
131
  }
132
132
  __name(getLegacyCredentialsPath, "getLegacyCredentialsPath");
133
133
  var ProjectsConfigSchema = z.object({
@@ -313,7 +313,7 @@ var SettingsFileSchema = z.object({
313
313
  telemetryNoticeShown: z.boolean().optional()
314
314
  });
315
315
  function getSettingsPath() {
316
- return path7.join(getConfigDir(), "settings.json");
316
+ return path6.join(getConfigDir(), "settings.json");
317
317
  }
318
318
  __name(getSettingsPath, "getSettingsPath");
319
319
  var settings;
@@ -397,7 +397,7 @@ __name(markTelemetryNoticeShown, "markTelemetryNoticeShown");
397
397
  // src/version.ts
398
398
  var VERSION = (
399
399
  // typeof is used to ensure this can be used just via tsx or node etc. without build
400
- "0.0.36"
400
+ "0.0.38"
401
401
  );
402
402
  var trackingEndpoint = "https://events.framer.com/track";
403
403
  var inProgressTrackings = /* @__PURE__ */ new Set();
@@ -1174,7 +1174,7 @@ var types = {
1174
1174
  members: [
1175
1175
  {
1176
1176
  name: "type",
1177
- type: '"page" | "collection" | "designPage" | "siteSettings" | "component" | "layoutTemplate" | "vectorSet" | "codeFile"',
1177
+ type: '"page" | "collection" | "designPage" | "siteSettings" | "component" | "layoutTemplate" | "vectorSet" | "codeFile" | "colorStyle" | "textStyle" | "linkStyle" | "blockquoteStyle" | "inlineCodeStyle" | "localization" | "localizationGlossary"',
1178
1178
  description: "",
1179
1179
  optional: false
1180
1180
  },
@@ -1314,11 +1314,11 @@ var types = {
1314
1314
  name: "AgentConversationCompletedResult",
1315
1315
  description: "",
1316
1316
  kind: "interface",
1317
- references: [],
1317
+ references: ["AgentResponseMessage"],
1318
1318
  members: [
1319
1319
  {
1320
1320
  name: "responseMessages",
1321
- type: "readonly unknown[]",
1321
+ type: "readonly AgentResponseMessage[]",
1322
1322
  description: "",
1323
1323
  optional: false
1324
1324
  }
@@ -1338,6 +1338,33 @@ var types = {
1338
1338
  }
1339
1339
  ]
1340
1340
  },
1341
+ agentresponsecontentpart: {
1342
+ name: "AgentResponseContentPart",
1343
+ description: "A content part of an assistant response message.\n\nReasoning and tool inputs are internal to the agent: reasoning content is omitted and tool\ncalls only expose the tool name and input. Text parts contain the user-facing response.",
1344
+ kind: "alias",
1345
+ alias: '{\n type: "reasoning";\n} | {\n type: "text";\n text: string;\n} | {\n type: "tool-call";\n toolName: string;\n input: unknown;\n}',
1346
+ references: []
1347
+ },
1348
+ agentresponsemessage: {
1349
+ name: "AgentResponseMessage",
1350
+ description: "An assistant message from an agent turn.\n\nA turn typically produces multiple messages: text emitted between tool calls is progress\nnarration, and the last message containing text is the agent\u2019s final response.",
1351
+ kind: "interface",
1352
+ references: ["AgentResponseContentPart"],
1353
+ members: [
1354
+ {
1355
+ name: "role",
1356
+ type: '"assistant"',
1357
+ description: "",
1358
+ optional: false
1359
+ },
1360
+ {
1361
+ name: "content",
1362
+ type: "readonly AgentResponseContentPart[]",
1363
+ description: "",
1364
+ optional: false
1365
+ }
1366
+ ]
1367
+ },
1341
1368
  agentturnoptions: {
1342
1369
  name: "AgentTurnOptions",
1343
1370
  description: "",
@@ -1355,6 +1382,12 @@ var types = {
1355
1382
  type: "readonly string[]",
1356
1383
  description: "Attach images to this agent turn by URL.\n\nURLs can be external or existing Framer asset URLs. They will be ingested into the\nproject's assets if needed, then made available to the agent as trusted attachment URLs.\n\nTip: if you have a local file (or bytes), upload it first (e.g. `framer.uploadImage(...)`) and\npass the returned asset URL here.",
1357
1384
  optional: true
1385
+ },
1386
+ {
1387
+ name: "fileUrls",
1388
+ type: "readonly string[]",
1389
+ description: "Attach files to this agent turn by URL.\n\nURLs can be external or existing Framer asset URLs. They will be ingested into the\nproject's assets if needed, then made available to the agent as file attachments.",
1390
+ optional: true
1358
1391
  }
1359
1392
  ]
1360
1393
  },
@@ -1395,7 +1428,7 @@ var types = {
1395
1428
  name: "AllMethods",
1396
1429
  description: "",
1397
1430
  kind: "alias",
1398
- alias: "keyof {\n [K in Method as (typeof methodToMessageTypes)[K] extends [] ? never : K]: (typeof methodToMessageTypes)[K];\n}",
1431
+ alias: "keyof { [K in Method as (typeof methodToMessageTypes)[K] extends [] ? never : K]: (typeof methodToMessageTypes)[K] }",
1399
1432
  references: []
1400
1433
  },
1401
1434
  anyeditableattributes: {
@@ -1647,7 +1680,7 @@ var types = {
1647
1680
  name: "AssetData",
1648
1681
  description: "",
1649
1682
  kind: "interface",
1650
- references: ["WithOptionalName"],
1683
+ references: ["WithOptionalName$1"],
1651
1684
  members: [
1652
1685
  {
1653
1686
  name: "url",
@@ -1656,7 +1689,7 @@ var types = {
1656
1689
  optional: false
1657
1690
  }
1658
1691
  ],
1659
- extends: ["WithOptionalName"]
1692
+ extends: ["WithOptionalName$1"]
1660
1693
  },
1661
1694
  assetdatatransfer: {
1662
1695
  name: "AssetDataTransfer",
@@ -2021,7 +2054,7 @@ var types = {
2021
2054
  name: "BytesDataTransfer",
2022
2055
  description: "",
2023
2056
  kind: "alias",
2024
- alias: 'BytesData & {\n type: "bytes";\n}',
2057
+ alias: 'BytesData & {\n type: "bytes";\n}',
2025
2058
  references: ["BytesData"]
2026
2059
  },
2027
2060
  canvasnode: {
@@ -2624,7 +2657,7 @@ var types = {
2624
2657
  members: [
2625
2658
  {
2626
2659
  name: "location",
2627
- type: "{\n x: number;\n y: number;\n }",
2660
+ type: "{\n x: number;\n y: number;\n }",
2628
2661
  description: "Coordinates of the anchor point.",
2629
2662
  optional: false
2630
2663
  },
@@ -3267,7 +3300,7 @@ var types = {
3267
3300
  name: "CustomCode",
3268
3301
  description: "Custom HTML code settings for all injection locations, including disabled state.",
3269
3302
  kind: "alias",
3270
- alias: "Record<CustomCodeLocation, {\n disabled: boolean;\n html: string | null;\n}>",
3303
+ alias: "Record<CustomCodeLocation, {\n disabled: boolean;\n html: string | null;\n}>",
3271
3304
  references: ["CustomCodeLocation"]
3272
3305
  },
3273
3306
  customcodelocation: {
@@ -4012,14 +4045,14 @@ var types = {
4012
4045
  name: "ExplicitPartial",
4013
4046
  description: "The opposite of Partial, can't omit it. Useful for making sure that you don't forget to handle a\nnew property in all cases where objects are built.",
4014
4047
  kind: "alias",
4015
- alias: "{\n [P in keyof T]: T[P] | undefined;\n}",
4048
+ alias: "{ [P in keyof T]: T[P] | undefined }",
4016
4049
  references: []
4017
4050
  },
4018
4051
  extractunmarshaledgradientattributes: {
4019
4052
  name: "ExtractUnmarshaledGradientAttributes",
4020
4053
  description: "",
4021
4054
  kind: "alias",
4022
- alias: "Omit<Extract<UnmarshaledGradient, {\n [classKey]: T[ClassKey];\n}>, ClassKey>",
4055
+ alias: "Omit<Extract<UnmarshaledGradient, {\n [classKey]: T[ClassKey];\n}>, ClassKey>",
4023
4056
  references: ["Extract", "UnmarshaledGradient", "ClassKey"]
4024
4057
  },
4025
4058
  field: {
@@ -4299,7 +4332,7 @@ var types = {
4299
4332
  name: "FontAttributes",
4300
4333
  description: "",
4301
4334
  kind: "alias",
4302
- alias: "Prettify<Partial<{\n weight: FontWeight;\n style: FontStyle$1;\n}>>",
4335
+ alias: "Prettify<Partial<{\n weight: FontWeight;\n style: FontStyle$1;\n}>>",
4303
4336
  references: ["Prettify"]
4304
4337
  },
4305
4338
  fontcontrol: {
@@ -4854,8 +4887,8 @@ var types = {
4854
4887
  name: "ImageData",
4855
4888
  description: "",
4856
4889
  kind: "interface",
4857
- references: ["WithOptionalName", "ImageOptions"],
4858
- extends: ["WithOptionalName", "ImageOptions"]
4890
+ references: ["WithOptionalName$1", "ImageOptions"],
4891
+ extends: ["WithOptionalName$1", "ImageOptions"]
4859
4892
  },
4860
4893
  imagedatafields: {
4861
4894
  name: "ImageDataFields",
@@ -5012,7 +5045,7 @@ var types = {
5012
5045
  name: "InitialState",
5013
5046
  description: "",
5014
5047
  kind: "alias",
5015
- alias: '{\n mode: Mode;\n intent: "plugin/open";\n} | {\n mode: PickModes<"collection" | "syncManagedCollection" | "configureManagedCollection">;\n intent: "collection/add";\n}',
5048
+ alias: '{\n mode: Mode;\n intent: "plugin/open";\n} | {\n mode: PickModes<"collection" | "syncManagedCollection" | "configureManagedCollection">;\n intent: "collection/add";\n}',
5016
5049
  references: []
5017
5050
  },
5018
5051
  inlinelocalizationvaluebylocale: {
@@ -5688,7 +5721,7 @@ var types = {
5688
5721
  name: "LocalizedValueUpdate",
5689
5722
  description: "",
5690
5723
  kind: "alias",
5691
- alias: '{\n action: "set";\n value: string;\n needsReview?: boolean;\n} | {\n action: "clear";\n} | {\n action: "ignore";\n needsReview?: boolean;\n}',
5724
+ alias: '{\n action: "set";\n value: string;\n needsReview?: boolean;\n} | {\n action: "clear";\n} | {\n action: "ignore";\n needsReview?: boolean;\n}',
5692
5725
  references: []
5693
5726
  },
5694
5727
  location: {
@@ -6118,7 +6151,7 @@ var types = {
6118
6151
  name: "NamedFileAssetInput",
6119
6152
  description: "",
6120
6153
  kind: "interface",
6121
- references: ["WithOptionalName", "AssetInput"],
6154
+ references: ["WithOptionalName$1", "AssetInput"],
6122
6155
  members: [
6123
6156
  {
6124
6157
  name: "file",
@@ -6127,7 +6160,7 @@ var types = {
6127
6160
  optional: false
6128
6161
  }
6129
6162
  ],
6130
- extends: ["WithOptionalName"]
6163
+ extends: ["WithOptionalName$1"]
6131
6164
  },
6132
6165
  namedimageassetinput: {
6133
6166
  name: "NamedImageAssetInput",
@@ -6201,7 +6234,7 @@ var types = {
6201
6234
  name: "NodeRuntimeErrorResult",
6202
6235
  description: "",
6203
6236
  kind: "alias",
6204
- alias: '{\n type: "ModuleRuntimeError" | "ReactRenderingError";\n message: string;\n}',
6237
+ alias: '{\n type: "ModuleRuntimeError" | "ReactRenderingError";\n message: string;\n}',
6205
6238
  references: []
6206
6239
  },
6207
6240
  nodetype: {
@@ -6292,7 +6325,7 @@ var types = {
6292
6325
  name: "NullableRecord",
6293
6326
  description: "Type helper to transform a interface so that each value can be null.",
6294
6327
  kind: "alias",
6295
- alias: "{\n [P in keyof T]-?: T[P] | null;\n}",
6328
+ alias: "{ [P in keyof T]-?: T[P] | null }",
6296
6329
  references: []
6297
6330
  },
6298
6331
  numbercontrol: {
@@ -6446,7 +6479,7 @@ var types = {
6446
6479
  name: "Ownership",
6447
6480
  description: "",
6448
6481
  kind: "alias",
6449
- alias: '{\n type: "project";\n} | {\n type: "external";\n name: string;\n}',
6482
+ alias: '{\n type: "project";\n} | {\n type: "external";\n name: string;\n}',
6450
6483
  references: []
6451
6484
  },
6452
6485
  paddingcontrol: {
@@ -6501,7 +6534,7 @@ var types = {
6501
6534
  name: "PerMethodPermissionMap",
6502
6535
  description: "",
6503
6536
  kind: "alias",
6504
- alias: "{\n [K in ProtectedMethod]: boolean;\n}",
6537
+ alias: "{ [K in ProtectedMethod]: boolean }",
6505
6538
  references: []
6506
6539
  },
6507
6540
  pixelnumber: {
@@ -6681,13 +6714,13 @@ var types = {
6681
6714
  },
6682
6715
  {
6683
6716
  name: "getLocaleLanguages",
6684
- type: "() => Promise<{\n code: string;\n name: string;\n }[]>",
6717
+ type: "() => Promise<{\n code: string;\n name: string;\n }[]>",
6685
6718
  description: "@alpha",
6686
6719
  optional: false
6687
6720
  },
6688
6721
  {
6689
6722
  name: "getLocaleRegions",
6690
- type: "(language: string) => Promise<{\n code: string;\n name: string;\n isCommon: boolean;\n }[]>",
6723
+ type: "(language: string) => Promise<{\n code: string;\n name: string;\n isCommon: boolean;\n }[]>",
6691
6724
  description: "@alpha",
6692
6725
  optional: false
6693
6726
  },
@@ -6933,13 +6966,13 @@ var types = {
6933
6966
  },
6934
6967
  {
6935
6968
  name: "addComponentInstance",
6936
- type: "(options: {\n url: string;\n attributes?: Partial<Record<string, unknown>>;\n parentId?: string;\n }) => Promise<SomeNodeData>",
6969
+ type: "(options: {\n url: string;\n attributes?: Partial<Record<string, unknown>>;\n parentId?: string;\n }) => Promise<SomeNodeData>",
6937
6970
  description: "",
6938
6971
  optional: false
6939
6972
  },
6940
6973
  {
6941
6974
  name: "addDetachedComponentLayers",
6942
- type: "(options: {\n url: string;\n layout?: boolean;\n attributes?: Partial<Record<string, unknown>>;\n }) => Promise<SomeNodeData>",
6975
+ type: "(options: {\n url: string;\n layout?: boolean;\n attributes?: Partial<Record<string, unknown>>;\n }) => Promise<SomeNodeData>",
6943
6976
  description: "",
6944
6977
  optional: false
6945
6978
  },
@@ -7335,7 +7368,7 @@ var types = {
7335
7368
  },
7336
7369
  {
7337
7370
  name: "createCodeFile",
7338
- type: "(name: string, code: string, options?: {\n editViaPlugin?: boolean;\n }) => Promise<CodeFileData>",
7371
+ type: "(name: string, code: string, options?: {\n editViaPlugin?: boolean;\n }) => Promise<CodeFileData>",
7339
7372
  description: "",
7340
7373
  optional: false
7341
7374
  },
@@ -7497,7 +7530,7 @@ var types = {
7497
7530
  },
7498
7531
  {
7499
7532
  name: "getChangedPaths",
7500
- type: "() => Promise<{\n added: string[];\n removed: string[];\n modified: string[];\n }>",
7533
+ type: "() => Promise<{\n added: string[];\n removed: string[];\n modified: string[];\n }>",
7501
7534
  description: "@alpha",
7502
7535
  optional: false
7503
7536
  },
@@ -7521,7 +7554,7 @@ var types = {
7521
7554
  },
7522
7555
  {
7523
7556
  name: "getAgentContext",
7524
- type: "(options?: {\n pagePath?: string;\n }) => Promise<string>",
7557
+ type: "(options?: {\n pagePath?: string;\n }) => Promise<string>",
7525
7558
  description: "@alpha",
7526
7559
  optional: false
7527
7560
  },
@@ -7587,43 +7620,49 @@ var types = {
7587
7620
  },
7588
7621
  {
7589
7622
  name: "readProjectForAgent",
7590
- type: "(queries: Record<string, unknown>[], options?: {\n pagePath?: string;\n }) => Promise<{\n results: unknown[];\n }>",
7623
+ type: "(queries: Record<string, unknown>[], options?: {\n pagePath?: string;\n }) => Promise<{\n results: unknown[];\n }>",
7591
7624
  description: "@alpha",
7592
7625
  optional: false
7593
7626
  },
7594
7627
  {
7595
7628
  name: "readComponentControlsForAgent",
7596
- type: "(input: {\n componentIds: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7629
+ type: "(input: {\n componentIds: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7597
7630
  description: "@alpha",
7598
7631
  optional: false
7599
7632
  },
7600
7633
  {
7601
7634
  name: "readIconSetControlsForAgent",
7602
- type: "(input: {\n iconSetNames: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7635
+ type: "(input: {\n iconSetNames: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7603
7636
  description: "@alpha",
7604
7637
  optional: false
7605
7638
  },
7606
7639
  {
7607
7640
  name: "readIconsForAgent",
7608
- type: "(input: {\n iconSetName: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<string[]>",
7641
+ type: "(input: {\n iconSetName: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<string[]>",
7609
7642
  description: "@alpha",
7610
7643
  optional: false
7611
7644
  },
7612
7645
  {
7613
7646
  name: "readLayoutTemplateControlsForAgent",
7614
- type: "(input: {\n layoutTemplateIds: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7647
+ type: "(input: {\n layoutTemplateIds: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7615
7648
  description: "@alpha",
7616
7649
  optional: false
7617
7650
  },
7618
7651
  {
7619
7652
  name: "readShaderControlsForAgent",
7620
- type: "(input: {\n shaderNames: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7653
+ type: "(input: {\n shaderNames: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7621
7654
  description: "@alpha",
7622
7655
  optional: false
7623
7656
  },
7624
7657
  {
7625
7658
  name: "applyAgentChanges",
7626
- type: "(dsl: string, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7659
+ type: "(dsl: string, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7660
+ description: "@alpha",
7661
+ optional: false
7662
+ },
7663
+ {
7664
+ name: "replaceTextForAgent",
7665
+ type: "(input: {\n id: string;\n searchText: string;\n replaceText: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<boolean>",
7627
7666
  description: "@alpha",
7628
7667
  optional: false
7629
7668
  },
@@ -7645,81 +7684,105 @@ var types = {
7645
7684
  description: "@alpha",
7646
7685
  optional: false
7647
7686
  },
7687
+ {
7688
+ name: "queryAnalyticsForAgent",
7689
+ type: "(input: {\n query: string;\n from: string;\n to?: string;\n }) => Promise<unknown[]>",
7690
+ description: "@alpha",
7691
+ optional: false
7692
+ },
7648
7693
  {
7649
7694
  name: "reviewChangesForAgent",
7650
- type: "(options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7695
+ type: "(options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7651
7696
  description: "@alpha",
7652
7697
  optional: false
7653
7698
  },
7654
7699
  {
7655
7700
  name: "flattenComponentInstanceForAgent",
7656
- type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7701
+ type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7657
7702
  description: "@alpha",
7658
7703
  optional: false
7659
7704
  },
7660
7705
  {
7661
7706
  name: "makeExternalComponentLocalForAgent",
7662
- type: "(input: {\n id: string;\n replaceAll?: boolean;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7707
+ type: "(input: {\n id: string;\n replaceAll?: boolean;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7663
7708
  description: "@alpha",
7664
7709
  optional: false
7665
7710
  },
7666
7711
  {
7667
7712
  name: "getNodeForAgent",
7668
- type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7713
+ type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7669
7714
  description: "@alpha",
7670
7715
  optional: false
7671
7716
  },
7672
7717
  {
7673
7718
  name: "getNodesForAgent",
7674
- type: "(input: {\n ids: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7719
+ type: "(input: {\n ids: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7675
7720
  description: "@alpha",
7676
7721
  optional: false
7677
7722
  },
7678
7723
  {
7679
7724
  name: "getNodesOfTypesForAgent",
7680
- type: "(input: {\n types: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7725
+ type: "(input: {\n types: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7726
+ description: "@alpha",
7727
+ optional: false
7728
+ },
7729
+ {
7730
+ name: "getDescendantsOfTypesForAgent",
7731
+ type: "(input: {\n id: string;\n types: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7732
+ description: "@alpha",
7733
+ optional: false
7734
+ },
7735
+ {
7736
+ name: "getRectForAgent",
7737
+ type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<Rect | null>",
7738
+ description: "@alpha",
7739
+ optional: false
7740
+ },
7741
+ {
7742
+ name: "getDescendantReferencesOfTypesForAgent",
7743
+ type: "(input: {\n id: string;\n types: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7681
7744
  description: "@alpha",
7682
7745
  optional: false
7683
7746
  },
7684
7747
  {
7685
7748
  name: "getScopeNodeForAgent",
7686
- type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7749
+ type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7687
7750
  description: "@alpha",
7688
7751
  optional: false
7689
7752
  },
7690
7753
  {
7691
7754
  name: "getGroundNodeForAgent",
7692
- type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7755
+ type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7693
7756
  description: "@alpha",
7694
7757
  optional: false
7695
7758
  },
7696
7759
  {
7697
7760
  name: "getParentNodeForAgent",
7698
- type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7761
+ type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7699
7762
  description: "@alpha",
7700
7763
  optional: false
7701
7764
  },
7702
7765
  {
7703
7766
  name: "getAncestorsForAgent",
7704
- type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7767
+ type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7705
7768
  description: "@alpha",
7706
7769
  optional: false
7707
7770
  },
7708
7771
  {
7709
7772
  name: "serializeForAgent",
7710
- type: "(input: {\n id: string;\n depth?: number;\n attributeFilter?: readonly string[];\n ancestorPath?: boolean;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7773
+ type: "(input: {\n id: string;\n depth?: number;\n attributeFilter?: readonly string[];\n ancestorPath?: boolean;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7711
7774
  description: "@alpha",
7712
7775
  optional: false
7713
7776
  },
7714
7777
  {
7715
7778
  name: "serializeNodesForAgent",
7716
- type: "(input: {\n ids: readonly string[];\n depth?: number;\n attributeFilter?: readonly string[];\n ancestorPath?: boolean;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7779
+ type: "(input: {\n ids: readonly string[];\n depth?: number;\n attributeFilter?: readonly string[];\n ancestorPath?: boolean;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7717
7780
  description: "@alpha",
7718
7781
  optional: false
7719
7782
  },
7720
7783
  {
7721
7784
  name: "paginateForAgent",
7722
- type: "(input: {\n items: readonly unknown[];\n keyName?: never;\n cursor?: never;\n } | {\n keyName: string;\n cursor: number;\n items?: never;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7785
+ type: "(input: {\n items: readonly unknown[];\n keyName?: never;\n cursor?: never;\n } | {\n keyName: string;\n cursor: number;\n items?: never;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7723
7786
  description: "@alpha",
7724
7787
  optional: false
7725
7788
  },
@@ -7906,7 +7969,7 @@ var types = {
7906
7969
  name: "Prettify",
7907
7970
  description: "This alias takes a type as its argument and returns a new type that has the same properties as\nthe original, but the properties are not intersected. This makes the new type easier to read and\nunderstand.\n\nExample:\n```ts\n// Original type:\n{ a: string; } & { b: number; } & { c: boolean; }\n\n// New type:\n{ a: string; b: number; c: boolean; }\n```",
7908
7971
  kind: "alias",
7909
- alias: "{\n [K in keyof T]: T[K] extends object ? Prettify<T[K]> : T[K];\n} & {}",
7972
+ alias: "{ [K in keyof T]: T[K] extends object ? Prettify<T[K]> : T[K] } & {}",
7910
7973
  references: []
7911
7974
  },
7912
7975
  projectinfo: {
@@ -8061,8 +8124,8 @@ var types = {
8061
8124
  alias: '"RadialGradient"',
8062
8125
  references: []
8063
8126
  },
8064
- rect$1: {
8065
- name: "Rect$1",
8127
+ rect: {
8128
+ name: "Rect",
8066
8129
  description: "",
8067
8130
  kind: "interface",
8068
8131
  references: [],
@@ -8295,7 +8358,7 @@ var types = {
8295
8358
  },
8296
8359
  {
8297
8360
  name: "clip",
8298
- type: "{\n x: number;\n y: number;\n width: number;\n height: number;\n }",
8361
+ type: "{\n x: number;\n y: number;\n width: number;\n height: number;\n }",
8299
8362
  description: "Clip region in CSS pixels (before scale).\nCaptures only this portion of the node.",
8300
8363
  optional: true
8301
8364
  }
@@ -8399,13 +8462,13 @@ var types = {
8399
8462
  members: [
8400
8463
  {
8401
8464
  name: "valuesBySource",
8402
- type: "{\n errors: readonly LocalizationValueError[];\n }",
8465
+ type: "{\n errors: readonly LocalizationValueError[];\n }",
8403
8466
  description: "Set one or more localized values",
8404
8467
  optional: false
8405
8468
  },
8406
8469
  {
8407
8470
  name: "statusByLocaleByGroup",
8408
- type: "{\n errors: readonly LocalizationStatusByLocaleError[];\n }",
8471
+ type: "{\n errors: readonly LocalizationStatusByLocaleError[];\n }",
8409
8472
  description: "Set the hidden locale IDs of one or more localization groups",
8410
8473
  optional: false
8411
8474
  }
@@ -8506,8 +8569,8 @@ var types = {
8506
8569
  alias: 'Pick<ComponentInstancePlaceholderAttributes, "title" | "codePreview">',
8507
8570
  references: ["ComponentInstancePlaceholderAttributes"]
8508
8571
  },
8509
- size: {
8510
- name: "Size",
8572
+ size$1: {
8573
+ name: "Size$1",
8511
8574
  description: "",
8512
8575
  kind: "interface",
8513
8576
  references: [],
@@ -8639,7 +8702,7 @@ var types = {
8639
8702
  name: "StartAgentConversationResult",
8640
8703
  description: "",
8641
8704
  kind: "alias",
8642
- alias: "({\n conversationId: string;\n} & AgentConversationCompletedResult) | ({\n conversationId: string;\n} & AgentConversationNeedsClarificationResult)",
8705
+ alias: "({\n conversationId: string;\n} & AgentConversationCompletedResult) | ({\n conversationId: string;\n} & AgentConversationNeedsClarificationResult)",
8643
8706
  references: [
8644
8707
  "AgentConversationCompletedResult",
8645
8708
  "AgentConversationNeedsClarificationResult"
@@ -8835,7 +8898,7 @@ var types = {
8835
8898
  name: "SVGData",
8836
8899
  description: "",
8837
8900
  kind: "interface",
8838
- references: ["WithOptionalName"],
8901
+ references: ["WithOptionalName$1"],
8839
8902
  members: [
8840
8903
  {
8841
8904
  name: "svg",
@@ -8844,7 +8907,7 @@ var types = {
8844
8907
  optional: false
8845
8908
  }
8846
8909
  ],
8847
- extends: ["WithOptionalName"]
8910
+ extends: ["WithOptionalName$1"]
8848
8911
  },
8849
8912
  textalignment: {
8850
8913
  name: "TextAlignment",
@@ -8885,7 +8948,7 @@ var types = {
8885
8948
  name: "TextStyleAttributes",
8886
8949
  description: "",
8887
8950
  kind: "alias",
8888
- alias: 'Prettify<Partial<Omit<TextStyleData, "id" | "color" | "font" | "boldFont" | "italicFont" | "boldItalicFont" | "breakpoints"> & {\n color: ColorStyle | string;\n font: Font;\n boldFont: Font | null;\n italicFont: Font | null;\n boldItalicFont: Font | null;\n breakpoints: TextStyleBreakpointAttributes[];\n}> & AssetPath>',
8951
+ alias: 'Prettify<Partial<Omit<TextStyleData, "id" | "color" | "font" | "boldFont" | "italicFont" | "boldItalicFont" | "breakpoints"> & {\n color: ColorStyle | string;\n font: Font;\n boldFont: Font | null;\n italicFont: Font | null;\n boldItalicFont: Font | null;\n breakpoints: TextStyleBreakpointAttributes[];\n}> & AssetPath>',
8889
8952
  references: ["Prettify", "TextStyleData", "AssetPath"]
8890
8953
  },
8891
8954
  textstylebreakpoint: {
@@ -9634,7 +9697,7 @@ var types = {
9634
9697
  name: "UpdateFieldAttributes",
9635
9698
  description: "The type of the `attributes` parameter of `Field.setAttributes`:\n\n```ts\nconst fileFieldAttributes: UpdateFieldAttributes<FileField> = {}\nfileFieldAttributes.allowedFileTypes = []\nfileField.setAttributes(fileFieldAttributes)\n```\n\nCan also use `typeof`:\n\n```ts\nconst fileFieldAttributes: UpdateFieldAttributes<typeof fileField> = {}\n```",
9636
9699
  kind: "alias",
9637
- alias: 'Omit<Extract<UpdateField, {\n type: T["type"];\n}>,\n"id" | "type">',
9700
+ alias: 'Omit<Extract<UpdateField, {\n type: T["type"];\n}>,\n"id" | "type">',
9638
9701
  references: ["Extract", "UpdateField"]
9639
9702
  },
9640
9703
  updatefieldbase: {
@@ -9841,7 +9904,7 @@ var types = {
9841
9904
  name: "UpdateVariableAttributes",
9842
9905
  description: "",
9843
9906
  kind: "alias",
9844
- alias: 'Omit<Extract<UpdateVariable, {\n type: T["type"];\n}>, "type">',
9907
+ alias: 'Omit<Extract<UpdateVariable, {\n type: T["type"];\n}>, "type">',
9845
9908
  references: ["Extract", "UpdateVariable"]
9846
9909
  },
9847
9910
  updatevariablebase: {
@@ -10868,8 +10931,8 @@ var types = {
10868
10931
  alias: "Partial<WithFieldRequired>",
10869
10932
  references: ["WithFieldRequired"]
10870
10933
  },
10871
- withoptionalname: {
10872
- name: "WithOptionalName",
10934
+ withoptionalname$1: {
10935
+ name: "WithOptionalName$1",
10873
10936
  description: "",
10874
10937
  kind: "interface",
10875
10938
  references: [],
@@ -12169,9 +12232,9 @@ var methodsByCategory = {
12169
12232
  {
12170
12233
  name: "getRect",
12171
12234
  category: "ComponentInstanceNode",
12172
- signature: "getRect(): Promise<Rect$1 | null>",
12235
+ signature: "getRect(): Promise<Rect | null>",
12173
12236
  description: "Get the bounding box of this node.\n\n@returns The bounding rectangle, or `null` if unavailable.",
12174
- references: ["Rect$1"]
12237
+ references: ["Rect"]
12175
12238
  },
12176
12239
  {
12177
12240
  name: "getRuntimeError",
@@ -12441,9 +12504,9 @@ var methodsByCategory = {
12441
12504
  {
12442
12505
  name: "getRect",
12443
12506
  category: "ComponentNode",
12444
- signature: "getRect(): Promise<Rect$1 | null>",
12507
+ signature: "getRect(): Promise<Rect | null>",
12445
12508
  description: "Get the bounding box of this node.\n\n@returns The bounding rectangle, or `null` if unavailable.",
12446
- references: ["Rect$1"]
12509
+ references: ["Rect"]
12447
12510
  },
12448
12511
  {
12449
12512
  name: "getVariables",
@@ -12666,9 +12729,9 @@ var methodsByCategory = {
12666
12729
  {
12667
12730
  name: "getRect",
12668
12731
  category: "DesignPageNode",
12669
- signature: "getRect(): Promise<Rect$1 | null>",
12732
+ signature: "getRect(): Promise<Rect | null>",
12670
12733
  description: "Get the bounding box of this node.\n\n@returns The bounding rectangle, or `null` if unavailable.",
12671
- references: ["Rect$1"]
12734
+ references: ["Rect"]
12672
12735
  },
12673
12736
  {
12674
12737
  name: "navigateTo",
@@ -13187,9 +13250,9 @@ var methodsByCategory = {
13187
13250
  {
13188
13251
  name: "getRect",
13189
13252
  category: "FrameNode",
13190
- signature: "getRect(): Promise<Rect$1 | null>",
13253
+ signature: "getRect(): Promise<Rect | null>",
13191
13254
  description: "Get the bounding box of this node.\n\n@returns The bounding rectangle, or `null` if unavailable.",
13192
- references: ["Rect$1"]
13255
+ references: ["Rect"]
13193
13256
  },
13194
13257
  {
13195
13258
  name: "gridAlignment",
@@ -13609,7 +13672,7 @@ var methodsByCategory = {
13609
13672
  {
13610
13673
  name: "addComponentInstance",
13611
13674
  category: "framer",
13612
- signature: "addComponentInstance({ url, attributes, parentId, }: AddComponentInstanceOptions): Promise<ComponentInstanceNode>",
13675
+ signature: "addComponentInstance({\n url,\n attributes,\n parentId\n }: AddComponentInstanceOptions): Promise<ComponentInstanceNode>",
13613
13676
  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",
13614
13677
  references: ["AddComponentInstanceOptions", "ComponentInstanceNode"]
13615
13678
  },
@@ -13626,7 +13689,7 @@ var methodsByCategory = {
13626
13689
  {
13627
13690
  name: "addDetachedComponentLayers",
13628
13691
  category: "framer",
13629
- signature: "addDetachedComponentLayers({ url, layout, attributes }: AddDetachedComponentLayersOptions): Promise<FrameNode>",
13692
+ signature: "addDetachedComponentLayers({\n url,\n layout,\n attributes\n }: AddDetachedComponentLayersOptions): Promise<FrameNode>",
13630
13693
  description: "Adds the layers of a component by module URL.\n@category canvas",
13631
13694
  references: ["AddDetachedComponentLayersOptions", "FrameNode"]
13632
13695
  },
@@ -13983,9 +14046,9 @@ var methodsByCategory = {
13983
14046
  {
13984
14047
  name: "getRect",
13985
14048
  category: "framer",
13986
- signature: "getRect(nodeId: NodeId): Promise<Rect$1 | null>",
14049
+ signature: "getRect(nodeId: NodeId): Promise<Rect | null>",
13987
14050
  description: "Get the rect of a node\n@category canvas",
13988
- references: ["Rect$1"]
14051
+ references: ["Rect"]
13989
14052
  },
13990
14053
  {
13991
14054
  name: "getRedirects",
@@ -14248,6 +14311,20 @@ var methodsByCategory = {
14248
14311
  description: "Returns the dynamic project context as a string.\n\nThe context includes project-specific data:\n- **Available fonts** \u2014 font families loaded in the project.\n- **Components** \u2014 component names and their controls.\n- **Design tokens** \u2014 color tokens defined in the project.\n- **Style presets** \u2014 text style presets defined in the project.\n- **Icon sets** \u2014 available icon sets and their definitions.\n\nThis data changes per project. Pair with the static prompt\nfrom {@link getSystemPrompt} for complete agent context.\n\n@returns A string containing the project context.",
14249
14312
  references: []
14250
14313
  },
14314
+ {
14315
+ name: "getDescendantReferencesOfTypes",
14316
+ category: "FramerAgentAPI",
14317
+ signature: "getDescendantReferencesOfTypes(input: { id: string; types: readonly string[]; }, options?: { pagePath?: string; }): Promise<unknown>",
14318
+ description: 'Get style and token nodes referenced by a node\'s descendants.\n\n@param input - `{ id, types }`: the ancestor node id and referenced node kinds to match.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The referenced nodes without their children.',
14319
+ references: []
14320
+ },
14321
+ {
14322
+ name: "getDescendantsOfTypes",
14323
+ category: "FramerAgentAPI",
14324
+ signature: "getDescendantsOfTypes(input: { id: string; types: readonly string[]; }, options?: { pagePath?: string; }): Promise<unknown>",
14325
+ description: 'Get descendants of a node with one or more kinds (e.g. `"FrameNode"`, `"RichTextNode"`, `"TextRun"`).\n\n@param input - `{ id, types }`: the ancestor node id and node kinds to match.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The matching descendants without their children.',
14326
+ references: []
14327
+ },
14251
14328
  {
14252
14329
  name: "getGroundNode",
14253
14330
  category: "FramerAgentAPI",
@@ -14283,6 +14360,13 @@ var methodsByCategory = {
14283
14360
  description: 'Get the direct parent of a node.\n\n@param input - `{ id }`: the id of the child node.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The parent node, or `null` if the node has no parent or doesn\'t exist.',
14284
14361
  references: []
14285
14362
  },
14363
+ {
14364
+ name: "getRect",
14365
+ category: "FramerAgentAPI",
14366
+ signature: "getRect(input: { id: string; }, options?: { pagePath?: string; }): Promise<Rect | null>",
14367
+ description: 'Get the measured rect for a node.\n\n@param input - `{ id }`: the id of the node to measure.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The rounded measured rect, or `null` if no node with that id exists on the page.',
14368
+ references: ["Rect"]
14369
+ },
14286
14370
  {
14287
14371
  name: "getScopeNode",
14288
14372
  category: "FramerAgentAPI",
@@ -14339,6 +14423,13 @@ var methodsByCategory = {
14339
14423
  description: "Executes the publish flow on behalf of an agent.\n\nThe input schema is documented in the string returned by {@link getSystemPrompt}.\n\n@param input - Action-discriminated input object (preview / confirm_publish / deploy_to_production).\n@returns The action's result \u2014 status, publish URLs, and any errors, warnings, or changes.",
14340
14424
  references: []
14341
14425
  },
14426
+ {
14427
+ name: "queryAnalytics",
14428
+ category: "FramerAgentAPI",
14429
+ signature: "queryAnalytics(input: { query: string; from: string; to?: string | undefined; }): Promise<unknown[]>",
14430
+ description: "Runs a read-only analytics query against the current site.\n\nThe input schema is documented in the string returned by {@link getSystemPrompt}.\n\n@param input - Query input object (query / from / to). Dates are ISO strings.\n@returns The analytics rows returned by the query.",
14431
+ references: []
14432
+ },
14342
14433
  {
14343
14434
  name: "queryImages",
14344
14435
  category: "FramerAgentAPI",
@@ -14395,6 +14486,13 @@ var methodsByCategory = {
14395
14486
  description: "Renames a branch.\n\n@param branchId - Branch id to rename.\n@param title - New branch title.",
14396
14487
  references: []
14397
14488
  },
14489
+ {
14490
+ name: "replaceText",
14491
+ category: "FramerAgentAPI",
14492
+ signature: "replaceText(input: { id: string; searchText: string; replaceText: string; }, options?: { pagePath?: string; }): Promise<boolean>",
14493
+ description: 'Replaces text within a text-like node.\n\n@param input - `{ id, searchText, replaceText }`: the target node id, text to find, and replacement text.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns `true` when text was replaced, or `false` when no matching text was found.',
14494
+ references: []
14495
+ },
14398
14496
  {
14399
14497
  name: "reviewChanges",
14400
14498
  category: "FramerAgentAPI",
@@ -14451,7 +14549,7 @@ var methodsByCategory = {
14451
14549
  {
14452
14550
  name: "cloneWithAttributes",
14453
14551
  category: "ImageAsset",
14454
- signature: 'cloneWithAttributes({ altText, resolution, }: Prettify<Partial<Pick<ImageAssetData, "altText" | "resolution">>>): ImageAsset',
14552
+ signature: 'cloneWithAttributes({\n altText,\n resolution\n }: Prettify<Partial<Pick<ImageAssetData, "altText" | "resolution">>>): ImageAsset',
14455
14553
  description: "Clone this image asset, optionally overriding `altText` or `resolution`.\nThe clone shares the same underlying image data.",
14456
14554
  references: ["Prettify", "ImageAssetData", "ImageAsset"]
14457
14555
  },
@@ -14479,9 +14577,9 @@ var methodsByCategory = {
14479
14577
  {
14480
14578
  name: "measure",
14481
14579
  category: "ImageAsset",
14482
- signature: "measure(): Promise<Size>",
14580
+ signature: "measure(): Promise<Size$1>",
14483
14581
  description: "Measure this image's natural dimensions.\n\n@returns The width and height in pixels. Warning: values may be zero.",
14484
- references: ["Size"]
14582
+ references: ["Size$1"]
14485
14583
  },
14486
14584
  {
14487
14585
  name: "resolution",
@@ -15025,9 +15123,9 @@ var methodsByCategory = {
15025
15123
  {
15026
15124
  name: "getRect",
15027
15125
  category: "SVGNode",
15028
- signature: "getRect(): Promise<Rect$1 | null>",
15126
+ signature: "getRect(): Promise<Rect | null>",
15029
15127
  description: "Get the bounding box of this node.\n\n@returns The bounding rectangle, or `null` if unavailable.",
15030
- references: ["Rect$1"]
15128
+ references: ["Rect"]
15031
15129
  },
15032
15130
  {
15033
15131
  name: "height",
@@ -15258,9 +15356,9 @@ var methodsByCategory = {
15258
15356
  {
15259
15357
  name: "getRect",
15260
15358
  category: "TextNode",
15261
- signature: "getRect(): Promise<Rect$1 | null>",
15359
+ signature: "getRect(): Promise<Rect | null>",
15262
15360
  description: "Get the bounding box of this node.\n\n@returns The bounding rectangle, or `null` if unavailable.",
15263
- references: ["Rect$1"]
15361
+ references: ["Rect"]
15264
15362
  },
15265
15363
  {
15266
15364
  name: "getText",
@@ -15820,9 +15918,9 @@ var methodsByCategory = {
15820
15918
  {
15821
15919
  name: "getRect",
15822
15920
  category: "UnknownNode",
15823
- signature: "getRect(): Promise<Rect$1 | null>",
15921
+ signature: "getRect(): Promise<Rect | null>",
15824
15922
  description: "Get the bounding box of this node.\n\n@returns The bounding rectangle, or `null` if unavailable.",
15825
- references: ["Rect$1"]
15923
+ references: ["Rect"]
15826
15924
  },
15827
15925
  {
15828
15926
  name: "navigateTo",
@@ -16019,9 +16117,9 @@ var methodsByCategory = {
16019
16117
  {
16020
16118
  name: "getRect",
16021
16119
  category: "VectorSetItemNode",
16022
- signature: "getRect(): Promise<Rect$1 | null>",
16120
+ signature: "getRect(): Promise<Rect | null>",
16023
16121
  description: "Get the bounding box of this node.\n\n@returns The bounding rectangle, or `null` if unavailable.",
16024
- references: ["Rect$1"]
16122
+ references: ["Rect"]
16025
16123
  },
16026
16124
  {
16027
16125
  name: "height",
@@ -16189,9 +16287,9 @@ var methodsByCategory = {
16189
16287
  {
16190
16288
  name: "getRect",
16191
16289
  category: "VectorSetNode",
16192
- signature: "getRect(): Promise<Rect$1 | null>",
16290
+ signature: "getRect(): Promise<Rect | null>",
16193
16291
  description: "Get the bounding box of this node.\n\n@returns The bounding rectangle, or `null` if unavailable.",
16194
- references: ["Rect$1"]
16292
+ references: ["Rect"]
16195
16293
  },
16196
16294
  {
16197
16295
  name: "navigateTo",
@@ -16331,9 +16429,9 @@ var methodsByCategory = {
16331
16429
  {
16332
16430
  name: "getRect",
16333
16431
  category: "WebPageNode",
16334
- signature: "getRect(): Promise<Rect$1 | null>",
16432
+ signature: "getRect(): Promise<Rect | null>",
16335
16433
  description: "Get the bounding box of this node.\n\n@returns The bounding rectangle, or `null` if unavailable.",
16336
- references: ["Rect$1"]
16434
+ references: ["Rect"]
16337
16435
  },
16338
16436
  {
16339
16437
  name: "navigateTo",
@@ -16618,6 +16716,391 @@ ${typeDef}`);
16618
16716
  }
16619
16717
  __name(renderDocs, "renderDocs");
16620
16718
 
16719
+ // src/prompt-context.ts
16720
+ function toKebabId(title) {
16721
+ const id = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
16722
+ return id || "section";
16723
+ }
16724
+ __name(toKebabId, "toKebabId");
16725
+ function uniquifyId(id, seen) {
16726
+ const count = seen.get(id) ?? 0;
16727
+ seen.set(id, count + 1);
16728
+ return count === 0 ? id : `${id}-${count + 1}`;
16729
+ }
16730
+ __name(uniquifyId, "uniquifyId");
16731
+ function splitPromptSections(markdown) {
16732
+ const normalized = markdown.replaceAll("\r\n", "\n");
16733
+ if (normalized.trim() === "") {
16734
+ throw new Error("Cannot split an empty agent prompt.");
16735
+ }
16736
+ const sections = [];
16737
+ let current;
16738
+ for (const line of normalized.split("\n")) {
16739
+ const heading = line.match(/^#\s+(.+?)\s*#*\s*$/u);
16740
+ if (heading) {
16741
+ current = { title: heading[1].trim(), lines: [] };
16742
+ sections.push(current);
16743
+ continue;
16744
+ }
16745
+ if (!current) {
16746
+ current = { title: "Preamble", lines: [] };
16747
+ sections.push(current);
16748
+ }
16749
+ current.lines.push(line);
16750
+ }
16751
+ const seen = /* @__PURE__ */ new Map();
16752
+ return sections.map((section) => ({
16753
+ id: uniquifyId(toKebabId(section.title), seen),
16754
+ title: section.title,
16755
+ content: section.lines.join("\n").trim()
16756
+ })).filter(
16757
+ (section) => section.title !== "Preamble" || section.content !== ""
16758
+ );
16759
+ }
16760
+ __name(splitPromptSections, "splitPromptSections");
16761
+ function renderTemplate(template, values) {
16762
+ let rendered = template;
16763
+ for (const [key, value] of Object.entries(values)) {
16764
+ rendered = rendered.split(`{{${key}}}`).join(value);
16765
+ }
16766
+ return rendered;
16767
+ }
16768
+ __name(renderTemplate, "renderTemplate");
16769
+ function writeRenderedFile(filePath, content) {
16770
+ fs8.mkdirSync(path6.dirname(filePath), { recursive: true });
16771
+ fs8.writeFileSync(filePath, `${content.trimEnd()}
16772
+ `, "utf-8");
16773
+ }
16774
+ __name(writeRenderedFile, "writeRenderedFile");
16775
+ function isTextFile(filePath) {
16776
+ const extension = path6.extname(filePath).toLowerCase();
16777
+ return [
16778
+ ".css",
16779
+ ".html",
16780
+ ".js",
16781
+ ".json",
16782
+ ".md",
16783
+ ".mjs",
16784
+ ".ts",
16785
+ ".tsx",
16786
+ ".txt",
16787
+ ".yaml",
16788
+ ".yml"
16789
+ ].includes(extension);
16790
+ }
16791
+ __name(isTextFile, "isTextFile");
16792
+ function renderFileTree(sourceDir, destinationDir, options) {
16793
+ for (const entry of fs8.readdirSync(sourceDir, { withFileTypes: true })) {
16794
+ const sourcePath = path6.join(sourceDir, entry.name);
16795
+ const destinationPath = path6.join(destinationDir, entry.name);
16796
+ if (entry.isDirectory()) {
16797
+ fs8.mkdirSync(destinationPath, { recursive: true });
16798
+ renderFileTree(sourcePath, destinationPath, options);
16799
+ continue;
16800
+ }
16801
+ if (entry.isSymbolicLink()) {
16802
+ throw new Error(options.getSymlinkErrorMessage(sourcePath));
16803
+ }
16804
+ const renderedDestinationPath = options.getRenderedDestinationPath({
16805
+ sourcePath,
16806
+ destinationPath
16807
+ });
16808
+ if (renderedDestinationPath) {
16809
+ const renderedContent = renderTemplate(
16810
+ fs8.readFileSync(sourcePath, "utf-8"),
16811
+ options.templateValues
16812
+ );
16813
+ writeRenderedFile(
16814
+ renderedDestinationPath,
16815
+ options.transformRenderedContent?.(renderedContent) ?? renderedContent
16816
+ );
16817
+ continue;
16818
+ }
16819
+ fs8.copyFileSync(sourcePath, destinationPath);
16820
+ }
16821
+ }
16822
+ __name(renderFileTree, "renderFileTree");
16823
+ var FRAMER_TEMPORARY_DIR = path6.join(os2.tmpdir(), "framer");
16824
+ function ensureTemporaryDir() {
16825
+ fs8.mkdirSync(FRAMER_TEMPORARY_DIR, { recursive: true });
16826
+ }
16827
+ __name(ensureTemporaryDir, "ensureTemporaryDir");
16828
+ function cleanupStaleSessionCodeFiles(activeSessionIds) {
16829
+ if (!fs8.existsSync(FRAMER_TEMPORARY_DIR)) return;
16830
+ const activeSessionIdsSet = new Set(activeSessionIds);
16831
+ for (const entry of fs8.readdirSync(FRAMER_TEMPORARY_DIR)) {
16832
+ const [sessionId] = entry.split("-");
16833
+ if (activeSessionIdsSet.has(sessionId)) continue;
16834
+ const filePath = path6.join(FRAMER_TEMPORARY_DIR, entry);
16835
+ fs8.rmSync(filePath, { recursive: true, force: true, maxRetries: 2 });
16836
+ }
16837
+ }
16838
+ __name(cleanupStaleSessionCodeFiles, "cleanupStaleSessionCodeFiles");
16839
+
16840
+ // src/skills.ts
16841
+ var META_SKILL_NAME = "framer";
16842
+ var CODE_COMPONENTS_SKILL_NAME = "framer-code-components";
16843
+ var __dirname$1 = path6.dirname(fileURLToPath(import.meta.url));
16844
+ var sourceSkillsDir = path6.join(__dirname$1, "..", "skills");
16845
+ var GENERATED_PROJECTS_DIR_NAME = "projects";
16846
+ var GENERATED_PROJECT_TEMPLATE_ID = "__template__";
16847
+ var PROJECT_SKILL_PREFIX = "framer-project-";
16848
+ var LEGACY_CANVAS_EDITING_SKILL_PREFIX = "framer-canvas-editing-project-";
16849
+ var PACKAGE_NAME = "@framer/agent";
16850
+ var DEFAULT_FRAMER_AGENT_COMMAND = `npx ${PACKAGE_NAME}`;
16851
+ var RELEASE_AGE_OVERRIDE_FRAMER_AGENT_COMMAND = `npx --min-release-age=0 ${PACKAGE_NAME}`;
16852
+ function getFramerAgentCommand() {
16853
+ return isNpxMinReleaseAgeOverrideEnabled() ? RELEASE_AGE_OVERRIDE_FRAMER_AGENT_COMMAND : DEFAULT_FRAMER_AGENT_COMMAND;
16854
+ }
16855
+ __name(getFramerAgentCommand, "getFramerAgentCommand");
16856
+ function replaceDefaultFramerAgentCommand(content) {
16857
+ return content.replaceAll(
16858
+ DEFAULT_FRAMER_AGENT_COMMAND,
16859
+ getFramerAgentCommand()
16860
+ );
16861
+ }
16862
+ __name(replaceDefaultFramerAgentCommand, "replaceDefaultFramerAgentCommand");
16863
+ function getSkillTemplateValues(skillDir) {
16864
+ return {
16865
+ FRAMER_TEMPORARY_DIR,
16866
+ FRAMER_AGENT_COMMAND: getFramerAgentCommand(),
16867
+ FRAMER_SKILL_DIR: skillDir
16868
+ };
16869
+ }
16870
+ __name(getSkillTemplateValues, "getSkillTemplateValues");
16871
+ function toSafeProjectId(projectId) {
16872
+ return projectId.replace(/[^a-zA-Z0-9_-]/g, "-");
16873
+ }
16874
+ __name(toSafeProjectId, "toSafeProjectId");
16875
+ function removeSkillDirContents(skillDir, options) {
16876
+ for (const entry of fs8.readdirSync(skillDir, { withFileTypes: true })) {
16877
+ const entryPath = path6.join(skillDir, entry.name);
16878
+ if (options.preserveGeneratedProjectBundles && entry.name === GENERATED_PROJECTS_DIR_NAME && entry.isDirectory()) {
16879
+ fs8.rmSync(path6.join(entryPath, GENERATED_PROJECT_TEMPLATE_ID), {
16880
+ recursive: true,
16881
+ force: true,
16882
+ maxRetries: 2
16883
+ });
16884
+ continue;
16885
+ }
16886
+ fs8.rmSync(entryPath, { recursive: true, force: true, maxRetries: 2 });
16887
+ }
16888
+ }
16889
+ __name(removeSkillDirContents, "removeSkillDirContents");
16890
+ function prepareSkillDir(root, skillName) {
16891
+ fs8.mkdirSync(root, { recursive: true });
16892
+ const rootStat = fs8.statSync(root);
16893
+ if (!rootStat.isDirectory()) {
16894
+ throw new Error(`Skill root is not a directory: ${root}`);
16895
+ }
16896
+ const skillDir = path6.join(root, skillName);
16897
+ const current = fs8.lstatSync(skillDir, { throwIfNoEntry: false });
16898
+ if (current && (current.isSymbolicLink() || !current.isDirectory())) {
16899
+ fs8.rmSync(skillDir, { recursive: true, force: true });
16900
+ }
16901
+ if (current?.isDirectory()) {
16902
+ removeSkillDirContents(skillDir, {
16903
+ preserveGeneratedProjectBundles: skillName === META_SKILL_NAME
16904
+ });
16905
+ }
16906
+ fs8.mkdirSync(skillDir, { recursive: true });
16907
+ return skillDir;
16908
+ }
16909
+ __name(prepareSkillDir, "prepareSkillDir");
16910
+ function installSourceSkill(root, skillName) {
16911
+ const sourceDir = path6.join(sourceSkillsDir, skillName);
16912
+ const skillDir = prepareSkillDir(root, skillName);
16913
+ renderFileTree(sourceDir, skillDir, {
16914
+ templateValues: getSkillTemplateValues(skillDir),
16915
+ getRenderedDestinationPath: /* @__PURE__ */ __name(({ sourcePath, destinationPath }) => isTextFile(sourcePath) ? destinationPath : void 0, "getRenderedDestinationPath"),
16916
+ getSymlinkErrorMessage: /* @__PURE__ */ __name((sourcePath) => `Source skill contains unsupported symlink: ${sourcePath}`, "getSymlinkErrorMessage")
16917
+ });
16918
+ return path6.join(skillDir, "SKILL.md");
16919
+ }
16920
+ __name(installSourceSkill, "installSourceSkill");
16921
+ function cleanupLegacyCanvasEditingSkills(skillRoots = getDefaultSkillRoots()) {
16922
+ for (const root of skillRoots) {
16923
+ if (!fs8.existsSync(root)) continue;
16924
+ for (const entry of fs8.readdirSync(root)) {
16925
+ if (!entry.startsWith(LEGACY_CANVAS_EDITING_SKILL_PREFIX)) continue;
16926
+ const skillDir = path6.join(root, entry);
16927
+ fs8.rmSync(skillDir, { recursive: true, force: true, maxRetries: 2 });
16928
+ }
16929
+ }
16930
+ }
16931
+ __name(cleanupLegacyCanvasEditingSkills, "cleanupLegacyCanvasEditingSkills");
16932
+ function getDefaultSkillRoots() {
16933
+ const home = os2.homedir();
16934
+ return [
16935
+ path6.join(home, ".agents", "skills"),
16936
+ path6.join(home, ".claude", "skills")
16937
+ ];
16938
+ }
16939
+ __name(getDefaultSkillRoots, "getDefaultSkillRoots");
16940
+ function cleanupProjectSkills(skillRoots = getDefaultSkillRoots()) {
16941
+ for (const root of skillRoots) {
16942
+ if (!fs8.existsSync(root)) continue;
16943
+ for (const entry of fs8.readdirSync(root)) {
16944
+ if (!entry.startsWith(PROJECT_SKILL_PREFIX)) continue;
16945
+ const skillDir = path6.join(root, entry);
16946
+ fs8.rmSync(skillDir, { recursive: true, force: true, maxRetries: 2 });
16947
+ }
16948
+ }
16949
+ }
16950
+ __name(cleanupProjectSkills, "cleanupProjectSkills");
16951
+ function installSkills(options = { type: "base" }) {
16952
+ const skillRoots = options.skillRoots ?? getDefaultSkillRoots();
16953
+ const skillNames = [META_SKILL_NAME, CODE_COMPONENTS_SKILL_NAME];
16954
+ const results = skillNames.map((skillName) => ({
16955
+ skillName,
16956
+ paths: skillRoots.map((root) => installSourceSkill(root, skillName))
16957
+ }));
16958
+ trackSkillsInstall({
16959
+ skillType: options.type,
16960
+ skillCount: results.length
16961
+ });
16962
+ return results;
16963
+ }
16964
+ __name(installSkills, "installSkills");
16965
+
16966
+ // src/generated-project-bundle.ts
16967
+ var PROJECT_BUNDLE_SCHEMA_VERSION = 1;
16968
+ var PROJECT_TEMPLATE_ID = "__template__";
16969
+ var TEMPLATE_FILE_MARKER = ".template";
16970
+ var __dirname2 = path6.dirname(fileURLToPath(import.meta.url));
16971
+ function sha256(content) {
16972
+ return crypto.createHash("sha256").update(content).digest("hex");
16973
+ }
16974
+ __name(sha256, "sha256");
16975
+ function renderPromptFile(section) {
16976
+ return [`# ${section.title}`, "", section.content].join("\n");
16977
+ }
16978
+ __name(renderPromptFile, "renderPromptFile");
16979
+ function getRenderedTemplatePath(filePath) {
16980
+ const extension = path6.extname(filePath);
16981
+ const suffix = `${TEMPLATE_FILE_MARKER}${extension}`;
16982
+ if (!filePath.endsWith(suffix)) return void 0;
16983
+ return filePath.slice(0, -suffix.length) + extension;
16984
+ }
16985
+ __name(getRenderedTemplatePath, "getRenderedTemplatePath");
16986
+ function makeMetadata(options, safeProjectId) {
16987
+ return {
16988
+ projectId: options.projectId,
16989
+ safeProjectId,
16990
+ sessionId: options.sessionId,
16991
+ generatedAt: options.generatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
16992
+ cliVersion: VERSION,
16993
+ promptHash: sha256(options.agentPrompt),
16994
+ contextHash: sha256(options.agentContext),
16995
+ contextSchemaVersion: PROJECT_BUNDLE_SCHEMA_VERSION
16996
+ };
16997
+ }
16998
+ __name(makeMetadata, "makeMetadata");
16999
+ function getInstalledFramerSkillDirs(skillRoots) {
17000
+ return skillRoots.map((root) => path6.join(root, "framer")).filter((skillDir) => fs8.existsSync(path6.join(skillDir, "SKILL.md")));
17001
+ }
17002
+ __name(getInstalledFramerSkillDirs, "getInstalledFramerSkillDirs");
17003
+ function getProjectTemplateDir(skillDir) {
17004
+ const installedTemplateDir = path6.join(
17005
+ skillDir,
17006
+ "projects",
17007
+ PROJECT_TEMPLATE_ID
17008
+ );
17009
+ if (fs8.existsSync(installedTemplateDir)) return installedTemplateDir;
17010
+ return path6.join(
17011
+ __dirname2,
17012
+ "..",
17013
+ "skills",
17014
+ "framer",
17015
+ "projects",
17016
+ PROJECT_TEMPLATE_ID
17017
+ );
17018
+ }
17019
+ __name(getProjectTemplateDir, "getProjectTemplateDir");
17020
+ function cleanupStaleGeneratedProjectBundles(activeProjectIds, skillRoots = getDefaultSkillRoots()) {
17021
+ const activeSafeProjectIds = new Set(activeProjectIds.map(toSafeProjectId));
17022
+ for (const skillDir of getInstalledFramerSkillDirs(skillRoots)) {
17023
+ const projectsDir = path6.join(skillDir, "projects");
17024
+ if (!fs8.existsSync(projectsDir)) continue;
17025
+ for (const entry of fs8.readdirSync(projectsDir, { withFileTypes: true })) {
17026
+ if (!entry.isDirectory()) continue;
17027
+ if (entry.name === PROJECT_TEMPLATE_ID) continue;
17028
+ if (activeSafeProjectIds.has(entry.name)) continue;
17029
+ fs8.rmSync(path6.join(projectsDir, entry.name), {
17030
+ recursive: true,
17031
+ force: true,
17032
+ maxRetries: 2
17033
+ });
17034
+ }
17035
+ }
17036
+ }
17037
+ __name(cleanupStaleGeneratedProjectBundles, "cleanupStaleGeneratedProjectBundles");
17038
+ function makeTemplateValues(metadata, sections, agentContext) {
17039
+ return {
17040
+ PROJECT_ID: metadata.projectId,
17041
+ SAFE_PROJECT_ID: metadata.safeProjectId,
17042
+ SESSION_ID: metadata.sessionId,
17043
+ GENERATED_AT: metadata.generatedAt,
17044
+ PROMPT_SECTION_LIST: sections.map((section) => `- \`prompt/${section.id}.md\` - ${section.title}`).join("\n"),
17045
+ PROJECT_CONTEXT: agentContext,
17046
+ READ_PROJECT_DOCS_COMMAND: replaceDefaultFramerAgentCommand(
17047
+ "npx @framer/agent@latest docs framer.agent.readProject"
17048
+ ),
17049
+ READ_PROJECT_COMMAND: replaceDefaultFramerAgentCommand(
17050
+ `npx @framer/agent@latest read-project -s ${metadata.sessionId} -p "/" -q '<queries-json>'`
17051
+ )
17052
+ };
17053
+ }
17054
+ __name(makeTemplateValues, "makeTemplateValues");
17055
+ function writeGeneratedProjectBundle(options) {
17056
+ const skillRoots = options.skillRoots ?? getDefaultSkillRoots();
17057
+ const framerSkillDirs = getInstalledFramerSkillDirs(skillRoots);
17058
+ if (framerSkillDirs.length === 0) {
17059
+ throw new Error(
17060
+ "Could not find an installed framer skill. Run `@framer/agent setup` before `session new`."
17061
+ );
17062
+ }
17063
+ const safeProjectId = toSafeProjectId(options.projectId);
17064
+ if (safeProjectId === PROJECT_TEMPLATE_ID) {
17065
+ throw new Error(`Project ID resolves to reserved template directory.`);
17066
+ }
17067
+ const renderedPrompt = replaceDefaultFramerAgentCommand(options.agentPrompt);
17068
+ const renderedContext = replaceDefaultFramerAgentCommand(
17069
+ options.agentContext
17070
+ );
17071
+ const sections = splitPromptSections(renderedPrompt);
17072
+ const metadata = makeMetadata(
17073
+ { ...options, agentPrompt: renderedPrompt, agentContext: renderedContext },
17074
+ safeProjectId
17075
+ );
17076
+ const paths = [];
17077
+ for (const skillDir of framerSkillDirs) {
17078
+ const projectDir = path6.join(skillDir, "projects", safeProjectId);
17079
+ const templateDir = getProjectTemplateDir(skillDir);
17080
+ fs8.rmSync(projectDir, { recursive: true, force: true, maxRetries: 2 });
17081
+ fs8.mkdirSync(projectDir, { recursive: true });
17082
+ renderFileTree(templateDir, projectDir, {
17083
+ templateValues: makeTemplateValues(metadata, sections, renderedContext),
17084
+ getRenderedDestinationPath: /* @__PURE__ */ __name(({ sourcePath, destinationPath }) => getRenderedTemplatePath(destinationPath) ?? (isTextFile(sourcePath) ? destinationPath : void 0), "getRenderedDestinationPath"),
17085
+ getSymlinkErrorMessage: /* @__PURE__ */ __name((sourcePath) => `Project template contains unsupported symlink: ${sourcePath}`, "getSymlinkErrorMessage"),
17086
+ transformRenderedContent: replaceDefaultFramerAgentCommand
17087
+ });
17088
+ for (const section of sections) {
17089
+ writeRenderedFile(
17090
+ path6.join(projectDir, "prompt", `${section.id}.md`),
17091
+ renderPromptFile(section)
17092
+ );
17093
+ }
17094
+ writeRenderedFile(
17095
+ path6.join(projectDir, "metadata.json"),
17096
+ JSON.stringify(metadata, null, " ")
17097
+ );
17098
+ paths.push(projectDir);
17099
+ }
17100
+ return { safeProjectId, paths };
17101
+ }
17102
+ __name(writeGeneratedProjectBundle, "writeGeneratedProjectBundle");
17103
+
16621
17104
  // src/headless-server-url.ts
16622
17105
  var PROD_HEADLESS_SERVER_URL = "wss://api.framer.com/channel/headless-plugin";
16623
17106
  var DEV_HEADLESS_SERVER_URL = "wss://api.development.framer.com/channel/headless-plugin";
@@ -16669,7 +17152,7 @@ function inferHeadlessServerUrl(projectUrlOrId) {
16669
17152
  }
16670
17153
  __name(inferHeadlessServerUrl, "inferHeadlessServerUrl");
16671
17154
  function getRelayTokenPath() {
16672
- return path7.join(getConfigDir(), "relay-token");
17155
+ return path6.join(getConfigDir(), "relay-token");
16673
17156
  }
16674
17157
  __name(getRelayTokenPath, "getRelayTokenPath");
16675
17158
  function readRelayToken() {
@@ -16684,7 +17167,7 @@ __name(readRelayToken, "readRelayToken");
16684
17167
 
16685
17168
  // src/relay-client.ts
16686
17169
  var __filename$1 = fileURLToPath(import.meta.url);
16687
- var __dirname$1 = path7.dirname(__filename$1);
17170
+ var __dirname3 = path6.dirname(__filename$1);
16688
17171
  var RELAY_PORT = Number(process.env.FRAMER_CLI_PORT) || 19988;
16689
17172
  var WAIT_TIMEOUT_SECONDS = 5;
16690
17173
  var client = createTRPCClient({
@@ -16809,7 +17292,7 @@ async function ensureRelayServerRunning(options = {}) {
16809
17292
  logger?.log("Relay server not running, starting it...");
16810
17293
  }
16811
17294
  const isRunningFromSource = __filename$1.endsWith(".ts");
16812
- const scriptPath = isRunningFromSource ? path7.resolve(__dirname$1, "./start-relay-server.ts") : path7.resolve(__dirname$1, "./start-relay-server.js");
17295
+ const scriptPath = isRunningFromSource ? path6.resolve(__dirname3, "./start-relay-server.ts") : path6.resolve(__dirname3, "./start-relay-server.js");
16813
17296
  debug("relay", `spawning server process: ${scriptPath}`);
16814
17297
  const serverProcess = spawn(
16815
17298
  isRunningFromSource ? "tsx" : process.execPath,
@@ -16846,171 +17329,6 @@ async function waitForClaudeCodeSkillDiscovery() {
16846
17329
  );
16847
17330
  }
16848
17331
  __name(waitForClaudeCodeSkillDiscovery, "waitForClaudeCodeSkillDiscovery");
16849
- var FRAMER_TEMPORARY_DIR = path7.join(os2.tmpdir(), "framer");
16850
- function ensureTemporaryDir() {
16851
- fs8.mkdirSync(FRAMER_TEMPORARY_DIR, { recursive: true });
16852
- }
16853
- __name(ensureTemporaryDir, "ensureTemporaryDir");
16854
- function cleanupStaleSessionCodeFiles(activeSessionIds) {
16855
- if (!fs8.existsSync(FRAMER_TEMPORARY_DIR)) return;
16856
- const activeSessionIdsSet = new Set(activeSessionIds);
16857
- for (const entry of fs8.readdirSync(FRAMER_TEMPORARY_DIR)) {
16858
- const [sessionId] = entry.split("-");
16859
- if (activeSessionIdsSet.has(sessionId)) continue;
16860
- const filePath = path7.join(FRAMER_TEMPORARY_DIR, entry);
16861
- fs8.rmSync(filePath, { recursive: true, force: true, maxRetries: 2 });
16862
- }
16863
- }
16864
- __name(cleanupStaleSessionCodeFiles, "cleanupStaleSessionCodeFiles");
16865
-
16866
- // src/skills.ts
16867
- var META_SKILL_NAME = "framer";
16868
- var CODE_COMPONENTS_SKILL_NAME = "framer-code-components";
16869
- var __dirname2 = path7.dirname(fileURLToPath(import.meta.url));
16870
- var skillsDocsDir = path7.join(__dirname2, "..", "docs", "skills");
16871
- function readSkillDoc(name2) {
16872
- return fs8.readFileSync(path7.join(skillsDocsDir, name2), "utf-8").trimEnd();
16873
- }
16874
- __name(readSkillDoc, "readSkillDoc");
16875
- function buildMetaSkill() {
16876
- const command = getFramerAgentCommand();
16877
- const template = readSkillDoc("framer.md");
16878
- return `${renderTemplate(template, {
16879
- FRAMER_TEMPORARY_DIR,
16880
- FRAMER_AGENT_COMMAND: command
16881
- })}
16882
- `;
16883
- }
16884
- __name(buildMetaSkill, "buildMetaSkill");
16885
- function buildCodeComponentsSkill() {
16886
- return `${readSkillDoc("framer-code-components.md")}
16887
- `;
16888
- }
16889
- __name(buildCodeComponentsSkill, "buildCodeComponentsSkill");
16890
- function renderTemplate(template, values) {
16891
- let rendered = template;
16892
- for (const [key, value] of Object.entries(values)) {
16893
- rendered = rendered.split(`{{${key}}}`).join(value);
16894
- }
16895
- return rendered;
16896
- }
16897
- __name(renderTemplate, "renderTemplate");
16898
- var PROJECT_SKILL_PREFIX = "framer-project-";
16899
- var LEGACY_CANVAS_EDITING_SKILL_PREFIX = "framer-canvas-editing-project-";
16900
- var PACKAGE_NAME = "@framer/agent";
16901
- var DEFAULT_FRAMER_AGENT_COMMAND = `npx ${PACKAGE_NAME}`;
16902
- var RELEASE_AGE_OVERRIDE_FRAMER_AGENT_COMMAND = `npx --min-release-age=0 ${PACKAGE_NAME}`;
16903
- function getFramerAgentCommand() {
16904
- return isNpxMinReleaseAgeOverrideEnabled() ? RELEASE_AGE_OVERRIDE_FRAMER_AGENT_COMMAND : DEFAULT_FRAMER_AGENT_COMMAND;
16905
- }
16906
- __name(getFramerAgentCommand, "getFramerAgentCommand");
16907
- function toSafeProjectId(projectId) {
16908
- return projectId.replace(/[^a-zA-Z0-9_-]/g, "-");
16909
- }
16910
- __name(toSafeProjectId, "toSafeProjectId");
16911
- function buildProjectSkill(projectId, agentContext, agentPrompt) {
16912
- const command = getFramerAgentCommand();
16913
- const skillName = `${PROJECT_SKILL_PREFIX}${toSafeProjectId(projectId)}`;
16914
- const template = readSkillDoc("framer-project.md");
16915
- const content = `${renderTemplate(template, {
16916
- SKILL_NAME: skillName,
16917
- PROJECT_ID: projectId,
16918
- GENERATED_AT: (/* @__PURE__ */ new Date()).toISOString(),
16919
- AGENT_PROMPT: agentPrompt.trimEnd().replaceAll(DEFAULT_FRAMER_AGENT_COMMAND, command),
16920
- AGENT_CONTEXT: agentContext.trimEnd().replaceAll(DEFAULT_FRAMER_AGENT_COMMAND, command),
16921
- FRAMER_TEMPORARY_DIR,
16922
- FRAMER_AGENT_COMMAND: command
16923
- })}
16924
- `;
16925
- return { skillName, content };
16926
- }
16927
- __name(buildProjectSkill, "buildProjectSkill");
16928
- function writeSkill(root, skillName, content) {
16929
- fs8.mkdirSync(root, { recursive: true });
16930
- const rootStat = fs8.statSync(root);
16931
- if (!rootStat.isDirectory()) {
16932
- throw new Error(`Skill root is not a directory: ${root}`);
16933
- }
16934
- const skillDir = path7.join(root, skillName);
16935
- const filePath = path7.join(skillDir, "SKILL.md");
16936
- const current = fs8.lstatSync(skillDir, { throwIfNoEntry: false });
16937
- if (current && (current.isSymbolicLink() || !current.isDirectory())) {
16938
- fs8.rmSync(skillDir, { recursive: true, force: true });
16939
- }
16940
- fs8.mkdirSync(skillDir, { recursive: true });
16941
- fs8.writeFileSync(filePath, content, "utf-8");
16942
- return filePath;
16943
- }
16944
- __name(writeSkill, "writeSkill");
16945
- function cleanupLegacyCanvasEditingSkills(skillRoots = getDefaultSkillRoots()) {
16946
- for (const root of skillRoots) {
16947
- if (!fs8.existsSync(root)) continue;
16948
- for (const entry of fs8.readdirSync(root)) {
16949
- if (!entry.startsWith(LEGACY_CANVAS_EDITING_SKILL_PREFIX)) continue;
16950
- const skillDir = path7.join(root, entry);
16951
- fs8.rmSync(skillDir, { recursive: true, force: true, maxRetries: 2 });
16952
- }
16953
- }
16954
- }
16955
- __name(cleanupLegacyCanvasEditingSkills, "cleanupLegacyCanvasEditingSkills");
16956
- function getDefaultSkillRoots() {
16957
- const home = os2.homedir();
16958
- return [
16959
- path7.join(home, ".agents", "skills"),
16960
- path7.join(home, ".claude", "skills")
16961
- ];
16962
- }
16963
- __name(getDefaultSkillRoots, "getDefaultSkillRoots");
16964
- function cleanupStaleSkills(activeProjectIds, skillRoots = getDefaultSkillRoots()) {
16965
- const sanitizedActiveProjectIds = new Set(
16966
- [...activeProjectIds].map(toSafeProjectId)
16967
- );
16968
- for (const root of skillRoots) {
16969
- if (!fs8.existsSync(root)) continue;
16970
- for (const entry of fs8.readdirSync(root)) {
16971
- if (!entry.startsWith(PROJECT_SKILL_PREFIX)) continue;
16972
- const sanitizedProjectId = entry.slice(PROJECT_SKILL_PREFIX.length);
16973
- const isActive = sanitizedActiveProjectIds.has(sanitizedProjectId);
16974
- if (isActive) continue;
16975
- const skillDir = path7.join(root, entry);
16976
- fs8.rmSync(skillDir, { recursive: true, force: true, maxRetries: 2 });
16977
- }
16978
- }
16979
- }
16980
- __name(cleanupStaleSkills, "cleanupStaleSkills");
16981
- function installSkills(options = { type: "base" }) {
16982
- const skillRoots = options.skillRoots ?? getDefaultSkillRoots();
16983
- const skills = [
16984
- { name: META_SKILL_NAME, content: buildMetaSkill() },
16985
- {
16986
- name: CODE_COMPONENTS_SKILL_NAME,
16987
- content: buildCodeComponentsSkill()
16988
- }
16989
- ];
16990
- if (options.type === "project") {
16991
- const projectSkill = buildProjectSkill(
16992
- options.projectId,
16993
- options.agentContext,
16994
- options.agentPrompt
16995
- );
16996
- skills.push({
16997
- name: projectSkill.skillName,
16998
- content: projectSkill.content
16999
- });
17000
- }
17001
- const results = skills.map((skill) => ({
17002
- skillName: skill.name,
17003
- paths: skillRoots.map(
17004
- (root) => writeSkill(root, skill.name, skill.content)
17005
- )
17006
- }));
17007
- trackSkillsInstall({
17008
- skillType: options.type,
17009
- skillCount: results.length
17010
- });
17011
- return results;
17012
- }
17013
- __name(installSkills, "installSkills");
17014
17332
 
17015
17333
  // src/cli.ts
17016
17334
  var PROGRAM_NAME = "@framer/agent";
@@ -17038,8 +17356,8 @@ function printSetupSummary(results) {
17038
17356
  const installLocations = /* @__PURE__ */ new Set();
17039
17357
  for (const result of results) {
17040
17358
  for (const filePath of result.paths) {
17041
- const skillDir = path7.dirname(filePath);
17042
- const root = path7.dirname(skillDir);
17359
+ const skillDir = path6.dirname(filePath);
17360
+ const root = path6.dirname(skillDir);
17043
17361
  installLocations.add(root);
17044
17362
  }
17045
17363
  }
@@ -17067,6 +17385,13 @@ async function installBaseSkills() {
17067
17385
  `Failed to clean up legacy canvas editing skills: ${formatErrorForUser(error)}`
17068
17386
  );
17069
17387
  }
17388
+ try {
17389
+ cleanupProjectSkills();
17390
+ } catch (error) {
17391
+ printWarning(
17392
+ `Failed to clean up generated project skills: ${formatErrorForUser(error)}`
17393
+ );
17394
+ }
17070
17395
  const results = installSkills();
17071
17396
  await waitForClaudeCodeSkillDiscovery();
17072
17397
  return results;
@@ -17104,29 +17429,30 @@ async function getAgentContext(sessionId) {
17104
17429
  return context;
17105
17430
  }
17106
17431
  __name(getAgentContext, "getAgentContext");
17107
- async function refreshSkillsFromSession(sessionId, projectId) {
17432
+ async function refreshGeneratedProjectBundleFromSession(sessionId, projectId) {
17108
17433
  try {
17109
17434
  debug("skills", "fetching agent system prompt + context...");
17110
17435
  const [agentPrompt, agentContext] = await Promise.all([
17111
17436
  getAgentSystemPrompt(sessionId),
17112
17437
  getAgentContext(sessionId)
17113
17438
  ]);
17114
- debug("skills", "installing skills...");
17115
- installSkills({
17116
- type: "project",
17439
+ debug("skills", "writing generated project bundle...");
17440
+ writeGeneratedProjectBundle({
17117
17441
  agentPrompt,
17118
17442
  projectId,
17443
+ sessionId,
17119
17444
  agentContext
17120
17445
  });
17121
- debug("skills", "skills installed");
17446
+ debug("skills", "generated project bundle written");
17447
+ await waitForClaudeCodeSkillDiscovery();
17122
17448
  } catch (err) {
17123
17449
  throw errorWithRef(
17124
- `Failed to refresh skills for session ${sessionId}: ${formatError(err)}`,
17450
+ `Failed to refresh generated project bundle for session ${sessionId}: ${formatError(err)}`,
17125
17451
  getErrorRef(err)
17126
17452
  );
17127
17453
  }
17128
17454
  }
17129
- __name(refreshSkillsFromSession, "refreshSkillsFromSession");
17455
+ __name(refreshGeneratedProjectBundleFromSession, "refreshGeneratedProjectBundleFromSession");
17130
17456
  async function resolveSessionCredentials(projectUrlOrId) {
17131
17457
  const projectId = extractProjectId(projectUrlOrId);
17132
17458
  try {
@@ -17315,13 +17641,18 @@ session.command("new <projectUrlOrId>").description("Create a new session and pr
17315
17641
  });
17316
17642
  sessionId = result.id;
17317
17643
  debug("session.new", `session created id=${sessionId}`);
17318
- debug("session.new", "fetching project name + refreshing skills...");
17644
+ debug(
17645
+ "session.new",
17646
+ "fetching project name + refreshing generated bundle..."
17647
+ );
17319
17648
  const [projectName] = await Promise.all([
17320
17649
  getProjectName(sessionId),
17321
- refreshSkillsFromSession(sessionId, projectId)
17650
+ refreshGeneratedProjectBundleFromSession(sessionId, projectId)
17322
17651
  ]);
17323
- debug("session.new", `project name="${projectName}", skills refreshed`);
17324
- await waitForClaudeCodeSkillDiscovery();
17652
+ debug(
17653
+ "session.new",
17654
+ `project name="${projectName}", generated files written`
17655
+ );
17325
17656
  saveProject({
17326
17657
  projectId,
17327
17658
  apiKey: credentials.apiKey,
@@ -17335,10 +17666,10 @@ session.command("new <projectUrlOrId>").description("Create a new session and pr
17335
17666
  (activeSession) => activeSession.projectId
17336
17667
  );
17337
17668
  try {
17338
- cleanupStaleSkills(activeProjectIds);
17669
+ cleanupStaleGeneratedProjectBundles(activeProjectIds);
17339
17670
  } catch (error) {
17340
17671
  printWarning(
17341
- `Failed to clean up stale skills: ${formatErrorForUser(error)}`
17672
+ `Failed to clean up stale generated project bundles: ${formatErrorForUser(error)}`
17342
17673
  );
17343
17674
  }
17344
17675
  const activeSessionIds = activeSessions.map(