mesurer-solid 0.1.7 → 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
 
@@ -199,7 +199,15 @@ try {
199
199
  }
200
200
  ```
201
201
 
202
- 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).
203
211
 
204
212
  ## Revalidate after source edits
205
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
 
@@ -135,6 +135,43 @@ The skill preserves existing human state, reads Arrange/text/annotation intent b
135
135
 
136
136
  See [Agent integration](https://github.com/jhomra21/mesurer-solid/blob/main/packages/mesurer/AGENT_INTEGRATION.md).
137
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
+
138
175
  ## Documentation
139
176
 
140
177
  - [Getting started](https://github.com/jhomra21/mesurer-solid/blob/main/docs/GETTING_STARTED.md)
@@ -142,6 +179,7 @@ See [Agent integration](https://github.com/jhomra21/mesurer-solid/blob/main/pack
142
179
  - [Arrange](https://github.com/jhomra21/mesurer-solid/blob/main/docs/ARRANGE.md)
143
180
  - [Screenshots](https://github.com/jhomra21/mesurer-solid/blob/main/docs/SCREENSHOTS.md)
144
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)
145
183
  - [Browser harness](https://github.com/jhomra21/mesurer-solid/blob/main/docs/BROWSER_HARNESS.md)
146
184
  - [Host isolation](https://github.com/jhomra21/mesurer-solid/blob/main/docs/HOST_ISOLATION.md)
147
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[];