@oyerinde/caliper 0.1.3 → 0.2.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/CHANGELOG.md +30 -0
- package/README.md +134 -25
- package/dist/bridge.cjs +50 -0
- package/dist/bridge.d.cts +1649 -0
- package/dist/bridge.d.ts +1649 -0
- package/dist/bridge.js +1 -0
- package/dist/bridge.server.cjs +34 -0
- package/dist/bridge.server.js +31 -0
- package/dist/chunk-3W2YKDGV.cjs +18631 -0
- package/dist/chunk-ACV6FK43.js +18619 -0
- package/dist/chunk-OSQHATBH.cjs +5891 -0
- package/dist/chunk-XYBNY4BT.js +5885 -0
- package/dist/index.cjs +24 -5131
- package/dist/index.d.cts +975 -18
- package/dist/index.d.ts +975 -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,36 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.2.0] - 2026-02-12
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Agent Bridge**: Support for AI agents and programmatic audits via `@oyerinde/caliper/bridge`.
|
|
10
|
+
- **MCP Server**: Integrated MCP server for AI auditing (activate via `npx @oyerinde/caliper`).
|
|
11
|
+
- **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`.
|
|
12
|
+
- **Accessibility Tools**: `caliper_check_contrast` and `caliper_delta_e`.
|
|
13
|
+
- **MCP prompts**: `caliper-selector-audit` and `caliper-selectors-compare`.
|
|
14
|
+
- **MCP resources**: `caliper://tabs` and `caliper://state`.
|
|
15
|
+
- **Context Menu**: Right-click selected elements to copy metadata.
|
|
16
|
+
- **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.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- **Geometry Engine**: Improved coordinate tracking for `fixed` and `sticky` elements and nested scroll containers.
|
|
21
|
+
- Fix: Precision tracking for sticky elements across complex DOM hierarchies.
|
|
22
|
+
- Fix: Deep scroll resolution for nested overflow containers.
|
|
23
|
+
- Fix: Real-time clipping path calculation for partially visible elements.
|
|
24
|
+
|
|
25
|
+
## [0.1.4] - 2026-01-16
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- Fixed selection triggering underlying element click events (buttons, links, etc.).
|
|
30
|
+
|
|
31
|
+
### Removed
|
|
32
|
+
|
|
33
|
+
- Removed double-click to remove rulers (use Delete/Backspace instead).
|
|
34
|
+
|
|
5
35
|
## [0.1.3] - 2026-01-13
|
|
6
36
|
|
|
7
37
|
### Improved
|
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
|
+
wsUrl: "ws://localhost: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,43 @@ 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)
|
|
265
|
+
},
|
|
266
|
+
bridge: {
|
|
267
|
+
enabled: true, // Connect to AI Agents
|
|
268
|
+
wsPort: 9876, // Port for MCP relay
|
|
171
269
|
},
|
|
172
270
|
});
|
|
173
271
|
```
|
|
@@ -182,6 +280,16 @@ To prevent Caliper from measuring specific elements (like sidebars, floating but
|
|
|
182
280
|
</div>
|
|
183
281
|
```
|
|
184
282
|
|
|
283
|
+
### Stable Markers
|
|
284
|
+
|
|
285
|
+
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.
|
|
286
|
+
|
|
287
|
+
**Usage:**
|
|
288
|
+
|
|
289
|
+
```tsx
|
|
290
|
+
<div {...caliperProps("main-sidebar")}>...</div>
|
|
291
|
+
```
|
|
292
|
+
|
|
185
293
|
---
|
|
186
294
|
|
|
187
295
|
## Interaction Guide ⌨️
|
|
@@ -189,6 +297,7 @@ To prevent Caliper from measuring specific elements (like sidebars, floating but
|
|
|
189
297
|
### Measurements
|
|
190
298
|
|
|
191
299
|
- **Cmd/Ctrl + Click + Hold** (250ms) — Select an element.
|
|
300
|
+
- **Right-Click** — Copy element metadata (selector, ID, text) when selected.
|
|
192
301
|
- **Hover** — View relative distances to target.
|
|
193
302
|
- **Option/Alt** — Hold to reveal the overlay.
|
|
194
303
|
- **Space** — Freeze the current state.
|
package/dist/bridge.cjs
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk3W2YKDGV_cjs = require('./chunk-3W2YKDGV.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(exports, "CALIPER_METHODS", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () { return chunk3W2YKDGV_cjs.CALIPER_METHODS; }
|
|
10
|
+
});
|
|
11
|
+
Object.defineProperty(exports, "CaliperActionResultSchema", {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
get: function () { return chunk3W2YKDGV_cjs.CaliperActionResultSchema; }
|
|
14
|
+
});
|
|
15
|
+
Object.defineProperty(exports, "CaliperAgentStateSchema", {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: function () { return chunk3W2YKDGV_cjs.CaliperAgentStateSchema; }
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports, "CaliperBridge", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () { return chunk3W2YKDGV_cjs.CaliperBridge; }
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(exports, "CaliperGetContextPayloadSchema", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
get: function () { return chunk3W2YKDGV_cjs.CaliperGetContextPayloadSchema; }
|
|
26
|
+
});
|
|
27
|
+
Object.defineProperty(exports, "CaliperInspectPayloadSchema", {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
get: function () { return chunk3W2YKDGV_cjs.CaliperInspectPayloadSchema; }
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperty(exports, "CaliperMeasurePayloadSchema", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
get: function () { return chunk3W2YKDGV_cjs.CaliperMeasurePayloadSchema; }
|
|
34
|
+
});
|
|
35
|
+
Object.defineProperty(exports, "CaliperSelectPayloadSchema", {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
get: function () { return chunk3W2YKDGV_cjs.CaliperSelectPayloadSchema; }
|
|
38
|
+
});
|
|
39
|
+
Object.defineProperty(exports, "CaliperWalkAndMeasurePayloadSchema", {
|
|
40
|
+
enumerable: true,
|
|
41
|
+
get: function () { return chunk3W2YKDGV_cjs.CaliperWalkAndMeasurePayloadSchema; }
|
|
42
|
+
});
|
|
43
|
+
Object.defineProperty(exports, "CaliperWalkDomPayloadSchema", {
|
|
44
|
+
enumerable: true,
|
|
45
|
+
get: function () { return chunk3W2YKDGV_cjs.CaliperWalkDomPayloadSchema; }
|
|
46
|
+
});
|
|
47
|
+
Object.defineProperty(exports, "dispatchCaliperIntent", {
|
|
48
|
+
enumerable: true,
|
|
49
|
+
get: function () { return chunk3W2YKDGV_cjs.dispatchCaliperIntent; }
|
|
50
|
+
});
|