@oyerinde/caliper 0.1.4 → 0.2.1
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/CHANGELOG.md +35 -0
- package/README.md +130 -25
- package/dist/bridge.cjs +50 -0
- package/dist/bridge.d.cts +1651 -0
- package/dist/bridge.d.ts +1651 -0
- package/dist/bridge.js +1 -0
- package/dist/bridge.server.cjs +34 -0
- package/dist/bridge.server.js +31 -0
- package/dist/chunk-L47FGEH6.js +18625 -0
- package/dist/chunk-MTIWXK3P.js +5896 -0
- package/dist/chunk-P37B6G5P.cjs +5902 -0
- package/dist/chunk-PYAVLOZM.cjs +18637 -0
- package/dist/index.cjs +24 -5131
- package/dist/index.d.cts +978 -18
- package/dist/index.d.ts +978 -2
- package/dist/index.global.js +154 -4878
- package/dist/index.global.js.map +1 -0
- package/dist/index.global.min.js +327 -0
- package/dist/index.global.min.js.map +1 -0
- package/dist/index.js +1 -5128
- package/dist/index.server.cjs +19 -8
- package/dist/index.server.js +19 -9
- package/dist/mcp.cjs +2305 -0
- package/dist/mcp.js +2303 -0
- package/dist/preset.cjs +44 -0
- package/dist/preset.d.cts +964 -0
- package/dist/preset.d.ts +964 -0
- package/dist/preset.js +31 -0
- package/dist/preset.server.cjs +43 -0
- package/dist/preset.server.js +39 -0
- package/dist/version.json +2 -2
- package/package.json +47 -9
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,41 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.2.1] - 2026-02-16
|
|
6
|
+
|
|
7
|
+
### Refactored
|
|
8
|
+
|
|
9
|
+
- **Configuration Engine**: Renamed `OverlayConfig` to `CaliperConfig` to reflect its expanded scope.
|
|
10
|
+
- **Bridge Decoupling**: Moved `bridge` configuration out of the core config type. It is now exclusively a plugin concern, with specialized `IIFEConfig` handling for CDN/script-tag users.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Agent Bridge Serialization**: Introduced `onStateChangeGlobal` to allow string-based callback names in `data-config` for IIFE/CDN environments.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **Boundary Box Snapping**: Fixed a bug where boxes would snap to `(0,0)` when elements animated out or were removed from the DOM. The overlay now retains the last known good position.
|
|
19
|
+
|
|
20
|
+
## [0.2.0] - 2026-02-12
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- **Agent Bridge**: Support for AI agents and programmatic audits via `@oyerinde/caliper/bridge`.
|
|
25
|
+
- **MCP Server**: Integrated MCP server for AI auditing (activate via `npx @oyerinde/caliper`).
|
|
26
|
+
- **MCP tools**: `caliper_list_tabs`, `caliper_get_context`, `caliper_switch_tab`, `caliper_inspect`, `caliper_measure`, `caliper_clear`, `caliper_walk_dom`, and `caliper_walk_and_measure`.
|
|
27
|
+
- **Accessibility Tools**: `caliper_check_contrast` and `caliper_delta_e`.
|
|
28
|
+
- **MCP prompts**: `caliper-selector-audit` and `caliper-selectors-compare`.
|
|
29
|
+
- **MCP resources**: `caliper://tabs` and `caliper://state`.
|
|
30
|
+
- **Context Menu**: Right-click selected elements to copy metadata.
|
|
31
|
+
- **Expanded Distribution**: Multi-entry support for `@oyerinde/caliper/preset` and `@oyerinde/caliper/bridge`, alongside dedicated `index.js`, `index.min.js`, and `index.global.js` bundles.
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- **Geometry Engine**: Improved coordinate tracking for `fixed` and `sticky` elements and nested scroll containers.
|
|
36
|
+
- Fix: Precision tracking for sticky elements across complex DOM hierarchies.
|
|
37
|
+
- Fix: Deep scroll resolution for nested overflow containers.
|
|
38
|
+
- Fix: Real-time clipping path calculation for partially visible elements.
|
|
39
|
+
|
|
5
40
|
## [0.1.4] - 2026-01-16
|
|
6
41
|
|
|
7
42
|
### Fixed
|
package/README.md
CHANGED
|
@@ -7,6 +7,16 @@
|
|
|
7
7
|
|
|
8
8
|
Caliper is a high-precision, framework-agnostic measurement tool that lives in your browser during development. It helps you catch "pixel-drift" and alignment issues before they reach production.
|
|
9
9
|
|
|
10
|
+
### AI Agents & MCP 🤖
|
|
11
|
+
|
|
12
|
+
Caliper is "AI-Native". It can be connected to AI agents (like Cursor, Claude Code, or Antigravity) via the **Model Context Protocol (MCP)**, allowing agents to perform pixel-perfect audits of your UI.
|
|
13
|
+
|
|
14
|
+
1. **Install Bridge**: Available as `@oyerinde/caliper/bridge` for custom integrations.
|
|
15
|
+
2. **Run Server**: `npx @oyerinde/caliper`
|
|
16
|
+
3. **Connect**: Add the MCP server to your editor on the default port **9876**.
|
|
17
|
+
|
|
18
|
+
The AI agent gains "layout eyes" and can perform high-precision audits, measurements, and alignment checks directly in your browser.
|
|
19
|
+
|
|
10
20
|
---
|
|
11
21
|
|
|
12
22
|
## Features 🚀
|
|
@@ -17,6 +27,8 @@ Caliper is a high-precision, framework-agnostic measurement tool that lives in y
|
|
|
17
27
|
- **Edge Projections**: Check alignment across the entire viewport using relative projections (W/A/S/D).
|
|
18
28
|
- **Viewport Rulers**: Draggable guidelines with magnetic snapping and chained distance measurements (Shift + R).
|
|
19
29
|
- **Integrated Calculator**: Precise spatial math for complex component spacing (T/R/B/L/G).
|
|
30
|
+
- **Agent Bridge**: Built-in support for AI-driven audits and programmatic UI inspection.
|
|
31
|
+
- **Agent State Sync**: Real-time "passive observation" synchronization with AI agents, providing stable JSON fingerprints for seamless tool-based hand-off.
|
|
20
32
|
- **Full Customization**: Fully configurable shortcuts and theme colors.
|
|
21
33
|
|
|
22
34
|
---
|
|
@@ -26,6 +38,7 @@ Caliper is a high-precision, framework-agnostic measurement tool that lives in y
|
|
|
26
38
|
Caliper is designed to be side-effect-free in production and easy to integrate into any modern stack.
|
|
27
39
|
|
|
28
40
|
### 1. Next.js (App Router)
|
|
41
|
+
|
|
29
42
|
```tsx
|
|
30
43
|
// app/layout.tsx
|
|
31
44
|
import Script from "next/script";
|
|
@@ -37,7 +50,7 @@ export default function RootLayout({ children }) {
|
|
|
37
50
|
{process.env.NODE_ENV === "development" && (
|
|
38
51
|
<Script
|
|
39
52
|
src="https://unpkg.com/@oyerinde/caliper/dist/index.global.js"
|
|
40
|
-
data-config={JSON.stringify({ theme: { primary:
|
|
53
|
+
data-config={JSON.stringify({ theme: { primary: "#AC2323" } })}
|
|
41
54
|
strategy="afterInteractive"
|
|
42
55
|
/>
|
|
43
56
|
)}
|
|
@@ -49,19 +62,21 @@ export default function RootLayout({ children }) {
|
|
|
49
62
|
```
|
|
50
63
|
|
|
51
64
|
### 2. Vite
|
|
65
|
+
|
|
52
66
|
```html
|
|
53
67
|
<!-- index.html -->
|
|
54
68
|
<script type="module">
|
|
55
|
-
if (import.meta.env.DEV) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
69
|
+
if (import.meta.env.DEV) {
|
|
70
|
+
// Run npm i @oyerinde/caliper then
|
|
71
|
+
import("@oyerinde/caliper").then(({ init }) => {
|
|
72
|
+
init({ theme: { primary: "#AC2323" } });
|
|
73
|
+
});
|
|
74
|
+
}
|
|
61
75
|
</script>
|
|
62
76
|
```
|
|
63
77
|
|
|
64
78
|
### 3. HTML (Plain)
|
|
79
|
+
|
|
65
80
|
```html
|
|
66
81
|
<!-- index.html -->
|
|
67
82
|
<script type="module">
|
|
@@ -76,12 +91,13 @@ if (import.meta.env.DEV) {
|
|
|
76
91
|
```
|
|
77
92
|
|
|
78
93
|
### 4. Astro
|
|
94
|
+
|
|
79
95
|
```html
|
|
80
96
|
<!-- src/components/Caliper.astro -->
|
|
81
97
|
<script type="module" is:inline>
|
|
82
98
|
if (import.meta.env.DEV) {
|
|
83
99
|
// Run npm i @oyerinde/caliper then
|
|
84
|
-
import(
|
|
100
|
+
import("@oyerinde/caliper").then(({ init }) => {
|
|
85
101
|
init();
|
|
86
102
|
});
|
|
87
103
|
}
|
|
@@ -89,6 +105,7 @@ if (import.meta.env.DEV) {
|
|
|
89
105
|
```
|
|
90
106
|
|
|
91
107
|
### 5. Nuxt
|
|
108
|
+
|
|
92
109
|
```ts
|
|
93
110
|
// nuxt.config.ts
|
|
94
111
|
export default defineNuxtConfig({
|
|
@@ -96,43 +113,45 @@ export default defineNuxtConfig({
|
|
|
96
113
|
head: {
|
|
97
114
|
script: [
|
|
98
115
|
{
|
|
99
|
-
src:
|
|
100
|
-
|
|
101
|
-
defer: true
|
|
102
|
-
}
|
|
103
|
-
]
|
|
104
|
-
}
|
|
105
|
-
}
|
|
116
|
+
src: "https://unpkg.com/@oyerinde/caliper/dist/index.global.js",
|
|
117
|
+
"data-config": JSON.stringify({ theme: { primary: "#AC2323" } }),
|
|
118
|
+
defer: true,
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
},
|
|
122
|
+
},
|
|
106
123
|
});
|
|
107
124
|
```
|
|
108
125
|
|
|
109
126
|
### 6. Vue
|
|
127
|
+
|
|
110
128
|
```html
|
|
111
129
|
<!-- index.html -->
|
|
112
130
|
<script type="module">
|
|
113
131
|
if (import.meta.env.DEV) {
|
|
114
132
|
// Run npm i @oyerinde/caliper then
|
|
115
133
|
import("@oyerinde/caliper").then(({ init }) => {
|
|
116
|
-
init({ theme: { primary:
|
|
134
|
+
init({ theme: { primary: "#AC2323" } });
|
|
117
135
|
});
|
|
118
136
|
}
|
|
119
137
|
</script>
|
|
120
138
|
```
|
|
121
139
|
|
|
122
140
|
### 7. TanStack Start
|
|
141
|
+
|
|
123
142
|
```tsx
|
|
124
143
|
// root.tsx
|
|
125
|
-
import { Meta, Scripts } from
|
|
144
|
+
import { Meta, Scripts } from "@tanstack/react-router";
|
|
126
145
|
|
|
127
146
|
export function Root() {
|
|
128
147
|
return (
|
|
129
148
|
<html lang="en">
|
|
130
149
|
<head>
|
|
131
150
|
<Meta />
|
|
132
|
-
{process.env.NODE_ENV ===
|
|
151
|
+
{process.env.NODE_ENV === "development" && (
|
|
133
152
|
<script
|
|
134
153
|
src="https://unpkg.com/@oyerinde/caliper/dist/index.global.js"
|
|
135
|
-
data-config={JSON.stringify({ theme: { primary:
|
|
154
|
+
data-config={JSON.stringify({ theme: { primary: "#AC2323" } })}
|
|
136
155
|
async
|
|
137
156
|
/>
|
|
138
157
|
)}
|
|
@@ -147,6 +166,59 @@ export function Root() {
|
|
|
147
166
|
|
|
148
167
|
---
|
|
149
168
|
|
|
169
|
+
## Agent Bridge Installation 🤖
|
|
170
|
+
|
|
171
|
+
The Agent Bridge enables AI agents (like Claude or Cursor) to communicate with Caliper. It is available as a sub-export of the main package.
|
|
172
|
+
|
|
173
|
+
### 1. Vite & Module Bundlers
|
|
174
|
+
|
|
175
|
+
If you've installed `@oyerinde/caliper` via npm, you can initialize the bridge using the plugin pattern:
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
import { init } from "@oyerinde/caliper";
|
|
179
|
+
import { CaliperBridge } from "@oyerinde/caliper/bridge";
|
|
180
|
+
|
|
181
|
+
const caliper = init();
|
|
182
|
+
|
|
183
|
+
caliper.use(
|
|
184
|
+
CaliperBridge({
|
|
185
|
+
enabled: true,
|
|
186
|
+
wsPort: 9876,
|
|
187
|
+
})
|
|
188
|
+
);
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### 2. Standalone (CDN/IIFE)
|
|
192
|
+
|
|
193
|
+
If you are using the global script tag, the bridge is automatically included in the default bundle. Use the **minified lite** version if you don't need bridge support:
|
|
194
|
+
|
|
195
|
+
```html
|
|
196
|
+
<!-- Full version (Includes Agent Bridge) -->
|
|
197
|
+
<script
|
|
198
|
+
src="https://unpkg.com/@oyerinde/caliper/dist/index.global.js"
|
|
199
|
+
data-config='{"bridge": {"enabled": true}}'
|
|
200
|
+
></script>
|
|
201
|
+
|
|
202
|
+
<!-- Lite Version (Core only, No Bridge) -->
|
|
203
|
+
<script src="https://unpkg.com/@oyerinde/caliper/dist/index.global.min.js"></script>
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### 3. Next.js (App Router)
|
|
207
|
+
|
|
208
|
+
Enable the bridge directly in your configuration block:
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
<Script
|
|
212
|
+
src="https://unpkg.com/@oyerinde/caliper/dist/index.global.js"
|
|
213
|
+
data-config={JSON.stringify({
|
|
214
|
+
bridge: { enabled: true },
|
|
215
|
+
})}
|
|
216
|
+
strategy="afterInteractive"
|
|
217
|
+
/>
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
150
222
|
## Configuration 🛠️
|
|
151
223
|
|
|
152
224
|
Caliper can be customized to fit your specific design system and workflow. `init()` automatically mounts the overlay in the browser.
|
|
@@ -157,17 +229,39 @@ import { init } from "@oyerinde/caliper";
|
|
|
157
229
|
init({
|
|
158
230
|
theme: {
|
|
159
231
|
primary: "#18A0FB", // Main brand color
|
|
160
|
-
|
|
161
|
-
calcBg: "rgba(
|
|
232
|
+
secondary: "#F24E1E", // Accent color (for highlights)
|
|
233
|
+
calcBg: "rgba(30,30,30,0.95)",
|
|
234
|
+
calcShadow: "rgba(0,0,0,0.5)",
|
|
235
|
+
calcOpHighlight: "#18A0FB", // Operator pulse color
|
|
236
|
+
calcText: "#FFFFFF",
|
|
237
|
+
text: "#FFFFFF",
|
|
238
|
+
projection: "#9B51E4", // Edge projection lines
|
|
239
|
+
ruler: "#18A0FB", // Ruler/guideline color
|
|
162
240
|
},
|
|
163
241
|
commands: {
|
|
164
|
-
activate: "Alt", //
|
|
242
|
+
activate: "Alt", // Reveal overlay
|
|
165
243
|
freeze: " ", // Key to lock lines
|
|
166
|
-
|
|
167
|
-
|
|
244
|
+
select: "Control", // Key to select (held)
|
|
245
|
+
clear: "Escape", // Clear measurements
|
|
246
|
+
ruler: "r", // Ruler (Shift+r)
|
|
247
|
+
selectionHoldDuration: 250, // Select hold-time (ms)
|
|
248
|
+
calculator: {
|
|
249
|
+
top: "t",
|
|
250
|
+
right: "r",
|
|
251
|
+
bottom: "b",
|
|
252
|
+
left: "l",
|
|
253
|
+
distance: "g",
|
|
254
|
+
},
|
|
255
|
+
projection: {
|
|
256
|
+
top: "w",
|
|
257
|
+
left: "a",
|
|
258
|
+
bottom: "s",
|
|
259
|
+
right: "d",
|
|
260
|
+
},
|
|
168
261
|
},
|
|
169
262
|
animation: {
|
|
170
|
-
|
|
263
|
+
enabled: true, // Smooth hover box
|
|
264
|
+
lerpFactor: 0.25, // Fluidity (low = slower)
|
|
171
265
|
},
|
|
172
266
|
});
|
|
173
267
|
```
|
|
@@ -182,6 +276,16 @@ To prevent Caliper from measuring specific elements (like sidebars, floating but
|
|
|
182
276
|
</div>
|
|
183
277
|
```
|
|
184
278
|
|
|
279
|
+
### Stable Markers
|
|
280
|
+
|
|
281
|
+
For AI agents to reliably rediscover elements across re-renders (like HMR), we recommend adding stable markers to critical UI components. Use the `caliperProps` helper to add these attributes only in non-production environments.
|
|
282
|
+
|
|
283
|
+
**Usage:**
|
|
284
|
+
|
|
285
|
+
```tsx
|
|
286
|
+
<div {...caliperProps("main-sidebar")}>...</div>
|
|
287
|
+
```
|
|
288
|
+
|
|
185
289
|
---
|
|
186
290
|
|
|
187
291
|
## Interaction Guide ⌨️
|
|
@@ -189,6 +293,7 @@ To prevent Caliper from measuring specific elements (like sidebars, floating but
|
|
|
189
293
|
### Measurements
|
|
190
294
|
|
|
191
295
|
- **Cmd/Ctrl + Click + Hold** (250ms) — Select an element.
|
|
296
|
+
- **Right-Click** — Copy element metadata (selector, ID, text) when selected.
|
|
192
297
|
- **Hover** — View relative distances to target.
|
|
193
298
|
- **Option/Alt** — Hold to reveal the overlay.
|
|
194
299
|
- **Space** — Freeze the current state.
|
package/dist/bridge.cjs
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkPYAVLOZM_cjs = require('./chunk-PYAVLOZM.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(exports, "CALIPER_METHODS", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () { return chunkPYAVLOZM_cjs.CALIPER_METHODS; }
|
|
10
|
+
});
|
|
11
|
+
Object.defineProperty(exports, "CaliperActionResultSchema", {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
get: function () { return chunkPYAVLOZM_cjs.CaliperActionResultSchema; }
|
|
14
|
+
});
|
|
15
|
+
Object.defineProperty(exports, "CaliperAgentStateSchema", {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: function () { return chunkPYAVLOZM_cjs.CaliperAgentStateSchema; }
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports, "CaliperBridge", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () { return chunkPYAVLOZM_cjs.CaliperBridge; }
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(exports, "CaliperGetContextPayloadSchema", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
get: function () { return chunkPYAVLOZM_cjs.CaliperGetContextPayloadSchema; }
|
|
26
|
+
});
|
|
27
|
+
Object.defineProperty(exports, "CaliperInspectPayloadSchema", {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
get: function () { return chunkPYAVLOZM_cjs.CaliperInspectPayloadSchema; }
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperty(exports, "CaliperMeasurePayloadSchema", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
get: function () { return chunkPYAVLOZM_cjs.CaliperMeasurePayloadSchema; }
|
|
34
|
+
});
|
|
35
|
+
Object.defineProperty(exports, "CaliperSelectPayloadSchema", {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
get: function () { return chunkPYAVLOZM_cjs.CaliperSelectPayloadSchema; }
|
|
38
|
+
});
|
|
39
|
+
Object.defineProperty(exports, "CaliperWalkAndMeasurePayloadSchema", {
|
|
40
|
+
enumerable: true,
|
|
41
|
+
get: function () { return chunkPYAVLOZM_cjs.CaliperWalkAndMeasurePayloadSchema; }
|
|
42
|
+
});
|
|
43
|
+
Object.defineProperty(exports, "CaliperWalkDomPayloadSchema", {
|
|
44
|
+
enumerable: true,
|
|
45
|
+
get: function () { return chunkPYAVLOZM_cjs.CaliperWalkDomPayloadSchema; }
|
|
46
|
+
});
|
|
47
|
+
Object.defineProperty(exports, "dispatchCaliperIntent", {
|
|
48
|
+
enumerable: true,
|
|
49
|
+
get: function () { return chunkPYAVLOZM_cjs.dispatchCaliperIntent; }
|
|
50
|
+
});
|