mesurer-solid 0.2.0-beta.9 → 0.2.1-beta.0

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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Mesurer's agent integration is the rendered page itself. The coding agent reads `window.__MESURER__` through the browser control it already has, consumes human visual intent, edits normal application source, and verifies the real Live result.
4
4
 
5
- The normal agent workflow requires no Mesurer MCP server, localhost daemon, Send-to-agent callback, or browser-tool-specific transport. The optional `codex()` plugin is a separate human convenience path for explicitly sending Context feedback to Codex threads that a local Codex process or the user has registered with the loopback companion; it does not replace the browser-state contract described here.
5
+ The normal agent workflow requires no Mesurer MCP server, localhost daemon, Send-to-agent callback, or browser-tool-specific transport. The optional `codex()` plugin is a separate human convenience path for sending Context feedback through the native host's Codex transport; it does not replace the browser-state contract described here.
6
6
 
7
7
  ## Install the agent skill
8
8
 
@@ -17,17 +17,14 @@ The installer writes a self-contained skill and injection artifact:
17
17
  .agents/skills/mesurer-ui/
18
18
  ├── SKILL.md
19
19
  └── assets/
20
- ├── inject-script.js
21
- ├── codex-connect.mjs
22
- ├── codex-lifecycle.mjs
23
- └── codex-bridge.mjs
20
+ └── inject-script.js
24
21
  ```
25
22
 
26
23
  ## Know the available capabilities
27
24
 
28
25
  The base inspector includes Select, X-ray, Rulers, Typography, Guides, Distance, and Settings. Color Picker uses application-local host capture when available and otherwise uses a working browser `EyeDropper`.
29
26
 
30
- First-party plugins add Context, Arrange, Screenshot, and optional Codex delivery. The complete public map, including the low-level inspection methods and plugin host, is in [Capabilities](../../docs/CAPABILITIES.md).
27
+ First-party plugins add Context, Edit, Screenshot, and optional Codex delivery. Edit movement preserves the existing Arrange agent method names for compatibility. The complete public map, including the low-level inspection methods and plugin host, is in [Capabilities](../../docs/CAPABILITIES.md).
31
28
 
32
29
  For normal coding-agent work, use `window.__MESURER__`. Use `window.__MESURER_INSTANCE__` only when the task requires mounted-instance or plugin-host operations.
33
30
 
@@ -46,7 +43,7 @@ if (hasMesurer) {
46
43
  }
47
44
  ```
48
45
 
49
- If it exists, use that instance. A person may already have selected targets, guides, measurements, annotations, Arrange intent, text/style intent, or screenshot review state. That state is part of the request.
46
+ If it exists, use that instance. A person may already have selected targets, guides, measurements, annotations, Edit movement intent, text/style intent, or screenshot review state. That state is part of the request.
50
47
 
51
48
  The injector reuses a connected instance by default. Deliberate replacement requires:
52
49
 
@@ -107,7 +104,7 @@ const textEditIntents = await Promise.all(
107
104
  )
