@pencil-agent/nano-pencil 2.0.1 → 2.0.2

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.
Files changed (186) hide show
  1. package/README.md +267 -267
  2. package/dist/build-meta.json +3 -3
  3. package/dist/core/export-html/AGENT.md +11 -11
  4. package/dist/core/export-html/template.css +971 -971
  5. package/dist/core/export-html/template.html +54 -54
  6. package/dist/core/model/custom-providers.js +1 -1
  7. package/dist/core/model-registry.js +5 -5
  8. package/dist/extensions/builtin/AGENT.md +115 -115
  9. package/dist/extensions/builtin/browser/AGENT.md +17 -17
  10. package/dist/extensions/builtin/browser/agent-workspace/agent_helpers.py +12 -12
  11. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/amazon/product-search.md +198 -198
  12. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/archive-org/scraping.md +341 -341
  13. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/arxiv/scraping.md +311 -311
  14. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/arxiv-bulk/scraping.md +333 -333
  15. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/atlas/overview.md +70 -70
  16. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/booking-com/scraping.md +578 -578
  17. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/capterra/scraping.md +440 -440
  18. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/centilebrain/generate-estimates.md +110 -110
  19. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/coingecko/scraping.md +325 -325
  20. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/coinmarketcap/scraping.md +463 -463
  21. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/coursera/scraping.md +360 -360
  22. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/craigslist/scraping.md +390 -390
  23. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/crossref/scraping.md +568 -568
  24. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/dev-to/scraping.md +323 -323
  25. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/duckduckgo/scraping.md +349 -349
  26. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/ebay/scraping.md +435 -435
  27. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/etsy/scraping.md +506 -506
  28. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/eventbrite/scraping.md +363 -363
  29. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/expedia/automation.md +168 -168
  30. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/facebook/groups.md +236 -236
  31. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/facebook/pages.md +295 -295
  32. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/framer/editor.md +108 -108
  33. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/fred/scraping.md +493 -493
  34. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/g2/scraping.md +580 -580
  35. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/genius/scraping.md +511 -511
  36. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/github/repo-actions.md +65 -65
  37. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/github/scraping.md +184 -184
  38. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/glassdoor/scraping.md +543 -543
  39. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/gmail/compose.md +122 -122
  40. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/goodreads/scraping.md +461 -461
  41. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/gutenberg/scraping.md +383 -383
  42. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/hackernews/scraping.md +243 -243
  43. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/howlongtobeat/scraping.md +473 -473
  44. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/imdb/scraping.md +271 -271
  45. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/itch-io/scraping.md +436 -436
  46. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/job-boards/indeed-glassdoor.md +1021 -1021
  47. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/letterboxd/scraping.md +349 -349
  48. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/linkedin/invitation-manager.md +109 -109
  49. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/loom/folder-enumeration.md +170 -170
  50. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/macrotrends/scraping.md +537 -537
  51. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/medium/article-hydration.md +120 -120
  52. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/medium/scraping.md +414 -414
  53. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/metacritic/scraping.md +477 -477
  54. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/musicbrainz/scraping.md +478 -478
  55. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/nasa/scraping.md +339 -339
  56. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/news-aggregation/multi-source.md +205 -205
  57. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/open-library/scraping.md +472 -472
  58. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/openalex/scraping.md +470 -470
  59. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/openstreetmap/scraping.md +490 -490
  60. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/package-registries/npm-pypi.md +478 -478
  61. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/polymarket/scraping.md +234 -234
  62. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/producthunt/scraping.md +307 -307
  63. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/pubmed/scraping.md +421 -421
  64. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/quora/scraping.md +364 -364
  65. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/rawg/scraping.md +352 -352
  66. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/reddit/scraping.md +124 -124
  67. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/rest-countries/scraping.md +233 -233
  68. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/sec-edgar/scraping.md +361 -361
  69. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/shopify-admin/README.md +36 -36
  70. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/shopify-admin/embedded-apps.md +72 -72
  71. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/shopify-admin/knowledge-base.md +109 -109
  72. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/shopify-admin/polaris-inputs.md +137 -137
  73. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/soundcloud/scraping.md +362 -362
  74. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/spotify/scraping.md +339 -339
  75. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/stackoverflow/scraping.md +435 -435
  76. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/steam/scraping.md +575 -575
  77. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/substack/scraping.md +338 -338
  78. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/thetechgeeks/pricing.md +52 -52
  79. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/tiktok/upload.md +107 -107
  80. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/tradingview/scraping.md +309 -309
  81. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/trello/boards-and-lists.md +88 -88
  82. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/trustpilot/scraping.md +375 -375
  83. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/walmart/scraping.md +444 -444
  84. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/wayback-machine/scraping.md +306 -306
  85. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/weather/scraping.md +398 -398
  86. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/wellfound/scraping.md +596 -596
  87. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/world-bank/scraping.md +356 -356
  88. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/xiaohongshu/scraping.md +84 -84
  89. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/youtube/scraping.md +418 -418
  90. package/dist/extensions/builtin/browser/agent-workspace/domain-skills/zillow/scraping.md +433 -433
  91. package/dist/extensions/builtin/browser/browser.md +73 -73
  92. package/dist/extensions/builtin/browser/install.md +142 -142
  93. package/dist/extensions/builtin/browser/interaction-skills/connection.md +48 -48
  94. package/dist/extensions/builtin/browser/interaction-skills/cookies.md +3 -3
  95. package/dist/extensions/builtin/browser/interaction-skills/cross-origin-iframes.md +3 -3
  96. package/dist/extensions/builtin/browser/interaction-skills/dialogs.md +64 -64
  97. package/dist/extensions/builtin/browser/interaction-skills/downloads.md +3 -3
  98. package/dist/extensions/builtin/browser/interaction-skills/drag-and-drop.md +3 -3
  99. package/dist/extensions/builtin/browser/interaction-skills/dropdowns.md +3 -3
  100. package/dist/extensions/builtin/browser/interaction-skills/iframes.md +3 -3
  101. package/dist/extensions/builtin/browser/interaction-skills/network-requests.md +3 -3
  102. package/dist/extensions/builtin/browser/interaction-skills/print-as-pdf.md +3 -3
  103. package/dist/extensions/builtin/browser/interaction-skills/profile-sync.md +90 -90
  104. package/dist/extensions/builtin/browser/interaction-skills/screenshots.md +17 -17
  105. package/dist/extensions/builtin/browser/interaction-skills/scrolling.md +3 -3
  106. package/dist/extensions/builtin/browser/interaction-skills/shadow-dom.md +3 -3
  107. package/dist/extensions/builtin/browser/interaction-skills/tabs.md +69 -69
  108. package/dist/extensions/builtin/browser/interaction-skills/uploads.md +1 -1
  109. package/dist/extensions/builtin/browser/interaction-skills/viewport.md +3 -3
  110. package/dist/extensions/builtin/browser/src/browser_harness/AGENT.md +15 -15
  111. package/dist/extensions/builtin/browser/src/browser_harness/__init__.py +8 -8
  112. package/dist/extensions/builtin/browser/src/browser_harness/_ipc.py +90 -90
  113. package/dist/extensions/builtin/browser/src/browser_harness/admin.py +722 -722
  114. package/dist/extensions/builtin/browser/src/browser_harness/daemon.py +328 -328
  115. package/dist/extensions/builtin/browser/src/browser_harness/helpers.py +396 -396
  116. package/dist/extensions/builtin/browser/src/browser_harness/run.py +103 -103
  117. package/dist/extensions/builtin/discipline/skills/brainstorming/SKILL.md +33 -33
  118. package/dist/extensions/builtin/discipline/skills/executing-plans/SKILL.md +25 -25
  119. package/dist/extensions/builtin/discipline/skills/finishing-development-branch/SKILL.md +25 -25
  120. package/dist/extensions/builtin/discipline/skills/receiving-code-review/SKILL.md +22 -22
  121. package/dist/extensions/builtin/discipline/skills/requesting-code-review/SKILL.md +31 -31
  122. package/dist/extensions/builtin/discipline/skills/systematic-debugging/SKILL.md +28 -28
  123. package/dist/extensions/builtin/discipline/skills/test-driven-development/SKILL.md +32 -32
  124. package/dist/extensions/builtin/discipline/skills/using-git-worktrees/SKILL.md +25 -25
  125. package/dist/extensions/builtin/discipline/skills/verification-before-completion/SKILL.md +27 -27
  126. package/dist/extensions/builtin/discipline/skills/writing-plans/SKILL.md +26 -26
  127. package/dist/extensions/builtin/goal/README.md +67 -67
  128. package/dist/extensions/builtin/grub/README.md +112 -112
  129. package/dist/extensions/builtin/link-world/agent-workspace/README.md +16 -16
  130. package/dist/extensions/builtin/link-world/internet-search/internet-search.md +65 -65
  131. package/dist/extensions/builtin/link-world/link-world-agent.md +82 -82
  132. package/dist/extensions/builtin/link-world/linkworld.md +313 -313
  133. package/dist/extensions/builtin/link-world/network-routing/network-routing.md +67 -67
  134. package/dist/extensions/builtin/loop/README.md +92 -92
  135. package/dist/extensions/builtin/mcp/figma-design.md +68 -68
  136. package/dist/extensions/builtin/mcp/mcp-management.md +85 -85
  137. package/dist/extensions/builtin/recap/AGENT.md +15 -15
  138. package/dist/extensions/builtin/sal/README.md +72 -72
  139. package/dist/extensions/builtin/security-audit/README.md +289 -289
  140. package/dist/extensions/builtin/team/AGENT.md +112 -112
  141. package/dist/extensions/builtin/team/TESTING.md +299 -299
  142. package/dist/extensions/builtin/token-save/README.md +56 -56
  143. package/dist/extensions/optional/AGENT.md +10 -10
  144. package/dist/modes/interactive/controllers/input-submit-controller.js +2 -2
  145. package/dist/modes/interactive/controllers/stream-render-controller.js +2 -2
  146. package/dist/modes/interactive/interactive-mode.js +19 -19
  147. package/dist/modes/interactive/theme/dark.json +85 -85
  148. package/dist/modes/interactive/theme/light.json +84 -84
  149. package/dist/modes/interactive/theme/theme-schema.json +335 -335
  150. package/dist/modes/interactive/theme/warm.json +81 -81
  151. package/dist/node_modules/@pencil-agent/ai/dist/cli.js +0 -0
  152. package/dist/node_modules/@pencil-agent/ai/dist/models.generated.js +1 -1
  153. package/docs/ACP/345/215/217/350/256/256/351/233/206/346/210/220/345/274/200/345/217/221/346/226/207/346/241/243.md +851 -0
  154. package/docs/SDK-TESTING.md +364 -0
  155. package/docs/codex-goal-command-impl.md +1055 -1055
  156. package/docs/codex-goal-vs-grub.md +500 -500
  157. package/docs/custom-provider.md +27 -27
  158. package/docs/extensions.md +27 -27
  159. package/docs/keybindings.md +27 -27
  160. package/docs/loop /351/207/215/346/236/204/345/256/214/346/210/220/346/200/273/347/273/223.md" +250 -250
  161. package/docs/loop /351/207/215/346/236/204/345/256/214/346/210/220/346/212/245/345/221/212.md" +122 -122
  162. package/docs/loop /351/207/215/346/236/204/346/226/271/346/241/210.md" +1222 -1222
  163. package/docs/loop /351/207/215/346/236/204/346/226/271/346/241/210/345/256/236/347/216/260/346/212/245/345/221/212.md" +158 -158
  164. package/docs/loop /351/207/215/346/236/204/346/226/271/346/241/210/345/257/271/346/257/224/345/210/206/346/236/220.md" +128 -128
  165. package/docs/loop /351/207/215/346/236/204/350/256/241/345/210/222.md" +320 -320
  166. package/docs/loop-usage-examples.md +214 -214
  167. package/docs/mem-core/346/212/200/346/234/257/346/226/207/346/241/243.md +593 -0
  168. package/docs/models.md +27 -27
  169. package/docs/packages.md +27 -27
  170. package/docs/pi-design-philosophy.md +457 -457
  171. package/docs/planmode.md +1987 -1987
  172. package/docs/prompt-templates.md +27 -27
  173. package/docs/providers.md +27 -27
  174. package/docs/sdk.md +27 -27
  175. package/docs/skills.md +27 -27
  176. package/docs/startup-performance-optimization.md +301 -0
  177. package/docs/themes.md +27 -27
  178. package/docs/tui.md +27 -27
  179. package/docs//350/256/244/347/237/245/345/234/260/345/233/276.md +47 -0
  180. package/package.json +190 -190
  181. package/docs/cc-agent-design.md +0 -1297
  182. package/docs/cc-tui-design.md +0 -1333
  183. package/docs/nanoPencil-/345/255/246/344/271/240/350/256/241/345/210/222.md +0 -170
  184. package/docs/scan-report.md +0 -3820
  185. package/docs//345/257/271/346/240/207Claude-Code.md +0 -1775
  186. package/docs//351/230/277/351/207/214/345/267/264/345/267/264/350/264/242/346/212/245/345/210/206/346/236/220/344/271/246.md +0 -261
