framer-dalton 0.0.21 → 0.0.23

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
- import fs6 from 'fs';
3
- import path6 from 'path';
2
+ import fs7 from 'fs';
3
+ import path7 from 'path';
4
4
  import { Command } from 'commander';
5
5
  import crypto, { randomUUID } from 'crypto';
6
6
  import http from 'http';
@@ -10,7 +10,7 @@ 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.21 */
13
+ /* @framer/ai CLI v0.0.23 */
14
14
  var __defProp = Object.defineProperty;
15
15
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
16
16
 
@@ -50,27 +50,27 @@ function openUrl(url) {
50
50
  __name(openUrl, "openUrl");
51
51
  function getConfigDir() {
52
52
  if (process.env.XDG_CONFIG_HOME) {
53
- return path6.join(process.env.XDG_CONFIG_HOME, "framer");
53
+ return path7.join(process.env.XDG_CONFIG_HOME, "framer");
54
54
  }
55
55
  if (process.platform === "win32") {
56
- return path6.join(process.env.APPDATA || os.homedir(), "framer");
56
+ return path7.join(process.env.APPDATA || os.homedir(), "framer");
57
57
  }
58
- return path6.join(os.homedir(), ".config", "framer");
58
+ return path7.join(os.homedir(), ".config", "framer");
59
59
  }
60
60
  __name(getConfigDir, "getConfigDir");
61
61
  function ensureConfigDir() {
62
62
  const configDir = getConfigDir();
63
- fs6.mkdirSync(configDir, { recursive: true, mode: 448 });
63
+ fs7.mkdirSync(configDir, { recursive: true, mode: 448 });
64
64
  }
65
65
  __name(ensureConfigDir, "ensureConfigDir");
66
66
 
67
67
  // src/config/projects.ts
68
68
  function getProjectsConfigPath() {
69
- return path6.join(getConfigDir(), "projects.json");
69
+ return path7.join(getConfigDir(), "projects.json");
70
70
  }
71
71
  __name(getProjectsConfigPath, "getProjectsConfigPath");
72
72
  function getLegacyCredentialsPath() {
73
- return path6.join(getConfigDir(), "credentials.json");
73
+ return path7.join(getConfigDir(), "credentials.json");
74
74
  }
75
75
  __name(getLegacyCredentialsPath, "getLegacyCredentialsPath");
76
76
  var ProjectsConfigSchema = z.object({
@@ -88,7 +88,7 @@ var ProjectsConfigSchema = z.object({
88
88
  var LegacyCredentialsSchema = z.record(z.string(), z.string());
89
89
  function readJsonFile(filePath) {
90
90
  try {
91
- return JSON.parse(fs6.readFileSync(filePath, "utf-8"));
91
+ return JSON.parse(fs7.readFileSync(filePath, "utf-8"));
92
92
  } catch (_error) {
93
93
  return null;
94
94
  }
@@ -96,7 +96,7 @@ function readJsonFile(filePath) {
96
96
  __name(readJsonFile, "readJsonFile");
97
97
  function writeProjectsConfig(config) {
98
98
  ensureConfigDir();
99
- fs6.writeFileSync(
99
+ fs7.writeFileSync(
100
100
  getProjectsConfigPath(),
101
101
  JSON.stringify(config, null, " "),
102
102
  {
@@ -123,7 +123,7 @@ function migrateLegacyCredentials() {
123
123
  }
124
124
  const config = { version: 2, projects };
125
125
  writeProjectsConfig(config);
126
- fs6.rmSync(getLegacyCredentialsPath(), { force: true });
126
+ fs7.rmSync(getLegacyCredentialsPath(), { force: true });
127
127
  return config;
128
128
  }
129
129
  __name(migrateLegacyCredentials, "migrateLegacyCredentials");
@@ -136,7 +136,7 @@ function readProjectsConfig() {
136
136
  return result.data;
137
137
  }
138
138
  }
139
- if (fs6.existsSync(getLegacyCredentialsPath())) {
139
+ if (fs7.existsSync(getLegacyCredentialsPath())) {
140
140
  return migrateLegacyCredentials();
141
141
  }
142
142
  return { version: 2, projects: {} };
@@ -219,7 +219,7 @@ var SettingsWatcher = class {
219
219
  __name(this, "SettingsWatcher");
220
220
  }
221
221
  start(callback) {
222
- fs6.watchFile(
222
+ fs7.watchFile(
223
223
  this.settingsPath,
224
224
  { persistent: false, interval: fsPollIntervalMs },
225
225
  (curr, prev) => {
@@ -236,7 +236,7 @@ var SettingsWatcher = class {
236
236
  return this;
237
237
  }
238
238
  stop() {
239
- fs6.unwatchFile(this.settingsPath);
239
+ fs7.unwatchFile(this.settingsPath);
240
240
  return this;
241
241
  }
242
242
  };
@@ -254,7 +254,7 @@ var SettingsFileSchema = z.object({
254
254
  telemetryNoticeShown: z.boolean().optional()
255
255
  });
256
256
  function getSettingsPath() {
257
- return path6.join(getConfigDir(), "settings.json");
257
+ return path7.join(getConfigDir(), "settings.json");
258
258
  }
259
259
  __name(getSettingsPath, "getSettingsPath");
260
260
  var settings;
@@ -273,7 +273,7 @@ __name(getSettings, "getSettings");
273
273
  function readSettingsFile() {
274
274
  const settingsPath = getSettingsPath();
275
275
  try {
276
- const raw = JSON.parse(fs6.readFileSync(settingsPath, "utf-8"));
276
+ const raw = JSON.parse(fs7.readFileSync(settingsPath, "utf-8"));
277
277
  const result = SettingsFileSchema.parse(raw);
278
278
  return {
279
279
  machineId: result.machineId ?? DEFAULT_SETTINGS.machineId,
@@ -292,7 +292,7 @@ function setSettings(newSettings) {
292
292
  __name(setSettings, "setSettings");
293
293
  function writeSettingsFile(settings2) {
294
294
  ensureConfigDir();
295
- fs6.writeFileSync(getSettingsPath(), JSON.stringify(settings2, null, " "), {
295
+ fs7.writeFileSync(getSettingsPath(), JSON.stringify(settings2, null, " "), {
296
296
  mode: 384
297
297
  });
298
298
  }
@@ -328,7 +328,7 @@ __name(markTelemetryNoticeShown, "markTelemetryNoticeShown");
328
328
  // src/version.ts
329
329
  var VERSION = (
330
330
  // typeof is used to ensure this can be used just via tsx or node etc. without build
331
- "0.0.21"
331
+ "0.0.23"
332
332
  );
333
333
  var trackingEndpoint = "https://events.framer.com/track";
334
334
  var inProgressTrackings = /* @__PURE__ */ new Set();
@@ -6293,6 +6293,12 @@ var types = {
6293
6293
  description: "@alpha",
6294
6294
  optional: false
6295
6295
  },
6296
+ {
6297
+ name: "unstable_getDependencyVersion",
6298
+ type: 'FramerPluginAPIAlpha["unstable_getDependencyVersion"]',
6299
+ description: "@alpha",
6300
+ optional: false
6301
+ },
6296
6302
  {
6297
6303
  name: "unstable_ensureMinimumDependencyVersion",
6298
6304
  type: 'FramerPluginAPI["unstable_ensureMinimumDependencyVersion"]',
@@ -7133,12 +7139,96 @@ var types = {
7133
7139
  description: "@alpha",
7134
7140
  optional: false
7135
7141
  },
7142
+ {
7143
+ name: "publishForAgent",
7144
+ type: "(input?: Record<string, unknown>) => Promise<unknown>",
7145
+ description: "@alpha",
7146
+ optional: false
7147
+ },
7148
+ {
7149
+ name: "queryImagesForAgent",
7150
+ type: "(input: Record<string, unknown>) => Promise<unknown>",
7151
+ description: "@alpha",
7152
+ optional: false
7153
+ },
7136
7154
  {
7137
7155
  name: "reviewChangesForAgent",
7138
7156
  type: "(options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7139
7157
  description: "@alpha",
7140
7158
  optional: false
7141
7159
  },
7160
+ {
7161
+ name: "flattenComponentInstanceForAgent",
7162
+ type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7163
+ description: "@alpha",
7164
+ optional: false
7165
+ },
7166
+ {
7167
+ name: "makeExternalComponentLocalForAgent",
7168
+ type: "(input: {\n id: string;\n replaceAll?: boolean;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7169
+ description: "@alpha",
7170
+ optional: false
7171
+ },
7172
+ {
7173
+ name: "getNodeForAgent",
7174
+ type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7175
+ description: "@alpha",
7176
+ optional: false
7177
+ },
7178
+ {
7179
+ name: "getNodesForAgent",
7180
+ type: "(input: {\n ids: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7181
+ description: "@alpha",
7182
+ optional: false
7183
+ },
7184
+ {
7185
+ name: "getNodesOfTypesForAgent",
7186
+ type: "(input: {\n types: readonly string[];\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7187
+ description: "@alpha",
7188
+ optional: false
7189
+ },
7190
+ {
7191
+ name: "getScopeNodeForAgent",
7192
+ type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7193
+ description: "@alpha",
7194
+ optional: false
7195
+ },
7196
+ {
7197
+ name: "getGroundNodeForAgent",
7198
+ type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7199
+ description: "@alpha",
7200
+ optional: false
7201
+ },
7202
+ {
7203
+ name: "getParentNodeForAgent",
7204
+ type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7205
+ description: "@alpha",
7206
+ optional: false
7207
+ },
7208
+ {
7209
+ name: "getAncestorsForAgent",
7210
+ type: "(input: {\n id: string;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7211
+ description: "@alpha",
7212
+ optional: false
7213
+ },
7214
+ {
7215
+ name: "serializeForAgent",
7216
+ type: "(input: {\n id: string;\n depth?: number;\n attributeFilter?: readonly string[];\n ancestorPath?: boolean;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7217
+ description: "@alpha",
7218
+ optional: false
7219
+ },
7220
+ {
7221
+ name: "serializeNodesForAgent",
7222
+ type: "(input: {\n ids: readonly string[];\n depth?: number;\n attributeFilter?: readonly string[];\n ancestorPath?: boolean;\n }, options?: {\n pagePath?: string;\n }) => Promise<unknown>",
7223
+ description: "@alpha",
7224
+ optional: false
7225
+ },
7226
+ {
7227
+ name: "paginateForAgent",
7228
+ 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>",
7229
+ description: "@alpha",
7230
+ optional: false
7231
+ },
7142
7232
  {
7143
7233
  name: "startAgentConversation",
7144
7234
  type: "(prompt: string, options?: StartAgentConversationOptions) => Promise<StartAgentConversationResult>",
@@ -7157,6 +7247,12 @@ var types = {
7157
7247
  description: "@alpha",
7158
7248
  optional: false
7159
7249
  },
7250
+ {
7251
+ name: "runSupervisorAgentCommand",
7252
+ type: "(options: RunSupervisorAgentCommandOptions) => Promise<RunSupervisorAgentCommandResult>",
7253
+ description: "@alpha",
7254
+ optional: false
7255
+ },
7160
7256
  {
7161
7257
  name: "[getAiServiceInfoMessageType]",
7162
7258
  type: "(version?: AiServiceVersion) => Promise<AiServiceInfo>",
@@ -7579,6 +7675,58 @@ var types = {
7579
7675
  alias: '"auto" | "lossless" | "small" | "medium" | "large" | "full"',
7580
7676
  references: []
7581
7677
  },
7678
+ runsupervisoragentcommandoptions: {
7679
+ name: "RunSupervisorAgentCommandOptions",
7680
+ description: "",
7681
+ kind: "interface",
7682
+ references: [],
7683
+ members: [
7684
+ {
7685
+ name: "goal",
7686
+ type: "string",
7687
+ description: "",
7688
+ optional: false
7689
+ },
7690
+ {
7691
+ name: "model",
7692
+ type: "string",
7693
+ description: "",
7694
+ optional: false
7695
+ },
7696
+ {
7697
+ name: "pagePath",
7698
+ type: "string",
7699
+ description: "",
7700
+ optional: true
7701
+ },
7702
+ {
7703
+ name: "maxSteps",
7704
+ type: "number",
7705
+ description: "",
7706
+ optional: true
7707
+ }
7708
+ ]
7709
+ },
7710
+ runsupervisoragentcommandresult: {
7711
+ name: "RunSupervisorAgentCommandResult",
7712
+ description: "",
7713
+ kind: "interface",
7714
+ references: [],
7715
+ members: [
7716
+ {
7717
+ name: "filename",
7718
+ type: "string",
7719
+ description: "",
7720
+ optional: false
7721
+ },
7722
+ {
7723
+ name: "archiveBase64",
7724
+ type: "string",
7725
+ description: "",
7726
+ optional: false
7727
+ }
7728
+ ]
7729
+ },
7582
7730
  screenshotoptions: {
7583
7731
  name: "ScreenshotOptions",
7584
7732
  description: "",
@@ -12891,6 +13039,13 @@ var methodsByCategory = {
12891
13039
  description: 'Applies commands to the canvas to create, update, remove, move, or duplicate nodes.\n\nThe command syntax is documented in the string returned by {@link getAgentSystemPrompt}.\nEach call is scoped to a single page.\n\n@param dsl - A string of commands separated by `;`. See {@link getAgentSystemPrompt} for syntax.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.',
12892
13040
  references: []
12893
13041
  },
13042
+ {
13043
+ name: "[$framerApiOnly.flattenComponentInstanceForAgent]",
13044
+ category: "framer",
13045
+ signature: "[$framerApiOnly.flattenComponentInstanceForAgent](input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
13046
+ description: 'Flattens a local component instance into raw editable layers.\n\n@param input - `{ id }`: the id of the component instance to flatten.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The flatten result \u2014 `success` with a `replacementId`, or `blocked` with a reason.',
13047
+ references: []
13048
+ },
12894
13049
  {
12895
13050
  name: "[$framerApiOnly.getAgentContext]",
12896
13051
  category: "framer",
@@ -12905,6 +13060,83 @@ var methodsByCategory = {
12905
13060
  description: "Returns the static agent system prompt as a string.\n\nThe prompt includes:\n- **Command reference** \u2014 syntax for adding, updating, removing, moving, and duplicating nodes.\n- **Design rules** \u2014 spacing, layout, typography, and responsive design guidance.\n- **Examples** \u2014 common UI patterns expressed as commands.\n- **`readProjectForAgent` query reference** \u2014 available query types and their parameters.\n\nThis is the sole documentation for the command syntax used by {@link applyAgentChanges}\nand the query types used by {@link readProjectForAgent}.\n\nThe prompt is static and does not depend on any specific project.\nCall {@link getAgentContext} to get the project-specific context.\n\n@returns A string containing the agent system prompt.",
12906
13061
  references: []
12907
13062
  },
13063
+ {
13064
+ name: "[$framerApiOnly.getAncestorsForAgent]",
13065
+ category: "framer",
13066
+ signature: "[$framerApiOnly.getAncestorsForAgent](input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
13067
+ description: 'Get every ancestor of a node, from the direct parent up to the page root.\n\n@param input - `{ id }`: the id of the node to start from.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The ancestors ordered from closest parent to the page root.',
13068
+ references: []
13069
+ },
13070
+ {
13071
+ name: "[$framerApiOnly.getGroundNodeForAgent]",
13072
+ category: "framer",
13073
+ signature: "[$framerApiOnly.getGroundNodeForAgent](input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
13074
+ description: 'Get the top-level node on the canvas that contains the given node.\n\n@param input - `{ id }`: the id of a descendant node.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The top-level node, or `null` if none applies.',
13075
+ references: []
13076
+ },
13077
+ {
13078
+ name: "[$framerApiOnly.getNodeForAgent]",
13079
+ category: "framer",
13080
+ signature: "[$framerApiOnly.getNodeForAgent](input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
13081
+ description: 'Get a single node on the page, including its children.\n\n@param input - `{ id }`: the id of the node to read.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The node, or `null` if no node with that id exists on the page.',
13082
+ references: []
13083
+ },
13084
+ {
13085
+ name: "[$framerApiOnly.getNodesForAgent]",
13086
+ category: "framer",
13087
+ signature: "[$framerApiOnly.getNodesForAgent](input: { ids: readonly string[]; }, options?: { pagePath?: string; }): Promise<unknown>",
13088
+ description: 'Get multiple nodes on the page, including their children.\nIds that don\'t resolve to a node are skipped.\n\n@param input - `{ ids }`: the ids of the nodes to read.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The nodes that were found, in input order.',
13089
+ references: []
13090
+ },
13091
+ {
13092
+ name: "[$framerApiOnly.getNodesOfTypesForAgent]",
13093
+ category: "framer",
13094
+ signature: "[$framerApiOnly.getNodesOfTypesForAgent](input: { types: readonly string[]; }, options?: { pagePath?: string; }): Promise<unknown>",
13095
+ description: 'Get every node on the page of one or more kinds (e.g. `"FrameNode"`, `"RichTextNode"`, `"ComponentInstanceNode"`).\n\n@param input - `{ types }`: the node kinds to match.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The matching nodes without their children.',
13096
+ references: []
13097
+ },
13098
+ {
13099
+ name: "[$framerApiOnly.getParentNodeForAgent]",
13100
+ category: "framer",
13101
+ signature: "[$framerApiOnly.getParentNodeForAgent](input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
13102
+ 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.',
13103
+ references: []
13104
+ },
13105
+ {
13106
+ name: "[$framerApiOnly.getScopeNodeForAgent]",
13107
+ category: "framer",
13108
+ signature: "[$framerApiOnly.getScopeNodeForAgent](input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
13109
+ description: 'Get the scope node (page or component) that contains the given node.\n\n@param input - `{ id }`: the id of a node inside the scope.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The enclosing scope node, or `null` if the node isn\'t in any scope.',
13110
+ references: []
13111
+ },
13112
+ {
13113
+ name: "[$framerApiOnly.makeExternalComponentLocalForAgent]",
13114
+ category: "framer",
13115
+ signature: "[$framerApiOnly.makeExternalComponentLocalForAgent](input: { id: string; replaceAll?: boolean; }, options?: { pagePath?: string; }): Promise<unknown>",
13116
+ description: 'Converts an external component into a local project component.\n\n@param input - `{ id, replaceAll? }`: the id of the external instance, and whether to replace all instances.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns `success` (with the local component name), `needs_confirmation` (retry with `replaceAll`), or `blocked` with a reason.',
13117
+ references: []
13118
+ },
13119
+ {
13120
+ name: "[$framerApiOnly.paginateForAgent]",
13121
+ category: "framer",
13122
+ signature: "[$framerApiOnly.paginateForAgent](input: { items: readonly unknown[]; keyName?: never; cursor?: never; } | { keyName: string; cursor: number; items?: never; }, options?: { pagePath?: string; }): Promise<unknown>",
13123
+ description: 'Paginate a large array of values across multiple calls. The cursor is\nopaque and only valid within the same headless session and page.\n\n- First page: pass `{ items }`.\n- Continuation: pass `{ keyName, cursor }` using values returned by a previous call.\n\n@param input - `{ items }` for a fresh array, or `{ keyName, cursor }` for continuation.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The current page, including `keyName`, `cursor`, `results`, `totalResults`, and (if more pages remain) `nextCursor`.',
13124
+ references: []
13125
+ },
13126
+ {
13127
+ name: "[$framerApiOnly.publishForAgent]",
13128
+ category: "framer",
13129
+ signature: "[$framerApiOnly.publishForAgent](input?: Record<string, unknown>): Promise<unknown>",
13130
+ description: "Executes the publish flow on behalf of an agent.\n\nThe input schema is documented in the string returned by {@link getAgentSystemPrompt}.\n\n@param input - Action-discriminated input object (preview / confirm_publish / deploy_to_production).\n@returns The action's result \u2014 status, publish URLs, and any errors, warnings, or changes.",
13131
+ references: []
13132
+ },
13133
+ {
13134
+ name: "[$framerApiOnly.queryImagesForAgent]",
13135
+ category: "framer",
13136
+ signature: "[$framerApiOnly.queryImagesForAgent](input: Record<string, unknown>): Promise<unknown>",
13137
+ description: 'Searches for stock images to use on the canvas (e.g. `"FrameNode"` `fill` values). Returns\ncandidate images with preview thumbnails and a `url` field for each. The returned URLs are\nregistered as trusted for this session so they can be applied directly via `fill="<url>"`\nin a subsequent {@link applyAgentChanges} DSL command. Without calling this method first,\nexternal image URLs are rejected at apply time.\n\nThe input schema is documented in the string returned by {@link getAgentSystemPrompt}.\n\n@param input - Search input object (source / query / count / orientation).\n@returns An object describing the candidates or an error.',
13138
+ references: []
13139
+ },
12908
13140
  {
12909
13141
  name: "[$framerApiOnly.readProjectForAgent]",
12910
13142
  category: "framer",
@@ -12919,6 +13151,20 @@ var methodsByCategory = {
12919
13151
  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
13152
  references: []
12921
13153
  },
13154
+ {
13155
+ name: "[$framerApiOnly.serializeForAgent]",
13156
+ category: "framer",
13157
+ signature: "[$framerApiOnly.serializeForAgent](input: { id: string; depth?: number; attributeFilter?: readonly string[]; ancestorPath?: boolean; }, options?: { pagePath?: string; }): Promise<unknown>",
13158
+ description: 'Serialize a single node on the page.\n\n@param input - `{ id }` plus optional serialization options:\n - `depth` \u2014 limit how many descendant levels to include.\n - `attributeFilter` \u2014 only return the listed attributes per node.\n - `ancestorPath` \u2014 also return the path of ancestors up to the page root.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The serialized node, or `null` if no node with that id exists on the page.',
13159
+ references: []
13160
+ },
13161
+ {
13162
+ name: "[$framerApiOnly.serializeNodesForAgent]",
13163
+ category: "framer",
13164
+ signature: "[$framerApiOnly.serializeNodesForAgent](input: { ids: readonly string[]; depth?: number; attributeFilter?: readonly string[]; ancestorPath?: boolean; }, options?: { pagePath?: string; }): Promise<unknown>",
13165
+ description: 'Serialize multiple nodes on the page. Ids that don\'t resolve to a node are skipped.\n\n@param input - `{ ids }` plus optional serialization options:\n - `depth` \u2014 limit how many descendant levels to include.\n - `attributeFilter` \u2014 only return the listed attributes per node.\n - `ancestorPath` \u2014 also return the path of ancestors up to the page root.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The serialized nodes that were found, in input order.',
13166
+ references: []
13167
+ },
12922
13168
  {
12923
13169
  name: "[$framerInternal.initialState]",
12924
13170
  category: "framer",
@@ -13121,6 +13367,13 @@ var methodsByCategory = {
13121
13367
  description: "",
13122
13368
  references: []
13123
13369
  },
13370
+ {
13371
+ name: "flattenComponentInstanceForAgent",
13372
+ category: "framer",
13373
+ signature: "flattenComponentInstanceForAgent(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
13374
+ description: 'Flattens a local component instance into raw editable layers.\n\n@param input - `{ id }`: the id of the component instance to flatten.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The flatten result \u2014 `success` with a `replacementId`, or `blocked` with a reason.',
13375
+ references: []
13376
+ },
13124
13377
  {
13125
13378
  name: "getAgentContext",
13126
13379
  category: "framer",
@@ -13135,6 +13388,13 @@ var methodsByCategory = {
13135
13388
  description: "Returns the static agent system prompt as a string.\n\nThe prompt includes:\n- **Command reference** \u2014 syntax for adding, updating, removing, moving, and duplicating nodes.\n- **Design rules** \u2014 spacing, layout, typography, and responsive design guidance.\n- **Examples** \u2014 common UI patterns expressed as commands.\n- **`readProjectForAgent` query reference** \u2014 available query types and their parameters.\n\nThis is the sole documentation for the command syntax used by {@link applyAgentChanges}\nand the query types used by {@link readProjectForAgent}.\n\nThe prompt is static and does not depend on any specific project.\nCall {@link getAgentContext} to get the project-specific context.\n\n@returns A string containing the agent system prompt.",
13136
13389
  references: []
13137
13390
  },
13391
+ {
13392
+ name: "getAncestorsForAgent",
13393
+ category: "framer",
13394
+ signature: "getAncestorsForAgent(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
13395
+ description: 'Get every ancestor of a node, from the direct parent up to the page root.\n\n@param input - `{ id }`: the id of the node to start from.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The ancestors ordered from closest parent to the page root.',
13396
+ references: []
13397
+ },
13138
13398
  {
13139
13399
  name: "getCanvasRoot",
13140
13400
  category: "framer",
@@ -13247,6 +13507,13 @@ var methodsByCategory = {
13247
13507
  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",
13248
13508
  references: ["Font"]
13249
13509
  },
13510
+ {
13511
+ name: "getGroundNodeForAgent",
13512
+ category: "framer",
13513
+ signature: "getGroundNodeForAgent(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
13514
+ description: 'Get the top-level node on the canvas that contains the given node.\n\n@param input - `{ id }`: the id of a descendant node.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The top-level node, or `null` if none applies.',
13515
+ references: []
13516
+ },
13250
13517
  {
13251
13518
  name: "getImage",
13252
13519
  category: "framer",
@@ -13296,6 +13563,27 @@ var methodsByCategory = {
13296
13563
  description: "Get a node by its id.\n@category canvas",
13297
13564
  references: ["AnyNode"]
13298
13565
  },
13566
+ {
13567
+ name: "getNodeForAgent",
13568
+ category: "framer",
13569
+ signature: "getNodeForAgent(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
13570
+ description: 'Get a single node on the page, including its children.\n\n@param input - `{ id }`: the id of the node to read.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The node, or `null` if no node with that id exists on the page.',
13571
+ references: []
13572
+ },
13573
+ {
13574
+ name: "getNodesForAgent",
13575
+ category: "framer",
13576
+ signature: "getNodesForAgent(input: { ids: readonly string[]; }, options?: { pagePath?: string; }): Promise<unknown>",
13577
+ description: 'Get multiple nodes on the page, including their children.\nIds that don\'t resolve to a node are skipped.\n\n@param input - `{ ids }`: the ids of the nodes to read.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The nodes that were found, in input order.',
13578
+ references: []
13579
+ },
13580
+ {
13581
+ name: "getNodesOfTypesForAgent",
13582
+ category: "framer",
13583
+ signature: "getNodesOfTypesForAgent(input: { types: readonly string[]; }, options?: { pagePath?: string; }): Promise<unknown>",
13584
+ description: 'Get every node on the page of one or more kinds (e.g. `"FrameNode"`, `"RichTextNode"`, `"ComponentInstanceNode"`).\n\n@param input - `{ types }`: the node kinds to match.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The matching nodes without their children.',
13585
+ references: []
13586
+ },
13299
13587
  {
13300
13588
  name: "getNodesWithAttribute",
13301
13589
  category: "framer",
@@ -13324,6 +13612,13 @@ var methodsByCategory = {
13324
13612
  description: "Get the parent of a node.\n@category canvas",
13325
13613
  references: ["AnyNode"]
13326
13614
  },
13615
+ {
13616
+ name: "getParentNodeForAgent",
13617
+ category: "framer",
13618
+ signature: "getParentNodeForAgent(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
13619
+ 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.',
13620
+ references: []
13621
+ },
13327
13622
  {
13328
13623
  name: "getProjectInfo",
13329
13624
  category: "framer",
@@ -13352,6 +13647,13 @@ var methodsByCategory = {
13352
13647
  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",
13353
13648
  references: ["Redirect"]
13354
13649
  },
13650
+ {
13651
+ name: "getScopeNodeForAgent",
13652
+ category: "framer",
13653
+ signature: "getScopeNodeForAgent(input: { id: string; }, options?: { pagePath?: string; }): Promise<unknown>",
13654
+ description: 'Get the scope node (page or component) that contains the given node.\n\n@param input - `{ id }`: the id of a node inside the scope.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The enclosing scope node, or `null` if the node isn\'t in any scope.',
13655
+ references: []
13656
+ },
13355
13657
  {
13356
13658
  name: "getText",
13357
13659
  category: "framer",
@@ -13380,6 +13682,13 @@ var methodsByCategory = {
13380
13682
  description: "Get all available vector sets.\n\n@alpha",
13381
13683
  references: ["VectorSet"]
13382
13684
  },
13685
+ {
13686
+ name: "makeExternalComponentLocalForAgent",
13687
+ category: "framer",
13688
+ signature: "makeExternalComponentLocalForAgent(input: { id: string; replaceAll?: boolean; }, options?: { pagePath?: string; }): Promise<unknown>",
13689
+ description: 'Converts an external component into a local project component.\n\n@param input - `{ id, replaceAll? }`: the id of the external instance, and whether to replace all instances.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns `success` (with the local component name), `needs_confirmation` (retry with `replaceAll`), or `blocked` with a reason.',
13690
+ references: []
13691
+ },
13383
13692
  {
13384
13693
  name: "mode",
13385
13694
  category: "framer",
@@ -13387,6 +13696,13 @@ var methodsByCategory = {
13387
13696
  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',
13388
13697
  references: ["Mode"]
13389
13698
  },
13699
+ {
13700
+ name: "paginateForAgent",
13701
+ category: "framer",
13702
+ signature: "paginateForAgent(input: { items: readonly unknown[]; keyName?: never; cursor?: never; } | { keyName: string; cursor: number; items?: never; }, options?: { pagePath?: string; }): Promise<unknown>",
13703
+ description: 'Paginate a large array of values across multiple calls. The cursor is\nopaque and only valid within the same headless session and page.\n\n- First page: pass `{ items }`.\n- Continuation: pass `{ keyName, cursor }` using values returned by a previous call.\n\n@param input - `{ items }` for a fresh array, or `{ keyName, cursor }` for continuation.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The current page, including `keyName`, `cursor`, `results`, `totalResults`, and (if more pages remain) `nextCursor`.',
13704
+ references: []
13705
+ },
13390
13706
  {
13391
13707
  name: "publish",
13392
13708
  category: "framer",
@@ -13394,6 +13710,20 @@ var methodsByCategory = {
13394
13710
  description: "",
13395
13711
  references: ["PublishResult"]
13396
13712
  },
13713
+ {
13714
+ name: "publishForAgent",
13715
+ category: "framer",
13716
+ signature: "publishForAgent(input?: Record<string, unknown>): Promise<unknown>",
13717
+ description: "Executes the publish flow on behalf of an agent.\n\nThe input schema is documented in the string returned by {@link getAgentSystemPrompt}.\n\n@param input - Action-discriminated input object (preview / confirm_publish / deploy_to_production).\n@returns The action's result \u2014 status, publish URLs, and any errors, warnings, or changes.",
13718
+ references: []
13719
+ },
13720
+ {
13721
+ name: "queryImagesForAgent",
13722
+ category: "framer",
13723
+ signature: "queryImagesForAgent(input: Record<string, unknown>): Promise<unknown>",
13724
+ description: 'Searches for stock images to use on the canvas (e.g. `"FrameNode"` `fill` values). Returns\ncandidate images with preview thumbnails and a `url` field for each. The returned URLs are\nregistered as trusted for this session so they can be applied directly via `fill="<url>"`\nin a subsequent {@link applyAgentChanges} DSL command. Without calling this method first,\nexternal image URLs are rejected at apply time.\n\nThe input schema is documented in the string returned by {@link getAgentSystemPrompt}.\n\n@param input - Search input object (source / query / count / orientation).\n@returns An object describing the candidates or an error.',
13725
+ references: []
13726
+ },
13397
13727
  {
13398
13728
  name: "readProjectForAgent",
13399
13729
  category: "framer",
@@ -13436,6 +13766,16 @@ var methodsByCategory = {
13436
13766
  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
13767
  references: []
13438
13768
  },
13769
+ {
13770
+ name: "runSupervisorAgentCommand",
13771
+ category: "framer",
13772
+ signature: "runSupervisorAgentCommand(options: RunSupervisorAgentCommandOptions): Promise<RunSupervisorAgentCommandResult>",
13773
+ description: "",
13774
+ references: [
13775
+ "RunSupervisorAgentCommandOptions",
13776
+ "RunSupervisorAgentCommandResult"
13777
+ ]
13778
+ },
13439
13779
  {
13440
13780
  name: "screenshot",
13441
13781
  category: "framer",
@@ -13443,6 +13783,20 @@ var methodsByCategory = {
13443
13783
  description: "",
13444
13784
  references: ["ScreenshotOptions", "ScreenshotResult"]
13445
13785
  },
13786
+ {
13787
+ name: "serializeForAgent",
13788
+ category: "framer",
13789
+ signature: "serializeForAgent(input: { id: string; depth?: number; attributeFilter?: readonly string[]; ancestorPath?: boolean; }, options?: { pagePath?: string; }): Promise<unknown>",
13790
+ description: 'Serialize a single node on the page.\n\n@param input - `{ id }` plus optional serialization options:\n - `depth` \u2014 limit how many descendant levels to include.\n - `attributeFilter` \u2014 only return the listed attributes per node.\n - `ancestorPath` \u2014 also return the path of ancestors up to the page root.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The serialized node, or `null` if no node with that id exists on the page.',
13791
+ references: []
13792
+ },
13793
+ {
13794
+ name: "serializeNodesForAgent",
13795
+ category: "framer",
13796
+ signature: "serializeNodesForAgent(input: { ids: readonly string[]; depth?: number; attributeFilter?: readonly string[]; ancestorPath?: boolean; }, options?: { pagePath?: string; }): Promise<unknown>",
13797
+ description: 'Serialize multiple nodes on the page. Ids that don\'t resolve to a node are skipped.\n\n@param input - `{ ids }` plus optional serialization options:\n - `depth` \u2014 limit how many descendant levels to include.\n - `attributeFilter` \u2014 only return the listed attributes per node.\n - `ancestorPath` \u2014 also return the path of ancestors up to the page root.\n@param options.pagePath - Target page path (e.g. `"/about"`). Defaults to the active page.\n@returns The serialized nodes that were found, in input order.',
13798
+ references: []
13799
+ },
13446
13800
  {
13447
13801
  name: "sessionId",
13448
13802
  category: "framer",
@@ -15737,13 +16091,35 @@ function inferHeadlessServerUrl(projectUrlOrId) {
15737
16091
  }
15738
16092
  }
15739
16093
  __name(inferHeadlessServerUrl, "inferHeadlessServerUrl");
16094
+ function getRelayTokenPath() {
16095
+ return path7.join(getConfigDir(), "relay-token");
16096
+ }
16097
+ __name(getRelayTokenPath, "getRelayTokenPath");
16098
+ function readRelayToken() {
16099
+ try {
16100
+ const token = fs7.readFileSync(getRelayTokenPath(), "utf-8").trim();
16101
+ return token.length > 0 ? token : null;
16102
+ } catch {
16103
+ return null;
16104
+ }
16105
+ }
16106
+ __name(readRelayToken, "readRelayToken");
16107
+
16108
+ // src/relay-client.ts
15740
16109
  var __filename$1 = fileURLToPath(import.meta.url);
15741
- var __dirname$1 = path6.dirname(__filename$1);
16110
+ var __dirname$1 = path7.dirname(__filename$1);
15742
16111
  var RELAY_PORT = Number(process.env.FRAMER_CLI_PORT) || 19988;
15743
16112
  var client = createTRPCClient({
15744
16113
  links: [
15745
16114
  httpLink({
15746
- url: `http://127.0.0.1:${RELAY_PORT}`
16115
+ url: `http://127.0.0.1:${RELAY_PORT}`,
16116
+ headers() {
16117
+ const token = readRelayToken();
16118
+ if (!token) {
16119
+ return {};
16120
+ }
16121
+ return { Authorization: `Bearer ${token}` };
16122
+ }
15747
16123
  })
15748
16124
  ]
15749
16125
  });
@@ -15806,7 +16182,7 @@ async function ensureRelayServerRunning(options = {}) {
15806
16182
  logger?.log("Relay server not running, starting it...");
15807
16183
  }
15808
16184
  const isRunningFromSource = __filename$1.endsWith(".ts");
15809
- const scriptPath = isRunningFromSource ? path6.resolve(__dirname$1, "./start-relay-server.ts") : path6.resolve(__dirname$1, "./start-relay-server.js");
16185
+ const scriptPath = isRunningFromSource ? path7.resolve(__dirname$1, "./start-relay-server.ts") : path7.resolve(__dirname$1, "./start-relay-server.js");
15810
16186
  debug("relay", `spawning server process: ${scriptPath}`);
15811
16187
  const serverProcess = spawn(
15812
16188
  isRunningFromSource ? "tsx" : process.execPath,
@@ -15833,19 +16209,19 @@ async function ensureRelayServerRunning(options = {}) {
15833
16209
  throw new Error("Failed to start relay server after 5 seconds");
15834
16210
  }
15835
16211
  __name(ensureRelayServerRunning, "ensureRelayServerRunning");
15836
- var FRAMER_TEMPORARY_DIR = path6.join(os.tmpdir(), "framer");
16212
+ var FRAMER_TEMPORARY_DIR = path7.join(os.tmpdir(), "framer");
15837
16213
  function ensureTemporaryDir() {
15838
- fs6.mkdirSync(FRAMER_TEMPORARY_DIR, { recursive: true });
16214
+ fs7.mkdirSync(FRAMER_TEMPORARY_DIR, { recursive: true });
15839
16215
  }
15840
16216
  __name(ensureTemporaryDir, "ensureTemporaryDir");
15841
16217
  function cleanupStaleSessionCodeFiles(activeSessionIds) {
15842
- if (!fs6.existsSync(FRAMER_TEMPORARY_DIR)) return;
16218
+ if (!fs7.existsSync(FRAMER_TEMPORARY_DIR)) return;
15843
16219
  const activeSessionIdsSet = new Set(activeSessionIds);
15844
- for (const entry of fs6.readdirSync(FRAMER_TEMPORARY_DIR)) {
16220
+ for (const entry of fs7.readdirSync(FRAMER_TEMPORARY_DIR)) {
15845
16221
  const [sessionId] = entry.split("-");
15846
16222
  if (activeSessionIdsSet.has(sessionId)) continue;
15847
- const filePath = path6.join(FRAMER_TEMPORARY_DIR, entry);
15848
- fs6.rmSync(filePath, { recursive: true, force: true, maxRetries: 2 });
16223
+ const filePath = path7.join(FRAMER_TEMPORARY_DIR, entry);
16224
+ fs7.rmSync(filePath, { recursive: true, force: true, maxRetries: 2 });
15849
16225
  }
15850
16226
  }
15851
16227
  __name(cleanupStaleSessionCodeFiles, "cleanupStaleSessionCodeFiles");
@@ -15853,10 +16229,10 @@ __name(cleanupStaleSessionCodeFiles, "cleanupStaleSessionCodeFiles");
15853
16229
  // src/skills.ts
15854
16230
  var META_SKILL_NAME = "framer";
15855
16231
  var CODE_COMPONENTS_SKILL_NAME = "framer-code-components";
15856
- var __dirname2 = path6.dirname(fileURLToPath(import.meta.url));
15857
- var skillsDocsDir = path6.join(__dirname2, "..", "docs", "skills");
16232
+ var __dirname2 = path7.dirname(fileURLToPath(import.meta.url));
16233
+ var skillsDocsDir = path7.join(__dirname2, "..", "docs", "skills");
15858
16234
  function readSkillDoc(name2) {
15859
- return fs6.readFileSync(path6.join(skillsDocsDir, name2), "utf-8").trimEnd();
16235
+ return fs7.readFileSync(path7.join(skillsDocsDir, name2), "utf-8").trimEnd();
15860
16236
  }
15861
16237
  __name(readSkillDoc, "readSkillDoc");
15862
16238
  function buildMetaSkill() {
@@ -15899,27 +16275,27 @@ function buildProjectCanvasSkill(projectId, agentContext, canvasPrompt) {
15899
16275
  }
15900
16276
  __name(buildProjectCanvasSkill, "buildProjectCanvasSkill");
15901
16277
  function writeSkill(root, skillName, content) {
15902
- fs6.mkdirSync(root, { recursive: true });
15903
- const rootStat = fs6.statSync(root);
16278
+ fs7.mkdirSync(root, { recursive: true });
16279
+ const rootStat = fs7.statSync(root);
15904
16280
  if (!rootStat.isDirectory()) {
15905
16281
  throw new Error(`Skill root is not a directory: ${root}`);
15906
16282
  }
15907
- const skillDir = path6.join(root, skillName);
15908
- const filePath = path6.join(skillDir, "SKILL.md");
15909
- const current = fs6.lstatSync(skillDir, { throwIfNoEntry: false });
16283
+ const skillDir = path7.join(root, skillName);
16284
+ const filePath = path7.join(skillDir, "SKILL.md");
16285
+ const current = fs7.lstatSync(skillDir, { throwIfNoEntry: false });
15910
16286
  if (current && (current.isSymbolicLink() || !current.isDirectory())) {
15911
- fs6.rmSync(skillDir, { recursive: true, force: true });
16287
+ fs7.rmSync(skillDir, { recursive: true, force: true });
15912
16288
  }
15913
- fs6.mkdirSync(skillDir, { recursive: true });
15914
- fs6.writeFileSync(filePath, content, "utf-8");
16289
+ fs7.mkdirSync(skillDir, { recursive: true });
16290
+ fs7.writeFileSync(filePath, content, "utf-8");
15915
16291
  return filePath;
15916
16292
  }
15917
16293
  __name(writeSkill, "writeSkill");
15918
16294
  function getDefaultSkillRoots() {
15919
16295
  const home = os.homedir();
15920
16296
  return [
15921
- path6.join(home, ".agents", "skills"),
15922
- path6.join(home, ".claude", "skills")
16297
+ path7.join(home, ".agents", "skills"),
16298
+ path7.join(home, ".claude", "skills")
15923
16299
  ];
15924
16300
  }
15925
16301
  __name(getDefaultSkillRoots, "getDefaultSkillRoots");
@@ -15929,14 +16305,14 @@ function cleanupStaleSkills(activeProjectIds, skillRoots) {
15929
16305
  [...activeProjectIds].map(toSafeProjectId)
15930
16306
  );
15931
16307
  for (const root of roots) {
15932
- if (!fs6.existsSync(root)) continue;
15933
- for (const entry of fs6.readdirSync(root)) {
16308
+ if (!fs7.existsSync(root)) continue;
16309
+ for (const entry of fs7.readdirSync(root)) {
15934
16310
  if (!entry.startsWith(CANVAS_SKILL_PREFIX)) continue;
15935
16311
  const sanitizedProjectId = entry.slice(CANVAS_SKILL_PREFIX.length);
15936
16312
  const isActive = sanitizedActiveProjectIds.has(sanitizedProjectId);
15937
16313
  if (isActive) continue;
15938
- const skillDir = path6.join(root, entry);
15939
- fs6.rmSync(skillDir, { recursive: true, force: true, maxRetries: 2 });
16314
+ const skillDir = path7.join(root, entry);
16315
+ fs7.rmSync(skillDir, { recursive: true, force: true, maxRetries: 2 });
15940
16316
  }
15941
16317
  }
15942
16318
  }
@@ -15997,8 +16373,8 @@ function printSetupSummary(results) {
15997
16373
  const installLocations = /* @__PURE__ */ new Set();
15998
16374
  for (const result of results) {
15999
16375
  for (const filePath of result.paths) {
16000
- const skillDir = path6.dirname(filePath);
16001
- const root = path6.dirname(skillDir);
16376
+ const skillDir = path7.dirname(filePath);
16377
+ const root = path7.dirname(skillDir);
16002
16378
  installLocations.add(root);
16003
16379
  }
16004
16380
  }
@@ -16173,7 +16549,7 @@ program.command("exec").description("Execute code in a session").requiredOption(
16173
16549
  let code = evalCode;
16174
16550
  if (!code && filePath) {
16175
16551
  try {
16176
- code = fs6.readFileSync(filePath, "utf-8");
16552
+ code = fs7.readFileSync(filePath, "utf-8");
16177
16553
  } catch (err) {
16178
16554
  printError(`Failed to read file: ${formatError(err)}`);
16179
16555
  await waitForTrackingToFinish();