108
105
  ```
109
106
 
110
- Treat annotation notes, Arrange Desired geometry, and text/style Desired state as intent. Treat selection, measurements, distances, geometry, and computed styles as rendered evidence.
107
+ Treat annotation notes, Edit movement Desired geometry, and text/style Desired state as intent. Treat selection, measurements, distances, geometry, and computed styles as rendered evidence.
111
108
 
112
109
  ## Agent API reference
113
110
 
@@ -130,13 +127,13 @@ Use the high-level Context and saved-intent methods for normal UI work. The lowe
130
127
 
131
128
  Context adds `capabilities()`, `context()`, `contextText()`, `select()`, `annotations()`, `review()`, `capturePlan()`, `prepareCapture()`, and `finishCapture()`.
132
129
 
133
- These inspection methods accept general DOM elements, including SVG. `select()` and point inspection can return SVG targets, and Context preserves their selector, tag, and geometry. Arrange and direct text editing remain HTML-only mutation paths.
130
+ These inspection methods accept general DOM elements, including SVG. `select()` and point inspection can return SVG targets, and Context preserves their selector, tag, and geometry. Edit movement and direct text editing remain HTML-only mutation paths.
134
131
 
135
132
  Human Select lifecycle follows the same public contract. Invoking Select clears the current element and Guide selection before toggling the tool, and holding Shift while clicking rendered targets adds or removes them from the human multi-selection. Browser and agent code should not assume a hidden selection survives Select-off or an off-state reload.
136
133
 
137
- Arrange adds `arrangements()`, `arrange()`, `showArrange()`, `arrangeCapturePlan()`, and `reviewArrange()`.
134
+ Edit movement exposes `arrangements()`, `arrange()`, `showArrange()`, `arrangeCapturePlan()`, and `reviewArrange()` under their existing compatibility names.
138
135
 
139
- Use `capabilities().capabilities` before calling optional Context, Arrange, or text-edit paths. The complete public list is in [Capabilities](../../docs/CAPABILITIES.md).
136
+ Use `capabilities().capabilities` before calling optional Context, Edit movement, or text-edit paths. The complete public list is in [Capabilities](../../docs/CAPABILITIES.md).
140
137
 
141
138
  ## Select exact targets
142
139
 
@@ -153,9 +150,9 @@ Each selector must resolve to exactly one target. Missing or ambiguous selectors
153
150
 
154
151
  For multi-selection, inspect every selected target and the relevant pair relationships. Prefer `selection.visualContext.distances`; use `distance(a, b)` when a needed pair has no existing evidence. Box, guide, container, and diagonal semantics are defined in [Measurements and distance geometry](../../docs/MEASUREMENTS.md).
155
152
 
156
- ## Arrange intent
153
+ ## Edit movement intent
157
154
 
158
- Arrange expresses requested geometry, not source implementation.
155
+ Edit movement expresses requested geometry, not source implementation. The agent method names keep `Arrange` for compatibility.
159
156
 
160
157
  ```js
161
158
  const intents = await window.__MESURER__.arrangements()
@@ -172,17 +169,17 @@ await window.__MESURER__.showArrange(arrangeId, "live")
172
169
  const review = await window.__MESURER__.reviewArrange(arrangeId)
173
170
  ```
174
171
 
175
- Live removes the temporary Arrange preview before measuring source output.
172
+ Live removes the temporary Edit movement preview before measuring source output.
176
173
 
177
- Arrange preview ownership is conservative. Mesurer restores an older transform only while the element still carries the exact preview value and priority Mesurer applied. Host-authored transform changes survive review, refresh, and disposal.
174
+ Edit movement preview ownership is conservative. Mesurer restores an older transform only while the element still carries the exact preview value and priority Mesurer applied. Host-authored transform changes survive review, refresh, and disposal.
178
175
 
179
- See [Arrange](../../docs/ARRANGE.md).
176
+ See [Edit](../../docs/EDIT.md).
180
177
 
181
178
  ## Text and Typography intent
182
179
 
183
180
  Direct text editing records copy and typography intent without pretending to edit source. The human-facing tool is **Typography**; the internal compatibility id remains `text-inspector`.
184
181
 
185
- Editing starts by double-click/double-tap while Select or Typography is active. Arrange keeps Select active, so editing works while Arrange remains selected.
182
+ Editing starts by double-click or double-tap while Edit is active. Typography in Select stays inspection-only. Movement and direct text/style editing can therefore share one Edit session.
186
183
 
187
184
  Native editing stays native. Mesurer does not intercept form controls or descendants that inherit `contenteditable`. A nested `contenteditable="false"` boundary ends inherited editability and can become a Mesurer target when the direct-text rules otherwise pass. Mixed inline copy can target the exact direct text run under the pointer while preserving inline children and the host element's native DOM surface.
188
185
 
@@ -201,7 +198,7 @@ const intent = await window.__MESURER__.textEdit(textEditId)
201
198
 
202
199
  Treat `intent.desired` and style deltas as visual/source requirements, not inline CSS instructions. Look for the application's semantic props, classes, design tokens, CSS variables, theme values, or stylesheet rules that produce the requested render.
203
200
 
204
- Verification must use Live source with the Desired preview inactive. Text/style preview ownership follows the same conservative rule as Arrange: while the DOM still equals Mesurer's owned value, undo/redo can move it to the restored Desired value; once the application changes it, Mesurer preserves the host value instead of overwriting it during history or cleanup.
201
+ Verification must use Live source with the Desired preview inactive. Text/style preview ownership follows the same conservative ownership rule as Edit movement: while the DOM still equals Mesurer's owned value, undo/redo can move it to the restored Desired value; once the application changes it, Mesurer preserves the host value instead of overwriting it during history or cleanup.
205
202
 
206
203
  Do not infer Context availability from transient chrome. While a direct editor is active the Add Note button is absent by design, but `annotations()`, annotation-scoped `context()`, and `review()` remain the durable interface.
207
204
 
@@ -248,19 +245,17 @@ The optional human `screenshot()` plugin from `mesurer-solid/plugins` is a separ
248
245
 
249
246
  ## Optional human-to-Codex delivery
250
247
 
251
- A page can mount `codex()` next to `context()` for explicit human-triggered delivery. This is optional and does not add a generic send method to `window.__MESURER__`.
248
+ The first-party `codex()` plugin is enabled by default and remains toggleable in Mesurer Settings. It is a human-triggered delivery path and does not add a generic send method to `window.__MESURER__`.
252
249
 
253
- For local Codex projects, the trusted `SessionStart` connector starts or reuses the packaged loopback companion and registers the current session with its project directory. Browser code cannot register arbitrary sessions or start the local process.
250
+ Native hosts expose `window.__MESURER_HOST__.codexBridge(request)`. The matching `codexBridge()` implementation is published from `mesurer-solid/plugins/codex/bridge` and runs in the host process. Shared sessions use Codex's existing local app-server. When the host inherits both `CODEX_THREAD_ID` and `CODEX_APP_TOOLS_PIPE_PATH` from Codex Desktop, Mesurer exposes only that exact Desktop thread, queues once through Codex's native queue command, and wakes the same thread with `codex://threads/<id>`. The app-tools pipe is an ownership signal only and is never opened. There is no Mesurer Codex daemon, localhost listener, marketplace plugin, or lifecycle hook.
254
251
 