@@ -1,108 +1,108 @@
1
- ---
2
- name: framer-editor
3
- description: Framer.com web editor (framer.com/projects/...) — DOM selectors, Monaco code-editor workflow, publish quirks, and the things Framer's React canvas will not let automation touch.
4
- ---
5
-
6
- # Framer — web editor
7
-
8
- Framer is a visual web builder with a code-editor side (Monaco) and a React-canvas side. Automation lives where both meet: DOM interactions succeed on the shell, but the canvas rejects synthetic events on many widgets.
9
-
10
- URL shape: `https://framer.com/projects/<project-slug>-<id>` (teamId query param after login). The left rail is tab-driven; the right rail is context-sensitive.
11
-
12
- ## Stable DOM selectors (verified April 2026)
13
-
14
- | Purpose | Selector |
15
- |---|---|
16
- | Pages tab (left rail) | `[data-testid="pages-tab"]` |
17
- | Layers tab | `[data-testid="layers-tab"]` |
18
- | Assets tab | `[data-testid="assets-tab"]` |
19
- | Page row in Pages panel | `[data-testid="page-row"]` |
20
- | Asset row in Assets panel | `[data-testid="asset-row"]` |
21
- | Monaco code editor input | `.monaco-editor textarea` |
22
- | Monaco rendered lines | `.view-line` |
23
- | Monaco error underlines | `.squiggly-error` |
24
- | Project menu button | `[data-testid="projectbar-menu-button"]` |
25
-
26
- Prefer `data-testid` over CSS-module class names — the latter are minified and change across deploys.
27
-
28
- ## Opening a code file in Monaco
29
-
30
- Single-click on an `asset-row` only selects it; you need a double-click to open the editor. A plain `element.click()` is not enough — the canvas listens for a full pointer+mouse event chain:
31
-
32
- ```javascript
33
- const row = document.querySelector('[data-testid="asset-row"][title="VacaturesApp"]');
34
- for (const type of ['pointerdown', 'mousedown', 'pointerup', 'mouseup', 'click']) {
35
- row.dispatchEvent(new MouseEvent(type, {bubbles: true, cancelable: true, view: window}));
36
- }
37
- row.dispatchEvent(new MouseEvent('dblclick', {bubbles: true, cancelable: true, view: window, detail: 2}));
38
- ```
39
-
40
- `detail: 2` matters — without it, Framer treats it as two unrelated single-clicks.
41
-
42
- ## Pasting into Monaco
43
-
44
- Monaco does not accept programmatic `.value =` — it ignores the assignment. The reliable path is clipboard + keystroke:
45
-
46
- 1. Put the new file contents on the clipboard (e.g. via `pbcopy` on macOS or an OS-level clipboard write).
47
- 2. Focus the Monaco textarea: `document.querySelector('.monaco-editor textarea').focus()`.
48
- 3. OS-level `Cmd+A` (select all) → `Cmd+V` (paste).
49
- 4. **Wait ~3 seconds**. Monaco applies the paste asynchronously; saving before the paste commits produces an empty file.
50
- 5. OS-level `Cmd+S` to save.
51
- 6. Verify: scroll to top (`Cmd+Up`), dump `document.querySelectorAll('.view-line')` text content, and confirm `document.querySelectorAll('.squiggly-error').length === 0`.
52
-
53
- The OS-level keystrokes require an accessibility-permitted input path (macOS System Events, Linux xdotool, etc.). JS-dispatched `KeyboardEvent` does not trigger Monaco's bindings.
54
-
55
- ## The Publish button
56
-
57
- The green **Publish** button in the top-right is only rendered when a page is selected in the Pages tab. While you are inside the Monaco code editor, the button is absent from the DOM. The workflow that works:
58
-
59
- 1. Pages tab → click the page you want to publish.
60
- 2. **Now** the Publish button is mounted.
61
- 3. Click it by screen coordinates (via OS-level click), not by synthetic event — the React handler on that button ignores JS-dispatched clicks.
62
-
63
- This is the single most common "automation silently did nothing" trap in Framer.
64
-
65
- ## Right-click / context menus
66
-
67
- ```javascript
68
- row.dispatchEvent(new MouseEvent('contextmenu', {
69
- bubbles: true, cancelable: true, view: window,
70
- button: 2, buttons: 2,
71
- }));
72
- ```
73
-
74
- The menu renders into a portal; it is not a child of `row`. Navigate items with OS-level arrow-down keystrokes (`key code 125` via AppleScript `System Events`) + Return. Rename flow: context menu → Rename → `Cmd+A` → type new name → Return.
75
-
76
- ## What Framer will not let automation do
77
-
78
- These are canvas-level React interactions that reject synthetic events or use modal right-panel state that is not DOM-traversable:
79
-
80
- - **Drag-drop** — component insertion, layer reordering, cross-hierarchy moves.
81
- - **Smart Component variant switching** — the On Tap → Change Variant setup lives in a modal nested panel; no stable selector path.
82
- - **Property binding** (the chain icon on a code-component prop) — exposes only `Fetch (HTTP)` and `Create Variable`; no CMS-field binding available from the UI, let alone scriptable.
83
- - **Page Settings** (SEO title / description / canonical / OG image / "Search Engines" toggle / draft/publish state) — right-rail Page Settings panel is not DOM-automatable.
84
- - **Custom Code Page Settings** (`<head>` injection) — static-only input, does not accept CMS tokens.
85
- - **Site Settings → Redirects** — exact-match only, no wildcards; UI-only.
86
- - **Font uploads, image drops** — filesystem drag source.
87
-
88
- For any of these: stop and hand a clickable step-by-step to the human, with selectors for the rail/panel where possible.
89
-
90
- ## Framer autolayout on Header-like nodes
91
-
92
- When a parent node has autolayout + a positioned Header child, any programmatic attempt to set `position`, `left`, or `right` on the Header through Framer's MCP / XML-update API triggers autolayout to force the Header to `left="-1293px"` or similar, visually losing it. The working pattern is "delete the Header, then copy a working one from a known-good page in the same project via `Cmd+C` / `Cmd+V`." This is Framer autolayout preempting your value, not a bug in your update call.
93
-
94
- ## Edge cache after publish
95
-
96
- After a successful publish, `curl` against the live domain may serve stale HTML for 30–60 seconds. For verification, append a cache-buster query param — any unused param works: `?v=<timestamp>`. This doesn't touch Framer's generated routes; it just forces the CDN to fetch a fresh copy.
97
-
98
- ## Sitemap / robots / redirects observations
99
-
100
- - **`/sitemap.xml`** — autogenerated. Static pages only. URLs with query parameters are **not** included. For dynamic routes (`/foo?slug=...`) you must submit them to Google Search Console manually.
101
- - **`robots.txt`** — proxied through Cloudflare on Framer-hosted domains; the default config blocks AI crawlers (Amazonbot, ClaudeBot, GPTBot, Bytespider) while allowing Google.
102
- - **Custom redirects** — exact match only. No regex, no wildcards. Configure in Site Settings → Redirects, one at a time.
103
-
104
- ## Prerequisites for automation on macOS
105
-
106
- - Chrome: "View → Developer → **Allow JavaScript from Apple Events**" checked.
107
- - System Settings → Privacy → **Accessibility** → grant to whichever process drives keystrokes (node, osascript, browser-harness wrapper).
108
- - Framer tab must exist in the front Chrome window; the editor does not tolerate off-screen or backgrounded tabs well during paste flows (Monaco loses focus).
1
+ ---
2
+ name: framer-editor
3
+ description: Framer.com web editor (framer.com/projects/...) — DOM selectors, Monaco code-editor workflow, publish quirks, and the things Framer's React canvas will not let automation touch.
4
+ ---
5
+
6
+ # Framer — web editor
7
+
8
+ Framer is a visual web builder with a code-editor side (Monaco) and a React-canvas side. Automation lives where both meet: DOM interactions succeed on the shell, but the canvas rejects synthetic events on many widgets.
9
+
10
+ URL shape: `https://framer.com/projects/<project-slug>-<id>` (teamId query param after login). The left rail is tab-driven; the right rail is context-sensitive.
11
+
12
+ ## Stable DOM selectors (verified April 2026)
13
+
14
+ | Purpose | Selector |
15
+ |---|---|
16
+ | Pages tab (left rail) | `[data-testid="pages-tab"]` |
17
+ | Layers tab | `[data-testid="layers-tab"]` |
18
+ | Assets tab | `[data-testid="assets-tab"]` |
19
+ | Page row in Pages panel | `[data-testid="page-row"]` |
20
+ | Asset row in Assets panel | `[data-testid="asset-row"]` |
21
+ | Monaco code editor input | `.monaco-editor textarea` |
22
+ | Monaco rendered lines | `.view-line` |
23
+ | Monaco error underlines | `.squiggly-error` |
24
+ | Project menu button | `[data-testid="projectbar-menu-button"]` |
25
+
26
+ Prefer `data-testid` over CSS-module class names — the latter are minified and change across deploys.
27
+
28
+ ## Opening a code file in Monaco
29
+
30
+ Single-click on an `asset-row` only selects it; you need a double-click to open the editor. A plain `element.click()` is not enough — the canvas listens for a full pointer+mouse event chain:
31
+
32
+ ```javascript
33
+ const row = document.querySelector('[data-testid="asset-row"][title="VacaturesApp"]');
34
+ for (const type of ['pointerdown', 'mousedown', 'pointerup', 'mouseup', 'click']) {
35
+ row.dispatchEvent(new MouseEvent(type, {bubbles: true, cancelable: true, view: window}));
36
+ }
37
+ row.dispatchEvent(new MouseEvent('dblclick', {bubbles: true, cancelable: true, view: window, detail: 2}));
38
+ ```
39
+
40
+ `detail: 2` matters — without it, Framer treats it as two unrelated single-clicks.
41
+
42
+ ## Pasting into Monaco
43
+
44
+ Monaco does not accept programmatic `.value =` — it ignores the assignment. The reliable path is clipboard + keystroke:
45
+
46
+ 1. Put the new file contents on the clipboard (e.g. via `pbcopy` on macOS or an OS-level clipboard write).
47
+ 2. Focus the Monaco textarea: `document.querySelector('.monaco-editor textarea').focus()`.
48
+ 3. OS-level `Cmd+A` (select all) → `Cmd+V` (paste).
49
+ 4. **Wait ~3 seconds**. Monaco applies the paste asynchronously; saving before the paste commits produces an empty file.
50
+ 5. OS-level `Cmd+S` to save.
51
+ 6. Verify: scroll to top (`Cmd+Up`), dump `document.querySelectorAll('.view-line')` text content, and confirm `document.querySelectorAll('.squiggly-error').length === 0`.
52
+
53
+ The OS-level keystrokes require an accessibility-permitted input path (macOS System Events, Linux xdotool, etc.). JS-dispatched `KeyboardEvent` does not trigger Monaco's bindings.
54
+
55
+ ## The Publish button
56
+
57
+ The green **Publish** button in the top-right is only rendered when a page is selected in the Pages tab. While you are inside the Monaco code editor, the button is absent from the DOM. The workflow that works:
58
+
59
+ 1. Pages tab → click the page you want to publish.
60
+ 2. **Now** the Publish button is mounted.
61
+ 3. Click it by screen coordinates (via OS-level click), not by synthetic event — the React handler on that button ignores JS-dispatched clicks.
62
+
63
+ This is the single most common "automation silently did nothing" trap in Framer.
64
+
65
+ ## Right-click / context menus
66
+
67
+ ```javascript
68
+ row.dispatchEvent(new MouseEvent('contextmenu', {
69
+ bubbles: true, cancelable: true, view: window,
70
+ button: 2, buttons: 2,
71
+ }));
72
+ ```
73
+
74
+ The menu renders into a portal; it is not a child of `row`. Navigate items with OS-level arrow-down keystrokes (`key code 125` via AppleScript `System Events`) + Return. Rename flow: context menu → Rename → `Cmd+A` → type new name → Return.
75
+
76
+ ## What Framer will not let automation do
77
+
78
+ These are canvas-level React interactions that reject synthetic events or use modal right-panel state that is not DOM-traversable:
79
+
80
+ - **Drag-drop** — component insertion, layer reordering, cross-hierarchy moves.
81
+ - **Smart Component variant switching** — the On Tap → Change Variant setup lives in a modal nested panel; no stable selector path.
82
+ - **Property binding** (the chain icon on a code-component prop) — exposes only `Fetch (HTTP)` and `Create Variable`; no CMS-field binding available from the UI, let alone scriptable.
83
+ - **Page Settings** (SEO title / description / canonical / OG image / "Search Engines" toggle / draft/publish state) — right-rail Page Settings panel is not DOM-automatable.
84
+ - **Custom Code Page Settings** (`<head>` injection) — static-only input, does not accept CMS tokens.
85
+ - **Site Settings → Redirects** — exact-match only, no wildcards; UI-only.
86
+ - **Font uploads, image drops** — filesystem drag source.
87
+
88
+ For any of these: stop and hand a clickable step-by-step to the human, with selectors for the rail/panel where possible.
89
+
90
+ ## Framer autolayout on Header-like nodes
91
+
92
+ When a parent node has autolayout + a positioned Header child, any programmatic attempt to set `position`, `left`, or `right` on the Header through Framer's MCP / XML-update API triggers autolayout to force the Header to `left="-1293px"` or similar, visually losing it. The working pattern is "delete the Header, then copy a working one from a known-good page in the same project via `Cmd+C` / `Cmd+V`." This is Framer autolayout preempting your value, not a bug in your update call.
93
+
94
+ ## Edge cache after publish
95
+
96
+ After a successful publish, `curl` against the live domain may serve stale HTML for 30–60 seconds. For verification, append a cache-buster query param — any unused param works: `?v=<timestamp>`. This doesn't touch Framer's generated routes; it just forces the CDN to fetch a fresh copy.
97
+
98
+ ## Sitemap / robots / redirects observations
99
+
100
+ - **`/sitemap.xml`** — autogenerated. Static pages only. URLs with query parameters are **not** included. For dynamic routes (`/foo?slug=...`) you must submit them to Google Search Console manually.
101
+ - **`robots.txt`** — proxied through Cloudflare on Framer-hosted domains; the default config blocks AI crawlers (Amazonbot, ClaudeBot, GPTBot, Bytespider) while allowing Google.
102
+ - **Custom redirects** — exact match only. No regex, no wildcards. Configure in Site Settings → Redirects, one at a time.
103
+
104
+ ## Prerequisites for automation on macOS
105
+
106
+ - Chrome: "View → Developer → **Allow JavaScript from Apple Events**" checked.
107
+ - System Settings → Privacy → **Accessibility** → grant to whichever process drives keystrokes (node, osascript, browser-harness wrapper).
108
+ - Framer tab must exist in the front Chrome window; the editor does not tolerate off-screen or backgrounded tabs well during paste flows (Monaco loses focus).