@ytspar/sweetlink 1.16.0 → 1.17.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/claude-skills/console-check-sweetlink/SKILL.md +1 -1
- package/claude-skills/console-check-sweetlink/evals/evals.json +35 -0
- package/claude-skills/resize-for-claude/evals/evals.json +23 -0
- package/claude-skills/responsive-screenshots/SKILL.md +1 -1
- package/claude-skills/responsive-screenshots/evals/evals.json +23 -0
- package/claude-skills/screenshot/SKILL.md +2 -0
- package/claude-skills/screenshot/evals/evals.json +35 -0
- package/dist/cli/sweetlink.js +70 -12
- package/dist/cli/sweetlink.js.map +1 -1
- package/dist/daemon/browser.d.ts +10 -0
- package/dist/daemon/browser.d.ts.map +1 -1
- package/dist/daemon/browser.js +57 -12
- package/dist/daemon/browser.js.map +1 -1
- package/dist/daemon/devices.d.ts +9 -4
- package/dist/daemon/devices.d.ts.map +1 -1
- package/dist/daemon/devices.js +25 -4
- package/dist/daemon/devices.js.map +1 -1
- package/dist/daemon/diff.d.ts +6 -0
- package/dist/daemon/diff.d.ts.map +1 -1
- package/dist/daemon/diff.js +46 -26
- package/dist/daemon/diff.js.map +1 -1
- package/dist/daemon/listeners.d.ts +2 -2
- package/dist/daemon/listeners.d.ts.map +1 -1
- package/dist/daemon/listeners.js +7 -5
- package/dist/daemon/listeners.js.map +1 -1
- package/dist/daemon/recording.d.ts +6 -1
- package/dist/daemon/recording.d.ts.map +1 -1
- package/dist/daemon/recording.js +81 -11
- package/dist/daemon/recording.js.map +1 -1
- package/dist/daemon/refs.d.ts.map +1 -1
- package/dist/daemon/refs.js +7 -2
- package/dist/daemon/refs.js.map +1 -1
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +127 -12
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/summary.d.ts.map +1 -1
- package/dist/daemon/summary.js +52 -10
- package/dist/daemon/summary.js.map +1 -1
- package/dist/daemon/types.d.ts +1 -1
- package/dist/daemon/types.d.ts.map +1 -1
- package/dist/daemon/types.js.map +1 -1
- package/dist/daemon/viewer.d.ts +7 -0
- package/dist/daemon/viewer.d.ts.map +1 -1
- package/dist/daemon/viewer.js +12 -4
- package/dist/daemon/viewer.js.map +1 -1
- package/dist/ruler.d.ts +1 -1
- package/dist/ruler.d.ts.map +1 -1
- package/dist/ruler.js +53 -32
- package/dist/ruler.js.map +1 -1
- package/package.json +37 -19
package/dist/ruler.d.ts
CHANGED
|
@@ -50,7 +50,7 @@ export interface RulerOutput {
|
|
|
50
50
|
* JavaScript function to inject into the page.
|
|
51
51
|
* Creates visual measurement overlays on elements.
|
|
52
52
|
*/
|
|
53
|
-
export declare const measureElementsScript = "\n(function(options) {\n const {\n selectors = [],\n showCenterLines = true,\n showDimensions = true,\n showPosition = false,\n colors = ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff'],\n limit = 5,\n showAlignment = true\n } = options || {};\n\n // Remove any existing measurement overlay\n const existingOverlay = document.getElementById('pixel-ruler-overlay');\n if (existingOverlay) existingOverlay.remove();\n\n // Create SVG overlay\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svg.id = 'pixel-ruler-overlay';\n svg.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n z-index: 999999;\n `;\n document.body.appendChild(svg);\n\n const results = [];\n let allRects = [];\n\n // Process each selector\n selectors.forEach((selector, selectorIndex) => {\n const color = colors[selectorIndex % colors.length];\n const elements = document.querySelectorAll(selector);\n const selectorResult = { selector, elements: [] };\n\n Array.from(elements).slice(0, limit).forEach((element, elementIndex) => {\n const rect = element.getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n\n selectorResult.elements.push({\n index: elementIndex,\n rect: { top: rect.top, left: rect.left, width: rect.width, height: rect.height },\n centerX,\n centerY\n });\n\n allRects.push({ rect, centerX, centerY, color, selector, elementIndex });\n\n // Draw bounding box\n const box = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n box.setAttribute('x', rect.left);\n box.setAttribute('y', rect.top);\n box.setAttribute('width', rect.width);\n box.setAttribute('height', rect.height);\n box.setAttribute('fill', 'none');\n box.setAttribute('stroke', color);\n box.setAttribute('stroke-width', '2');\n box.setAttribute('stroke-dasharray', '4,2');\n svg.appendChild(box);\n\n // Draw center lines\n if (showCenterLines) {\n // Horizontal center line\n const hLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n hLine.setAttribute('x1', rect.left);\n hLine.setAttribute('y1', centerY);\n hLine.setAttribute('x2', rect.left + rect.width);\n hLine.setAttribute('y2', centerY);\n hLine.setAttribute('stroke', color);\n hLine.setAttribute('stroke-width', '1');\n hLine.setAttribute('stroke-dasharray', '2,2');\n svg.appendChild(hLine);\n\n // Vertical center line\n const vLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n vLine.setAttribute('x1', centerX);\n vLine.setAttribute('y1', rect.top);\n vLine.setAttribute('x2', centerX);\n vLine.setAttribute('y2', rect.top + rect.height);\n vLine.setAttribute('stroke', color);\n vLine.setAttribute('stroke-width', '1');\n vLine.setAttribute('stroke-dasharray', '2,2');\n svg.appendChild(vLine);\n\n // Center point\n const centerDot = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n centerDot.setAttribute('cx', centerX);\n centerDot.setAttribute('cy', centerY);\n centerDot.setAttribute('r', '4');\n centerDot.setAttribute('fill', color);\n svg.appendChild(centerDot);\n }\n\n // Draw dimension labels\n if (showDimensions) {\n //
|
|
53
|
+
export declare const measureElementsScript = "\n(function(options) {\n const {\n selectors = [],\n showCenterLines = true,\n showDimensions = true,\n showPosition = false,\n colors = ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff'],\n limit = 5,\n showAlignment = true\n } = options || {};\n\n // Remove any existing measurement overlay\n const existingOverlay = document.getElementById('pixel-ruler-overlay');\n if (existingOverlay) existingOverlay.remove();\n\n // Create SVG overlay\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svg.id = 'pixel-ruler-overlay';\n svg.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n z-index: 999999;\n `;\n document.body.appendChild(svg);\n\n const results = [];\n let allRects = [];\n\n // Process each selector\n selectors.forEach((selector, selectorIndex) => {\n const color = colors[selectorIndex % colors.length];\n const elements = document.querySelectorAll(selector);\n const selectorResult = { selector, elements: [] };\n\n Array.from(elements).slice(0, limit).forEach((element, elementIndex) => {\n const rect = element.getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n\n selectorResult.elements.push({\n index: elementIndex,\n rect: { top: rect.top, left: rect.left, width: rect.width, height: rect.height },\n centerX,\n centerY\n });\n\n allRects.push({ rect, centerX, centerY, color, selector, elementIndex });\n\n // Draw bounding box\n const box = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n box.setAttribute('x', rect.left);\n box.setAttribute('y', rect.top);\n box.setAttribute('width', rect.width);\n box.setAttribute('height', rect.height);\n box.setAttribute('fill', 'none');\n box.setAttribute('stroke', color);\n box.setAttribute('stroke-width', '2');\n box.setAttribute('stroke-dasharray', '4,2');\n svg.appendChild(box);\n\n // Draw center lines\n if (showCenterLines) {\n // Horizontal center line\n const hLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n hLine.setAttribute('x1', rect.left);\n hLine.setAttribute('y1', centerY);\n hLine.setAttribute('x2', rect.left + rect.width);\n hLine.setAttribute('y2', centerY);\n hLine.setAttribute('stroke', color);\n hLine.setAttribute('stroke-width', '1');\n hLine.setAttribute('stroke-dasharray', '2,2');\n svg.appendChild(hLine);\n\n // Vertical center line\n const vLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n vLine.setAttribute('x1', centerX);\n vLine.setAttribute('y1', rect.top);\n vLine.setAttribute('x2', centerX);\n vLine.setAttribute('y2', rect.top + rect.height);\n vLine.setAttribute('stroke', color);\n vLine.setAttribute('stroke-width', '1');\n vLine.setAttribute('stroke-dasharray', '2,2');\n svg.appendChild(vLine);\n\n // Center point\n const centerDot = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n centerDot.setAttribute('cx', centerX);\n centerDot.setAttribute('cy', centerY);\n centerDot.setAttribute('r', '4');\n centerDot.setAttribute('fill', color);\n svg.appendChild(centerDot);\n }\n\n // Draw dimension labels\n if (showDimensions) {\n // Position the label OUTSIDE the bbox so it doesn't overlap\n // page content. Default: above the bbox (top); fall back below\n // when the element is at the very top of the page.\n const dimLabel = `${Math.round(rect.width)}\u00D7${Math.round(rect.height)}`;\n const labelHeight = 22;\n const labelW = Math.max(70, dimLabel.length * 9);\n const goAbove = rect.top >= labelHeight + 4;\n const ly = goAbove ? rect.top - labelHeight - 2 : rect.top + rect.height + 2;\n const lx = rect.left;\n\n const labelBg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n labelBg.setAttribute('x', lx);\n labelBg.setAttribute('y', ly);\n labelBg.setAttribute('width', String(labelW));\n labelBg.setAttribute('height', String(labelHeight));\n labelBg.setAttribute('fill', color);\n labelBg.setAttribute('rx', '3');\n svg.appendChild(labelBg);\n\n const dimText = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n dimText.setAttribute('x', lx + labelW / 2);\n dimText.setAttribute('y', ly + 15);\n dimText.setAttribute('fill', '#ffffff');\n dimText.setAttribute('font-family', 'system-ui, sans-serif');\n dimText.setAttribute('font-size', '13');\n dimText.setAttribute('font-weight', '700');\n dimText.setAttribute('text-anchor', 'middle');\n dimText.textContent = dimLabel;\n svg.appendChild(dimText);\n }\n\n // Draw position labels (separate, opposite side of dim label)\n if (showPosition) {\n const posText = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n // Position label below-right outside the bbox.\n posText.setAttribute('x', rect.left + rect.width + 4);\n posText.setAttribute('y', rect.top + 14);\n posText.setAttribute('fill', color);\n posText.setAttribute('font-family', 'system-ui, sans-serif');\n posText.setAttribute('font-size', '12');\n posText.textContent = `(${Math.round(rect.left)}, ${Math.round(rect.top)})`;\n svg.appendChild(posText);\n }\n });\n\n results.push(selectorResult);\n });\n\n // Show alignment comparison between elements\n let alignment = null;\n if (showAlignment && allRects.length >= 2) {\n const first = allRects[0];\n const second = allRects[1];\n\n // Draw alignment line between centers\n const alignLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n alignLine.setAttribute('x1', first.centerX);\n alignLine.setAttribute('y1', first.centerY);\n alignLine.setAttribute('x2', second.centerX);\n alignLine.setAttribute('y2', second.centerY);\n alignLine.setAttribute('stroke', '#ffffff');\n alignLine.setAttribute('stroke-width', '2');\n svg.appendChild(alignLine);\n\n // Calculate vertical offset\n const verticalOffset = Math.round(first.centerY - second.centerY);\n const horizontalOffset = Math.round(first.centerX - second.centerX);\n\n // Offset label\n const midX = (first.centerX + second.centerX) / 2;\n const midY = (first.centerY + second.centerY) / 2;\n\n const offsetLabel = `\u0394y=${verticalOffset}px \u0394x=${horizontalOffset}px`;\n const offsetW = Math.max(140, offsetLabel.length * 9);\n const offsetH = 28;\n const offsetBg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n offsetBg.setAttribute('x', midX - offsetW / 2);\n offsetBg.setAttribute('y', midY - offsetH / 2);\n offsetBg.setAttribute('width', String(offsetW));\n offsetBg.setAttribute('height', String(offsetH));\n offsetBg.setAttribute('fill', 'rgba(20,20,20,0.95)');\n offsetBg.setAttribute('rx', '4');\n svg.appendChild(offsetBg);\n\n const offsetText = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n offsetText.setAttribute('x', midX);\n offsetText.setAttribute('y', midY + 6);\n offsetText.setAttribute('fill', '#ffffff');\n offsetText.setAttribute('font-family', 'system-ui, sans-serif');\n offsetText.setAttribute('font-size', '14');\n offsetText.setAttribute('font-weight', '700');\n offsetText.setAttribute('text-anchor', 'middle');\n offsetText.textContent = offsetLabel;\n svg.appendChild(offsetText);\n\n alignment = {\n verticalOffset,\n horizontalOffset,\n aligned: Math.abs(verticalOffset) <= 2 && Math.abs(horizontalOffset) <= 2\n };\n }\n\n return {\n results,\n summary: results.map(r => `${r.selector}: ${r.elements.length} elements`).join(', '),\n alignment\n };\n})\n";
|
|
54
54
|
/**
|
|
55
55
|
* Measure elements and inject visual overlay using Playwright
|
|
56
56
|
*/
|
package/dist/ruler.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ruler.d.ts","sourceRoot":"","sources":["../src/ruler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,kDAAkD;IAClD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,6CAA6C;IAC7C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,uCAAuC;IACvC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,kBAAkB,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE;QACV,cAAc,EAAE,MAAM,CAAC;QACvB,gBAAgB,EAAE,MAAM,CAAC;QACzB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;CACH;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,
|
|
1
|
+
{"version":3,"file":"ruler.d.ts","sourceRoot":"","sources":["../src/ruler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,kDAAkD;IAClD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,6CAA6C;IAC7C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,uCAAuC;IACvC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,kBAAkB,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE;QACV,cAAc,EAAE,MAAM,CAAC;QACvB,gBAAgB,EAAE,MAAM,CAAC;QACzB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;CACH;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,6jQAgNjC,CAAC;AAEF;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAClD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,OAAO,CAAC,WAAW,GAAG;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA+DrD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,kBAAkB,CAWxD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,kBAAkB,CAQxD"}
|
package/dist/ruler.js
CHANGED
|
@@ -112,36 +112,46 @@ export const measureElementsScript = `
|
|
|
112
112
|
|
|
113
113
|
// Draw dimension labels
|
|
114
114
|
if (showDimensions) {
|
|
115
|
-
//
|
|
115
|
+
// Position the label OUTSIDE the bbox so it doesn't overlap
|
|
116
|
+
// page content. Default: above the bbox (top); fall back below
|
|
117
|
+
// when the element is at the very top of the page.
|
|
118
|
+
const dimLabel = \`\${Math.round(rect.width)}×\${Math.round(rect.height)}\`;
|
|
119
|
+
const labelHeight = 22;
|
|
120
|
+
const labelW = Math.max(70, dimLabel.length * 9);
|
|
121
|
+
const goAbove = rect.top >= labelHeight + 4;
|
|
122
|
+
const ly = goAbove ? rect.top - labelHeight - 2 : rect.top + rect.height + 2;
|
|
123
|
+
const lx = rect.left;
|
|
124
|
+
|
|
116
125
|
const labelBg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
|
117
|
-
labelBg.setAttribute('x',
|
|
118
|
-
labelBg.setAttribute('y',
|
|
119
|
-
labelBg.setAttribute('width',
|
|
120
|
-
labelBg.setAttribute('height',
|
|
121
|
-
labelBg.setAttribute('fill',
|
|
122
|
-
labelBg.setAttribute('rx', '
|
|
126
|
+
labelBg.setAttribute('x', lx);
|
|
127
|
+
labelBg.setAttribute('y', ly);
|
|
128
|
+
labelBg.setAttribute('width', String(labelW));
|
|
129
|
+
labelBg.setAttribute('height', String(labelHeight));
|
|
130
|
+
labelBg.setAttribute('fill', color);
|
|
131
|
+
labelBg.setAttribute('rx', '3');
|
|
123
132
|
svg.appendChild(labelBg);
|
|
124
133
|
|
|
125
|
-
// Dimension text
|
|
126
134
|
const dimText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
|
127
|
-
dimText.setAttribute('x',
|
|
128
|
-
dimText.setAttribute('y',
|
|
129
|
-
dimText.setAttribute('fill',
|
|
130
|
-
dimText.setAttribute('font-family', '
|
|
131
|
-
dimText.setAttribute('font-size', '
|
|
132
|
-
dimText.setAttribute('font-weight', '
|
|
133
|
-
dimText.
|
|
135
|
+
dimText.setAttribute('x', lx + labelW / 2);
|
|
136
|
+
dimText.setAttribute('y', ly + 15);
|
|
137
|
+
dimText.setAttribute('fill', '#ffffff');
|
|
138
|
+
dimText.setAttribute('font-family', 'system-ui, sans-serif');
|
|
139
|
+
dimText.setAttribute('font-size', '13');
|
|
140
|
+
dimText.setAttribute('font-weight', '700');
|
|
141
|
+
dimText.setAttribute('text-anchor', 'middle');
|
|
142
|
+
dimText.textContent = dimLabel;
|
|
134
143
|
svg.appendChild(dimText);
|
|
135
144
|
}
|
|
136
145
|
|
|
137
|
-
// Draw position labels
|
|
146
|
+
// Draw position labels (separate, opposite side of dim label)
|
|
138
147
|
if (showPosition) {
|
|
139
148
|
const posText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
|
140
|
-
|
|
149
|
+
// Position label below-right outside the bbox.
|
|
150
|
+
posText.setAttribute('x', rect.left + rect.width + 4);
|
|
141
151
|
posText.setAttribute('y', rect.top + 14);
|
|
142
152
|
posText.setAttribute('fill', color);
|
|
143
|
-
posText.setAttribute('font-family', '
|
|
144
|
-
posText.setAttribute('font-size', '
|
|
153
|
+
posText.setAttribute('font-family', 'system-ui, sans-serif');
|
|
154
|
+
posText.setAttribute('font-size', '12');
|
|
145
155
|
posText.textContent = \`(\${Math.round(rect.left)}, \${Math.round(rect.top)})\`;
|
|
146
156
|
svg.appendChild(posText);
|
|
147
157
|
}
|
|
@@ -174,24 +184,27 @@ export const measureElementsScript = `
|
|
|
174
184
|
const midX = (first.centerX + second.centerX) / 2;
|
|
175
185
|
const midY = (first.centerY + second.centerY) / 2;
|
|
176
186
|
|
|
187
|
+
const offsetLabel = \`Δy=\${verticalOffset}px Δx=\${horizontalOffset}px\`;
|
|
188
|
+
const offsetW = Math.max(140, offsetLabel.length * 9);
|
|
189
|
+
const offsetH = 28;
|
|
177
190
|
const offsetBg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
|
178
|
-
offsetBg.setAttribute('x', midX -
|
|
179
|
-
offsetBg.setAttribute('y', midY -
|
|
180
|
-
offsetBg.setAttribute('width',
|
|
181
|
-
offsetBg.setAttribute('height',
|
|
182
|
-
offsetBg.setAttribute('fill', 'rgba(
|
|
191
|
+
offsetBg.setAttribute('x', midX - offsetW / 2);
|
|
192
|
+
offsetBg.setAttribute('y', midY - offsetH / 2);
|
|
193
|
+
offsetBg.setAttribute('width', String(offsetW));
|
|
194
|
+
offsetBg.setAttribute('height', String(offsetH));
|
|
195
|
+
offsetBg.setAttribute('fill', 'rgba(20,20,20,0.95)');
|
|
183
196
|
offsetBg.setAttribute('rx', '4');
|
|
184
197
|
svg.appendChild(offsetBg);
|
|
185
198
|
|
|
186
199
|
const offsetText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
|
187
200
|
offsetText.setAttribute('x', midX);
|
|
188
|
-
offsetText.setAttribute('y', midY +
|
|
201
|
+
offsetText.setAttribute('y', midY + 6);
|
|
189
202
|
offsetText.setAttribute('fill', '#ffffff');
|
|
190
|
-
offsetText.setAttribute('font-family', '
|
|
191
|
-
offsetText.setAttribute('font-size', '
|
|
192
|
-
offsetText.setAttribute('font-weight', '
|
|
203
|
+
offsetText.setAttribute('font-family', 'system-ui, sans-serif');
|
|
204
|
+
offsetText.setAttribute('font-size', '14');
|
|
205
|
+
offsetText.setAttribute('font-weight', '700');
|
|
193
206
|
offsetText.setAttribute('text-anchor', 'middle');
|
|
194
|
-
offsetText.textContent =
|
|
207
|
+
offsetText.textContent = offsetLabel;
|
|
195
208
|
svg.appendChild(offsetText);
|
|
196
209
|
|
|
197
210
|
alignment = {
|
|
@@ -242,10 +255,18 @@ export async function measureViaPlaywright(options) {
|
|
|
242
255
|
if (dir && !fs.existsSync(dir)) {
|
|
243
256
|
fs.mkdirSync(dir, { recursive: true });
|
|
244
257
|
}
|
|
245
|
-
|
|
258
|
+
// If any measured element extends below the viewport, capture the
|
|
259
|
+
// full page so all overlays are visible — otherwise users see
|
|
260
|
+
// half their highlights cut off. (page.viewportSize is missing
|
|
261
|
+
// from some test doubles, hence the typeof guard.)
|
|
262
|
+
const vp = typeof page.viewportSize === 'function' ? page.viewportSize() : null;
|
|
263
|
+
const extendsBelow = vp ? result.results.some((r) => r.elements.some((e) => e.rect.top + e.rect.height > vp.height)) : false;
|
|
264
|
+
await page.screenshot({ path: options.output, fullPage: extendsBelow });
|
|
246
265
|
screenshotPath = options.output;
|
|
247
|
-
if (options.verbose)
|
|
248
|
-
console.log(`[Sweetlink Ruler] Screenshot saved to: ${options.output}`
|
|
266
|
+
if (options.verbose) {
|
|
267
|
+
console.log(`[Sweetlink Ruler] Screenshot saved to: ${options.output}` +
|
|
268
|
+
(extendsBelow ? ' (full page — measured elements extend below viewport)' : ''));
|
|
269
|
+
}
|
|
249
270
|
}
|
|
250
271
|
return { ...result, screenshotPath };
|
|
251
272
|
}
|
package/dist/ruler.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ruler.js","sourceRoot":"","sources":["../src/ruler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAyC7C;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG
|
|
1
|
+
{"version":3,"file":"ruler.js","sourceRoot":"","sources":["../src/ruler.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ytspar/sweetlink",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"description": "Autonomous development toolkit for AI agents - screenshots, DOM queries, console logs, and JavaScript execution via WebSocket and Chrome DevTools Protocol",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"autonomous-development",
|
|
@@ -23,75 +23,93 @@
|
|
|
23
23
|
"exports": {
|
|
24
24
|
".": {
|
|
25
25
|
"types": "./dist/index.d.ts",
|
|
26
|
-
"import": "./dist/index.js"
|
|
26
|
+
"import": "./dist/index.js",
|
|
27
|
+
"default": "./dist/index.js"
|
|
27
28
|
},
|
|
28
29
|
"./types": {
|
|
29
30
|
"types": "./dist/types.d.ts",
|
|
30
|
-
"import": "./dist/types.js"
|
|
31
|
+
"import": "./dist/types.js",
|
|
32
|
+
"default": "./dist/types.js"
|
|
31
33
|
},
|
|
32
34
|
"./server": {
|
|
33
35
|
"types": "./dist/server.d.ts",
|
|
34
|
-
"import": "./dist/server.js"
|
|
36
|
+
"import": "./dist/server.js",
|
|
37
|
+
"default": "./dist/server.js"
|
|
35
38
|
},
|
|
36
39
|
"./browser": {
|
|
37
40
|
"types": "./dist/browser.d.ts",
|
|
38
|
-
"import": "./dist/browser.js"
|
|
41
|
+
"import": "./dist/browser.js",
|
|
42
|
+
"default": "./dist/browser.js"
|
|
39
43
|
},
|
|
40
44
|
"./browser/commands/schema": {
|
|
41
45
|
"types": "./dist/browser/commands/schema.d.ts",
|
|
42
|
-
"import": "./dist/browser/commands/schema.js"
|
|
46
|
+
"import": "./dist/browser/commands/schema.js",
|
|
47
|
+
"default": "./dist/browser/commands/schema.js"
|
|
43
48
|
},
|
|
44
49
|
"./browser/commands/outline": {
|
|
45
50
|
"types": "./dist/browser/commands/outline.d.ts",
|
|
46
|
-
"import": "./dist/browser/commands/outline.js"
|
|
51
|
+
"import": "./dist/browser/commands/outline.js",
|
|
52
|
+
"default": "./dist/browser/commands/outline.js"
|
|
47
53
|
},
|
|
48
54
|
"./browser/consoleCapture": {
|
|
49
55
|
"types": "./dist/browser/consoleCapture.d.ts",
|
|
50
|
-
"import": "./dist/browser/consoleCapture.js"
|
|
56
|
+
"import": "./dist/browser/consoleCapture.js",
|
|
57
|
+
"default": "./dist/browser/consoleCapture.js"
|
|
51
58
|
},
|
|
52
59
|
"./browser/earlyConsoleCapture": {
|
|
53
60
|
"types": "./dist/browser/earlyConsoleCapture.d.ts",
|
|
54
|
-
"import": "./dist/browser/earlyConsoleCapture.js"
|
|
61
|
+
"import": "./dist/browser/earlyConsoleCapture.js",
|
|
62
|
+
"default": "./dist/browser/earlyConsoleCapture.js"
|
|
55
63
|
},
|
|
56
64
|
"./browser/screenshotUtils": {
|
|
57
65
|
"types": "./dist/browser/screenshotUtils.d.ts",
|
|
58
|
-
"import": "./dist/browser/screenshotUtils.js"
|
|
66
|
+
"import": "./dist/browser/screenshotUtils.js",
|
|
67
|
+
"default": "./dist/browser/screenshotUtils.js"
|
|
59
68
|
},
|
|
60
69
|
"./urlUtils": {
|
|
61
70
|
"types": "./dist/urlUtils.d.ts",
|
|
62
|
-
"import": "./dist/urlUtils.js"
|
|
71
|
+
"import": "./dist/urlUtils.js",
|
|
72
|
+
"default": "./dist/urlUtils.js"
|
|
63
73
|
},
|
|
64
74
|
"./ruler": {
|
|
65
75
|
"types": "./dist/ruler.d.ts",
|
|
66
|
-
"import": "./dist/ruler.js"
|
|
76
|
+
"import": "./dist/ruler.js",
|
|
77
|
+
"default": "./dist/ruler.js"
|
|
67
78
|
},
|
|
68
79
|
"./playwright": {
|
|
69
80
|
"types": "./dist/playwright.d.ts",
|
|
70
|
-
"import": "./dist/playwright.js"
|
|
81
|
+
"import": "./dist/playwright.js",
|
|
82
|
+
"default": "./dist/playwright.js"
|
|
71
83
|
},
|
|
72
84
|
"./cdp": {
|
|
73
85
|
"types": "./dist/cdp.d.ts",
|
|
74
|
-
"import": "./dist/cdp.js"
|
|
86
|
+
"import": "./dist/cdp.js",
|
|
87
|
+
"default": "./dist/cdp.js"
|
|
75
88
|
},
|
|
76
89
|
"./vite": {
|
|
77
90
|
"types": "./dist/vite.d.ts",
|
|
78
|
-
"import": "./dist/vite.js"
|
|
91
|
+
"import": "./dist/vite.js",
|
|
92
|
+
"default": "./dist/vite.js"
|
|
79
93
|
},
|
|
80
94
|
"./auto": {
|
|
81
95
|
"types": "./dist/auto.d.ts",
|
|
82
|
-
"import": "./dist/auto.js"
|
|
96
|
+
"import": "./dist/auto.js",
|
|
97
|
+
"default": "./dist/auto.js"
|
|
83
98
|
},
|
|
84
99
|
"./next": {
|
|
85
100
|
"types": "./dist/next.d.ts",
|
|
86
|
-
"import": "./dist/next.js"
|
|
101
|
+
"import": "./dist/next.js",
|
|
102
|
+
"default": "./dist/next.js"
|
|
87
103
|
},
|
|
88
104
|
"./daemon": {
|
|
89
105
|
"types": "./dist/daemon/types.d.ts",
|
|
90
|
-
"import": "./dist/daemon/types.js"
|
|
106
|
+
"import": "./dist/daemon/types.js",
|
|
107
|
+
"default": "./dist/daemon/types.js"
|
|
91
108
|
},
|
|
92
109
|
"./daemon/client": {
|
|
93
110
|
"types": "./dist/daemon/client.d.ts",
|
|
94
|
-
"import": "./dist/daemon/client.js"
|
|
111
|
+
"import": "./dist/daemon/client.js",
|
|
112
|
+
"default": "./dist/daemon/client.js"
|
|
95
113
|
}
|
|
96
114
|
},
|
|
97
115
|
"bin": {
|