255
- Delivery uses Codex's native durable queue. Mesurer queues once and keeps the queued-submission id. Desktop delivery opens the existing `codex://threads/<threadId>` destination and lets Codex's queue watcher run the item when the thread can accept it. CLI/TUI sessions use the same queued item and may resume a cold `notLoaded` thread through the shared daemon. Mesurer never calls `turn/steer`, never deletes and resends an existing queue item during recovery, and does not use the Desktop app-tools pipe as a second delivery path.
252
+ Shared delivery exposes currently loaded Codex threads. Desktop fallback exposes only the exact inherited current thread and refuses any other destination. Page affinity and explicit destination overrides remain fail-closed.
256
253
 
257
- The browser plugin connects lazily on the first Queue to Codex or thread-picker action. Page affinity and an explicit destination override persist per tab. If several registered threads are visible and the page has no saved destination, the user must choose one.
254
+ Shared delivery calls `thread/queue/add` directly. Desktop current-thread delivery uses the native queue command only for that exact inherited thread. Mesurer never calls `turn/steer`, never creates a thread, and never reconstructs a second user-message queue. The typed `codex:v1` service exposes `health()`, `listThreads()`, `useThread(thread)`, `delivery(deliveryId)`, and canonical `queue(request?)`. `send(request?)` remains a compatibility alias.
258
255
 
259
- The typed `codex:v1` service exposes `health()`, `listThreads()`, `useThread(thread)`, `delivery(deliveryId)`, and canonical `queue(request?)`. `send(request?)` remains a compatibility alias. The generic plugin command is `codex.queue`; `codex.send` remains its compatibility alias. Queue submission is single-flight. A matched completed turn may remove only the annotation ids sent with that delivery; interrupted, failed, ambiguous, or unreadable work keeps them.
256
+ Queue submission is single-flight. A matched completed turn may remove only the annotation ids sent with that delivery; interrupted, failed, ambiguous, or unreadable work keeps them. Turn completion is transport state, not proof that the requested UI result is correct.
260
257
 
261
- Mesurer does not create new Codex threads. Create or open the thread in Codex and let `SessionStart` register it. Turn completion is transport lifecycle, not proof that the requested UI result is correct.
262
-
263
- See [Queue Context feedback to Codex](../../docs/CODEX.md) for setup, routing, recovery, privacy, and failure behavior.
258
+ See [Queue Context feedback to Codex](../../docs/CODEX.md) for host wiring, routing, recovery, privacy, and failure behavior.
264
259
 
