mesurer-solid 0.1.8-beta.3 → 0.1.9-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.
- package/AGENT_INTEGRATION.md +7 -6
- package/README.md +36 -7
- package/dist/agent.d.ts +1 -1
- package/dist/codex-plugin.d.ts +12 -6
- package/dist/context.d.ts +21 -6
- package/dist/core.d.ts +3 -3
- package/dist/core.js +4 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.js +3928 -2649
- package/dist/inject-script.d.ts +3 -0
- package/dist/inject-script.js +300 -15
- package/dist/inject.d.ts +8 -0
- package/dist/inject.js +3942 -2644
- package/dist/layout-guides.d.ts +31 -0
- package/dist/plugins.d.ts +5 -2
- package/dist/plugins.js +2981 -1935
- package/dist/screenshot.d.ts +35 -2
- package/package.json +1 -1
- package/skills/mesurer-ui/SKILL.md +14 -7
package/AGENT_INTEGRATION.md
CHANGED
|
@@ -10,7 +10,6 @@ The normal agent workflow requires no Mesurer MCP server, localhost daemon, Send
|
|
|
10
10
|
npx --yes --package=mesurer-solid mesurer-skill install
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Use `mesurer-solid@beta` only when intentionally validating a prerelease.
|
|
14
13
|
|
|
15
14
|
The installer writes a self-contained skill and injection artifact:
|
|
16
15
|
|
|
@@ -124,13 +123,15 @@ Use the high-level Context and saved-intent methods for normal UI work. The lowe
|
|
|
124
123
|
| `distance(a, b)` | Measure two selector targets. |
|
|
125
124
|
| `viewport()` | Read viewport/document dimensions, scrolling, device pixel ratio, and overflow. |
|
|
126
125
|
| `feedback(selectors?)` | Read viewport data, inspected elements, plugin description, and plugin state together. |
|
|
127
|
-
| `command(id, args?)` | Execute a registered Mesurer command. |
|
|
126
|
+
| `command(id, args?)` | Execute a registered Mesurer command and return its JSON-safe result when present. |
|
|
128
127
|
| `state()` | Read plugin state. |
|
|
129
128
|
| `stable(frames?)` | Wait for fonts and rendering before measuring again. |
|
|
130
129
|
| `textEdits()` / `textEdit(id)` | Read saved direct-text and typography intent. |
|
|
131
130
|
|
|
132
131
|
Context adds `capabilities()`, `context()`, `contextText()`, `select()`, `annotations()`, `review()`, `capturePlan()`, `prepareCapture()`, and `finishCapture()`.
|
|
133
132
|
|
|
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.
|
|
134
|
+
|
|
134
135
|
Arrange adds `arrangements()`, `arrange()`, `showArrange()`, `arrangeCapturePlan()`, and `reviewArrange()`.
|
|
135
136
|
|
|
136
137
|
Use `capabilities().capabilities` before calling optional Context, Arrange, or text-edit paths. The complete public list is in [Capabilities](../../docs/CAPABILITIES.md).
|
|
@@ -148,7 +149,7 @@ const context = await window.__MESURER__.select([
|
|
|
148
149
|
|
|
149
150
|
Each selector must resolve to exactly one target. Missing or ambiguous selectors throw rather than binding to a guess.
|
|
150
151
|
|
|
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.
|
|
152
|
+
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).
|
|
152
153
|
|
|
153
154
|
## Arrange intent
|
|
154
155
|
|
|
@@ -181,7 +182,7 @@ Direct text editing records copy and typography intent without pretending to edi
|
|
|
181
182
|
|
|
182
183
|
Editing starts by double-click/double-tap while Select or Typography is active. Arrange keeps Select active, so editing works while Arrange remains selected.
|
|
183
184
|
|
|
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.
|
|
185
|
+
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.
|
|
185
186
|
|
|
186
187
|
The editing UI exposes direct B/I/U, Font, Size, Weight, rendered-page colors, custom color, and a separate Text/H1/H2/H3 semantic preset popup. Missing heading levels are not invented.
|
|
187
188
|
|
|
@@ -241,7 +242,7 @@ try {
|
|
|
241
242
|
}
|
|
242
243
|
```
|
|
243
244
|
|
|
244
|
-
The optional human `screenshot()` plugin from `mesurer-solid/plugins` is a separate camera workflow. It
|
|
245
|
+
The optional human `screenshot()` plugin from `mesurer-solid/plugins` is a separate camera workflow. It may use application-native, Chromium extension, or browser display capture internally, but none of those paths changes the agent contract above. Do not add or configure a host capture path only to collect coding-agent evidence. Preserve an existing human preview unless the task is specifically about Screenshot behavior.
|
|
245
246
|
|
|
246
247
|
## Optional human-to-Codex delivery
|
|
247
248
|
|
|
@@ -253,7 +254,7 @@ Delivery uses Codex's native durable queue. Mesurer queues once and keeps the qu
|
|
|
253
254
|
|
|
254
255
|
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.
|
|
255
256
|
|
|
256
|
-
The typed `codex:v1` service exposes `health()`, `listThreads()`, `useThread(thread)`, `delivery(deliveryId)`, and `send(
|
|
257
|
+
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.
|
|
257
258
|
|
|
258
259
|
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.
|
|
259
260
|
|
package/README.md
CHANGED
|
@@ -4,6 +4,10 @@ Framework-agnostic UI inspection, measurement, visual intent, and agent-readable
|
|
|
4
4
|
|
|
5
5
|
Mesurer Solid ships its own isolated Solid 2 renderer. Host applications can use Solid 1 or 2, React, Vue, Svelte, vanilla DOM, or an Electron renderer without providing Solid.
|
|
6
6
|
|
|
7
|
+
<p align="center">
|
|
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
|
+
</p>
|
|
10
|
+
|
|
7
11
|
## Installation
|
|
8
12
|
|
|
9
13
|
```bash
|
|
@@ -16,7 +20,6 @@ or:
|
|
|
16
20
|
npm install -D mesurer-solid
|
|
17
21
|
```
|
|
18
22
|
|
|
19
|
-
Use `mesurer-solid@beta` only when intentionally testing a prerelease.
|
|
20
23
|
|
|
21
24
|
## Usage
|
|
22
25
|
|
|
@@ -34,7 +37,7 @@ if (import.meta.env.DEV) {
|
|
|
34
37
|
}
|
|
35
38
|
```
|
|
36
39
|
|
|
37
|
-
For Vite, put this in the existing browser entry such as `src/main.tsx`, `src/main.ts`, or `src/index.tsx`. In Electron, use the renderer entry. In SSR applications, mount from a client-only module or lifecycle.
|
|
40
|
+
For Vite, put this in the existing browser entry such as `src/main.tsx`, `src/main.ts`, or `src/index.tsx`. In Electron, use the renderer entry and keep privileged Electron work in preload/main. If preload exposes `window.__MESURER_HOST__.captureScreenshot`, Screenshot uses native capture automatically. Renderer configuration remains `screenshot()`; there is no Electron-specific Screenshot factory or provider option. In SSR applications, mount from a client-only module or lifecycle.
|
|
38
41
|
|
|
39
42
|
`src/dev/mesurer.ts` is an optional organization pattern, not a required filename or directory. Do not mount Mesurer from `vite.config.ts`, server/API code, Node-only scripts, an Electron main process, or a module that also executes during SSR.
|
|
40
43
|
|
|
@@ -46,13 +49,14 @@ All public first-party plugin factories are exported from `mesurer-solid/plugins
|
|
|
46
49
|
|
|
47
50
|
```ts
|
|
48
51
|
import { mountMesurer } from "mesurer-solid"
|
|
49
|
-
import { arrange, context, screenshot } from "mesurer-solid/plugins"
|
|
52
|
+
import { arrange, context, layoutGuides, screenshot } from "mesurer-solid/plugins"
|
|
50
53
|
|
|
51
54
|
const mesurer = mountMesurer({
|
|
52
55
|
agent: true,
|
|
53
56
|
plugins: [
|
|
54
57
|
context(),
|
|
55
58
|
arrange(),
|
|
59
|
+
layoutGuides(),
|
|
56
60
|
screenshot(),
|
|
57
61
|
],
|
|
58
62
|
})
|
|
@@ -62,6 +66,8 @@ The base inspector includes Select, X-ray, Rulers, Typography, Guides, Distance,
|
|
|
62
66
|
|
|
63
67
|
For explicit plugin composition, `mesurer-solid/plugins` also exports `select`, `xray`, `colorPicker`, `rulers`, `typography`, `guides`, `distance`, `settings`, `defaults`, and `compose`.
|
|
64
68
|
|
|
69
|
+
Resolve plugin-owned capabilities with `await mesurer.service<T>(serviceId)`. The helper waits for configured plugins to finish loading and keeps normal consumers on the mounted API instead of requiring `pluginHost.service.get(...)`.
|
|
70
|
+
|
|
65
71
|
| Entry | Purpose |
|
|
66
72
|
| --- | --- |
|
|
67
73
|
| `mesurer-solid` | Mount API, public domain types, and agent API |
|
|
@@ -73,27 +79,47 @@ For explicit plugin composition, `mesurer-solid/plugins` also exports `select`,
|
|
|
73
79
|
| `mesurer-codex` | Run the optional loopback Codex queue companion |
|
|
74
80
|
| `mesurer-codex-connect` | Start or reuse the matching Codex companion and register the current Codex session |
|
|
75
81
|
|
|
82
|
+
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.
|
|
83
|
+
|
|
76
84
|
## Features
|
|
77
85
|
|
|
78
|
-
- Select one or many rendered elements and inspect exact geometry.
|
|
86
|
+
- Select one or many rendered HTML or SVG elements and inspect exact geometry.
|
|
79
87
|
- Measure distance and pairwise multi-selection spacing.
|
|
80
88
|
- Use X-ray, guides, rulers, and persisted settings.
|
|
89
|
+
- 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.
|
|
81
90
|
- Inspect Typography and preview reversible direct copy/style changes.
|
|
82
91
|
- Arrange selected UI into a Desired position without changing source.
|
|
83
|
-
- Capture
|
|
92
|
+
- Capture page regions through the optional Screenshot plugin. It selects native host capture, the Chromium extension adapter, or browser display capture internally.
|
|
84
93
|
- Read selection, measurements, guides, annotations, layout, styles, and saved human intent through Context and agent APIs.
|
|
85
94
|
- 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.
|
|
86
95
|
- Extend the runtime with tools, settings, overlays, commands, hooks, state, and services.
|
|
87
96
|
- Compact the toolbar to active controls without changing tool state or order.
|
|
97
|
+
- Choose System, Light, or Dark appearance while keeping the same theme across isolated and document-backed Mesurer UI.
|
|
88
98
|
|
|
89
99
|
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.
|
|
90
100
|
|
|
91
|
-
|
|
101
|
+
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.
|
|
102
|
+
|
|
103
|
+
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.
|
|
104
|
+
|
|
105
|
+
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.
|
|
106
|
+
|
|
107
|
+
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. Mixed inline copy can target the exact direct text run before or after an inline child without flattening or recreating that child, and the host element keeps its native DOM APIs throughout the interaction.
|
|
92
108
|
|
|
93
109
|
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.
|
|
94
110
|
|
|
95
111
|
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.
|
|
96
112
|
|
|
113
|
+
## Appearance
|
|
114
|
+
|
|
115
|
+
The default appearance is `"system"`. Users can change it under **Settings > General > Appearance**, or applications can choose the initial mode:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
mountMesurer({ theme: "light" })
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The setting accepts `"system"`, `"light"`, or `"dark"` and persists with the other Mesurer settings. System mode follows `prefers-color-scheme`.
|
|
122
|
+
|
|
97
123
|
## Shortcuts
|
|
98
124
|
|
|
99
125
|
Global shortcuts are enabled by default. Turn them off from **Settings > General > Shortcuts** or pass `shortcutsEnabled: false` to `mountMesurer()`. Toolbar controls, editor-local keys, and Escape/cancel behavior remain available.
|
|
@@ -107,6 +133,7 @@ Global shortcuts are enabled by default. Turn them off from **Settings > General
|
|
|
107
133
|
| `R` | Rulers |
|
|
108
134
|
| `A` | Typography |
|
|
109
135
|
| `G` | Guides |
|
|
136
|
+
| `L` | Layout Guides when the plugin is enabled |
|
|
110
137
|
| `H` / `V` | Horizontal / vertical guide orientation |
|
|
111
138
|
| `Alt` / `Option` | Distance overlay |
|
|
112
139
|
| `Cmd/Ctrl + ,` | Settings |
|
|
@@ -166,8 +193,10 @@ See [Queue Context feedback to Codex](https://github.com/jhomra21/mesurer-solid/
|
|
|
166
193
|
- [Capabilities](https://github.com/jhomra21/mesurer-solid/blob/main/docs/CAPABILITIES.md)
|
|
167
194
|
- [Getting started](https://github.com/jhomra21/mesurer-solid/blob/main/docs/GETTING_STARTED.md)
|
|
168
195
|
- [Direct text editing and Typography](https://github.com/jhomra21/mesurer-solid/blob/main/docs/TEXT_EDITING.md)
|
|
169
|
-
- [Arrange](https://github.com/jhomra21/mesurer-solid/blob/main/docs/ARRANGE.md)
|
|
196
|
+
- [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)
|
|
197
|
+
- [Measurements and distance geometry](https://github.com/jhomra21/mesurer-solid/blob/main/docs/MEASUREMENTS.md)
|
|
170
198
|
- [Screenshots](https://github.com/jhomra21/mesurer-solid/blob/main/docs/SCREENSHOTS.md)
|
|
199
|
+
- [Electron renderer example](https://github.com/jhomra21/mesurer-solid/blob/main/examples/electron-renderer/README.md)
|
|
171
200
|
- [Context workflow](https://github.com/jhomra21/mesurer-solid/blob/main/docs/CONTEXT_WORKFLOW.md)
|
|
172
201
|
- [Queue Context feedback to Codex](https://github.com/jhomra21/mesurer-solid/blob/main/docs/CODEX.md)
|
|
173
202
|
- [Browser and agent integration](https://github.com/jhomra21/mesurer-solid/blob/main/docs/BROWSER_HARNESS.md)
|
package/dist/agent.d.ts
CHANGED
|
@@ -123,7 +123,7 @@ export type MesurerAgentHarness = {
|
|
|
123
123
|
distance(a: string, b: string): AgentDistance | null;
|
|
124
124
|
viewport(): AgentViewportSnapshot;
|
|
125
125
|
feedback(selectors?: string[]): Promise<AgentFeedbackSnapshot>;
|
|
126
|
-
command(id: string, args?: AgentCommandArgs):
|
|
126
|
+
command(id: string, args?: AgentCommandArgs): ReturnType<MesurerPluginHost["command"]["execute"]>;
|
|
127
127
|
state(): Promise<PluginStateSnapshot>;
|
|
128
128
|
textEdits(): Promise<MesurerTextEditIntent[]>;
|
|
129
129
|
textEdit(id: string): Promise<MesurerTextEditIntent>;
|
package/dist/codex-plugin.d.ts
CHANGED
|
@@ -11,14 +11,16 @@ export type MesurerCodexPluginOptions = {
|
|
|
11
11
|
/** Remove annotations included in a delivery after Codex reports that turn finished. Defaults to true. */
|
|
12
12
|
clearCompletedAnnotations?: boolean;
|
|
13
13
|
};
|
|
14
|
-
export type
|
|
15
|
-
/** Optional instruction for this
|
|
14
|
+
export type MesurerCodexQueueRequest = {
|
|
15
|
+
/** Optional instruction for this queue operation. */
|
|
16
16
|
instruction?: string;
|
|
17
|
-
/**
|
|
17
|
+
/** Queue only these saved annotation ids. When omitted, all saved annotations are queued. */
|
|
18
18
|
annotationIds?: string[];
|
|
19
|
-
/**
|
|
19
|
+
/** Queue to a particular bridge-visible Codex thread for this request. */
|
|
20
20
|
thread?: string;
|
|
21
21
|
};
|
|
22
|
+
/** @deprecated Use `MesurerCodexQueueRequest`. */
|
|
23
|
+
export type MesurerCodexSendRequest = MesurerCodexQueueRequest;
|
|
22
24
|
export type MesurerCodexDeliveryStatus = "queued" | "working" | "completed" | "interrupted";
|
|
23
25
|
export type MesurerCodexDispatchStatus = "persisting" | "persisted" | "resumed" | "already-loaded" | "unsupported" | "wake-failed" | "untracked" | "desktop-local" | "waiting-active" | "desktop-sent" | "desktop-opened" | "desktop-send-uncertain" | "desktop-wait-failed";
|
|
24
26
|
export type MesurerCodexDelivery = {
|
|
@@ -35,7 +37,7 @@ export type MesurerCodexDelivery = {
|
|
|
35
37
|
createdAt: number;
|
|
36
38
|
updatedAt: number;
|
|
37
39
|
};
|
|
38
|
-
export type
|
|
40
|
+
export type MesurerCodexQueueResult = {
|
|
39
41
|
thread: string;
|
|
40
42
|
output: string;
|
|
41
43
|
/** Mesurer currently delivers feedback as a queued Codex follow-up, never as an in-flight steer. */
|
|
@@ -52,6 +54,8 @@ export type MesurerCodexSendResult = {
|
|
|
52
54
|
/** Exact saved annotations included in this queued request. */
|
|
53
55
|
annotationIds: string[];
|
|
54
56
|
};
|
|
57
|
+
/** @deprecated Use `MesurerCodexQueueResult`. */
|
|
58
|
+
export type MesurerCodexSendResult = MesurerCodexQueueResult;
|
|
55
59
|
export type MesurerCodexHealth = {
|
|
56
60
|
/** Current bridge default target. Null when the bridge has not been bound yet. */
|
|
57
61
|
thread: string | null;
|
|
@@ -91,6 +95,8 @@ export type MesurerCodexService = {
|
|
|
91
95
|
* Queue Context for the page-pinned/default target or one explicit bridge-visible thread.
|
|
92
96
|
* This does not steer or interrupt an in-flight Codex turn.
|
|
93
97
|
*/
|
|
94
|
-
|
|
98
|
+
queue(request?: MesurerCodexQueueRequest): Promise<MesurerCodexQueueResult>;
|
|
99
|
+
/** @deprecated Use `queue()`; Mesurer delivery is durable queueing, not in-flight send/steer. */
|
|
100
|
+
send(request?: MesurerCodexQueueRequest): Promise<MesurerCodexQueueResult>;
|
|
95
101
|
};
|
|
96
102
|
export declare function codex(options?: MesurerCodexPluginOptions): MesurerPlugin;
|
package/dist/context.d.ts
CHANGED
|
@@ -147,6 +147,18 @@ export type MesurerContextGuide = {
|
|
|
147
147
|
orientation: "vertical" | "horizontal";
|
|
148
148
|
position: number;
|
|
149
149
|
};
|
|
150
|
+
export type MesurerContextLayoutGuide = {
|
|
151
|
+
id: string;
|
|
152
|
+
kind: "columns" | "rows" | "grid";
|
|
153
|
+
visible: boolean;
|
|
154
|
+
color: string;
|
|
155
|
+
opacity: number;
|
|
156
|
+
count: number;
|
|
157
|
+
size: number;
|
|
158
|
+
gutter: number;
|
|
159
|
+
offset: number;
|
|
160
|
+
align: "stretch" | "min" | "center" | "max";
|
|
161
|
+
};
|
|
150
162
|
export type MesurerContextMeasurement = {
|
|
151
163
|
id: string;
|
|
152
164
|
rect: MesurerContextRect;
|
|
@@ -209,6 +221,7 @@ export type MesurerContextV1 = {
|
|
|
209
221
|
targets: MesurerContextTarget[];
|
|
210
222
|
visualContext: {
|
|
211
223
|
guides: MesurerContextGuide[];
|
|
224
|
+
layoutGuides: MesurerContextLayoutGuide[];
|
|
212
225
|
measurements: MesurerContextMeasurement[];
|
|
213
226
|
distances: MesurerContextDistance[];
|
|
214
227
|
};
|
|
@@ -266,7 +279,7 @@ export type MesurerWorkspaceContextSource = {
|
|
|
266
279
|
deltaX: number;
|
|
267
280
|
deltaY: number;
|
|
268
281
|
snapped?: boolean;
|
|
269
|
-
elementRef?:
|
|
282
|
+
elementRef?: Element | null;
|
|
270
283
|
}>;
|
|
271
284
|
activeMeasurement: {
|
|
272
285
|
id: string;
|
|
@@ -274,14 +287,14 @@ export type MesurerWorkspaceContextSource = {
|
|
|
274
287
|
deltaX: number;
|
|
275
288
|
deltaY: number;
|
|
276
289
|
snapped?: boolean;
|
|
277
|
-
elementRef?:
|
|
290
|
+
elementRef?: Element | null;
|
|
278
291
|
} | null;
|
|
279
292
|
heldDistances: Array<{
|
|
280
293
|
id: string;
|
|
281
294
|
rectA: MesurerContextRect;
|
|
282
295
|
rectB: MesurerContextRect;
|
|
283
|
-
elementRefA?:
|
|
284
|
-
elementRefB?:
|
|
296
|
+
elementRefA?: Element | null;
|
|
297
|
+
elementRefB?: Element | null;
|
|
285
298
|
horizontal: {
|
|
286
299
|
x1: number;
|
|
287
300
|
x2: number;
|
|
@@ -302,14 +315,14 @@ export type MesurerWorkspaceContextSource = {
|
|
|
302
315
|
}>;
|
|
303
316
|
} | null;
|
|
304
317
|
currentSelection(): {
|
|
305
|
-
elements:
|
|
318
|
+
elements: Element[];
|
|
306
319
|
region: MesurerContextRect | null;
|
|
307
320
|
};
|
|
308
321
|
annotations(): MesurerAnnotation[];
|
|
309
322
|
annotation(id: string): (MesurerAnnotation & {
|
|
310
323
|
resolvedTargets: Array<{
|
|
311
324
|
target: MesurerAnnotationTarget;
|
|
312
|
-
element:
|
|
325
|
+
element: Element | null;
|
|
313
326
|
}>;
|
|
314
327
|
}) | null;
|
|
315
328
|
annotationRect(id: string): MesurerContextRect | null;
|
|
@@ -319,6 +332,7 @@ export declare function captureMesurerContext(options: {
|
|
|
319
332
|
ownerDocument: Document;
|
|
320
333
|
ownerWindow: Window;
|
|
321
334
|
request?: MesurerContextRequest;
|
|
335
|
+
layoutGuides?: MesurerContextLayoutGuide[];
|
|
322
336
|
}): MesurerContextV1;
|
|
323
337
|
export declare function formatMesurerContext(context: MesurerContextV1): string;
|
|
324
338
|
export declare function createMesurerCapturePlan(context: MesurerContextV1): MesurerCapturePlanV1;
|
|
@@ -327,5 +341,6 @@ export declare function reviewMesurerAnnotation(options: {
|
|
|
327
341
|
ownerDocument: Document;
|
|
328
342
|
ownerWindow: Window;
|
|
329
343
|
annotationId: string;
|
|
344
|
+
layoutGuides?: MesurerContextLayoutGuide[];
|
|
330
345
|
}): MesurerReviewV1;
|
|
331
346
|
export declare function copyTextToClipboard(ownerDocument: Document, ownerWindow: Window, text: string): Promise<void>;
|
package/dist/core.d.ts
CHANGED
|
@@ -77,7 +77,7 @@ export type OverlayContribution = {
|
|
|
77
77
|
};
|
|
78
78
|
export type CommandHandler = (args: PluginValue | undefined, context: {
|
|
79
79
|
source?: PluginValue;
|
|
80
|
-
}) => void | Promise<void>;
|
|
80
|
+
}) => void | PluginValue | Promise<void | PluginValue>;
|
|
81
81
|
export type HookHandler = (event: PluginValue) => void | Promise<void>;
|
|
82
82
|
export type StateSliceDefinition<T extends PluginValue = PluginValue> = {
|
|
83
83
|
id: string;
|
|
@@ -103,7 +103,7 @@ export type MesurerPluginContext = {
|
|
|
103
103
|
};
|
|
104
104
|
command: {
|
|
105
105
|
register(id: string, handler: CommandHandler): Registration;
|
|
106
|
-
execute(id: string, args?: PluginValue, source?: PluginValue): Promise<
|
|
106
|
+
execute(id: string, args?: PluginValue, source?: PluginValue): Promise<PluginValue | undefined>;
|
|
107
107
|
};
|
|
108
108
|
hook: {
|
|
109
109
|
on(name: string, handler: HookHandler): Registration;
|
|
@@ -175,7 +175,7 @@ export type MesurerPluginHost = {
|
|
|
175
175
|
get<T>(id: string): T | undefined;
|
|
176
176
|
};
|
|
177
177
|
command: {
|
|
178
|
-
execute(id: string, args?: PluginValue, source?: PluginValue): Promise<
|
|
178
|
+
execute(id: string, args?: PluginValue, source?: PluginValue): Promise<PluginValue | undefined>;
|
|
179
179
|
};
|
|
180
180
|
hook: {
|
|
181
181
|
emit(name: string, event: PluginValue): Promise<void>;
|
package/dist/core.js
CHANGED
|
@@ -85,8 +85,10 @@ function i() {
|
|
|
85
85
|
if (!o) throw Error(`Unknown Mesurer command: ${e}`);
|
|
86
86
|
let s = t === 0, c = s ? x("history") : null;
|
|
87
87
|
t += 1;
|
|
88
|
+
let l;
|
|
88
89
|
try {
|
|
89
|
-
await o.handler(n, { source: a })
|
|
90
|
+
let t = await o.handler(n, { source: a });
|
|
91
|
+
t !== void 0 && (l = t), await i.emit("command", {
|
|
90
92
|
id: e,
|
|
91
93
|
args: n
|
|
92
94
|
});
|
|
@@ -97,6 +99,7 @@ function i() {
|
|
|
97
99
|
let e = x("history");
|
|
98
100
|
C(c, e) || (h.push(c), h.length > r && h.shift(), g.length = 0);
|
|
99
101
|
}
|
|
102
|
+
return l;
|
|
100
103
|
}, E = () => {
|
|
101
104
|
let e = h.pop();
|
|
102
105
|
return e ? (g.push(x("history")), g.length > r && g.shift(), S(e, "history"), _(void 0, "history"), !0) : !1;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { type MesurerAgentHarness, type MesurerTextEditIntent } from "./agent";
|
|
2
|
-
import type
|
|
2
|
+
import { type ArrangeCapturePlan, type ArrangeIntent, type ArrangePresentation, type ArrangeReview } from "./arrange";
|
|
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
6
|
export type ColorPickerFormat = "hex" | "rgb" | "hsl" | "oklch";
|
|
7
|
+
export type MesurerTheme = "system" | "light" | "dark";
|
|
7
8
|
export type MesurerBuiltinPluginId = "select" | "xray" | "color-picker" | "rulers" | "text-inspector" | "guides" | "distance" | "settings";
|
|
8
9
|
export type LinePattern = "solid" | "dashed" | "dotted";
|
|
9
10
|
export type LineStyle = {
|
|
@@ -80,6 +81,7 @@ export type MesurerStoredSettings = {
|
|
|
80
81
|
multiMeasureEnabled?: boolean;
|
|
81
82
|
persistOnReload?: boolean;
|
|
82
83
|
shortcutsEnabled?: boolean;
|
|
84
|
+
theme?: MesurerTheme;
|
|
83
85
|
guideStyle?: Partial<GuideStyle>;
|
|
84
86
|
selectionSpacingStyle?: Partial<SelectionSpacingStyle>;
|
|
85
87
|
rulerSettings?: Partial<RulerSettings>;
|
|
@@ -106,6 +108,7 @@ export type MesurerPersistence = {
|
|
|
106
108
|
saveWorkspace(workspace: MesurerStoredWorkspace): void;
|
|
107
109
|
clearWorkspace(): void;
|
|
108
110
|
clearSettings(): void;
|
|
111
|
+
setPageKey?(pageKey: string): void;
|
|
109
112
|
subscribe?: (listener: (snapshot: MesurerPersistenceSnapshot | null, source?: {
|
|
110
113
|
settings?: boolean;
|
|
111
114
|
workspace?: boolean;
|
|
@@ -122,6 +125,7 @@ export type MesurerOptions = {
|
|
|
122
125
|
hoverHighlightEnabled?: boolean;
|
|
123
126
|
persistOnReload?: boolean;
|
|
124
127
|
shortcutsEnabled?: boolean;
|
|
128
|
+
theme?: MesurerTheme;
|
|
125
129
|
persistKey?: string;
|
|
126
130
|
persistence?: MesurerPersistence;
|
|
127
131
|
onPersistenceError?: (cause: unknown) => void;
|
|
@@ -192,6 +196,7 @@ export type MountedMesurer = {
|
|
|
192
196
|
readonly pluginHost: MesurerPluginHost | undefined;
|
|
193
197
|
readonly ready: Promise<void>;
|
|
194
198
|
readonly agent: MesurerBrowserAgent;
|
|
199
|
+
service<T>(id: string): Promise<T>;
|
|
195
200
|
context(request?: MesurerContextRequest): Promise<MesurerContextV1>;
|
|
196
201
|
contextText(request?: MesurerContextRequest): Promise<string>;
|
|
197
202
|
copyContext(request?: MesurerContextRequest): Promise<void>;
|
|
@@ -224,7 +229,7 @@ export { MESURER_VERSION } from "./version";
|
|
|
224
229
|
export type { AgentDistance, AgentEdges, AgentElementInspection, AgentFeedbackSnapshot, AgentRect, AgentViewportSnapshot, CreateMesurerAgentHarnessOptions, MesurerAgentHarness, MesurerTextEditIntent, MesurerTextEditService, MesurerTextStyleChange, MesurerTextStyleProperty, } from "./agent";
|
|
225
230
|
export type { ArrangeCapturePlan, ArrangeIntent, ArrangeOffset, ArrangePresentation, ArrangeRect, ArrangeReview, ArrangeReviewTarget, ArrangeTarget, MesurerArrangeService, } from "./arrange";
|
|
226
231
|
export { captureMesurerContext, copyTextToClipboard, createMesurerCapturePlan, formatMesurerContext, reviewMesurerAnnotation, } from "./context";
|
|
227
|
-
export type { MesurerAnnotation, MesurerAnnotationBaseline, MesurerAnnotationTarget, MesurerCapturePlanV1, MesurerContextDistance, MesurerContextEdges, MesurerContextGuide, MesurerContextMeasurement, MesurerContextRect, MesurerContextRequest, MesurerContextTarget, MesurerContextV1, MesurerElementFingerprint, MesurerElementInspection, MesurerReviewChange, MesurerReviewMetricChange, MesurerReviewPresenceChange, MesurerReviewV1, } from "./context";
|
|
232
|
+
export type { MesurerAnnotation, MesurerAnnotationBaseline, MesurerAnnotationTarget, MesurerCapturePlanV1, MesurerContextDistance, MesurerContextEdges, MesurerContextGuide, MesurerContextLayoutGuide, MesurerContextMeasurement, MesurerContextRect, MesurerContextRequest, MesurerContextTarget, MesurerContextV1, MesurerElementFingerprint, MesurerElementInspection, MesurerReviewChange, MesurerReviewMetricChange, MesurerReviewPresenceChange, MesurerReviewV1, } from "./context";
|
|
228
233
|
export { createMesurerPluginHost, createMesurerRuntime, defineMesurerPlugin } from "./core";
|
|
229
234
|
export type { CommandHandler as MesurerCommandHandler, MesurerPlugin, MesurerPluginContext, MesurerPluginDescription, MesurerPluginHost, OverlayContribution, Registration as MesurerRegistration, SettingsContribution, StateSliceDefinition, ToolContribution, } from "./core";
|
|
230
235
|
export type { MesurerHostLayerMode } from "./host-layer";
|