mesurer-solid 0.1.7-beta.9 → 0.1.8-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
- There is no Mesurer MCP server, localhost daemon, Send-to-agent callback, or harness-specific transport.
5
+ The normal agent workflow requires no Mesurer MCP server, localhost daemon, Send-to-agent callback, or harness-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.
6
6
 
7
7
  ## Install the Agent Skill
8
8
 
@@ -151,6 +151,8 @@ The editing UI exposes direct B/I/U, Font, Size, Weight, rendered-page colors, c
151
151
 
152
152
  If Typography was already explicitly selected, the direct-edit session suppresses the older hover/pinned Typography surface so the field has one live card. The normal surface returns when editing ends.
153
153
 
154
+ Direct edit also owns the field's visible selection lane. The duplicate ordinary selected border is paint-suppressed, the selected dimensions pill remains available, and the Typography card stays source-relative without reacting to ordinary pointer movement. The selection-adjacent Add Note button is intentionally hidden during the active edit and returns afterward. Existing saved annotation state remains available throughout.
155
+
154
156
  Read durable intent through:
155
157
 
156
158
  ```js
@@ -162,6 +164,8 @@ Treat `intent.desired` and style deltas as visual/source requirements, not inlin
162
164
 
163
165
  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.
164
166
 
167
+ 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.
168
+
165
169
  See [Direct text editing and Typography](../../docs/TEXT_EDITING.md).
166
170
 
167
171
  ## Annotation and context review
@@ -195,7 +199,15 @@ try {
195
199
  }
196
200
  ```
197
201
 
198
- The optional `mesurer-solid/screenshot` plugin is a separate human camera workflow. It is not an agent delivery capability. Preserve an existing human preview unless the task is specifically about Screenshot behavior.
202
+ The optional human `screenshot()` plugin from `mesurer-solid/plugins` is a separate camera workflow. It is not an agent delivery capability. Preserve an existing human preview unless the task is specifically about Screenshot behavior.
203
+
204
+ ## Optional human-to-Codex delivery
205
+
206
+ A source-mounted page may opt into `codex()` from `mesurer-solid/plugins` alongside `context()`. This is not an agent integration requirement and does not add a generic send capability to `window.__MESURER__`.
207
+
208
+ When the current Codex thread starts `mesurer-codex`, the companion reads Codex's `CODEX_THREAD_ID`, registers that thread, and makes it the default destination. That means a Codex session that starts or uses Mesurer can route later human Context feedback back to the same thread without copying an id by hand. A normal shell may still select the initial session explicitly with `mesurer-codex --thread <SESSION>`.
209
+
210
+ A different or newly-created Codex thread can join an already-running bridge with `mesurer-codex --register-current`. Registration is accepted only from a local process without a browser Origin. The bridge keeps previously registered threads; the `codex:v1` service can inspect them with `health()`, switch the default with `useThread(thread)`, or send one message to another registered destination with `send({ thread })`. Mesurer does not create or resume Codex threads itself. See [Send Context feedback to Codex](../../docs/CODEX.md).
199
211
 
200
212
  ## Revalidate after source edits
201
213
 