265
260
  ## Revalidate after source edits
266
261
 
@@ -272,7 +267,7 @@ await window.__MESURER__.stable()
272
267
 
273
268
  Then compare the same evidence retained before editing:
274
269
 
275
- - Arrange Desired against Live through `reviewArrange()`;
270
+ - Edit movement Desired against Live through `reviewArrange()`;
276
271
  - text/style Desired against Live with the text preview inactive;
277
272
  - saved annotations through `review()`;
278
273
  - current selections and measurements through fresh `context()`;
@@ -282,6 +277,6 @@ Do not clear human history merely to expose Live state, and do not reinject just
282
277
 
283
278
  ## Completion rule
284
279
 
285
- A meaningful Mesurer call should affect the work. If exact geometry is available, use it instead of estimating pixels from a screenshot. If the user already encoded intent in Arrange, text editing, annotations, or selection, consume it before asking them to repeat it.
280
+ A meaningful Mesurer call should affect the work. If exact geometry is available, use it instead of estimating pixels from a screenshot. If the user already encoded intent in Edit movement, text editing, annotations, or selection, consume it before asking them to repeat it.
286
281
 
287
282
  The repository's packaged [`mesurer-ui` skill](./skills/mesurer-ui/SKILL.md) carries the operational version of this contract for coding agents. [Browser and agent integration](../../docs/BROWSER_HARNESS.md) documents the browser-control boundary.
package/README.md CHANGED
@@ -8,6 +8,11 @@ Mesurer Solid ships its own isolated Solid 2 renderer. Host applications can use
8
8
  <img src="https://raw.githubusercontent.com/jhomra21/mesurer-solid/main/docs/assets/readme/hero-multi-spacing.png" alt="Mesurer Solid measuring spacing between selected elements" width="100%">
9
9
  </p>
10
10
 
11
+ <p align="center">
12
+ <img src="https://raw.githubusercontent.com/jhomra21/mesurer-solid/main/docs/assets/readme/electron-typography.png" alt="Mesurer Solid inspecting typography inside an Electron application" width="49%">
13
+ <img src="https://raw.githubusercontent.com/jhomra21/mesurer-solid/main/docs/assets/readme/electron-rulers.png" alt="Mesurer Solid using rulers and guides inside an Electron application" width="49%">
14
+ </p>
15
+
11
16
  ## Installation
12
17
 
13
18
  ```bash
@@ -51,20 +56,20 @@ All public first-party plugin factories are exported from `mesurer-solid/plugins
51
56
 
52
57
  ```ts
53
58
  import { mountMesurer } from "mesurer-solid"
54
- import { arrange, context, layoutGuides, screenshot } from "mesurer-solid/plugins"
59
+ import { context, edit, layoutGuides, screenshot } from "mesurer-solid/plugins"
55
60
 
56
61
  const mesurer = mountMesurer({
57
62
  agent: true,
58
63
  plugins: [
59
64
  context(),
60
- arrange(),
65
+ edit(),
61
66
  layoutGuides(),
62
67
  screenshot(),
63
68
  ],
64
69
  })
65
70
  ```
66
71
 
67
- The base inspector includes Select, X-ray, Rulers, Typography, Guides, Distance, Settings, plugin hosting, direct text editing, and the low-level inspection API. Color Picker uses application-local capture when `window.__MESURER_HOST__.captureScreenshot` is available; other supported browser hosts use an operational `EyeDropper`. A successful sample is copied to the clipboard using `colorPickerClickFormat`.
72
+ The base inspector includes Select, X-ray, Rulers, Typography, Guides, Distance, Settings, plugin hosting, direct text editing, and the low-level inspection API. The toolbar groups those controls into Select and Edit. Typography stays read-only in Select; Edit owns movement and direct text/style changes. Color Picker uses application-local capture when `window.__MESURER_HOST__.captureScreenshot` is available; other supported browser hosts use an operational `EyeDropper`. A successful sample is copied to the clipboard using `colorPickerClickFormat`.
68
73
 
69
74
  `mesurer-solid/plugins` also exports the built-in factories for lower-level composition. Normal mounts already include the built-ins. Use `excludeBuiltins` with names such as `"xray"`, `"typography"`, and `"colorPicker"` when a mount should omit one.
70
75
 
