mesurer-solid 0.1.0-beta.11

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.
@@ -0,0 +1,359 @@
1
+ export type MesurerContextRequest = {
2
+ scope?: "workspace";
3
+ } | {
4
+ scope: "selection";
5
+ } | {
6
+ annotation: string;
7
+ };
8
+ export type MesurerContextRect = {
9
+ left: number;
10
+ top: number;
11
+ width: number;
12
+ height: number;
13
+ };
14
+ export type MesurerContextEdges = {
15
+ top: number;
16
+ right: number;
17
+ bottom: number;
18
+ left: number;
19
+ };
20
+ export type MesurerElementFingerprint = {
21
+ tag: string;
22
+ id: string | null;
23
+ testId: string | null;
24
+ role: string | null;
25
+ ariaLabel: string | null;
26
+ classes: string[];
27
+ text: string | null;
28
+ };
29
+ export type MesurerElementInspection = {
30
+ selector: string;
31
+ tag: string;
32
+ id: string | null;
33
+ classes: string[];
34
+ text: string;
35
+ role: string | null;
36
+ ariaLabel: string | null;
37
+ rect: MesurerContextRect & {
38
+ right: number;
39
+ bottom: number;
40
+ x: number;
41
+ y: number;
42
+ };
43
+ margin: MesurerContextEdges;
44
+ padding: MesurerContextEdges;
45
+ border: MesurerContextEdges;
46
+ typography: {
47
+ fontFamily: string;
48
+ fontSize: string;
49
+ fontWeight: string;
50
+ lineHeight: string;
51
+ letterSpacing: string;
52
+ textAlign: string;
53
+ color: string;
54
+ };
55
+ appearance: {
56
+ backgroundColor: string;
57
+ borderColor: string;
58
+ borderRadius: string;
59
+ boxShadow: string;
60
+ opacity: string;
61
+ };
62
+ layout: {
63
+ display: string;
64
+ position: string;
65
+ zIndex: string;
66
+ overflowX: string;
67
+ overflowY: string;
68
+ flexDirection: string;
69
+ alignItems: string;
70
+ justifyContent: string;
71
+ gap: string;
72
+ gridTemplateColumns: string;
73
+ gridTemplateRows: string;
74
+ transform: string;
75
+ };
76
+ scroll: {
77
+ clientWidth: number;
78
+ clientHeight: number;
79
+ scrollWidth: number;
80
+ scrollHeight: number;
81
+ overflowsX: boolean;
82
+ overflowsY: boolean;
83
+ };
84
+ };
85
+ export type MesurerAnnotationTarget = {
86
+ id: string;
87
+ selector: string;
88
+ fingerprint: MesurerElementFingerprint;
89
+ lastRect: MesurerContextRect;
90
+ };
91
+ export type MesurerAnnotationBaseline = {
92
+ targets: Array<{
93
+ id: string;
94
+ selector: string;
95
+ rect: MesurerContextRect;
96
+ }>;
97
+ guides: Array<{
98
+ id: string;
99
+ orientation: "vertical" | "horizontal";
100
+ position: number;
101
+ }>;
102
+ measurements: Array<{
103
+ id: string;
104
+ rect: MesurerContextRect;
105
+ deltaX: number;
106
+ deltaY: number;
107
+ snapped?: boolean;
108
+ }>;
109
+ distances: Array<{
110
+ id: string;
111
+ rectA: MesurerContextRect;
112
+ rectB: MesurerContextRect;
113
+ horizontal: {
114
+ x1: number;
115
+ x2: number;
116
+ y: number;
117
+ value: number;
118
+ } | null;
119
+ vertical: {
120
+ y1: number;
121
+ y2: number;
122
+ x: number;
123
+ value: number;
124
+ } | null;
125
+ }>;
126
+ };
127
+ export type MesurerAnnotation = {
128
+ id: string;
129
+ note: string;
130
+ createdAt: number;
131
+ anchor: {
132
+ kind: "elements";
133
+ targets: MesurerAnnotationTarget[];
134
+ region: MesurerContextRect | null;
135
+ } | {
136
+ kind: "region";
137
+ rect: MesurerContextRect;
138
+ };
139
+ baseline: MesurerAnnotationBaseline;
140
+ };
141
+ export type MesurerContextTarget = {
142
+ ref: string;
143
+ inspection: MesurerElementInspection;
144
+ };
145
+ export type MesurerContextGuide = {
146
+ id: string;
147
+ orientation: "vertical" | "horizontal";
148
+ position: number;
149
+ };
150
+ export type MesurerContextMeasurement = {
151
+ id: string;
152
+ rect: MesurerContextRect;
153
+ deltaX: number;
154
+ deltaY: number;
155
+ snapped?: boolean;
156
+ targetRef?: string;
157
+ };
158
+ export type MesurerContextDistance = {
159
+ id: string;
160
+ rectA: MesurerContextRect;
161
+ rectB: MesurerContextRect;
162
+ horizontal: {
163
+ x1: number;
164
+ x2: number;
165
+ y: number;
166
+ value: number;
167
+ } | null;
168
+ vertical: {
169
+ y1: number;
170
+ y2: number;
171
+ x: number;
172
+ value: number;
173
+ } | null;
174
+ targetARef?: string;
175
+ targetBRef?: string;
176
+ };
177
+ export type MesurerContextV1 = {
178
+ schema: "mesurer.context/v1";
179
+ id: string;
180
+ createdAt: string;
181
+ scope: {
182
+ kind: "workspace";
183
+ } | {
184
+ kind: "selection";
185
+ } | {
186
+ kind: "annotation";
187
+ annotationId: string;
188
+ note: string;
189
+ targetStatus: "connected" | "partial" | "stale";
190
+ };
191
+ page: {
192
+ url: string;
193
+ title: string;
194
+ };
195
+ viewport: {
196
+ width: number;
197
+ height: number;
198
+ devicePixelRatio: number;
199
+ scrollX: number;
200
+ scrollY: number;
201
+ };
202
+ coordinateSpace: "viewport-css-px";
203
+ /** Requested/annotated viewport regions. Empty for whole-workspace context. */
204
+ regions: MesurerContextRect[];
205
+ visualState: {
206
+ rulersVisible: boolean;
207
+ xrayVisible: boolean;
208
+ };
209
+ targets: MesurerContextTarget[];
210
+ visualContext: {
211
+ guides: MesurerContextGuide[];
212
+ measurements: MesurerContextMeasurement[];
213
+ distances: MesurerContextDistance[];
214
+ };
215
+ };
216
+ export type MesurerReviewMetricChange = {
217
+ kind: "target-rect" | "guide" | "measurement" | "distance";
218
+ label: string;
219
+ before: number;
220
+ current: number;
221
+ delta: number;
222
+ unit: "px";
223
+ };
224
+ export type MesurerReviewPresenceChange = {
225
+ kind: "missing";
226
+ evidence: "target" | "guide" | "measurement" | "distance";
227
+ id: string;
228
+ label: string;
229
+ };
230
+ export type MesurerReviewChange = MesurerReviewMetricChange | MesurerReviewPresenceChange;
231
+ export type MesurerReviewV1 = {
232
+ schema: "mesurer.review/v1";
233
+ annotationId: string;
234
+ note: string;
235
+ targetStatus: "connected" | "partial" | "stale";
236
+ baseline: MesurerAnnotationBaseline;
237
+ current: MesurerContextV1;
238
+ changes: MesurerReviewChange[];
239
+ };
240
+ export type MesurerCapturePlanV1 = {
241
+ schema: "mesurer.capture/v1";
242
+ contextId: string;
243
+ chrome: "hide";
244
+ evidence: "show";
245
+ captures: Array<{
246
+ id: "viewport";
247
+ kind: "viewport";
248
+ } | {
249
+ id: "focus";
250
+ kind: "clip";
251
+ rect: MesurerContextRect;
252
+ }>;
253
+ };
254
+ export type MesurerEvidenceImage = {
255
+ id: "viewport" | "focus" | string;
256
+ kind: "viewport" | "focus" | string;
257
+ mimeType: "image/png" | "image/jpeg" | string;
258
+ /** Base64 image bytes without a data URL prefix. */
259
+ data: string;
260
+ };
261
+ export type MesurerEvidenceProvider = (input: {
262
+ context: MesurerContextV1;
263
+ plan: MesurerCapturePlanV1;
264
+ }) => Promise<MesurerEvidenceImage[]>;
265
+ export type MesurerContextDelivery = {
266
+ context: MesurerContextV1;
267
+ text: string;
268
+ images: MesurerEvidenceImage[];
269
+ };
270
+ export type MesurerContextSender = (delivery: MesurerContextDelivery) => Promise<void>;
271
+ export type AcpTextContentBlock = {
272
+ type: "text";
273
+ text: string;
274
+ };
275
+ export type AcpImageContentBlock = {
276
+ type: "image";
277
+ mimeType: string;
278
+ data: string;
279
+ };
280
+ export type MesurerAcpContentBlock = AcpTextContentBlock | AcpImageContentBlock;
281
+ /**
282
+ * Explicit renderer-to-protocol adapter source. The renderer owns live DOM references;
283
+ * this public boundary deliberately describes only the fields that may enter JSON context.
284
+ */
285
+ export type MesurerWorkspaceContextSource = {
286
+ snapshot(): {
287
+ rulersVisible: boolean;
288
+ xrayVisible: boolean;
289
+ guideRelevanceTolerance?: number;
290
+ measurements: Array<{
291
+ id: string;
292
+ rect: MesurerContextRect;
293
+ deltaX: number;
294
+ deltaY: number;
295
+ snapped?: boolean;
296
+ elementRef?: HTMLElement | null;
297
+ }>;
298
+ activeMeasurement: {
299
+ id: string;
300
+ rect: MesurerContextRect;
301
+ deltaX: number;
302
+ deltaY: number;
303
+ snapped?: boolean;
304
+ elementRef?: HTMLElement | null;
305
+ } | null;
306
+ heldDistances: Array<{
307
+ id: string;
308
+ rectA: MesurerContextRect;
309
+ rectB: MesurerContextRect;
310
+ elementRefA?: HTMLElement | null;
311
+ elementRefB?: HTMLElement | null;
312
+ horizontal: {
313
+ x1: number;
314
+ x2: number;
315
+ y: number;
316
+ value: number;
317
+ } | null;
318
+ vertical: {
319
+ y1: number;
320
+ y2: number;
321
+ x: number;
322
+ value: number;
323
+ } | null;
324
+ }>;
325
+ guides: Array<{
326
+ id: string;
327
+ orientation: "vertical" | "horizontal";
328
+ position: number;
329
+ }>;
330
+ } | null;
331
+ currentSelection(): {
332
+ elements: HTMLElement[];
333
+ region: MesurerContextRect | null;
334
+ };
335
+ annotations(): MesurerAnnotation[];
336
+ annotation(id: string): (MesurerAnnotation & {
337
+ resolvedTargets: Array<{
338
+ target: MesurerAnnotationTarget;
339
+ element: HTMLElement | null;
340
+ }>;
341
+ }) | null;
342
+ annotationRect(id: string): MesurerContextRect | null;
343
+ };
344
+ export declare function captureMesurerContext(options: {
345
+ runtime: MesurerWorkspaceContextSource;
346
+ ownerDocument: Document;
347
+ ownerWindow: Window;
348
+ request?: MesurerContextRequest;
349
+ }): MesurerContextV1;
350
+ export declare function formatMesurerContext(context: MesurerContextV1): string;
351
+ export declare function createMesurerCapturePlan(context: MesurerContextV1): MesurerCapturePlanV1;
352
+ export declare function reviewMesurerAnnotation(options: {
353
+ runtime: MesurerWorkspaceContextSource;
354
+ ownerDocument: Document;
355
+ ownerWindow: Window;
356
+ annotationId: string;
357
+ }): MesurerReviewV1;
358
+ export declare function toAcpContentBlocks(context: MesurerContextV1, images?: MesurerEvidenceImage[]): MesurerAcpContentBlock[];
359
+ export declare function copyTextToClipboard(ownerDocument: Document, ownerWindow: Window, text: string): Promise<void>;
package/dist/core.d.ts ADDED
@@ -0,0 +1,147 @@
1
+ export type Registration = {
2
+ readonly dispose: () => void;
3
+ };
4
+ export type PluginId = string;
5
+ export type PluginStateSnapshot = Record<string, unknown>;
6
+ export type PluginStateScope = "all" | "history" | "persist";
7
+ export type ToolContribution = {
8
+ id: string;
9
+ label: string;
10
+ shortcut?: string;
11
+ command: string;
12
+ order?: number;
13
+ builtin?: string;
14
+ icon?: {
15
+ viewBox?: string;
16
+ paths: string[];
17
+ };
18
+ active?: () => boolean;
19
+ disabled?: () => boolean;
20
+ };
21
+ export type SettingsContribution = {
22
+ id: string;
23
+ label: string;
24
+ order?: number;
25
+ builtin?: string;
26
+ };
27
+ export type OverlayContribution = {
28
+ id: string;
29
+ order?: number;
30
+ builtin?: string;
31
+ };
32
+ export type CommandHandler = (args: unknown, context: {
33
+ source?: unknown;
34
+ }) => void | Promise<void>;
35
+ export type HookHandler = (event: unknown) => void | Promise<void>;
36
+ export type StateSliceDefinition<T = unknown> = {
37
+ id: string;
38
+ initial: T;
39
+ history?: boolean;
40
+ persist?: boolean;
41
+ };
42
+ export type MesurerPluginContext = {
43
+ state: {
44
+ register<T>(definition: StateSliceDefinition<T>): Registration;
45
+ get<T>(id: string): T | undefined;
46
+ update<T>(id: string, update: (value: T) => T): void;
47
+ };
48
+ tool: {
49
+ register(contribution: ToolContribution): Registration;
50
+ };
51
+ settings: {
52
+ register(contribution: SettingsContribution): Registration;
53
+ };
54
+ overlay: {
55
+ register(contribution: OverlayContribution): Registration;
56
+ };
57
+ command: {
58
+ register(id: string, handler: CommandHandler): Registration;
59
+ execute(id: string, args?: unknown, source?: unknown): Promise<void>;
60
+ };
61
+ hook: {
62
+ on(name: string, handler: HookHandler): Registration;
63
+ emit(name: string, event: unknown): Promise<void>;
64
+ };
65
+ service: {
66
+ provide<T>(id: string, value: T): Registration;
67
+ get<T>(id: string): T | undefined;
68
+ };
69
+ lifecycle: {
70
+ onDispose(handler: () => void): Registration;
71
+ };
72
+ };
73
+ export type MesurerPlugin = {
74
+ id: PluginId;
75
+ version?: string;
76
+ requires?: string[];
77
+ provides?: string[];
78
+ setup(context: MesurerPluginContext): void | Promise<void>;
79
+ };
80
+ export type MesurerPluginDescription = {
81
+ plugins: Array<{
82
+ id: string;
83
+ version?: string;
84
+ requires: string[];
85
+ provides: string[];
86
+ }>;
87
+ tools: Array<{
88
+ id: string;
89
+ label: string;
90
+ shortcut?: string;
91
+ command: string;
92
+ order?: number;
93
+ builtin?: string;
94
+ }>;
95
+ settings: SettingsContribution[];
96
+ overlays: OverlayContribution[];
97
+ state: Array<{
98
+ id: string;
99
+ history: boolean;
100
+ persist: boolean;
101
+ }>;
102
+ commands: string[];
103
+ hooks: string[];
104
+ services: string[];
105
+ };
106
+ export type MesurerPluginChange = {
107
+ pluginId?: string;
108
+ reason: "load" | "remove" | "replace" | "registration" | "state" | "history";
109
+ };
110
+ export type MesurerPluginHost = {
111
+ load(plugin: MesurerPlugin): Promise<void>;
112
+ remove(id: string): boolean;
113
+ replace(plugin: MesurerPlugin): Promise<void>;
114
+ has(id: string): boolean;
115
+ plugin(id: string): MesurerPlugin | undefined;
116
+ listPlugins(): MesurerPlugin[];
117
+ tools(): ToolContribution[];
118
+ settings(): SettingsContribution[];
119
+ overlays(): OverlayContribution[];
120
+ state: {
121
+ get<T>(id: string): T | undefined;
122
+ update<T>(id: string, update: (value: T) => T): void;
123
+ serialize(scope?: PluginStateScope): PluginStateSnapshot;
124
+ restore(snapshot: PluginStateSnapshot, scope?: PluginStateScope): void;
125
+ };
126
+ service: {
127
+ get<T>(id: string): T | undefined;
128
+ };
129
+ command: {
130
+ execute(id: string, args?: unknown, source?: unknown): Promise<void>;
131
+ };
132
+ hook: {
133
+ emit(name: string, event: unknown): Promise<void>;
134
+ };
135
+ undo(): boolean;
136
+ redo(): boolean;
137
+ canUndo(): boolean;
138
+ canRedo(): boolean;
139
+ subscribe(listener: (event: MesurerPluginChange) => void): () => void;
140
+ describe(): MesurerPluginDescription;
141
+ dispose(): void;
142
+ };
143
+ export declare const defineMesurerPlugin: <T extends MesurerPlugin>(plugin: T) => T;
144
+ export declare const createMesurerPluginHost: () => MesurerPluginHost;
145
+ export declare function createMesurerRuntime(options?: {
146
+ plugins?: MesurerPlugin[];
147
+ }): Promise<MesurerPluginHost>;