package/README.md CHANGED
@@ -42,35 +42,35 @@ Full placement examples: [Getting started](https://github.com/jhomra21/mesurer-s
42
42
 
43
43
  ## First-party plugins
44
44
 
45
+ All public first-party plugin factories are exported from `mesurer-solid/plugins` and use the feature name directly:
46
+
45
47
  ```ts
46
- import {
47
- contextPlugin,
48
- mountMesurer,
49
- } from "mesurer-solid"
50
- import { arrangePlugin } from "mesurer-solid/arrange"
51
- import { screenshotPlugin } from "mesurer-solid/screenshot"
48
+ import { mountMesurer } from "mesurer-solid"
49
+ import { arrange, context, screenshot } from "mesurer-solid/plugins"
52
50
 
53
51
  const mesurer = mountMesurer({
54
52
  agent: true,
55
53
  plugins: [
56
- contextPlugin(),
57
- arrangePlugin(),
58
- screenshotPlugin(),
54
+ context(),
55
+ arrange(),
56
+ screenshot(),
59
57
  ],
60
58
  })
61
59
  ```
62
60
 
63
61
  The base inspector includes Select, X-ray, Rulers, Typography, Guides, Distance, Settings, plugin hosting, direct text editing, and the low-level inspection API. Native Color Picker is available only when the host exposes an operational `EyeDropper`.
64
62
 
63
+ For explicit plugin composition, `mesurer-solid/plugins` also exports `select`, `xray`, `colorPicker`, `rulers`, `typography`, `guides`, `distance`, `settings`, `defaults`, and `compose`.
64
+
65
65
  | Entry | Purpose |
66
66
  | --- | --- |
67
- | `mesurer-solid` | Mount API, context plugin, public types, agent surface |
68
- | `mesurer-solid/arrange` | Arrange layout-intent plugin |
69
- | `mesurer-solid/screenshot` | Screenshot capture plugin |
67
+ | `mesurer-solid` | Mount API, public domain types, and agent surface |
68
+ | `mesurer-solid/plugins` | All first-party plugin factories and plugin-specific contracts |
70
69
  | `mesurer-solid/core` | Lower-level framework-neutral public contracts |
71
70
  | `mesurer-solid/inject` | Programmatic browser injection |
72
71
  | `mesurer-solid/inject-script` | Built classic injection artifact |
73
72
  | `mesurer-skill` | Install the portable coding-agent skill |
73
+ | `mesurer-codex` | Run the optional loopback Codex queue companion |
74
74
 
75
75
  ## Features
76
76
 
@@ -88,6 +88,8 @@ Arrange is not a toolbar mode. It can be activated before a selection exists and
88
88
 
89
89
  Direct text editing respects native editing boundaries. Descendants of an editable ancestor remain native, while a nested `contenteditable="false"` boundary ends inherited editability and can become a Mesurer target when the normal direct-text rules pass.
90
90
 
91
+ 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.
92
+
91
93
  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.
92
94
 
93
95
  ## Shortcuts
@@ -133,6 +135,43 @@ The skill preserves existing human state, reads Arrange/text/annotation intent b
133
135
 
134
136
  See [Agent integration](https://github.com/jhomra21/mesurer-solid/blob/main/packages/mesurer/AGENT_INTEGRATION.md).
135
137
 
138
+ ### Optional Send to Codex
139
+
140
+ When Codex starts the loopback companion itself, `mesurer-codex` reads `CODEX_THREAD_ID`, so Mesurer feedback naturally routes back to that same Codex CLI/App thread:
141
+
142
+ ```bash
143
+ bunx mesurer-codex
144
+ ```
145
+
146
+ A normal shell can still choose the initial thread explicitly:
147
+
148
+ ```bash
149
+ bunx mesurer-codex --thread <SESSION>
150
+ ```
151
+
152
+ Mount the optional transport next to Context:
153
+
154
+ ```ts
155
+ import { mountMesurer } from "mesurer-solid"
156
+ import { codex, context } from "mesurer-solid/plugins"
157
+
158
+ mountMesurer({
159
+ plugins: [context(), codex()],
160
+ })
161
+ ```
162
+
163
+ A different or newly-created Codex thread can register itself with the running bridge and become the active target:
164
+
165
+ ```bash
166
+ bunx mesurer-codex --register-current
167
+ ```
168
+
169
+ The bridge remembers registered threads. `codex:v1` exposes `health()`, `useThread(thread)`, and `send({ thread })` for switching or one-off routing among those registered destinations. Browser pages cannot register arbitrary Codex sessions themselves.
170
+
171
+ This uses Codex's own queued-user-message command. It does not replace the normal browser-harness agent workflow, and it does not resume or take ownership of a target Codex thread.
172
+
173
+ See [Send Context feedback to Codex](https://github.com/jhomra21/mesurer-solid/blob/main/docs/CODEX.md).
174
+
136
175
  ## Documentation
137
176
 
138
177
  - [Getting started](https://github.com/jhomra21/mesurer-solid/blob/main/docs/GETTING_STARTED.md)
@@ -140,6 +179,7 @@ See [Agent integration](https://github.com/jhomra21/mesurer-solid/blob/main/pack
140
179
  - [Arrange](https://github.com/jhomra21/mesurer-solid/blob/main/docs/ARRANGE.md)
141
180
  - [Screenshots](https://github.com/jhomra21/mesurer-solid/blob/main/docs/SCREENSHOTS.md)
142
181
  - [Context workflow](https://github.com/jhomra21/mesurer-solid/blob/main/docs/CONTEXT_WORKFLOW.md)
182
+ - [Send Context feedback to Codex](https://github.com/jhomra21/mesurer-solid/blob/main/docs/CODEX.md)
143
183
  - [Browser harness](https://github.com/jhomra21/mesurer-solid/blob/main/docs/BROWSER_HARNESS.md)
144
184
  - [Host isolation](https://github.com/jhomra21/mesurer-solid/blob/main/docs/HOST_ISOLATION.md)
145
185
  - [Trusted Types](https://github.com/jhomra21/mesurer-solid/blob/main/docs/TRUSTED_TYPES.md)
package/dist/arrange.d.ts CHANGED
@@ -87,4 +87,4 @@ export type MesurerArrangeService = {
87
87
  review(id: string, tolerance?: number): ArrangeReview;
88
88
  clear(): Promise<void>;
89
89
  };
90
- export declare const arrangePlugin: () => MesurerPlugin;
90
+ export declare const arrange: () => MesurerPlugin;
@@ -0,0 +1,37 @@
1
+ import type { MesurerPlugin } from "./core";
2
+ export declare const MESURER_CODEX_PLUGIN_ID = "mesurer.codex";
3
+ export declare const MESURER_CODEX_SERVICE_ID = "codex:v1";
4
+ export type MesurerCodexPluginOptions = {
5
+ /** Loopback bridge URL. Defaults to http://127.0.0.1:47365. */
6
+ endpoint?: string;
7
+ /** Default instruction prepended to Mesurer evidence. */
8
+ instruction?: string;
9
+ /** Show the Send to Codex toolbar action. Defaults to true. */
10
+ ui?: boolean;
11
+ };
12
+ export type MesurerCodexSendRequest = {
13
+ /** Optional instruction for this send. */
14
+ instruction?: string;
15
+ /** Send only these saved annotation ids. When omitted, all saved annotations are sent. */
16
+ annotationIds?: string[];
17
+ /** Send to a particular registered Codex thread without changing the bridge default. */
18
+ thread?: string;
19
+ };
20
+ export type MesurerCodexSendResult = {
21
+ thread: string;
22
+ output: string;
23
+ };
24
+ export type MesurerCodexHealth = {
25
+ /** Current default target. Null when the bridge has not been bound yet. */
26
+ thread: string | null;
27
+ /** Threads explicitly registered by local Codex processes/users. */
28
+ threads: string[];
29
+ };
30
+ export type MesurerCodexService = {
31
+ health(): Promise<MesurerCodexHealth>;
32
+ /** Switch the default target to an already-registered thread. */
33
+ useThread(thread: string): Promise<MesurerCodexHealth>;
34
+ /** Send Context to the default target or to one explicitly registered thread. */
35
+ send(request?: MesurerCodexSendRequest): Promise<MesurerCodexSendResult>;
36
+ };
37
+ export declare function codex(options?: MesurerCodexPluginOptions): MesurerPlugin;
@@ -18,4 +18,4 @@ export type MesurerContextService = {
18
18
  prepareCapture(): Promise<void>;
19
19
  finishCapture(): Promise<void>;
20
20
  };
21
- export declare function contextPlugin(options?: MesurerContextPluginOptions): MesurerPlugin;
21
+ export declare function context(options?: MesurerContextPluginOptions): MesurerPlugin;
package/dist/index.d.ts CHANGED
@@ -3,14 +3,6 @@ import type { ArrangeCapturePlan, ArrangeIntent, ArrangePresentation, ArrangeRev
3
3
  import type { MesurerAnnotation, MesurerCapturePlanV1, MesurerContextRequest, MesurerContextV1, MesurerReviewV1 } from "./context";
4
4
  import type { MesurerPlugin, MesurerPluginDescription, MesurerPluginHost } from "./core";
5
5
  import { type MesurerHostLayerMode } from "./host-layer";
6
- export type MesurerAvailablePlugin = {
7
- id: string;
8
- label: string;
9
- order?: number;
10
- create(): MesurerPlugin | Promise<MesurerPlugin>;
11
- settingsIds?: string[];
12
- hiddenSettingsControlIds?: string[];
13
- };
14
6
  export type ColorPickerFormat = "hex" | "rgb" | "hsl" | "oklch";
15
7
  export type MesurerBuiltinPluginId = "select" | "xray" | "color-picker" | "rulers" | "text-inspector" | "guides" | "distance" | "settings";
16
8
  export type LinePattern = "solid" | "dashed" | "dotted";
@@ -142,9 +134,12 @@ export type MesurerOptions = {
142
134
  guideStyle?: Partial<GuideStyle>;
143
135
  selectionSpacingStyle?: Partial<SelectionSpacingStyle>;
144
136
  rulerSettings?: Partial<RulerSettings>;
137
+ /**
138
+ * Initial enabled plugin set. Omit this to enable every first-party Mesurer plugin.
139
+ * Omitted first-party plugins remain toggleable in Settings from the same canonical
140
+ * registry; callers never maintain a separate availability or Settings list.
141
+ */
145
142
  plugins?: MesurerPlugin[];
146
- /** Additional plugins that Settings may load on demand even when initially disabled. */
147
- availablePlugins?: MesurerAvailablePlugin[];
148
143
  excludePlugins?: MesurerBuiltinPluginId[];
149
144
  pluginHost?: MesurerPluginHost;
150
145
  onPluginHost?: (host: MesurerPluginHost) => void;
@@ -230,18 +225,6 @@ export type { AgentDistance, AgentEdges, AgentElementInspection, AgentFeedbackSn
230
225
  export type { ArrangeCapturePlan, ArrangeIntent, ArrangeOffset, ArrangePresentation, ArrangeRect, ArrangeReview, ArrangeReviewTarget, ArrangeTarget, MesurerArrangeService, } from "./arrange";
231
226
  export { captureMesurerContext, copyTextToClipboard, createMesurerCapturePlan, formatMesurerContext, reviewMesurerAnnotation, } from "./context";
232
227
  export type { MesurerAnnotation, MesurerAnnotationBaseline, MesurerAnnotationTarget, MesurerCapturePlanV1, MesurerContextDistance, MesurerContextEdges, MesurerContextGuide, MesurerContextMeasurement, MesurerContextRect, MesurerContextRequest, MesurerContextTarget, MesurerContextV1, MesurerElementFingerprint, MesurerElementInspection, MesurerReviewChange, MesurerReviewMetricChange, MesurerReviewPresenceChange, MesurerReviewV1, } from "./context";
233
- export { contextPlugin, MESURER_CONTEXT_PLUGIN_ID, MESURER_CONTEXT_SERVICE_ID, } from "./context-plugin";
234
- export type { MesurerContextPluginOptions, MesurerContextService, } from "./context-plugin";
235
228
  export { createMesurerPluginHost, createMesurerRuntime, defineMesurerPlugin } from "./core";
236
229
  export type { CommandHandler as MesurerCommandHandler, MesurerPlugin, MesurerPluginContext, MesurerPluginDescription, MesurerPluginHost, OverlayContribution, Registration as MesurerRegistration, SettingsContribution, StateSliceDefinition, ToolContribution, } from "./core";
237
230
  export type { MesurerHostLayerMode } from "./host-layer";
238
- export declare const selectPlugin: () => MesurerPlugin;
239
- export declare const xrayPlugin: () => MesurerPlugin;
240
- export declare const colorPickerPlugin: () => MesurerPlugin;
241
- export declare const rulersPlugin: () => MesurerPlugin;
242
- export declare const textInspectorPlugin: () => MesurerPlugin;
243
- export declare const guidesPlugin: () => MesurerPlugin;
244
- export declare const distancePlugin: () => MesurerPlugin;
245
- export declare const settingsPlugin: () => MesurerPlugin;
246
- export declare const defaultMesurerPlugins: () => MesurerPlugin[];
247
- export declare const composeMesurerPlugins: (plugins?: MesurerPlugin[], exclude?: MesurerBuiltinPluginId[]) => MesurerPlugin[];