@@ -80,8 +85,7 @@ Advanced integrations may supply their own `pluginHost`. That host remains calle
80
85
  | `mesurer-solid/inject` | Programmatic browser injection |
81
86
  | `mesurer-solid/inject-script` | Built classic injection artifact |
82
87
  | `mesurer-skill` | Install the portable coding-agent skill |
83
- | `mesurer-codex` | Run the optional loopback Codex queue companion |
84
- | `mesurer-codex-connect` | Start or reuse the matching Codex companion and register the current Codex session |
88
+ | `mesurer-solid/plugins/codex/bridge` | Native-host Codex Bridge for the first-party Codex plugin |
85
89
 
86
90
  Programmatic injection reuses an existing connected instance by default. Lifecycle-owning integrations can set `recoverDisconnected: true` in `MesurerInjectConfig` to remount Mesurer when page DOM replacement disconnects its host. The option defaults to `false`, so ordinary one-shot injection does not silently reappear after disposal.
87
91
 
@@ -91,8 +95,8 @@ Programmatic injection reuses an existing connected instance by default. Lifecyc
91
95
  - Measure distance and pairwise multi-selection spacing.
92
96
  - Use X-ray, guides, rulers, and persisted settings.
93
97
  - Add page-scoped columns, rows, or pixel grids with the optional `layoutGuides()` plugin. Guide edits participate in plugin undo/redo, and Context includes the current page's saved guides with their visibility state.
94
- - Inspect Typography and preview reversible direct copy/style changes.
95
- - Arrange selected UI into a Desired position without changing source.
98
+ - Inspect rendered typography in Select. Edit previews reversible direct copy and style changes.
99
+ - Use Edit to move selected UI and change direct text, typography, and text color without changing source.
96
100
  - Capture page regions through the optional Screenshot plugin. It selects native host capture, the Chromium extension adapter, or browser display capture internally.
97
101
  - Read selection, measurements, guides, annotations, layout, styles, and saved human intent through Context and agent APIs.
98
102
  - Keep saved annotations across same-tab reloads and conservatively rebind them to their original DOM targets; markers, cards, and ownership evidence stay attached through scrolling, repeated-note markers stay local, Add Note remains available while a note is open, and cards/composers occlude Select hover and selection chrome.
@@ -100,11 +104,11 @@ Programmatic injection reuses an existing connected instance by default. Lifecyc
100
104
  - Compact the toolbar to active controls without changing tool state or order.
101
105
  - Choose System, Light, or Dark appearance while keeping the same theme across isolated and document-backed Mesurer UI.
102
106
 
103
- Arrange is not a toolbar mode. It can be activated before a selection exists and enables Select automatically. Turning Arrange off leaves Select active; turning Select off exits Arrange. Escape clears the current Select or Arrange selection first. A second Escape with nothing selected exits Select, or exits both Arrange and Select. Each moved Arrange target has a Reset position control, and the Arrange menu can reset all positions on the current page.
107
+ Use `1` for Select and `2` for Edit. Select contains inspection tools. Edit owns movement and direct text/style changes. Context and Codex remain visible in both modes. The grouped toolbar changes modes in 150 ms. `Shift+A` still enters Edit for compatibility with existing Arrange workflows.
104
108
 
105
109
  Toolbar dragging starts after the pointer crosses the drag threshold. Dragging from Settings, Guide, or plugin triggers closes the open menu or panel. Pointer activity inside menus, dialogs, form controls, editable regions, and sliders does not drag the toolbar.
106
110
 
107
- Select and agent point inspection use the same rendered hit-test path. They can target SVG and visible `pointer-events:none` descendants instead of collapsing those descendants to an interactive ancestor. Open shadow roots are traversed; closed shadow roots remain browser-owned boundaries. Context and annotations accept the same SVG targets. Arrange and direct text editing only mutate HTML elements.
111
+ Select and agent point inspection use the same rendered hit-test path. They can target SVG and visible `pointer-events:none` descendants instead of collapsing those descendants to an interactive ancestor. Open shadow roots are traversed; closed shadow roots remain browser-owned boundaries. Context and annotations accept the same SVG targets. Edit movement and direct text editing only mutate HTML elements.
108
112
 
