framer-dalton 0.0.14 → 0.0.16

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
@@ -10,7 +10,7 @@ import { z } from 'zod';
10
10
  import { fileURLToPath } from 'url';
11
11
  import { createTRPCClient, httpLink } from '@trpc/client';
12
12
 
13
- /* @framer/ai CLI v0.0.14 */
13
+ /* @framer/ai CLI v0.0.16 */
14
14
  var __defProp = Object.defineProperty;
15
15
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
16
16
  function openUrl(url) {
@@ -14982,7 +14982,7 @@ __name(renderDocs, "renderDocs");
14982
14982
  // src/version.ts
14983
14983
  var VERSION = (
14984
14984
  // typeof is used to ensure this can be used just via tsx or node etc. without build
14985
- "0.0.14"
14985
+ "0.0.16"
14986
14986
  );
14987
14987
 
14988
14988
  // src/relay-client.ts
@@ -15344,7 +15344,31 @@ async function ensureRelayForCli() {
15344
15344
  }
15345
15345
  }
15346
15346
  __name(ensureRelayForCli, "ensureRelayForCli");
15347
- program.option("-s, --session <id>", "Session ID (required for code execution)").option("-e, --eval <code>", "Code to execute (or pipe via stdin)").option("-f, --file <path>", "File containing code to execute").action(async (options) => {
15347
+ async function execAndPrint(sessionId, code) {
15348
+ await ensureRelayForCli();
15349
+ try {
15350
+ const result = await client.exec.mutate({
15351
+ sessionId: String(sessionId),
15352
+ code,
15353
+ cwd: process.cwd()
15354
+ });
15355
+ for (const line of result.output) {
15356
+ print(line);
15357
+ }
15358
+ if (result.error) {
15359
+ printError(`Error: ${result.error}`);
15360
+ process.exit(1);
15361
+ }
15362
+ } catch (err) {
15363
+ printError(`Execution failed: ${formatError(err)}`);
15364
+ process.exit(1);
15365
+ }
15366
+ }
15367
+ __name(execAndPrint, "execAndPrint");
15368
+ program.command("exec").description("Execute code in a session").requiredOption(
15369
+ "-s, --session <id>",
15370
+ "Session ID (create one with `session new <projectUrlOrId>`)"
15371
+ ).option("-e, --eval <code>", "Code to execute (or pipe via stdin)").option("-f, --file <path>", "File containing code to execute").action(async (options, command) => {
15348
15372
  const { session: sessionId, eval: evalCode, file: filePath } = options;
15349
15373
  ensureTemporaryDir();
15350
15374
  let code = evalCode;
@@ -15363,34 +15387,43 @@ program.option("-s, --session <id>", "Session ID (required for code execution)")
15363
15387
  code = await readStdin();
15364
15388
  }
15365
15389
  if (!code) {
15366
- program.help();
15390
+ command.help();
15367
15391
  return;
15368
15392
  }
15369
- if (!sessionId) {
15370
- printError("Error: -s/--session is required.");
15371
- printError(
15372
- "Run `framer session new <projectUrlOrId>` first to get a session ID."
15373
- );
15374
- process.exit(1);
15375
- }
15376
- await ensureRelayForCli();
15393
+ await execAndPrint(sessionId, code);
15394
+ });
15395
+ program.command("apply-changes").description("Apply canvas DSL changes to a page").requiredOption(
15396
+ "-s, --session <id>",
15397
+ "Session ID (create one with `session new <projectUrlOrId>`)"
15398
+ ).requiredOption("-e, --eval <dsl>", "DSL string to apply").option("-p, --page <path>", "Target page path", "/").action(async (options) => {
15399
+ const { session: sessionId, eval: dsl, page: pagePath } = options;
15400
+ const code = `
15401
+ const result = await framer.applyAgentChanges(${JSON.stringify(dsl)}, { pagePath: ${JSON.stringify(pagePath)} });
15402
+ if (result) console.log(JSON.stringify(result, null, 2));
15403
+ `;
15404
+ await execAndPrint(sessionId, code);
15405
+ });
15406
+ program.command("read-project").description("Read project state for a page").requiredOption(
15407
+ "-s, --session <id>",
15408
+ "Session ID (create one with `session new <projectUrlOrId>`)"
15409
+ ).requiredOption("-q, --queries <json>", "JSON array of query objects").requiredOption("-p, --page <path>", "Target page path").action(async (options) => {
15410
+ const {
15411
+ session: sessionId,
15412
+ queries: queriesJson,
15413
+ page: pagePath
15414
+ } = options;
15415
+ let queries;
15377
15416
  try {
15378
- const result = await client.exec.mutate({
15379
- sessionId: String(sessionId),
15380
- code,
15381
- cwd: process.cwd()
15382
- });
15383
- for (const line of result.output) {
15384
- print(line);
15385
- }
15386
- if (result.error) {
15387
- printError(`Error: ${result.error}`);
15388
- process.exit(1);
15389
- }
15390
- } catch (err) {
15391
- printError(`Execution failed: ${formatError(err)}`);
15417
+ queries = JSON.parse(queriesJson);
15418
+ } catch {
15419
+ printError("Invalid JSON for --queries");
15392
15420
  process.exit(1);
15393
15421
  }
15422
+ const code = `
15423
+ const result = await framer.readProjectForAgent(${JSON.stringify(queries)}, { pagePath: ${JSON.stringify(pagePath)} });
15424
+ if (result) console.log(JSON.stringify(result, null, 2));
15425
+ `;
15426
+ await execAndPrint(sessionId, code);
15394
15427
  });
15395
15428
  var session = program.command("session").description("Manage sessions");
15396
15429
  session.command("new <projectUrlOrId>").description("Create a new session and print the session ID").action(async (projectUrlOrId) => {
@@ -13,7 +13,7 @@ import { createRequire } from 'module';
13
13
  import * as vm from 'vm';
14
14
  import { connect } from 'framer-api';
15
15
 
16
- /* @framer/ai relay server v0.0.14 */
16
+ /* @framer/ai relay server v0.0.16 */
17
17
  var __defProp = Object.defineProperty;
18
18
  var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
19
19
  var __typeError = (msg) => {
@@ -93,7 +93,7 @@ __name(log, "log");
93
93
  // src/version.ts
94
94
  var VERSION = (
95
95
  // typeof is used to ensure this can be used just via tsx or node etc. without build
96
- "0.0.14"
96
+ "0.0.16"
97
97
  );
98
98
 
99
99
  // src/relay-client.ts
@@ -11,12 +11,10 @@ allowed-tools: ["Bash(npx framer-dalton:*)", "Bash(npx framer-dalton@latest:*)",
11
11
 
12
12
  ## Rules
13
13
 
14
- - For design/layout work, do not use low-level node APIs (`createNode`, `setAttributes`, `setRect`, etc.). Use the canvas editing flow (`readProjectForAgent` + `applyAgentChanges`) with the embedded prompt and project context in this skill.
15
- - Canvas editing agent methods are employee-only.
16
- - Canvas editing methods are not globals. Call `framer.readProjectForAgent` and `framer.applyAgentChanges` as `framer.*`.
14
+ - For design/layout work, do not use low-level node APIs (`createNode`, `setAttributes`, `setRect`, etc.). Use the canvas editing flow (`read-project` + `apply-changes`) with the embedded prompt and project context in this skill.
17
15
  - During normal task execution, do not call `framer.getAgentSystemPrompt()` or `framer.getAgentContext()`. This skill already includes `getAgentContext({ pagePath: "/" })`.
18
- - `framer.readProjectForAgent(queries, { pagePath })` reads project state. Start with page structure only, then request additional targeted queries only if needed. Query types are documented in the embedded prompt below. Never guess names for examples, icon sets, or fonts; look them up first.
19
- - `framer.applyAgentChanges(dsl, { pagePath })` applies canvas DSL changes. After applying changes, re-read project state to inspect results and iterate with `readProjectForAgent` + `applyAgentChanges` until accurate.
16
+ - `npx framer-dalton read-project -s <sessionId> -q <queries> -p <pagePath>` reads project state. Start with page structure only, then request additional targeted queries only if needed. Query types are documented in the embedded prompt below. Never guess names for examples, icon sets, or fonts; look them up first.
17
+ - `npx framer-dalton apply-changes -s <sessionId> -p <pagePath> -e <dsl>` applies canvas DSL changes. After applying changes, re-read project state to inspect results and iterate with `read-project` + `apply-changes` until accurate.
20
18
  - Request examples only when needed, and only after inspecting page structure first. Keep example queries targeted and minimal.
21
19
  - Use screenshots only when visual verification is necessary and cannot be confirmed from state reads. Do not use them for initial inspection or between every small change.
22
20
  - When setting text content, use raw Unicode characters directly (for example `->`, not `\u2192`).
@@ -27,31 +25,18 @@ allowed-tools: ["Bash(npx framer-dalton:*)", "Bash(npx framer-dalton@latest:*)",
27
25
  ## Workflow Loop
28
26
 
29
27
  ```bash
30
- # 1) Read page structure first — write code to a unique file, then execute with -f
31
- # {{FRAMER_TEMPORARY_DIR}}/<sessionId>-read-page.js:
32
- # const { results } = await framer.readProjectForAgent(
33
- # [{ type: "page", path: "/" }],
34
- # { pagePath: "/" }
35
- # );
36
- # console.log(results);
37
-
38
- framer -s <sessionId> -f {{FRAMER_TEMPORARY_DIR}}/<sessionId>-read-page.js
28
+ # 1) Read page structure first
29
+ npx framer-dalton read-project -s <sessionId> -q '[{"type":"page","path":"/"}]' -p "/"
39
30
 
40
31
  # 2) Request additional targeted queries only if needed
41
32
 
42
- # 3) Apply changes in a later call, once `dsl` has been prepared
43
- # {{FRAMER_TEMPORARY_DIR}}/<sessionId>-apply-changes.js:
44
- # const dsl = `
45
- # ...your canvas DSL...
46
- # `;
47
- # await framer.applyAgentChanges(dsl, { pagePath: "/" });
48
-
49
- framer -s <sessionId> -f {{FRAMER_TEMPORARY_DIR}}/<sessionId>-apply-changes.js
33
+ # 3) Apply changes pass DSL directly via apply-changes
34
+ npx framer-dalton apply-changes -s <sessionId> -p "/" -e "$dsl"
50
35
  ```
51
36
 
52
37
  ## Critical for UX: Streaming
53
38
 
54
- When you generate a DSL file to apply, keep it short. Each file must only cover ONE logical section (header, footer, hero, card, etc.). Once you generate ONE section, apply it and continue with the next section.
39
+ When you generate DSL to apply, keep it short. Each `apply-changes` call must only cover ONE logical section (header, footer, hero, card, etc.). Once you apply ONE section, continue with the next.
55
40
 
56
41
  This ensures progress is streamed to the user in small, visible increments.
57
42
 
@@ -59,8 +44,8 @@ This ensures progress is streamed to the user in small, visible increments.
59
44
 
60
45
  This is the static canvas-editing prompt returned by `framer.getAgentSystemPrompt()`. It is the sole documentation for:
61
46
 
62
- - command syntax for `applyAgentChanges`
63
- - query types and parameters for `readProjectForAgent`
47
+ - command syntax for `apply-changes`
48
+ - query types and parameters for `read-project`
64
49
  - design rules and examples used by the canvas editing flow
65
50
 
66
51
  {{CANVAS_PROMPT}}
@@ -52,6 +52,8 @@ Create a session:
52
52
  npx framer-dalton session new "<url or id>"
53
53
  ```
54
54
 
55
+ Note that during beta, you cannot connect to non-beta projects. If creating a session errors with a message about this, you need to move your project to beta.
56
+
55
57
  #### 2. Look up the API (before EVERY code execution)
56
58
 
57
59
  **You MUST run `npx framer-dalton docs` before writing any code.** Do not guess method names or signatures.
@@ -66,7 +68,7 @@ npx framer-dalton docs Collection.getItems # What are the parameters and return
66
68
  Only after checking docs, write your code to a unique file under `{{FRAMER_TEMPORARY_DIR}}/` and execute with `-f`. Name each file `<sessionId>-<short-summary>.js` where `<short-summary>` is a brief kebab-case description (e.g., `1-read-collections.js`, `1-add-team-member.js`). Files are automatically deleted after execution.
67
69
 
68
70
  ```bash
69
- npx framer-dalton -s 1 -f {{FRAMER_TEMPORARY_DIR}}/1-read-collections.js
71
+ npx framer-dalton exec -s 1 -f {{FRAMER_TEMPORARY_DIR}}/1-read-collections.js
70
72
  ```
71
73
 
72
74
  #### 4. Store results in `state`
@@ -100,7 +102,7 @@ state.collections = await framer.getCollections();
100
102
  ```
101
103
 
102
104
  ```bash
103
- npx framer-dalton -s 1 -f {{FRAMER_TEMPORARY_DIR}}/1-get-collections.js
105
+ npx framer-dalton exec -s 1 -f {{FRAMER_TEMPORARY_DIR}}/1-get-collections.js
104
106
  ```
105
107
 
106
108
  ```js
@@ -110,7 +112,7 @@ console.log(state.teamItems.length);
110
112
  ```
111
113
 
112
114
  ```bash
113
- npx framer-dalton -s 1 -f {{FRAMER_TEMPORARY_DIR}}/1-get-team-items.js
115
+ npx framer-dalton exec -s 1 -f {{FRAMER_TEMPORARY_DIR}}/1-get-team-items.js
114
116
  ```
115
117
 
116
118
  Store anything you'll reference again.
@@ -140,7 +142,7 @@ npx framer-dalton session list
140
142
 
141
143
  ## Canvas Editing
142
144
 
143
- For design tasks, do not try to build or restyle pages with low-level node APIs. Instead, load the dynamically created project-scoped canvas skill and follow its `readProjectForAgent` plus `applyAgentChanges` flow.
145
+ For design tasks, do not try to build or restyle pages with low-level node APIs. Instead, load the dynamically created project-scoped canvas skill and use the `read-project` and `apply-changes` subcommands.
144
146
 
145
147
  After session creation, load the dynamically created project-scoped skill `framer-canvas-editing-project-<projectId>` for canvas editing on the connected project. It contains the canvas editing guidance, the live agent system prompt, and the live project context for `pagePath: "/"`.
146
148
 
@@ -149,7 +151,7 @@ After session creation, load the dynamically created project-scoped skill `frame
149
151
  Write your code to a unique file under `{{FRAMER_TEMPORARY_DIR}}/` and execute with `-f`:
150
152
 
151
153
  ```bash
152
- npx framer-dalton -s <sessionId> -f {{FRAMER_TEMPORARY_DIR}}/<sessionId>-<short-summary>.js
154
+ npx framer-dalton exec -s <sessionId> -f {{FRAMER_TEMPORARY_DIR}}/<sessionId>-<short-summary>.js
153
155
  ```
154
156
 
155
157
  ## API Documentation
@@ -645,6 +647,7 @@ const contributors = await framer.getChangeContributors();
645
647
 
646
648
  ### Known Limitations
647
649
 
648
- - **Pages**: No list, delete, update, move, or settings APIs (create only)
650
+ - **Pages**: Cannot change the path of a page
651
+ - **Collection Index/Detail Pages**: Cannot be created as new pages; the user must create them through the UI. Once they exist, they can be modified normally through canvas editing.
649
652
  - **Code overrides**: Cannot assign overrides to nodes
650
653
  - **Analytics**: No APIs exist for accessing analytics data
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "framer-dalton",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "framer-dalton": "./dist/cli.js"