109
113
  Persisted workspace evidence is page-scoped by route, including sorted query parameters. In-tab navigation swaps the current page workspace without carrying page-owned guides or selection state to another route. Toolbar placement remains tab-session UI and survives those route changes and reloads.
110
114
 
@@ -112,7 +116,7 @@ Direct text editing respects native editing boundaries. Descendants of an editab
112
116
 
113
117
  While direct text editing is active, Mesurer keeps one visible edit ring, keeps the selected dimensions pill and Typography separated by the same `2px` rendered gap when the card is below the source, and keeps Typography stationary during ordinary pointer movement. The selection-adjacent Add Note button is suppressed only for the active edit and returns when the editor closes; saved annotation markers and panels remain available.
114
118
 
115
- Mesurer previews text, styles, and Arrange transforms only while it still owns the value it applied. Host-authored changes take ownership and are preserved through undo/redo, Live review, cleanup, and disposal.
119
+ Mesurer previews text, styles, and Edit movement only while it still owns the value it applied. Host-authored changes take ownership and are preserved through undo/redo, Live review, cleanup, and disposal.
116
120
 
117
121
  ## Appearance
118
122
 
@@ -131,6 +135,8 @@ Global shortcuts are enabled by default. Turn them off from **Settings > General
131
135
  | Shortcut | Action |
132
136
  | --- | --- |
133
137
  | `M` | Toggle Mesurer |
138
+ | `1` | Select mode |
139
+ | `2` | Edit mode |
134
140
  | `S` | Select |
135
141
  | `X` | X-ray |
136
142
  | `P` | Color Picker when supported |
@@ -141,7 +147,7 @@ Global shortcuts are enabled by default. Turn them off from **Settings > General
141
147
  | `H` / `V` | Horizontal / vertical guide orientation |
142
148
  | `Alt` / `Option` | Distance overlay |
143
149
  | `Cmd/Ctrl + ,` | Settings |
144
- | `Shift + A` | Arrange |
150
+ | `Shift + A` | Edit compatibility shortcut |
145
151
  | `Shift + S` | Screenshot |
146
152
  | `C` | Copy Context |
147
153
  | `Shift + C` | Copy Selection |
@@ -151,7 +157,7 @@ Plugin shortcuts are active only when their plugin is mounted and enabled.
151
157
 
152
158
  ## Agent integration
153
159
 
154
- Enable `agent: true` to expose the full browser agent object through `mesurer.agent` and `window.__MESURER__`. The mounted instance also mirrors the high-level Context, Arrange, and text-intent methods.
160
+ Enable `agent: true` to expose the full browser agent object through `mesurer.agent` and `window.__MESURER__`. The mounted instance also mirrors high-level Context, Edit movement, and text-intent methods. The movement method names retain `Arrange` for compatibility.
155
161
 
156
162
  ```ts
157
163
  const workspace = await mesurer.context()
@@ -164,40 +170,28 @@ Install the portable Agent Skill with:
164
170
  npx --yes --package=mesurer-solid mesurer-skill install
165
171
  ```
166
172
 
167
- The skill preserves existing human state, reads Arrange/text/annotation intent before source changes, and verifies the real Live result after implementation.
173
+ The skill preserves existing human state, reads Edit movement, text, and annotation intent before source changes, and verifies the real Live result after implementation.
168
174
 
169
175
  See [Agent integration](https://github.com/jhomra21/mesurer-solid/blob/main/packages/mesurer/AGENT_INTEGRATION.md).
170
176
 
171
- ### Optional Queue to Codex
177
+ ### Queue to Codex
172
178
 
173
- Mount `codex()` next to Context when a person should be able to queue the current review to Codex:
179
+ Codex is enabled by default and remains toggleable under **Settings -> Plugins**.
174
180
 
175
- ```ts
176
- import { mountMesurer } from "mesurer-solid"
177
- import { codex, context } from "mesurer-solid/plugins"
181
+ Native applications expose `window.__MESURER_HOST__.codexBridge` from preload/main and back it with `codexBridge()` from `mesurer-solid/plugins/codex/bridge`. The bridge runs in the native host process. Shared sessions use Codex's local app-server directly. If the host inherited an exact Codex Desktop thread, the bridge queues once to that thread through Codex's native queue command and wakes it with `codex://threads/<id>`. The Desktop app-tools pipe is never opened. There is no Mesurer localhost server, helper Electron process, marketplace plugin, SessionStart hook, or repeated trust step.
178
182
 
179
- mountMesurer({
180
- plugins: [context(), codex()],
181
- })
182
- ```
183
-
184
- The trusted Codex `SessionStart` integration normally starts or reuses the local companion and registers the current thread. It can also be run directly:
185
-
186
- ```bash
187
- bunx mesurer-codex-connect
188
- ```
183
+ **Queue to Codex** remains one runtime-neutral API. Shared delivery tracks Queued, Working, Finished, or Interrupted through the shared app-server. Desktop current-thread delivery reports the durable queued submission and wake result without fabricating private Desktop lifecycle state. It does not create threads or invoke Steer.
189
184
 
190
- **Queue to Codex** writes one item to Codex's native durable queue and tracks that delivery through Queued, Working, Finished, or Interrupted. It does not create threads or invoke Steer. A Mesurer page keeps its selected destination across a same-tab reload.
185
+ Saved annotations included in a delivery are removed only after the exact matched turn completes. Interrupted, failed, ambiguous, or unreadable deliveries keep them. Set `codex({ clearCompletedAnnotations: false })` to retain completed notes.
191
186
 
192
- Saved annotations included in a delivery are removed only after the exact matched turn completes. Interrupted, failed, or uncertain deliveries keep them. Set `codex({ clearCompletedAnnotations: false })` to retain completed notes.
187
+ See [Queue Context feedback to Codex](https://github.com/jhomra21/mesurer-solid/blob/main/docs/CODEX.md) for host wiring, loaded-thread discovery, recovery, and the typed `codex:v1` service.
193
188
 
194
- See [Queue Context feedback to Codex](https://github.com/jhomra21/mesurer-solid/blob/main/docs/CODEX.md) for thread discovery, Desktop and CLI/TUI behavior, lifecycle recovery, permissions, and the typed `codex:v1` service.
195
189
  ## Documentation
196
190
 
197
191
  - [Capabilities](https://github.com/jhomra21/mesurer-solid/blob/main/docs/CAPABILITIES.md)
198
192
  - [Getting started](https://github.com/jhomra21/mesurer-solid/blob/main/docs/GETTING_STARTED.md)
199
193
  - [Direct text editing and Typography](https://github.com/jhomra21/mesurer-solid/blob/main/docs/TEXT_EDITING.md)
200
- - [Arrange](https://github.com/jhomra21/mesurer-solid/blob/main/docs/ARRANGE.md) and [Layout Guides](https://github.com/jhomra21/mesurer-solid/blob/main/docs/LAYOUT_GUIDES.md)
194
+ - [Edit](https://github.com/jhomra21/mesurer-solid/blob/main/docs/EDIT.md) and [Layout Guides](https://github.com/jhomra21/mesurer-solid/blob/main/docs/LAYOUT_GUIDES.md)
201
195
  - [Measurements and distance geometry](https://github.com/jhomra21/mesurer-solid/blob/main/docs/MEASUREMENTS.md)
202
196
  - [Screenshots](https://github.com/jhomra21/mesurer-solid/blob/main/docs/SCREENSHOTS.md)
203
197
  - [Electron renderer example](https://github.com/jhomra21/mesurer-solid/blob/main/examples/electron-renderer/README.md)
package/dist/arrange.d.ts CHANGED
@@ -90,3 +90,26 @@ export type MesurerArrangeService = {
90
90
  clear(): Promise<void>;
91
91
  };
92
92
  export declare const arrange: () => MesurerPlugin;
93
+ /**
94
+ * Canonical public name for Mesurer's page-editing plugin.
95
+ *
96
+ * The underlying Arrange ids remain stable so persisted layouts, agent data,
97
+ * and existing integrations continue to work across the rename.
98
+ */
99
+ export declare const edit: () => MesurerPlugin;
100
+ export declare const MESURER_EDIT_ACTIVE_STATE_ID: string;
101
+ export declare const MESURER_EDIT_PLUGIN_ID: string;
102
+ export declare const MESURER_EDIT_SERVICE_ID: string;
103
+ export declare const MESURER_EDIT_SETTINGS_STATE_ID: string;
104
+ export declare const MESURER_EDIT_STATE_ID: string;
105
+ export type EditRect = ArrangeRect;
106
+ export type EditOffset = ArrangeOffset;
107
+ export type EditElementFingerprint = ArrangeElementFingerprint;
108
+ export type EditTarget = ArrangeTarget;
109
+ export type EditIntent = ArrangeIntent;
110
+ export type EditPresentation = ArrangePresentation;
111
+ export type EditReviewTarget = ArrangeReviewTarget;
112
+ export type EditReview = ArrangeReview;
113
+ export type EditCapturePlan = ArrangeCapturePlan;
114
+ export type MesurerEditSettings = MesurerArrangeSettings;
115
+ export type MesurerEditService = MesurerArrangeService;
package/dist/core.d.ts CHANGED
@@ -22,6 +22,7 @@ export type ToolMenuContribution = {
22
22
  label?: string;
23
23
  items: ToolMenuItemContribution[];
24
24
  };
25
+ export type ToolbarMode = "select" | "edit" | "always";
25
26
  export type ToolContribution = {
26
27
  id: string;
27
28
  label: string;
@@ -29,6 +30,8 @@ export type ToolContribution = {
29
30
  command: string;
30
31
  order?: number;
31
32
  builtin?: string;
33
+ toolbarMode?: ToolbarMode;
34
+ modeSwitch?: boolean;
32
35
  icon?: {
33
36
  viewBox?: string;
34
37
  paths: string[];
@@ -138,6 +141,8 @@ export type MesurerPluginDescription = {
138
141
  command: string;
139
142
  order?: number;
140
143
  builtin?: string;
144
+ toolbarMode?: ToolbarMode;
145
+ modeSwitch?: boolean;
141
146
  }>;
142
147
  settings: SettingsDescription[];
143
148
  overlays: OverlayContribution[];
package/dist/index.d.ts CHANGED
@@ -142,9 +142,9 @@ export type MesurerOptions = {
142
142
  selectionSpacingStyle?: Partial<SelectionSpacingStyle>;
143
143
  rulerSettings?: Partial<RulerSettings>;
144
144
  /**
145
- * Initial enabled plugin set. Omit this to enable every first-party Mesurer plugin.
146
- * Omitted first-party plugins remain toggleable in Settings from the same canonical
147
- * registry; callers never maintain a separate availability or Settings list.
145
+ * Initial enabled plugin set. Omit this to use the first-party catalog defaults.
146
+ * First-party plugins, including Codex, remain toggleable in Settings from the
147
+ * same canonical registry.
148
148
  */
149
149
  plugins?: readonly MesurerPlugin[];
150
150
  /** Built-in tools to omit from this mount. Names match the public plugin factories. */
@@ -254,5 +254,5 @@ export type { ArrangeCapturePlan, ArrangeIntent, ArrangeOffset, ArrangePresentat
254
254
  export { captureMesurerContext, copyTextToClipboard, createMesurerCapturePlan, formatMesurerContext, reviewMesurerAnnotation, } from "./context";
255
255
  export type { MesurerAnnotation, MesurerAnnotationBaseline, MesurerAnnotationTarget, MesurerCapturePlanV1, MesurerContextDistance, MesurerContextEdges, MesurerContextGuide, MesurerContextLayoutGuide, MesurerContextMeasurement, MesurerContextRect, MesurerContextRequest, MesurerContextTarget, MesurerContextV1, MesurerElementFingerprint, MesurerElementInspection, MesurerReviewChange, MesurerReviewMetricChange, MesurerReviewPresenceChange, MesurerReviewV1, } from "./context";
256
256
  export { createMesurerPluginHost, createMesurerRuntime, defineMesurerPlugin } from "./core";
257
- export type { CommandHandler as MesurerCommandHandler, MesurerPlugin, MesurerPluginContext, MesurerPluginDescription, MesurerPluginHost, OverlayContribution, Registration as MesurerRegistration, SettingsContribution, StateSliceDefinition, ToolContribution, } from "./core";
257
+ export type { CommandHandler as MesurerCommandHandler, MesurerPlugin, MesurerPluginContext, MesurerPluginDescription, MesurerPluginHost, OverlayContribution, Registration as MesurerRegistration, SettingsContribution, StateSliceDefinition, ToolContribution, ToolbarMode, } from "./core";
258
258
  export type { MesurerHostLayerMode } from "./host-layer";